Commit 4203f572 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-15923 option to control who can set session @@timestamp

--secure-timestamp=NO|SUPER|REPLICATION|YES
parent bbf5cf4d
......@@ -1038,6 +1038,14 @@ The following specify which files/extra groups are read (specified before remain
--secure-file-priv=name
Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to
files within specified directory
--secure-timestamp=name
Restricts direct setting of a session timestamp. Possible
levels are: YES - timestamp cannot deviate from the
system clock, REPLICATION - replication thread can adjust
timestamp to match the master's, SUPER - a user with this
privilege and a replication thread can adjust timestamp,
NO - historical behavior, anyone can modify session
timestamp
--server-id=# Uniquely identifies the server instance in the community
of replication partners
--session-track-schema
......@@ -1616,6 +1624,7 @@ rpl-semi-sync-slave-trace-level 32
safe-user-create FALSE
secure-auth TRUE
secure-file-priv (No default value)
secure-timestamp NO
server-id 1
session-track-schema TRUE
session-track-state-change FALSE
......
#
# MDEV-15923 option to control who can set session @@timestamp
#
source include/have_binlog_format_statement.inc;
source include/master-slave.inc;
connection slave;
select @@secure_timestamp;
### SUPER
disable_abort_on_error;
set timestamp=1234567890.101112;
enable_abort_on_error;
select if(now(6) > 20100101, 'READONLY', 'EDITABLE') as 'SUPER';
### non-privileged user
create user foo@127.0.0.1;
connect con2,127.0.0.1,foo,,test,$SLAVE_MYPORT;
disable_abort_on_error;
set timestamp=1234567890.101112;
enable_abort_on_error;
select if(now(6) > 20100101, 'READONLY', 'EDITABLE') as 'non-privileged';
disconnect con2;
connection slave;
drop user foo@127.0.0.1;
### replication
connection master;
set time_zone='+00:00';
set timestamp=1234567890.101112;
select @@timestamp, now(6);
create table t1 (b varchar(20), a timestamp(6) default current_timestamp(6));
insert t1 (b) values ('replicated');
sync_slave_with_master;
create trigger t1rbr before insert on t1 for each row set new.a=now(6);
set @@global.slave_run_triggers_for_rbr= yes;
binlog 'LQfqWg8BAAAA/AAAAAABAAABAAQAMTAuMy42LU1hcmlhREItZGVidWctbG9nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtB+paEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEEwQADQgICAoKCgFlBcaR';
binlog '0gKWSRMBAAAAMQAAAHQDAAAAAB8AAAAAAAEABHRlc3QAAnQxAAIPEQMUAAYBQFUzwA==0gKWSRcBAAAAMAAAAKQDAAAAAB8AAAAAAAEAAv/8BmJpbmxvZ0mWAtIBivg3mwo+';
set @@global.slave_run_triggers_for_rbr= default;
select b, if(a > 20100101, 'READONLY', 'EDITABLE') as 'REPLICATION' from t1;
connection master;
#set binlog_format=row;
#insert t1 (b) values ('binlog');
#let datadir=`select @@datadir`;
#exec $MYSQL_BINLOG $datadir/master-bin.000001;
drop table t1;
source include/rpl_end.inc;
include/master-slave.inc
[connection master]
connection slave;
select @@secure_timestamp;
@@secure_timestamp
NO
set timestamp=1234567890.101112;
select if(now(6) > 20100101, 'READONLY', 'EDITABLE') as 'SUPER';
SUPER
EDITABLE
create user foo@127.0.0.1;
connect con2,127.0.0.1,foo,,test,$SLAVE_MYPORT;
set timestamp=1234567890.101112;
select if(now(6) > 20100101, 'READONLY', 'EDITABLE') as 'non-privileged';
non-privileged
EDITABLE
disconnect con2;
connection slave;
drop user foo@127.0.0.1;
connection master;
set time_zone='+00:00';
set timestamp=1234567890.101112;
select @@timestamp, now(6);
@@timestamp now(6)
1234567890.101112 2009-02-13 23:31:30.101112
create table t1 (b varchar(20), a timestamp(6) default current_timestamp(6));
insert t1 (b) values ('replicated');
connection slave;
create trigger t1rbr before insert on t1 for each row set new.a=now(6);
set @@global.slave_run_triggers_for_rbr= yes;
binlog 'LQfqWg8BAAAA/AAAAAABAAABAAQAMTAuMy42LU1hcmlhREItZGVidWctbG9nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtB+paEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEEwQADQgICAoKCgFlBcaR';
binlog '0gKWSRMBAAAAMQAAAHQDAAAAAB8AAAAAAAEABHRlc3QAAnQxAAIPEQMUAAYBQFUzwA==0gKWSRcBAAAAMAAAAKQDAAAAAB8AAAAAAAEAAv/8BmJpbmxvZ0mWAtIBivg3mwo+';
set @@global.slave_run_triggers_for_rbr= default;
select b, if(a > 20100101, 'READONLY', 'EDITABLE') as 'REPLICATION' from t1;
b REPLICATION
replicated EDITABLE
binlog EDITABLE
connection master;
drop table t1;
include/rpl_end.inc
include/master-slave.inc
[connection master]
connection slave;
select @@secure_timestamp;
@@secure_timestamp
REPLICATION
set timestamp=1234567890.101112;
ERROR HY000: The MariaDB server is running with the --secure-timestamp=REPLICATION option so it cannot execute this statement
select if(now(6) > 20100101, 'READONLY', 'EDITABLE') as 'SUPER';
SUPER
READONLY
create user foo@127.0.0.1;
connect con2,127.0.0.1,foo,,test,$SLAVE_MYPORT;
set timestamp=1234567890.101112;
ERROR HY000: The MariaDB server is running with the --secure-timestamp=REPLICATION option so it cannot execute this statement
select if(now(6) > 20100101, 'READONLY', 'EDITABLE') as 'non-privileged';
non-privileged
READONLY
disconnect con2;
connection slave;
drop user foo@127.0.0.1;
connection master;
set time_zone='+00:00';
set timestamp=1234567890.101112;
select @@timestamp, now(6);
@@timestamp now(6)
1234567890.101112 2009-02-13 23:31:30.101112
create table t1 (b varchar(20), a timestamp(6) default current_timestamp(6));
insert t1 (b) values ('replicated');
connection slave;
create trigger t1rbr before insert on t1 for each row set new.a=now(6);
set @@global.slave_run_triggers_for_rbr= yes;
binlog 'LQfqWg8BAAAA/AAAAAABAAABAAQAMTAuMy42LU1hcmlhREItZGVidWctbG9nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtB+paEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEEwQADQgICAoKCgFlBcaR';
binlog '0gKWSRMBAAAAMQAAAHQDAAAAAB8AAAAAAAEABHRlc3QAAnQxAAIPEQMUAAYBQFUzwA==0gKWSRcBAAAAMAAAAKQDAAAAAB8AAAAAAAEAAv/8BmJpbmxvZ0mWAtIBivg3mwo+';
set @@global.slave_run_triggers_for_rbr= default;
select b, if(a > 20100101, 'READONLY', 'EDITABLE') as 'REPLICATION' from t1;
b REPLICATION
replicated EDITABLE
binlog READONLY
connection master;
drop table t1;
include/rpl_end.inc
include/master-slave.inc
[connection master]
connection slave;
select @@secure_timestamp;
@@secure_timestamp
SUPER
set timestamp=1234567890.101112;
select if(now(6) > 20100101, 'READONLY', 'EDITABLE') as 'SUPER';
SUPER
EDITABLE
create user foo@127.0.0.1;
connect con2,127.0.0.1,foo,,test,$SLAVE_MYPORT;
set timestamp=1234567890.101112;
ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
select if(now(6) > 20100101, 'READONLY', 'EDITABLE') as 'non-privileged';
non-privileged
READONLY
disconnect con2;
connection slave;
drop user foo@127.0.0.1;
connection master;
set time_zone='+00:00';
set timestamp=1234567890.101112;
select @@timestamp, now(6);
@@timestamp now(6)
1234567890.101112 2009-02-13 23:31:30.101112
create table t1 (b varchar(20), a timestamp(6) default current_timestamp(6));
insert t1 (b) values ('replicated');
connection slave;
create trigger t1rbr before insert on t1 for each row set new.a=now(6);
set @@global.slave_run_triggers_for_rbr= yes;
binlog 'LQfqWg8BAAAA/AAAAAABAAABAAQAMTAuMy42LU1hcmlhREItZGVidWctbG9nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtB+paEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEEwQADQgICAoKCgFlBcaR';
binlog '0gKWSRMBAAAAMQAAAHQDAAAAAB8AAAAAAAEABHRlc3QAAnQxAAIPEQMUAAYBQFUzwA==0gKWSRcBAAAAMAAAAKQDAAAAAB8AAAAAAAEAAv/8BmJpbmxvZ0mWAtIBivg3mwo+';
set @@global.slave_run_triggers_for_rbr= default;
select b, if(a > 20100101, 'READONLY', 'EDITABLE') as 'REPLICATION' from t1;
b REPLICATION
replicated EDITABLE
binlog EDITABLE
connection master;
drop table t1;
include/rpl_end.inc
include/master-slave.inc
[connection master]
connection slave;
select @@secure_timestamp;
@@secure_timestamp
YES
set timestamp=1234567890.101112;
ERROR HY000: The MariaDB server is running with the --secure-timestamp=YES option so it cannot execute this statement
select if(now(6) > 20100101, 'READONLY', 'EDITABLE') as 'SUPER';
SUPER
READONLY
create user foo@127.0.0.1;
connect con2,127.0.0.1,foo,,test,$SLAVE_MYPORT;
set timestamp=1234567890.101112;
ERROR HY000: The MariaDB server is running with the --secure-timestamp=YES option so it cannot execute this statement
select if(now(6) > 20100101, 'READONLY', 'EDITABLE') as 'non-privileged';
non-privileged
READONLY
disconnect con2;
connection slave;
drop user foo@127.0.0.1;
connection master;
set time_zone='+00:00';
set timestamp=1234567890.101112;
select @@timestamp, now(6);
@@timestamp now(6)
1234567890.101112 2009-02-13 23:31:30.101112
create table t1 (b varchar(20), a timestamp(6) default current_timestamp(6));
insert t1 (b) values ('replicated');
connection slave;
create trigger t1rbr before insert on t1 for each row set new.a=now(6);
set @@global.slave_run_triggers_for_rbr= yes;
binlog 'LQfqWg8BAAAA/AAAAAABAAABAAQAMTAuMy42LU1hcmlhREItZGVidWctbG9nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtB+paEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEEwQADQgICAoKCgFlBcaR';
binlog '0gKWSRMBAAAAMQAAAHQDAAAAAB8AAAAAAAEABHRlc3QAAnQxAAIPEQMUAAYBQFUzwA==0gKWSRcBAAAAMAAAAKQDAAAAAB8AAAAAAAEAAv/8BmJpbmxvZ0mWAtIBivg3mwo+';
set @@global.slave_run_triggers_for_rbr= default;
select b, if(a > 20100101, 'READONLY', 'EDITABLE') as 'REPLICATION' from t1;
b REPLICATION
replicated READONLY
binlog READONLY
connection master;
drop table t1;
include/rpl_end.inc
......@@ -3540,6 +3540,20 @@ NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST NULL
READ_ONLY YES
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME SECURE_TIMESTAMP
SESSION_VALUE NULL
GLOBAL_VALUE NO
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE NO
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE ENUM
VARIABLE_COMMENT Restricts direct setting of a session timestamp. Possible levels are: YES - timestamp cannot deviate from the system clock, REPLICATION - replication thread can adjust timestamp to match the master's, SUPER - a user with this privilege and a replication thread can adjust timestamp, NO - historical behavior, anyone can modify session timestamp
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST NO,SUPER,REPLICATION,YES
READ_ONLY YES
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME SERVER_ID
SESSION_VALUE 1
GLOBAL_VALUE 1
......
......@@ -4156,6 +4156,20 @@ NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST NULL
READ_ONLY YES
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME SECURE_TIMESTAMP
SESSION_VALUE NULL
GLOBAL_VALUE NO
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE NO
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE ENUM
VARIABLE_COMMENT Restricts direct setting of a session timestamp. Possible levels are: YES - timestamp cannot deviate from the system clock, REPLICATION - replication thread can adjust timestamp to match the master's, SUPER - a user with this privilege and a replication thread can adjust timestamp, NO - historical behavior, anyone can modify session timestamp
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST NO,SUPER,REPLICATION,YES
READ_ONLY YES
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME SERVER_ID
SESSION_VALUE 1
GLOBAL_VALUE 1
......
#
# MDEV-15923 option to control who can set session @@timestamp
#
source inc/secure_timestamp_func.inc;
#
# MDEV-15923 option to control who can set session @@timestamp
#
source inc/secure_timestamp_func.inc;
#
# MDEV-15923 option to control who can set session @@timestamp
#
source inc/secure_timestamp_func.inc;
#
# MDEV-15923 option to control who can set session @@timestamp
#
source inc/secure_timestamp_func.inc;
......@@ -534,6 +534,7 @@ ulonglong slave_skipped_errors;
ulong feature_files_opened_with_delayed_keys= 0, feature_check_constraint= 0;
ulonglong denied_connections;
my_decimal decimal_zero;
long opt_secure_timestamp;
/*
Maximum length of parameter value which can be set through
......
......@@ -302,6 +302,9 @@ extern my_bool encrypt_binlog;
extern my_bool encrypt_tmp_disk_tables, encrypt_tmp_files;
extern ulong encryption_algorithm;
extern const char *encryption_algorithm_names[];
extern long opt_secure_timestamp;
enum secure_timestamp { SECTIME_NO, SECTIME_SUPER, SECTIME_REPL, SECTIME_YES };
#ifdef HAVE_PSI_INTERFACE
#ifdef HAVE_MMAP
......
......@@ -3522,15 +3522,20 @@ class THD :public Statement,
*/
inline void set_time(my_time_t t, ulong sec_part)
{
start_time= t;
start_time_sec_part= sec_part > TIME_MAX_SECOND_PART ? 0 : sec_part;
user_time.val= hrtime_from_time(start_time) + start_time_sec_part;
if (slave_thread)
set_system_time_from_user_time(sec_part <= TIME_MAX_SECOND_PART);
else // BINLOG command
set_system_time();
PSI_CALL_set_thread_start_time(start_time);
start_utime= utime_after_lock= microsecond_interval_timer();
if (opt_secure_timestamp > (slave_thread ? SECTIME_REPL : SECTIME_SUPER))
set_time(); // note that BINLOG itself requires SUPER
else
{
start_time= t;
start_time_sec_part= sec_part > TIME_MAX_SECOND_PART ? 0 : sec_part;
user_time.val= hrtime_from_time(start_time) + start_time_sec_part;
if (slave_thread)
set_system_time_from_user_time(sec_part <= TIME_MAX_SECOND_PART);
else // BINLOG command
set_system_time();
PSI_CALL_set_thread_start_time(start_time);
start_utime= utime_after_lock= microsecond_interval_timer();
}
}
void set_time_after_lock()
{
......
......@@ -4212,11 +4212,24 @@ static Sys_var_harows Sys_select_limit(
SESSION_VAR(select_limit), NO_CMD_LINE,
VALID_RANGE(0, HA_POS_ERROR), DEFAULT(HA_POS_ERROR), BLOCK_SIZE(1));
static const char *secure_timestamp_levels[]= {"NO", "SUPER", "REPLICATION", "YES", 0};
static bool check_timestamp(sys_var *self, THD *thd, set_var *var)
{
if (opt_secure_timestamp == SECTIME_NO)
return false;
if (opt_secure_timestamp == SECTIME_SUPER)
return check_has_super(self, thd, var);
char buf[1024];
strxnmov(buf, sizeof(buf), "--secure-timestamp=",
secure_timestamp_levels[opt_secure_timestamp], NULL);
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), buf);
return true;
}
static Sys_var_timestamp Sys_timestamp(
"timestamp", "Set the time for this client",
sys_var::ONLY_SESSION, NO_CMD_LINE,
VALID_RANGE(0, TIMESTAMP_MAX_VALUE),
NO_MUTEX_GUARD, IN_BINLOG);
NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_timestamp));
static bool update_last_insert_id(THD *thd, set_var *var)
{
......@@ -6052,3 +6065,13 @@ static Sys_var_uint Sys_in_subquery_conversion_threshold(
SESSION_VAR(in_subquery_conversion_threshold), CMD_LINE(OPT_ARG),
VALID_RANGE(0, UINT_MAX), DEFAULT(IN_SUBQUERY_CONVERSION_THRESHOLD), BLOCK_SIZE(1));
#endif
static Sys_var_enum Sys_secure_timestamp(
"secure_timestamp", "Restricts direct setting of a session "
"timestamp. Possible levels are: YES - timestamp cannot deviate from "
"the system clock, REPLICATION - replication thread can adjust "
"timestamp to match the master's, SUPER - a user with this "
"privilege and a replication thread can adjust timestamp, NO - "
"historical behavior, anyone can modify session timestamp",
READ_ONLY GLOBAL_VAR(opt_secure_timestamp), CMD_LINE(REQUIRED_ARG),
secure_timestamp_levels, DEFAULT(SECTIME_NO));
......@@ -1892,10 +1892,11 @@ public:
const char *comment, int flag_args,
CMD_LINE getopt,
double min_val, double max_val,
PolyLock *lock, enum binlog_status_enum binlog_status_arg)
PolyLock *lock, enum binlog_status_enum binlog_status_arg,
on_check_function on_check_func=0)
: Sys_var_double(name_arg, comment, flag_args, 0,
sizeof(double), getopt, min_val,
max_val, 0, lock, binlog_status_arg)
max_val, 0, lock, binlog_status_arg, on_check_func)
{
SYSVAR_ASSERT(scope() == ONLY_SESSION);
SYSVAR_ASSERT(getopt.id < 0); // NO_CMD_LINE, because the offset is fake
......
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