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;
|
||||
drop user foo@bar;
|
||||
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 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)
|
||||
{
|
||||
const char* role= role_grant_pair->r_uname? role_grant_pair->r_uname: "";
|
||||
if (user_from->is_role() ? strcmp(user_from->user.str, role) :
|
||||
(strcmp(user_from->user.str, user) ||
|
||||
my_strcasecmp(system_charset_info, user_from->host.str, host)))
|
||||
continue;
|
||||
if (user_from->is_role())
|
||||
{
|
||||
/* When searching for roles within the ROLES_MAPPINGS_HASH, we have
|
||||
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
|
||||
{
|
||||
|
Reference in New Issue
Block a user