summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/grant5.result16
-rw-r--r--mysql-test/t/grant5.test18
-rw-r--r--sql/sql_acl.cc26
-rw-r--r--sql/sql_parse.cc13
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