Skip to content

Commit

Permalink
MDEV-21957 Bind BINLOG ADMIN to @@binlog_format, @@binlog_direct_.., …
Browse files Browse the repository at this point in the history
…@@sql_log_bin
  • Loading branch information
abarkov committed Mar 17, 2020
1 parent c7ba923 commit b602584
Show file tree
Hide file tree
Showing 14 changed files with 347 additions and 19 deletions.
2 changes: 1 addition & 1 deletion mysql-test/main/grant2.result
Expand Up @@ -162,7 +162,7 @@ connection con10;
set sql_log_off = 1;
ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
set sql_log_bin = 0;
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, BINLOG ADMIN privilege(s) for this operation
disconnect con10;
connection default;
delete from mysql.user where user like 'mysqltest\_1';
Expand Down
6 changes: 3 additions & 3 deletions mysql-test/suite/binlog/r/binlog_grant.result
Expand Up @@ -14,7 +14,7 @@ set session sql_log_bin = 1;
connection plain;
[plain]
set session sql_log_bin = 1;
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, BINLOG ADMIN privilege(s) for this operation
**** Variable BINLOG_FORMAT ****
connection root;
[root]
Expand All @@ -23,9 +23,9 @@ set session binlog_format = row;
connection plain;
[plain]
set global binlog_format = row;
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, BINLOG ADMIN privilege(s) for this operation
set session binlog_format = row;
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, BINLOG ADMIN privilege(s) for this operation
**** Clean up ****
disconnect plain;
disconnect root;
Expand Down
2 changes: 1 addition & 1 deletion mysql-test/suite/rpl/r/rpl_temporary.result
Expand Up @@ -45,7 +45,7 @@ SELECT @@session.sql_select_limit = @save_select_limit;
@@session.sql_select_limit = @save_select_limit
1
SET @@session.sql_select_limit=10, @@session.sql_log_bin=0;
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, BINLOG ADMIN privilege(s) for this operation
SELECT @@session.sql_select_limit = @save_select_limit;
@@session.sql_select_limit = @save_select_limit
1
Expand Down
@@ -0,0 +1,44 @@
SET @global= @@global.binlog_direct_non_transactional_updates;
SET @session= @@global.binlog_direct_non_transactional_updates;
#
#
#
# Test that "SET binlog_direct_non_transactional_updates" 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 binlog_direct_non_transactional_updates=0;
ERROR 42000: Access denied; you need (at least one of) the SUPER, BINLOG ADMIN privilege(s) for this operation
SET GLOBAL binlog_direct_non_transactional_updates=0;
ERROR 42000: Access denied; you need (at least one of) the SUPER, BINLOG ADMIN privilege(s) for this operation
SET SESSION binlog_direct_non_transactional_updates=0;
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_direct_non_transactional_updates" is allowed with BINLOG ADMIN
CREATE USER user1@localhost;
GRANT BINLOG ADMIN ON *.* TO user1@localhost;
connect user1,localhost,user1,,;
connection user1;
SET binlog_direct_non_transactional_updates=0;
SET GLOBAL binlog_direct_non_transactional_updates=0;
SET SESSION binlog_direct_non_transactional_updates=0;
disconnect user1;
connection default;
DROP USER user1@localhost;
# Test that "SET binlog_direct_non_transactional_updates" is allowed with SUPER
CREATE USER user1@localhost;
GRANT SUPER ON *.* TO user1@localhost;
connect user1,localhost,user1,,;
connection user1;
SET binlog_direct_non_transactional_updates=0;
SET GLOBAL binlog_direct_non_transactional_updates=0;
SET SESSION binlog_direct_non_transactional_updates=0;
disconnect user1;
connection default;
DROP USER user1@localhost;
SET GLOBAL binlog_direct_non_transactional_updates=@global;
SET SESSION binlog_direct_non_transactional_updates=@session;
40 changes: 40 additions & 0 deletions mysql-test/suite/sys_vars/r/binlog_format_grant.result
@@ -0,0 +1,40 @@
#
#
#
# Test that "SET binlog_format" 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 binlog_format=mixed;
ERROR 42000: Access denied; you need (at least one of) the SUPER, BINLOG ADMIN privilege(s) for this operation
SET GLOBAL binlog_format=mixed;
ERROR 42000: Access denied; you need (at least one of) the SUPER, BINLOG ADMIN privilege(s) for this operation
SET SESSION binlog_format=mixed;
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_format" is allowed with BINLOG ADMIN
CREATE USER user1@localhost;
GRANT BINLOG ADMIN ON *.* TO user1@localhost;
connect user1,localhost,user1,,;
connection user1;
SET binlog_format=mixed;
SET GLOBAL binlog_format=mixed;
SET SESSION binlog_format=mixed;
disconnect user1;
connection default;
DROP USER user1@localhost;
# Test that "SET binlog_format" is allowed with SUPER
CREATE USER user1@localhost;
GRANT SUPER ON *.* TO user1@localhost;
connect user1,localhost,user1,,;
connection user1;
SET binlog_format=mixed;
SET GLOBAL binlog_format=mixed;
SET SESSION binlog_format=mixed;
disconnect user1;
connection default;
DROP USER user1@localhost;
42 changes: 42 additions & 0 deletions mysql-test/suite/sys_vars/r/sql_log_bin_grant.result
@@ -0,0 +1,42 @@
#
#
#
# Test that "SET sql_log_bin" 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 sql_log_bin=1;
ERROR 42000: Access denied; you need (at least one of) the SUPER, BINLOG ADMIN privilege(s) for this operation
SET GLOBAL sql_log_bin=1;
ERROR 42000: Access denied; you need (at least one of) the SUPER, BINLOG ADMIN privilege(s) for this operation
SET SESSION sql_log_bin=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 sql_log_bin" is allowed with BINLOG ADMIN
CREATE USER user1@localhost;
GRANT BINLOG ADMIN ON *.* TO user1@localhost;
connect user1,localhost,user1,,;
connection user1;
SET sql_log_bin=1;
SET GLOBAL sql_log_bin=1;
ERROR HY000: Variable 'sql_log_bin' is a SESSION variable
SET SESSION sql_log_bin=1;
disconnect user1;
connection default;
DROP USER user1@localhost;
# Test that "SET sql_log_bin" is allowed with SUPER
CREATE USER user1@localhost;
GRANT SUPER ON *.* TO user1@localhost;
connect user1,localhost,user1,,;
connection user1;
SET sql_log_bin=1;
SET GLOBAL sql_log_bin=1;
ERROR HY000: Variable 'sql_log_bin' is a SESSION variable
SET SESSION sql_log_bin=1;
disconnect user1;
connection default;
DROP USER user1@localhost;
@@ -0,0 +1,56 @@
source include/have_log_bin.inc;

