13 Commits

Author SHA1 Message Date
Guy Lichtman
83b85084fb offsets for 5.5.43 and 5.6.24 2015-04-15 12:13:49 +03:00
Guy Lichtman
24f157beb2 new configuration: audit_json_file_bufsize . Controls the buffer size used when logging to a file. Value of 0 means default size, value of 1 means no buffering. 2015-03-09 10:37:31 +02:00
Guy Lichtman
8d28867ee5 Offsets for MariaDB 5.5.42 and 10.0.17 2015-03-09 10:30:28 +02:00
Guy Lichtman
b47ec14636 Modifications to pull request #103 . Changed the name of the record_logins var to: force_record_logins and default value is disabled for backwards compatibility. Also changed the implementation a bit regarding flow and filtering on the empty user. issue #101 2015-02-10 15:06:42 +02:00
Guy Lichtman
1ac2324ab9 offsets for 5.5.42, 5.6.23, mariadb 10.0.16 2015-02-10 00:08:46 +02:00
Guy Lichtman
56462bd9d4 fix for empty "Connect" entries at startup. issue #40 and pr #103 : 2015-02-10 00:04:21 +02:00
Guy Lichtman
00194ab4bb Merge pull request #103 from RickPizzi/master
new option audit_record_logins to enable logging of Connect and Quit cmds
2015-02-09 23:38:29 +02:00
Riccardo Pizzi
de390805f1 added Failed Login auditing 2015-02-07 16:18:05 -05:00
Rick Pizzi
9d66bfbdd3 new option audit_record_logins to enable logging of Connect/Quit regardless the content of variable audit_record_cmds 2015-02-07 15:43:01 -05:00
Guy Lichtman
a1c8250058 New offsets added. Fixing issue #98 and a crash seen on percona when changing default database ("use <db>"). 2015-01-26 18:11:55 +02:00
Guy Lichtman
08899ffc55 offsets for 5.6.22 and 5.5.41 2014-12-28 16:53:43 +02:00
Guy Lichtman
272a1ae190 added special variable named audit_plugin_version_<version>_<revision> where '.' is repalced with '_'. This variable can be used to extract the version of the plugin by using a tool such as nm or objdump. issue #96. 2014-12-20 20:29:36 +02:00
Guy Lichtman
4c1af961c5 MariaDB 10.0.15 offsets 2014-11-30 17:20:15 +02:00
6 changed files with 173 additions and 33 deletions

View File

