Commit d821dd10 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-9580 SHOW GRANTS FOR <current_user> fails

use get_current_user() to distinguish user name without
a hostname and a role name.

move privilege checks inside mysql_show_grants() to remove
duplicate get_current_user() calls
parent 23b1b69b
SHOW GRANTS FOR root@invalid_host; SHOW GRANTS FOR root@invalid_host;
ERROR 42000: There is no such grant defined for user 'root' on host '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;
...@@ -5,3 +5,21 @@ ...@@ -5,3 +5,21 @@
# #
--error ER_NONEXISTING_GRANT --error ER_NONEXISTING_GRANT
SHOW GRANTS FOR root@invalid_host; 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;
...@@ -7559,9 +7559,6 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user) ...@@ -7559,9 +7559,6 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
mysql_rwlock_rdlock(&LOCK_grant);
mysql_mutex_lock(&acl_cache->lock);
if (lex_user->user.str == current_user.str) if (lex_user->user.str == current_user.str)
{ {
username= thd->security_ctx->priv_user; username= thd->security_ctx->priv_user;
...@@ -7579,23 +7576,28 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user) ...@@ -7579,23 +7576,28 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user)
} }
else 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) if (!lex_user)
{
mysql_mutex_unlock(&acl_cache->lock);
mysql_rwlock_unlock(&LOCK_grant);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
}
if (lex_user->is_role()) if (lex_user->is_role())
{ {
rolename= lex_user->user.str; rolename= lex_user->user.str;
do_check_access= strcmp(rolename, sctx->priv_role);
} }
else else
{ {
username= lex_user->user.str; username= lex_user->user.str;
hostname= lex_user->host.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); DBUG_ASSERT(rolename || username);
...@@ -7610,12 +7612,10 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user) ...@@ -7610,12 +7612,10 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user)
field_list.push_back(field); field_list.push_back(field);
if (protocol->send_result_set_metadata(&field_list, if (protocol->send_result_set_metadata(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
{
mysql_mutex_unlock(&acl_cache->lock);
mysql_rwlock_unlock(&LOCK_grant);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
}
mysql_rwlock_rdlock(&LOCK_grant);
mysql_mutex_lock(&acl_cache->lock);
if (username) if (username)
{ {
......
...@@ -4374,21 +4374,10 @@ end_with_restore_list: ...@@ -4374,21 +4374,10 @@ end_with_restore_list:
case SQLCOM_SHOW_GRANTS: case SQLCOM_SHOW_GRANTS:
{ {
LEX_USER *grant_user= lex->grant_user; LEX_USER *grant_user= lex->grant_user;
Security_context *sctx= thd->security_ctx;
if (!grant_user) if (!grant_user)
goto error; 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; break;
} }
#endif #endif
......
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