Commit 513cfd04 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-21960 Bind READ_ONLY ADMIN to @@read_only

parent b6025841
......@@ -20,7 +20,7 @@ id name
CREATE user sameea;
CONNECT connn,localhost,sameea,,;
SET Global read_ONLY=ON;
ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
ERROR 42000: Access denied; you need (at least one of) the SUPER, READ_ONLY ADMIN privilege(s) for this operation
CREATE TABLE t2
(
id INT NOT NULL auto_increment,
......
#
# MDEV-21960 Bind READ_ONLY ADMIN to @@read_only
#
# Test that "SET read_only" is not allowed without READ_ONLY ADMIN or SUPER
CREATE USER user1@localhost;
GRANT ALL PRIVILEGES ON *.* TO user1@localhost;
REVOKE READ_ONLY ADMIN, SUPER ON *.* FROM user1@localhost;
connect user1,localhost,user1,,;
connection user1;
SET GLOBAL read_only=0;
ERROR 42000: Access denied; you need (at least one of) the SUPER, READ_ONLY ADMIN privilege(s) for this operation
SET read_only=0;
ERROR HY000: Variable 'read_only' is a GLOBAL variable and should be set with SET GLOBAL
SET SESSION read_only=0;
ERROR HY000: Variable 'read_only' is a GLOBAL variable and should be set with SET GLOBAL
disconnect user1;
connection default;
DROP USER user1@localhost;
# Test that "SET read_only" is allowed with READ_ONLY ADMIN
CREATE USER user1@localhost;
GRANT READ_ONLY ADMIN ON *.* TO user1@localhost;
connect user1,localhost,user1,,;
connection user1;
SET GLOBAL read_only=0;
SET read_only=0;
ERROR HY000: Variable 'read_only' is a GLOBAL variable and should be set with SET GLOBAL
SET SESSION read_only=0;
ERROR HY000: Variable 'read_only' is a GLOBAL variable and should be set with SET GLOBAL
disconnect user1;
connection default;
DROP USER user1@localhost;
# Test that "SET read_only" is allowed with SUPER
CREATE USER user1@localhost;
GRANT SUPER ON *.* TO user1@localhost;
connect user1,localhost,user1,,;
connection user1;
SET GLOBAL read_only=0;
SET read_only=0;
ERROR HY000: Variable 'read_only' is a GLOBAL variable and should be set with SET GLOBAL
SET SESSION read_only=0;
ERROR HY000: Variable 'read_only' is a GLOBAL variable and should be set with SET GLOBAL
disconnect user1;
connection default;
DROP USER user1@localhost;
--source include/not_embedded.inc
--echo #
--echo # MDEV-21960 Bind READ_ONLY ADMIN to @@read_only
--echo #
--echo # Test that "SET read_only" is not allowed without READ_ONLY ADMIN or SUPER
CREATE USER user1@localhost;
GRANT ALL PRIVILEGES ON *.* TO user1@localhost;
REVOKE READ_ONLY ADMIN, SUPER ON *.* FROM user1@localhost;
--connect(user1,localhost,user1,,)
--connection user1
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
SET GLOBAL read_only=0;
--error ER_GLOBAL_VARIABLE
SET read_only=0;
--error ER_GLOBAL_VARIABLE
SET SESSION read_only=0;
--disconnect user1
--connection default
DROP USER user1@localhost;
--echo # Test that "SET read_only" is allowed with READ_ONLY ADMIN
CREATE USER user1@localhost;
GRANT READ_ONLY ADMIN ON *.* TO user1@localhost;
--connect(user1,localhost,user1,,)
--connection user1
SET GLOBAL read_only=0;
--error ER_GLOBAL_VARIABLE
SET read_only=0;
--error ER_GLOBAL_VARIABLE
SET SESSION read_only=0;
--disconnect user1
--connection default
DROP USER user1@localhost;
--echo # Test that "SET read_only" is allowed with SUPER
CREATE USER user1@localhost;
GRANT SUPER ON *.* TO user1@localhost;
--connect(user1,localhost,user1,,)
--connection user1
SET GLOBAL read_only=0;
--error ER_GLOBAL_VARIABLE
SET read_only=0;
--error ER_GLOBAL_VARIABLE
SET SESSION read_only=0;
--disconnect user1
--connection default
DROP USER user1@localhost;
......@@ -325,7 +325,11 @@ constexpr privilege_t PRIV_SET_SYSTEM_VAR_SQL_LOG_BIN=
/* Privileges related to --read-only */
// Was super prior to 10.5.2
constexpr privilege_t PRIV_IGNORE_READ_ONLY= READ_ONLY_ADMIN_ACL | SUPER_ACL;
// Was super prior to 10.5.2
constexpr privilege_t PRIV_SET_SYSTEM_GLOBAL_VAR_READ_ONLY=
READ_ONLY_ADMIN_ACL | SUPER_ACL;
/*
Privileges related to connection handling.
......
......@@ -2822,7 +2822,9 @@ static bool fix_read_only(sys_var *self, THD *thd, enum_var_type type)
transition (especially when transitioning from false to true) and
synchronizes both booleans in the end.
*/
static Sys_var_mybool Sys_readonly(
static Sys_var_on_access_global<Sys_var_mybool,
PRIV_SET_SYSTEM_GLOBAL_VAR_READ_ONLY>
Sys_readonly(
"read_only",
"Make all non-temporary tables read-only, with the exception for "
"replication (slave) threads and users with the SUPER privilege",
......
......@@ -118,6 +118,17 @@ class Sys_var_on_access: public BASE
};
template<class BASE, privilege_t GLOBAL_PRIV>
class Sys_var_on_access_global: public BASE
{
using BASE::BASE;
bool on_check_access_global(THD *thd) const override
{
return check_global_access(thd, GLOBAL_PRIV);
}
};
/**
A small wrapper class to pass getopt arguments as a pair
to the Sys_var_* constructors. It improves type safety and helps
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment