Commit a44a924a authored by unknown's avatar unknown
Browse files

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.
parent 2efabfd1
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -855,3 +855,44 @@ f3
drop trigger trg11;
drop table t21,t31;
drop table t11;
STOP SLAVE;
FLUSH LOGS;
RESET SLAVE;
START SLAVE;
SELECT MASTER_POS_WAIT('master-bin.000001', 513) >= 0;
MASTER_POS_WAIT('master-bin.000001', 513) >= 0
1
SHOW TABLES;
Tables_in_test
t1
t2
SHOW TRIGGERS;
Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
trg1	INSERT	t1	INSERT INTO t2 VALUES(CURRENT_USER())	AFTER	NULL		
SELECT * FROM t1;
c
1
SELECT * FROM t2;
s
@
INSERT INTO t1 VALUES(2);
SELECT * FROM t1;
c
1
2
SELECT * FROM t2;
s
@
root@localhost
DROP TRIGGER trg1;
Warnings:
Warning	1454	No definer attribute for trigger 'test'.'trg1'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger.
DROP TABLE t1;
DROP TABLE t2;
STOP SLAVE;
RESET SLAVE;
SHOW TABLES;
Tables_in_test
SHOW TRIGGERS;
Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
RESET MASTER;
+532 B

File added.

No diff preview for this file type.

+74 −0
Original line number Diff line number Diff line
@@ -162,6 +162,7 @@ use test;
drop table t1,t2;
drop database other;


#
# Test specific triggers including SELECT into var with replication
# BUG#13227:
@@ -257,6 +258,79 @@ while ($rnd)
}


#
# BUG#16266: Definer is not fully qualified error during replication.
#
# The idea of this test is to emulate replication of a trigger from the old
# master (master w/o "DEFINER in triggers" support) to the new slave and check
# that:
#   1. the trigger on the slave will be replicated w/o errors;
#   2. the trigger on the slave will be non-SUID (will have no DEFINER);
#   3. the trigger can be activated later on the slave w/o errors.
#
# In order to emulate this kind of replication, we make the slave playing the binlog,
# recorded by 5.0.16 master. This binlog contains the following statements:
#   CREATE TABLE t1(c INT);
#   CREATE TABLE t2(s CHAR(200));
#   CREATE TRIGGER trg1 AFTER INSERT ON t1
#     FOR EACH ROW
#       INSERT INTO t2 VALUES(CURRENT_USER());
#   INSERT INTO t1 VALUES(1);
#

# 1. Check that the trigger's replication is succeeded.

# Stop the slave.

connection slave;
STOP SLAVE;

# Replace master's binlog.

connection master;
FLUSH LOGS;
exec cp $MYSQL_TEST_DIR/std_data/bug16266.000001 $MYSQLTEST_VARDIR/log/master-bin.000001;

# Make the slave to replay the new binlog.

connection slave;
RESET SLAVE;
START SLAVE;

SELECT MASTER_POS_WAIT('master-bin.000001', 513) >= 0;

# Check that the replication succeeded.

SHOW TABLES;
SHOW TRIGGERS;
SELECT * FROM t1;
SELECT * FROM t2;

# 2. Check that the trigger is non-SUID on the slave;
# 3. Check that the trigger can be activated on the slave.

INSERT INTO t1 VALUES(2);

SELECT * FROM t1;
SELECT * FROM t2;

# That's all, cleanup.

DROP TRIGGER trg1;
DROP TABLE t1;
DROP TABLE t2;

STOP SLAVE;
RESET SLAVE;

# The master should be clean.

connection master;
SHOW TABLES;
SHOW TRIGGERS;

RESET MASTER;


#
# End of tests
+1 −0
Original line number Diff line number Diff line
@@ -531,6 +531,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
                           TABLE_LIST *create_table);

bool get_default_definer(THD *thd, LEX_USER *definer);
LEX_USER *create_default_definer(THD *thd);
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name);

enum enum_mysql_completiontype {
+29 −1
Original line number Diff line number Diff line
@@ -7206,6 +7206,34 @@ bool get_default_definer(THD *thd, LEX_USER *definer)
}


/*
  Create default definer for the specified THD. Also check that the current
  user is conformed to the definers requirements.

  SYNOPSIS
    create_default_definer()
    thd         [in] thread handler

  RETURN
    On success, return a valid pointer to the created and initialized
    LEX_USER, which contains definer information.
    On error, return 0.
*/

LEX_USER *create_default_definer(THD *thd)
{
  LEX_USER *definer;

  if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
    return 0;

  if (get_default_definer(thd, definer))
    return 0;

  return definer;
}


/*
  Create definer with the given user and host names. Also check that the user
  and host names satisfy definers requirements.
@@ -7218,7 +7246,7 @@ bool get_default_definer(THD *thd, LEX_USER *definer)

  RETURN
    On success, return a valid pointer to the created and initialized
    LEX_STRING, which contains definer information.
    LEX_USER, which contains definer information.
    On error, return 0.
*/

Loading