mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-28294: set default role bypasses Replicate_Wild_Ignore_Table: mysql.%
Problem: ======== When replicating SET DEFAULT ROLE, the pre-update check (i.e. that in set_var_default_role::check()) tries to validate the existence of the given rules/user even when the targeted tables are ignored. When previously issued CREATE USER/ROLE commands are ignored by the replica because of the replication filtering rules, this results in an error because the targeted data does not exist. Solution: ======== Before checking that the given roles/user exist of a SET DEFAULT ROLE command, first ensure that the mysql.user and mysql.roles_mapping tables are not excluded by replication filters. Reviewed By: ============ Andrei Elkin <andrei.elkin@mariadb.com> Sergei Golubchik <serg@mariadb.com>
This commit is contained in:
committed by
Andrei
parent
c7f8cfc9e7
commit
8963d64ee8
@ -1249,18 +1249,8 @@ class Grant_tables
|
||||
DBUG_ENTER("Grant_tables::open_and_lock");
|
||||
DBUG_ASSERT(first_table_in_list);
|
||||
#ifdef HAVE_REPLICATION
|
||||
if (first_table_in_list->tl.lock_type >= TL_WRITE_ALLOW_WRITE &&
|
||||
thd->slave_thread && !thd->spcont)
|
||||
{
|
||||
/*
|
||||
GRANT and REVOKE are applied the slave in/exclusion rules as they are
|
||||
some kind of updates to the mysql.% tables.
|
||||
*/
|
||||
Rpl_filter *rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter;
|
||||
if (rpl_filter->is_on() &&
|
||||
!rpl_filter->tables_ok(0, &first_table_in_list->tl))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (int ignore_ret= rpl_ignore_tables(thd))
|
||||
DBUG_RETURN(ignore_ret);
|
||||
#endif
|
||||
if (open_and_lock_tables(thd, &first_table_in_list->tl, FALSE,
|
||||
MYSQL_LOCK_IGNORE_TIMEOUT))
|
||||
@ -1290,6 +1280,32 @@ class Grant_tables
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
/* Checks if the tables targeted by a grant command should be ignored because
|
||||
of the configured replication filters
|
||||
|
||||
@retval 1 Tables are excluded for replication
|
||||
@retval 0 tables are included for replication
|
||||
*/
|
||||
int rpl_ignore_tables(THD *thd)
|
||||
{
|
||||
DBUG_ENTER("Grant_tables::rpl_ignore_tables");
|
||||
if (first_table_in_list->tl.lock_type >= TL_WRITE_ALLOW_WRITE &&
|
||||
thd->slave_thread && !thd->spcont)
|
||||
{
|
||||
/*
|
||||
GRANT and REVOKE are applied the slave in/exclusion rules as they are
|
||||
some kind of updates to the mysql.% tables.
|
||||
*/
|
||||
Rpl_filter *rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter;
|
||||
if (rpl_filter->is_on() &&
|
||||
!rpl_filter->tables_ok(0, &first_table_in_list->tl))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline const User_table& user_table() const
|
||||
{
|
||||
return m_user_table;
|
||||
@ -3469,6 +3485,16 @@ int acl_check_set_default_role(THD *thd, const char *host, const char *user,
|
||||
const char *role)
|
||||
{
|
||||
DBUG_ENTER("acl_check_set_default_role");
|
||||
#ifdef HAVE_REPLICATION
|
||||
/*
|
||||
If the roles_mapping table is excluded by the replication filter, we return
|
||||
successful without validating the user/role data because the command will
|
||||
be ignored in a later call to `acl_set_default_role()` for a graceful exit.
|
||||
*/
|
||||
Grant_tables tables(Table_roles_mapping, TL_WRITE);
|
||||
if (tables.rpl_ignore_tables(thd))
|
||||
DBUG_RETURN(0);
|
||||
#endif
|
||||
DBUG_RETURN(check_alter_user(thd, host, user) ||
|
||||
check_user_can_set_role(thd, user, host, NULL, role, NULL));
|
||||
}
|
||||
|
Reference in New Issue
Block a user