From 589355f0f58dc91d0c2f779f1a66bc22f87ed5a2 Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Tue, 9 Sep 2008 12:19:31 +0200 Subject: [PATCH] Bug #39106: SUPER is not required to change binlog format for session A user without SUPER privileges can change the value of the session variable BINLOG_FORMAT, causing problems for a DBA. This changeset requires a user to have SUPER privileges to change the value of the session variable BINLOG_FORMAT, and not only the global variable BINLOG_FORMAT. mysql-test/suite/binlog/t/binlog_grant.test: Adding test to test grants needed for SQL_LOG_BIN and BINLOG_FORMAT. sql/set_var.cc: Adding code to check that user has SUPER permission needed to change the value of BINLOG_FORMAT. sql/set_var.h: Adding function sys_var_thd_binlog_format::check() --- mysql-test/suite/binlog/r/binlog_grant.result | 28 +++++++++ mysql-test/suite/binlog/t/binlog_grant.test | 60 +++++++++++++++++++ sql/set_var.cc | 15 +++++ sql/set_var.h | 1 + 4 files changed, 104 insertions(+) create mode 100644 mysql-test/suite/binlog/r/binlog_grant.result create mode 100644 mysql-test/suite/binlog/t/binlog_grant.test diff --git a/mysql-test/suite/binlog/r/binlog_grant.result b/mysql-test/suite/binlog/r/binlog_grant.result new file mode 100644 index 00000000000..21ebb891103 --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_grant.result @@ -0,0 +1,28 @@ +reset master; +set @saved_binlog_format = @@global.binlog_format; +create user mysqltest_1@localhost; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +**** Variable SQL_LOG_BIN **** +[root] +set global sql_log_bin = 1; +ERROR HY000: Variable 'sql_log_bin' is a SESSION variable and can't be used with SET GLOBAL +set session sql_log_bin = 1; +[plain] +set global sql_log_bin = 1; +ERROR HY000: Variable 'sql_log_bin' is a SESSION variable and can't be used with SET GLOBAL +set session sql_log_bin = 1; +ERROR 42000: Access denied; you need the SUPER privilege for this operation +**** Variable BINLOG_FORMAT **** +[root] +set global binlog_format = row; +set session binlog_format = row; +[plain] +set global binlog_format = row; +ERROR 42000: Access denied; you need the SUPER privilege for this operation +set session binlog_format = row; +ERROR 42000: Access denied; you need the SUPER privilege for this operation +**** Clean up **** +set global binlog_format = @saved_binlog_format; +drop user mysqltest_1@localhost; diff --git a/mysql-test/suite/binlog/t/binlog_grant.test b/mysql-test/suite/binlog/t/binlog_grant.test new file mode 100644 index 00000000000..d36dcce4cc3 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_grant.test @@ -0,0 +1,60 @@ +# Test grants for various objects (especially variables) related to +# the binary log + +source include/have_log_bin.inc; + +connection default; +--disable_warnings +reset master; +--enable_warnings + +set @saved_binlog_format = @@global.binlog_format; +create user mysqltest_1@localhost; +show grants for mysqltest_1@localhost; + +connect (plain,localhost,mysqltest_1,,test); +connect (root,localhost,root,,test); + +# Testing setting both session and global SQL_LOG_BIN variable both as +# root and as plain user. + +--echo **** Variable SQL_LOG_BIN **** + +connection root; +--echo [root] +--error ER_LOCAL_VARIABLE +set global sql_log_bin = 1; +set session sql_log_bin = 1; + +connection plain; +--echo [plain] +--error ER_LOCAL_VARIABLE +set global sql_log_bin = 1; +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +set session sql_log_bin = 1; + + +# Testing setting both session and global BINLOG_FORMAT variable both +# as root and as plain user. + +--echo **** Variable BINLOG_FORMAT **** + +connection root; +--echo [root] +set global binlog_format = row; +set session binlog_format = row; + +connection plain; +--echo [plain] +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +set global binlog_format = row; +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +set session binlog_format = row; + +--echo **** Clean up **** +disconnect plain; +disconnect root; + +connection default; +set global binlog_format = @saved_binlog_format; +drop user mysqltest_1@localhost; diff --git a/sql/set_var.cc b/sql/set_var.cc index 7d9d88f0281..4259c3a6aaf 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1162,6 +1162,21 @@ void fix_slave_exec_mode(enum_var_type type) bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT); } + +bool sys_var_thd_binlog_format::check(THD *thd, set_var *var) { + /* + All variables that affect writing to binary log (either format or + turning logging on and off) use the same checking. We call the + superclass ::check function to assign the variable correctly, and + then check the value. + */ + bool result= sys_var_thd_enum::check(thd, var); + if (!result) + result= check_log_update(thd, var); + return result; +} + + bool sys_var_thd_binlog_format::is_readonly() const { /* diff --git a/sql/set_var.h b/sql/set_var.h index 603c3114d0e..8ae97c6502d 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -1126,6 +1126,7 @@ public: &binlog_format_typelib, fix_binlog_format_after_update) {}; + bool check(THD *thd, set_var *var); bool is_readonly() const; };