Commit a88d3cc1 authored by unknown's avatar unknown
Browse files

Fix for bug#10964: Information Schema:Authorization check on(2nd version, after review)

                   privilege tables is improper
    added privilege check for USER_PRIVILEGES, SCHEMA_PRIVILEGES,
    TABLE_PRIVILEGES, COLUMN_PRIVILEGES tables

parent a923940c
Loading
Loading
Loading
Loading
+70 −0
Original line number Diff line number Diff line
@@ -752,3 +752,73 @@ SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHE
table_schema	count(*)
information_schema	15
mysql	17
create database mysqltest;
create table mysqltest.t1 (f1 int, f2 int);
create table mysqltest.t2 (f1 int);
grant select (f1) on mysqltest.t1 to user1@localhost;
grant select on mysqltest.t2 to user2@localhost;
grant select on mysqltest.* to user3@localhost;
grant select on *.* to user4@localhost;
select * from information_schema.column_privileges;
GRANTEE	TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	COLUMN_NAME	PRIVILEGE_TYPE	IS_GRANTABLE
'user1'@'localhost'	NULL	mysqltest	t1	f1	SELECT	NO
select * from information_schema.table_privileges;
GRANTEE	TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	PRIVILEGE_TYPE	IS_GRANTABLE
select * from information_schema.schema_privileges;
GRANTEE	TABLE_CATALOG	TABLE_SCHEMA	PRIVILEGE_TYPE	IS_GRANTABLE
select * from information_schema.user_privileges;
GRANTEE	TABLE_CATALOG	PRIVILEGE_TYPE	IS_GRANTABLE
'user1'@'localhost'	NULL	USAGE	NO
show grants;
Grants for user1@localhost
GRANT USAGE ON *.* TO 'user1'@'localhost'
GRANT SELECT (f1) ON `mysqltest`.`t1` TO 'user1'@'localhost'
select * from information_schema.column_privileges;
GRANTEE	TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	COLUMN_NAME	PRIVILEGE_TYPE	IS_GRANTABLE
select * from information_schema.table_privileges;
GRANTEE	TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	PRIVILEGE_TYPE	IS_GRANTABLE
'user2'@'localhost'	NULL	mysqltest	t2	SELECT	NO
select * from information_schema.schema_privileges;
GRANTEE	TABLE_CATALOG	TABLE_SCHEMA	PRIVILEGE_TYPE	IS_GRANTABLE
select * from information_schema.user_privileges;
GRANTEE	TABLE_CATALOG	PRIVILEGE_TYPE	IS_GRANTABLE
'user2'@'localhost'	NULL	USAGE	NO
show grants;
Grants for user2@localhost
GRANT USAGE ON *.* TO 'user2'@'localhost'
GRANT SELECT ON `mysqltest`.`t2` TO 'user2'@'localhost'
select * from information_schema.column_privileges;
GRANTEE	TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	COLUMN_NAME	PRIVILEGE_TYPE	IS_GRANTABLE
select * from information_schema.table_privileges;
GRANTEE	TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	PRIVILEGE_TYPE	IS_GRANTABLE
select * from information_schema.schema_privileges;
GRANTEE	TABLE_CATALOG	TABLE_SCHEMA	PRIVILEGE_TYPE	IS_GRANTABLE
'user3'@'localhost'	NULL	mysqltest	SELECT	NO
select * from information_schema.user_privileges;
GRANTEE	TABLE_CATALOG	PRIVILEGE_TYPE	IS_GRANTABLE
'user3'@'localhost'	NULL	USAGE	NO
show grants;
Grants for user3@localhost
GRANT USAGE ON *.* TO 'user3'@'localhost'
GRANT SELECT ON `mysqltest`.* TO 'user3'@'localhost'
select * from information_schema.column_privileges where grantee like '%user%';
GRANTEE	TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	COLUMN_NAME	PRIVILEGE_TYPE	IS_GRANTABLE
'user1'@'localhost'	NULL	mysqltest	t1	f1	SELECT	NO
select * from information_schema.table_privileges where grantee like '%user%';
GRANTEE	TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	PRIVILEGE_TYPE	IS_GRANTABLE
'user2'@'localhost'	NULL	mysqltest	t2	SELECT	NO
select * from information_schema.schema_privileges where grantee like '%user%';
GRANTEE	TABLE_CATALOG	TABLE_SCHEMA	PRIVILEGE_TYPE	IS_GRANTABLE
'user3'@'localhost'	NULL	mysqltest	SELECT	NO
select * from information_schema.user_privileges where grantee like '%user%';
GRANTEE	TABLE_CATALOG	PRIVILEGE_TYPE	IS_GRANTABLE
'user1'@'localhost'	NULL	USAGE	NO
'user2'@'localhost'	NULL	USAGE	NO
'user3'@'localhost'	NULL	USAGE	NO
'user4'@'localhost'	NULL	SELECT	NO
show grants;
Grants for user4@localhost
GRANT SELECT ON *.* TO 'user4'@'localhost'
drop user user1@localhost, user2@localhost, user3@localhost, user4@localhost;
use test;
drop database mysqltest;
+44 −0
Original line number Diff line number Diff line
@@ -493,3 +493,47 @@ flush privileges;
#
SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA;