SET @global= @@global.binlog_direct_non_transactional_updates;
SET @session= @@global.binlog_direct_non_transactional_updates;


--echo #
--echo #
--echo #

--echo # Test that "SET binlog_direct_non_transactional_updates" 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
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
SET binlog_direct_non_transactional_updates=0;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
SET GLOBAL binlog_direct_non_transactional_updates=0;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
SET SESSION binlog_direct_non_transactional_updates=0;
--disconnect user1
--connection default
DROP USER user1@localhost;

--echo # Test that "SET binlog_direct_non_transactional_updates" is allowed with BINLOG ADMIN

CREATE USER user1@localhost;
GRANT BINLOG ADMIN ON *.* TO user1@localhost;
--connect(user1,localhost,user1,,)
--connection user1
SET binlog_direct_non_transactional_updates=0;
SET GLOBAL binlog_direct_non_transactional_updates=0;
SET SESSION binlog_direct_non_transactional_updates=0;
--disconnect user1
--connection default
DROP USER user1@localhost;

--echo # Test that "SET binlog_direct_non_transactional_updates" is allowed with SUPER

CREATE USER user1@localhost;
GRANT SUPER ON *.* TO user1@localhost;
--connect(user1,localhost,user1,,)
--connection user1
SET binlog_direct_non_transactional_updates=0;
SET GLOBAL binlog_direct_non_transactional_updates=0;
SET SESSION binlog_direct_non_transactional_updates=0;
--disconnect user1
--connection default
DROP USER user1@localhost;


SET GLOBAL binlog_direct_non_transactional_updates=@global;
SET SESSION binlog_direct_non_transactional_updates=@session;
49 changes: 49 additions & 0 deletions mysql-test/suite/sys_vars/t/binlog_format_grant.test
@@ -0,0 +1,49 @@
source include/have_log_bin.inc;


--echo #
--echo #
--echo #

--echo # Test that "SET binlog_format" 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
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
SET binlog_format=mixed;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
SET GLOBAL binlog_format=mixed;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
SET SESSION binlog_format=mixed;
--disconnect user1
--connection default
DROP USER user1@localhost;

--echo # Test that "SET binlog_format" is allowed with BINLOG ADMIN

CREATE USER user1@localhost;
GRANT BINLOG ADMIN ON *.* TO user1@localhost;
--connect(user1,localhost,user1,,)
--connection user1
SET binlog_format=mixed;
SET GLOBAL binlog_format=mixed;
SET SESSION binlog_format=mixed;
--disconnect user1
--connection default
DROP USER user1@localhost;

--echo # Test that "SET binlog_format" is allowed with SUPER

