-
Notifications
You must be signed in to change notification settings - Fork 714
FB8-54, FB8-55, FB8-70, FB8-101: Expose more information to audit plugin #934
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
INSTALL PLUGIN null_audit SONAME 'adt_null.so'; | ||
SET @@null_audit_extended_log = 1; | ||
CREATE TABLE foo (v INT); | ||
DROP TABLE foo; | ||
SHOW STATUS LIKE "Audit_null_generic_event_response"; | ||
Variable_name Value | ||
Audit_null_generic_event_response database:test | ||
CREATE TABLE foo (v INT); | ||
SHOW STATUS LIKE "Audit_null_generic_event_response"; | ||
Variable_name Value | ||
Audit_null_generic_event_response affected_rows:0 | ||
INSERT INTO foo VALUES (1), (2); | ||
SHOW STATUS LIKE "Audit_null_generic_event_response"; | ||
Variable_name Value | ||
Audit_null_generic_event_response affected_rows:2 | ||
SELECT * FROM foo; | ||
v | ||
1 | ||
2 | ||
SHOW STATUS LIKE "Audit_null_generic_event_response"; | ||
Variable_name Value | ||
Audit_null_generic_event_response affected_rows:-1 | ||
DELETE FROM foo; | ||
SHOW STATUS LIKE "Audit_null_generic_event_response"; | ||
Variable_name Value | ||
Audit_null_generic_event_response affected_rows:2 | ||
DROP TABLE foo; | ||
SHOW STATUS LIKE "Audit_null_generic_event_response"; | ||
Variable_name Value | ||
Audit_null_generic_event_response port:MYSQLD_PORT | ||
UNINSTALL PLUGIN null_audit; | ||
Warnings: | ||
Warning 1620 Plugin is busy and will be uninstalled on shutdown | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
INSTALL PLUGIN null_audit SONAME 'adt_null.so'; | ||
CREATE USER cert_auth@localhost REQUIRE X509; | ||
GRANT SELECT ON test.* TO cert_auth@localhost; | ||
CREATE TABLE foo (i INT); | ||
FLUSH PRIVILEGES; | ||
SET @@null_audit_extended_log = 1; | ||
SELECT * FROM foo; | ||
i | ||
SHOW STATUS LIKE "Audit_null_generic_event_response"; | ||
Variable_name Value | ||
Audit_null_generic_event_response connection_certificate:-----BEGIN CERTIFICATE-----\nMIIDyDCCArCgAwIBAgIJAOG0pVw936YVMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNV\nBAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hvbG0xEjAQBgNVBAcMCVN0b2NraG9sbTEP\nMA0GA1UECgwGT3JhY2xlMQ4wDAYDVQQLDAVNeVNRTDELMAkGA1UEAwwCQ0EwHhcN\nMTQxMjA1MDQ0OTIzWhcNMjkxMjAxMDQ0OTIzWjBnMQswCQYDVQQGEwJTRTESMBAG\nA1UECAwJU3RvY2tob2xtMRIwEAYDVQQHDAlTdG9ja2hvbG0xDzANBgNVBAoMBk9y\nYWNsZTEOMAwGA1UECwwFTXlTUUwxDzANBgNVBAMMBkNsaWVudDCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBAMjRof6kjPMbF3EbdDUR4A5sQAr7wPfw67vJ\nHaHH17CK9vHP+mvQeWTru2mlDYAG31IU0oUyz7/OKkcoW80LKKu7BzPVi9O0csSm\ntcw3uQOoeFYlWB8XMHzRCrvsPKMDkJeZkkmus1eWXBrp6AIjrsjJBVBj5XehmnMG\ndA5GUCjYyU/EHDe4UhgLrxkr1OVmdKTz8No | ||
DROP USER cert_auth@localhost; | ||
DROP TABLE foo; | ||
UNINSTALL PLUGIN null_audit; | ||
Warnings: | ||
Warning 1620 Plugin is busy and will be uninstalled on shutdown |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
$AUDIT_NULL_OPT |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
--source include/have_null_audit_plugin.inc | ||
--source include/count_sessions.inc | ||
--source include/have_debug.inc | ||
|
||
eval INSTALL PLUGIN null_audit SONAME '$AUDIT_NULL'; | ||
|
||
SET @@null_audit_extended_log = 1; | ||
|
||
## database name in generic event | ||
CREATE TABLE foo (v INT); | ||
DROP TABLE foo; | ||
|
||
--replace_regex /.*(database:[^;]*).*/\1/ | ||
SHOW STATUS LIKE "Audit_null_generic_event_response"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Try to use something like SET @param_name = 'database:';
SELECT SUBSTRING(REGEX_SUBSTR(variable_value, CONCAT('.*(', @param_name, '[^;]*).*' )), LENGTH(@param_name)) INTO @extracted_param
FROM performance_schema.global_status
WHERE variable_name='Audit_null_generic_event_response'; Then use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if that's better - with this approach, the query is easier to read, and the value is there in the result file. The test also won't stop at the first error, and in the end, it will display all issues, not only the first. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only reason for this complexity is to have everything related to the assertion in one place (in the .test file) and not split between .test and .result. From my experience, .result files are never reviewed properly and developers very often do './mtr --record' without checking if the output is still expected. |
||
|
||
## affected_rows in generic event | ||
CREATE TABLE foo (v INT); | ||
--replace_regex /.*(affected_rows:[^;]*).*/\1/ | ||
SHOW STATUS LIKE "Audit_null_generic_event_response"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Likewise |
||
|
||
INSERT INTO foo VALUES (1), (2); | ||
--replace_regex /.*(affected_rows:[^;]*).*/\1/ | ||
SHOW STATUS LIKE "Audit_null_generic_event_response"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Likewise |
||
|
||
SELECT * FROM foo; | ||
--replace_regex /.*(affected_rows:[^;]*).*/\1/ | ||
SHOW STATUS LIKE "Audit_null_generic_event_response"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Likewise |
||
|
||
DELETE FROM foo; | ||
--replace_regex /.*(affected_rows:[^;]*).*/\1/ | ||
SHOW STATUS LIKE "Audit_null_generic_event_response"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Likewise |
||
|
||
DROP TABLE foo; | ||
|
||
## port | ||
let $MYSQLD_PORT= `SELECT @@port`; | ||
--replace_result $MYSQLD_PORT MYSQLD_PORT | ||
--replace_regex /.*(port:[^;]*).*/\1/ | ||
SHOW STATUS LIKE "Audit_null_generic_event_response"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Likewise |
||
|
||
|
||
UNINSTALL PLUGIN null_audit; | ||
|
||
--source include/wait_until_count_sessions.inc |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--ssl-mode=VERIFY_CA | ||
--ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem | ||
--ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem | ||
--ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
$AUDIT_NULL_OPT |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
--source include/have_ssl.inc | ||
--source include/count_sessions.inc | ||
--source include/have_debug.inc | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add |
||
eval INSTALL PLUGIN null_audit SONAME '$AUDIT_NULL'; | ||
|
||
CREATE USER cert_auth@localhost REQUIRE X509; | ||
GRANT SELECT ON test.* TO cert_auth@localhost; | ||
CREATE TABLE foo (i INT); | ||
FLUSH PRIVILEGES; | ||
connect(con1,localhost,cert_auth,,,,,SSL); | ||
|
||
SET @@null_audit_extended_log = 1; | ||
|
||
SELECT * FROM foo; | ||
|
||
--replace_regex /.*(connection_certificate:[^;]*).*/\1/ | ||
SHOW STATUS LIKE "Audit_null_generic_event_response"; | ||
|
||
disconnect con1; | ||
connection default; | ||
DROP USER cert_auth@localhost; | ||
DROP TABLE foo; | ||
|
||
UNINSTALL PLUGIN null_audit; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still no There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
--source include/wait_until_count_sessions.inc |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,8 @@ | |
#include <mysqld_error.h> | ||
#include <stdio.h> | ||
#include <sys/types.h> | ||
#include <sstream> | ||
#include <boost/algorithm/string/replace.hpp> | ||
|
||
#include "lex_string.h" | ||
#include "m_ctype.h" | ||
|
@@ -130,6 +132,13 @@ static char *g_record_buffer; | |
|
||
#undef AUDIT_NULL_VAR | ||
|
||
#ifndef DBUG_OFF | ||
static const constexpr size_t event_response_buffer_len = 1000; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is 1000 enough now when we have certificates also included in GENERAL STATUS event? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For now yes, as all other fields are short. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should |
||
static char generic_event_response[event_response_buffer_len + 1] = { | ||
0, | ||
}; | ||
#endif | ||
|
||
/* | ||
Plugin status variables for SHOW STATUS | ||
*/ | ||
|
@@ -144,6 +153,11 @@ static SHOW_VAR simple_status[] = { | |
|
||
#undef AUDIT_NULL_VAR | ||
|
||
#ifndef DBUG_OFF | ||
{"Audit_null_generic_event_response", (char *)generic_event_response, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this also be wrapped in |
||
SHOW_CHAR, SHOW_SCOPE_GLOBAL}, | ||
#endif | ||
|
||
{0, 0, SHOW_UNDEF, SHOW_SCOPE_GLOBAL}}; | ||
|
||
/* | ||
|
@@ -175,6 +189,12 @@ static MYSQL_THDVAR_INT(event_order_check_exact, PLUGIN_VAR_RQCMDARG, | |
"Plugin checks exact event order.", NULL, NULL, 1, 0, 1, | ||
0); | ||
|
||
#ifndef DBUG_OFF | ||
static MYSQL_THDVAR_INT(extended_log, PLUGIN_VAR_RQCMDARG, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's better to declare this var as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But doesn't that make thread level control useful? If it's a threadvar, you can turn it on for only one thread, and other threads won't accidentally modify the status variables, breaking tests. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Such change is too visible for user to be discussed only here (unless FB chimes in) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this be debug only since it's mainly used for testing? Are there security issues with non-privileged users getting access to see the last logged query. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And is audit_null used outside MTR testing, in production? This is only present in that plugin, that's why I didn't see it as an issue. I can make it debug only, but that will also make all related tests debug only. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not used in production, but if it's used as a template for other audit plugins, it might run the risk of it getting out. Let's make it debug-only and having the tests be debug-only would be fine. |
||
"Provide extended debug information with audit_null.", | ||
NULL, NULL, 1, 0, 1, 0); | ||
#endif | ||
|
||
static MYSQL_THDVAR_STR(event_record_def, | ||
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC, | ||
"Event recording definition", NULL, NULL, NULL); | ||
|
@@ -411,6 +431,45 @@ static int process_command(MYSQL_THD thd, LEX_CSTRING event_command, | |
return 0; | ||
} | ||
|
||
#ifndef DBUG_OFF | ||
/* | ||
* Exposes a generic audit log event in a status variable | ||
*/ | ||
static void log_event(const mysql_event_general *event) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this function also be wrapped in |
||
#define EVENT_PARAM(name) event_str << #name ":" << event->name << ";"; | ||
#define EVENT_PARAM_STR(name) \ | ||
{ \ | ||
std::string tmp(event->name.str, event->name.length); \ | ||
boost::replace_all(tmp, "\n", "\\n"); \ | ||
event_str << #name ":" << tmp << ";"; \ | ||
} | ||
std::stringstream event_str; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm also seeing an internal error compiling this: ../../../plugin/audit_null/audit_null.cc: In function ‘void log_event(const mysql_event_general*)’: |
||
EVENT_PARAM(event_subclass); | ||
EVENT_PARAM(general_error_code); | ||
// skipping general_thread_id | ||
EVENT_PARAM_STR(general_user); | ||
EVENT_PARAM_STR(general_command); | ||
EVENT_PARAM_STR(general_query); | ||
// EVENT_PARAM_STR(general_charset); | ||
EVENT_PARAM(general_time); | ||
EVENT_PARAM(general_rows); | ||
EVENT_PARAM_STR(general_host); | ||
EVENT_PARAM_STR(general_sql_command); | ||
EVENT_PARAM_STR(general_external_user); | ||
EVENT_PARAM_STR(general_ip); | ||
EVENT_PARAM(query_id); | ||
EVENT_PARAM_STR(database); | ||
EVENT_PARAM(affected_rows); | ||
EVENT_PARAM(port); | ||
EVENT_PARAM_STR(connection_certificate); | ||
#undef EVENT_PARAM | ||
#undef EVENT_PARAM_STR | ||
|
||
const std::string str = event_str.str(); | ||
strncpy(generic_event_response, str.c_str(), event_response_buffer_len); | ||
} | ||
#endif | ||
|
||
/** | ||
@brief Plugin function handler. | ||
|
||
|
@@ -454,9 +513,16 @@ static int audit_null_notify(MYSQL_THD thd, mysql_event_class_t event_class, | |
case MYSQL_AUDIT_GENERAL_RESULT: | ||
number_of_calls_general_result++; | ||
break; | ||
case MYSQL_AUDIT_GENERAL_STATUS: | ||
case MYSQL_AUDIT_GENERAL_STATUS: { | ||
#ifndef DBUG_OFF | ||
const int extended_info = static_cast<int>(THDVAR(thd, extended_log)); | ||
if (extended_info != 0) { | ||
log_event(static_cast<const mysql_event_general *>(event)); | ||
} | ||
#endif | ||
number_of_calls_general_status++; | ||
break; | ||
} | ||
default: | ||
break; | ||
} | ||
|
@@ -767,6 +833,9 @@ static SYS_VAR *system_variables[] = { | |
MYSQL_SYSVAR(event_order_check_consume_ignore_count), | ||
MYSQL_SYSVAR(event_order_started), | ||
MYSQL_SYSVAR(event_order_check_exact), | ||
#ifndef DBUG_OFF | ||
MYSQL_SYSVAR(extended_log), | ||
#endif | ||
|
||
MYSQL_SYSVAR(event_record_def), | ||
MYSQL_SYSVAR(event_record), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure the test works with
--repeat=2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked, it works.