#
# Bug #10964  Information Schema:Authorization check on privilege tables is improper
#

create database mysqltest;
create table mysqltest.t1 (f1 int, f2 int);
create table mysqltest.t2 (f1 int);
grant select (f1) on mysqltest.t1 to user1@localhost;
grant select on mysqltest.t2 to user2@localhost;
grant select on mysqltest.* to user3@localhost;
grant select on *.* to user4@localhost;

connect (con1,localhost,user1,,);
connect (con2,localhost,user2,,);
connect (con3,localhost,user3,,);
connect (con4,localhost,user4,,);
connection con1;
select * from information_schema.column_privileges;
select * from information_schema.table_privileges;
select * from information_schema.schema_privileges;
select * from information_schema.user_privileges;
show grants;
connection con2;
select * from information_schema.column_privileges;
select * from information_schema.table_privileges;
select * from information_schema.schema_privileges;
select * from information_schema.user_privileges;
show grants;
connection con3;
select * from information_schema.column_privileges;
select * from information_schema.table_privileges;
select * from information_schema.schema_privileges;
select * from information_schema.user_privileges;
show grants;
connection con4;
select * from information_schema.column_privileges where grantee like '%user%';
select * from information_schema.table_privileges where grantee like '%user%';
select * from information_schema.schema_privileges where grantee like '%user%';
select * from information_schema.user_privileges where grantee like '%user%';
show grants;
connection default;
drop user user1@localhost, user2@localhost, user3@localhost, user4@localhost;
use test;
drop database mysqltest;
+34 −1
Original line number Diff line number Diff line
@@ -5406,10 +5406,12 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
  uint counter;
  ACL_USER *acl_user;
  ulong want_access;

  char buff[100];
  TABLE *table= tables->table;
  bool no_global_access= check_access(thd, SELECT_ACL, "mysql",0,1,1);
  char *curr_host= thd->priv_host ? thd->priv_host : (char *) "%";
  DBUG_ENTER("fill_schema_user_privileges");

  for (counter=0 ; counter < acl_users.elements ; counter++)
  {
    const char *user,*host, *is_grantable="YES";
@@ -5418,6 +5420,12 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
      user= "";
    if (!(host=acl_user->host.hostname))
      host= "";

    if (no_global_access &&
        (strcmp(thd->priv_user, user) ||
         my_strcasecmp(system_charset_info, curr_host, host)))
      continue;
      
    want_access= acl_user->access;
    if (!(want_access & GRANT_ACL))
      is_grantable= "NO";
@@ -5453,6 +5461,8 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
  ulong want_access;
  char buff[100];
  TABLE *table= tables->table;
  bool no_global_access= check_access(thd, SELECT_ACL, "mysql",0,1,1);
  char *curr_host= thd->priv_host ? thd->priv_host : (char *) "%";
  DBUG_ENTER("fill_schema_schema_privileges");

  for (counter=0 ; counter < acl_dbs.elements ; counter++)
@@ -5465,6 +5475,11 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
    if (!(host=acl_db->host.hostname))
      host= "";

    if (no_global_access &&
        (strcmp(thd->priv_user, user) ||
         my_strcasecmp(system_charset_info, curr_host, host)))
      continue;

    want_access=acl_db->access;
    if (want_access)
    {
@@ -5501,6 +5516,8 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
  uint index;
  char buff[100];
  TABLE *table= tables->table;
  bool no_global_access= check_access(thd, SELECT_ACL, "mysql",0,1,1);
  char *curr_host= thd->priv_host ? thd->priv_host : (char *) "%";
  DBUG_ENTER("fill_schema_table_privileges");

  for (index=0 ; index < column_priv_hash.records ; index++)
@@ -5510,6 +5527,13 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
							  index);
    if (!(user=grant_table->user))
      user= "";

    if (no_global_access &&
        (strcmp(thd->priv_user, user) ||
         my_strcasecmp(system_charset_info, curr_host,
                       grant_table->host.hostname)))
      continue;

    ulong table_access= grant_table->privs;
    if (table_access)
    {
@@ -5554,6 +5578,8 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
  uint index;
  char buff[100];
  TABLE *table= tables->table;
  bool no_global_access= check_access(thd, SELECT_ACL, "mysql",0,1,1);
  char *curr_host= thd->priv_host ? thd->priv_host : (char *) "%";
  DBUG_ENTER("fill_schema_table_privileges");

  for (index=0 ; index < column_priv_hash.records ; index++)
@@ -5563,6 +5589,13 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
							  index);
    if (!(user=grant_table->user))
      user= "";

    if (no_global_access &&
        (strcmp(thd->priv_user, user) ||
         my_strcasecmp(system_charset_info, curr_host,
                       grant_table->host.hostname)))
      continue;

    ulong table_access= grant_table->cols;
    if (table_access != 0)
    {