diff --git a/mysql-test/suite/roles/create_and_drop_role.result b/mysql-test/suite/roles/create_and_drop_role.result index c36de3bc3d3..4a5fd3ee429 100644 --- a/mysql-test/suite/roles/create_and_drop_role.result +++ b/mysql-test/suite/roles/create_and_drop_role.result @@ -38,5 +38,5 @@ create role ''; ERROR OP000: Invalid role specification ``. create role r1; drop user r1; -ERROR HY000: Operation DROP USER failed for 'r1' +ERROR HY000: Operation DROP USER failed for 'r1'@'%' drop role r1; diff --git a/mysql-test/suite/roles/grant_proxy-5526.result b/mysql-test/suite/roles/grant_proxy-5526.result new file mode 100644 index 00000000000..7921969299a --- /dev/null +++ b/mysql-test/suite/roles/grant_proxy-5526.result @@ -0,0 +1,9 @@ +create role r1; +create user user; +grant proxy on r1 to user; +show grants for user; +Grants for user@% +GRANT USAGE ON *.* TO 'user'@'%' +GRANT PROXY ON 'r1'@'%' TO 'user'@'%' +drop user user; +drop role r1; diff --git a/mysql-test/suite/roles/grant_proxy-5526.test b/mysql-test/suite/roles/grant_proxy-5526.test new file mode 100644 index 00000000000..8f5f8cf6843 --- /dev/null +++ b/mysql-test/suite/roles/grant_proxy-5526.test @@ -0,0 +1,10 @@ +# +# MDEV-5526 Assertion `proxied_user->host.length' fails on GRANT PROXY ON +# +create role r1; +create user user; +grant proxy on r1 to user; +show grants for user; +drop user user; +drop role r1; + diff --git a/mysql-test/suite/roles/password.result b/mysql-test/suite/roles/password.result index e41816bdef7..041a049ccec 100644 --- a/mysql-test/suite/roles/password.result +++ b/mysql-test/suite/roles/password.result @@ -1,14 +1,14 @@ create role r1; grant select on *.* to r1 identified by 'foobar'; -ERROR 28000: Can't find any matching row in the user table +drop user r1; grant select on *.* to r1 identified by ''; -ERROR 28000: Can't find any matching row in the user table +drop user r1; grant select on mysql.user to r1 identified by password '00000000000000000000000000000000000000000'; -ERROR 28000: Can't find any matching row in the user table +drop user r1; grant select on *.* to r1 identified via plugin; -ERROR 28000: Can't find any matching row in the user table +ERROR HY000: Plugin 'plugin' is not loaded grant select on mysql.user to r1 identified via plugin using 'param'; -ERROR 28000: Can't find any matching row in the user table +ERROR HY000: Plugin 'plugin' is not loaded grant select on *.* to r1 require subject 'foobar'; ERROR 28000: Can't find any matching row in the user table grant select on mysql.user to r1 require issuer 'foobar'; diff --git a/mysql-test/suite/roles/password.test b/mysql-test/suite/roles/password.test index 6b5073fae43..f638c5f39be 100644 --- a/mysql-test/suite/roles/password.test +++ b/mysql-test/suite/roles/password.test @@ -12,16 +12,18 @@ create role r1; ---error ER_PASSWORD_NO_MATCH +# IDENTIFIED does not apply to roles, using it forces username context grant select on *.* to r1 identified by 'foobar'; ---error ER_PASSWORD_NO_MATCH +drop user r1; grant select on *.* to r1 identified by ''; ---error ER_PASSWORD_NO_MATCH +drop user r1; grant select on mysql.user to r1 identified by password '00000000000000000000000000000000000000000'; ---error ER_PASSWORD_NO_MATCH +drop user r1; +--error ER_PLUGIN_IS_NOT_LOADED grant select on *.* to r1 identified via plugin; ---error ER_PASSWORD_NO_MATCH +--error ER_PLUGIN_IS_NOT_LOADED grant select on mysql.user to r1 identified via plugin using 'param'; + --error ER_PASSWORD_NO_MATCH grant select on *.* to r1 require subject 'foobar'; --error ER_PASSWORD_NO_MATCH diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 0e5767c0da7..4abf447549d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -8351,7 +8351,7 @@ static int handle_roles_mappings_table(TABLE *table, bool drop, { role= safe_str(get_field(thd->mem_root, role_field)); - if (strcmp(user_from->user.str, role)) + if (!user_from->is_role() || strcmp(user_from->user.str, role)) continue; error= 0; @@ -8574,7 +8574,6 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop, const char *UNINIT_VAR(user); const char *UNINIT_VAR(host); const char *UNINIT_VAR(role); - uint role_not_matched= 1; ACL_USER *acl_user= NULL; ACL_ROLE *acl_role= NULL; ACL_DB *acl_db= NULL; @@ -8734,11 +8733,10 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop, if (struct_no == ROLES_MAPPINGS_HASH) { - role_not_matched= strcmp(user_from->user.str, role); - if (role_not_matched && + if (user_from->is_role() ? strcmp(user_from->user.str, role) : (strcmp(user_from->user.str, user) || my_strcasecmp(system_charset_info, user_from->host.str, host))) - continue; + continue; } else { @@ -8858,14 +8856,14 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop, size_t old_key_length= role_grant_pair->hashkey.length; bool oom; - if (role_not_matched) - oom= role_grant_pair->init(&acl_memroot, user_to->user.str, - user_to->host.str, - role_grant_pair->r_uname, false); - else + if (user_to->is_role()) oom= role_grant_pair->init(&acl_memroot, role_grant_pair->u_uname, role_grant_pair->u_hname, user_to->user.str, false); + else + oom= role_grant_pair->init(&acl_memroot, user_to->user.str, + user_to->host.str, + role_grant_pair->r_uname, false); if (oom) DBUG_RETURN(-1); @@ -9349,20 +9347,20 @@ bool mysql_rename_user(THD *thd, List &list) while ((tmp_user_from= user_list++)) { tmp_user_to= user_list++; - if (!(user_from= get_current_user(thd, tmp_user_from, false)) || - user_from->is_role()) + if (!(user_from= get_current_user(thd, tmp_user_from, false))) { append_user(&wrong_users, user_from); result= TRUE; continue; } - if (!(user_to= get_current_user(thd, tmp_user_to, false)) || - user_to->is_role()) + if (!(user_to= get_current_user(thd, tmp_user_to, false))) { append_user(&wrong_users, user_to); result= TRUE; continue; } + DBUG_ASSERT(!user_from->is_role()); + DBUG_ASSERT(!user_to->is_role()); /* Search all in-memory structures and grant tables diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 7514b7bec63..e13687530ee 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1771,7 +1771,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type keyword keyword_sp %type user grant_user grant_role user_or_role current_role - admin_option_for_role + admin_option_for_role user_maybe_role %type opt_collate @@ -13916,7 +13916,7 @@ ident_or_text: | LEX_HOSTNAME { $$=$1;} ; -user: +user_maybe_role: ident_or_text { if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user)))) @@ -13974,7 +13974,15 @@ user: } ; -user_or_role: user | current_role; +user_or_role: user_maybe_role | current_role; + +user: user_maybe_role + { + if ($1->user.str != current_user.str && $1->host.str == 0) + $1->host= host_not_specified; + $$= $1; + } + ; /* Keyword that we allow for identifiers (except SP labels) */ keyword: