mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Bug #42217 mysql.procs_priv does not get replicated
mysql.procs_priv table itself does not get replicated. Inserting routine privilege record into mysql.procs_priv table is triggered by creating function/procedure statements according to current user's privileges. Because the current user of SQL thread has GLOBAL_ACL, which doesn't need any check mysql.procs_priv privilege when create/alter/execute routines. Corresponding GLOBAL_ACL privilege user doesn't insert routine privilege record into mysql.procs_priv when creating a routine. Fixed by switching the current user of SQL thread to definer user if the definer user exists on slave. That populates procs_priv, otherwise to keep the SQL thread user and procs_priv remains unchanged. mysql-test/suite/rpl/r/rpl_do_grant.result: Test case result for routine privilege when definer user exist or not on slave mysql-test/suite/rpl/t/rpl_do_grant.test: Test case result for routine privilege when definer user exist or not on slave sql/sql_parse.cc: Switch current user of SQL thread to definer user if the definer user existes on slave when checking whether the routine privilege is needed to insert mysql.procs_priv table or not.
This commit is contained in:
@ -4129,9 +4129,32 @@ end_with_restore_list:
|
||||
|
||||
res= (sp_result= lex->sphead->create(thd));
|
||||
switch (sp_result) {
|
||||
case SP_OK:
|
||||
case SP_OK: {
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
/* only add privileges if really neccessary */
|
||||
|
||||
Security_context security_context;
|
||||
bool restore_backup_context= false;
|
||||
Security_context *backup= NULL;
|
||||
LEX_USER *definer= thd->lex->definer;
|
||||
/*
|
||||
Check if the definer exists on slave,
|
||||
then use definer privilege to insert routine privileges to mysql.procs_priv.
|
||||
|
||||
For current user of SQL thread has GLOBAL_ACL privilege,
|
||||
which doesn't any check routine privileges,
|
||||
so no routine privilege record will insert into mysql.procs_priv.
|
||||
*/
|
||||
if (thd->slave_thread && is_acl_user(definer->host.str, definer->user.str))
|
||||
{
|
||||
security_context.change_security_context(thd,
|
||||
&thd->lex->definer->user,
|
||||
&thd->lex->definer->host,
|
||||
&thd->lex->sphead->m_db,
|
||||
&backup);
|
||||
restore_backup_context= true;
|
||||
}
|
||||
|
||||
if (sp_automatic_privileges && !opt_noacl &&
|
||||
check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS,
|
||||
lex->sphead->m_db.str, name,
|
||||
@ -4143,8 +4166,19 @@ end_with_restore_list:
|
||||
ER_PROC_AUTO_GRANT_FAIL,
|
||||
ER(ER_PROC_AUTO_GRANT_FAIL));
|
||||
}
|
||||
|
||||
/*
|
||||
Restore current user with GLOBAL_ACL privilege of SQL thread
|
||||
*/
|
||||
if (restore_backup_context)
|
||||
{
|
||||
DBUG_ASSERT(thd->slave_thread == 1);
|
||||
thd->security_ctx->restore_security_context(thd, backup);
|
||||
}
|
||||
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case SP_WRITE_ROW_FAILED:
|
||||
my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name);
|
||||
break;
|
||||
|
Reference in New Issue
Block a user