29 Commits

Author SHA1 Message Date
Arnold Robbins
051b1fd67e Add MariaDB 10.1.12 offsets. 2016-03-10 13:57:44 +02:00
Arnold Robbins
4e4387cebd Add offsets for MariaDB 10.0.24 and MariaDB 5.5.48. 2016-02-25 12:34:12 +02:00
Arnold Robbins
d9129cc112 Add support for MySQL 5.7.{9,10,11}.
Add support for MariaDB 10.1.{10,11}.
Fix segfault for set var to null (issue 133).
If password masking regex doesn't compile, revert to default regex.
2016-02-07 15:59:41 +02:00
Arnold Robbins
685b20e20c Offsets for MariaDB 10.0.22 and 10.0.23. 2015-12-28 10:21:25 +02:00
Arnold Robbins
94b7274600 Offsets for MySQL 5.5.47, 5.6.28, MariaDB 5.5.47. 2015-12-13 14:17:46 +02:00
Guy Lichtman
051daf06a4 offsets for MySQL 5.5.46/5.6.27 and MariadDB 5.5.46 2015-10-12 14:03:54 +03:00
Guy Lichtman
15c77835bf mariadb offsets 10.0.21 and 5.5.45. Offset validation following experience with issue: #118. 2015-08-11 13:47:51 +03:00
Guy Lichtman
ee115750e5 Remove inlines for better investigation of issue #118 2015-08-02 16:38:04 +03:00
Guy Lichtman
a46b02b834 offsets 5.5.45 and 5.6.26 2015-07-29 15:19:34 +03:00
Guy Lichtman
ef67fba5e6 issue #118. Possible fix for the issue. 2015-07-29 15:16:07 +03:00
Guy Lichtman
c6d57e7205 documentation fixes. see issue #115 2015-07-12 17:58:36 +03:00
Guy Lichtman
b29ebeac51 Offsets for MariaDB 10.0.20 2015-07-12 17:58:07 +03:00
Guy Lichtman
a5bf3035e5 offsets for MariaDB 5.5.44 2015-06-16 12:35:51 +03:00
Guy Lichtman
734882dfaa offsets for 5.6.25 and 5.5.44 2015-06-07 17:21:06 +03:00
Guy Lichtman
3ac3682926 mariadb offsets for: 10.0.19 2015-05-17 13:25:48 +03:00
Guy Lichtman
7fcd565e9d mariadb offsets for 5.5.43 2015-05-06 14:10:56 +03:00
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
9 changed files with 734 additions and 162 deletions

View File

@@ -35,16 +35,21 @@ This will create configure script. Then run:
CXX='gcc -static-libgcc' CC='gcc -static-libgcc' ./configure --with-mysql=mysql-5.1.40
==== MySQL 5.5 / 5.6 ======
==== MySQL 5.5 / 5.6 / 5.7 ======
Extract MySQL 5.5 or 5.6 source code
Extract MySQL 5.5, 5.6, or 5.7 source code
go to mysql-src dir and run:
cd mysql-5.5.x or mysql-5.6.x
cd mysql-5.5.x or mysql-5.6.x or mysql-5.7.x
cmake .
make
Note: MySQL 5.7 requires Boost 1.59. You may have to install that
first (see www.boost.org). In such a case, use:
cmake -DWITH_BOOST=/path/to/boost_1_59_0 .
Note: For MariaDB use: cmake . -DBUILD_CONFIG=mysql_release
Note: to speed things up it is possible to build just the following directories:

View File

@@ -27,8 +27,13 @@ AC_DEFUN([MYSQL_SRC_TEST], [
AC_MSG_ERROR([Failed to find required header file $file in $withval, check the path and make sure you've run './configure ..<options>.. && cd include && make' in MySQL 5.1 sources dir or 'cmake . && make' in MySQL 5.5 sources dir.])
fi
done
dnl binary_log_types.h included by mysql_com.h included by mysql_inc.h -
dnl is found in libbinlogevents/export.
dnl
dnl table_id.h included from table.h included by mysql_inc.h is
dnl in libbinlogevents/include.
AC_DEFINE([MYSQL_SRC], [1], [Source directory for MySQL])
MYSQL_INC="-I$withval/sql -I$withval/include -I$withval/regex -I$withval"
MYSQL_INC="-I$withval/sql -I$withval/libbinlogevents/export -I$withval/libbinlogevents/include -I$withval/include -I$withval/regex -I$withval"
AC_MSG_RESULT(["$withval"])
],
[

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

@@ -20,6 +20,18 @@
#define AUDIT_LOG_PREFIX "Audit Plugin:"
#define AUDIT_PROTOCOL_VERSION "1.0"
#if !defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 50709
// For locking we use the native lock routines provided by MySQL.
// The data types and functions for native locking changed at 5.7.x.
// Try to hide this with macros.
#define rw_lock_t native_rw_lock_t
#define rw_rdlock native_rw_rdlock
#define rw_wrlock native_rw_wrlock
#define rw_unlock native_rw_unlock
#define rwlock_destroy native_rw_destroy
#define my_rwlock_init(lock, unused) native_rw_init(lock)
#endif
class THD;
#define MAX_NUM_QUERY_TABLE_ELEM 100
@@ -49,7 +61,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 +76,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,12 +198,40 @@ 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
{
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
return thd->db;
#else
return thd->db().str;
#endif
}
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);
if(!Audit_formatter::thd_offsets.sec_ctx_user) //no offsets use compiled in header
{
return sctx->user;
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
return sctx->user;
#else
return sctx->user().str;
#endif
}
return *(const char **) (((unsigned char *) sctx)
+ Audit_formatter::thd_offsets.sec_ctx_user);
@@ -202,11 +244,20 @@ public:
{
//interface changed in 5.5.34 and 5.6.14 and up host changed to get_host()
//see: http://bazaar.launchpad.net/~mysql/mysql-server/5.5/revision/4407.1.1/sql/sql_class.h
#if !defined(MARIADB_BASE_VERSION) && ( ( MYSQL_VERSION_ID >= 50534 && MYSQL_VERSION_ID < 50600) || (MYSQL_VERSION_ID >= 50614) )
return sctx->get_host()->ptr();
#else
#if defined(MARIADB_BASE_VERSION)
return sctx->host;
#else
// MySQL
#if MYSQL_VERSION_ID < 50534 || (MYSQL_VERSION_ID >= 50600 && MYSQL_VERSION_ID < 50614)
return sctx->host;
#elif (MYSQL_VERSION_ID >= 50534 && MYSQL_VERSION_ID < 50600) \
|| (MYSQL_VERSION_ID >= 50614 && MYSQL_VERSION_ID < 50709)
return sctx->get_host()->ptr();
#else
// interface changed again in 5.7
return sctx->host().str;
#endif
#endif // ! defined(MARIADB_BASE_VERSION)
}
return *(const char **) (((unsigned char *) sctx)
+ Audit_formatter::thd_offsets.sec_ctx_host);
@@ -218,11 +269,20 @@ public:
if(!Audit_formatter::thd_offsets.sec_ctx_ip) //no offsets use compiled in header
{
//interface changed in 5.5.34 and 5.6.14 and up host changed to get_ip()
#if !defined(MARIADB_BASE_VERSION) && ( (MYSQL_VERSION_ID >= 50534 && MYSQL_VERSION_ID < 50600) || (MYSQL_VERSION_ID >= 50614) )
#if defined(MARIADB_BASE_VERSION)
return sctx->ip;
#else
// MySQL
#if MYSQL_VERSION_ID < 50534 || (MYSQL_VERSION_ID >= 50600 && MYSQL_VERSION_ID < 50614)
return sctx->ip;
#elif (MYSQL_VERSION_ID >= 50534 && MYSQL_VERSION_ID < 50600) \
|| (MYSQL_VERSION_ID >= 50614 && MYSQL_VERSION_ID < 50709)
return sctx->get_ip()->ptr();
#else
return sctx->ip;
#endif
// interface changed again in 5.7
return sctx->ip().str;
#endif
#endif // ! defined(MARIADB_BASE_VERSION)
}
return *(const char **) (((unsigned char *) sctx)
+ Audit_formatter::thd_offsets.sec_ctx_ip);
@@ -233,7 +293,11 @@ public:
Security_context * sctx = thd_inst_main_security_ctx(thd);
if(!Audit_formatter::thd_offsets.sec_ctx_priv_user) //no offsets use compiled in header
{
return sctx->priv_user;
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
return sctx->priv_user;
#else
return sctx->priv_user().str;
#endif
}
#if MYSQL_VERSION_ID < 50505
//in 5.1.x priv_user is a pointer
@@ -532,7 +596,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 +613,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

@@ -14,17 +14,27 @@
#include <my_config.h>
#include <mysql_version.h>
#if MYSQL_VERSION_ID < 50505
#include <mysql_priv.h>
#else
//version 5.5.x doesn't contain mysql_priv.h . We need to add the includes provided by it.
#if MYSQL_VERSION_ID >= 50505
// These two are not present in 5.7.9
#if MYSQL_VERSION_ID < 50709
#include <my_pthread.h>
#include <sql_priv.h>
#endif
#include <mysql/plugin.h>
#if MYSQL_VERSION_ID >= 50600
//in 5.6 we use the audit plugin interface
// From 5.6 we use the audit plugin interface
#include <mysql/plugin_audit.h>
#endif
#include <sql_parse.h>
#include <sql_class.h>
#include <my_global.h>
@@ -41,9 +51,14 @@
#define pthread_mutex_destroy mysql_mutex_destroy
#define pthread_mutex_t mysql_mutex_t
*/
#endif /* ! if MYSQL_VERSION_ID >= 50505 */
#endif /* ! if MYSQL_VERSION_ID < 50505 */
#else
#include <mysql_priv.h>
#if MYSQL_VERSION_ID >= 50709
#include <sql/log.h>
#if ! defined(MARIADB_BASE_VERSION)
#include <sql/auth/auth_common.h>
#endif
#endif
#include <violite.h>

View File

@@ -23,15 +23,33 @@ if [ $? = 0 ]; then
fi
COMMAND_MEMBER=command
THREAD_ID=thread_id
SEC_CONTEXT=main_security_ctx
USER=user
HOST=host
IP=ip
PRIV_USER=priv_user
DB=db
#in 5.6 command member is named m_command
echo $MYVER | grep -P '^(5\.6|10\.)' > /dev/null
echo $MYVER | grep -P '^(5\.6|5\.7|10\.)' > /dev/null
if [ $? = 0 ]; then
COMMAND_MEMBER=m_command
fi
#in 5.7 thread_id changed to m_thread_id. main_security_ctx changed to m_main_security_ctx
echo $MYVER | grep -P '^(5\.7)' > /dev/null
if [ $? = 0 ]; then
THREAD_ID=m_thread_id
SEC_CONTEXT=m_main_security_ctx
USER=m_user
HOST=m_host
IP=m_ip
PRIV_USER=m_priv_user
DB=m_db
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)->'$SEC_CONTEXT') - (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
@@ -47,7 +48,9 @@ ThdOffsets Audit_formatter::thd_offsets = { 0 };
Audit_handler * Audit_handler::m_audit_handler_list[Audit_handler::MAX_AUDIT_HANDLERS_NUM];
const char * Audit_json_formatter::DEF_MSG_DELIMITER = "\\n";
#if MYSQL_VERSION_ID < 50709
#define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
#endif
const char * Audit_formatter::retrieve_object_type (TABLE_LIST *pObj)
@@ -198,7 +201,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 +212,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;
}
@@ -379,12 +407,12 @@ bool Audit_socket_handler::handler_log_audit(ThdSesData *pThdData)
static inline yajl_gen_status yajl_add_string(yajl_gen hand, const char * str)
static yajl_gen_status yajl_add_string(yajl_gen hand, const char * str)
{
return yajl_gen_string(hand, (const unsigned char*)str, strlen(str));
}
static inline void yajl_add_string_val(yajl_gen hand, const char * name, const char* val)
static void yajl_add_string_val(yajl_gen hand, const char * name, const char* val)
{
if(0 == val)
{
@@ -394,22 +422,25 @@ static inline void yajl_add_string_val(yajl_gen hand, const char * name, const c
yajl_add_string(hand, val);
}
static inline void yajl_add_string_val(yajl_gen hand, const char * name, const char* val, size_t val_len)
static void yajl_add_string_val(yajl_gen hand, const char * name, const char* val, size_t val_len)
{
yajl_add_string(hand, name);
yajl_gen_string(hand, (const unsigned char*)val, val_len);
}
static inline void yajl_add_uint64(yajl_gen gen, const char * name, uint64 num)
static void yajl_add_uint64(yajl_gen gen, const char * name, uint64 num)
{
const size_t max_int64_str_len = 21;
char buf[max_int64_str_len];
snprintf(buf, max_int64_str_len, "%llu", num);
yajl_add_string_val(gen, name, buf);
}
static inline void yajl_add_obj( yajl_gen gen, const char *db,const char* ptype,const char * name =NULL)
static void yajl_add_obj( yajl_gen gen, const char *db,const char* ptype,const char * name =NULL)
{
yajl_add_string_val(gen, "db", db);
if(db)
{
yajl_add_string_val(gen, "db", db);
}
if (name)
{
yajl_add_string_val(gen, "name", name);
@@ -417,7 +448,7 @@ static inline void yajl_add_obj( yajl_gen gen, const char *db,const char* ptype
yajl_add_string_val(gen, "obj_type",ptype);
}
static inline const char * retrieve_user (THD * thd)
static const char * retrieve_user (THD * thd)
{
const char * user = Audit_formatter::thd_inst_main_security_ctx_user(thd);
@@ -436,7 +467,25 @@ static inline const char * retrieve_user (THD * thd)
//will return a pointer to the query and set len with the length of the query
//starting with MySQL version 5.1.41 thd_query_string is added
#if MYSQL_VERSION_ID > 50140
//And at 5.7 it changed
#if ! defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 50709
extern "C" LEX_CSTRING thd_query_unsafe(MYSQL_THD thd);
static const char * thd_query_str(THD * thd, size_t * len)
{
const LEX_CSTRING str = thd_query_unsafe(thd);
if(str.length > 0)
{
*len = str.length;
return str.str;
}
*len = 0;
return NULL;
}
#elif defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID > 50140
extern "C" {
MYSQL_LEX_STRING *thd_query_string(MYSQL_THD thd);
}
@@ -519,6 +568,40 @@ ssize_t Audit_json_formatter::start_msg_format(IWriter * writer)
}
// This routine replaces clear text with the string in `replace', leaving the rest of the string intact.
//
// thd - MySQL thread, used for allocating memory
// str - pointer to start of original string
// str_len - length thereof
// cleartext_start - start of cleartext to replace
// cleartext_len - length of cleartext
// replace - \0 terminated string with replacement text
static const char *replace_in_string(THD *thd,
const char *str, size_t str_len,
size_t cleartext_start, size_t cleartext_len,
const char *replace)
{
size_t to_alloc = str_len + strlen(replace) + 1;
char *new_str = (char *) thd_alloc(thd, to_alloc);
memset(new_str, '\0', to_alloc);
// point to text after clear text
const char *trailing = str + cleartext_start + cleartext_len;
// how much text after clear text to copy in
size_t final_to_move = ((str + str_len) - trailing);
char *pos = new_str;
memcpy(pos, str, cleartext_start); // copy front of string
pos += cleartext_start;
memcpy(pos, replace, strlen(replace)); // copy replacement text
pos += strlen(replace);
memcpy(pos, trailing, final_to_move); // copy trailing part of string
return new_str;
}
ssize_t Audit_json_formatter::event_format(ThdSesData* pThdData, IWriter * writer)
{
THD * thd = pThdData->getTHD();
@@ -569,16 +652,35 @@ ssize_t Audit_json_formatter::event_format(ThdSesData* pThdData, IWriter * write
const CHARSET_INFO *col_connection;
#endif
col_connection = Item::default_charset();
String sQuery (query,qlen,col_connection) ;
if (strcmp (col_connection->csname,"utf8")!=0) {
pThdData->getTHD()->convert_string (&sQuery,col_connection,&my_charset_utf8_general_ci);
// See comment below as to why we don't use String class directly, or call
// pThdData->getTHD()->convert_string (&sQuery,col_connection,&my_charset_utf8_general_ci);
const char *query_text = query;
size_t query_len = qlen;
if (strcmp(col_connection->csname, "utf8") != 0) {
// max UTF-8 bytes per char is 4.
size_t to_amount = (qlen * 4) + 1;
char* to = (char *) thd_alloc(thd, to_amount);
uint errors = 0;
size_t len = copy_and_convert(to, to_amount,
&my_charset_utf8_general_ci,
query, qlen,
col_connection, & errors);
to[len] = '\0';
query = to;
qlen = len;
}
if(m_perform_password_masking && m_password_mask_regex_compiled && m_password_mask_regex_preg && m_perform_password_masking(cmd))
{
//do password masking
int matches[90] = {0};
if(pcre_exec(m_password_mask_regex_preg, NULL, sQuery.ptr(), sQuery.length(), 0, 0, matches, array_elements(matches)) >= 0)
if(pcre_exec(m_password_mask_regex_preg, NULL, query_text, query_len, 0, 0, matches, array_elements(matches)) >= 0)
{
//search for the first substring that matches with the name psw
char *first = NULL, *last = NULL;
@@ -590,17 +692,24 @@ ssize_t Audit_json_formatter::event_format(ThdSesData* pThdData, IWriter * write
//first 2 bytes give us the number
int n = (((int)(entry)[0]) << 8) | (entry)[1];
if (n > 0 && n < (int)array_elements(matches) && matches[n*2] >= 0)
{ //we have a match
sQuery.copy(); //make sure string is alloced before doing replace
const char * pass_replace = "***";
sQuery.replace(matches[n*2], matches[(n*2) + 1] - matches[n*2], pass_replace, strlen(pass_replace));
{
// We have a match.
// Starting with MySQL 5.7, we cannot use the String::replace() function.
// Doing so causes a crash in the string's destructor. It appears that the
// interfaces in MySQL have changed fairly drastically. So we just do the
// replacement ourselves.
const char *pass_replace = "***";
const char *updated = replace_in_string(thd, query_text, query_len, matches[n*2], matches[(n*2) + 1] - matches[n*2], pass_replace);
query_text = updated;
query_len = strlen(query_text);
break;
}
}
}
}
}
yajl_add_string_val(gen, "query", sQuery.ptr(), sQuery.length());
yajl_add_string_val(gen, "query", query_text, query_len);
}
else
{
@@ -662,9 +771,11 @@ bool ThdSesData::startGetObjects()
}
const char *cmd = getCmdName();
//commands which have single database object
if (strcmp (cmd,"Init DB") ==0 || strcmp (cmd, "SHOW TABLES")== 0 || strcmp (cmd, "SHOW TABLE")==0)
if (strcmp (cmd,"Init DB") ==0
|| strcmp (cmd, "SHOW TABLES")== 0
|| strcmp (cmd, "SHOW TABLE")==0)
{
if(getTHD()->db)
if(Audit_formatter::thd_db(getTHD()))
{
m_objIterType = OBJ_DB;
return true;
@@ -691,7 +802,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,45 @@
//64 bit offsets
const ThdOffsets thd_offsets_arr[] =
{
/* +++ MYSQL 64 OFFSETS GO HERE +++ */
//offsets for: /mysqlrpm/5.5.48/usr/sbin/mysqld (5.5.48)
{"5.5.48","69b209f0c08027a501b1cb7a20e6e582", 6144, 6192, 3816, 4312, 88, 2592, 96, 0, 32, 104, 120, 6264},
//offsets for: /mysqlrpm/5.6.29/usr/sbin/mysqld (5.6.29)
{"5.6.29","badcd2b5b459d5fd6e4fb6a4bd3a1f91", 6992, 7040, 4000, 4520, 72, 2704, 96, 0, 32, 104, 136, 7128},
//offsets for: /mysqlrpm/5.7.11/usr/sbin/mysqld (5.7.11)
{"5.7.11","68ebf5245b47e43235466a2820cf5d46", 7792, 7840, 3616, 4768, 456, 360, 0, 32, 64, 160, 536, 7956},
//offsets for: /mysqlrpm/5.7.10/usr/sbin/mysqld (5.7.10)
{"5.7.10","8e9c0636d9263cea97498dd99e7841b6", 7784, 7832, 3608, 4760, 456, 360, 0, 32, 64, 160, 536, 7948},
//offsets for: /mysqlrpm/5.7.9/usr/sbin/mysqld (5.7.9)
{"5.7.9","1cb6f2ea6f98c2788d51a196afa153d9", 7784, 7832, 3608, 4760, 456, 360, 0, 32, 64, 160, 536, 7948},
//offsets for: /mysqlrpm/5.5.47/usr/sbin/mysqld (5.5.47)
{"5.5.47","a35964c285630302290dc1ad31bddd93", 6144, 6192, 3816, 4312, 88, 2592, 96, 0, 32, 104, 120, 6264},
//offsets for: /mysqlrpm/5.6.28/usr/sbin/mysqld (5.6.28)
{"5.6.28","a88464e4d2cb6d11311179166613c015", 6992, 7040, 4000, 4520, 72, 2704, 96, 0, 32, 104, 136, 7128},
//offsets for: /mysqlrpm/5.6.27/usr/sbin/mysqld (5.6.27)
{"5.6.27","212c7e3701046857fa6d7f1404f427d9", 6992, 7040, 4000, 4520, 72, 2704, 96, 0, 32, 104, 136, 7128},
//offsets for: /mysqlrpm/5.5.46/usr/sbin/mysqld (5.5.46)
{"5.5.46","f2e3131d0aedf9275073225efb4a83c4", 6144, 6192, 3816, 4312, 88, 2592, 96, 0, 32, 104, 120, 6264},
//offsets for: /mysqlrpm/5.5.45/usr/sbin/mysqld (5.5.45)
{"5.5.45","fc867721baf46f7b6158ad3ded16aa5e", 6144, 6192, 3816, 4312, 88, 2592, 96, 0, 32, 104, 120, 6264},
//offsets for: /mysqlrpm/5.6.26/usr/sbin/mysqld (5.6.26)
{"5.6.26","560ab8bd2c6513eac8283af1630e604a", 6992, 7040, 4000, 4520, 72, 2704, 96, 0, 32, 104, 136, 7128},
//offsets for: /mysqlrpm/5.5.44/usr/sbin/mysqld (5.5.44)
{"5.5.44","1291a4a24d7a87415660237d691e821f", 6144, 6192, 3816, 4312, 88, 2592, 96, 0, 32, 104, 120, 6264},
//offsets for: /mysqlrpm/5.6.25/usr/sbin/mysqld (5.6.25)
{"5.6.25","2e38dabed666cd8521f28e855a43b7ca", 6984, 7032, 4000, 4520, 72, 2704, 96, 0, 32, 104, 136, 7120},
//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 +430,45 @@ const ThdOffsets thd_offsets_arr[] =
//32 bit offsets
const ThdOffsets thd_offsets_arr[] =
{
/* +++ MYSQL 32 OFFSETS GO HERE +++ */
//offsets for: /mysqlrpm/5.5.48/usr/sbin/mysqld (5.5.48)
{"5.5.48","731f6399029830b0b9ffa151541ed474", 3872, 3900, 2368, 2748, 44, 1656, 60, 0, 20, 64, 60, 3956},
//offsets for: /mysqlrpm/5.6.29/usr/sbin/mysqld (5.6.29)
{"5.6.29","c1e32ee3937f2ad5fc9df94d1e0aa649", 4676, 4704, 2660, 3052, 36, 1748, 60, 0, 20, 64, 72, 4776},
//offsets for: /mysqlrpm/5.7.11/usr/sbin/mysqld (5.7.11)
{"5.7.11","014a96aac6006bf942dd2047aad0ccd1", 5064, 5092, 2200, 3020, 296, 200, 0, 20, 40, 100, 340, 5180},
//offsets for: /mysqlrpm/5.7.10/usr/sbin/mysqld (5.7.10)
{"5.7.10","e6389a154b82cfaac4a89f1b2a995365", 5060, 5088, 2196, 3016, 296, 200, 0, 20, 40, 100, 340, 5172},
//offsets for: /mysqlrpm/5.7.9/usr/sbin/mysqld (5.7.9)
{"5.7.9","95a6843300e1fef377d298210a4e2525", 5060, 5088, 2196, 3016, 296, 200, 0, 20, 40, 100, 340, 5172},
//offsets for: /mysqlrpm/5.5.47/usr/sbin/mysqld (5.5.47)
{"5.5.47","669f76493658cd2758af28a1c391391a", 3872, 3900, 2368, 2748, 44, 1656, 60, 0, 20, 64, 60, 3956},
//offsets for: /mysqlrpm/5.6.28/usr/sbin/mysqld (5.6.28)
{"5.6.28","b108d8002c70f9e6bf57b6c47f1b4a74", 4676, 4704, 2660, 3052, 36, 1748, 60, 0, 20, 64, 72, 4776},
//offsets for: /mysqlrpm/5.6.27/usr/sbin/mysqld (5.6.27)
{"5.6.27","66d0b372d6eb134730c43bdb1c2ac4e5", 4672, 4700, 2660, 3052, 36, 1748, 60, 0, 20, 64, 72, 4772},
//offsets for: /mysqlrpm/5.5.46/usr/sbin/mysqld (5.5.46)
{"5.5.46","ad19ca91985eaafe185c0a3f4e51fd9a", 3872, 3900, 2368, 2748, 44, 1656, 60, 0, 20, 64, 60, 3956},
//offsets for: /mysqlrpm/5.5.45/usr/sbin/mysqld (5.5.45)
{"5.5.45","c91cfb5d8b250a40d626d4fe1bc89fdd", 3872, 3900, 2368, 2748, 44, 1656, 60, 0, 20, 64, 60, 3956},
//offsets for: /mysqlrpm/5.6.26/usr/sbin/mysqld (5.6.26)
{"5.6.26","1cb4e5089554ae6b92569955980b95aa", 4672, 4700, 2660, 3052, 36, 1748, 60, 0, 20, 64, 72, 4772},
//offsets for: /mysqlrpm/5.5.44/usr/sbin/mysqld (5.5.44)
{"5.5.44","e69b8c103a28a09dbe6aedd1b3b433f8", 3872, 3900, 2368, 2748, 44, 1656, 60, 0, 20, 64, 60, 3956},
//offsets for: /mysqlrpm/5.6.25/usr/sbin/mysqld (5.6.25)
{"5.6.25","2e90f40fd72446f7c68e662ab4b51ee9", 4672, 4700, 2660, 3052, 36, 1748, 60, 0, 20, 64, 72, 4772},
//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)
@@ -740,7 +818,54 @@ const ThdOffsets thd_offsets_arr[] =
#ifdef __x86_64__
//64 bit offsets
const ThdOffsets thd_offsets_arr[] =
{
{
/* +++ MARIADB 64 OFFSETS GO HERE +++ */
//offsets for: /mariadb/10.1.12/bin/mysqld (10.1.12-MariaDB)
{"10.1.12-MariaDB","e2ba726e2e6f56976518581da0a2c443", 13592, 13656, 6368, 7976, 88, 2976, 8, 0, 16, 24, 152, 13748},
//offsets for: /mariadb/10.0.24/bin/mysqld (10.0.24-MariaDB)
{"10.0.24-MariaDB","f757c1ee447cf82766b7b6d776beadc0", 13432, 13496, 6208, 7816, 88, 2976, 8, 0, 16, 24, 152, 13588},
//offsets for: /mariadb/5.5.48/bin/mysqld (5.5.48-MariaDB)
{"5.5.48-MariaDB","fe4ddddc2591703dfdb5f66075ee4751", 12032, 12096, 5800, 6904, 88, 2920, 8, 0, 16, 24, 152, 12168},
//offsets for: /mariadb/10.1.11/bin/mysqld (10.1.11-MariaDB)
{"10.1.11-MariaDB","91dc9f2e78433f0efc975174263a4206", 13592, 13656, 6368, 7976, 88, 2976, 8, 0, 16, 24, 152, 13748},
//offsets for: /mariadb/10.1.10/bin/mysqld (10.1.10-MariaDB)
{"10.1.10-MariaDB","d6dd898de1ac04fc742bf525f8ce37bf", 13576, 13640, 6352, 7960, 88, 2960, 8, 0, 16, 24, 152, 13732},
//offsets for: /mariadb/10.0.23/bin/mysqld (10.0.23-MariaDB)
{"10.0.23-MariaDB","1cc0611b29e35a3a64eba2ff9bc3663c", 13416, 13480, 6192, 7800, 88, 2976, 8, 0, 16, 24, 152, 13572},
//offsets for: /mariadb/10.0.22/bin/mysqld (10.0.22-MariaDB)
{"10.0.22-MariaDB","271759a346ed0b973c1b3570eb6e70bc", 13416, 13480, 6192, 7800, 88, 2976, 8, 0, 16, 24, 152, 13572},
//offsets for: /mariadb/5.5.47/bin/mysqld (5.5.47-MariaDB)
{"5.5.47-MariaDB","642990798709d79dcdc662104805b44b", 12032, 12096, 5800, 6904, 88, 2920, 8, 0, 16, 24, 152, 12168},
//offsets for: /mariadb/10.1.9/bin/mysqld (10.1.9-MariaDB)
{"10.1.9-MariaDB","f6a488fd8331d6201c0598fb6ff3fa9e", 13576, 13640, 6352, 7960, 88, 2960, 8, 0, 16, 24, 152, 13732},
//offsets for: /mariadb/10.1.8/bin/mysqld (10.1.8-MariaDB)
{"10.1.8-MariaDB","cf103655e354afa2bf43cc4899b65101", 13576, 13640, 6352, 7960, 88, 2960, 8, 0, 16, 24, 152, 13732},
//offsets for: /mariadb/5.5.46/bin/mysqld (5.5.46-MariaDB)
{"5.5.46-MariaDB","ec8c941f31086bed6cf9c7e97ed61c0a", 12032, 12096, 5800, 6904, 88, 2920, 8, 0, 16, 24, 152, 12168},
//offsets for: /mariadb/10.0.21/bin/mysqld (10.0.21-MariaDB)
{"10.0.21-MariaDB","e565b3971cc11516822e676465d5b4a9", 13416, 13480, 6192, 7800, 88, 2976, 8, 0, 16, 24, 152, 13572},
//offsets for: /mariadb/5.5.45/bin/mysqld (5.5.45-MariaDB)
{"5.5.45-MariaDB","70faaed59f9d41cfea9510dbdaa8cb0d", 12032, 12096, 5800, 6904, 88, 2920, 8, 0, 16, 24, 152, 12168},
//offsets for: /mariadb/10.0.20/bin/mysqld (10.0.20-MariaDB)
{"10.0.20-MariaDB","1fd5e15156937feb7f4c5fd1164dd029", 13408, 13472, 6192, 7792, 88, 3000, 8, 0, 16, 24, 152, 13564},
//offsets for: /mariadb/5.5.44/bin/mysqld (5.5.44-MariaDB)
{"5.5.44-MariaDB","d4a60362e7a50edca299cfd7d4b6f6b8", 12016, 12080, 5800, 6896, 88, 2944, 8, 0, 16, 24, 152, 12152},
//offsets for: /mariadb/10.0.19/bin/mysqld (10.0.19-MariaDB)
{"10.0.19-MariaDB","c0e7e8c4396c7e59a2cbbecdd3c6435e", 13408, 13472, 6192, 7792, 88, 3000, 8, 0, 16, 24, 152, 13564},
//offsets for: /mariadb/10.0.18/bin/mysqld (10.0.18-MariaDB)
{"10.0.18-MariaDB","94ad1b6c2323272ec77ce4aca37ef4e3", 13408, 13472, 6192, 7792, 88, 3000, 8, 0, 16, 24, 152, 13564},
//offsets for: /mariadb/5.5.43/bin/mysqld (5.5.43-MariaDB)
{"5.5.43-MariaDB","eedfc38ad498ea35e3c6ab4a47ad769e", 12016, 12080, 5800, 6896, 88, 2944, 8, 0, 16, 24, 152, 12152},
//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 +910,53 @@ const ThdOffsets thd_offsets_arr[] =
//32 bit offsets
const ThdOffsets thd_offsets_arr[] =
{
/* +++ MARIADB 32 OFFSETS GO HERE +++ */
//offsets for: /mariadb/10.1.12/bin/mysqld (10.1.12-MariaDB)
{"10.1.12-MariaDB","590bb2be8fb17c7b3599539d4a69ab44", 8472, 8508, 3816, 5276, 44, 1892, 4, 0, 8, 12, 84, 8584},
//offsets for: /mariadb/10.0.24/bin/mysqld (10.0.24-MariaDB)
{"10.0.24-MariaDB","2571649d8352ee31a77a2a7a500ed54a", 8344, 8380, 3688, 5148, 44, 1892, 4, 0, 8, 12, 84, 8452},
//offsets for: /mariadb/5.5.48/bin/mysqld (5.5.48-MariaDB)
{"5.5.48-MariaDB","09caa6790e00e0da77f78159ae5c2558", 7276, 7312, 3460, 4468, 44, 1856, 4, 0, 8, 12, 84, 7372},
//offsets for: /mariadb/10.1.11/bin/mysqld (10.1.11-MariaDB)
{"10.1.11-MariaDB","bc5982b6028c0ef5d50ff7f8465bc6e5", 8472, 8508, 3816, 5276, 44, 1892, 4, 0, 8, 12, 84, 8584},
//offsets for: /mariadb/10.1.10/bin/mysqld (10.1.10-MariaDB)
{"10.1.10-MariaDB","102b27c47031aecdf8ffaf881c841e28", 8464, 8500, 3808, 5268, 44, 1884, 4, 0, 8, 12, 84, 8576},
//offsets for: /mariadb/10.0.23/bin/mysqld (10.0.23-MariaDB)
{"10.0.23-MariaDB","487c1be817fcf314df0edc3f688fdc80", 8336, 8372, 3680, 5140, 44, 1892, 4, 0, 8, 12, 84, 8444},
//offsets for: /mariadb/10.0.22/bin/mysqld (10.0.22-MariaDB)
{"10.0.22-MariaDB","6fce26b567ab09fc3fe2008a9d8e16b9", 8332, 8368, 3680, 5140, 44, 1892, 4, 0, 8, 12, 84, 8440},
//offsets for: /mariadb/5.5.47/bin/mysqld (5.5.47-MariaDB)
{"5.5.47-MariaDB","5d7d4f995a41dc09e3a557e0a5529b11", 7276, 7312, 3460, 4468, 44, 1856, 4, 0, 8, 12, 84, 7372},
//offsets for: /mariadb/10.1.9/bin/mysqld (10.1.9-MariaDB)
{"10.1.9-MariaDB","3f2078219f1098a89a7b12978b33a7e3", 8460, 8496, 3808, 5268, 44, 1884, 4, 0, 8, 12, 84, 8572},
//offsets for: /mariadb/10.1.8/bin/mysqld (10.1.8-MariaDB)
{"10.1.8-MariaDB","aba39e89c42a58d6ed73f9fd96c75b42", 8460, 8496, 3808, 5268, 44, 1884, 4, 0, 8, 12, 84, 8572},
//offsets for: /mariadb/5.5.46/bin/mysqld (5.5.46-MariaDB)
{"5.5.46-MariaDB","df034940564625d2ad168799d47190d1", 7276, 7312, 3460, 4468, 44, 1856, 4, 0, 8, 12, 84, 7372},
//offsets for: /mariadb/10.0.21/bin/mysqld (10.0.21-MariaDB)
{"10.0.21-MariaDB","3b330c8fef5e540fea0060d8778e1e20", 8332, 8368, 3680, 5140, 44, 1892, 4, 0, 8, 12, 84, 8440},
//offsets for: /mariadb/5.5.45/bin/mysqld (5.5.45-MariaDB)
{"5.5.45-MariaDB","c1b8f68c1012af3fba72fe72066992e0", 7276, 7312, 3460, 4468, 44, 1856, 4, 0, 8, 12, 84, 7372},
//offsets for: /mariadb/10.0.20/bin/mysqld (10.0.20-MariaDB)
{"10.0.20-MariaDB","707e0ad28b6b6ab79dee1b7e0ce9e7e8", 8328, 8364, 3680, 5136, 44, 1904, 4, 0, 8, 12, 84, 8436},
//offsets for: /mariadb/5.5.44/bin/mysqld (5.5.44-MariaDB)
{"5.5.44-MariaDB","c1e0214abf6271d97c01c95a905a5527", 7272, 7308, 3460, 4464, 44, 1868, 4, 0, 8, 12, 84, 7368},
//offsets for: /mariadb/10.0.19/bin/mysqld (10.0.19-MariaDB)
{"10.0.19-MariaDB","c8f349901e9957f505ae00d300f8c9a4", 8328, 8364, 3680, 5136, 44, 1904, 4, 0, 8, 12, 84, 8436},
//offsets for: /mariadb/10.0.18/bin/mysqld (10.0.18-MariaDB)
{"10.0.18-MariaDB","a1f007a1656689db27b711feb47653a2", 8328, 8364, 3680, 5136, 44, 1904, 4, 0, 8, 12, 84, 8436},
//offsets for: /mariadb/5.5.43/bin/mysqld (5.5.43-MariaDB)
{"5.5.43-MariaDB","711b99e3b6d5a71934b1eda2c4039d76", 7272, 7308, 3460, 4464, 44, 1868, 4, 0, 8, 12, 84, 7368},
//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;
@@ -86,6 +87,23 @@ static char password_masking_regex_check_buff[4096] = {0};
static char * password_masking_regex_string = NULL;
static char password_masking_regex_buff[4096] = {0};
#define _COMMENT_SPACE_ "(?:/\\*.*?\\*/|\\s)*?"
#define _QUOTED_PSW_ "[\'|\"](?<psw>.*?)(?<!\\\\)[\'|\"]"
static const char default_pw_masking_regex[] =
//identified by [password] '***'
"identified"_COMMENT_SPACE_"by"_COMMENT_SPACE_"(?:password)?"_COMMENT_SPACE_ _QUOTED_PSW_
//password function
"|password"_COMMENT_SPACE_"\\("_COMMENT_SPACE_ _QUOTED_PSW_ _COMMENT_SPACE_"\\)"
//Used at: CHANGE MASTER TO MASTER_PASSWORD='new3cret', SET PASSWORD [FOR user] = 'hash', password 'user_pass';
"|password"_COMMENT_SPACE_"(?:for"_COMMENT_SPACE_"\\S+?)?"_COMMENT_SPACE_"="_COMMENT_SPACE_ _QUOTED_PSW_
"|password"_COMMENT_SPACE_ _QUOTED_PSW_
//federated engine create table with connection. See: http://dev.mysql.com/doc/refman/5.5/en/federated-create-connection.html
//commented out as federated engine is disabled by default
//"|ENGINE"_COMMENT_SPACE_"="_COMMENT_SPACE_"FEDERATED"_COMMENT_SPACE_".*CONNECTION"_COMMENT_SPACE_"="_COMMENT_SPACE_"[\'|\"]\\S+?://\\S+?:(?<psw>.*)@\\S+[\'|\"]"
;
//socket name
static char json_socket_name_buff[1024] = {0};
@@ -196,18 +214,6 @@ static my_bool check_do_password_masking(const char * cmd)
return false;
}
//utility compiles the regex. if fails zero outs password_masking_regex_string
static void password_masking_regex_compile()
{
int res = json_formatter.compile_password_masking_regex(password_masking_regex_string);
if(res)
{ password_masking_regex_buff[0] = '\0';
password_masking_regex_string = password_masking_regex_buff;
}
sql_print_information("%s Compile password_masking_regex res: [%d]", log_prefix, res);
}
static void audit(ThdSesData *pThdData)
{
THDPRINTED *pThdPrintedList = GetThdPrintedList (pThdData->getTHD());
@@ -220,16 +226,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 +238,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())
{
@@ -294,9 +307,16 @@ static void audit(ThdSesData *pThdData)
}
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
static int (*trampoline_send_result_to_client)(Query_cache *pthis, THD *thd, char *sql, uint query_length) = NULL;
#else
static int (*trampoline_send_result_to_client)(Query_cache *pthis, THD *thd, const LEX_CSTRING& sql_query) = NULL;
#endif
#if MYSQL_VERSION_ID > 50505
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100108
static bool (*trampoline_open_tables)(THD *thd, const DDL_options_st &options, TABLE_LIST **start, uint *counter, uint flags,
Prelocking_strategy *prelocking_strategy) = NULL;
#elif MYSQL_VERSION_ID > 50505
static bool (*trampoline_open_tables)(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
Prelocking_strategy *prelocking_strategy) = NULL;
#else
@@ -344,7 +364,11 @@ static bool audit_check_table_access(THD *thd, ulong want_access,TABLE_LIST *tab
static unsigned int trampoline_check_table_access_size = 0;
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
static int audit_send_result_to_client(Query_cache *pthis, THD *thd, char *sql, uint query_length)
#else
static int audit_send_result_to_client(Query_cache *pthis, THD *thd, const LEX_CSTRING& sql_query)
#endif
{
int res;
void *pList = thd_alloc (thd, sizeof (QueryTableInf));
@@ -355,7 +379,11 @@ static int audit_send_result_to_client(Query_cache *pthis, THD *thd, char *sql,
memset (pList,0,sizeof (QueryTableInf));
THDVAR(thd, query_cache_table_list) =(ulong)pList;
}
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
res = trampoline_send_result_to_client (pthis,thd, sql, query_length);
#else
res = trampoline_send_result_to_client (pthis, thd, sql_query);
#endif
if (res)
{
ThdSesData thd_data (thd);
@@ -366,31 +394,37 @@ static int audit_send_result_to_client(Query_cache *pthis, THD *thd, char *sql,
}
static unsigned int trampoline_send_result_to_client_size =0;
#if MYSQL_VERSION_ID > 50505
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100108
static bool audit_open_tables(THD *thd, const DDL_options_st &options, TABLE_LIST **start, uint *counter, uint flags,
Prelocking_strategy *prelocking_strategy)
{
bool res;
res = trampoline_open_tables (thd, options, start, counter, flags, prelocking_strategy);
#elif MYSQL_VERSION_ID > 50505
static bool audit_open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
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;
}
static unsigned int trampoline_open_tables_size =0;
bool res;
res = trampoline_open_tables (thd, start, counter, flags, prelocking_strategy);
#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;
int res;
res = trampoline_open_tables (thd, start, counter, flags);
#endif
//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
//called by log_slow_statement and general audit event caught by audit interface
@@ -423,8 +457,13 @@ static struct st_mysql_daemon audit_plugin =
#else
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
static void audit_notify(THD *thd, unsigned int event_class,
const void * event)
#else
static int audit_notify(THD *thd, mysql_event_class_t event_class,
const void * event)
#endif
{
if (MYSQL_AUDIT_GENERAL_CLASS == event_class)
{
@@ -446,6 +485,9 @@ static void audit_notify(THD *thd, unsigned int event_class,
audit (&ThdData);
}
}
#if ! defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 50709
return 0; // Zero means success, MySQL continues processing the event.
#endif
}
static int plugin_type = MYSQL_AUDIT_PLUGIN;
@@ -454,8 +496,25 @@ static struct st_mysql_audit audit_plugin=
MYSQL_AUDIT_INTERFACE_VERSION, /* interface version */
NULL, /* release_thd function */
audit_notify, /* notify function */
#if ! defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 50709
// As of 5.7.9, this is an array of bitmaps of events that we're interested in.
{ (unsigned long) MYSQL_AUDIT_GENERAL_ALL,
(unsigned long) MYSQL_AUDIT_CONNECTION_ALL,
0,
0,
0,
0,
0,
0,
(unsigned long) MYSQL_AUDIT_COMMAND_ALL,
0,
0
}
#else
{ (unsigned long) MYSQL_AUDIT_GENERAL_CLASSMASK |
MYSQL_AUDIT_CONNECTION_CLASSMASK } /* class mask */
#endif
};
#endif
@@ -492,20 +551,24 @@ void remove_hot_functions ()
trampoline_acl_authenticate_size=0;
#endif
#if MYSQL_VERSION_ID > 50505
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100108
target_function = (void *)*(bool (*)(THD *thd, const DDL_options_st &options, TABLE_LIST **start, uint *counter, uint flags,
Prelocking_strategy *prelocking_strategy)) &open_tables;
#elif MYSQL_VERSION_ID > 50505
target_function = (void *)*(bool (*)(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
Prelocking_strategy *prelocking_strategy)) &open_tables;
remove_hot_patch_function(target_function,
(void*) trampoline_open_tables, trampoline_open_tables_size, true);
trampoline_open_tables_size=0;
#else
target_function = (void *)*(int (*)(THD *thd, TABLE_LIST **start, uint *counter, uint flags)) &open_tables;
#endif
remove_hot_patch_function(target_function,
(void*) trampoline_open_tables, trampoline_open_tables_size, true);
trampoline_open_tables_size=0;
#endif
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
int (Query_cache::*pf_send_result_to_client)(THD *,char *, uint) = &Query_cache::send_result_to_client;
#else
int (Query_cache::*pf_send_result_to_client)(THD *,const LEX_CSTRING&) = &Query_cache::send_result_to_client;
#endif
target_function = *(void **) &pf_send_result_to_client;
remove_hot_patch_function(target_function,
(void*) trampoline_send_result_to_client, trampoline_send_result_to_client_size, true);
@@ -515,7 +578,14 @@ void remove_hot_functions ()
(void*) trampoline_check_table_access,
trampoline_check_table_access_size, true);
trampoline_check_table_access_size=0;
remove_hot_patch_function((void*)mysql_execute_command,
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
target_function = (void*) mysql_execute_command;
#else
target_function = (void*)
(int (*)(THD *thd, bool first_level)) &mysql_execute_command;
#endif
remove_hot_patch_function(target_function,
(void*) trampoline_mysql_execute_command,
trampoline_mysql_execute_size, true);
trampoline_mysql_execute_size=0;
@@ -587,7 +657,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;
}
@@ -597,7 +671,11 @@ static int audit_mysql_execute_command(THD *thd)
{
case 1:
//hot patch function were removed and we call the real execute (restored)
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
res = mysql_execute_command(thd);
#else
res = mysql_execute_command(thd, false);
#endif
break;
case 2:
//denied uninstall plugin
@@ -658,7 +736,7 @@ static bool parse_thd_offsets_string (char *poffsets_string)
char offset_str [2048] = {0};
char *poffset_str = offset_str;
strncpy (poffset_str,poffsets_string,2048);
strncpy (poffset_str,poffsets_string,array_elements(offset_str));
char * comma_delimiter = strchr (poffset_str,',');
size_t i =0;
OFFSET *pOffset;
@@ -669,34 +747,44 @@ static bool parse_thd_offsets_string (char *poffsets_string)
if (!((poffset_str[j] >= '0' && poffset_str[j] <='9') || poffset_str[j] == ' ' || poffset_str[j] == ','))
return false;
}
while (comma_delimiter !=NULL)
while (poffset_str !=NULL)
{
*comma_delimiter = '\0';
comma_delimiter = strchr (poffset_str,',');
if(comma_delimiter)
{
*comma_delimiter = '\0';
}
pOffset = (OFFSET*)&Audit_formatter::thd_offsets.query_id + i;
if ((size_t)pOffset- (size_t)&Audit_formatter::thd_offsets < sizeof (Audit_formatter::thd_offsets))
{
sscanf (poffset_str, "%zu", pOffset);
if(sscanf (poffset_str, "%zu", pOffset) != 1)
{
sql_print_error("%s Failed parsing audit_offsets: scanf failed for offset string: \"%s\" (possible missing offset)", log_prefix, poffset_str);
return false;
}
}
else
{
sql_print_error("%s Failed parsing audit_offsets: too many offsets specified", log_prefix);
return false;
}
i++;
poffset_str = comma_delimiter + 1;
comma_delimiter = strchr (poffset_str,',');
}
if (poffset_str !=NULL)
{
pOffset = &Audit_formatter::thd_offsets.query_id + i;
if ((size_t)pOffset- (size_t)&Audit_formatter::thd_offsets < sizeof (Audit_formatter::thd_offsets))
{
sscanf (poffset_str, "%zu", pOffset);
}
else
{
return false;
}
}
if(comma_delimiter)
{
poffset_str = comma_delimiter + 1;
}
else
{
poffset_str = NULL;
}
}
//validate that we got all offsets. If there is still space in thd_offsets then we didn't get all offsets
pOffset = (OFFSET*)&Audit_formatter::thd_offsets.query_id + i;
if ((size_t)pOffset- (size_t)&Audit_formatter::thd_offsets < sizeof (Audit_formatter::thd_offsets))
{
sql_print_error("%s Failed parsing audit_offsets: not all offsets specified. This may happen if you used an old version of offset-extract.sh script.", log_prefix);
return false;
}
return true;
}
@@ -715,7 +803,8 @@ static bool validate_offsets(const ThdOffsets * offset)
{
sql_print_error(
"%s Offsets: %s (%s) match thread validation check fails with value: %lu. Skipping offest.",
log_prefix, offset->version, offset->md5digest, res);
log_prefix, offset->version, offset->md5digest,
(unsigned long) res);
return false;
}
//extended validation via security_context method
@@ -728,7 +817,11 @@ static bool validate_offsets(const ThdOffsets * offset)
char user_test_val[] = "aud_tusr";
if(!offset->sec_ctx_user) //use compiled header
{
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
sctx->user = user_test_val;
#else
sctx->set_user_ptr(user_test_val, strlen(user_test_val));
#endif
}
else
{
@@ -853,7 +946,7 @@ static int setup_offsets()
}
if (parse_thd_offsets_string (offsets_string))
{
sql_print_information ("%s setup_offsets Audit_formatter::thd_offsets values: %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu", log_prefix,
sql_print_information ("%s setup_offsets Audit_formatter::thd_offsets values: %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu %zu", log_prefix,
Audit_formatter::thd_offsets.query_id,
Audit_formatter::thd_offsets.thread_id,
Audit_formatter::thd_offsets.main_security_ctx,
@@ -863,7 +956,9 @@ static int setup_offsets()
Audit_formatter::thd_offsets.sec_ctx_user,
Audit_formatter::thd_offsets.sec_ctx_host,
Audit_formatter::thd_offsets.sec_ctx_ip,
Audit_formatter::thd_offsets.sec_ctx_priv_user);
Audit_formatter::thd_offsets.sec_ctx_priv_user,
Audit_formatter::thd_offsets.db,
Audit_formatter::thd_offsets.killed);
if (!validate_offsets(&Audit_formatter::thd_offsets))
{
@@ -1011,9 +1106,13 @@ const char * retrieve_command (THD * thd, bool & is_sql_cmd)
return "select";
}
const int sql_command = thd_sql_command(thd);
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100108
if (command == COM_QUERY && sql_command >= 0 && sql_command < SQLCOM_END)
#else
if (sql_command >=0 && sql_command < MAX_COM_STATUS_VARS_RECORDS )
#endif
{
is_sql_cmd = true;
is_sql_cmd = true;
cmd = com_status_vars_array[sql_command].name;
}
if(!cmd)
@@ -1057,8 +1156,8 @@ static int set_com_status_vars_array ()
size_t initial_offset = (size_t) com_status_vars[status_vars_index].value;
status_vars_index =0;
while (com_status_vars[status_vars_index].name != NullS)
{
int sql_command_idx = (com_status_vars[status_vars_index].value - (char*) (initial_offset)) / sizeof (ulong);
{
int sql_command_idx = ((size_t)(com_status_vars[status_vars_index].value) - (initial_offset)) / sizeof (ulong);
if (sql_command_idx >=0 && sql_command_idx < MAX_COM_STATUS_VARS_RECORDS)
{
com_status_vars_array [sql_command_idx].name = com_status_vars[status_vars_index].name;
@@ -1171,9 +1270,18 @@ static int do_hot_patch(void ** trampoline_func_pp, unsigned int * trampoline_si
static void NAME ## _string_update(THD *thd, struct st_mysql_sys_var *var, void *tgt, const void *save)\
{\
num_ ## NAME = string_to_array(save, NAME ## _array, array_elements( NAME ## _array), sizeof( NAME ## _array[0]));\
strncpy( NAME ##_buff , *static_cast<char*const*>(save), array_elements( NAME ## _buff) - 1);\
/* handle "set global audit_xxx = null;" */ \
char *const* save_p = static_cast<char*const*>(save);\
if (save_p != NULL && *save_p != NULL)\
{\
strncpy( NAME ##_buff , *static_cast<char*const*>(save), array_elements( NAME ## _buff) - 1);\
}\
else\
{\
NAME ## _buff[0] = '\0';\
}\
NAME ## _string = NAME ##_buff;\
sql_print_information("%s Set " #NAME " num: %d, value: %s", log_prefix, num_ ## NAME, NAME ## _string);\
sql_print_information("%s Set " #NAME " num: %d, value: %s", log_prefix, num_ ## NAME, NAME ## _string);\
}
DECLARE_STRING_ARR_UPDATE_FUNC(delay_cmds)
@@ -1185,15 +1293,47 @@ DECLARE_STRING_ARR_UPDATE_FUNC(record_objs)
static void password_masking_regex_string_update(THD *thd, struct st_mysql_sys_var *var, void *tgt, const void *save)
{
const char * str_val = *static_cast<char*const*>(save);
const char * str = str_val;
//copy str to buffer only if str is not pointing to buff
if(str != password_masking_regex_buff)
const char * str_val = "";
char *const* save_p = static_cast<char*const*>(save);
// if got a null pointer or empty string, use ""
if (save_p != NULL && *save_p != NULL)
{
strncpy( password_masking_regex_buff , str, array_elements( password_masking_regex_buff) - 1);
}
password_masking_regex_string = password_masking_regex_buff;
password_masking_regex_compile();
str_val = *save_p;
}
// if a string value supplied, check that it compiles
if (*str_val)
{
int res = json_formatter.compile_password_masking_regex(str_val);
if (res != 0) // fails compilation
{
// copy in default pw
strncpy(password_masking_regex_buff, default_pw_masking_regex, array_elements(password_masking_regex_buff) - 1);
password_masking_regex_string = password_masking_regex_buff;
// compile it
json_formatter.compile_password_masking_regex(password_masking_regex_string);
}
else
{
// all ok, save it
if (str_val != password_masking_regex_buff)
{
strncpy(password_masking_regex_buff, str_val, array_elements(password_masking_regex_buff) - 1);
}
password_masking_regex_string = password_masking_regex_buff;
// it was already compiled, don't need to do it again
}
sql_print_information("%s Compile password_masking_regex res: [%d]", log_prefix, res);
}
else
{
// clear out password
password_masking_regex_buff[0] = '\0';
password_masking_regex_string = password_masking_regex_buff;
json_formatter.compile_password_masking_regex(password_masking_regex_string);
}
sql_print_information("%s Set password_masking_regex value: [%s]", log_prefix, str_val);
}
@@ -1211,7 +1351,14 @@ static void replace_char(char * str, const char tofind, const char rplc)
static void json_socket_name_update(THD *thd, struct st_mysql_sys_var *var, void *tgt, const void *save)
{
const char * str_val = *static_cast<char*const*>(save);
const char * str_val = NULL;
char *const* save_p = static_cast<char*const*>(save);
if (save_p != NULL && *save_p != NULL)
{
str_val = *save_p;
}
const char * str = str_val;
const size_t buff_len = array_elements( json_socket_name_buff) -1;
//copy str to buffer only if str is not pointing to buff
@@ -1417,8 +1564,14 @@ static void record_objs_string_update_extended(THD *thd, struct st_mysql_sys_var
//hot patch stuff
void * target_function = NULL;
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
target_function = (void*) mysql_execute_command;
#else
target_function = (void*)
(int (*)(THD *thd, bool first_level)) &mysql_execute_command;
#endif
if(do_hot_patch((void **)&trampoline_mysql_execute_command, &trampoline_mysql_execute_size,
(void *)mysql_execute_command, (void *)audit_mysql_execute_command, "mysql_execute_command"))
target_function, (void *)audit_mysql_execute_command, "mysql_execute_command"))
{
DBUG_RETURN(1);
}
@@ -1447,7 +1600,11 @@ static void record_objs_string_update_extended(THD *thd, struct st_mysql_sys_var
DBUG_RETURN(1);
}
#endif
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
int (Query_cache::*pf_send_result_to_client)(THD *,char *, uint) = &Query_cache::send_result_to_client;
#else
int (Query_cache::*pf_send_result_to_client)(THD *,const LEX_CSTRING&) = &Query_cache::send_result_to_client;
#endif
target_function = *(void **) &pf_send_result_to_client;
if(do_hot_patch((void **)&trampoline_send_result_to_client, &trampoline_send_result_to_client_size,
(void *)target_function, (void *)audit_send_result_to_client, "send_result_to_client"))
@@ -1461,22 +1618,20 @@ static void record_objs_string_update_extended(THD *thd, struct st_mysql_sys_var
DBUG_RETURN(1);
}
#if MYSQL_VERSION_ID > 50505
target_function = (void *)*(bool (*)(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100108
target_function = (void *)*(bool (*)(THD *thd, const DDL_options_st &options, TABLE_LIST **start, uint *counter, uint flags,
Prelocking_strategy *prelocking_strategy)) &open_tables;
if(do_hot_patch((void **)&trampoline_open_tables, &trampoline_open_tables_size,
(void *)target_function, (void *)audit_open_tables, "open_tables"))
{
DBUG_RETURN(1);
}
#elif MYSQL_VERSION_ID > 50505
target_function = (void *)*(bool (*)(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
Prelocking_strategy *prelocking_strategy)) &open_tables;
#else
target_function = (void *)*(int (*)(THD *thd, TABLE_LIST **start, uint *counter, uint flags)) &open_tables;
if(do_hot_patch((void **)&trampoline_open_tables, &trampoline_open_tables_size,
target_function = (void *)*(int (*)(THD *thd, TABLE_LIST **start, uint *counter, uint flags)) &open_tables;
#endif
if(do_hot_patch((void **)&trampoline_open_tables, &trampoline_open_tables_size,
(void *)target_function, (void *)audit_open_tables, "open_tables"))
{
DBUG_RETURN(1);
}
#endif
}
if (set_com_status_vars_array () !=0)
{
DBUG_RETURN(1);
@@ -1514,10 +1669,18 @@ static struct st_mysql_show_var audit_status[] =
{
{ "Audit_version",
(char *) MYSQL_AUDIT_PLUGIN_VERSION "-" MYSQL_AUDIT_PLUGIN_REVISION,
SHOW_CHAR },
SHOW_CHAR
#if ! defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 50709
, SHOW_SCOPE_GLOBAL
#endif
},
{ "Audit_protocol_version",
(char *) AUDIT_PROTOCOL_VERSION,
SHOW_CHAR },
SHOW_CHAR
#if ! defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 50709
, SHOW_SCOPE_GLOBAL
#endif
},
//{"called", (char *)&number_of_calls, SHOW_LONG},
{ 0, 0, (enum_mysql_show_type) 0 } };
@@ -1565,10 +1728,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,
@@ -1609,23 +1780,11 @@ static MYSQL_SYSVAR_STR(checksum, checksum_string,
"AUDIT plugin checksum. Checksum for mysqld corresponding to offsets",
NULL, NULL, "");
#define _COMMENT_SPACE_ "(?:/\\*.*?\\*/|\\s)*?"
#define _QUOTED_PSW_ "[\'|\"](?<psw>.*?)(?<!\\\\)[\'|\"]"
static MYSQL_SYSVAR_STR(password_masking_regex, password_masking_regex_string,
PLUGIN_VAR_RQCMDARG ,
"AUDIT plugin regex to use for password masking",
password_masking_regex_check, password_masking_regex_string_update,
//identified by [password] '***'
"identified"_COMMENT_SPACE_"by"_COMMENT_SPACE_"(?:password)?"_COMMENT_SPACE_ _QUOTED_PSW_
//password function
"|password"_COMMENT_SPACE_"\\("_COMMENT_SPACE_ _QUOTED_PSW_ _COMMENT_SPACE_"\\)"
//Used at: CHANGE MASTER TO MASTER_PASSWORD='new3cret', SET PASSWORD [FOR user] = 'hash', password 'user_pass';
"|password"_COMMENT_SPACE_"(?:for"_COMMENT_SPACE_"\\S+?)?"_COMMENT_SPACE_"="_COMMENT_SPACE_ _QUOTED_PSW_
"|password"_COMMENT_SPACE_ _QUOTED_PSW_
//federated engine create table with connection. See: http://dev.mysql.com/doc/refman/5.5/en/federated-create-connection.html
//commented out as federated engine is disabled by default
//"|ENGINE"_COMMENT_SPACE_"="_COMMENT_SPACE_"FEDERATED"_COMMENT_SPACE_".*CONNECTION"_COMMENT_SPACE_"="_COMMENT_SPACE_"[\'|\"]\\S+?://\\S+?:(?<psw>.*)@\\S+[\'|\"]"
default_pw_masking_regex
);
static MYSQL_SYSVAR_BOOL(uninstall_plugin, uninstall_plugin_enable,
@@ -1661,11 +1820,11 @@ static MYSQL_SYSVAR_STR(delay_cmds, delay_cmds_string,
NULL, delay_cmds_string_update, NULL);
static MYSQL_SYSVAR_STR(whitelist_cmds, whitelist_cmds_string,
PLUGIN_VAR_RQCMDARG,
"AUDIT plugin commands to skip, comma separated",
NULL, whitelist_cmds_string_update, NULL);
"AUDIT plugin whitelisted commands for which queries are not recorded, comma separated",
NULL, whitelist_cmds_string_update, "BEGIN,COMMIT");
static MYSQL_SYSVAR_STR(record_cmds, record_cmds_string,
PLUGIN_VAR_RQCMDARG,
"AUDIT plugin whitelisted commands for which queries are not recorded, comma separated",
"AUDIT plugin commands for which queries are recorded, comma separated. If set then only queries of these commands will be recorded.",
NULL, record_cmds_string_update, NULL);
static MYSQL_SYSVAR_STR(password_masking_cmds, password_masking_cmds_string,
PLUGIN_VAR_RQCMDARG,
@@ -1680,7 +1839,7 @@ static MYSQL_SYSVAR_STR(whitelist_users, whitelist_users_string,
static MYSQL_SYSVAR_STR(record_objs, record_objs_string,
PLUGIN_VAR_RQCMDARG,
"AUDIT plugin objects to record, comma separated",
"AUDIT plugin objects to record, comma separated. If set then only queries containing these objects will be recorded.",
NULL, record_objs_string_update_extended, NULL);
/*
@@ -1689,7 +1848,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),
@@ -1769,8 +1930,9 @@ extern "C" void __attribute__ ((constructor)) audit_plugin_so_init(void)
audit_plugin.interface_version >> 8);
}
#elif !defined(MARIADB_BASE_VERSION)
//interface version for MySQL 5.6 changed in 5.6.14
#elif !defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID < 50709
// Interface version for MySQL 5.6 changed in 5.6.14.
// This is not needed for 5.7.
extern "C" void __attribute__ ((constructor)) audit_plugin_so_init(void)
{
const char * ver_5_6_13 = "5.6.13";
@@ -1797,3 +1959,13 @@ extern "C" int __cxa_pure_virtual (void)
log_prefix);
return 0;
}
/*
* Variable to hold version
*/
MYSQL_AUDIT_PLUGIN_SYMBOL_VERSION() = '\0';