Skip to content

Commit

Permalink
MDEV-7774: Crash when dropping user within rebuild_role_grants
Browse files Browse the repository at this point in the history
The issue comes from not taking all possibilities to match an entry
within the roles_mapping HASH, when updating the data structure.
  • Loading branch information
cvicentiu committed May 3, 2015
1 parent acab0fa commit 6c55e52
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 4 deletions.
18 changes: 18 additions & 0 deletions mysql-test/suite/roles/create_and_drop_role.result
Original file line number Diff line number Diff line change
Expand Up @@ -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;
19 changes: 19 additions & 0 deletions mysql-test/suite/roles/create_and_drop_role.test
Original file line number Diff line number Diff line change
Expand Up @@ -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;
28 changes: 24 additions & 4 deletions sql/sql_acl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down

0 comments on commit 6c55e52

Please sign in to comment.