mirror of
https://github.com/MariaDB/server.git
synced 2025-08-26 01:44:06 +03:00
MDEV-22312: Bad error message for SET DEFAULT ROLE when user account is not granted the role
- `SET DEFAULT ROLE xxx [FOR yyy]` should say: "User yyy has not been granted a role xxx" if: - The current user (not the user `yyy` in the FOR clause) can see the role xxx. It can see the role if: * role exists in `mysql.roles_mappings` (traverse the graph), * If the current user has read access on `mysql.user` table - in that case, it can see all roles, granted or not. - Otherwise it should be "Invalid role specification". In other words, it should not be possible to use `SET DEFAULT ROLE` to discover whether a specific role exist or not.
This commit is contained in:
@@ -14,7 +14,7 @@ set default role role_a for user_a@localhost;
|
|||||||
set default role invalid_role for user_a@localhost;
|
set default role invalid_role for user_a@localhost;
|
||||||
ERROR OP000: Invalid role specification `invalid_role`.
|
ERROR OP000: Invalid role specification `invalid_role`.
|
||||||
set default role role_b for user_a@localhost;
|
set default role role_b for user_a@localhost;
|
||||||
ERROR OP000: Invalid role specification `role_b`.
|
ERROR OP000: User `user_a@localhost` has not been granted role `role_b`
|
||||||
set default role role_b for user_b@localhost;
|
set default role role_b for user_b@localhost;
|
||||||
show grants;
|
show grants;
|
||||||
Grants for user_a@localhost
|
Grants for user_a@localhost
|
||||||
@@ -36,7 +36,7 @@ user host default_role
|
|||||||
user_a localhost role_a
|
user_a localhost role_a
|
||||||
user_b localhost role_b
|
user_b localhost role_b
|
||||||
set default role role_b for current_user;
|
set default role role_b for current_user;
|
||||||
ERROR OP000: Invalid role specification `role_b`.
|
ERROR OP000: User `user_a@localhost` has not been granted role `role_b`
|
||||||
show grants;
|
show grants;
|
||||||
Grants for user_b@localhost
|
Grants for user_b@localhost
|
||||||
GRANT role_b TO 'user_b'@'localhost'
|
GRANT role_b TO 'user_b'@'localhost'
|
||||||
|
@@ -38,3 +38,90 @@ ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'us
|
|||||||
drop role test_role;
|
drop role test_role;
|
||||||
drop role not_granted_role;
|
drop role not_granted_role;
|
||||||
drop user test_user@localhost;
|
drop user test_user@localhost;
|
||||||
|
#
|
||||||
|
# MDEV-22312: Bad error message for SET DEFAULT ROLE when user account
|
||||||
|
# is not granted the role
|
||||||
|
#
|
||||||
|
CREATE USER a;
|
||||||
|
CREATE USER b;
|
||||||
|
CREATE ROLE r1;
|
||||||
|
CREATE ROLE r2;
|
||||||
|
SET DEFAULT ROLE r1 FOR a;
|
||||||
|
ERROR OP000: User `a@%` has not been granted role `r1`
|
||||||
|
GRANT r1 TO b;
|
||||||
|
GRANT r2 TO b;
|
||||||
|
SET DEFAULT ROLE r1 FOR b;
|
||||||
|
# Change user b
|
||||||
|
SELECT CURRENT_ROLE;
|
||||||
|
CURRENT_ROLE
|
||||||
|
r1
|
||||||
|
SET ROLE r2;
|
||||||
|
SELECT CURRENT_ROLE;
|
||||||
|
CURRENT_ROLE
|
||||||
|
r2
|
||||||
|
SET DEFAULT ROLE r1 FOR a;
|
||||||
|
ERROR 42000: Access denied for user 'b'@'%' to database 'mysql'
|
||||||
|
SET DEFAULT ROLE r2;
|
||||||
|
# Change user root (session 1: select_priv to b)
|
||||||
|
GRANT SELECT ON mysql.* TO b;
|
||||||
|
# Change user b (session 1: select_priv)
|
||||||
|
SHOW GRANTS FOR b;
|
||||||
|
Grants for b@%
|
||||||
|
GRANT r1 TO 'b'@'%'
|
||||||
|
GRANT r2 TO 'b'@'%'
|
||||||
|
GRANT USAGE ON *.* TO 'b'@'%'
|
||||||
|
GRANT SELECT ON `mysql`.* TO 'b'@'%'
|
||||||
|
SET DEFAULT ROLE r1 FOR a;
|
||||||
|
ERROR 42000: Access denied for user 'b'@'%' to database 'mysql'
|
||||||
|
SELECT CURRENT_ROLE;
|
||||||
|
CURRENT_ROLE
|
||||||
|
r2
|
||||||
|
SET DEFAULT ROLE NONE;
|
||||||
|
SELECT CURRENT_ROLE;
|
||||||
|
CURRENT_ROLE
|
||||||
|
r2
|
||||||
|
SET DEFAULT ROLE current_role FOR current_user;
|
||||||
|
SET DEFAULT ROLE invalid_role;
|
||||||
|
ERROR OP000: Invalid role specification `invalid_role`.
|
||||||
|
SET DEFAULT ROLE invalid_role FOR a;
|
||||||
|
ERROR 42000: Access denied for user 'b'@'%' to database 'mysql'
|
||||||
|
SET DEFAULT ROLE none FOR a;
|
||||||
|
ERROR 42000: Access denied for user 'b'@'%' to database 'mysql'
|
||||||
|
# Change user root (session 2: adding update_priv to user b)
|
||||||
|
GRANT UPDATE ON mysql.* TO b;
|
||||||
|
# Change user b
|
||||||
|
SHOW GRANTS FOR b;
|
||||||
|
Grants for b@%
|
||||||
|
GRANT r1 TO 'b'@'%'
|
||||||
|
GRANT r2 TO 'b'@'%'
|
||||||
|
GRANT USAGE ON *.* TO 'b'@'%'
|
||||||
|
GRANT SELECT, UPDATE ON `mysql`.* TO 'b'@'%'
|
||||||
|
SET DEFAULT ROLE r1 FOR a;
|
||||||
|
ERROR OP000: User `a@%` has not been granted role `r1`
|
||||||
|
SET DEFAULT ROLE invalid_role;
|
||||||
|
ERROR OP000: Invalid role specification `invalid_role`.
|
||||||
|
SET DEFAULT ROLE invalid_role FOR a;
|
||||||
|
ERROR OP000: Invalid role specification `invalid_role`.
|
||||||
|
SET DEFAULT ROLE none FOR a;
|
||||||
|
# Change user root (session 3: Grant role to user a)
|
||||||
|
GRANT r1 TO a;
|
||||||
|
SET DEFAULT ROLE r1 FOR a;
|
||||||
|
# Change user a (verify session 3)
|
||||||
|
SELECT CURRENT_ROLE;
|
||||||
|
CURRENT_ROLE
|
||||||
|
r1
|
||||||
|
SET DEFAULT ROLE None;
|
||||||
|
# Change user b (session 3: role granted to user a)
|
||||||
|
SET DEFAULT ROLE r1 FOR a;
|
||||||
|
SET DEFAULT ROLE r2 FOR a;
|
||||||
|
ERROR OP000: User `a@%` has not been granted role `r2`
|
||||||
|
SET DEFAULT ROLE invalid_role;
|
||||||
|
ERROR OP000: Invalid role specification `invalid_role`.
|
||||||
|
SET DEFAULT ROLE invalid_role FOR a;
|
||||||
|
ERROR OP000: Invalid role specification `invalid_role`.
|
||||||
|
SELECT user, host, default_role FROM mysql.user where user='a' or user='b';
|
||||||
|
user host default_role
|
||||||
|
a % r1
|
||||||
|
b % r2
|
||||||
|
DROP ROLE r1, r2;
|
||||||
|
DROP USER a, b;
|
||||||
|
@@ -60,3 +60,110 @@ change_user 'root';
|
|||||||
drop role test_role;
|
drop role test_role;
|
||||||
drop role not_granted_role;
|
drop role not_granted_role;
|
||||||
drop user test_user@localhost;
|
drop user test_user@localhost;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-22312: Bad error message for SET DEFAULT ROLE when user account
|
||||||
|
--echo # is not granted the role
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE USER a;
|
||||||
|
CREATE USER b;
|
||||||
|
CREATE ROLE r1;
|
||||||
|
CREATE ROLE r2;
|
||||||
|
# Role has not been granted to user a, but the role is visible to current_user
|
||||||
|
--error ER_INVALID_ROLE
|
||||||
|
SET DEFAULT ROLE r1 FOR a;
|
||||||
|
# Granting roles to user b
|
||||||
|
GRANT r1 TO b;
|
||||||
|
GRANT r2 TO b;
|
||||||
|
# After granting the role, role can be set as default
|
||||||
|
SET DEFAULT ROLE r1 FOR b;
|
||||||
|
|
||||||
|
--echo # Change user b
|
||||||
|
change_user b;
|
||||||
|
SELECT CURRENT_ROLE;
|
||||||
|
SET ROLE r2;
|
||||||
|
SELECT CURRENT_ROLE;
|
||||||
|
# User b has no UPDATE_PRIV for mysql.user
|
||||||
|
--error ER_DBACCESS_DENIED_ERROR
|
||||||
|
SET DEFAULT ROLE r1 FOR a;
|
||||||
|
SET DEFAULT ROLE r2;
|
||||||
|
|
||||||
|
--echo # Change user root (session 1: select_priv to b)
|
||||||
|
change_user root;
|
||||||
|
# Let's grant select_priv to user b
|
||||||
|
GRANT SELECT ON mysql.* TO b;
|
||||||
|
|
||||||
|
--echo # Change user b (session 1: select_priv)
|
||||||
|
change_user b;
|
||||||
|
SHOW GRANTS FOR b;
|
||||||
|
# User must have update_priv before setting the role
|
||||||
|
--error ER_DBACCESS_DENIED_ERROR
|
||||||
|
SET DEFAULT ROLE r1 FOR a;
|
||||||
|
# Testing the `CURRENT_ROLE` as a special case
|
||||||
|
SELECT CURRENT_ROLE;
|
||||||
|
SET DEFAULT ROLE NONE;
|
||||||
|
SELECT CURRENT_ROLE;
|
||||||
|
SET DEFAULT ROLE current_role FOR current_user;
|
||||||
|
# Testing of non-existing role
|
||||||
|
--error ER_INVALID_ROLE
|
||||||
|
SET DEFAULT ROLE invalid_role;
|
||||||
|
# Testing of non-existing role for different user
|
||||||
|
--error ER_DBACCESS_DENIED_ERROR
|
||||||
|
SET DEFAULT ROLE invalid_role FOR a;
|
||||||
|
# Testing the `None` role for different user
|
||||||
|
-- error ER_DBACCESS_DENIED_ERROR
|
||||||
|
SET DEFAULT ROLE none FOR a;
|
||||||
|
|
||||||
|
--echo # Change user root (session 2: adding update_priv to user b)
|
||||||
|
change_user root;
|
||||||
|
# update_priv are enough
|
||||||
|
GRANT UPDATE ON mysql.* TO b;
|
||||||
|
|
||||||
|
--echo # Change user b
|
||||||
|
change_user b;
|
||||||
|
SHOW GRANTS FOR b;
|
||||||
|
# In all tests in session user a has not been granted the role
|
||||||
|
# Testing setting role for different user, should fail with new error
|
||||||
|
--error ER_INVALID_ROLE
|
||||||
|
SET DEFAULT ROLE r1 FOR a;
|
||||||
|
# Testing of non-existing role
|
||||||
|
--error ER_INVALID_ROLE
|
||||||
|
SET DEFAULT ROLE invalid_role;
|
||||||
|
# Testing of non-existing role for different user with update_priv
|
||||||
|
--error ER_INVALID_ROLE
|
||||||
|
SET DEFAULT ROLE invalid_role FOR a;
|
||||||
|
# Testing the `None` role for different user with update_priv
|
||||||
|
SET DEFAULT ROLE none FOR a;
|
||||||
|
|
||||||
|
--echo # Change user root (session 3: Grant role to user a)
|
||||||
|
change_user root;
|
||||||
|
# After granting the privilege for a, user b can set default role
|
||||||
|
GRANT r1 TO a;
|
||||||
|
SET DEFAULT ROLE r1 FOR a;
|
||||||
|
|
||||||
|
--echo # Change user a (verify session 3)
|
||||||
|
change_user a;
|
||||||
|
SELECT CURRENT_ROLE;
|
||||||
|
SET DEFAULT ROLE None;
|
||||||
|
|
||||||
|
--echo # Change user b (session 3: role granted to user a)
|
||||||
|
change_user b;
|
||||||
|
# This should set role because b has update_priv
|
||||||
|
SET DEFAULT ROLE r1 FOR a;
|
||||||
|
# Testing non-granted role r2 still should fail
|
||||||
|
-- error ER_INVALID_ROLE
|
||||||
|
SET DEFAULT ROLE r2 FOR a;
|
||||||
|
# Testing of non-existing role
|
||||||
|
--error ER_INVALID_ROLE
|
||||||
|
SET DEFAULT ROLE invalid_role;
|
||||||
|
# Testing of non-existing role for different user
|
||||||
|
--error ER_INVALID_ROLE
|
||||||
|
SET DEFAULT ROLE invalid_role FOR a;
|
||||||
|
|
||||||
|
# Clear the workspace
|
||||||
|
change_user root;
|
||||||
|
--sorted_result
|
||||||
|
SELECT user, host, default_role FROM mysql.user where user='a' or user='b';
|
||||||
|
DROP ROLE r1, r2;
|
||||||
|
DROP USER a, b;
|
||||||
|
@@ -66,7 +66,7 @@ Grants for test_user@localhost
|
|||||||
GRANT USAGE ON *.* TO 'test_user'@'localhost'
|
GRANT USAGE ON *.* TO 'test_user'@'localhost'
|
||||||
GRANT test_role1 TO 'test_user'@'localhost'
|
GRANT test_role1 TO 'test_user'@'localhost'
|
||||||
set role test_role2;
|
set role test_role2;
|
||||||
ERROR OP000: Invalid role specification `test_role2`.
|
ERROR OP000: User `test_user@localhost` has not been granted role `test_role2`
|
||||||
select current_user(), current_role();
|
select current_user(), current_role();
|
||||||
current_user() current_role()
|
current_user() current_role()
|
||||||
test_user@localhost NULL
|
test_user@localhost NULL
|
||||||
|
@@ -923,8 +923,17 @@ int set_var_default_role::check(THD *thd)
|
|||||||
{
|
{
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
real_user= get_current_user(thd, user);
|
real_user= get_current_user(thd, user);
|
||||||
int status= acl_check_set_default_role(thd, real_user->host.str, real_user->user.str);
|
real_role= role.str;
|
||||||
return status;
|
if (role.str == current_role.str)
|
||||||
|
{
|
||||||
|
if (!thd->security_ctx->priv_role[0])
|
||||||
|
real_role= "NONE";
|
||||||
|
else
|
||||||
|
real_role= thd->security_ctx->priv_role;
|
||||||
|
}
|
||||||
|
|
||||||
|
return acl_check_set_default_role(thd, real_user->host.str,
|
||||||
|
real_user->user.str, real_role);
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
@@ -935,7 +944,8 @@ int set_var_default_role::update(THD *thd)
|
|||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
|
Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
|
||||||
thd->m_reprepare_observer= 0;
|
thd->m_reprepare_observer= 0;
|
||||||
int res= acl_set_default_role(thd, real_user->host.str, real_user->user.str, role.str);
|
int res= acl_set_default_role(thd, real_user->host.str, real_user->user.str,
|
||||||
|
real_role);
|
||||||
thd->m_reprepare_observer= save_reprepare_observer;
|
thd->m_reprepare_observer= save_reprepare_observer;
|
||||||
return res;
|
return res;
|
||||||
#else
|
#else
|
||||||
|
@@ -339,6 +339,7 @@ class set_var_default_role: public set_var_base
|
|||||||
{
|
{
|
||||||
LEX_USER *user, *real_user;
|
LEX_USER *user, *real_user;
|
||||||
LEX_STRING role;
|
LEX_STRING role;
|
||||||
|
const char *real_role;
|
||||||
public:
|
public:
|
||||||
set_var_default_role(LEX_USER *user_arg, LEX_STRING role_arg) :
|
set_var_default_role(LEX_USER *user_arg, LEX_STRING role_arg) :
|
||||||
user(user_arg), role(role_arg) {}
|
user(user_arg), role(role_arg) {}
|
||||||
|
114
sql/sql_acl.cc
114
sql/sql_acl.cc
@@ -201,6 +201,8 @@ LEX_STRING current_user= { C_STRING_WITH_LEN("*current_user") };
|
|||||||
LEX_STRING current_role= { C_STRING_WITH_LEN("*current_role") };
|
LEX_STRING current_role= { C_STRING_WITH_LEN("*current_role") };
|
||||||
LEX_STRING current_user_and_current_role= { C_STRING_WITH_LEN("*current_user_and_current_role") };
|
LEX_STRING current_user_and_current_role= { C_STRING_WITH_LEN("*current_user_and_current_role") };
|
||||||
|
|
||||||
|
class ACL_USER;
|
||||||
|
static ACL_USER *find_user_or_anon(const char *host, const char *user, const char *ip);
|
||||||
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
static plugin_ref old_password_plugin;
|
static plugin_ref old_password_plugin;
|
||||||
@@ -2034,8 +2036,21 @@ bool acl_getroot(Security_context *sctx, char *user, char *host,
|
|||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_user_can_set_role(const char *user, const char *host,
|
static int check_role_is_granted_callback(ACL_USER_BASE *grantee, void *data)
|
||||||
const char *ip, const char *rolename, ulonglong *access)
|
{
|
||||||
|
LEX_CSTRING *rolename= static_cast<LEX_CSTRING *>(data);
|
||||||
|
if (rolename->length == grantee->user.length &&
|
||||||
|
!strcmp(rolename->str, grantee->user.str))
|
||||||
|
return -1; // End search, we've found our role.
|
||||||
|
|
||||||
|
/* Keep looking, we haven't found our role yet. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int check_user_can_set_role(THD *thd, const char *user, const char *host,
|
||||||
|
const char *ip, const char *rolename,
|
||||||
|
ulonglong *access)
|
||||||
{
|
{
|
||||||
ACL_ROLE *role;
|
ACL_ROLE *role;
|
||||||
ACL_USER_BASE *acl_user_base;
|
ACL_USER_BASE *acl_user_base;
|
||||||
@@ -2053,8 +2068,7 @@ static int check_user_can_set_role(const char *user, const char *host,
|
|||||||
acl_user= find_user_wild(host, user, ip);
|
acl_user= find_user_wild(host, user, ip);
|
||||||
if (acl_user == NULL)
|
if (acl_user == NULL)
|
||||||
{
|
{
|
||||||
my_error(ER_INVALID_CURRENT_USER, MYF(0), rolename);
|
result= ER_INVALID_CURRENT_USER;
|
||||||
result= -1;
|
|
||||||
}
|
}
|
||||||
else if (access)
|
else if (access)
|
||||||
*access= acl_user->access;
|
*access= acl_user->access;
|
||||||
@@ -2065,9 +2079,9 @@ static int check_user_can_set_role(const char *user, const char *host,
|
|||||||
role= find_acl_role(rolename);
|
role= find_acl_role(rolename);
|
||||||
|
|
||||||
/* According to SQL standard, the same error message must be presented */
|
/* According to SQL standard, the same error message must be presented */
|
||||||
if (role == NULL) {
|
if (role == NULL)
|
||||||
my_error(ER_INVALID_ROLE, MYF(0), rolename);
|
{
|
||||||
result= -1;
|
result= ER_INVALID_ROLE;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2088,7 +2102,6 @@ static int check_user_can_set_role(const char *user, const char *host,
|
|||||||
/* According to SQL standard, the same error message must be presented */
|
/* According to SQL standard, the same error message must be presented */
|
||||||
if (!is_granted)
|
if (!is_granted)
|
||||||
{
|
{
|
||||||
my_error(ER_INVALID_ROLE, MYF(0), rolename);
|
|
||||||
result= 1;
|
result= 1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -2097,16 +2110,65 @@ static int check_user_can_set_role(const char *user, const char *host,
|
|||||||
{
|
{
|
||||||
*access = acl_user->access | role->access;
|
*access = acl_user->access | role->access;
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
mysql_mutex_unlock(&acl_cache->lock);
|
mysql_mutex_unlock(&acl_cache->lock);
|
||||||
return result;
|
|
||||||
|
|
||||||
|
/* We present different error messages depending if the user has sufficient
|
||||||
|
privileges to know if the INVALID_ROLE exists. */
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case ER_INVALID_CURRENT_USER:
|
||||||
|
my_error(ER_INVALID_CURRENT_USER, MYF(0), rolename);
|
||||||
|
break;
|
||||||
|
case ER_INVALID_ROLE:
|
||||||
|
/* Role doesn't exist at all */
|
||||||
|
my_error(ER_INVALID_ROLE, MYF(0), rolename);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
StringBuffer<1024> c_usr;
|
||||||
|
LEX_CSTRING role_lex;
|
||||||
|
/* First, check if current user can see mysql database. */
|
||||||
|
bool read_access= !check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 1);
|
||||||
|
|
||||||
|
role_lex.str= rolename;
|
||||||
|
role_lex.length= strlen(rolename);
|
||||||
|
mysql_mutex_lock(&acl_cache->lock);
|
||||||
|
ACL_USER *cur_user= find_user_or_anon(thd->security_ctx->priv_host,
|
||||||
|
thd->security_ctx->priv_user,
|
||||||
|
thd->security_ctx->ip);
|
||||||
|
|
||||||
|
/* If the current user does not have select priv to mysql database,
|
||||||
|
see if the current user can discover the role if it was granted to him.
|
||||||
|
*/
|
||||||
|
if (cur_user && (read_access ||
|
||||||
|
traverse_role_graph_down(cur_user, &role_lex,
|
||||||
|
check_role_is_granted_callback,
|
||||||
|
NULL) == -1))
|
||||||
|
{
|
||||||
|
/* Role is not granted but current user can see the role */
|
||||||
|
c_usr.append(user, strlen(user));
|
||||||
|
c_usr.append('@');
|
||||||
|
c_usr.append(host, strlen(host));
|
||||||
|
my_printf_error(ER_INVALID_ROLE, "User %`s has not been granted role %`s",
|
||||||
|
MYF(0), c_usr.c_ptr(), rolename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Role is not granted and current user cannot see the role */
|
||||||
|
my_error(ER_INVALID_ROLE, MYF(0), rolename);
|
||||||
|
}
|
||||||
|
mysql_mutex_unlock(&acl_cache->lock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int acl_check_setrole(THD *thd, char *rolename, ulonglong *access)
|
int acl_check_setrole(THD *thd, char *rolename, ulonglong *access)
|
||||||
{
|
{
|
||||||
/* Yes! priv_user@host. Don't ask why - that's what check_access() does. */
|
return check_user_can_set_role(thd, thd->security_ctx->priv_user,
|
||||||
return check_user_can_set_role(thd->security_ctx->priv_user,
|
|
||||||
thd->security_ctx->host, thd->security_ctx->ip, rolename, access);
|
thd->security_ctx->host, thd->security_ctx->ip, rolename, access);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2886,9 +2948,12 @@ WSREP_ERROR_LABEL:
|
|||||||
DBUG_RETURN(result);
|
DBUG_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
int acl_check_set_default_role(THD *thd, const char *host, const char *user)
|
int acl_check_set_default_role(THD *thd, const char *host, const char *user,
|
||||||
|
const char *role)
|
||||||
{
|
{
|
||||||
return check_alter_user(thd, host, user);
|
DBUG_ENTER("acl_check_set_default_role");
|
||||||
|
DBUG_RETURN(check_alter_user(thd, host, user) ||
|
||||||
|
check_user_can_set_role(thd, user, host, NULL, role, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
int acl_set_default_role(THD *thd, const char *host, const char *user,
|
int acl_set_default_role(THD *thd, const char *host, const char *user,
|
||||||
@@ -2910,16 +2975,6 @@ int acl_set_default_role(THD *thd, const char *host, const char *user,
|
|||||||
DBUG_PRINT("enter",("host: '%s' user: '%s' rolename: '%s'",
|
DBUG_PRINT("enter",("host: '%s' user: '%s' rolename: '%s'",
|
||||||
safe_str(user), safe_str(host), safe_str(rolename)));
|
safe_str(user), safe_str(host), safe_str(rolename)));
|
||||||
|
|
||||||
if (rolename == current_role.str) {
|
|
||||||
if (!thd->security_ctx->priv_role[0])
|
|
||||||
rolename= "NONE";
|
|
||||||
else
|
|
||||||
rolename= thd->security_ctx->priv_role;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check_user_can_set_role(user, host, host, rolename, NULL))
|
|
||||||
DBUG_RETURN(result);
|
|
||||||
|
|
||||||
if (!strcasecmp(rolename, "NONE"))
|
if (!strcasecmp(rolename, "NONE"))
|
||||||
clear_role= TRUE;
|
clear_role= TRUE;
|
||||||
|
|
||||||
@@ -8508,17 +8563,6 @@ void get_mqh(const char *user, const char *host, USER_CONN *uc)
|
|||||||
mysql_mutex_unlock(&acl_cache->lock);
|
mysql_mutex_unlock(&acl_cache->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_role_is_granted_callback(ACL_USER_BASE *grantee, void *data)
|
|
||||||
{
|
|
||||||
LEX_CSTRING *rolename= static_cast<LEX_CSTRING *>(data);
|
|
||||||
if (rolename->length == grantee->user.length &&
|
|
||||||
!strcmp(rolename->str, grantee->user.str))
|
|
||||||
return -1; // End search, we've found our role.
|
|
||||||
|
|
||||||
/* Keep looking, we haven't found our role yet. */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Initialize a TABLE_LIST array and open grant tables
|
Initialize a TABLE_LIST array and open grant tables
|
||||||
|
|
||||||
@@ -10329,7 +10373,7 @@ acl_check_proxy_grant_access(THD *thd, const char *host, const char *user,
|
|||||||
Security context in THD contains two pairs of (user,host):
|
Security context in THD contains two pairs of (user,host):
|
||||||
1. (user,host) pair referring to inbound connection.
|
1. (user,host) pair referring to inbound connection.
|
||||||
2. (priv_user,priv_host) pair obtained from mysql.user table after doing
|
2. (priv_user,priv_host) pair obtained from mysql.user table after doing
|
||||||
authnetication of incoming connection.
|
authentication of incoming connection.
|
||||||
Privileges should be checked wrt (priv_user, priv_host) tuple, because
|
Privileges should be checked wrt (priv_user, priv_host) tuple, because
|
||||||
(user,host) pair obtained from inbound connection may have different
|
(user,host) pair obtained from inbound connection may have different
|
||||||
values than what is actually stored in mysql.user table and while granting
|
values than what is actually stored in mysql.user table and while granting
|
||||||
|
@@ -402,7 +402,7 @@ bool acl_check_proxy_grant_access (THD *thd, const char *host, const char *user,
|
|||||||
bool with_grant);
|
bool with_grant);
|
||||||
int acl_setrole(THD *thd, char *rolename, ulonglong access);
|
int acl_setrole(THD *thd, char *rolename, ulonglong access);
|
||||||
int acl_check_setrole(THD *thd, char *rolename, ulonglong *access);
|
int acl_check_setrole(THD *thd, char *rolename, ulonglong *access);
|
||||||
int acl_check_set_default_role(THD *thd, const char *host, const char *user);
|
int acl_check_set_default_role(THD *thd, const char *host, const char *user, const char *role);
|
||||||
int acl_set_default_role(THD *thd, const char *host, const char *user,
|
int acl_set_default_role(THD *thd, const char *host, const char *user,
|
||||||
const char *rolename);
|
const char *rolename);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user