CREATE USER user1@localhost;
GRANT SUPER ON *.* TO user1@localhost;
--connect(user1,localhost,user1,,)
--connection user1
SET binlog_format=mixed;
SET GLOBAL binlog_format=mixed;
SET SESSION binlog_format=mixed;
--disconnect user1
--connection default
DROP USER user1@localhost;
51 changes: 51 additions & 0 deletions mysql-test/suite/sys_vars/t/sql_log_bin_grant.test
@@ -0,0 +1,51 @@
source include/have_log_bin.inc;


--echo #
--echo #
--echo #

--echo # Test that "SET sql_log_bin" 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
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
SET sql_log_bin=1;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
SET GLOBAL sql_log_bin=1;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
SET SESSION sql_log_bin=1;
--disconnect user1
--connection default
DROP USER user1@localhost;

--echo # Test that "SET sql_log_bin" is allowed with BINLOG ADMIN

CREATE USER user1@localhost;
GRANT BINLOG ADMIN ON *.* TO user1@localhost;
--connect(user1,localhost,user1,,)
--connection user1
SET sql_log_bin=1;
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
SET GLOBAL sql_log_bin=1;
SET SESSION sql_log_bin=1;
--disconnect user1
--connection default
DROP USER user1@localhost;

--echo # Test that "SET sql_log_bin" is allowed with SUPER

CREATE USER user1@localhost;
GRANT SUPER ON *.* TO user1@localhost;
--connect(user1,localhost,user1,,)
--connection user1
SET sql_log_bin=1;
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
SET GLOBAL sql_log_bin=1;
SET SESSION sql_log_bin=1;
--disconnect user1
--connection default
DROP USER user1@localhost;
9 changes: 9 additions & 0 deletions sql/privilege.h
Expand Up @@ -315,6 +315,15 @@ constexpr privilege_t PRIV_DEBUG= SUPER_ACL;
constexpr privilege_t PRIV_SET_GLOBAL_SYSTEM_VARIABLE= SUPER_ACL;
constexpr privilege_t PRIV_SET_RESTRICTED_SESSION_SYSTEM_VARIABLE= SUPER_ACL;

/* The following variables respected only SUPER_ACL prior to 10.5.2 */
constexpr privilege_t PRIV_SET_SYSTEM_VAR_BINLOG_FORMAT=
SUPER_ACL | BINLOG_ADMIN_ACL;
constexpr privilege_t PRIV_SET_SYSTEM_VAR_BINLOG_DIRECT_NON_TRANSACTIONAL_UPDATES=
SUPER_ACL | BINLOG_ADMIN_ACL;
constexpr privilege_t PRIV_SET_SYSTEM_VAR_SQL_LOG_BIN=
SUPER_ACL | BINLOG_ADMIN_ACL;


/* Privileges related to --read-only */
constexpr privilege_t PRIV_IGNORE_READ_ONLY= READ_ONLY_ADMIN_ACL | SUPER_ACL;

Expand Down
18 changes: 16 additions & 2 deletions sql/set_var.cc
Expand Up @@ -756,6 +756,11 @@ int sql_set_variables(THD *thd, List<set_var_base> *var_list, bool free)
Functions to handle SET mysql_internal_variable=const_expr
*****************************************************************************/

bool sys_var::on_check_access_global(THD *thd) const
{
return check_global_access(thd, PRIV_SET_GLOBAL_SYSTEM_VARIABLE);
}

/**
Verify that the supplied value is correct.
Expand All @@ -780,8 +785,7 @@ int set_var::check(THD *thd)
my_error(err, MYF(0), var->name.str);
return -1;
}
if (type == OPT_GLOBAL &&
check_global_access(thd, PRIV_SET_GLOBAL_SYSTEM_VARIABLE))
if (type == OPT_GLOBAL && var->on_check_access_global(thd))
return 1;
/* value is a NULL pointer if we are using SET ... = DEFAULT */
if (!value)
Expand All @@ -794,6 +798,16 @@ int set_var::check(THD *thd)
my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name.str);
return -1;
}
switch (type) {
case SHOW_OPT_DEFAULT:
case SHOW_OPT_SESSION:
DBUG_ASSERT(var->scope() != sys_var::GLOBAL);
if (var->on_check_access_session(thd))
return -1;
break;
case SHOW_OPT_GLOBAL: // Checked earlier
break;
}
return var->check(thd, this) ? -1 : 0;
}

Expand Down
6 changes: 6 additions & 0 deletions sql/set_var.h
Expand Up @@ -214,6 +214,12 @@ class sys_var: protected Value_source // for double_from_string_with_check
virtual uchar *default_value_ptr(THD *thd)
{ return (uchar*)&option.def_value; }

virtual bool on_check_access_global(THD *thd) const;
virtual bool on_check_access_session(THD *thd) const
{
return false;
}

private:
virtual bool do_check(THD *thd, set_var *var) = 0;
/**
Expand Down

0 comments on commit b602584

Please sign in to comment.