mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
MDEV-5525 Assertion `status == 0' fails on creating user after granting it role admin option
don't add entries to acl_roles_mappings hash for non-existing grantees.
This commit is contained in:
parent
416148a4cf
commit
dba4e82a84
3 changed files with 67 additions and 21 deletions
|
@ -40,3 +40,9 @@ create role r1;
|
|||
drop user r1;
|
||||
ERROR HY000: Operation DROP USER failed for 'r1'@'%'
|
||||
drop role r1;
|
||||
create role r1 with admin u1;
|
||||
Warnings:
|
||||
Note 1449 The user specified as a definer ('u1'@'%') does not exist
|
||||
create user foo@bar;
|
||||
drop user foo@bar;
|
||||
drop role r1;
|
||||
|
|
|
@ -60,3 +60,11 @@ create role r1;
|
|||
drop user r1;
|
||||
drop role r1;
|
||||
|
||||
#
|
||||
# MDEV-5525 Assertion `status == 0' fails on creating user after granting it role admin option
|
||||
#
|
||||
create role r1 with admin u1;
|
||||
create user foo@bar;
|
||||
drop user foo@bar;
|
||||
drop role r1;
|
||||
|
||||
|
|
|
@ -3388,7 +3388,7 @@ abort:
|
|||
}
|
||||
|
||||
/**
|
||||
Updates the mysql.roles_mapping table and the acl_roles_mappings hash.
|
||||
Updates the mysql.roles_mapping table
|
||||
|
||||
@param table TABLE to update
|
||||
@param user user name of the grantee
|
||||
|
@ -3436,20 +3436,10 @@ replace_roles_mapping_table(TABLE *table, LEX_STRING *user, LEX_STRING *host,
|
|||
host->str, user->str, role->str));
|
||||
goto table_error;
|
||||
}
|
||||
/*
|
||||
This should always return something, as the check was performed
|
||||
earlier
|
||||
*/
|
||||
my_hash_delete(&acl_roles_mappings, (uchar*)existing);
|
||||
}
|
||||
else
|
||||
else if (with_admin)
|
||||
{
|
||||
if (revoke_grant)
|
||||
existing->with_admin= false;
|
||||
else
|
||||
existing->with_admin|= with_admin;
|
||||
|
||||
table->field[3]->store(existing->with_admin + 1);
|
||||
table->field[3]->store(!revoke_grant + 1);
|
||||
|
||||
if ((error= table->file->ha_update_row(table->record[1], table->record[0])))
|
||||
{
|
||||
|
@ -3469,14 +3459,6 @@ replace_roles_mapping_table(TABLE *table, LEX_STRING *user, LEX_STRING *host,
|
|||
host->str, user->str, role->str));
|
||||
goto table_error;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* allocate a new entry that will go in the hash */
|
||||
ROLE_GRANT_PAIR *hash_entry= new (&acl_memroot) ROLE_GRANT_PAIR;
|
||||
if (hash_entry->init(&acl_memroot, user->str, host->str, role->str, with_admin))
|
||||
DBUG_RETURN(1);
|
||||
my_hash_insert(&acl_roles_mappings, (uchar*) hash_entry);
|
||||
}
|
||||
|
||||
/* all ok */
|
||||
DBUG_RETURN(0);
|
||||
|
@ -3487,6 +3469,48 @@ table_error:
|
|||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Updates the acl_roles_mappings hash
|
||||
|
||||
@param user user name of the grantee
|
||||
@param host host name of the grantee
|
||||
@param role role name to grant
|
||||
@param with_admin WITH ADMIN OPTION flag
|
||||
@param existing the entry in the acl_roles_mappings hash or NULL.
|
||||
it is never NULL if revoke_grant is true.
|
||||
it is NULL when a new pair is added, it's not NULL
|
||||
when an existing pair is updated.
|
||||
@param revoke_grant true for REVOKE, false for GRANT
|
||||
*/
|
||||
static int
|
||||
update_role_mapping(LEX_STRING *user, LEX_STRING *host, LEX_STRING *role,
|
||||
bool with_admin, ROLE_GRANT_PAIR *existing, bool revoke_grant)
|
||||
{
|
||||
if (revoke_grant)
|
||||
{
|
||||
if (with_admin)
|
||||
{
|
||||
existing->with_admin= false;
|
||||
return 0;
|
||||
}
|
||||
return my_hash_delete(&acl_roles_mappings, (uchar*)existing);
|
||||
}
|
||||
|
||||
if (existing)
|
||||
{
|
||||
existing->with_admin|= with_admin;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* allocate a new entry that will go in the hash */
|
||||
ROLE_GRANT_PAIR *hash_entry= new (&acl_memroot) ROLE_GRANT_PAIR;
|
||||
if (hash_entry->init(&acl_memroot, user->str, host->str,
|
||||
role->str, with_admin))
|
||||
return 1;
|
||||
return my_hash_insert(&acl_roles_mappings, (uchar*) hash_entry);
|
||||
}
|
||||
|
||||
static void
|
||||
acl_update_proxy_user(ACL_PROXY_USER *new_value, bool is_revoke)
|
||||
{
|
||||
|
@ -6051,6 +6075,8 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
|
|||
}
|
||||
continue;
|
||||
}
|
||||
update_role_mapping(&username, &hostname, &rolename,
|
||||
thd->lex->with_admin_option, hash_entry, revoke);
|
||||
|
||||
/*
|
||||
Only need to propagate grants when granting/revoking a role to/from
|
||||
|
@ -9205,6 +9231,10 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool handle_as_role)
|
|||
undo_add_role_user_mapping(grantee, role);
|
||||
result= TRUE;
|
||||
}
|
||||
else if (grantee)
|
||||
update_role_mapping(&thd->lex->definer->user,
|
||||
&thd->lex->definer->host,
|
||||
&user_name->user, true, NULL, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9591,6 +9621,8 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
|
|||
{
|
||||
result= -1; //Something went wrong
|
||||
}
|
||||
update_role_mapping(&lex_user->user, &lex_user->host,
|
||||
&role_grant->user, false, pair, true);
|
||||
/*
|
||||
Delete from the parent_grantee array of the roles granted,
|
||||
the entry pointing to this user_or_role
|
||||
|
|
Loading…
Reference in a new issue