MDEV-33393 audit plugin do not report user did the action..

The '<replication_slave>' user is assigned to the slave replication
thread so this name appears in the auditing logs.
This commit is contained in:
Alexey Botchkov 2024-02-11 00:05:24 +04:00
parent b770633e07
commit 85517f609a
9 changed files with 154 additions and 8 deletions

View File

@ -0,0 +1,64 @@
include/master-slave.inc
[connection master]
drop table if exists t1;
connection slave;
reset master;
CREATE TABLE IF NOT EXISTS mysql.server_audit_filters (
filtername char(80) COLLATE utf8_bin NOT NULL DEFAULT '',
rule longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT 'true' CHECK (json_valid(rule)),
CONSTRAINT c_filtername UNIQUE (filtername)
) ENGINE=Aria;
CREATE TABLE IF NOT EXISTS mysql.server_audit_users (host char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
user char(80) COLLATE utf8_bin NOT NULL DEFAULT '',
filtername char(80) NOT NULL DEFAULT '',
CONSTRAINT c_host_user UNIQUE (host, user)
) ENGINE=Aria;
INSERT INTO mysql.server_audit_filters VALUES ('ignore_sys', '{"ignore_tables" : "mysql.*"}');
INSERT INTO mysql.server_audit_users VALUES ('%','<replication_slave>','ignore_sys');
INSERT INTO mysql.server_audit_users VALUES ('%','root','ignore_sys');
install plugin server_audit soname 'server_audit2';
set global server_audit_logging=on;
connection master;
create table t1 (a int);
insert into t1 values (1);
truncate t1;
drop table t1;
connection slave;
set global server_audit_logging=off;
truncate mysql.server_audit_filters;
truncate mysql.server_audit_users;
INSERT INTO mysql.server_audit_filters VALUES ('no_logging','false');
INSERT INTO mysql.server_audit_users VALUES ('%','<replication_slave>','no_logging');
set global server_audit_logging=on;
connection master;
create table t1 (a int);
insert into t1 values (1);
truncate t1;
drop table t1;
connection slave;
set global server_audit_logging=off;
uninstall plugin server_audit;
Warnings:
Warning 1620 Plugin is busy and will be uninstalled on shutdown
truncate mysql.server_audit_filters;
truncate mysql.server_audit_users;
TIME,HOSTNAME,,,0,0,AUDIT_CONFIG,,file_path=server_audit.log,0
TIME,HOSTNAME,,,0,0,AUDIT_CONFIG,,rotate_size=1000000,0
TIME,HOSTNAME,,,0,0,AUDIT_CONFIG,,file_rotations=9,0
TIME,HOSTNAME,root,localhost,ID,0,AUDIT_CONFIG,test,logging=ON,0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_logging=on',0
TIME,HOSTNAME,<replication_slave>,,ID,ID,CREATE,test,t1,
TIME,HOSTNAME,<replication_slave>,,ID,ID,WRITE,test,t1,
TIME,HOSTNAME,<replication_slave>,,ID,ID,CREATE,test,t1,
TIME,HOSTNAME,<replication_slave>,,ID,ID,DROP,test,t1,
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select master_pos_wait(\'master-bin.#', POS, 300, \'\')',0
TIME,HOSTNAME,root,localhost,ID,0,AUDIT_CONFIG,test,logging=OFF,0
TIME,HOSTNAME,,,0,0,AUDIT_CONFIG,,file_path=server_audit.log,0
TIME,HOSTNAME,,,0,0,AUDIT_CONFIG,,rotate_size=1000000,0
TIME,HOSTNAME,,,0,0,AUDIT_CONFIG,,file_rotations=9,0
TIME,HOSTNAME,root,localhost,ID,0,AUDIT_CONFIG,test,logging=ON,0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_logging=on',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select master_pos_wait(\'master-bin.#', POS, 300, \'\')',0
TIME,HOSTNAME,root,localhost,ID,0,AUDIT_CONFIG,test,logging=OFF,0
connection master;
include/rpl_end.inc

View File

@ -0,0 +1,77 @@
if (!$SERVER_AUDIT2_SO) {
skip No SERVER_AUDIT2 plugin;
}
source include/master-slave.inc;
--disable_warnings
drop table if exists t1;
sync_slave_with_master;
reset master;
--enable_warnings
--disable_warnings
CREATE TABLE IF NOT EXISTS mysql.server_audit_filters (
filtername char(80) COLLATE utf8_bin NOT NULL DEFAULT '',
rule longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT 'true' CHECK (json_valid(rule)),
CONSTRAINT c_filtername UNIQUE (filtername)
) ENGINE=Aria;
CREATE TABLE IF NOT EXISTS mysql.server_audit_users (host char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
user char(80) COLLATE utf8_bin NOT NULL DEFAULT '',
filtername char(80) NOT NULL DEFAULT '',
CONSTRAINT c_host_user UNIQUE (host, user)
) ENGINE=Aria;
--enable_warnings
INSERT INTO mysql.server_audit_filters VALUES ('ignore_sys', '{"ignore_tables" : "mysql.*"}');
INSERT INTO mysql.server_audit_users VALUES ('%','<replication_slave>','ignore_sys');
INSERT INTO mysql.server_audit_users VALUES ('%','root','ignore_sys');
install plugin server_audit soname 'server_audit2';
set global server_audit_logging=on;
# this is done to make test deterministic
# so the above 'set' command is always logged before the 'create table t1'
-- disable_query_log
-- disable_result_log
select * from mysql.server_audit_filters;
select * from mysql.server_audit_users;
-- enable_result_log
-- enable_query_log
connection master;
create table t1 (a int);
insert into t1 values (1);
truncate t1;
drop table t1;
sync_slave_with_master;
set global server_audit_logging=off;
truncate mysql.server_audit_filters;
truncate mysql.server_audit_users;
INSERT INTO mysql.server_audit_filters VALUES ('no_logging','false');
INSERT INTO mysql.server_audit_users VALUES ('%','<replication_slave>','no_logging');
set global server_audit_logging=on;
connection master;
create table t1 (a int);
insert into t1 values (1);
truncate t1;
drop table t1;
sync_slave_with_master;
set global server_audit_logging=off;
uninstall plugin server_audit;
truncate mysql.server_audit_filters;
truncate mysql.server_audit_users;
let $MYSQLD_DATADIR= `SELECT @@datadir`;
# replace the timestamp and the hostname with constant values
--replace_regex /[0-9]* [0-9][0-9]:[0-9][0-9]:[0-9][0-9]\,[^,]*\,/TIME,HOSTNAME,/ /\,[1-9][0-9]*\,/,1,/ /\,[1-9][0-9]*/,ID/ /000001\\', [0-9]*,/#', POS,/
cat_file $MYSQLD_DATADIR/server_audit.log;
remove_file $MYSQLD_DATADIR/server_audit.log;
connection master;
--source include/rpl_end.inc

View File

@ -297,7 +297,8 @@ static TYPELIB tc_heuristic_recover_typelib=
};
const char *first_keyword= "first";
const char *my_localhost= "localhost", *delayed_user= "DELAYED";
const char *my_localhost= "localhost",
*delayed_user= "delayed", *slave_user= "<replication_slave>";
bool opt_large_files= sizeof(my_off_t) > 4;
static my_bool opt_autocommit; ///< for --autocommit command-line option

