Check the user privileges and fail the command, even if there are no slaves
that need starting respectively stopping.

Signed-off-by: Kristian Nielsen <kniel...@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

_______________________________________________
commits mailing list -- commits@lists.mariadb.org
To unsubscribe send an email to commits-le...@lists.mariadb.org

Reply via email to