polardbxengine/mysql-test/suite/rpl_nogtid/t/rpl_insert_priv_check.test

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