summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/sys_vars/inc/sysvar_global_and_session_grant.inc49
-rw-r--r--mysql-test/suite/sys_vars/r/binlog_annotate_row_events_grant.result42
-rw-r--r--mysql-test/suite/sys_vars/r/binlog_row_image_grant.result42
-rw-r--r--mysql-test/suite/sys_vars/t/binlog_annotate_row_events_grant.test9
-rw-r--r--mysql-test/suite/sys_vars/t/binlog_row_image_grant.test9
-rw-r--r--sql/privilege.h6
-rw-r--r--sql/sys_vars.cc10
7 files changed, 165 insertions, 2 deletions
diff --git a/mysql-test/suite/sys_vars/inc/sysvar_global_and_session_grant.inc b/mysql-test/suite/sys_vars/inc/sysvar_global_and_session_grant.inc
new file mode 100644
index 00000000000..0c6d070583b
--- /dev/null
+++ b/mysql-test/suite/sys_vars/inc/sysvar_global_and_session_grant.inc
@@ -0,0 +1,49 @@
+--source include/not_embedded.inc
+
+
+--eval SET @global=@@global.$var
+
+--echo # Test that "SET $var" is not allowed without $grant or SUPER
+
+CREATE USER user1@localhost;
+GRANT ALL PRIVILEGES ON *.* TO user1@localhost;
+--eval REVOKE $grant, SUPER ON *.* FROM user1@localhost
+--connect(user1,localhost,user1,,)
+--connection user1
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+--eval SET GLOBAL $var=$value
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+--eval SET $var=$value
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+--eval SET SESSION $var=$value
+--disconnect user1
+--connection default
+DROP USER user1@localhost;
+
+--echo # Test that "SET $var" is allowed with $grant
+
+CREATE USER user1@localhost;
+--eval GRANT $grant ON *.* TO user1@localhost
+--connect(user1,localhost,user1,,)
+--connection user1
+--eval SET GLOBAL $var=$value
+--eval SET $var=$value
+--eval SET SESSION $var=$value
+--disconnect user1
+--connection default
+DROP USER user1@localhost;
+
+--echo # Test that "SET $var" is allowed with SUPER
+
+CREATE USER user1@localhost;
+GRANT SUPER ON *.* TO user1@localhost;
+--connect(user1,localhost,user1,,)
+--connection user1
+--eval SET GLOBAL $var=$value
+--eval SET $var=$value
+--eval SET SESSION $var=$value
+--disconnect user1
+--connection default
+DROP USER user1@localhost;
+
+--eval SET @@global.$var=@global
diff --git a/mysql-test/suite/sys_vars/r/binlog_annotate_row_events_grant.result b/mysql-test/suite/sys_vars/r/binlog_annotate_row_events_grant.result
new file mode 100644
index 00000000000..1ff25d209bd
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/binlog_annotate_row_events_grant.result
@@ -0,0 +1,42 @@
+#
+# MDEV-21971 Bind BINLOG ADMIN to binlog_annotate_row_events and binlog_row_image global and session variables
+#
+SET @global=@@global.binlog_annotate_row_events;
+# Test that "SET binlog_annotate_row_events" is not allowed without BINLOG ADMIN or SUPER
+CREATE USER user1@localhost;
+GRANT ALL PRIVILEGES ON *.* TO user1@localhost;
+REVOKE BINLOG ADMIN, SUPER ON *.* FROM user1@localhost;
+connect user1,localhost,user1,,;
+connection user1;
+SET GLOBAL binlog_annotate_row_events=1;
+ERROR 42000: Access denied; you need (at least one of) the SUPER, BINLOG ADMIN privilege(s) for this operation
+SET binlog_annotate_row_events=1;
+ERROR 42000: Access denied; you need (at least one of) the SUPER, BINLOG ADMIN privilege(s) for this operation
+SET SESSION binlog_annotate_row_events=1;
+ERROR 42000: Access denied; you need (at least one of) the SUPER, BINLOG ADMIN privilege(s) for this operation
+disconnect user1;
+connection default;
+DROP USER user1@localhost;
+# Test that "SET binlog_annotate_row_events" is allowed with BINLOG ADMIN
+CREATE USER user1@localhost;
+GRANT BINLOG ADMIN ON *.* TO user1@localhost;
+connect user1,localhost,user1,,;
+connection user1;
+SET GLOBAL binlog_annotate_row_events=1;
+SET binlog_annotate_row_events=1;
+SET SESSION binlog_annotate_row_events=1;
+disconnect user1;
+connection default;
+DROP USER user1@localhost;
+# Test that "SET binlog_annotate_row_events" is allowed with SUPER
+CREATE USER user1@localhost;
+GRANT SUPER ON *.* TO user1@localhost;
+connect user1,localhost,user1,,;
+connection user1;
+SET GLOBAL binlog_annotate_row_events=1;
+SET binlog_annotate_row_events=1;
+SET SESSION binlog_annotate_row_events=1;
+disconnect user1;
+connection default;
+DROP USER user1@localhost;
+SET @@global.binlog_annotate_row_events=@global;
diff --git a/mysql-test/suite/sys_vars/r/binlog_row_image_grant.result b/mysql-test/suite/sys_vars/r/binlog_row_image_grant.result
new file mode 100644
index 00000000000..d9cf65d9932
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/binlog_row_image_grant.result
@@ -0,0 +1,42 @@
+#
+# MDEV-21971 Bind BINLOG ADMIN to binlog_annotate_row_events and binlog_row_image global and session variables
+#
+SET @global=@@global.binlog_row_image;
+# Test that "SET binlog_row_image" is not allowed without BINLOG ADMIN or SUPER
+CREATE USER user1@localhost;
+GRANT ALL PRIVILEGES ON *.* TO user1@localhost;
+REVOKE BINLOG ADMIN, SUPER ON *.* FROM user1@localhost;
+connect user1,localhost,user1,,;
+connection user1;
+SET GLOBAL binlog_row_image=1;
+ERROR 42000: Access denied; you need (at least one of) the SUPER, BINLOG ADMIN privilege(s) for this operation
+SET binlog_row_image=1;
+ERROR 42000: Access denied; you need (at least one of) the SUPER, BINLOG ADMIN privilege(s) for this operation
+SET SESSION binlog_row_image=1;
+ERROR 42000: Access denied; you need (at least one of) the SUPER, BINLOG ADMIN privilege(s) for this operation
+disconnect user1;
+connection default;
+DROP USER user1@localhost;
+# Test that "SET binlog_row_image" is allowed with BINLOG ADMIN
+CREATE USER user1@localhost;
+GRANT BINLOG ADMIN ON *.* TO user1@localhost;
+connect user1,localhost,user1,,;
+connection user1;
+SET GLOBAL binlog_row_image=1;
+SET binlog_row_image=1;
+SET SESSION binlog_row_image=1;
+disconnect user1;
+connection default;
+DROP USER user1@localhost;
+# Test that "SET binlog_row_image" is allowed with SUPER
+CREATE USER user1@localhost;
+GRANT SUPER ON *.* TO user1@localhost;
+connect user1,localhost,user1,,;
+connection user1;
+SET GLOBAL binlog_row_image=1;
+SET binlog_row_image=1;
+SET SESSION binlog_row_image=1;
+disconnect user1;
+connection default;
+DROP USER user1@localhost;
+SET @@global.binlog_row_image=@global;
diff --git a/mysql-test/suite/sys_vars/t/binlog_annotate_row_events_grant.test b/mysql-test/suite/sys_vars/t/binlog_annotate_row_events_grant.test
new file mode 100644
index 00000000000..d289267a031
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/binlog_annotate_row_events_grant.test
@@ -0,0 +1,9 @@
+--echo #
+--echo # MDEV-21971 Bind BINLOG ADMIN to binlog_annotate_row_events and binlog_row_image global and session variables
+--echo #
+
+--let var = binlog_annotate_row_events
+--let grant = BINLOG ADMIN
+--let value = 1
+
+--source suite/sys_vars/inc/sysvar_global_and_session_grant.inc
diff --git a/mysql-test/suite/sys_vars/t/binlog_row_image_grant.test b/mysql-test/suite/sys_vars/t/binlog_row_image_grant.test
new file mode 100644
index 00000000000..e50b3750ad3
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/binlog_row_image_grant.test
@@ -0,0 +1,9 @@
+--echo #
+--echo # MDEV-21971 Bind BINLOG ADMIN to binlog_annotate_row_events and binlog_row_image global and session variables
+--echo #
+
+--let var = binlog_row_image
+--let grant = BINLOG ADMIN
+--let value = 1
+
+--source suite/sys_vars/inc/sysvar_global_and_session_grant.inc
diff --git a/sql/privilege.h b/sql/privilege.h
index 0dd3712650a..1a11c1bb4ad 100644
--- a/sql/privilege.h
+++ b/sql/privilege.h
@@ -322,6 +322,12 @@ constexpr privilege_t PRIV_SET_SYSTEM_VAR_BINLOG_FORMAT=
constexpr privilege_t PRIV_SET_SYSTEM_VAR_BINLOG_DIRECT_NON_TRANSACTIONAL_UPDATES=
SUPER_ACL | BINLOG_ADMIN_ACL;
+constexpr privilege_t PRIV_SET_SYSTEM_VAR_BINLOG_ANNOTATE_ROW_EVENTS=
+ SUPER_ACL | BINLOG_ADMIN_ACL;
+
+constexpr privilege_t PRIV_SET_SYSTEM_VAR_BINLOG_ROW_IMAGE=
+ SUPER_ACL | BINLOG_ADMIN_ACL;
+
constexpr privilege_t PRIV_SET_SYSTEM_VAR_SQL_LOG_BIN=
SUPER_ACL | BINLOG_ADMIN_ACL;
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 72bf4178872..924cf914520 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -6314,7 +6314,10 @@ static Sys_var_mybool Sys_userstat(
GLOBAL_VAR(opt_userstat_running),
CMD_LINE(OPT_ARG), DEFAULT(FALSE));
-static Sys_var_mybool Sys_binlog_annotate_row_events(
+static Sys_var_on_access<Sys_var_mybool,
+ PRIV_SET_SYSTEM_VAR_BINLOG_ANNOTATE_ROW_EVENTS,
+ PRIV_SET_SYSTEM_VAR_BINLOG_ANNOTATE_ROW_EVENTS>
+Sys_binlog_annotate_row_events(
"binlog_annotate_row_events",
"Tells the master to annotate RBR events with the statement that "
"caused these events",
@@ -6428,7 +6431,10 @@ static Sys_var_mybool Sys_binlog_encryption(
DEFAULT(FALSE));
static const char *binlog_row_image_names[]= {"MINIMAL", "NOBLOB", "FULL", NullS};
-static Sys_var_enum Sys_binlog_row_image(
+static Sys_var_on_access<Sys_var_enum,
+ PRIV_SET_SYSTEM_VAR_BINLOG_ROW_IMAGE,
+ PRIV_SET_SYSTEM_VAR_BINLOG_ROW_IMAGE>
+Sys_binlog_row_image(
"binlog_row_image",
"Controls whether rows should be logged in 'FULL', 'NOBLOB' or "
"'MINIMAL' formats. 'FULL', means that all columns in the before "