195 lines
5.9 KiB
Plaintext
195 lines
5.9 KiB
Plaintext
# ==== Purpose ====
|
|
#
|
|
# To Verify that Write_rows_log_event, Update_rows_log_event,
|
|
# Partial_update_rows_log_event, and Delete_rows_log_event can fail
|
|
# due to insufficient privileges, and succeed with sufficient privileges.
|
|
#
|
|
# ==== Implementation ====
|
|
#
|
|
# TC1. Execute INSERT/UPDATE/DELETE with and without the necessary privileges
|
|
# ----------------------------------------------------------------------------
|
|
# 1) Create a table on master and insert a row
|
|
# 2) On slave create an user 'u1' which will be used as a
|
|
# PRIVILEGE_CHECKS_USER to apply events in the replication stream.
|
|
# 3) Start slave and expect an error as the user doesn't have INSERT privilege.
|
|
# 4) Stop slave and grant INSERT privilege.
|
|
# 5) Start slave again and this time there should not be any error.
|
|
# 6) Revoke the privilege granted in step 4)
|
|
# 7) Ensure the table is the same on master and slave.
|
|
# 9) Drop the table from master and slave.
|
|
#
|
|
# The above described test-case will be repeated for the combinations of the
|
|
# pair `privilege target` and `privilege`, where each has the following values:
|
|
# - `privilege target`: *.*, $RPL_PRIV_DB.*, $RPL_PRIV_DB.t
|
|
# - `privilege`: INSERT, UPDATE, UPDATE with partial updates, DELETE,
|
|
# INSERT(c,d), UPDATE(c)
|
|
# where `c` and `d` are columns in the create table.
|
|
#
|
|
# ==== References ====
|
|
#
|
|
# WL#12966: Replication with Restricted Privileges
|
|
#
|
|
|
|
--source include/not_group_replication_plugin.inc
|
|
--source include/have_binlog_format_row.inc
|
|
--let $applier_user = 'a_bigger_username_just_for_test'
|
|
if ($grant_to == '')
|
|
{
|
|
--let $grant_to = $applier_user
|
|
}
|
|
--let $rpl_privilege_checks_user = 2:$applier_user
|
|
--let $rpl_skip_start_slave=1
|
|
--source include/master-slave.inc
|
|
--source include/rpl_use_privilege_db.inc
|
|
|
|
--write_file $MYSQLTEST_VARDIR/tmp/check_privilege.inc PROCEDURE
|
|
|
|
--source include/rpl_connection_master.inc
|
|
--eval $sql_statment
|
|
--source include/save_master_pos.inc
|
|
|
|
--source include/rpl_connection_slave.inc
|
|
# 3) Start slave and expect an error as the user doesn't have the privilege.
|
|
START SLAVE;
|
|
--let $slave_sql_errno= convert_error(ER_TABLEACCESS_DENIED_ERROR)
|
|
--source include/wait_for_slave_sql_error.inc
|
|
|
|
# 4) Stop slave and grant the privilege.
|
|
STOP SLAVE;
|
|
--eval GRANT $privilege ON $priv_context TO $grant_to
|
|
|
|
# 5) Start slave again and this time there should not be any error.
|
|
START SLAVE;
|
|
--source include/sync_slave_sql.inc
|
|
|
|
# 6) Revoke the privilege granted in step 4)
|
|
--eval REVOKE $privilege ON $priv_context FROM $grant_to
|
|
|
|
#END OF
|
|
PROCEDURE
|
|
|
|
# 1) Create a table on master and insert a row
|
|
SET @@session.sql_log_bin = OFF;
|
|
CREATE TABLE t(c INT, d INT);
|
|
SET @@session.sql_log_bin = ON;
|
|
|
|
# 2) On slave create an user 'u1' which will be used as a
|
|
# PRIVILEGE_CHECKS_USER to apply events in the replication stream.
|
|
--source include/rpl_connection_slave.inc
|
|
--source include/rpl_use_privilege_db.inc
|
|
CALL mtr.add_suppression(".*command denied to user.");
|
|
CALL mtr.add_suppression(".*the option binlog_row_value_options.*");
|
|
CALL mtr.add_suppression(".*The slave coordinator and worker threads are stopped.*");
|
|
CREATE TABLE t(c INT, d INT);
|
|
|
|
--let $context = 3
|
|
|
|
while ($context != 0)
|
|
{
|
|
--let $privileges = 6
|
|
|
|
if ($context == 3)
|
|
{
|
|
--let $priv_context = *.*
|
|
}
|
|
if ($context == 2)
|
|
{
|
|
--let $priv_context = $RPL_PRIV_DB.*
|
|
}
|
|
if ($context == 1)
|
|
{
|
|
--let $priv_context = $RPL_PRIV_DB.t
|
|
}
|
|
|
|
while ($privileges != 0)
|
|
{
|
|
if ($privileges == 6)
|
|
{
|
|
--let $privilege = INSERT
|
|
--let $sql_statment = INSERT INTO t VALUES(10, 10)
|
|
}
|
|
if ($privileges == 5)
|
|
{
|
|
--let $privilege = UPDATE
|
|
--let $sql_statment = UPDATE t SET c = 12 WHERE c = 10
|
|
}
|
|
if ($privileges == 4)
|
|
{
|
|
--let $privilege = UPDATE
|
|
--let $sql_statment = UPDATE t SET c = 8 WHERE c = 12
|
|
|
|
--source include/rpl_connection_slave.inc
|
|
# Set the options to generate partial_update_rows_event on slave
|
|
--disable_warnings
|
|
SET @binlog_row_value_options_save= @@GLOBAL.BINLOG_ROW_VALUE_OPTIONS;
|
|
SET @@GLOBAL.BINLOG_ROW_VALUE_OPTIONS= PARTIAL_JSON;
|
|
--enable_warnings
|
|
}
|
|
if ($privileges == 3)
|
|
{
|
|
--let $privilege = DELETE
|
|
--let $sql_statment = DELETE FROM t WHERE c = 8
|
|
}
|
|
if (`SELECT $privileges = 2 AND $context = 1`)
|
|
{
|
|
# Added a negative test for column level privilege check when row type is
|
|
# MINIMAL
|
|
if (`SELECT @@SESSION.binlog_row_image = "MINIMAL"`)
|
|
{
|
|
--eval GRANT INSERT(c) ON $priv_context TO $grant_to
|
|
--source include/rpl_connection_master.inc
|
|
INSERT INTO t VALUES(10, 10);
|
|
--source include/save_master_pos.inc
|
|
--source include/rpl_connection_slave.inc
|
|
START SLAVE;
|
|
--let $slave_sql_errno= convert_error(ER_TABLEACCESS_DENIED_ERROR)
|
|
--source include/wait_for_slave_sql_error.inc
|
|
STOP SLAVE;
|
|
}
|
|
--let $privilege = INSERT(c, d)
|
|
--let $sql_statment = INSERT INTO t VALUES(10, 10)
|
|
}
|
|
if (`SELECT $privileges = 1 AND $context = 1`)
|
|
{
|
|
--let $privilege = UPDATE(c)
|
|
--let $sql_statment = UPDATE t SET c = 12 WHERE c = 10
|
|
}
|
|
|
|
if (`SELECT $privileges > 2 OR ($privileges <= 2 AND $context = 1)`)
|
|
{
|
|
--echo #
|
|
--echo # Running test for
|
|
--echo # GRANT $privilege ON $priv_context TO ...
|
|
--echo #
|
|
|
|
--source $MYSQLTEST_VARDIR/tmp/check_privilege.inc
|
|
STOP SLAVE;
|
|
|
|
if ($privileges == 4)
|
|
{
|
|
--disable_warnings
|
|
SET @@GLOBAL.BINLOG_ROW_VALUE_OPTIONS= @binlog_row_value_options_save;
|
|
--enable_warnings
|
|
}
|
|
|
|
# 8) Ensure the table is the same on master and slave.
|
|
--let $diff_tables = master:t, slave:t
|
|
--source include/diff_tables.inc
|
|
}
|
|
|
|
--dec $privileges
|
|
}
|
|
|
|
--dec $context
|
|
}
|
|
|
|
# 9) Drop the table from master and slave.
|
|
DROP TABLE t;
|
|
--source include/rpl_connection_master.inc
|
|
DROP TABLE t;
|
|
|
|
# Clean up
|
|
--remove_file $MYSQLTEST_VARDIR/tmp/check_privilege.inc
|
|
--let $rpl_only_running_threads=1
|
|
--source include/rpl_end.inc
|