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.
pull/141/head
Arnold Robbins 2016-02-07 15:59:41 +02:00
parent 685b20e20c
commit d9129cc112
7 changed files with 392 additions and 94 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 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: 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 . cmake .
make 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: For MariaDB use: cmake . -DBUILD_CONFIG=mysql_release
Note: to speed things up it is possible to build just the following directories: 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.]) 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 fi
done 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]) 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"]) AC_MSG_RESULT(["$withval"])
], ],
[ [

View File

@ -20,6 +20,18 @@
#define AUDIT_LOG_PREFIX "Audit Plugin:" #define AUDIT_LOG_PREFIX "Audit Plugin:"
#define AUDIT_PROTOCOL_VERSION "1.0" #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; class THD;
#define MAX_NUM_QUERY_TABLE_ELEM 100 #define MAX_NUM_QUERY_TABLE_ELEM 100
@ -190,7 +202,11 @@ public:
{ {
if(!Audit_formatter::thd_offsets.db) //no offsets use compiled in header 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) return *(const char **) (((unsigned char *) thd)
+ Audit_formatter::thd_offsets.db); + Audit_formatter::thd_offsets.db);
@ -211,7 +227,11 @@ public:
Security_context * sctx = thd_inst_main_security_ctx(thd); Security_context * sctx = thd_inst_main_security_ctx(thd);
if(!Audit_formatter::thd_offsets.sec_ctx_user) //no offsets use compiled in header 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) return *(const char **) (((unsigned char *) sctx)
+ Audit_formatter::thd_offsets.sec_ctx_user); + 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() //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 //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) ) #if defined(MARIADB_BASE_VERSION)
return sctx->get_host()->ptr();
#else
return sctx->host; 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
#endif // ! defined(MARIADB_BASE_VERSION)
} }
return *(const char **) (((unsigned char *) sctx) return *(const char **) (((unsigned char *) sctx)
+ Audit_formatter::thd_offsets.sec_ctx_host); + 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 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() //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(); return sctx->get_ip()->ptr();
#else #else
return sctx->ip; // interface changed again in 5.7
return sctx->ip().str;
#endif #endif
#endif // ! defined(MARIADB_BASE_VERSION)
} }
return *(const char **) (((unsigned char *) sctx) return *(const char **) (((unsigned char *) sctx)
+ Audit_formatter::thd_offsets.sec_ctx_ip); + Audit_formatter::thd_offsets.sec_ctx_ip);
@ -255,7 +293,11 @@ public:
Security_context * sctx = thd_inst_main_security_ctx(thd); Security_context * sctx = thd_inst_main_security_ctx(thd);
if(!Audit_formatter::thd_offsets.sec_ctx_priv_user) //no offsets use compiled in header 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 #if MYSQL_VERSION_ID < 50505
//in 5.1.x priv_user is a pointer //in 5.1.x priv_user is a pointer

