From e46eea8660fb515455cb0d2e8c9d987df1acb1a3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 26 Oct 2013 15:52:29 +0200 Subject: [PATCH] remove inherited routine grants when a routine is dropped --- mysql-test/suite/roles/drop_routines.result | 53 ++++++--------------- mysql-test/suite/roles/drop_routines.test | 30 +++++++----- sql/sql_acl.cc | 16 ++++--- 3 files changed, 42 insertions(+), 57 deletions(-) diff --git a/mysql-test/suite/roles/drop_routines.result b/mysql-test/suite/roles/drop_routines.result index bbb6cc6ca39..ad2a82c37c5 100644 --- a/mysql-test/suite/roles/drop_routines.result +++ b/mysql-test/suite/roles/drop_routines.result @@ -1,13 +1,10 @@ create role r1; create role r2; create role r3; -create role r4; create user u1; grant r2 to r1; grant r3 to r2; -grant r4 to r3; grant r1 to u1; -grant r4 to r1; show grants for u1; Grants for u1@% GRANT USAGE ON *.* TO 'u1'@'%' @@ -17,11 +14,8 @@ Grants for r1 GRANT USAGE ON *.* TO 'r1' GRANT USAGE ON *.* TO 'r2' GRANT USAGE ON *.* TO 'r3' -GRANT USAGE ON *.* TO 'r4' GRANT r2 TO 'r1' GRANT r3 TO 'r2' -GRANT r4 TO 'r1' -GRANT r4 TO 'r3' grant SELECT on *.* to u1; grant INSERT on mysql.* to r1; grant DELETE on mysql.roles_mapping to r2; @@ -35,70 +29,51 @@ select COUNT(*) into param1 from mysql.roles_mapping; end| grant execute on function mysql.test_func to r2; grant execute on procedure mysql.test_proc to r3; -grant execute on mysql.* to r4; +revoke execute on procedure mysql.test_proc from r2; +ERROR 42000: There is no such grant defined for user 'r2' on host '' on routine 'test_proc' show grants for r1; Grants for r1 GRANT DELETE ON `mysql`.`roles_mapping` TO 'r2' GRANT EXECUTE ON FUNCTION `mysql`.`test_func` TO 'r2' GRANT EXECUTE ON PROCEDURE `mysql`.`test_proc` TO 'r3' -GRANT EXECUTE ON `mysql`.* TO 'r4' GRANT INSERT ON `mysql`.* TO 'r1' GRANT UPDATE ON `mysql`.`user` TO 'r3' GRANT USAGE ON *.* TO 'r1' GRANT USAGE ON *.* TO 'r2' GRANT USAGE ON *.* TO 'r3' -GRANT USAGE ON *.* TO 'r4' GRANT r2 TO 'r1' GRANT r3 TO 'r2' -GRANT r4 TO 'r1' -GRANT r4 TO 'r3' show grants for r2; Grants for r2 GRANT DELETE ON `mysql`.`roles_mapping` TO 'r2' GRANT EXECUTE ON FUNCTION `mysql`.`test_func` TO 'r2' GRANT EXECUTE ON PROCEDURE `mysql`.`test_proc` TO 'r3' -GRANT EXECUTE ON `mysql`.* TO 'r4' GRANT UPDATE ON `mysql`.`user` TO 'r3' GRANT USAGE ON *.* TO 'r2' GRANT USAGE ON *.* TO 'r3' -GRANT USAGE ON *.* TO 'r4' GRANT r3 TO 'r2' -GRANT r4 TO 'r3' show grants for r3; Grants for r3 GRANT EXECUTE ON PROCEDURE `mysql`.`test_proc` TO 'r3' -GRANT EXECUTE ON `mysql`.* TO 'r4' GRANT UPDATE ON `mysql`.`user` TO 'r3' GRANT USAGE ON *.* TO 'r3' -GRANT USAGE ON *.* TO 'r4' -GRANT r4 TO 'r3' -show grants for r4; -Grants for r4 -GRANT EXECUTE ON `mysql`.* TO 'r4' -GRANT USAGE ON *.* TO 'r4' drop function mysql.test_func; -Warnings: -Warning 1403 There is no such grant defined for user 'r1' on host '' on routine 'test_func' -Warning 1403 There is no such grant defined for user 'r1' on host '' on routine 'test_func' drop procedure mysql.test_proc; -Warnings: -Warning 1403 There is no such grant defined for user 'r2' on host '' on routine 'test_proc' -Warning 1403 There is no such grant defined for user 'r1' on host '' on routine 'test_proc' -Warning 1403 There is no such grant defined for user 'r2' on host '' on routine 'test_proc' -Warning 1403 There is no such grant defined for user 'r1' on host '' on routine 'test_proc' -show grants for r1; -Grants for r1 +create function mysql.test_func (s CHAR(20)) +returns CHAR(50) DETERMINISTIC +return concat('Test string: ',s); +show grants for r2; +Grants for r2 GRANT DELETE ON `mysql`.`roles_mapping` TO 'r2' -GRANT EXECUTE ON `mysql`.* TO 'r4' -GRANT INSERT ON `mysql`.* TO 'r1' GRANT UPDATE ON `mysql`.`user` TO 'r3' -GRANT USAGE ON *.* TO 'r1' GRANT USAGE ON *.* TO 'r2' GRANT USAGE ON *.* TO 'r3' -GRANT USAGE ON *.* TO 'r4' -GRANT r2 TO 'r1' GRANT r3 TO 'r2' -GRANT r4 TO 'r1' -GRANT r4 TO 'r3' -drop role r1, r2, r3, r4; +select mysql.test_func("none"); +ERROR 42000: execute command denied to user 'u1'@'%' for routine 'mysql.test_func' +set role r1; +select mysql.test_func("r1"); +ERROR 42000: execute command denied to user 'u1'@'%' for routine 'mysql.test_func' +drop function mysql.test_func; +drop role r1, r2, r3; drop user u1; diff --git a/mysql-test/suite/roles/drop_routines.test b/mysql-test/suite/roles/drop_routines.test index 78f2039f55a..b5972d8d9f9 100644 --- a/mysql-test/suite/roles/drop_routines.test +++ b/mysql-test/suite/roles/drop_routines.test @@ -3,15 +3,12 @@ source include/not_embedded.inc; create role r1; create role r2; create role r3; -create role r4; create user u1; #CREATE A CHAIN OF ROLES grant r2 to r1; grant r3 to r2; -grant r4 to r3; grant r1 to u1; -grant r4 to r1; --sorted_result show grants for u1; @@ -27,7 +24,6 @@ create function mysql.test_func (s CHAR(20)) returns CHAR(50) DETERMINISTIC return concat('Test string: ',s); - delimiter |; create procedure mysql.test_proc (OUT param1 INT) begin @@ -37,7 +33,9 @@ delimiter ;| grant execute on function mysql.test_func to r2; grant execute on procedure mysql.test_proc to r3; -grant execute on mysql.* to r4; + +--error ER_NONEXISTING_PROC_GRANT +revoke execute on procedure mysql.test_proc from r2; --sorted_result show grants for r1; @@ -45,17 +43,27 @@ show grants for r1; show grants for r2; --sorted_result show grants for r3; ---sorted_result -show grants for r4; drop function mysql.test_func; drop procedure mysql.test_proc; -# HERE there are func_priv_hash and proc_priv hash entries inherited from other roles that are not -# deleted. These remain and could affect privilege checks +create function mysql.test_func (s CHAR(20)) +returns CHAR(50) DETERMINISTIC +return concat('Test string: ',s); --sorted_result -show grants for r1; +show grants for r2; -drop role r1, r2, r3, r4; +--connect (u1,localhost,u1,,) + +--error ER_PROCACCESS_DENIED_ERROR +select mysql.test_func("none"); +set role r1; +--error ER_PROCACCESS_DENIED_ERROR +select mysql.test_func("r1"); + +connection default; + +drop function mysql.test_func; +drop role r1, r2, r3; drop user u1; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 94c880a6848..ffb5e80a0dd 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -4334,6 +4334,7 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, int old_row_exists= 1; int error=0; ulong store_proc_rights; + HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash; DBUG_ENTER("replace_routine_table"); if (!initialized) @@ -4342,6 +4343,12 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, DBUG_RETURN(-1); } + if (revoke_grant && !grant_name->init_privs) // only inherited role privs + { + my_hash_delete(hash, (uchar*) grant_name); + DBUG_RETURN(0); + } + get_grantor(thd, grantor); /* New users are created before this function is called. @@ -4433,8 +4440,7 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, } else { - my_hash_delete(is_proc ? &proc_priv_hash : &func_priv_hash,(uchar*) - grant_name); + my_hash_delete(hash, (uchar*) grant_name); } DBUG_RETURN(0); @@ -5685,7 +5691,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, grant_name= routine_hash_search(Str->host.str, NullS, db_name, Str->user.str, table_name, is_proc, 1); - if (!grant_name) + if (!grant_name || !grant_name->init_privs) { if (revoke_grant) { @@ -9435,10 +9441,6 @@ bool mysql_revoke_all(THD *thd, List &list) if (!strcmp(lex_user->user.str,user) && !strcmp(lex_user->host.str, host)) { - /* only inherited rights, nothing to do here */ - if (!grant_proc->init_privs) - continue; - if (replace_routine_table(thd,grant_proc,tables[4].table,*lex_user, grant_proc->db, grant_proc->tname,