View File

@ -264,7 +264,7 @@ extern time_t server_start_time, flush_status_time;
extern char *opt_mysql_tmpdir, mysql_charsets_dir[];
extern size_t mysql_unpacked_real_data_home_len;
extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list;
extern const char *first_keyword, *delayed_user;
extern const char *first_keyword, *delayed_user, *slave_user;
extern MYSQL_PLUGIN_IMPORT const char *my_localhost;
extern MYSQL_PLUGIN_IMPORT const char **errmesg; /* Error messages */
extern const char *myisam_recover_options_str;

View File

@ -3511,6 +3511,7 @@ static int init_slave_thread(THD* thd, Master_info *mi,
}
thd->security_ctx->skip_grants();
thd->security_ctx->user=(char*) slave_user;
thd->slave_thread= 1;
thd->connection_name= mi->connection_name;
thd->variables.sql_log_slow= !MY_TEST(thd->variables.log_slow_disabled_statements & LOG_SLOW_DISABLE_SLAVE);

View File

@ -7532,7 +7532,7 @@ static bool can_grant_role(THD *thd, ACL_ROLE *role)
{
Security_context *sctx= thd->security_ctx;
if (!sctx->user) // replication
if (!sctx->is_user_defined()) // galera
return true;
ACL_USER *grantee= find_user_exact(sctx->priv_host, sctx->priv_user);

View File

@ -4504,7 +4504,7 @@ void Security_context::destroy()
my_free((char*) host);
host= NULL;
}
if (user != delayed_user)
if (is_user_defined())
{
my_free((char*) user);
user= NULL;

View File

@ -1506,6 +1506,8 @@ public:
*/
bool check_access(const privilege_t want_access, bool match_any = false);
bool is_priv_user(const char *user, const char *host);
bool is_user_defined() const
{ return user && user != delayed_user && user != slave_user; };
};

View File

@ -2776,9 +2776,10 @@ static my_bool list_callback(THD *tmp, list_callback_arg *arg)
thd_info->thread_id=tmp->thread_id;
thd_info->os_thread_id=tmp->os_thread_id;
thd_info->user= arg->thd->strdup(tmp_sctx->user ? tmp_sctx->user :
(tmp->system_thread ?
"system user" : "unauthenticated user"));
thd_info->user= arg->thd->strdup(tmp_sctx->user && tmp_sctx->user != slave_user ?
tmp_sctx->user :
(tmp->system_thread ?
"system user" : "unauthenticated user"));
if (tmp->peer_port && (tmp_sctx->host || tmp_sctx->ip) &&
arg->thd->security_ctx->host_or_ip[0])
{
@ -3225,7 +3226,7 @@ static my_bool processlist_callback(THD *tmp, processlist_callback_arg *arg)
/* ID */
arg->table->field[0]->store((longlong) tmp->thread_id, TRUE);
/* USER */
val= tmp_sctx->user ? tmp_sctx->user :
val= tmp_sctx->user && tmp_sctx->user != slave_user ? tmp_sctx->user :
(tmp->system_thread ? "system user" : "unauthenticated user");
arg->table->field[1]->store(val, strlen(val), cs);
/* HOST */