View File

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

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]; Audit_handler * Audit_handler::m_audit_handler_list[Audit_handler::MAX_AUDIT_HANDLERS_NUM];
const char * Audit_json_formatter::DEF_MSG_DELIMITER = "\\n"; 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)) #define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
#endif
const char * Audit_formatter::retrieve_object_type (TABLE_LIST *pObj) const char * Audit_formatter::retrieve_object_type (TABLE_LIST *pObj)
@ -465,7 +467,25 @@ static const char * retrieve_user (THD * thd)
//will return a pointer to the query and set len with the length of the query //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 //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" { extern "C" {
MYSQL_LEX_STRING *thd_query_string(MYSQL_THD thd); MYSQL_LEX_STRING *thd_query_string(MYSQL_THD thd);
} }
@ -548,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) ssize_t Audit_json_formatter::event_format(ThdSesData* pThdData, IWriter * writer)
{ {
THD * thd = pThdData->getTHD(); THD * thd = pThdData->getTHD();
@ -599,15 +653,34 @@ ssize_t Audit_json_formatter::event_format(ThdSesData* pThdData, IWriter * write
#endif #endif
col_connection = Item::default_charset(); col_connection = Item::default_charset();
String sQuery (query,qlen,col_connection) ; // See comment below as to why we don't use String class directly, or call
if (strcmp (col_connection->csname,"utf8")!=0) { // pThdData->getTHD()->convert_string (&sQuery,col_connection,&my_charset_utf8_general_ci);
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)) if(m_perform_password_masking && m_password_mask_regex_compiled && m_password_mask_regex_preg && m_perform_password_masking(cmd))
{ {
//do password masking //do password masking
int matches[90] = {0}; 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 //search for the first substring that matches with the name psw
char *first = NULL, *last = NULL; char *first = NULL, *last = NULL;
@ -619,17 +692,24 @@ ssize_t Audit_json_formatter::event_format(ThdSesData* pThdData, IWriter * write
//first 2 bytes give us the number //first 2 bytes give us the number
int n = (((int)(entry)[0]) << 8) | (entry)[1]; int n = (((int)(entry)[0]) << 8) | (entry)[1];
if (n > 0 && n < (int)array_elements(matches) && matches[n*2] >= 0) 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 // We have a match.
const char * pass_replace = "***";
sQuery.replace(matches[n*2], matches[(n*2) + 1] - matches[n*2], pass_replace, strlen(pass_replace)); // 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; break;
} }
} }
} }
} }
} }
yajl_add_string_val(gen, "query", sQuery.ptr(), sQuery.length()); yajl_add_string_val(gen, "query", query_text, query_len);
} }
else else
{ {
@ -691,7 +771,9 @@ bool ThdSesData::startGetObjects()
} }
const char *cmd = getCmdName(); const char *cmd = getCmdName();
//commands which have single database object //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(Audit_formatter::thd_db(getTHD())) if(Audit_formatter::thd_db(getTHD()))
{ {

28
src/audit_offsets.cc Normal file → Executable file
View File

@ -21,6 +21,16 @@
//64 bit offsets //64 bit offsets
const ThdOffsets thd_offsets_arr[] = const ThdOffsets thd_offsets_arr[] =
{ {
//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) //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}, {"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) //offsets for: /mysqlrpm/5.6.28/usr/sbin/mysqld (5.6.28)
@ -419,6 +429,16 @@ const ThdOffsets thd_offsets_arr[] =
//32 bit offsets //32 bit offsets
const ThdOffsets thd_offsets_arr[] = const ThdOffsets thd_offsets_arr[] =
{ {
//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) //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}, {"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) //offsets for: /mysqlrpm/5.6.28/usr/sbin/mysqld (5.6.28)
@ -797,6 +817,10 @@ const ThdOffsets thd_offsets_arr[] =
//64 bit offsets //64 bit offsets
const ThdOffsets thd_offsets_arr[] = const ThdOffsets thd_offsets_arr[] =
{ {
//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) //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}, {"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) //offsets for: /mariadb/10.0.22/bin/mysqld (10.0.22-MariaDB)
@ -877,6 +901,10 @@ const ThdOffsets thd_offsets_arr[] =
//32 bit offsets //32 bit offsets
const ThdOffsets thd_offsets_arr[] = const ThdOffsets thd_offsets_arr[] =
{ {
//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) //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}, {"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) //offsets for: /mariadb/10.0.22/bin/mysqld (10.0.22-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_string = NULL;
static char password_masking_regex_buff[4096] = {0}; 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 //socket name
static char json_socket_name_buff[1024] = {0}; static char json_socket_name_buff[1024] = {0};
@ -197,18 +214,6 @@ static my_bool check_do_password_masking(const char * cmd)
return false; 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) static void audit(ThdSesData *pThdData)
{ {
THDPRINTED *pThdPrintedList = GetThdPrintedList (pThdData->getTHD()); THDPRINTED *pThdPrintedList = GetThdPrintedList (pThdData->getTHD());
@ -302,14 +307,18 @@ 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; 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, TABLE_LIST **start, uint *counter, uint flags,
Prelocking_strategy *prelocking_strategy) = NULL;
#elif 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, static bool (*trampoline_open_tables)(THD *thd, const DDL_options_st &options, TABLE_LIST **start, uint *counter, uint flags,
Prelocking_strategy *prelocking_strategy) = NULL; 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 #else
static int (*trampoline_open_tables)(THD *thd, TABLE_LIST **start, uint *counter, uint flags) = NULL; static int (*trampoline_open_tables)(THD *thd, TABLE_LIST **start, uint *counter, uint flags) = NULL;
#endif #endif
@ -355,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; 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) 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; int res;
void *pList = thd_alloc (thd, sizeof (QueryTableInf)); void *pList = thd_alloc (thd, sizeof (QueryTableInf));
@ -366,7 +379,11 @@ static int audit_send_result_to_client(Query_cache *pthis, THD *thd, char *sql,
memset (pList,0,sizeof (QueryTableInf)); memset (pList,0,sizeof (QueryTableInf));
THDVAR(thd, query_cache_table_list) =(ulong)pList; 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); 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) if (res)
{ {
ThdSesData thd_data (thd); ThdSesData thd_data (thd);
@ -377,19 +394,19 @@ static int audit_send_result_to_client(Query_cache *pthis, THD *thd, char *sql,
} }
static unsigned int trampoline_send_result_to_client_size =0; 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, static bool audit_open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
Prelocking_strategy *prelocking_strategy) Prelocking_strategy *prelocking_strategy)
{ {
bool res; bool res;
res = trampoline_open_tables (thd, start, counter, flags, prelocking_strategy); res = trampoline_open_tables (thd, start, counter, flags, prelocking_strategy);
#elif 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);
#else #else
static int audit_open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags) static int audit_open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
{ {
@ -440,8 +457,13 @@ static struct st_mysql_daemon audit_plugin =
#else #else
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
static void audit_notify(THD *thd, unsigned int event_class, static void audit_notify(THD *thd, unsigned int event_class,
const void * event) 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) if (MYSQL_AUDIT_GENERAL_CLASS == event_class)
{ {
@ -463,6 +485,9 @@ static void audit_notify(THD *thd, unsigned int event_class,
audit (&ThdData); 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; static int plugin_type = MYSQL_AUDIT_PLUGIN;
@ -471,8 +496,25 @@ static struct st_mysql_audit audit_plugin=
MYSQL_AUDIT_INTERFACE_VERSION, /* interface version */ MYSQL_AUDIT_INTERFACE_VERSION, /* interface version */
NULL, /* release_thd function */ NULL, /* release_thd function */
audit_notify, /* notify 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 | { (unsigned long) MYSQL_AUDIT_GENERAL_CLASSMASK |
MYSQL_AUDIT_CONNECTION_CLASSMASK } /* class mask */ MYSQL_AUDIT_CONNECTION_CLASSMASK } /* class mask */
#endif
}; };
#endif #endif
@ -509,12 +551,12 @@ void remove_hot_functions ()
trampoline_acl_authenticate_size=0; trampoline_acl_authenticate_size=0;
#endif #endif
#if MYSQL_VERSION_ID > 50505 #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100108
target_function = (void *)*(bool (*)(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
Prelocking_strategy *prelocking_strategy)) &open_tables;
#elif 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, target_function = (void *)*(bool (*)(THD *thd, const DDL_options_st &options, TABLE_LIST **start, uint *counter, uint flags,
Prelocking_strategy *prelocking_strategy)) &open_tables; 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;
#else #else
target_function = (void *)*(int (*)(THD *thd, TABLE_LIST **start, uint *counter, uint flags)) &open_tables; target_function = (void *)*(int (*)(THD *thd, TABLE_LIST **start, uint *counter, uint flags)) &open_tables;
#endif #endif
@ -522,7 +564,11 @@ void remove_hot_functions ()
(void*) trampoline_open_tables, trampoline_open_tables_size, true); (void*) trampoline_open_tables, trampoline_open_tables_size, true);
trampoline_open_tables_size=0; trampoline_open_tables_size=0;
#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; 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; target_function = *(void **) &pf_send_result_to_client;
remove_hot_patch_function(target_function, remove_hot_patch_function(target_function,
(void*) trampoline_send_result_to_client, trampoline_send_result_to_client_size, true); (void*) trampoline_send_result_to_client, trampoline_send_result_to_client_size, true);
@ -532,7 +578,14 @@ void remove_hot_functions ()
(void*) trampoline_check_table_access, (void*) trampoline_check_table_access,
trampoline_check_table_access_size, true); trampoline_check_table_access_size, true);
trampoline_check_table_access_size=0; 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, (void*) trampoline_mysql_execute_command,
trampoline_mysql_execute_size, true); trampoline_mysql_execute_size, true);
trampoline_mysql_execute_size=0; trampoline_mysql_execute_size=0;
@ -618,7 +671,11 @@ static int audit_mysql_execute_command(THD *thd)
{ {
case 1: case 1:
//hot patch function were removed and we call the real execute (restored) //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); res = mysql_execute_command(thd);
#else
res = mysql_execute_command(thd, false);
#endif
break; break;
case 2: case 2:
//denied uninstall plugin //denied uninstall plugin
@ -746,7 +803,8 @@ static bool validate_offsets(const ThdOffsets * offset)
{ {
sql_print_error( sql_print_error(
"%s Offsets: %s (%s) match thread validation check fails with value: %lu. Skipping offest.", "%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; return false;
} }
//extended validation via security_context method //extended validation via security_context method
@ -759,7 +817,11 @@ static bool validate_offsets(const ThdOffsets * offset)
char user_test_val[] = "aud_tusr"; char user_test_val[] = "aud_tusr";
if(!offset->sec_ctx_user) //use compiled header if(!offset->sec_ctx_user) //use compiled header
{ {
#if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID < 50709
sctx->user = user_test_val; sctx->user = user_test_val;
#else
sctx->set_user_ptr(user_test_val, strlen(user_test_val));
#endif
} }
else else
{ {
@ -1044,9 +1106,13 @@ const char * retrieve_command (THD * thd, bool & is_sql_cmd)
return "select"; return "select";
} }
const int sql_command = thd_sql_command(thd); 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 ) 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; cmd = com_status_vars_array[sql_command].name;
} }
if(!cmd) if(!cmd)
@ -1204,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)\ 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]));\ 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;\ 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) DECLARE_STRING_ARR_UPDATE_FUNC(delay_cmds)
@ -1218,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) 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_val = "";
const char * str = str_val; char *const* save_p = static_cast<char*const*>(save);
//copy str to buffer only if str is not pointing to buff
if(str != password_masking_regex_buff) // 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); str_val = *save_p;
} }
password_masking_regex_string = password_masking_regex_buff;
password_masking_regex_compile(); // 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); sql_print_information("%s Set password_masking_regex value: [%s]", log_prefix, str_val);
} }
@ -1244,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) 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 char * str = str_val;
const size_t buff_len = array_elements( json_socket_name_buff) -1; const size_t buff_len = array_elements( json_socket_name_buff) -1;
//copy str to buffer only if str is not pointing to buff //copy str to buffer only if str is not pointing to buff
@ -1450,8 +1564,14 @@ static void record_objs_string_update_extended(THD *thd, struct st_mysql_sys_var
//hot patch stuff //hot patch stuff
void * target_function = NULL; 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, 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); DBUG_RETURN(1);
} }
@ -1480,7 +1600,11 @@ static void record_objs_string_update_extended(THD *thd, struct st_mysql_sys_var
DBUG_RETURN(1); DBUG_RETURN(1);
} }
#endif #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; 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; target_function = *(void **) &pf_send_result_to_client;
if(do_hot_patch((void **)&trampoline_send_result_to_client, &trampoline_send_result_to_client_size, 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")) (void *)target_function, (void *)audit_send_result_to_client, "send_result_to_client"))
@ -1494,12 +1618,12 @@ static void record_objs_string_update_extended(THD *thd, struct st_mysql_sys_var
DBUG_RETURN(1); DBUG_RETURN(1);
} }
#if MYSQL_VERSION_ID > 50505 #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100108
target_function = (void *)*(bool (*)(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
Prelocking_strategy *prelocking_strategy)) &open_tables;
#elif 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, target_function = (void *)*(bool (*)(THD *thd, const DDL_options_st &options, TABLE_LIST **start, uint *counter, uint flags,
Prelocking_strategy *prelocking_strategy)) &open_tables; 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;
#else #else
target_function = (void *)*(int (*)(THD *thd, TABLE_LIST **start, uint *counter, uint flags)) &open_tables; target_function = (void *)*(int (*)(THD *thd, TABLE_LIST **start, uint *counter, uint flags)) &open_tables;
#endif #endif
@ -1545,10 +1669,18 @@ static struct st_mysql_show_var audit_status[] =
{ {
{ "Audit_version", { "Audit_version",
(char *) MYSQL_AUDIT_PLUGIN_VERSION "-" MYSQL_AUDIT_PLUGIN_REVISION, (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", { "Audit_protocol_version",
(char *) 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}, //{"called", (char *)&number_of_calls, SHOW_LONG},
{ 0, 0, (enum_mysql_show_type) 0 } }; { 0, 0, (enum_mysql_show_type) 0 } };
@ -1648,23 +1780,11 @@ static MYSQL_SYSVAR_STR(checksum, checksum_string,
"AUDIT plugin checksum. Checksum for mysqld corresponding to offsets", "AUDIT plugin checksum. Checksum for mysqld corresponding to offsets",
NULL, NULL, ""); NULL, NULL, "");
#define _COMMENT_SPACE_ "(?:/\\*.*?\\*/|\\s)*?"
#define _QUOTED_PSW_ "[\'|\"](?<psw>.*?)(?<!\\\\)[\'|\"]"
static MYSQL_SYSVAR_STR(password_masking_regex, password_masking_regex_string, static MYSQL_SYSVAR_STR(password_masking_regex, password_masking_regex_string,
PLUGIN_VAR_RQCMDARG , PLUGIN_VAR_RQCMDARG ,
"AUDIT plugin regex to use for password masking", "AUDIT plugin regex to use for password masking",
password_masking_regex_check, password_masking_regex_string_update, password_masking_regex_check, password_masking_regex_string_update,
//identified by [password] '***' default_pw_masking_regex
"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+[\'|\"]"
); );
static MYSQL_SYSVAR_BOOL(uninstall_plugin, uninstall_plugin_enable, static MYSQL_SYSVAR_BOOL(uninstall_plugin, uninstall_plugin_enable,
@ -1701,7 +1821,7 @@ static MYSQL_SYSVAR_STR(delay_cmds, delay_cmds_string,
static MYSQL_SYSVAR_STR(whitelist_cmds, whitelist_cmds_string, static MYSQL_SYSVAR_STR(whitelist_cmds, whitelist_cmds_string,
PLUGIN_VAR_RQCMDARG, PLUGIN_VAR_RQCMDARG,
"AUDIT plugin whitelisted commands for which queries are not recorded, comma separated", "AUDIT plugin whitelisted commands for which queries are not recorded, comma separated",
NULL, whitelist_cmds_string_update, NULL); NULL, whitelist_cmds_string_update, "BEGIN,COMMIT");
static MYSQL_SYSVAR_STR(record_cmds, record_cmds_string, static MYSQL_SYSVAR_STR(record_cmds, record_cmds_string,
PLUGIN_VAR_RQCMDARG, PLUGIN_VAR_RQCMDARG,
"AUDIT plugin commands for which queries are recorded, comma separated. If set then only queries of these commands will be recorded.", "AUDIT plugin commands for which queries are recorded, comma separated. If set then only queries of these commands will be recorded.",
@ -1810,8 +1930,9 @@ extern "C" void __attribute__ ((constructor)) audit_plugin_so_init(void)
audit_plugin.interface_version >> 8); audit_plugin.interface_version >> 8);
} }
#elif !defined(MARIADB_BASE_VERSION) #elif !defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID < 50709
//interface version for MySQL 5.6 changed in 5.6.14 // 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) extern "C" void __attribute__ ((constructor)) audit_plugin_so_init(void)
{ {
const char * ver_5_6_13 = "5.6.13"; const char * ver_5_6_13 = "5.6.13";