diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index de1f265aedf..38eb1d6a3ae 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -753,3 +753,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; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 1a6e41dba69..7302b3e5e58 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -498,3 +498,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; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 1f229c41d00..28b841435c8 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -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) {