Commit 3e3d6271 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-5771 Privileges acquired via roles depend on the order of granting

GRANT ROLE: don't forget to propagate privileges from granted role to a grantee
parent ee9d0f46
create database mysqltest1;
create database mysqltest2;
create role r1, r2;
grant all on mysqltest1.* to r1;
grant all on mysqltest2.* to r2;
grant r1 to r2;
grant r2 to foo@localhost;
select current_user;
current_user
foo@localhost
show tables in mysqltest1;
ERROR 42000: Access denied for user 'foo'@'localhost' to database 'mysqltest1'
show tables in mysqltest2;
ERROR 42000: Access denied for user 'foo'@'localhost' to database 'mysqltest2'
set role r2;
show tables in mysqltest1;
Tables_in_mysqltest1
show tables in mysqltest2;
Tables_in_mysqltest2
show grants;
Grants for foo@localhost
GRANT r2 TO 'foo'@'localhost'
GRANT USAGE ON *.* TO 'foo'@'localhost'
GRANT r1 TO 'r2'
GRANT USAGE ON *.* TO 'r2'
GRANT ALL PRIVILEGES ON `mysqltest2`.* TO 'r2'
GRANT USAGE ON *.* TO 'r1'
GRANT ALL PRIVILEGES ON `mysqltest1`.* TO 'r1'
drop user foo@localhost;
drop role r1;
drop role r2;
drop database mysqltest1;
drop database mysqltest2;
#
# MDEV-5771 Privileges acquired via roles depend on the order of granting
#
--source include/not_embedded.inc
create database mysqltest1;
create database mysqltest2;
create role r1, r2;
grant all on mysqltest1.* to r1;
grant all on mysqltest2.* to r2;
grant r1 to r2;
grant r2 to foo@localhost;
--connect (foo,localhost,foo,,)
select current_user;
--error ER_DBACCESS_DENIED_ERROR
show tables in mysqltest1;
--error ER_DBACCESS_DENIED_ERROR
show tables in mysqltest2;
set role r2;
show tables in mysqltest1;
show tables in mysqltest2;
show grants;
connection default;
drop user foo@localhost;
drop role r1;
drop role r2;
drop database mysqltest1;
drop database mysqltest2;
...@@ -46,7 +46,7 @@ role9 role6 NO ...@@ -46,7 +46,7 @@ role9 role6 NO
role9 role7 NO role9 role7 NO
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 0 Debug_role_merges_global 11
Debug_role_merges_db 0 Debug_role_merges_db 0
Debug_role_merges_table 0 Debug_role_merges_table 0
Debug_role_merges_column 0 Debug_role_merges_column 0
...@@ -54,7 +54,7 @@ Debug_role_merges_routine 0 ...@@ -54,7 +54,7 @@ Debug_role_merges_routine 0
grant select on *.* to role1; grant select on *.* to role1;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 8 Debug_role_merges_global 19
Debug_role_merges_db 0 Debug_role_merges_db 0
Debug_role_merges_table 0 Debug_role_merges_table 0
Debug_role_merges_column 0 Debug_role_merges_column 0
...@@ -102,7 +102,7 @@ role9 ...@@ -102,7 +102,7 @@ role9
revoke select on *.* from role1; revoke select on *.* from role1;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 0 Debug_role_merges_db 0
Debug_role_merges_table 0 Debug_role_merges_table 0
Debug_role_merges_column 0 Debug_role_merges_column 0
...@@ -118,7 +118,7 @@ set role none; ...@@ -118,7 +118,7 @@ set role none;
grant select on mysql.* to role1; grant select on mysql.* to role1;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 8 Debug_role_merges_db 8
Debug_role_merges_table 0 Debug_role_merges_table 0
Debug_role_merges_column 0 Debug_role_merges_column 0
...@@ -156,7 +156,7 @@ GRANT role9 TO 'role10' ...@@ -156,7 +156,7 @@ GRANT role9 TO 'role10'
revoke select on mysql.* from role1; revoke select on mysql.* from role1;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 16 Debug_role_merges_db 16
Debug_role_merges_table 0 Debug_role_merges_table 0
Debug_role_merges_column 0 Debug_role_merges_column 0
...@@ -167,7 +167,7 @@ set role none; ...@@ -167,7 +167,7 @@ set role none;
grant select on mysql.roles_mapping to role1; grant select on mysql.roles_mapping to role1;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 16 Debug_role_merges_db 16
Debug_role_merges_table 8 Debug_role_merges_table 8
Debug_role_merges_column 0 Debug_role_merges_column 0
...@@ -205,7 +205,7 @@ GRANT role9 TO 'role10' ...@@ -205,7 +205,7 @@ GRANT role9 TO 'role10'
revoke select on mysql.roles_mapping from role1; revoke select on mysql.roles_mapping from role1;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 16 Debug_role_merges_db 16
Debug_role_merges_table 16 Debug_role_merges_table 16
Debug_role_merges_column 0 Debug_role_merges_column 0
...@@ -216,7 +216,7 @@ set role none; ...@@ -216,7 +216,7 @@ set role none;
grant select(User) on mysql.roles_mapping to role1; grant select(User) on mysql.roles_mapping to role1;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 16 Debug_role_merges_db 16
Debug_role_merges_table 24 Debug_role_merges_table 24
Debug_role_merges_column 8 Debug_role_merges_column 8
...@@ -256,7 +256,7 @@ GRANT role9 TO 'role10' ...@@ -256,7 +256,7 @@ GRANT role9 TO 'role10'
grant select(Host) on mysql.roles_mapping to role3; grant select(Host) on mysql.roles_mapping to role3;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 16 Debug_role_merges_db 16
Debug_role_merges_table 30 Debug_role_merges_table 30
Debug_role_merges_column 14 Debug_role_merges_column 14
...@@ -294,7 +294,7 @@ GRANT role9 TO 'role10' ...@@ -294,7 +294,7 @@ GRANT role9 TO 'role10'
revoke select(User) on mysql.roles_mapping from role1; revoke select(User) on mysql.roles_mapping from role1;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 16 Debug_role_merges_db 16
Debug_role_merges_table 38 Debug_role_merges_table 38
Debug_role_merges_column 22 Debug_role_merges_column 22
...@@ -307,7 +307,7 @@ count(concat(Host)) ...@@ -307,7 +307,7 @@ count(concat(Host))
revoke select(Host) on mysql.roles_mapping from role3; revoke select(Host) on mysql.roles_mapping from role3;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 16 Debug_role_merges_db 16
Debug_role_merges_table 44 Debug_role_merges_table 44
Debug_role_merges_column 28 Debug_role_merges_column 28
...@@ -320,7 +320,7 @@ create function fn1() returns char(10) return "fn1"; ...@@ -320,7 +320,7 @@ create function fn1() returns char(10) return "fn1";
grant execute on procedure test.pr1 to role1; grant execute on procedure test.pr1 to role1;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 16 Debug_role_merges_db 16
Debug_role_merges_table 44 Debug_role_merges_table 44
Debug_role_merges_column 28 Debug_role_merges_column 28
...@@ -336,7 +336,7 @@ ERROR 42000: execute command denied to user 'foo'@'localhost' for routine 'test. ...@@ -336,7 +336,7 @@ ERROR 42000: execute command denied to user 'foo'@'localhost' for routine 'test.
grant execute on function test.fn1 to role5; grant execute on function test.fn1 to role5;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 16 Debug_role_merges_db 16
Debug_role_merges_table 44 Debug_role_merges_table 44
Debug_role_merges_column 28 Debug_role_merges_column 28
...@@ -347,7 +347,7 @@ fn1 ...@@ -347,7 +347,7 @@ fn1
revoke execute on procedure test.pr1 from role1; revoke execute on procedure test.pr1 from role1;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 16 Debug_role_merges_db 16
Debug_role_merges_table 44 Debug_role_merges_table 44
Debug_role_merges_column 28 Debug_role_merges_column 28
...@@ -360,7 +360,7 @@ fn1 ...@@ -360,7 +360,7 @@ fn1
revoke execute on function test.fn1 from role5; revoke execute on function test.fn1 from role5;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 16 Debug_role_merges_db 16
Debug_role_merges_table 44 Debug_role_merges_table 44
Debug_role_merges_column 28 Debug_role_merges_column 28
...@@ -373,7 +373,7 @@ drop function fn1; ...@@ -373,7 +373,7 @@ drop function fn1;
grant select on mysql.roles_mapping to role3; grant select on mysql.roles_mapping to role3;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 16 Debug_role_merges_db 16
Debug_role_merges_table 50 Debug_role_merges_table 50
Debug_role_merges_column 28 Debug_role_merges_column 28
...@@ -381,7 +381,7 @@ Debug_role_merges_routine 26 ...@@ -381,7 +381,7 @@ Debug_role_merges_routine 26
grant select on mysql.roles_mapping to role1; grant select on mysql.roles_mapping to role1;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 16 Debug_role_merges_db 16
Debug_role_merges_table 53 Debug_role_merges_table 53
Debug_role_merges_column 28 Debug_role_merges_column 28
...@@ -389,7 +389,7 @@ Debug_role_merges_routine 26 ...@@ -389,7 +389,7 @@ Debug_role_merges_routine 26
revoke select on mysql.roles_mapping from role3; revoke select on mysql.roles_mapping from role3;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 16 Debug_role_merges_db 16
Debug_role_merges_table 54 Debug_role_merges_table 54
Debug_role_merges_column 28 Debug_role_merges_column 28
...@@ -397,7 +397,7 @@ Debug_role_merges_routine 26 ...@@ -397,7 +397,7 @@ Debug_role_merges_routine 26
revoke select on mysql.roles_mapping from role1; revoke select on mysql.roles_mapping from role1;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 16 Debug_role_merges_db 16
Debug_role_merges_table 62 Debug_role_merges_table 62
Debug_role_merges_column 28 Debug_role_merges_column 28
...@@ -405,7 +405,7 @@ Debug_role_merges_routine 26 ...@@ -405,7 +405,7 @@ Debug_role_merges_routine 26
grant select on mysql.* to role1; grant select on mysql.* to role1;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 24 Debug_role_merges_db 24
Debug_role_merges_table 62 Debug_role_merges_table 62
Debug_role_merges_column 28 Debug_role_merges_column 28
...@@ -413,7 +413,7 @@ Debug_role_merges_routine 26 ...@@ -413,7 +413,7 @@ Debug_role_merges_routine 26
grant select on test.* to role1; grant select on test.* to role1;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 32 Debug_role_merges_db 32
Debug_role_merges_table 62 Debug_role_merges_table 62
Debug_role_merges_column 28 Debug_role_merges_column 28
...@@ -421,7 +421,7 @@ Debug_role_merges_routine 26 ...@@ -421,7 +421,7 @@ Debug_role_merges_routine 26
revoke select on mysql.* from role1; revoke select on mysql.* from role1;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 40 Debug_role_merges_db 40
Debug_role_merges_table 62 Debug_role_merges_table 62
Debug_role_merges_column 28 Debug_role_merges_column 28
...@@ -429,7 +429,7 @@ Debug_role_merges_routine 26 ...@@ -429,7 +429,7 @@ Debug_role_merges_routine 26
revoke select on test.* from role1; revoke select on test.* from role1;
show status like 'debug%'; show status like 'debug%';
Variable_name Value Variable_name Value
Debug_role_merges_global 16 Debug_role_merges_global 27
Debug_role_merges_db 48 Debug_role_merges_db 48
Debug_role_merges_table 62 Debug_role_merges_table 62
Debug_role_merges_column 28 Debug_role_merges_column 28
......
...@@ -5321,6 +5321,13 @@ static int merge_role_privileges(ACL_ROLE *role __attribute__((unused)), ...@@ -5321,6 +5321,13 @@ static int merge_role_privileges(ACL_ROLE *role __attribute__((unused)),
return !changed; // don't recurse into the subgraph if privs didn't change return !changed; // don't recurse into the subgraph if privs didn't change
} }
static bool merge_one_role_privileges(ACL_ROLE *grantee)
{
PRIVS_TO_MERGE data= { PRIVS_TO_MERGE::ALL, 0, 0 };
grantee->counter= 1;
return merge_role_privileges(0, grantee, &data);
}
/***************************************************************** /*****************************************************************
End of the role privilege propagation and graph traversal code End of the role privilege propagation and graph traversal code
******************************************************************/ ******************************************************************/
...@@ -6083,8 +6090,8 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke) ...@@ -6083,8 +6090,8 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
Only need to propagate grants when granting/revoking a role to/from Only need to propagate grants when granting/revoking a role to/from
a role a role
*/ */
if (role_as_user) if (role_as_user && merge_one_role_privileges(role_as_user) == 0)
propagate_role_grants(role_as_user, PRIVS_TO_MERGE::ALL, 0, 0); propagate_role_grants(role_as_user, PRIVS_TO_MERGE::ALL);
} }
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