mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 21:12:26 +01:00
Merge jbruehe@bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/M50/bug16730-5.0
This commit is contained in:
commit
0ab30e24e8
7 changed files with 559 additions and 372 deletions
|
@ -65,109 +65,6 @@ user_str
|
|||
mysqltest_dfn@localhost
|
||||
mysqltest_dfn@localhost
|
||||
|
||||
---> connection: default
|
||||
use mysqltest_db1;
|
||||
REVOKE SELECT ON mysqltest_db1.t1 FROM mysqltest_dfn@localhost;
|
||||
|
||||
---> connection: wl2818_definer_con
|
||||
use mysqltest_db1;
|
||||
DROP TRIGGER trg1;
|
||||
SET @new_sum = 0;
|
||||
SET @old_sum = 0;
|
||||
---> INSERT INTO statement; BEFORE timing
|
||||
CREATE TRIGGER trg1 BEFORE INSERT ON t1
|
||||
FOR EACH ROW
|
||||
SET @new_sum = @new_sum + NEW.num_value;
|
||||
INSERT INTO t1 VALUES(4);
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
|
||||
---> INSERT INTO statement; AFTER timing
|
||||
DROP TRIGGER trg1;
|
||||
CREATE TRIGGER trg1 AFTER INSERT ON t1
|
||||
FOR EACH ROW
|
||||
SET @new_sum = @new_sum + NEW.num_value;
|
||||
INSERT INTO t1 VALUES(5);
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
|
||||
---> UPDATE statement; BEFORE timing
|
||||
DROP TRIGGER trg1;
|
||||
CREATE TRIGGER trg1 BEFORE UPDATE ON t1
|
||||
FOR EACH ROW
|
||||
SET @old_sum = @old_sum + OLD.num_value;
|
||||
UPDATE t1 SET num_value = 10;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
|
||||
---> UPDATE statement; AFTER timing
|
||||
DROP TRIGGER trg1;
|
||||
CREATE TRIGGER trg1 AFTER UPDATE ON t1
|
||||
FOR EACH ROW
|
||||
SET @new_sum = @new_sum + NEW.num_value;
|
||||
UPDATE t1 SET num_value = 20;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
|
||||
---> DELETE statement; BEFORE timing
|
||||
DROP TRIGGER trg1;
|
||||
CREATE TRIGGER trg1 BEFORE DELETE ON t1
|
||||
FOR EACH ROW
|
||||
SET @old_sum = @old_sum + OLD.num_value;
|
||||
DELETE FROM t1;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
|
||||
---> DELETE statement; AFTER timing
|
||||
DROP TRIGGER trg1;
|
||||
CREATE TRIGGER trg1 AFTER DELETE ON t1
|
||||
FOR EACH ROW
|
||||
SET @old_sum = @old_sum + OLD.num_value;
|
||||
DELETE FROM t1;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
|
||||
|
||||
---> connection: default
|
||||
use mysqltest_db1;
|
||||
GRANT SELECT ON mysqltest_db1.t1 TO mysqltest_dfn@localhost;
|
||||
REVOKE UPDATE ON mysqltest_db1.t1 FROM mysqltest_dfn@localhost;
|
||||
|
||||
---> connection: wl2818_definer_con
|
||||
use mysqltest_db1;
|
||||
DROP TRIGGER trg1;
|
||||
SET @new_sum = 0;
|
||||
SET @old_sum = 0;
|
||||
---> INSERT INTO statement; BEFORE timing
|
||||
CREATE TRIGGER trg1 BEFORE INSERT ON t1
|
||||
FOR EACH ROW
|
||||
SET @new_sum = @new_sum + NEW.num_value;
|
||||
INSERT INTO t1 VALUES(4);
|
||||
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
|
||||
---> INSERT INTO statement; AFTER timing
|
||||
DROP TRIGGER trg1;
|
||||
CREATE TRIGGER trg1 AFTER INSERT ON t1
|
||||
FOR EACH ROW
|
||||
SET @new_sum = @new_sum + NEW.num_value;
|
||||
INSERT INTO t1 VALUES(5);
|
||||
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
|
||||
---> UPDATE statement; BEFORE timing
|
||||
DROP TRIGGER trg1;
|
||||
CREATE TRIGGER trg1 BEFORE UPDATE ON t1
|
||||
FOR EACH ROW
|
||||
SET @old_sum = @old_sum + OLD.num_value;
|
||||
UPDATE t1 SET num_value = 10;
|
||||
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
|
||||
---> UPDATE statement; AFTER timing
|
||||
DROP TRIGGER trg1;
|
||||
CREATE TRIGGER trg1 AFTER UPDATE ON t1
|
||||
FOR EACH ROW
|
||||
SET @new_sum = @new_sum + NEW.num_value;
|
||||
UPDATE t1 SET num_value = 20;
|
||||
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
|
||||
---> DELETE statement; BEFORE timing
|
||||
DROP TRIGGER trg1;
|
||||
CREATE TRIGGER trg1 BEFORE DELETE ON t1
|
||||
FOR EACH ROW
|
||||
SET @old_sum = @old_sum + OLD.num_value;
|
||||
DELETE FROM t1;
|
||||
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
|
||||
---> DELETE statement; AFTER timing
|
||||
DROP TRIGGER trg1;
|
||||
CREATE TRIGGER trg1 AFTER DELETE ON t1
|
||||
FOR EACH ROW
|
||||
SET @old_sum = @old_sum + OLD.num_value;
|
||||
DELETE FROM t1;
|
||||
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
|
||||
|
||||
---> connection: wl2818_definer_con
|
||||
use mysqltest_db1;
|
||||
DROP TRIGGER trg1;
|
||||
|
@ -229,3 +126,187 @@ DROP USER mysqltest_inv@localhost;
|
|||
DROP DATABASE mysqltest_db1;
|
||||
Warnings:
|
||||
Warning 1454 No definer attribute for trigger 'mysqltest_db1'.'trg1'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger.
|
||||
DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
|
||||
DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
|
||||
DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
|
||||
DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%';
|
||||
FLUSH PRIVILEGES;
|
||||
DROP DATABASE IF EXISTS mysqltest_db1;
|
||||
CREATE DATABASE mysqltest_db1;
|
||||
use mysqltest_db1;
|
||||
CREATE TABLE t1(col CHAR(20));
|
||||
CREATE TABLE t2(col CHAR(20));
|
||||
CREATE TABLE t3(col CHAR(20));
|
||||
CREATE TABLE t4(col CHAR(20));
|
||||
CREATE USER mysqltest_u1@localhost;
|
||||
REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost;
|
||||
GRANT SUPER ON *.* TO mysqltest_u1@localhost;
|
||||
GRANT SELECT ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
|
||||
SET @mysqltest_var = NULL;
|
||||
|
||||
---> connection: default
|
||||
use mysqltest_db1;
|
||||
REVOKE SELECT ON mysqltest_db1.t1 FROM mysqltest_u1@localhost;
|
||||
GRANT DELETE ON mysqltest_db1.* TO mysqltest_u1@localhost;
|
||||
SHOW GRANTS FOR mysqltest_u1@localhost;
|
||||
Grants for mysqltest_u1@localhost
|
||||
GRANT SUPER ON *.* TO 'mysqltest_u1'@'localhost'
|
||||
GRANT DELETE ON `mysqltest_db1`.* TO 'mysqltest_u1'@'localhost'
|
||||
|
||||
---> connection: bug15166_u1_con
|
||||
use mysqltest_db1;
|
||||
CREATE TRIGGER t1_trg_after_delete AFTER DELETE ON t1
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = 'Hello, world!';
|
||||
|
||||
---> connection: default
|
||||
use mysqltest_db1;
|
||||
GRANT UPDATE ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
|
||||
GRANT UPDATE ON mysqltest_db1.t2 TO mysqltest_u1@localhost;
|
||||
GRANT UPDATE(col) ON mysqltest_db1.t3 TO mysqltest_u1@localhost;
|
||||
GRANT UPDATE(col) ON mysqltest_db1.t4 TO mysqltest_u1@localhost;
|
||||
|
||||
---> connection: bug15166_u1_con
|
||||
use mysqltest_db1;
|
||||
CREATE TRIGGER t1_trg_err_1 BEFORE INSERT ON t1
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = NEW.col;
|
||||
DROP TRIGGER t1_trg_err_1;
|
||||
CREATE TRIGGER t1_trg_err_2 BEFORE DELETE ON t1
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = OLD.col;
|
||||
DROP TRIGGER t1_trg_err_2;
|
||||
CREATE TRIGGER t2_trg_before_insert BEFORE INSERT ON t2
|
||||
FOR EACH ROW
|
||||
SET NEW.col = 't2_trg_before_insert';
|
||||
CREATE TRIGGER t3_trg_err_1 BEFORE INSERT ON t3
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = NEW.col;
|
||||
DROP TRIGGER t3_trg_err_1;
|
||||
CREATE TRIGGER t3_trg_err_2 BEFORE DELETE ON t3
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = OLD.col;
|
||||
DROP TRIGGER t3_trg_err_2;
|
||||
CREATE TRIGGER t4_trg_before_insert BEFORE INSERT ON t4
|
||||
FOR EACH ROW
|
||||
SET NEW.col = 't4_trg_before_insert';
|
||||
|
||||
---> connection: default
|
||||
use mysqltest_db1;
|
||||
REVOKE UPDATE ON mysqltest_db1.t1 FROM mysqltest_u1@localhost;
|
||||
REVOKE UPDATE ON mysqltest_db1.t2 FROM mysqltest_u1@localhost;
|
||||
GRANT SELECT ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
|
||||
GRANT SELECT ON mysqltest_db1.t2 TO mysqltest_u1@localhost;
|
||||
REVOKE UPDATE(col) ON mysqltest_db1.t3 FROM mysqltest_u1@localhost;
|
||||
REVOKE UPDATE(col) ON mysqltest_db1.t4 FROM mysqltest_u1@localhost;
|
||||
GRANT SELECT(col) on mysqltest_db1.t3 TO mysqltest_u1@localhost;
|
||||
GRANT SELECT(col) on mysqltest_db1.t4 TO mysqltest_u1@localhost;
|
||||
|
||||
---> connection: bug15166_u1_con
|
||||
use mysqltest_db1;
|
||||
CREATE TRIGGER t1_trg_after_insert AFTER INSERT ON t1
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = NEW.col;
|
||||
CREATE TRIGGER t1_trg_after_update AFTER UPDATE ON t1
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = OLD.col;
|
||||
CREATE TRIGGER t2_trg_err_1 BEFORE UPDATE ON t2
|
||||
FOR EACH ROW
|
||||
SET NEW.col = 't2_trg_err_1';
|
||||
DROP TRIGGER t2_trg_err_1;
|
||||
CREATE TRIGGER t2_trg_err_2 BEFORE UPDATE ON t2
|
||||
FOR EACH ROW
|
||||
SET NEW.col = CONCAT(OLD.col, '(updated)');
|
||||
DROP TRIGGER t2_trg_err_2;
|
||||
CREATE TRIGGER t3_trg_after_insert AFTER INSERT ON t3
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = NEW.col;
|
||||
CREATE TRIGGER t3_trg_after_update AFTER UPDATE ON t3
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = OLD.col;
|
||||
CREATE TRIGGER t4_trg_err_1 BEFORE UPDATE ON t4
|
||||
FOR EACH ROW
|
||||
SET NEW.col = 't4_trg_err_1';
|
||||
DROP TRIGGER t4_trg_err_1;
|
||||
CREATE TRIGGER t4_trg_err_2 BEFORE UPDATE ON t4
|
||||
FOR EACH ROW
|
||||
SET NEW.col = CONCAT(OLD.col, '(updated)');
|
||||
DROP TRIGGER t4_trg_err_2;
|
||||
|
||||
---> connection: default
|
||||
use mysqltest_db1;
|
||||
REVOKE SELECT ON mysqltest_db1.t1 FROM mysqltest_u1@localhost;
|
||||
REVOKE SELECT ON mysqltest_db1.t2 FROM mysqltest_u1@localhost;
|
||||
GRANT UPDATE ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
|
||||
GRANT UPDATE ON mysqltest_db1.t2 TO mysqltest_u1@localhost;
|
||||
REVOKE SELECT(col) ON mysqltest_db1.t3 FROM mysqltest_u1@localhost;
|
||||
REVOKE SELECT(col) ON mysqltest_db1.t4 FROM mysqltest_u1@localhost;
|
||||
GRANT UPDATE(col) ON mysqltest_db1.t3 TO mysqltest_u1@localhost;
|
||||
GRANT UPDATE(col) ON mysqltest_db1.t4 TO mysqltest_u1@localhost;
|
||||
INSERT INTO t1 VALUES('line1');
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for column 'col' in table 't1'
|
||||
SELECT * FROM t1;
|
||||
col
|
||||
line1
|
||||
SELECT @mysqltest_var;
|
||||
@mysqltest_var
|
||||
NULL
|
||||
INSERT INTO t2 VALUES('line2');
|
||||
SELECT * FROM t2;
|
||||
col
|
||||
t2_trg_before_insert
|
||||
INSERT INTO t3 VALUES('t3_line1');
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for column 'col' in table 't3'
|
||||
SELECT * FROM t3;
|
||||
col
|
||||
t3_line1
|
||||
SELECT @mysqltest_var;
|
||||
@mysqltest_var
|
||||
NULL
|
||||
INSERT INTO t4 VALUES('t4_line2');
|
||||
SELECT * FROM t4;
|
||||
col
|
||||
t4_trg_before_insert
|
||||
|
||||
---> connection: default
|
||||
use mysqltest_db1;
|
||||
REVOKE UPDATE ON mysqltest_db1.t1 FROM mysqltest_u1@localhost;
|
||||
REVOKE UPDATE ON mysqltest_db1.t2 FROM mysqltest_u1@localhost;
|
||||
GRANT SELECT ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
|
||||
GRANT SELECT ON mysqltest_db1.t2 TO mysqltest_u1@localhost;
|
||||
REVOKE UPDATE(col) ON mysqltest_db1.t3 FROM mysqltest_u1@localhost;
|
||||
REVOKE UPDATE(col) ON mysqltest_db1.t4 FROM mysqltest_u1@localhost;
|
||||
GRANT SELECT(col) ON mysqltest_db1.t3 TO mysqltest_u1@localhost;
|
||||
GRANT SELECT(col) ON mysqltest_db1.t4 TO mysqltest_u1@localhost;
|
||||
INSERT INTO t1 VALUES('line3');
|
||||
SELECT * FROM t1;
|
||||
col
|
||||
line1
|
||||
line3
|
||||
SELECT @mysqltest_var;
|
||||
@mysqltest_var
|
||||
line3
|
||||
INSERT INTO t2 VALUES('line4');
|
||||
ERROR 42000: UPDATE command denied to user 'mysqltest_u1'@'localhost' for column 'col' in table 't2'
|
||||
SELECT * FROM t2;
|
||||
col
|
||||
t2_trg_before_insert
|
||||
INSERT INTO t3 VALUES('t3_line2');
|
||||
SELECT * FROM t3;
|
||||
col
|
||||
t3_line1
|
||||
t3_line2
|
||||
SELECT @mysqltest_var;
|
||||
@mysqltest_var
|
||||
t3_line2
|
||||
INSERT INTO t4 VALUES('t4_line2');
|
||||
ERROR 42000: UPDATE command denied to user 'mysqltest_u1'@'localhost' for column 'col' in table 't4'
|
||||
SELECT * FROM t4;
|
||||
col
|
||||
t4_trg_before_insert
|
||||
DELETE FROM t1;
|
||||
SELECT @mysqltest_var;
|
||||
@mysqltest_var
|
||||
Hello, world!
|
||||
DROP USER mysqltest_u1@localhost;
|
||||
DROP DATABASE mysqltest_db1;
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
#
|
||||
# Tests for WL#2818:
|
||||
# - Check that triggers are executed under the authorization of the definer.
|
||||
# - Check that if trigger contains NEW/OLD variables, the definer must have
|
||||
# SELECT privilege on the subject table.
|
||||
# - Check DEFINER clause of CREATE TRIGGER statement;
|
||||
# - Check that SUPER privilege required to create a trigger with different
|
||||
# definer.
|
||||
|
@ -18,6 +16,8 @@
|
|||
# - Check that the definer of a trigger does not exist, the trigger will
|
||||
# not be activated.
|
||||
# - Check that SHOW TRIGGERS statement provides "Definer" column.
|
||||
# - Check that if trigger contains NEW/OLD variables, the definer must have
|
||||
# SELECT privilege on the subject table (aka BUG#15166/BUG#15196).
|
||||
#
|
||||
# Let's also check that user name part of definer can contain '@' symbol (to
|
||||
# check that triggers are not affected by BUG#13310 "incorrect user parsing
|
||||
|
@ -142,223 +142,6 @@ INSERT INTO t1 VALUES(3);
|
|||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
|
||||
#
|
||||
# Check that if trigger contains NEW/OLD variables, the definer must have
|
||||
# SELECT/UPDATE privilege on the subject table:
|
||||
# - drop the trigger;
|
||||
# - create a new trigger, which will use NEW variable;
|
||||
# - create another new trigger, which will use OLD variable;
|
||||
# - revoke SELECT/UPDATE privilege on the first table from "definer";
|
||||
# - insert a row into the first table;
|
||||
# - analyze error code;
|
||||
#
|
||||
|
||||
#
|
||||
# SELECT privilege.
|
||||
#
|
||||
|
||||
--connection default
|
||||
--echo
|
||||
--echo ---> connection: default
|
||||
|
||||
use mysqltest_db1;
|
||||
|
||||
REVOKE SELECT ON mysqltest_db1.t1 FROM mysqltest_dfn@localhost;
|
||||
|
||||
--connection wl2818_definer_con
|
||||
--echo
|
||||
--echo ---> connection: wl2818_definer_con
|
||||
|
||||
use mysqltest_db1;
|
||||
|
||||
DROP TRIGGER trg1;
|
||||
|
||||
SET @new_sum = 0;
|
||||
SET @old_sum = 0;
|
||||
|
||||
# INSERT INTO statement; BEFORE timing
|
||||
|
||||
--echo ---> INSERT INTO statement; BEFORE timing
|
||||
|
||||
CREATE TRIGGER trg1 BEFORE INSERT ON t1
|
||||
FOR EACH ROW
|
||||
SET @new_sum = @new_sum + NEW.num_value;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
INSERT INTO t1 VALUES(4);
|
||||
|
||||
# INSERT INTO statement; AFTER timing
|
||||
|
||||
--echo ---> INSERT INTO statement; AFTER timing
|
||||
|
||||
DROP TRIGGER trg1;
|
||||
|
||||
CREATE TRIGGER trg1 AFTER INSERT ON t1
|
||||
FOR EACH ROW
|
||||
SET @new_sum = @new_sum + NEW.num_value;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
INSERT INTO t1 VALUES(5);
|
||||
|
||||
# UPDATE statement; BEFORE timing
|
||||
|
||||
--echo ---> UPDATE statement; BEFORE timing
|
||||
|
||||
DROP TRIGGER trg1;
|
||||
|
||||
CREATE TRIGGER trg1 BEFORE UPDATE ON t1
|
||||
FOR EACH ROW
|
||||
SET @old_sum = @old_sum + OLD.num_value;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
UPDATE t1 SET num_value = 10;
|
||||
|
||||
# UPDATE statement; AFTER timing
|
||||
|
||||
--echo ---> UPDATE statement; AFTER timing
|
||||
|
||||
DROP TRIGGER trg1;
|
||||
|
||||
CREATE TRIGGER trg1 AFTER UPDATE ON t1
|
||||
FOR EACH ROW
|
||||
SET @new_sum = @new_sum + NEW.num_value;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
UPDATE t1 SET num_value = 20;
|
||||
|
||||
# DELETE statement; BEFORE timing
|
||||
|
||||
--echo ---> DELETE statement; BEFORE timing
|
||||
|
||||
DROP TRIGGER trg1;
|
||||
|
||||
CREATE TRIGGER trg1 BEFORE DELETE ON t1
|
||||
FOR EACH ROW
|
||||
SET @old_sum = @old_sum + OLD.num_value;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
DELETE FROM t1;
|
||||
|
||||
# DELETE statement; AFTER timing
|
||||
|
||||
--echo ---> DELETE statement; AFTER timing
|
||||
|
||||
DROP TRIGGER trg1;
|
||||
|
||||
CREATE TRIGGER trg1 AFTER DELETE ON t1
|
||||
FOR EACH ROW
|
||||
SET @old_sum = @old_sum + OLD.num_value;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
DELETE FROM t1;
|
||||
|
||||
#
|
||||
# UPDATE privilege
|
||||
#
|
||||
# NOTE: At the moment, UPDATE privilege is required if the trigger contains
|
||||
# NEW/OLD variables, whenever the trigger modifies them or not. Moreover,
|
||||
# UPDATE privilege is checked for whole table, not for individual columns.
|
||||
#
|
||||
# The following test cases should be changed when full support of UPDATE
|
||||
# privilege will be done.
|
||||
#
|
||||
|
||||
--connection default
|
||||
--echo
|
||||
--echo ---> connection: default
|
||||
|
||||
use mysqltest_db1;
|
||||
|
||||
GRANT SELECT ON mysqltest_db1.t1 TO mysqltest_dfn@localhost;
|
||||
REVOKE UPDATE ON mysqltest_db1.t1 FROM mysqltest_dfn@localhost;
|
||||
|
||||
--connection wl2818_definer_con
|
||||
--echo
|
||||
--echo ---> connection: wl2818_definer_con
|
||||
|
||||
use mysqltest_db1;
|
||||
|
||||
DROP TRIGGER trg1;
|
||||
|
||||
SET @new_sum = 0;
|
||||
SET @old_sum = 0;
|
||||
|
||||
# INSERT INTO statement; BEFORE timing
|
||||
|
||||
--echo ---> INSERT INTO statement; BEFORE timing
|
||||
|
||||
CREATE TRIGGER trg1 BEFORE INSERT ON t1
|
||||
FOR EACH ROW
|
||||
SET @new_sum = @new_sum + NEW.num_value;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
INSERT INTO t1 VALUES(4);
|
||||
|
||||
# INSERT INTO statement; AFTER timing
|
||||
|
||||
--echo ---> INSERT INTO statement; AFTER timing
|
||||
|
||||
DROP TRIGGER trg1;
|
||||
|
||||
CREATE TRIGGER trg1 AFTER INSERT ON t1
|
||||
FOR EACH ROW
|
||||
SET @new_sum = @new_sum + NEW.num_value;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
INSERT INTO t1 VALUES(5);
|
||||
|
||||
# UPDATE statement; BEFORE timing
|
||||
|
||||
--echo ---> UPDATE statement; BEFORE timing
|
||||
|
||||
DROP TRIGGER trg1;
|
||||
|
||||
CREATE TRIGGER trg1 BEFORE UPDATE ON t1
|
||||
FOR EACH ROW
|
||||
SET @old_sum = @old_sum + OLD.num_value;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
UPDATE t1 SET num_value = 10;
|
||||
|
||||
# UPDATE statement; AFTER timing
|
||||
|
||||
--echo ---> UPDATE statement; AFTER timing
|
||||
|
||||
DROP TRIGGER trg1;
|
||||
|
||||
CREATE TRIGGER trg1 AFTER UPDATE ON t1
|
||||
FOR EACH ROW
|
||||
SET @new_sum = @new_sum + NEW.num_value;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
UPDATE t1 SET num_value = 20;
|
||||
|
||||
# DELETE statement; BEFORE timing
|
||||
|
||||
--echo ---> DELETE statement; BEFORE timing
|
||||
|
||||
DROP TRIGGER trg1;
|
||||
|
||||
CREATE TRIGGER trg1 BEFORE DELETE ON t1
|
||||
FOR EACH ROW
|
||||
SET @old_sum = @old_sum + OLD.num_value;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
DELETE FROM t1;
|
||||
|
||||
# DELETE statement; AFTER timing
|
||||
|
||||
--echo ---> DELETE statement; AFTER timing
|
||||
|
||||
DROP TRIGGER trg1;
|
||||
|
||||
CREATE TRIGGER trg1 AFTER DELETE ON t1
|
||||
FOR EACH ROW
|
||||
SET @old_sum = @old_sum + OLD.num_value;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
DELETE FROM t1;
|
||||
|
||||
#
|
||||
# Check DEFINER clause of CREATE TRIGGER statement.
|
||||
#
|
||||
|
@ -473,3 +256,311 @@ DROP USER mysqltest_dfn@localhost;
|
|||
DROP USER mysqltest_inv@localhost;
|
||||
|
||||
DROP DATABASE mysqltest_db1;
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# BUG#15166: Wrong update [was: select/update] permissions required to execute
|
||||
# triggers.
|
||||
#
|
||||
# BUG#15196: Wrong select permission required to execute triggers.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
#
|
||||
# Prepare environment.
|
||||
#
|
||||
|
||||
DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
|
||||
DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
|
||||
DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
|
||||
DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%';
|
||||
FLUSH PRIVILEGES;
|
||||
|
||||
--disable_warnings
|
||||
DROP DATABASE IF EXISTS mysqltest_db1;
|
||||
--enable_warnings
|
||||
|
||||
CREATE DATABASE mysqltest_db1;
|
||||
|
||||
use mysqltest_db1;
|
||||
|
||||
# Tables for tesing table-level privileges:
|
||||
CREATE TABLE t1(col CHAR(20)); # table for "read-value" trigger
|
||||
CREATE TABLE t2(col CHAR(20)); # table for "write-value" trigger
|
||||
|
||||
# Tables for tesing column-level privileges:
|
||||
CREATE TABLE t3(col CHAR(20)); # table for "read-value" trigger
|
||||
CREATE TABLE t4(col CHAR(20)); # table for "write-value" trigger
|
||||
|
||||
CREATE USER mysqltest_u1@localhost;
|
||||
REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost;
|
||||
GRANT SUPER ON *.* TO mysqltest_u1@localhost;
|
||||
GRANT SELECT ON mysqltest_db1.t1 TO mysqltest_u1@localhost; # to allow connect
|
||||
|
||||
SET @mysqltest_var = NULL;
|
||||
|
||||
--connect (bug15166_u1_con,localhost,mysqltest_u1,,mysqltest_db1)
|
||||
|
||||
# parsing (CREATE TRIGGER) time:
|
||||
# - check that nor SELECT either UPDATE is required to execute triggger w/o
|
||||
# NEW/OLD variables.
|
||||
|
||||
--connection default
|
||||
--echo
|
||||
--echo ---> connection: default
|
||||
|
||||
use mysqltest_db1;
|
||||
|
||||
REVOKE SELECT ON mysqltest_db1.t1 FROM mysqltest_u1@localhost;
|
||||
GRANT DELETE ON mysqltest_db1.* TO mysqltest_u1@localhost;
|
||||
SHOW GRANTS FOR mysqltest_u1@localhost;
|
||||
|
||||
--connection bug15166_u1_con
|
||||
--echo
|
||||
--echo ---> connection: bug15166_u1_con
|
||||
|
||||
use mysqltest_db1;
|
||||
|
||||
CREATE TRIGGER t1_trg_after_delete AFTER DELETE ON t1
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = 'Hello, world!';
|
||||
|
||||
# parsing (CREATE TRIGGER) time:
|
||||
# - check that UPDATE is not enough to read the value;
|
||||
# - check that UPDATE is required to modify the value;
|
||||
|
||||
--connection default
|
||||
--echo
|
||||
--echo ---> connection: default
|
||||
|
||||
use mysqltest_db1;
|
||||
|
||||
GRANT UPDATE ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
|
||||
GRANT UPDATE ON mysqltest_db1.t2 TO mysqltest_u1@localhost;
|
||||
|
||||
GRANT UPDATE(col) ON mysqltest_db1.t3 TO mysqltest_u1@localhost;
|
||||
GRANT UPDATE(col) ON mysqltest_db1.t4 TO mysqltest_u1@localhost;
|
||||
|
||||
--connection bug15166_u1_con
|
||||
--echo
|
||||
--echo ---> connection: bug15166_u1_con
|
||||
|
||||
use mysqltest_db1;
|
||||
|
||||
# - table-level privileges
|
||||
|
||||
# TODO: check privileges at CREATE TRIGGER time.
|
||||
# --error ER_COLUMNACCESS_DENIED_ERROR
|
||||
CREATE TRIGGER t1_trg_err_1 BEFORE INSERT ON t1
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = NEW.col;
|
||||
DROP TRIGGER t1_trg_err_1;
|
||||
|
||||
# TODO: check privileges at CREATE TRIGGER time.
|
||||
# --error ER_COLUMNACCESS_DENIED_ERROR
|
||||
CREATE TRIGGER t1_trg_err_2 BEFORE DELETE ON t1
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = OLD.col;
|
||||
DROP TRIGGER t1_trg_err_2;
|
||||
|
||||
CREATE TRIGGER t2_trg_before_insert BEFORE INSERT ON t2
|
||||
FOR EACH ROW
|
||||
SET NEW.col = 't2_trg_before_insert';
|
||||
|
||||
# - column-level privileges
|
||||
|
||||
# TODO: check privileges at CREATE TRIGGER time.
|
||||
# --error ER_COLUMNACCESS_DENIED_ERROR
|
||||
CREATE TRIGGER t3_trg_err_1 BEFORE INSERT ON t3
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = NEW.col;
|
||||
DROP TRIGGER t3_trg_err_1;
|
||||
|
||||
# TODO: check privileges at CREATE TRIGGER time.
|
||||
# --error ER_COLUMNACCESS_DENIED_ERROR
|
||||
CREATE TRIGGER t3_trg_err_2 BEFORE DELETE ON t3
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = OLD.col;
|
||||
DROP TRIGGER t3_trg_err_2;
|
||||
|
||||
CREATE TRIGGER t4_trg_before_insert BEFORE INSERT ON t4
|
||||
FOR EACH ROW
|
||||
SET NEW.col = 't4_trg_before_insert';
|
||||
|
||||
# parsing (CREATE TRIGGER) time:
|
||||
# - check that SELECT is required to read the value;
|
||||
# - check that SELECT is not enough to modify the value;
|
||||
|
||||
--connection default
|
||||
--echo
|
||||
--echo ---> connection: default
|
||||
|
||||
use mysqltest_db1;
|
||||
|
||||
REVOKE UPDATE ON mysqltest_db1.t1 FROM mysqltest_u1@localhost;
|
||||
REVOKE UPDATE ON mysqltest_db1.t2 FROM mysqltest_u1@localhost;
|
||||
GRANT SELECT ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
|
||||
GRANT SELECT ON mysqltest_db1.t2 TO mysqltest_u1@localhost;
|
||||
|
||||
REVOKE UPDATE(col) ON mysqltest_db1.t3 FROM mysqltest_u1@localhost;
|
||||
REVOKE UPDATE(col) ON mysqltest_db1.t4 FROM mysqltest_u1@localhost;
|
||||
GRANT SELECT(col) on mysqltest_db1.t3 TO mysqltest_u1@localhost;
|
||||
GRANT SELECT(col) on mysqltest_db1.t4 TO mysqltest_u1@localhost;
|
||||
|
||||
--connection bug15166_u1_con
|
||||
--echo
|
||||
--echo ---> connection: bug15166_u1_con
|
||||
|
||||
use mysqltest_db1;
|
||||
|
||||
# - table-level privileges
|
||||
|
||||
CREATE TRIGGER t1_trg_after_insert AFTER INSERT ON t1
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = NEW.col;
|
||||
|
||||
CREATE TRIGGER t1_trg_after_update AFTER UPDATE ON t1
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = OLD.col;
|
||||
|
||||
# TODO: check privileges at CREATE TRIGGER time.
|
||||
# --error ER_COLUMNACCESS_DENIED_ERROR
|
||||
CREATE TRIGGER t2_trg_err_1 BEFORE UPDATE ON t2
|
||||
FOR EACH ROW
|
||||
SET NEW.col = 't2_trg_err_1';
|
||||
DROP TRIGGER t2_trg_err_1;
|
||||
|
||||
# TODO: check privileges at CREATE TRIGGER time.
|
||||
# --error ER_COLUMNACCESS_DENIED_ERROR
|
||||
CREATE TRIGGER t2_trg_err_2 BEFORE UPDATE ON t2
|
||||
FOR EACH ROW
|
||||
SET NEW.col = CONCAT(OLD.col, '(updated)');
|
||||
DROP TRIGGER t2_trg_err_2;
|
||||
|
||||
# - column-level privileges
|
||||
|
||||
CREATE TRIGGER t3_trg_after_insert AFTER INSERT ON t3
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = NEW.col;
|
||||
|
||||
CREATE TRIGGER t3_trg_after_update AFTER UPDATE ON t3
|
||||
FOR EACH ROW
|
||||
SET @mysqltest_var = OLD.col;
|
||||
|
||||
# TODO: check privileges at CREATE TRIGGER time.
|
||||
# --error ER_COLUMNACCESS_DENIED_ERROR
|
||||
CREATE TRIGGER t4_trg_err_1 BEFORE UPDATE ON t4
|
||||
FOR EACH ROW
|
||||
SET NEW.col = 't4_trg_err_1';
|
||||
DROP TRIGGER t4_trg_err_1;
|
||||
|
||||
# TODO: check privileges at CREATE TRIGGER time.
|
||||
# --error ER_COLUMNACCESS_DENIED_ERROR
|
||||
CREATE TRIGGER t4_trg_err_2 BEFORE UPDATE ON t4
|
||||
FOR EACH ROW
|
||||
SET NEW.col = CONCAT(OLD.col, '(updated)');
|
||||
DROP TRIGGER t4_trg_err_2;
|
||||
|
||||
# execution time:
|
||||
# - check that UPDATE is not enough to read the value;
|
||||
# - check that UPDATE is required to modify the value;
|
||||
|
||||
--connection default
|
||||
--echo
|
||||
--echo ---> connection: default
|
||||
|
||||
use mysqltest_db1;
|
||||
|
||||
REVOKE SELECT ON mysqltest_db1.t1 FROM mysqltest_u1@localhost;
|
||||
REVOKE SELECT ON mysqltest_db1.t2 FROM mysqltest_u1@localhost;
|
||||
GRANT UPDATE ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
|
||||
GRANT UPDATE ON mysqltest_db1.t2 TO mysqltest_u1@localhost;
|
||||
|
||||
REVOKE SELECT(col) ON mysqltest_db1.t3 FROM mysqltest_u1@localhost;
|
||||
REVOKE SELECT(col) ON mysqltest_db1.t4 FROM mysqltest_u1@localhost;
|
||||
GRANT UPDATE(col) ON mysqltest_db1.t3 TO mysqltest_u1@localhost;
|
||||
GRANT UPDATE(col) ON mysqltest_db1.t4 TO mysqltest_u1@localhost;
|
||||
|
||||
# - table-level privileges
|
||||
|
||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||
INSERT INTO t1 VALUES('line1');
|
||||
|
||||
SELECT * FROM t1;
|
||||
SELECT @mysqltest_var;
|
||||
|
||||
INSERT INTO t2 VALUES('line2');
|
||||
|
||||
SELECT * FROM t2;
|
||||
|
||||
# - column-level privileges
|
||||
|
||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||
INSERT INTO t3 VALUES('t3_line1');
|
||||
|
||||
SELECT * FROM t3;
|
||||
SELECT @mysqltest_var;
|
||||
|
||||
INSERT INTO t4 VALUES('t4_line2');
|
||||
|
||||
SELECT * FROM t4;
|
||||
|
||||
# execution time:
|
||||
# - check that SELECT is required to read the value;
|
||||
# - check that SELECT is not enough to modify the value;
|
||||
|
||||
--connection default
|
||||
--echo
|
||||
--echo ---> connection: default
|
||||
|
||||
use mysqltest_db1;
|
||||
|
||||
REVOKE UPDATE ON mysqltest_db1.t1 FROM mysqltest_u1@localhost;
|
||||
REVOKE UPDATE ON mysqltest_db1.t2 FROM mysqltest_u1@localhost;
|
||||
GRANT SELECT ON mysqltest_db1.t1 TO mysqltest_u1@localhost;
|
||||
GRANT SELECT ON mysqltest_db1.t2 TO mysqltest_u1@localhost;
|
||||
|
||||
REVOKE UPDATE(col) ON mysqltest_db1.t3 FROM mysqltest_u1@localhost;
|
||||
REVOKE UPDATE(col) ON mysqltest_db1.t4 FROM mysqltest_u1@localhost;
|
||||
GRANT SELECT(col) ON mysqltest_db1.t3 TO mysqltest_u1@localhost;
|
||||
GRANT SELECT(col) ON mysqltest_db1.t4 TO mysqltest_u1@localhost;
|
||||
|
||||
# - table-level privileges
|
||||
|
||||
INSERT INTO t1 VALUES('line3');
|
||||
|
||||
SELECT * FROM t1;
|
||||
SELECT @mysqltest_var;
|
||||
|
||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||
INSERT INTO t2 VALUES('line4');
|
||||
|
||||
SELECT * FROM t2;
|
||||
|
||||
# - column-level privileges
|
||||
|
||||
INSERT INTO t3 VALUES('t3_line2');
|
||||
|
||||
SELECT * FROM t3;
|
||||
SELECT @mysqltest_var;
|
||||
|
||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||
INSERT INTO t4 VALUES('t4_line2');
|
||||
|
||||
SELECT * FROM t4;
|
||||
|
||||
# execution time:
|
||||
# - check that nor SELECT either UPDATE is required to execute triggger w/o
|
||||
# NEW/OLD variables.
|
||||
|
||||
DELETE FROM t1;
|
||||
|
||||
SELECT @mysqltest_var;
|
||||
|
||||
#
|
||||
# Cleanup.
|
||||
#
|
||||
|
||||
DROP USER mysqltest_u1@localhost;
|
||||
|
||||
DROP DATABASE mysqltest_db1;
|
||||
|
|
31
sql/item.cc
31
sql/item.cc
|
@ -5215,6 +5215,7 @@ void Item_insert_value::print(String *str)
|
|||
setup_field()
|
||||
thd - current thread context
|
||||
table - table of trigger (and where we looking for fields)
|
||||
table_grant_info - GRANT_INFO of the subject table
|
||||
|
||||
NOTE
|
||||
This function does almost the same as fix_fields() for Item_field
|
||||
|
@ -5228,7 +5229,8 @@ void Item_insert_value::print(String *str)
|
|||
table of trigger which uses this item.
|
||||
*/
|
||||
|
||||
void Item_trigger_field::setup_field(THD *thd, TABLE *table)
|
||||
void Item_trigger_field::setup_field(THD *thd, TABLE *table,
|
||||
GRANT_INFO *table_grant_info)
|
||||
{
|
||||
bool save_set_query_id= thd->set_query_id;
|
||||
|
||||
|
@ -5242,6 +5244,7 @@ void Item_trigger_field::setup_field(THD *thd, TABLE *table)
|
|||
0, &field_idx);
|
||||
thd->set_query_id= save_set_query_id;
|
||||
triggers= table->triggers;
|
||||
table_grants= table_grant_info;
|
||||
}
|
||||
|
||||
|
||||
|
@ -5260,22 +5263,42 @@ bool Item_trigger_field::fix_fields(THD *thd, Item **items)
|
|||
Since trigger is object tightly associated with TABLE object most
|
||||
of its set up can be performed during trigger loading i.e. trigger
|
||||
parsing! So we have little to do in fix_fields. :)
|
||||
FIXME may be we still should bother about permissions here.
|
||||
*/
|
||||
|
||||
DBUG_ASSERT(fixed == 0);
|
||||
|
||||
/* Set field. */
|
||||
|
||||
if (field_idx != (uint)-1)
|
||||
{
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
/*
|
||||
Check access privileges for the subject table. We check privileges only
|
||||
in runtime.
|
||||
*/
|
||||
|
||||
if (table_grants)
|
||||
{
|
||||
table_grants->want_privilege=
|
||||
access_type == AT_READ ? SELECT_ACL : UPDATE_ACL;
|
||||
|
||||
if (check_grant_column(thd, table_grants, triggers->table->s->db,
|
||||
triggers->table->s->table_name, field_name,
|
||||
strlen(field_name), thd->security_ctx))
|
||||
return TRUE;
|
||||
}
|
||||
#endif // NO_EMBEDDED_ACCESS_CHECKS
|
||||
|
||||
field= (row_version == OLD_ROW) ? triggers->old_field[field_idx] :
|
||||
triggers->new_field[field_idx];
|
||||
set_field(field);
|
||||
fixed= 1;
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
my_error(ER_BAD_FIELD_ERROR, MYF(0), field_name,
|
||||
(row_version == NEW_ROW) ? "NEW" : "OLD");
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
14
sql/item.h
14
sql/item.h
|
@ -2126,6 +2126,8 @@ public:
|
|||
/* Is this item represents row from NEW or OLD row ? */
|
||||
enum row_version_type {OLD_ROW, NEW_ROW};
|
||||
row_version_type row_version;
|
||||
/* Is this item used for reading or updating the value? */
|
||||
enum access_types { AT_READ = 0x1, AT_UPDATE = 0x2 };
|
||||
/* Next in list of all Item_trigger_field's in trigger */
|
||||
Item_trigger_field *next_trg_field;
|
||||
/* Index of the field in the TABLE::field array */
|
||||
|
@ -2135,18 +2137,24 @@ public:
|
|||
|
||||
Item_trigger_field(Name_resolution_context *context_arg,
|
||||
row_version_type row_ver_arg,
|
||||
const char *field_name_arg)
|
||||
const char *field_name_arg,
|
||||
access_types access_type_arg)
|
||||
:Item_field(context_arg,
|
||||
(const char *)NULL, (const char *)NULL, field_name_arg),
|
||||
row_version(row_ver_arg), field_idx((uint)-1)
|
||||
row_version(row_ver_arg), field_idx((uint)-1),
|
||||
access_type(access_type_arg), table_grants(NULL)
|
||||
{}
|
||||
void setup_field(THD *thd, TABLE *table);
|
||||
void setup_field(THD *thd, TABLE *table, GRANT_INFO *table_grant_info);
|
||||
enum Type type() const { return TRIGGER_FIELD_ITEM; }
|
||||
bool eq(const Item *item, bool binary_cmp) const;
|
||||
bool fix_fields(THD *, Item **);
|
||||
void print(String *str);
|
||||
table_map used_tables() const { return (table_map)0L; }
|
||||
void cleanup();
|
||||
|
||||
private:
|
||||
access_types access_type;
|
||||
GRANT_INFO *table_grants;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -381,7 +381,12 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
|
|||
for (trg_field= (Item_trigger_field *)(lex->trg_table_fields.first);
|
||||
trg_field; trg_field= trg_field->next_trg_field)
|
||||
{
|
||||
trg_field->setup_field(thd, table);
|
||||
/*
|
||||
NOTE: now we do not check privileges at CREATE TRIGGER time. This will
|
||||
be changed in the future.
|
||||
*/
|
||||
trg_field->setup_field(thd, table, NULL);
|
||||
|
||||
if (!trg_field->fixed &&
|
||||
trg_field->fix_fields(thd, (Item **)0))
|
||||
return 1;
|
||||
|
@ -828,8 +833,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
|
|||
|
||||
char *trg_name_buff;
|
||||
List_iterator_fast<ulonglong> itm(triggers->definition_modes_list);
|
||||
List_iterator_fast<LEX_STRING> it_definer(triggers->
|
||||
definers_list);
|
||||
List_iterator_fast<LEX_STRING> it_definer(triggers->definers_list);
|
||||
LEX *old_lex= thd->lex, lex;
|
||||
sp_rcontext *save_spcont= thd->spcont;
|
||||
ulong save_sql_mode= thd->variables.sql_mode;
|
||||
|
@ -844,6 +848,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
|
|||
{
|
||||
trg_sql_mode= itm++;
|
||||
LEX_STRING *trg_definer= it_definer++;
|
||||
|
||||
thd->variables.sql_mode= (ulong)*trg_sql_mode;
|
||||
lex_start(thd, (uchar*)trg_create_str->str, trg_create_str->length);
|
||||
|
||||
|
@ -917,11 +922,11 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
|
|||
(Item_trigger_field *)(lex.trg_table_fields.first);
|
||||
trg_field;
|
||||
trg_field= trg_field->next_trg_field)
|
||||
trg_field->setup_field(thd, table);
|
||||
|
||||
triggers->m_spec_var_used[lex.trg_chistics.event]
|
||||
[lex.trg_chistics.action_time]=
|
||||
lex.trg_table_fields.first ? TRUE : FALSE;
|
||||
{
|
||||
trg_field->setup_field(thd, table,
|
||||
&triggers->subject_table_grants[lex.trg_chistics.event]
|
||||
[lex.trg_chistics.action_time]);
|
||||
}
|
||||
|
||||
lex_end(&lex);
|
||||
}
|
||||
|
@ -1172,33 +1177,14 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event,
|
|||
}
|
||||
|
||||
/*
|
||||
If the trigger uses special variables (NEW/OLD), check that we have
|
||||
SELECT and UPDATE privileges on the subject table.
|
||||
Fetch information about table-level privileges to GRANT_INFO structure for
|
||||
subject table. Check of privileges that will use it and information about
|
||||
column-level privileges will happen in Item_trigger_field::fix_fields().
|
||||
*/
|
||||
|
||||
if (is_special_var_used(event, time_type))
|
||||
{
|
||||
TABLE_LIST table_list, **save_query_tables_own_last;
|
||||
bzero((char *) &table_list, sizeof (table_list));
|
||||
table_list.db= (char *) table->s->db;
|
||||
table_list.db_length= strlen(table_list.db);
|
||||
table_list.table_name= (char *) table->s->table_name;
|
||||
table_list.table_name_length= strlen(table_list.table_name);
|
||||
table_list.alias= (char *) table->alias;
|
||||
table_list.table= table;
|
||||
save_query_tables_own_last= thd->lex->query_tables_own_last;
|
||||
thd->lex->query_tables_own_last= 0;
|
||||
|
||||
err_status= check_table_access(thd, SELECT_ACL | UPDATE_ACL,
|
||||
&table_list, 0);
|
||||
thd->lex->query_tables_own_last= save_query_tables_own_last;
|
||||
if (err_status)
|
||||
{
|
||||
sp_restore_security_context(thd, save_ctx);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
fill_effective_table_privileges(thd,
|
||||
&subject_table_grants[event][time_type],
|
||||
table->s->db, table->s->table_name);
|
||||
#endif // NO_EMBEDDED_ACCESS_CHECKS
|
||||
|
||||
thd->reset_sub_statement_state(&statement_state, SUB_STMT_TRIGGER);
|
||||
|
|
|
@ -56,10 +56,9 @@ class Table_triggers_list: public Sql_alloc
|
|||
LEX_STRING sroutines_key;
|
||||
|
||||
/*
|
||||
is_special_var_used specifies whether trigger body contains special
|
||||
variables (NEW/OLD).
|
||||
Grant information for each trigger (pair: subject table, trigger definer).
|
||||
*/
|
||||
bool m_spec_var_used[TRG_EVENT_MAX][TRG_ACTION_MAX];
|
||||
GRANT_INFO subject_table_grants[TRG_EVENT_MAX][TRG_ACTION_MAX];
|
||||
|
||||
public:
|
||||
/*
|
||||
|
@ -78,6 +77,7 @@ public:
|
|||
record1_field(0), table(table_arg)
|
||||
{
|
||||
bzero((char *)bodies, sizeof(bodies));
|
||||
bzero((char *)&subject_table_grants, sizeof(subject_table_grants));
|
||||
}
|
||||
~Table_triggers_list();
|
||||
|
||||
|
@ -109,11 +109,6 @@ public:
|
|||
return test(bodies[TRG_EVENT_UPDATE][TRG_ACTION_BEFORE]);
|
||||
}
|
||||
|
||||
inline bool is_special_var_used(int event, int action_time) const
|
||||
{
|
||||
return m_spec_var_used[event][action_time];
|
||||
}
|
||||
|
||||
void set_table(TABLE *new_table);
|
||||
|
||||
friend class Item_trigger_field;
|
||||
|
|
|
@ -7303,7 +7303,8 @@ simple_ident_q:
|
|||
new_row ?
|
||||
Item_trigger_field::NEW_ROW:
|
||||
Item_trigger_field::OLD_ROW,
|
||||
$3.str)))
|
||||
$3.str,
|
||||
Item_trigger_field::AT_READ)))
|
||||
YYABORT;
|
||||
|
||||
/*
|
||||
|
@ -7929,7 +7930,9 @@ sys_option_value:
|
|||
|
||||
if (!(trg_fld= new Item_trigger_field(Lex->current_context(),
|
||||
Item_trigger_field::NEW_ROW,
|
||||
$2.base_name.str)) ||
|
||||
$2.base_name.str,
|
||||
Item_trigger_field::AT_UPDATE)
|
||||
) ||
|
||||
!(sp_fld= new sp_instr_set_trigger_field(lex->sphead->
|
||||
instructions(),
|
||||
lex->spcont,
|
||||
|
|
Loading…
Reference in a new issue