mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-7774: Crash when dropping user within rebuild_role_grants
The issue comes from not taking all possibilities to match an entry within the roles_mapping HASH, when updating the data structure.
This commit is contained in:
@ -46,3 +46,21 @@ Note 1449 The user specified as a definer ('u1'@'%') does not exist
|
|||||||
create user foo@bar;
|
create user foo@bar;
|
||||||
drop user foo@bar;
|
drop user foo@bar;
|
||||||
drop role r1;
|
drop role r1;
|
||||||
|
CREATE USER u1;
|
||||||
|
CREATE ROLE r1;
|
||||||
|
CREATE USER r1@localhost;
|
||||||
|
CREATE ROLE r2;
|
||||||
|
GRANT r2 to r1;
|
||||||
|
GRANT r2 to r1@localhost;
|
||||||
|
DROP ROLE r1;
|
||||||
|
SELECT * FROM mysql.roles_mapping;
|
||||||
|
Host User Role Admin_option
|
||||||
|
localhost r1 r2 N
|
||||||
|
localhost root r2 Y
|
||||||
|
SHOW GRANTS FOR r1@localhost;
|
||||||
|
Grants for r1@localhost
|
||||||
|
GRANT r2 TO 'r1'@'localhost'
|
||||||
|
GRANT USAGE ON *.* TO 'r1'@'localhost'
|
||||||
|
DROP USER u1;
|
||||||
|
DROP ROLE r2;
|
||||||
|
DROP USER r1@localhost;
|
||||||
|
@ -68,3 +68,22 @@ create user foo@bar;
|
|||||||
drop user foo@bar;
|
drop user foo@bar;
|
||||||
drop role r1;
|
drop role r1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# MDEV-7774 Assertion `status == 0' fails when dropping in this order:
|
||||||
|
#
|
||||||
|
CREATE USER u1;
|
||||||
|
CREATE ROLE r1;
|
||||||
|
CREATE USER r1@localhost;
|
||||||
|
CREATE ROLE r2;
|
||||||
|
GRANT r2 to r1;
|
||||||
|
GRANT r2 to r1@localhost;
|
||||||
|
# MDEV-7774: Dropping in this order caused the crash.
|
||||||
|
DROP ROLE r1;
|
||||||
|
--sorted_result
|
||||||
|
SELECT * FROM mysql.roles_mapping;
|
||||||
|
SHOW GRANTS FOR r1@localhost; # Related to MDEV-7774, also caused a crash, by
|
||||||
|
# not updating the internal acl_roles_mapping
|
||||||
|
# data structure correctly;
|
||||||
|
DROP USER u1;
|
||||||
|
DROP ROLE r2;
|
||||||
|
DROP USER r1@localhost;
|
||||||
|
@ -8802,10 +8802,30 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
|
|||||||
if (struct_no == ROLES_MAPPINGS_HASH)
|
if (struct_no == ROLES_MAPPINGS_HASH)
|
||||||
{
|
{
|
||||||
const char* role= role_grant_pair->r_uname? role_grant_pair->r_uname: "";
|
const char* role= role_grant_pair->r_uname? role_grant_pair->r_uname: "";
|
||||||
if (user_from->is_role() ? strcmp(user_from->user.str, role) :
|
if (user_from->is_role())
|
||||||
(strcmp(user_from->user.str, user) ||
|
{
|
||||||
my_strcasecmp(system_charset_info, user_from->host.str, host)))
|
/* When searching for roles within the ROLES_MAPPINGS_HASH, we have
|
||||||
continue;
|
to check both the user field as well as the role field for a match.
|
||||||
|
|
||||||
|
It is possible to have a role granted to a role. If we are going
|
||||||
|
to modify the mapping entry, it needs to be done on either on the
|
||||||
|
"user" end (here represented by a role) or the "role" end. At least
|
||||||
|
one part must match.
|
||||||
|
|
||||||
|
If the "user" end has a not-empty host string, it can never match
|
||||||
|
as we are searching for a role here. A role always has an empty host
|
||||||
|
string.
|
||||||
|
*/
|
||||||
|
if ((*host || strcmp(user_from->user.str, user)) &&
|
||||||
|
strcmp(user_from->user.str, role))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (strcmp(user_from->user.str, user) ||
|
||||||
|
my_strcasecmp(system_charset_info, user_from->host.str, host))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user