16 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
8 changed files with 576 additions and 144 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

@@ -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
@@ -190,7 +202,11 @@ public:
{
if(!Audit_formatter::thd_offsets.db) //no offsets use compiled in header
{
return thd->db;
#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);
@@ -211,7 +227,11 @@ public:
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);
@@ -224,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);
@@ -240,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);
@@ -255,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

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, %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
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

@@ -48,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)
@@ -405,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)
{
@@ -420,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);
@@ -443,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);
@@ -462,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);
}
@@ -545,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();
@@ -595,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;
@@ -616,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
{
@@ -688,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;

View File

@@ -21,6 +21,33 @@
//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)
@@ -403,6 +430,33 @@ 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)
@@ -764,7 +818,44 @@ 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)
@@ -819,6 +910,43 @@ 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)

View File

@@ -87,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};
@@ -197,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());
@@ -302,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
@@ -352,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));
@@ -363,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);
@@ -374,13 +394,25 @@ 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);
#else
static int audit_open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
{
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))
{
@@ -389,20 +421,8 @@ static bool audit_open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint
}
return res;
}
#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);
//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;
}
#endif
static unsigned int trampoline_open_tables_size =0;
@@ -437,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)
{
@@ -460,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;
@@ -468,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
@@ -506,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);
@@ -529,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;
@@ -615,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
@@ -676,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;
@@ -687,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;
}
@@ -733,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
@@ -746,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
{
@@ -871,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,
@@ -881,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))
{
@@ -1029,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)
@@ -1075,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;
@@ -1189,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)
@@ -1203,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);
}
@@ -1229,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
@@ -1435,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);
}
@@ -1465,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"))
@@ -1479,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);
@@ -1532,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 } };
@@ -1635,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,
@@ -1687,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,
@@ -1706,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);
/*
@@ -1797,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";