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,
/*
This helper function is used to removes roles and grantees
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.
*/
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,
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
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)
{ // no row, no revoke
......@@ -9323,7 +9326,10 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
result= -1;
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;
continue;
......@@ -9429,6 +9435,10 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &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,
......@@ -9443,6 +9453,59 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
counter++;
}
} 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);
......
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