diff --git a/mysql-test/r/acl_roles_set_role-multiple-role.result b/mysql-test/r/acl_roles_set_role-multiple-role.result index 680d50de7fd..ffb0255b045 100644 --- a/mysql-test/r/acl_roles_set_role-multiple-role.result +++ b/mysql-test/r/acl_roles_set_role-multiple-role.result @@ -62,10 +62,24 @@ ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'ro show grants; Grants for test_user@localhost GRANT USAGE ON *.* TO 'test_user'@'localhost' +GRANT r_crt TO 'test_user'@'localhost' +GRANT r_del TO 'test_user'@'localhost' +GRANT r_drp TO 'test_user'@'localhost' +GRANT r_ins TO 'test_user'@'localhost' +GRANT r_rld TO 'test_user'@'localhost' +GRANT r_sel TO 'test_user'@'localhost' +GRANT r_upd TO 'test_user'@'localhost' set role r_sel; show grants; Grants for test_user@localhost GRANT USAGE ON *.* TO 'test_user'@'localhost' +GRANT r_crt TO 'test_user'@'localhost' +GRANT r_del TO 'test_user'@'localhost' +GRANT r_drp TO 'test_user'@'localhost' +GRANT r_ins TO 'test_user'@'localhost' +GRANT r_rld TO 'test_user'@'localhost' +GRANT r_sel TO 'test_user'@'localhost' +GRANT r_upd TO 'test_user'@'localhost' select * from mysql.roles_mapping; HostFk UserFk RoleFk localhost test_user r_crt @@ -79,6 +93,13 @@ set role r_ins; show grants; Grants for test_user@localhost GRANT USAGE ON *.* TO 'test_user'@'localhost' +GRANT r_crt TO 'test_user'@'localhost' +GRANT r_del TO 'test_user'@'localhost' +GRANT r_drp TO 'test_user'@'localhost' +GRANT r_ins TO 'test_user'@'localhost' +GRANT r_rld TO 'test_user'@'localhost' +GRANT r_sel TO 'test_user'@'localhost' +GRANT r_upd TO 'test_user'@'localhost' select * from mysql.roles_mapping; ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'roles_mapping' insert into mysql.roles_mapping (HostFk, UserFk, RoleFk) values ('', diff --git a/mysql-test/r/acl_roles_set_role-recursive.result b/mysql-test/r/acl_roles_set_role-recursive.result index e7ebd77fbb0..6661ed0058e 100644 --- a/mysql-test/r/acl_roles_set_role-recursive.result +++ b/mysql-test/r/acl_roles_set_role-recursive.result @@ -34,49 +34,59 @@ ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'ro show grants; Grants for test_user@localhost GRANT USAGE ON *.* TO 'test_user'@'localhost' +GRANT test_role1 TO 'test_user'@'localhost' set role test_role1; show grants; Grants for test_user@localhost GRANT USAGE ON *.* TO 'test_user'@'localhost' +GRANT test_role1 TO 'test_user'@'localhost' select * from mysql.roles_mapping where HostFk=''; HostFk UserFk RoleFk test_role1 test_role2 show grants; Grants for test_user@localhost GRANT USAGE ON *.* TO 'test_user'@'localhost' +GRANT test_role1 TO 'test_user'@'localhost' set role none; show grants; Grants for test_user@localhost GRANT USAGE ON *.* TO 'test_user'@'localhost' +GRANT test_role1 TO 'test_user'@'localhost' select * from mysql.roles_mapping; ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'roles_mapping' show grants; Grants for test_user@localhost GRANT USAGE ON *.* TO 'test_user'@'localhost' +GRANT test_role1 TO 'test_user'@'localhost' set role test_role2; ERROR HY000: The role 'test_role2' has not been granted or is invalid. show grants; Grants for test_user@localhost GRANT USAGE ON *.* TO 'test_user'@'localhost' +GRANT test_role1 TO 'test_user'@'localhost' select * from mysql.roles_mapping; ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'roles_mapping' show grants; Grants for test_user@localhost GRANT USAGE ON *.* TO 'test_user'@'localhost' +GRANT test_role1 TO 'test_user'@'localhost' set role test_role1; show grants; Grants for test_user@localhost GRANT USAGE ON *.* TO 'test_user'@'localhost' +GRANT test_role1 TO 'test_user'@'localhost' select * from mysql.roles_mapping where HostFk=''; HostFk UserFk RoleFk test_role1 test_role2 show grants; Grants for test_user@localhost GRANT USAGE ON *.* TO 'test_user'@'localhost' +GRANT test_role1 TO 'test_user'@'localhost' set role none; show grants; Grants for test_user@localhost GRANT USAGE ON *.* TO 'test_user'@'localhost' +GRANT test_role1 TO 'test_user'@'localhost' select * from mysql.roles_mapping; ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'roles_mapping' delete from mysql.user where user='test_role1'; diff --git a/mysql-test/r/acl_roles_set_role-simple.result b/mysql-test/r/acl_roles_set_role-simple.result index 4b2cbdec28d..11ed783e02f 100644 --- a/mysql-test/r/acl_roles_set_role-simple.result +++ b/mysql-test/r/acl_roles_set_role-simple.result @@ -21,10 +21,12 @@ ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'ro show grants; Grants for test_user@localhost GRANT USAGE ON *.* TO 'test_user'@'localhost' +GRANT test_role1 TO 'test_user'@'localhost' set role test_role1; show grants; Grants for test_user@localhost GRANT USAGE ON *.* TO 'test_user'@'localhost' +GRANT test_role1 TO 'test_user'@'localhost' select * from mysql.roles_mapping; HostFk UserFk RoleFk localhost test_user test_role1 diff --git a/mysql-test/t/acl_roles_set_role-multiple-role.test b/mysql-test/t/acl_roles_set_role-multiple-role.test index 0e47100ffb6..3d5de6bd7fc 100644 --- a/mysql-test/t/acl_roles_set_role-multiple-role.test +++ b/mysql-test/t/acl_roles_set_role-multiple-role.test @@ -57,13 +57,16 @@ change_user 'test_user'; --error ER_TABLEACCESS_DENIED_ERROR select * from mysql.roles_mapping; +--sorted_result show grants; set role r_sel; +--sorted_result show grants; --sorted_result select * from mysql.roles_mapping; set role r_ins; +--sorted_result show grants; --error ER_TABLEACCESS_DENIED_ERROR select * from mysql.roles_mapping; diff --git a/mysql-test/t/acl_roles_set_role-recursive.test b/mysql-test/t/acl_roles_set_role-recursive.test index 9bf8bdaf8e9..0a7ba637c85 100644 --- a/mysql-test/t/acl_roles_set_role-recursive.test +++ b/mysql-test/t/acl_roles_set_role-recursive.test @@ -15,11 +15,16 @@ insert into mysql.roles_mapping (HostFk, UserFk, RoleFk) values ('', 'test_role2'); flush privileges; +--sorted_result select user, host from mysql.user where user not like 'root'; +--sorted_result select * from mysql.roles_mapping where UserFk like 'test_user'; +--sorted_result select * from mysql.roles_mapping where UserFk like 'test_role1'; grant select on *.* to 'test_role2'@''; +--sorted_result select * from mysql.user where user like 'test_role1'; +--sorted_result select * from mysql.user where user like 'test_role2'; flush privileges; @@ -28,32 +33,43 @@ change_user 'test_user'; --error ER_TABLEACCESS_DENIED_ERROR select * from mysql.roles_mapping; +--sorted_result show grants; set role test_role1; +--sorted_result show grants; select * from mysql.roles_mapping where HostFk=''; +--sorted_result show grants; set role none; +--sorted_result show grants; --error ER_TABLEACCESS_DENIED_ERROR select * from mysql.roles_mapping; +--sorted_result show grants; --error ER_INVALID_ROLE set role test_role2; +--sorted_result show grants; --error ER_TABLEACCESS_DENIED_ERROR select * from mysql.roles_mapping; #Make sure that this still works after an ER_INVALID_ROLE error +--sorted_result show grants; set role test_role1; +--sorted_result show grants; +--sorted_result select * from mysql.roles_mapping where HostFk=''; +--sorted_result show grants; set role none; +--sorted_result show grants; --error ER_TABLEACCESS_DENIED_ERROR select * from mysql.roles_mapping; diff --git a/mysql-test/t/acl_roles_set_role-simple.test b/mysql-test/t/acl_roles_set_role-simple.test index 048b6916d83..b09bbc02b97 100644 --- a/mysql-test/t/acl_roles_set_role-simple.test +++ b/mysql-test/t/acl_roles_set_role-simple.test @@ -7,9 +7,12 @@ update mysql.user set is_role='Y' where user='test_role1'; insert into mysql.roles_mapping (HostFk, UserFk, RoleFk) values ('localhost', 'test_user', 'test_role1'); +--sorted_result select user, host from mysql.user where user not like 'root'; +--sorted_result select * from mysql.roles_mapping; grant select on *.* to 'test_role1'@''; +--sorted_result select * from mysql.user where user='test_role1'; flush privileges; @@ -18,9 +21,12 @@ change_user 'test_user'; --error ER_TABLEACCESS_DENIED_ERROR select * from mysql.roles_mapping; +--sorted_result show grants; set role test_role1; +--sorted_result show grants; +--sorted_result select * from mysql.roles_mapping; set role none; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 79bf2544629..9041e2c49c1 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -309,6 +309,9 @@ static bool compare_hostname(const acl_host_and_ip *host, const char *hostname, const char *ip); static bool show_proxy_grants (THD *thd, LEX_USER *user, char *buff, size_t buffsize); +static bool show_role_grants(THD *thd, LEX_USER *lex_user, + ACL_USER_BASE *acl_entry, + char *buff, size_t buffsize); static bool show_global_privileges(THD *thd, LEX_USER *lex_user, ACL_USER_BASE *acl_entry, bool handle_as_role, char *buff, size_t buffsize); @@ -6300,6 +6303,13 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) DBUG_RETURN(TRUE); } + /* Show granted roles to acl_user */ + if (show_role_grants(thd, lex_user, acl_user, buff, sizeof(buff))) + { + error= -1; + goto end; + } + /* Add first global access grants */ if (show_global_privileges(thd, lex_user, acl_user, FALSE, buff, sizeof(buff))) { @@ -6349,6 +6359,42 @@ end: DBUG_RETURN(error); } +static bool show_role_grants(THD *thd, LEX_USER *lex_user, + ACL_USER_BASE *acl_entry, + char *buff, size_t buffsize) +{ + uint counter; + Protocol *protocol= thd->protocol; + + String grant(buff,sizeof(buff),system_charset_info); + for (counter= 0; counter < acl_entry->role_grants.elements; counter++) + { + grant.length(0); + grant.append(STRING_WITH_LEN("GRANT ")); + ACL_ROLE *acl_role= *(dynamic_element(&acl_entry->role_grants, counter, + ACL_ROLE**)); + grant.append(acl_role->user.str, acl_role->user.length, + system_charset_info); + grant.append(STRING_WITH_LEN(" TO '")); + grant.append(lex_user->user.str, lex_user->user.length, + system_charset_info); + if (!(acl_entry->flags & IS_ROLE)) + { + grant.append(STRING_WITH_LEN("'@'")); + grant.append(lex_user->host.str, lex_user->host.length, + system_charset_info); + } + grant.append('\''); + protocol->prepare_for_resend(); + protocol->store(grant.ptr(),grant.length(),grant.charset()); + if (protocol->write()) + { + return TRUE; + } + } + return FALSE; +} + static bool show_global_privileges(THD *thd, LEX_USER *lex_user, ACL_USER_BASE *acl_entry, bool handle_as_role, char *buff, size_t buffsize)