Commit 2eed3b7d authored by Vicențiu Ciorbaru's avatar Vicențiu Ciorbaru Committed by Sergei Golubchik

Implemented REVOKE ALL FROM for Roles and role grants.

parent 65eee0be
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'@'%'
GRANT r1 TO 'u1'@'%'
show grants for r1;
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;
grant UPDATE on mysql.user to r3;
create function mysql.test_func (s CHAR(20))
returns CHAR(50) DETERMINISTIC
return concat('Test string: ',s);
create procedure mysql.test_proc (OUT param1 INT)
begin
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;
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
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;
drop user u1;
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;
--sorted_result
show grants for r1;
grant SELECT on *.* to u1;
grant INSERT on mysql.* to r1;
grant DELETE on mysql.roles_mapping to r2;
grant UPDATE on mysql.user to r3;
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
select COUNT(*) into param1 from mysql.roles_mapping;
end|
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;
--sorted_result
show grants for r1;
--sorted_result
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
--sorted_result
show grants for r1;
drop role r1, r2, r3, r4;
drop user u1;
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'@'%'
GRANT r1 TO 'u1'@'%'
show grants for r1;
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;
grant UPDATE on mysql.user to r3;
create function mysql.test_func (s CHAR(20))
returns CHAR(50) DETERMINISTIC
return concat('Test string: ',s);
create procedure mysql.test_proc (OUT param1 INT)
begin
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;
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'
revoke all privileges, grant option from r4;
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 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 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 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 USAGE ON *.* TO 'r4'
revoke all privileges, grant option from r3;
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 INSERT ON `mysql`.* TO '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'
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 USAGE ON *.* TO 'r2'
GRANT USAGE ON *.* TO 'r3'
GRANT r3 TO 'r2'
show grants for r3;
Grants for r3
GRANT USAGE ON *.* TO 'r3'
show grants for r4;
Grants for r4
GRANT USAGE ON *.* TO 'r4'
revoke all privileges, grant option from r2;
show grants for r1;
Grants for r1
GRANT INSERT ON `mysql`.* TO 'r1'
GRANT USAGE ON *.* TO 'r1'
GRANT USAGE ON *.* TO 'r2'
GRANT USAGE ON *.* TO 'r4'
GRANT r2 TO 'r1'
GRANT r4 TO 'r1'
show grants for r2;
Grants for r2
GRANT USAGE ON *.* TO 'r2'
show grants for r3;
Grants for r3
GRANT USAGE ON *.* TO 'r3'
show grants for r4;
Grants for r4
GRANT USAGE ON *.* TO 'r4'
revoke all privileges, grant option from r1;
show grants for r1;
Grants for r1
GRANT USAGE ON *.* TO 'r1'
show grants for r2;
Grants for r2
GRANT USAGE ON *.* TO 'r2'
show grants for r3;
Grants for r3
GRANT USAGE ON *.* TO 'r3'
show grants for r4;
Grants for r4
GRANT USAGE ON *.* TO 'r4'
revoke all privileges, grant option from u1;
show grants for u1;
Grants for u1@%
GRANT USAGE ON *.* TO 'u1'@'%'
drop function mysql.test_func;
drop procedure mysql.test_proc;
show grants for r1;
Grants for r1
GRANT USAGE ON *.* TO 'r1'
drop role r1, r2, r3, r4;
drop user u1;
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;
--sorted_result
show grants for r1;
grant SELECT on *.* to u1;
grant INSERT on mysql.* to r1;
grant DELETE on mysql.roles_mapping to r2;
grant UPDATE on mysql.user to r3;
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
select COUNT(*) into param1 from mysql.roles_mapping;
end|
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;
--sorted_result
show grants for r1;
--sorted_result
show grants for r2;
--sorted_result
show grants for r3;
--sorted_result
show grants for r4;
revoke all privileges, grant option from r4;
--sorted_result
show grants for r1;
--sorted_result
show grants for r2;
--sorted_result
show grants for r3;
--sorted_result
show grants for r4;
revoke all privileges, grant option from r3;
--sorted_result
show grants for r1;
--sorted_result
show grants for r2;
--sorted_result
show grants for r3;
--sorted_result
show grants for r4;
revoke all privileges, grant option from r2;
--sorted_result
show grants for r1;
--sorted_result
show grants for r2;
--sorted_result
show grants for r3;
--sorted_result
show grants for r4;
revoke all privileges, grant option from r1;
--sorted_result
show grants for r1;
--sorted_result
show grants for r2;
--sorted_result
show grants for r3;
--sorted_result
show grants for r4;
revoke all privileges, grant option from u1;
show grants for u1;
drop function mysql.test_func;
drop procedure mysql.test_proc;
--sorted_result
show grants for r1;
drop role r1, r2, r3, r4;
drop user u1;
...@@ -2385,7 +2385,7 @@ static bool add_role_user_mapping(const char *uname, const char *hname, ...@@ -2385,7 +2385,7 @@ static bool add_role_user_mapping(const char *uname, const char *hname,
/* /*
This helper function is used to removes roles and grantees This helper function is used to removes roles and grantees
from the corresponding cross-reference arrays. see remove_role_user_mapping(). from the corresponding cross-reference arrays. see remove_role_user_mapping().
as such, it asserts that a element to delete is present in the array, as such, it asserts that an element to delete is present in the array,
and is present only once. and is present only once.
*/ */
static void remove_ptr_from_dynarray(DYNAMIC_ARRAY *array, void *ptr) static void remove_ptr_from_dynarray(DYNAMIC_ARRAY *array, void *ptr)
...@@ -4371,6 +4371,9 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, ...@@ -4371,6 +4371,9 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name,
The following should never happen as we first check the in memory The following should never happen as we first check the in memory
grant tables for the user. There is however always a small change that grant tables for the user. There is however always a small change that
the user has modified the grant tables directly. the user has modified the grant tables directly.
Also, there is also a second posibility that this routine entry
is created for a role by being inherited from a granted role.
*/ */
if (revoke_grant) if (revoke_grant)
{ // no row, no revoke { // no row, no revoke
...@@ -9323,7 +9326,10 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) ...@@ -9323,7 +9326,10 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
result= -1; result= -1;
continue; continue;
} }
if (!find_user_exact(lex_user->host.str, lex_user->user.str))
/* This is not a role and the user could not be found */
if (!lex_user->is_role() &&
!find_user_exact(lex_user->host.str, lex_user->user.str))
{ {
result= -1; result= -1;
continue; continue;
...@@ -9429,6 +9435,10 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) ...@@ -9429,6 +9435,10 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
if (!strcmp(lex_user->user.str,user) && if (!strcmp(lex_user->user.str,user) &&
!strcmp(lex_user->host.str, host)) !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, if (replace_routine_table(thd,grant_proc,tables[4].table,*lex_user,
grant_proc->db, grant_proc->db,
grant_proc->tname, grant_proc->tname,
...@@ -9443,6 +9453,59 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) ...@@ -9443,6 +9453,59 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
counter++; counter++;
} }
} while (revoked); } while (revoked);
ACL_USER_BASE *user_or_role;
/* remove role grants */
if (lex_user->is_role())
{
/* this can not fail due to get_current_user already having searched for it */
user_or_role= find_acl_role(lex_user->user.str);
}
else
{
user_or_role= find_user_exact(lex_user->host.str, lex_user->user.str);
}
/*
Find every role grant pair matching the role_grants array and remove it,
both from the acl_roles_mappings and the roles_mapping table
*/
for (counter= 0; counter < user_or_role->role_grants.elements; counter++)
{
ACL_ROLE *role_grant= *dynamic_element(&user_or_role->role_grants,
counter, ACL_ROLE**);
ROLE_GRANT_PAIR *pair = find_role_grant_pair(&lex_user->user,
&lex_user->host,
&role_grant->user);
if (replace_roles_mapping_table(tables[6].table,
&lex_user->user,
&lex_user->host,
&role_grant->user, false, pair, true))
{
result= -1; //Something went wrong
}
/*
Delete from the parent_grantee array of the roles granted,
the entry pointing to this user_or_role
*/
remove_ptr_from_dynarray(&role_grant->parent_grantee, user_or_role);
}
/* TODO
How to handle an error in the replace_roles_mapping_table, in
regards to the privileges held in memory
*/
/* Finally, clear the role_grants array */
if (counter == user_or_role->role_grants.elements)
{
reset_dynamic(&user_or_role->role_grants);
}
/*
If we are revoking from a role, we need to update all the parent grantees
*/
if (lex_user->is_role())
{
propagate_role_grants((ACL_ROLE *)user_or_role, PRIVS_TO_MERGE::ALL, 0, 0);
}
} }
mysql_mutex_unlock(&acl_cache->lock); mysql_mutex_unlock(&acl_cache->lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment