Check the user privileges and fail the command, even if there are no slaves that need starting respectively stopping. Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org> --- mysql-test/suite/multi_source/simple.result | 28 +++++++++++++++ mysql-test/suite/multi_source/simple.test | 38 +++++++++++++++++++++ sql/rpl_mi.cc | 7 ++++ 3 files changed, 73 insertions(+) diff --git a/mysql-test/suite/multi_source/simple.result b/mysql-test/suite/multi_source/simple.result index f9f43d44ca7..da80b89c2ef 100644 --- a/mysql-test/suite/multi_source/simple.result +++ b/mysql-test/suite/multi_source/simple.result @@ -520,6 +520,34 @@ Slave_received_heartbeats 0 Slave_heartbeat_period 60.000 Gtid_Slave_Pos stop all slaves; +# +# MDEV-21858: START/STOP ALL SLAVES does not return access errors +# +connection slave; +SET SESSION sql_log_bin=0; +CREATE USER 'unpriv'@'127.0.0.1'; +GRANT USAGE ON *.* TO 'unpriv'@'127.0.0.1'; +connect con1,127.0.0.1,unpriv,,,$SERVER_MYPORT_3; +STOP SLAVE 'slave2'; +ERROR 42000: Access denied; you need (at least one of) the REPLICATION SLAVE ADMIN privilege(s) for this operation +START SLAVE 'slave2'; +ERROR 42000: Access denied; you need (at least one of) the REPLICATION SLAVE ADMIN privilege(s) for this operation +STOP ALL SLAVES; +ERROR 42000: Access denied; you need (at least one of) the REPLICATION SLAVE ADMIN privilege(s) for this operation +connection slave; +START SLAVE 'slave2'; +set default_master_connection = 'slave2'; +include/wait_for_slave_to_start.inc +connection con1; +START ALL SLAVES; +ERROR 42000: Access denied; you need (at least one of) the REPLICATION SLAVE ADMIN privilege(s) for this operation +disconnect con1; +connection slave; +STOP SLAVE 'slave2'; +set default_master_connection = 'slave2'; +include/wait_for_slave_to_stop.inc +DROP USER 'unpriv'@'127.0.0.1'; +SET SESSION sql_log_bin=1; include/reset_master_slave.inc disconnect slave; connection master1; diff --git a/mysql-test/suite/multi_source/simple.test b/mysql-test/suite/multi_source/simple.test index ac5e84586ae..5894a205480 100644 --- a/mysql-test/suite/multi_source/simple.test +++ b/mysql-test/suite/multi_source/simple.test @@ -84,6 +84,44 @@ query_vertical show all slaves status; # Ensure that start all slaves doesn't do anything as all slaves are stopped stop all slaves; +--echo # +--echo # MDEV-21858: START/STOP ALL SLAVES does not return access errors +--echo # +--connection slave +SET SESSION sql_log_bin=0; +CREATE USER 'unpriv'@'127.0.0.1'; +GRANT USAGE ON *.* TO 'unpriv'@'127.0.0.1'; + +connect (con1,127.0.0.1,unpriv,,,$SERVER_MYPORT_3); + +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +STOP SLAVE 'slave2'; +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +START SLAVE 'slave2'; + +# Test that STOP/START ALL SLAVES checks privileges, even if there are no +# slaves that need stopping or starting. +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +STOP ALL SLAVES; + +--connection slave +START SLAVE 'slave2'; +set default_master_connection = 'slave2'; +--source include/wait_for_slave_to_start.inc + +--connection con1 +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +START ALL SLAVES; +--disconnect con1 + +--connection slave +STOP SLAVE 'slave2'; +set default_master_connection = 'slave2'; +--source include/wait_for_slave_to_stop.inc + +DROP USER 'unpriv'@'127.0.0.1'; +SET SESSION sql_log_bin=1; + # # clean up # diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index b7b018b8f63..f101e1fcf04 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -21,6 +21,7 @@ #include "slave.h" #include "strfunc.h" #include "sql_repl.h" +#include "sql_acl.h" #ifdef HAVE_REPLICATION @@ -1641,6 +1642,9 @@ bool Master_info_index::start_all_slaves(THD *thd) DBUG_ENTER("start_all_slaves"); mysql_mutex_assert_owner(&LOCK_active_mi); + if (check_global_access(thd, PRIV_STMT_START_SLAVE)) + DBUG_RETURN(-1); + for (uint i= 0; i< master_info_hash.records; i++) { Master_info *mi; @@ -1719,6 +1723,9 @@ bool Master_info_index::stop_all_slaves(THD *thd) mysql_mutex_assert_owner(&LOCK_active_mi); DBUG_ASSERT(thd); + if (check_global_access(thd, PRIV_STMT_STOP_SLAVE)) + DBUG_RETURN(-1); + for (uint i= 0; i< master_info_hash.records; i++) { Master_info *mi; -- 2.39.5