@@ -116,12 +116,17 @@ fi
if test -z "$MYSQL_AUDIT_PLUGIN_REVISION" ;then
MYSQL_AUDIT_PLUGIN_REVISION=99999
fi
if test -z "$MYSQL_AUDIT_PLUGIN_SYMBOL_VERSION" ;then
MYSQL_AUDIT_PLUGIN_SYMBOL_VERSION=${MYSQL_AUDIT_PLUGIN_VERSION//./_}_$MYSQL_AUDIT_PLUGIN_REVISION
fi
AC_SUBST(MYSQL_AUDIT_PLUGIN_VERSION)
AC_SUBST(MYSQL_AUDIT_PLUGIN_REVISION)
echo "Version: $MYSQL_AUDIT_PLUGIN_VERSION-$MYSQL_AUDIT_PLUGIN_REVISION"
echo "Version: $MYSQL_AUDIT_PLUGIN_VERSION-$MYSQL_AUDIT_PLUGIN_REVISION Symbol version: $MYSQL_AUDIT_PLUGIN_SYMBOL_VERSION"
CPPFLAGS="$CPPFLAGS -DMYSQL_AUDIT_PLUGIN_VERSION='\"$MYSQL_AUDIT_PLUGIN_VERSION\"'"
CPPFLAGS="$CPPFLAGS -DMYSQL_AUDIT_PLUGIN_REVISION='\"$MYSQL_AUDIT_PLUGIN_REVISION\"'"
CPPFLAGS="$CPPFLAGS '-DMYSQL_AUDIT_PLUGIN_SYMBOL_VERSION()=extern const char audit_plugin_version_$MYSQL_AUDIT_PLUGIN_SYMBOL_VERSION'"
#subst the relevant variables

View File

@@ -49,7 +49,7 @@ typedef size_t OFFSET;
#define MAX_NUM_USER_ELEM 256
/**
* The struct usd to hold offsets. We should have one per version.
* The struct used to hold offsets. We should have one per version.
*/
typedef struct ThdOffsets
{
@@ -64,7 +64,9 @@ typedef struct ThdOffsets
OFFSET sec_ctx_user;
OFFSET sec_ctx_host;
OFFSET sec_ctx_ip;
OFFSET sec_ctx_priv_user;
OFFSET sec_ctx_priv_user;
OFFSET db;
OFFSET killed;
} ThdOffsets;
/*
@@ -184,6 +186,26 @@ public:
+ Audit_formatter::thd_offsets.main_security_ctx);
}
static inline const char * thd_db(THD * thd)
{
if(!Audit_formatter::thd_offsets.db) //no offsets use compiled in header
{
return thd->db;
}
return *(const char **) (((unsigned char *) thd)
+ Audit_formatter::thd_offsets.db);
}
static inline int thd_killed(THD * thd)
{
if(!Audit_formatter::thd_offsets.killed) //no offsets use thd_killed function
{
return ::thd_killed(thd);
}
return *(int *) (((unsigned char *) thd)
+ Audit_formatter::thd_offsets.killed);
}
static inline const char * thd_inst_main_security_ctx_user(THD * thd)
{
Security_context * sctx = thd_inst_main_security_ctx(thd);
@@ -532,7 +554,7 @@ class Audit_file_handler: public Audit_io_handler
public:
Audit_file_handler() :
m_sync_period(0), m_log_file(NULL), m_sync_counter(0)
m_sync_period(0), m_log_file(NULL), m_sync_counter(0), m_bufsize(0)
{
m_io_type = "file";
}
@@ -549,6 +571,11 @@ public:
*/
unsigned int m_sync_period;
/**
* The buf size used by the file stream. 0 = use default, negative or 1 = no buffering
*/
long m_bufsize;
/**
* Write function we pass to formatter
*/

View File

@@ -31,7 +31,7 @@ if [ $? = 0 ]; then
fi
echo "set logging on" > offsets.gdb
echo 'printf "{\"'$MYVER'\",\"'$MYMD5'\", %d, %d, %d, %d, %d, %d, %d, %d, %d, %d}", ((size_t)&((THD *)log_slow_statement)->query_id) - (size_t)log_slow_statement, ((size_t)&((THD *)log_slow_statement)->thread_id) - (size_t)log_slow_statement, ((size_t)&((THD *)log_slow_statement)->main_security_ctx) - (size_t)log_slow_statement, ((size_t)&((THD *)log_slow_statement)->'$COMMAND_MEMBER') - (size_t)log_slow_statement, ((size_t)&((THD *)log_slow_statement)->lex) - (size_t)log_slow_statement, (size_t)&((LEX*)log_slow_statement)->comment - (size_t) log_slow_statement, ((size_t)&((Security_context *)log_slow_statement)->user) - (size_t)log_slow_statement, ((size_t)&((Security_context *)log_slow_statement)->host) - (size_t)log_slow_statement, ((size_t)&((Security_context *)log_slow_statement)->ip) - (size_t)log_slow_statement, ((size_t)&((Security_context *)log_slow_statement)->priv_user) - (size_t)log_slow_statement' >> offsets.gdb
echo 'printf "{\"'$MYVER'\",\"'$MYMD5'\", %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d}", ((size_t)&((THD *)log_slow_statement)->query_id) - (size_t)log_slow_statement, ((size_t)&((THD *)log_slow_statement)->thread_id) - (size_t)log_slow_statement, ((size_t)&((THD *)log_slow_statement)->main_security_ctx) - (size_t)log_slow_statement, ((size_t)&((THD *)log_slow_statement)->'$COMMAND_MEMBER') - (size_t)log_slow_statement, ((size_t)&((THD *)log_slow_statement)->lex) - (size_t)log_slow_statement, (size_t)&((LEX*)log_slow_statement)->comment - (size_t) log_slow_statement, ((size_t)&((Security_context *)log_slow_statement)->user) - (size_t)log_slow_statement, ((size_t)&((Security_context *)log_slow_statement)->host) - (size_t)log_slow_statement, ((size_t)&((Security_context *)log_slow_statement)->ip) - (size_t)log_slow_statement, ((size_t)&((Security_context *)log_slow_statement)->priv_user) - (size_t)log_slow_statement, ((size_t)&((THD *)log_slow_statement)->db) - (size_t)log_slow_statement, ((size_t)&((THD *)log_slow_statement)->killed) - (size_t)log_slow_statement' >> offsets.gdb
SYMPARAM=""
if [ -n "$2" ]; then

View File

@@ -21,6 +21,7 @@
#include "audit_handler.h"
//for definition of sockaddr_un
#include <sys/un.h>
#include <stdio_ext.h>
#include "static_assert.h"
//utility macro to log also with a date as a prefix
@@ -198,7 +199,7 @@ int Audit_file_handler::open(const char * io_dest, bool log_errors)
{
char format_name[FN_REFLEN];
fn_format(format_name, io_dest, "", "", MY_UNPACK_FILENAME);
m_log_file = my_fopen(format_name, O_RDWR | O_APPEND, MYF(0));
m_log_file = my_fopen(format_name, O_WRONLY | O_APPEND| O_CREAT, MYF(0));
if (!m_log_file)
{
if(log_errors)
@@ -209,6 +210,31 @@ int Audit_file_handler::open(const char * io_dest, bool log_errors)
}
return -1;
}
ssize_t bufsize = BUFSIZ;
int res =0;
//0 -> use default, 1 or negative -> disabled
if(m_bufsize > 1)
{
bufsize = m_bufsize;
}
if(1 == m_bufsize || m_bufsize < 0)
{
//disabled
res = setvbuf(m_log_file, NULL, _IONBF, 0);
}
else
{
res = setvbuf(m_log_file, NULL, _IOFBF, bufsize);
}
if(res)
{
sql_print_error(
"%s unable to set bufzie [%zd (%ld)] for file %s: %s.",
AUDIT_LOG_PREFIX, bufsize, m_bufsize, m_io_dest, strerror(errno));
}
sql_print_information("%s bufsize for file [%s]: %zd. Value of json_file_bufsize: %ld.", AUDIT_LOG_PREFIX, m_io_dest,
__fbufsize(m_log_file), m_bufsize);
return 0;
}
@@ -691,7 +717,7 @@ bool ThdSesData::getNextObject(const char ** db_name, const char ** obj_name, co
{
if(m_firstTable)
{
*db_name = getTHD()->db;
*db_name = Audit_formatter::thd_db(getTHD());
*obj_name = NULL;
if(obj_type)
{

View File

@@ -21,6 +21,18 @@
//64 bit offsets
const ThdOffsets thd_offsets_arr[] =
{
//offsets for: /mysqlrpm/5.5.43/usr/sbin/mysqld (5.5.43)
{"5.5.43","d9bc90e06a5f97a4e6524bee2cd2ba62", 6136, 6184, 3816, 4312, 88, 2592, 96, 0, 32, 104, 120, 6256},
//offsets for: /mysqlrpm/5.6.24/usr/sbin/mysqld (5.6.24)
{"5.6.24","fa139b24fa0074925a76592a3beba284", 6976, 7024, 4000, 4520, 72, 2704, 96, 0, 32, 104, 136, 7112},
//offsets for: /mysqlrpm/5.5.42/usr/sbin/mysqld (5.5.42)
{"5.5.42","2b3289c6a80d166b0343677c31a99676", 6136, 6184, 3816, 4312, 88, 2592, 96, 0, 32, 104, 120, 6256},
//offsets for: /mysqlrpm/5.6.23/usr/sbin/mysqld (5.6.23)
{"5.6.23","088aac6f0be2f01ea83b101c5c327599", 7928, 7976, 3992, 4512, 72, 2704, 96, 0, 32, 104, 136, 8064},
//offsets for: /mysqlrpm/5.5.41/usr/sbin/mysqld (5.5.41)
{"5.5.41","66afe25ebb34b6099dda39f73f5fe615", 6136, 6184, 3816, 4312, 88, 2592, 96, 0, 32, 104},
//offsets for: /mysqlrpm/5.6.22/usr/sbin/mysqld (5.6.22)
{"5.6.22","6810010c49b77534274fe7ff9943575e", 7928, 7976, 3992, 4512, 72, 2704, 96, 0, 32, 104},
//offsets for: /mysqlrpm/5.5.40/usr/sbin/mysqld (5.5.40)
{"5.5.40","0ef1c3b1e694a2b780113f4641cb3c67", 6136, 6184, 3816, 4312, 88, 2592, 96, 0, 32, 104},
//offsets for: /mysqlrpm/5.6.21/usr/sbin/mysqld (5.6.21)
@@ -391,6 +403,18 @@ const ThdOffsets thd_offsets_arr[] =
//32 bit offsets
const ThdOffsets thd_offsets_arr[] =
{
//offsets for: /mysqlrpm/5.5.43/usr/sbin/mysqld (5.5.43)
{"5.5.43","5bb9944b00a46765a12e6a3a261e10fa", 3868, 3896, 2368, 2748, 44, 1656, 60, 0, 20, 64, 60, 3952},
//offsets for: /mysqlrpm/5.6.24/usr/sbin/mysqld (5.6.24)
{"5.6.24","55aab9806d2b88fe1fe0ab66dd2017eb", 4668, 4696, 2660, 3052, 36, 1748, 60, 0, 20, 64, 72, 4768},
//offsets for: /mysqlrpm/5.5.42/usr/sbin/mysqld (5.5.42)
{"5.5.42","e0e62892aeb511bcfe92fcd95bf90fcb", 3868, 3896, 2368, 2748, 44, 1656, 60, 0, 20, 64, 60, 3952},
//offsets for: /mysqlrpm/5.6.23/usr/sbin/mysqld (5.6.23)
{"5.6.23","727e1bd34328073ec9cdfd2d564fd5ce", 5652, 5680, 2656, 3048, 36, 1748, 60, 0, 20, 64, 72, 5752},
//offsets for: /mysqlrpm/5.5.41/usr/sbin/mysqld (5.5.41)
{"5.5.41","b234951450a025962337644f8895420a", 3868, 3896, 2368, 2748, 44, 1656, 60, 0, 20, 64},
//offsets for: /mysqlrpm/5.6.22/usr/sbin/mysqld (5.6.22)
{"5.6.22","5835e81c4b1e6b26dc91ab7734791a63", 5652, 5680, 2656, 3048, 36, 1748, 60, 0, 20, 64},
//offsets for: /mysqlrpm/5.5.40/usr/sbin/mysqld (5.5.40)
{"5.5.40","a1549dfa57facd1bc63ba130d359c206", 3868, 3896, 2368, 2748, 44, 1656, 60, 0, 20, 64},
//offsets for: /mysqlrpm/5.6.21/usr/sbin/mysqld (5.6.21)
@@ -741,6 +765,16 @@ const ThdOffsets thd_offsets_arr[] =
//64 bit offsets
const ThdOffsets thd_offsets_arr[] =
{
//offsets for: /mariadb/10.0.17/bin/mysqld (10.0.17-MariaDB)
{"10.0.17-MariaDB","080d431c04b2d0c7dff5ca5c5f760b18", 14368, 14432, 6192, 7792, 88, 3000, 8, 0, 16, 24, 152, 14524},
//offsets for: /mariadb/5.5.42/bin/mysqld (5.5.42-MariaDB)
{"5.5.42-MariaDB","04b7fbb6804ca8961fa8b4308a66a7c8", 12016, 12080, 5800, 6896, 88, 2944, 8, 0, 16, 24, 152, 12152},
//offsets for: /mariadb/10.0.16/bin/mysqld (10.0.16-MariaDB)
{"10.0.16-MariaDB","c8cc8c9c5e1a1fb33bb2555d27b076a8", 14368, 14432, 6192, 7792, 88, 3000, 8, 0, 16, 24, 152, 14524},
//offsets for: /mariadb/5.5.41/bin/mysqld (5.5.41-MariaDB)
{"5.5.41-MariaDB","2073691580d80e2760a7e9d89aa93736", 12016, 12080, 5800, 6896, 88, 2936, 8, 0, 16, 24},
//offsets for: /mariadb/10.0.15/bin/mysqld (10.0.15-MariaDB)
{"10.0.15-MariaDB","a7d7f8d53605449629f565baeeb15ef1", 14368, 14432, 6192, 7792, 88, 2992, 8, 0, 16, 24},
//offsets for: bin/mysqld (10.0.14-MariaDB)
{"10.0.14-MariaDB","715a7512a2d5e9cf8722f033ac39abc2", 14368, 14432, 6192, 7792, 88, 2992, 8, 0, 16, 24},
//offsets for: /mariadb/10.0.10/bin/mysqld (10.0.10-MariaDB)
@@ -785,6 +819,16 @@ const ThdOffsets thd_offsets_arr[] =
//32 bit offsets
const ThdOffsets thd_offsets_arr[] =
{
//offsets for: /mariadb/10.0.17/bin/mysqld (10.0.17-MariaDB)
{"10.0.17-MariaDB","d23ec9269df72a12bbe5b5255f40ed17", 9316, 9352, 3680, 5136, 44, 1904, 4, 0, 8, 12, 84, 9424},
//offsets for: /mariadb/5.5.42/bin/mysqld (5.5.42-MariaDB)
{"5.5.42-MariaDB","6306b4ed556f3d22517e9a82a7478f7c", 7272, 7308, 3460, 4464, 44, 1868, 4, 0, 8, 12, 84, 7368},
//offsets for: /mariadb/10.0.16/bin/mysqld (10.0.16-MariaDB)
{"10.0.16-MariaDB","04ad0bec5198a8598e79f2b18492bdcb", 9316, 9352, 3680, 5136, 44, 1904, 4, 0, 8, 12, 84, 9424},
//offsets for: /mariadb/5.5.41/bin/mysqld (5.5.41-MariaDB)
{"5.5.41-MariaDB","51da3a9aedfde2f4e320c607b1992f74", 7272, 7308, 3460, 4464, 44, 1860, 4, 0, 8, 12},
//offsets for: /mariadb/10.0.15/bin/mysqld (10.0.15-MariaDB)
{"10.0.15-MariaDB","3b9b7cb72c530207c82929016db7e266", 9316, 9352, 3680, 5136, 44, 1896, 4, 0, 8, 12},
//offsets for: /mariadb/10.0.14/bin/mysqld (10.0.14-MariaDB)
{"10.0.14-MariaDB","311ee785ffab56e289cee28b6ffddcd4", 9316, 9352, 3680, 5136, 44, 1896, 4, 0, 8, 12},
//offsets for: /mariadb/10.0.10/bin/mysqld (10.0.10-MariaDB)

View File

@@ -44,6 +44,7 @@ static Audit_json_formatter json_formatter;
//flags to hold if audit handlers are enabled
static my_bool json_file_handler_enable = FALSE;
static my_bool force_record_logins_enable = FALSE;
static my_bool json_file_handler_flush = FALSE;
static my_bool json_socket_handler_enable = FALSE;
static my_bool uninstall_plugin_enable = FALSE;
@@ -220,16 +221,7 @@ static void audit(ThdSesData *pThdData)
return;
}
}
if (num_record_cmds > 0) {
const char * cmd = pThdData->getCmdName();
const char *cmds[2];
cmds[0] = cmd;
cmds[1] = NULL;
if (!check_array(cmds, (char *) record_cmds_array, MAX_COMMAND_CHAR_NUMBERS)) {
return;
}
}
if (num_whitelist_users > 0) {
if (num_whitelist_users > 0) {
const char * user = pThdData->getUserName(); //If name is present, then no need to log the query
const char *users[2];
if(NULL == user || '\0' == user[0]) //empty user use special symbol: "{}"
@@ -241,8 +233,24 @@ static void audit(ThdSesData *pThdData)
if (check_array(users, (char *) whitelist_users_array, MAX_USER_CHAR_NUMBERS)) {
return;
}
}
bool do_objs_cmds_check = true;
if (force_record_logins_enable) {
const char * cmd = pThdData->getCmdName();
if (!strcasecmp(cmd, "Connect") || !strcasecmp(cmd, "Quit") || !strcasecmp(cmd, "Failed Login")) {
do_objs_cmds_check = false;
}
}
if (num_record_objs > 0) {
if (num_record_cmds > 0 && do_objs_cmds_check) {
const char * cmd = pThdData->getCmdName();
const char *cmds[2];
cmds[0] = cmd;
cmds[1] = NULL;
if (!check_array(cmds, (char *) record_cmds_array, MAX_COMMAND_CHAR_NUMBERS)) {
return;
}
}
if (num_record_objs > 0 && do_objs_cmds_check) {
bool matched = false;
if(pThdData->startGetObjects())
{
@@ -371,26 +379,32 @@ static bool audit_open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint
Prelocking_strategy *prelocking_strategy)
{
bool res;
res = trampoline_open_tables (thd, start, counter, flags, prelocking_strategy);
ThdSesData thd_data (thd);
audit(&thd_data);
return res;
bool res;
res = trampoline_open_tables (thd, start, counter, flags, prelocking_strategy);
//only log if thread id or query id is non 0 (otherwise this is comming from startup activity)
if(Audit_formatter::thd_inst_thread_id(thd) || Audit_formatter::thd_inst_query_id(thd))
{
ThdSesData thd_data (thd);
audit(&thd_data);
}
return res;
}
static unsigned int trampoline_open_tables_size =0;
#else
static int audit_open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
{
bool res;
res = trampoline_open_tables (thd, start, counter, flags);
ThdSesData thd_data (thd);
audit(&thd_data);
return res;
bool res;
res = trampoline_open_tables (thd, start, counter, flags);
//only log if thread id or query id is non 0 (otherwise this is comming from startup activity)
if(Audit_formatter::thd_inst_thread_id(thd) || Audit_formatter::thd_inst_query_id(thd))
{
ThdSesData thd_data (thd);
audit(&thd_data);
}
return res;
}
static unsigned int trampoline_open_tables_size =0;
#endif
static unsigned int trampoline_open_tables_size =0;
//called by log_slow_statement and general audit event caught by audit interface
@@ -587,7 +601,11 @@ static int audit_mysql_execute_command(THD *thd)
audit(&thd_data);
}
int res;
if(thd_killed(thd))
#if defined(MARIADB_BASE_VERSION)
if(Audit_formatter::thd_killed(thd) >= KILL_CONNECTION)
#else
if(Audit_formatter::thd_killed(thd) == THD::KILL_CONNECTION)
#endif
{
res = 1;
}
@@ -1565,10 +1583,18 @@ static MYSQL_SYSVAR_BOOL(header_msg, json_formatter.m_write_start_msg,
PLUGIN_VAR_RQCMDARG,
"AUDIT write header message at start of logging or file flush Enable|Disable. Default enabled.", NULL, NULL, 1);
static MYSQL_SYSVAR_BOOL(force_record_logins, force_record_logins_enable,
PLUGIN_VAR_RQCMDARG,
"AUDIT force record Connect, Quit and Failed Login commands, regardless of the settings in audit_record_cmds and audit_record_objs Enable|Disable. Default disabled.", NULL, NULL, 0);
static MYSQL_SYSVAR_STR(json_log_file, json_file_handler.m_io_dest,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
"AUDIT plugin json log file name",
NULL, NULL, "mysql-audit.json");
static MYSQL_SYSVAR_LONG(json_file_bufsize, json_file_handler.m_bufsize,
PLUGIN_VAR_RQCMDARG,
"AUDIT plugin json log file buffer size. Buffer size in bytes (lager size may improve performance). 0 = use default size, 1 = no buffering. If changed during runtime need to perform a flush for the new value to take affect.",
NULL, NULL, 0, 1, 262144, 0);
static MYSQL_SYSVAR_UINT(json_file_sync, json_file_handler.m_sync_period,
PLUGIN_VAR_RQCMDARG,
@@ -1689,7 +1715,9 @@ static MYSQL_SYSVAR_STR(record_objs, record_objs_string,
static struct st_mysql_sys_var* audit_system_variables[] =
{
MYSQL_SYSVAR(header_msg),
MYSQL_SYSVAR(force_record_logins),
MYSQL_SYSVAR(json_log_file),
MYSQL_SYSVAR(json_file_bufsize),
MYSQL_SYSVAR(json_file_sync),
MYSQL_SYSVAR(json_file_retry),
MYSQL_SYSVAR(json_socket_retry),
@@ -1797,3 +1825,13 @@ extern "C" int __cxa_pure_virtual (void)
log_prefix);
return 0;
}
/*
* Variable to hold version
*/
MYSQL_AUDIT_PLUGIN_SYMBOL_VERSION() = '\0';