File: rpl_insert_priv_check.test

package info (click to toggle)
mysql-8.0 8.0.43-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,273,924 kB
  • sloc: cpp: 4,684,605; ansic: 412,450; pascal: 108,398; java: 83,641; perl: 30,221; cs: 27,067; sql: 26,594; sh: 24,181; python: 21,816; yacc: 17,169; php: 11,522; xml: 7,388; javascript: 7,076; makefile: 2,194; lex: 1,075; awk: 670; asm: 520; objc: 183; ruby: 97; lisp: 86
file content (197 lines) | stat: -rw-r--r-- 6,284 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# ==== 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
--source include/skip_config_privilege_checks_user.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
# Since $rpl_privilege_checks_user is instantiated the replication applier has
# no privileges on the test database
--let $RPL_PRIV_DB = test
--let $rpl_skip_start_slave=1
--source include/master-slave.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
CALL mtr.add_suppression(".*command denied to user.");
CALL mtr.add_suppression(".*the option binlog_row_value_options.*");
CALL mtr.add_suppression(".*The replica coordinator and worker threads are stopped.*");
CALL mtr.add_suppression(".*Replica worker thread has failed to apply an event. As a consequence, the coordinator*");
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