summaryrefslogtreecommitdiff
path: root/sql/sql_trigger.cc
diff options
context:
space:
mode:
authorunknown <anozdrin@mysql.com>2006-03-01 14:13:07 +0300
committerunknown <anozdrin@mysql.com>2006-03-01 14:13:07 +0300
commita44a924a407ae1f1135a14ee750468e6fc88d9b0 (patch)
treebaf54f335b2a6ccc3c2d1da9406e0832ddb6c26b /sql/sql_trigger.cc
parent2efabfd11a6fa5621c851a472c076e4ef5184d6d (diff)
downloadmariadb-git-a44a924a407ae1f1135a14ee750468e6fc88d9b0.tar.gz
Fix for BUG#16266: Definer is not fully qualified error during replication.
The idea of the fix is to extend support of non-SUID triggers for backward compatibility. Formerly non-SUID triggers were appeared when "new" server is being started against "old" database. Now, they are also created when "new" slave receives updates from "old" master. mysql-test/r/rpl_trigger.result: Updated the result file with the results of the test for BUG#16266. mysql-test/t/rpl_trigger.test: Added the test case for BUG#16266. sql/mysql_priv.h: Added an utility operation to be used from sql_yacc.yy. sql/sql_parse.cc: Add a utility operation to be used from sql_yacc.yy. sql/sql_trigger.cc: Extend support of non-SUID triggers. sql/sql_view.cc: Initialize LEX::definer if DEFINER-clause is missing. sql/sql_yacc.yy: Extended support of non-SUID triggers. mysql-test/std_data/bug16266.000001: A new binlog file for testing a patch for BUG#16266.
Diffstat (limited to 'sql/sql_trigger.cc')
-rw-r--r--sql/sql_trigger.cc108
1 files changed, 84 insertions, 24 deletions
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 4c3ae5c032d..9ccc70d8ccd 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -264,7 +264,17 @@ end:
log_query.set((char *) 0, 0, system_charset_info); /* reset log_query */
log_query.append(STRING_WITH_LEN("CREATE "));
- append_definer(thd, &log_query, &definer_user, &definer_host);
+
+ if (definer_user.str && definer_host.str)
+ {
+ /*
+ Append definer-clause if the trigger is SUID (a usual trigger in
+ new MySQL versions).
+ */
+
+ append_definer(thd, &log_query, &definer_user, &definer_host);
+ }
+
log_query.append(thd->lex->trigger_definition_begin);
}
@@ -289,17 +299,30 @@ end:
LEX)
tables - table list containing one open table for which the
trigger is created.
- definer_user - [out] after a call it points to 0-terminated string,
- which contains user name part of the actual trigger
- definer. The caller is responsible to provide memory for
+ definer_user - [out] after a call it points to 0-terminated string or
+ contains the NULL-string:
+ - 0-terminated is returned if the trigger is SUID. The
+ string contains user name part of the actual trigger
+ definer.
+ - NULL-string is returned if the trigger is non-SUID.
+ Anyway, the caller is responsible to provide memory for
storing LEX_STRING object.
- definer_host - [out] after a call it points to 0-terminated string,
- which contains host name part of the actual trigger
- definer. The caller is responsible to provide memory for
+ definer_host - [out] after a call it points to 0-terminated string or
+ contains the NULL-string:
+ - 0-terminated string is returned if the trigger is
+ SUID. The string contains host name part of the
+ actual trigger definer.
+ - NULL-string is returned if the trigger is non-SUID.
+ Anyway, the caller is responsible to provide memory for
storing LEX_STRING object.
NOTE
- Assumes that trigger name is fully qualified.
+ - Assumes that trigger name is fully qualified.
+ - NULL-string means the following LEX_STRING instance:
+ { str = 0; length = 0 }.
+ - In other words, definer_user and definer_host should contain
+ simultaneously NULL-strings (non-SUID/old trigger) or valid strings
+ (SUID/new trigger).
RETURN VALUE
False - success
@@ -336,12 +359,30 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
return 1;
}
- /*
- Definer attribute of the Lex instance is always set in sql_yacc.yy when
- trigger is created.
- */
+ if (!lex->definer)
+ {
+ /*
+ DEFINER-clause is missing.
- DBUG_ASSERT(lex->definer);
+ If we are in slave thread, this means that we received CREATE TRIGGER
+ from the master, that does not support definer in triggers. So, we
+ should mark this trigger as non-SUID. Note that this does not happen
+ when we parse triggers' definitions during opening .TRG file.
+ LEX::definer is ignored in that case.
+
+ Otherwise, we should use CURRENT_USER() as definer.
+
+ NOTE: when CREATE TRIGGER statement is allowed to be executed in PS/SP,
+ it will be required to create the definer below in persistent MEM_ROOT
+ of PS/SP.
+ */
+
+ if (!thd->slave_thread)
+ {
+ if (!(lex->definer= create_default_definer(thd)))
+ return 1;
+ }
+ }
/*
If the specified definer differs from the current user, we should check
@@ -349,10 +390,11 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
under another user one must have SUPER privilege).
*/
- if (strcmp(lex->definer->user.str, thd->security_ctx->priv_user) ||
- my_strcasecmp(system_charset_info,
- lex->definer->host.str,
- thd->security_ctx->priv_host))
+ if (lex->definer &&
+ (strcmp(lex->definer->user.str, thd->security_ctx->priv_user) ||
+ my_strcasecmp(system_charset_info,
+ lex->definer->host.str,
+ thd->security_ctx->priv_host)))
{
if (check_global_access(thd, SUPER_ACL))
{
@@ -446,8 +488,8 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
*trg_sql_mode= thd->variables.sql_mode;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (!is_acl_user(lex->definer->host.str,
- lex->definer->user.str))
+ if (lex->definer && !is_acl_user(lex->definer->host.str,
+ lex->definer->user.str))
{
push_warning_printf(thd,
MYSQL_ERROR::WARN_LEVEL_NOTE,
@@ -458,12 +500,30 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
}
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
- *definer_user= lex->definer->user;
- *definer_host= lex->definer->host;
+ if (lex->definer)
+ {
+ /* SUID trigger. */
+
+ *definer_user= lex->definer->user;
+ *definer_host= lex->definer->host;
- trg_definer->str= trg_definer_holder;
- trg_definer->length= strxmov(trg_definer->str, definer_user->str, "@",
- definer_host->str, NullS) - trg_definer->str;
+ trg_definer->str= trg_definer_holder;
+ trg_definer->length= strxmov(trg_definer->str, definer_user->str, "@",
+ definer_host->str, NullS) - trg_definer->str;
+ }
+ else
+ {
+ /* non-SUID trigger. */
+
+ definer_user->str= 0;
+ definer_user->length= 0;
+
+ definer_host->str= 0;
+ definer_host->length= 0;
+
+ trg_definer->str= (char*) "";
+ trg_definer->length= 0;
+ }
if (!sql_create_definition_file(&dir, &file, &triggers_file_type,
(gptr)this, triggers_file_parameters, 0))