diff options
author | Brandon Nesterenko <brandon.nesterenko@mariadb.com> | 2022-04-26 19:51:42 -0600 |
---|---|---|
committer | Brandon Nesterenko <brandon.nesterenko@mariadb.com> | 2022-04-29 17:01:05 -0600 |
commit | 960223da39e6e7704b3b0e2de9fda404cc5f8d51 (patch) | |
tree | 101c69694eac4ebd4a306131cdadcdf66392bf93 /sql/sql_acl.cc | |
parent | 388032e99057449219d4a943b4407e36c42ec4af (diff) | |
download | mariadb-git-10.2-MDEV-28294-pre-exec.tar.gz |
MDEV-28294: set default role bypasses Replicate_Wild_Ignore_Table: mysql.%10.2-MDEV-28294-pre-exec
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 rules/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>
Diffstat (limited to 'sql/sql_acl.cc')
-rw-r--r-- | sql/sql_acl.cc | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f62dd5471eb..403c296ce10 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1428,6 +1428,50 @@ class Grant_tables return m_roles_mapping_table; } + /* + Outputs the TABLE_LIST corresponding to the table specification of + which_tables. + + @param which_tables [in] Bit map specifying which tables to include in the + output. See enum_acl_tables + + @param lock_type [in] Lock type for the tables + + @param tbls_out [out] Empty TABLE_LIST which will be populated using + the specification from which_tables + + @param n_tables [out] The number of tables output in tbls_out + */ + static void get_table_list(uint which_tables, enum thr_lock_type lock_type, + TABLE_LIST *tbls_out, size_t *n_tables) + { + DBUG_ENTER("Grant_tables::get_table_list"); + Grant_tables tables(which_tables, lock_type); + TABLE_LIST *my_tl= &(tables.first_table_in_list->tl); + *n_tables= 0; + DBUG_ASSERT(which_tables < ( 1 << TABLES_MAX)); + while (which_tables) + { + if (which_tables & 1) + { + tbls_out->init_one_table( + my_tl->db, my_tl->db_length, my_tl->table_name, + my_tl->table_name_length, my_tl->alias, my_tl->lock_type); + *n_tables+= 1; + + /* + Stop if this was the last table to populate + */ + if (!(tbls_out->next_local)) + break; + + tbls_out= tbls_out->next_local; + } + which_tables >>= 1; + } + DBUG_VOID_RETURN; + } + private: User_table m_user_table; Db_table m_db_table; @@ -3558,6 +3602,21 @@ WSREP_ERROR_LABEL: DBUG_RETURN(result); } +void acl_get_tables_set_password(TABLE_LIST *tables, size_t *n_tables) +{ + DBUG_ENTER("acl_get_tables_set_password"); + Grant_tables::get_table_list(Table_user, TL_WRITE, tables, n_tables); + DBUG_VOID_RETURN; +} + +void acl_get_tables_set_default_role(TABLE_LIST *tables, size_t *n_tables) +{ + DBUG_ENTER("acl_get_tables_set_default_role"); + Grant_tables::get_table_list(Table_roles_mapping, TL_WRITE, tables, + n_tables); + DBUG_VOID_RETURN; +} + int acl_check_set_default_role(THD *thd, const char *host, const char *user, const char *role) { |