diff options
-rw-r--r-- | mysql-test/r/grant5.result | 16 | ||||
-rw-r--r-- | mysql-test/t/grant5.test | 18 | ||||
-rw-r--r-- | sql/sql_acl.cc | 26 | ||||
-rw-r--r-- | sql/sql_parse.cc | 13 |
4 files changed, 48 insertions, 25 deletions
diff --git a/mysql-test/r/grant5.result b/mysql-test/r/grant5.result index 2df394c0432..d7f3b6812bb 100644 --- a/mysql-test/r/grant5.result +++ b/mysql-test/r/grant5.result @@ -1,2 +1,18 @@ SHOW GRANTS FOR root@invalid_host; ERROR 42000: There is no such grant defined for user 'root' on host 'invalid_host' +create user test; +create user foo; +create role foo; +grant foo to test; +set role foo; +show grants for test; +Grants for test@% +GRANT foo TO 'test'@'%' +GRANT USAGE ON *.* TO 'test'@'%' +show grants for foo; +Grants for foo +GRANT USAGE ON *.* TO 'foo' +show grants for foo@'%'; +ERROR 42000: Access denied for user 'test'@'%' to database 'mysql' +drop user test, foo; +drop role foo; diff --git a/mysql-test/t/grant5.test b/mysql-test/t/grant5.test index db953d97fb3..14f2fd65020 100644 --- a/mysql-test/t/grant5.test +++ b/mysql-test/t/grant5.test @@ -5,3 +5,21 @@ # --error ER_NONEXISTING_GRANT SHOW GRANTS FOR root@invalid_host; + +# +# MDEV-9580 SHOW GRANTS FOR <current_user> fails +# +create user test; +create user foo; +create role foo; +grant foo to test; +--connect (conn_1, localhost, test,,) +set role foo; +show grants for test; # user +show grants for foo; # role +--error ER_DBACCESS_DENIED_ERROR +show grants for foo@'%'; # user +--connection default +drop user test, foo; +drop role foo; + diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index bbd1dd86880..502e9ff83f2 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -7559,9 +7559,6 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user) DBUG_RETURN(TRUE); } - mysql_rwlock_rdlock(&LOCK_grant); - mysql_mutex_lock(&acl_cache->lock); - if (lex_user->user.str == current_user.str) { username= thd->security_ctx->priv_user; @@ -7579,23 +7576,28 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user) } else { - lex_user= get_current_user(thd, lex_user, false); + Security_context *sctx= thd->security_ctx; + bool do_check_access; + + lex_user= get_current_user(thd, lex_user); if (!lex_user) - { - mysql_mutex_unlock(&acl_cache->lock); - mysql_rwlock_unlock(&LOCK_grant); DBUG_RETURN(TRUE); - } if (lex_user->is_role()) { rolename= lex_user->user.str; + do_check_access= strcmp(rolename, sctx->priv_role); } else { username= lex_user->user.str; hostname= lex_user->host.str; + do_check_access= strcmp(username, sctx->priv_user) || + strcmp(hostname, sctx->priv_host); } + + if (do_check_access && check_access(thd, SELECT_ACL, "mysql", 0, 0, 1, 0)) + DBUG_RETURN(TRUE); } DBUG_ASSERT(rolename || username); @@ -7610,12 +7612,10 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user) field_list.push_back(field); if (protocol->send_result_set_metadata(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - { - mysql_mutex_unlock(&acl_cache->lock); - mysql_rwlock_unlock(&LOCK_grant); - DBUG_RETURN(TRUE); - } + + mysql_rwlock_rdlock(&LOCK_grant); + mysql_mutex_lock(&acl_cache->lock); if (username) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d2fed787ba9..b91455888b8 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4374,21 +4374,10 @@ end_with_restore_list: case SQLCOM_SHOW_GRANTS: { LEX_USER *grant_user= lex->grant_user; - Security_context *sctx= thd->security_ctx; if (!grant_user) goto error; - if (grant_user->user.str && !strcmp(sctx->priv_user, grant_user->user.str) && - grant_user->host.str && !strcmp(sctx->priv_host, grant_user->host.str)) - grant_user->user= current_user; - - if (grant_user->user.str == current_user.str || - grant_user->user.str == current_role.str || - grant_user->user.str == current_user_and_current_role.str || - !check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 0)) - { - res = mysql_show_grants(thd, grant_user); - } + res = mysql_show_grants(thd, grant_user); break; } #endif |