diff --git a/mysql-test/suite/sys_vars/r/relay_log_purge_grant.result b/mysql-test/suite/sys_vars/r/relay_log_purge_grant.result new file mode 100644 index 00000000000..0823bf1ff9d --- /dev/null +++ b/mysql-test/suite/sys_vars/r/relay_log_purge_grant.result @@ -0,0 +1,46 @@ +# +# MDEV-21969 Bind REPLICATION SLAVE ADMIN to relay_log_*, sync_master_info, sync_relay_log, sync_relay_log_info +# +SET @global=@@global.relay_log_purge; +# Test that "SET relay_log_purge" is not allowed without REPLICATION SLAVE ADMIN or SUPER +CREATE USER user1@localhost; +GRANT ALL PRIVILEGES ON *.* TO user1@localhost; +REVOKE REPLICATION SLAVE ADMIN, SUPER ON *.* FROM user1@localhost; +connect user1,localhost,user1,,; +connection user1; +SET GLOBAL relay_log_purge=1; +ERROR 42000: Access denied; you need (at least one of) the SUPER, REPLICATION SLAVE ADMIN privilege(s) for this operation +SET relay_log_purge=1; +ERROR HY000: Variable 'relay_log_purge' is a GLOBAL variable and should be set with SET GLOBAL +SET SESSION relay_log_purge=1; +ERROR HY000: Variable 'relay_log_purge' is a GLOBAL variable and should be set with SET GLOBAL +disconnect user1; +connection default; +DROP USER user1@localhost; +# Test that "SET relay_log_purge" is allowed with REPLICATION SLAVE ADMIN +CREATE USER user1@localhost; +GRANT REPLICATION SLAVE ADMIN ON *.* TO user1@localhost; +connect user1,localhost,user1,,; +connection user1; +SET GLOBAL relay_log_purge=1; +SET relay_log_purge=1; +ERROR HY000: Variable 'relay_log_purge' is a GLOBAL variable and should be set with SET GLOBAL +SET SESSION relay_log_purge=1; +ERROR HY000: Variable 'relay_log_purge' is a GLOBAL variable and should be set with SET GLOBAL +disconnect user1; +connection default; +DROP USER user1@localhost; +# Test that "SET relay_log_purge" is allowed with SUPER +CREATE USER user1@localhost; +GRANT SUPER ON *.* TO user1@localhost; +connect user1,localhost,user1,,; +connection user1; +SET GLOBAL relay_log_purge=1; +SET relay_log_purge=1; +ERROR HY000: Variable 'relay_log_purge' is a GLOBAL variable and should be set with SET GLOBAL +SET SESSION relay_log_purge=1; +ERROR HY000: Variable 'relay_log_purge' is a GLOBAL variable and should be set with SET GLOBAL +disconnect user1; +connection default; +DROP USER user1@localhost; +SET @@global.relay_log_purge=@global; diff --git a/mysql-test/suite/sys_vars/r/relay_log_recovery_grant.result b/mysql-test/suite/sys_vars/r/relay_log_recovery_grant.result new file mode 100644 index 00000000000..9e90c99ff0d --- /dev/null +++ b/mysql-test/suite/sys_vars/r/relay_log_recovery_grant.result @@ -0,0 +1,46 @@ +# +# MDEV-21969 Bind REPLICATION SLAVE ADMIN to relay_log_*, sync_master_info, sync_relay_log, sync_relay_log_info +# +SET @global=@@global.relay_log_recovery; +# Test that "SET relay_log_recovery" is not allowed without REPLICATION SLAVE ADMIN or SUPER +CREATE USER user1@localhost; +GRANT ALL PRIVILEGES ON *.* TO user1@localhost; +REVOKE REPLICATION SLAVE ADMIN, SUPER ON *.* FROM user1@localhost; +connect user1,localhost,user1,,; +connection user1; +SET GLOBAL relay_log_recovery=1; +ERROR 42000: Access denied; you need (at least one of) the SUPER, REPLICATION SLAVE ADMIN privilege(s) for this operation +SET relay_log_recovery=1; +ERROR HY000: Variable 'relay_log_recovery' is a GLOBAL variable and should be set with SET GLOBAL +SET SESSION relay_log_recovery=1; +ERROR HY000: Variable 'relay_log_recovery' is a GLOBAL variable and should be set with SET GLOBAL +disconnect user1; +connection default; +DROP USER user1@localhost; +# Test that "SET relay_log_recovery" is allowed with REPLICATION SLAVE ADMIN +CREATE USER user1@localhost; +GRANT REPLICATION SLAVE ADMIN ON *.* TO user1@localhost; +connect user1,localhost,user1,,; +connection user1; +SET GLOBAL relay_log_recovery=1; +SET relay_log_recovery=1; +ERROR HY000: Variable 'relay_log_recovery' is a GLOBAL variable and should be set with SET GLOBAL +SET SESSION relay_log_recovery=1; +ERROR HY000: Variable 'relay_log_recovery' is a GLOBAL variable and should be set with SET GLOBAL +disconnect user1; +connection default; +DROP USER user1@localhost; +# Test that "SET relay_log_recovery" is allowed with SUPER +CREATE USER user1@localhost; +GRANT SUPER ON *.* TO user1@localhost; +connect user1,localhost,user1,,; +connection user1; +SET GLOBAL relay_log_recovery=1; +SET relay_log_recovery=1; +ERROR HY000: Variable 'relay_log_recovery' is a GLOBAL variable and should be set with SET GLOBAL +SET SESSION relay_log_recovery=1; +ERROR HY000: Variable 'relay_log_recovery' is a GLOBAL variable and should be set with SET GLOBAL +disconnect user1; +connection default; +DROP USER user1@localhost; +SET @@global.relay_log_recovery=@global; diff --git a/mysql-test/suite/sys_vars/r/sync_master_info_grant.result b/mysql-test/suite/sys_vars/r/sync_master_info_grant.result new file mode 100644 index 00000000000..40b04ea4480 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/sync_master_info_grant.result @@ -0,0 +1,46 @@ +# +# MDEV-21969 Bind REPLICATION SLAVE ADMIN to relay_log_*, sync_master_info, sync_relay_log, sync_relay_log_info +# +SET @global=@@global.sync_master_info; +# Test that "SET sync_master_info" is not allowed without REPLICATION SLAVE ADMIN or SUPER +CREATE USER user1@localhost; +GRANT ALL PRIVILEGES ON *.* TO user1@localhost; +REVOKE REPLICATION SLAVE ADMIN, SUPER ON *.* FROM user1@localhost; +connect user1,localhost,user1,,; +connection user1; +SET GLOBAL sync_master_info=20000; +ERROR 42000: Access denied; you need (at least one of) the SUPER, REPLICATION SLAVE ADMIN privilege(s) for this operation +SET sync_master_info=20000; +ERROR HY000: Variable 'sync_master_info' is a GLOBAL variable and should be set with SET GLOBAL +SET SESSION sync_master_info=20000; +ERROR HY000: Variable 'sync_master_info' is a GLOBAL variable and should be set with SET GLOBAL +disconnect user1; +connection default; +DROP USER user1@localhost; +# Test that "SET sync_master_info" is allowed with REPLICATION SLAVE ADMIN +CREATE USER user1@localhost; +GRANT REPLICATION SLAVE ADMIN ON *.* TO user1@localhost; +connect user1,localhost,user1,,; +connection user1; +SET GLOBAL sync_master_info=20000; +SET sync_master_info=20000; +ERROR HY000: Variable 'sync_master_info' is a GLOBAL variable and should be set with SET GLOBAL +SET SESSION sync_master_info=20000; +ERROR HY000: Variable 'sync_master_info' is a GLOBAL variable and should be set with SET GLOBAL +disconnect user1; +connection default; +DROP USER user1@localhost; +# Test that "SET sync_master_info" is allowed with SUPER +CREATE USER user1@localhost; +GRANT SUPER ON *.* TO user1@localhost; +connect user1,localhost,user1,,; +connection user1; +SET GLOBAL sync_master_info=20000; +SET sync_master_info=20000; +ERROR HY000: Variable 'sync_master_info' is a GLOBAL variable and should be set with SET GLOBAL +SET SESSION sync_master_info=20000; +ERROR HY000: Variable 'sync_master_info' is a GLOBAL variable and should be set with SET GLOBAL +disconnect user1; +connection default; +DROP USER user1@localhost; +SET @@global.sync_master_info=@global; diff --git a/mysql-test/suite/sys_vars/r/sync_relay_log_grant.result b/mysql-test/suite/sys_vars/r/sync_relay_log_grant.result new file mode 100644 index 00000000000..f71e8325858 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/sync_relay_log_grant.result @@ -0,0 +1,46 @@ +# +# MDEV-21969 Bind REPLICATION SLAVE ADMIN to relay_log_*, sync_master_info, sync_relay_log, sync_relay_log_info +# +SET @global=@@global.sync_relay_log; +# Test that "SET sync_relay_log" is not allowed without REPLICATION SLAVE ADMIN or SUPER +CREATE USER user1@localhost; +GRANT ALL PRIVILEGES ON *.* TO user1@localhost; +REVOKE REPLICATION SLAVE ADMIN, SUPER ON *.* FROM user1@localhost; +connect user1,localhost,user1,,; +connection user1; +SET GLOBAL sync_relay_log=20000; +ERROR 42000: Access denied; you need (at least one of) the SUPER, REPLICATION SLAVE ADMIN privilege(s) for this operation +SET sync_relay_log=20000; +ERROR HY000: Variable 'sync_relay_log' is a GLOBAL variable and should be set with SET GLOBAL +SET SESSION sync_relay_log=20000; +ERROR HY000: Variable 'sync_relay_log' is a GLOBAL variable and should be set with SET GLOBAL +disconnect user1; +connection default; +DROP USER user1@localhost; +# Test that "SET sync_relay_log" is allowed with REPLICATION SLAVE ADMIN +CREATE USER user1@localhost; +GRANT REPLICATION SLAVE ADMIN ON *.* TO user1@localhost; +connect user1,localhost,user1,,; +connection user1; +SET GLOBAL sync_relay_log=20000; +SET sync_relay_log=20000; +ERROR HY000: Variable 'sync_relay_log' is a GLOBAL variable and should be set with SET GLOBAL +SET SESSION sync_relay_log=20000; +ERROR HY000: Variable 'sync_relay_log' is a GLOBAL variable and should be set with SET GLOBAL +disconnect user1; +connection default; +DROP USER user1@localhost; +# Test that "SET sync_relay_log" is allowed with SUPER +CREATE USER user1@localhost; +GRANT SUPER ON *.* TO user1@localhost; +connect user1,localhost,user1,,; +connection user1; +SET GLOBAL sync_relay_log=20000; +SET sync_relay_log=20000; +ERROR HY000: Variable 'sync_relay_log' is a GLOBAL variable and should be set with SET GLOBAL +SET SESSION sync_relay_log=20000; +ERROR HY000: Variable 'sync_relay_log' is a GLOBAL variable and should be set with SET GLOBAL +disconnect user1; +connection default; +DROP USER user1@localhost; +SET @@global.sync_relay_log=@global; diff --git a/mysql-test/suite/sys_vars/r/sync_relay_log_info_grant.result b/mysql-test/suite/sys_vars/r/sync_relay_log_info_grant.result new file mode 100644 index 00000000000..25727aac07c --- /dev/null +++ b/mysql-test/suite/sys_vars/r/sync_relay_log_info_grant.result @@ -0,0 +1,46 @@ +# +# MDEV-21969 Bind REPLICATION SLAVE ADMIN to relay_log_*, sync_master_info, sync_relay_log, sync_relay_log_info +# +SET @global=@@global.sync_relay_log_info; +# Test that "SET sync_relay_log_info" is not allowed without REPLICATION SLAVE ADMIN or SUPER +CREATE USER user1@localhost; +GRANT ALL PRIVILEGES ON *.* TO user1@localhost; +REVOKE REPLICATION SLAVE ADMIN, SUPER ON *.* FROM user1@localhost; +connect user1,localhost,user1,,; +connection user1; +SET GLOBAL sync_relay_log_info=20000; +ERROR 42000: Access denied; you need (at least one of) the SUPER, REPLICATION SLAVE ADMIN privilege(s) for this operation +SET sync_relay_log_info=20000; +ERROR HY000: Variable 'sync_relay_log_info' is a GLOBAL variable and should be set with SET GLOBAL +SET SESSION sync_relay_log_info=20000; +ERROR HY000: Variable 'sync_relay_log_info' is a GLOBAL variable and should be set with SET GLOBAL +disconnect user1; +connection default; +DROP USER user1@localhost; +# Test that "SET sync_relay_log_info" is allowed with REPLICATION SLAVE ADMIN +CREATE USER user1@localhost; +GRANT REPLICATION SLAVE ADMIN ON *.* TO user1@localhost; +connect user1,localhost,user1,,; +connection user1; +SET GLOBAL sync_relay_log_info=20000; +SET sync_relay_log_info=20000; +ERROR HY000: Variable 'sync_relay_log_info' is a GLOBAL variable and should be set with SET GLOBAL +SET SESSION sync_relay_log_info=20000; +ERROR HY000: Variable 'sync_relay_log_info' is a GLOBAL variable and should be set with SET GLOBAL +disconnect user1; +connection default; +DROP USER user1@localhost; +# Test that "SET sync_relay_log_info" is allowed with SUPER +CREATE USER user1@localhost; +GRANT SUPER ON *.* TO user1@localhost; +connect user1,localhost,user1,,; +connection user1; +SET GLOBAL sync_relay_log_info=20000; +SET sync_relay_log_info=20000; +ERROR HY000: Variable 'sync_relay_log_info' is a GLOBAL variable and should be set with SET GLOBAL +SET SESSION sync_relay_log_info=20000; +ERROR HY000: Variable 'sync_relay_log_info' is a GLOBAL variable and should be set with SET GLOBAL +disconnect user1; +connection default; +DROP USER user1@localhost; +SET @@global.sync_relay_log_info=@global; diff --git a/mysql-test/suite/sys_vars/t/relay_log_purge_grant.test b/mysql-test/suite/sys_vars/t/relay_log_purge_grant.test new file mode 100644 index 00000000000..f93d7048d86 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/relay_log_purge_grant.test @@ -0,0 +1,9 @@ +--echo # +--echo # MDEV-21969 Bind REPLICATION SLAVE ADMIN to relay_log_*, sync_master_info, sync_relay_log, sync_relay_log_info +--echo # + +--let var = relay_log_purge +--let grant = REPLICATION SLAVE ADMIN +--let value = 1 + +--source suite/sys_vars/inc/sysvar_global_grant.inc diff --git a/mysql-test/suite/sys_vars/t/relay_log_recovery_grant.test b/mysql-test/suite/sys_vars/t/relay_log_recovery_grant.test new file mode 100644 index 00000000000..1c052618bdb --- /dev/null +++ b/mysql-test/suite/sys_vars/t/relay_log_recovery_grant.test @@ -0,0 +1,9 @@ +--echo # +--echo # MDEV-21969 Bind REPLICATION SLAVE ADMIN to relay_log_*, sync_master_info, sync_relay_log, sync_relay_log_info +--echo # + +--let var = relay_log_recovery +--let grant = REPLICATION SLAVE ADMIN +--let value = 1 + +--source suite/sys_vars/inc/sysvar_global_grant.inc diff --git a/mysql-test/suite/sys_vars/t/sync_master_info_grant.test b/mysql-test/suite/sys_vars/t/sync_master_info_grant.test new file mode 100644 index 00000000000..c46979e4cd5 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/sync_master_info_grant.test @@ -0,0 +1,9 @@ +--echo # +--echo # MDEV-21969 Bind REPLICATION SLAVE ADMIN to relay_log_*, sync_master_info, sync_relay_log, sync_relay_log_info +--echo # + +--let var = sync_master_info +--let grant = REPLICATION SLAVE ADMIN +--let value = 20000 + +--source suite/sys_vars/inc/sysvar_global_grant.inc diff --git a/mysql-test/suite/sys_vars/t/sync_relay_log_grant.test b/mysql-test/suite/sys_vars/t/sync_relay_log_grant.test new file mode 100644 index 00000000000..6812885a75e --- /dev/null +++ b/mysql-test/suite/sys_vars/t/sync_relay_log_grant.test @@ -0,0 +1,9 @@ +--echo # +--echo # MDEV-21969 Bind REPLICATION SLAVE ADMIN to relay_log_*, sync_master_info, sync_relay_log, sync_relay_log_info +--echo # + +--let var = sync_relay_log +--let grant = REPLICATION SLAVE ADMIN +--let value = 20000 + +--source suite/sys_vars/inc/sysvar_global_grant.inc diff --git a/mysql-test/suite/sys_vars/t/sync_relay_log_info_grant.test b/mysql-test/suite/sys_vars/t/sync_relay_log_info_grant.test new file mode 100644 index 00000000000..1b563b5dea3 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/sync_relay_log_info_grant.test @@ -0,0 +1,9 @@ +--echo # +--echo # MDEV-21969 Bind REPLICATION SLAVE ADMIN to relay_log_*, sync_master_info, sync_relay_log, sync_relay_log_info +--echo # + +--let var = sync_relay_log_info +--let grant = REPLICATION SLAVE ADMIN +--let value = 20000 + +--source suite/sys_vars/inc/sysvar_global_grant.inc diff --git a/sql/privilege.h b/sql/privilege.h index 7198c04ee14..0dd3712650a 100644 --- a/sql/privilege.h +++ b/sql/privilege.h @@ -552,6 +552,17 @@ constexpr privilege_t PRIV_SET_SYSTEM_GLOBAL_VAR_RPL_SEMI_SYNC_SLAVE_DELAY_MASTE constexpr privilege_t PRIV_SET_SYSTEM_GLOBAL_VAR_RPL_SEMI_SYNC_SLAVE_KILL_CONN_TIMEOUT= REPL_SLAVE_ADMIN_ACL | SUPER_ACL; +constexpr privilege_t PRIV_SET_SYSTEM_GLOBAL_VAR_RELAY_LOG_PURGE= + REPL_SLAVE_ADMIN_ACL | SUPER_ACL; +constexpr privilege_t PRIV_SET_SYSTEM_GLOBAL_VAR_RELAY_LOG_RECOVERY= + REPL_SLAVE_ADMIN_ACL | SUPER_ACL; +constexpr privilege_t PRIV_SET_SYSTEM_GLOBAL_VAR_SYNC_MASTER_INFO= + REPL_SLAVE_ADMIN_ACL | SUPER_ACL; +constexpr privilege_t PRIV_SET_SYSTEM_GLOBAL_VAR_SYNC_RELAY_LOG= + REPL_SLAVE_ADMIN_ACL | SUPER_ACL; +constexpr privilege_t PRIV_SET_SYSTEM_GLOBAL_VAR_SYNC_RELAY_LOG_INFO= + REPL_SLAVE_ADMIN_ACL | SUPER_ACL; + /* Privileges for federated database related statements */ // Was SUPER_ACL prior to 10.5.2 diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 9bddb13da18..72bf4178872 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -5149,12 +5149,16 @@ static Sys_var_charptr_fscs Sys_relay_log_info_file( READ_ONLY GLOBAL_VAR(relay_log_info_file), CMD_LINE(REQUIRED_ARG), DEFAULT(0)); -static Sys_var_mybool Sys_relay_log_purge( +static Sys_var_on_access_global<Sys_var_mybool, + PRIV_SET_SYSTEM_GLOBAL_VAR_RELAY_LOG_PURGE> +Sys_relay_log_purge( "relay_log_purge", "if disabled - do not purge relay logs. " "if enabled - purge them as soon as they are no more needed.", GLOBAL_VAR(relay_log_purge), CMD_LINE(OPT_ARG), DEFAULT(TRUE)); -static Sys_var_mybool Sys_relay_log_recovery( +static Sys_var_on_access_global<Sys_var_mybool, + PRIV_SET_SYSTEM_GLOBAL_VAR_RELAY_LOG_RECOVERY> +Sys_relay_log_recovery( "relay_log_recovery", "Enables automatic relay log recovery " "right after the database startup, which means that the IO Thread " "starts re-fetching from the master right after the last transaction " @@ -5474,13 +5478,17 @@ static Sys_var_ulonglong Sys_relay_log_space_limit( READ_ONLY GLOBAL_VAR(relay_log_space_limit), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, ULONGLONG_MAX), DEFAULT(0), BLOCK_SIZE(1)); -static Sys_var_uint Sys_sync_relaylog_period( +static Sys_var_on_access_global<Sys_var_uint, + PRIV_SET_SYSTEM_GLOBAL_VAR_SYNC_RELAY_LOG> +Sys_sync_relaylog_period( "sync_relay_log", "Synchronously flush relay log to disk after " "every #th event. Use 0 to disable synchronous flushing", GLOBAL_VAR(sync_relaylog_period), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, UINT_MAX), DEFAULT(10000), BLOCK_SIZE(1)); -static Sys_var_uint Sys_sync_relayloginfo_period( +static Sys_var_on_access_global<Sys_var_uint, + PRIV_SET_SYSTEM_GLOBAL_VAR_SYNC_RELAY_LOG_INFO> +Sys_sync_relayloginfo_period( "sync_relay_log_info", "Synchronously flush relay log info " "to disk after every #th transaction. Use 0 to disable " "synchronous flushing", @@ -5496,7 +5504,9 @@ Sys_sync_binlog_period( GLOBAL_VAR(sync_binlog_period), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1)); -static Sys_var_uint Sys_sync_masterinfo_period( +static Sys_var_on_access_global<Sys_var_uint, + PRIV_SET_SYSTEM_GLOBAL_VAR_SYNC_MASTER_INFO> +Sys_sync_masterinfo_period( "sync_master_info", "Synchronously flush master info to disk " "after every #th event. Use 0 to disable synchronous flushing", GLOBAL_VAR(sync_masterinfo_period), CMD_LINE(REQUIRED_ARG),