Backport from 6.0-codebase.
Bug #36098 Audit plugin (wl 3771) feature disabled in 6.0 avoid recusrive locking of LOCK_plugin
This commit is contained in:
parent
94098b22c0
commit
da31abf8ed
@ -24,8 +24,7 @@
|
|||||||
|
|
||||||
#define MYSQL_AUDIT_CLASS_MASK_SIZE 1
|
#define MYSQL_AUDIT_CLASS_MASK_SIZE 1
|
||||||
|
|
||||||
#define MYSQL_AUDIT_INTERFACE_VERSION ( 0x010000 | MYSQL_AUDIT_CLASS_MASK_SIZE )
|
#define MYSQL_AUDIT_INTERFACE_VERSION 0x0100
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The first word in every event class struct indicates the specific
|
The first word in every event class struct indicates the specific
|
||||||
|
14
sql/log.cc
14
sql/log.cc
@ -43,7 +43,6 @@
|
|||||||
|
|
||||||
/* max size of the log message */
|
/* max size of the log message */
|
||||||
#define MAX_LOG_BUFFER_SIZE 1024
|
#define MAX_LOG_BUFFER_SIZE 1024
|
||||||
#define MAX_USER_HOST_SIZE 512
|
|
||||||
#define MAX_TIME_SIZE 32
|
#define MAX_TIME_SIZE 32
|
||||||
#define MY_OFF_T_UNDEF (~(my_off_t)0UL)
|
#define MY_OFF_T_UNDEF (~(my_off_t)0UL)
|
||||||
|
|
||||||
@ -1069,7 +1068,6 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
|
|||||||
bool error= FALSE;
|
bool error= FALSE;
|
||||||
Log_event_handler **current_handler= general_log_handler_list;
|
Log_event_handler **current_handler= general_log_handler_list;
|
||||||
char user_host_buff[MAX_USER_HOST_SIZE + 1];
|
char user_host_buff[MAX_USER_HOST_SIZE + 1];
|
||||||
Security_context *sctx= thd->security_ctx;
|
|
||||||
uint user_host_len= 0;
|
uint user_host_len= 0;
|
||||||
time_t current_time;
|
time_t current_time;
|
||||||
|
|
||||||
@ -1081,21 +1079,15 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
|
|||||||
unlock();
|
unlock();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
|
user_host_len= make_user_name(thd, user_host_buff);
|
||||||
sctx->priv_user ? sctx->priv_user : "", "[",
|
|
||||||
sctx->user ? sctx->user : "", "] @ ",
|
|
||||||
sctx->host ? sctx->host : "", " [",
|
|
||||||
sctx->ip ? sctx->ip : "", "]", NullS) -
|
|
||||||
user_host_buff;
|
|
||||||
|
|
||||||
current_time= my_time(0);
|
current_time= my_time(0);
|
||||||
|
|
||||||
mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_LOG, 0, current_time,
|
mysql_audit_general_log(thd, current_time,
|
||||||
user_host_buff, user_host_len,
|
user_host_buff, user_host_len,
|
||||||
command_name[(uint) command].str,
|
command_name[(uint) command].str,
|
||||||
command_name[(uint) command].length,
|
command_name[(uint) command].length,
|
||||||
query, query_length,
|
query, query_length);
|
||||||
thd->variables.character_set_client,0);
|
|
||||||
|
|
||||||
while (*current_handler)
|
while (*current_handler)
|
||||||
error|= (*current_handler++)->
|
error|= (*current_handler++)->
|
||||||
|
@ -2923,15 +2923,10 @@ void my_message_sql(uint error, const char *str, myf MyFlags)
|
|||||||
error= ER_UNKNOWN_ERROR;
|
error= ER_UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_ERROR, error, str);
|
||||||
|
|
||||||
if (thd)
|
if (thd)
|
||||||
{
|
{
|
||||||
mysql_audit_general(thd,MYSQL_AUDIT_GENERAL_ERROR,error,my_time(0),
|
|
||||||
0,0,str,str ? strlen(str) : 0,
|
|
||||||
thd->query(), thd->query_length(),
|
|
||||||
thd->variables.character_set_client,
|
|
||||||
thd->warning_info->current_row_for_warning());
|
|
||||||
|
|
||||||
|
|
||||||
if (MyFlags & ME_FATALERROR)
|
if (MyFlags & ME_FATALERROR)
|
||||||
thd->is_fatal_error= 1;
|
thd->is_fatal_error= 1;
|
||||||
(void) thd->raise_condition(error,
|
(void) thd->raise_condition(error,
|
||||||
|
@ -3519,7 +3519,6 @@ void set_var_free()
|
|||||||
@param str Name of system variable to find
|
@param str Name of system variable to find
|
||||||
@param length Length of variable. zero means that we should use strlen()
|
@param length Length of variable. zero means that we should use strlen()
|
||||||
on the variable
|
on the variable
|
||||||
@param no_error Refuse to emit an error, even if one occurred.
|
|
||||||
|
|
||||||
@retval
|
@retval
|
||||||
pointer pointer to variable definitions
|
pointer pointer to variable definitions
|
||||||
@ -3527,7 +3526,7 @@ void set_var_free()
|
|||||||
0 Unknown variable (error message is given)
|
0 Unknown variable (error message is given)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sys_var *intern_find_sys_var(const char *str, uint length, bool no_error)
|
sys_var *intern_find_sys_var(const char *str, uint length)
|
||||||
{
|
{
|
||||||
sys_var *var;
|
sys_var *var;
|
||||||
|
|
||||||
@ -3537,9 +3536,6 @@ sys_var *intern_find_sys_var(const char *str, uint length, bool no_error)
|
|||||||
*/
|
*/
|
||||||
var= (sys_var*) my_hash_search(&system_variable_hash,
|
var= (sys_var*) my_hash_search(&system_variable_hash,
|
||||||
(uchar*) str, length ? length : strlen(str));
|
(uchar*) str, length ? length : strlen(str));
|
||||||
if (!(var || no_error))
|
|
||||||
my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
|
|
||||||
|
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,18 +34,21 @@ extern void mysql_audit_notify(THD *thd, uint event_class,
|
|||||||
uint event_subtype, ...);
|
uint event_subtype, ...);
|
||||||
extern void mysql_audit_release(THD *thd);
|
extern void mysql_audit_release(THD *thd);
|
||||||
|
|
||||||
|
#define MAX_USER_HOST_SIZE 512
|
||||||
|
static inline uint make_user_name(THD *thd, char *buf)
|
||||||
|
{
|
||||||
|
Security_context *sctx= thd->security_ctx;
|
||||||
|
return strxnmov(buf, MAX_USER_HOST_SIZE,
|
||||||
|
sctx->priv_user ? sctx->priv_user : "", "[",
|
||||||
|
sctx->user ? sctx->user : "", "] @ ",
|
||||||
|
sctx->host ? sctx->host : "", " [",
|
||||||
|
sctx->ip ? sctx->ip : "", "]", NullS) - buf;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Call audit plugins of GENERAL audit class.
|
Call audit plugins of GENERAL audit class, MYSQL_AUDIT_GENERAL_LOG subtype.
|
||||||
event_subtype should be set to one of:
|
|
||||||
MYSQL_AUDIT_GENERAL_LOG
|
|
||||||
MYSQL_AUDIT_GENERAL_ERROR
|
|
||||||
MYSQL_AUDIT_GENERAL_RESULT
|
|
||||||
|
|
||||||
@param[in] thd
|
@param[in] thd
|
||||||
@param[in] event_subtype Type of general audit event.
|
|
||||||
@param[in] error_code Error code
|
|
||||||
@param[in] time time that event occurred
|
@param[in] time time that event occurred
|
||||||
@param[in] user User name
|
@param[in] user User name
|
||||||
@param[in] userlen User name length
|
@param[in] userlen User name length
|
||||||
@ -53,24 +56,74 @@ extern void mysql_audit_release(THD *thd);
|
|||||||
@param[in] cmdlen Command name length
|
@param[in] cmdlen Command name length
|
||||||
@param[in] query Query string
|
@param[in] query Query string
|
||||||
@param[in] querylen Query string length
|
@param[in] querylen Query string length
|
||||||
@param[in] clientcs Charset of query string
|
|
||||||
@param[in] rows Number of affected rows
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
void mysql_audit_general(THD *thd, uint event_subtype,
|
void mysql_audit_general_log(THD *thd, time_t time,
|
||||||
int error_code, time_t time,
|
|
||||||
const char *user, uint userlen,
|
const char *user, uint userlen,
|
||||||
const char *cmd, uint cmdlen,
|
const char *cmd, uint cmdlen,
|
||||||
const char *query, uint querylen,
|
const char *query, uint querylen)
|
||||||
CHARSET_INFO *clientcs,
|
|
||||||
ha_rows rows)
|
|
||||||
{
|
{
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
if (mysql_global_audit_mask[0] & MYSQL_AUDIT_GENERAL_CLASSMASK)
|
if (mysql_global_audit_mask[0] & MYSQL_AUDIT_GENERAL_CLASSMASK)
|
||||||
|
{
|
||||||
|
CHARSET_INFO *clientcs= thd ? thd->variables.character_set_client
|
||||||
|
: global_system_variables.character_set_client;
|
||||||
|
|
||||||
|
mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, MYSQL_AUDIT_GENERAL_LOG,
|
||||||
|
0, time, user, userlen, cmd, cmdlen,
|
||||||
|
query, querylen, clientcs, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Call audit plugins of GENERAL audit class.
|
||||||
|
event_subtype should be set to one of:
|
||||||
|
MYSQL_AUDIT_GENERAL_ERROR
|
||||||
|
MYSQL_AUDIT_GENERAL_RESULT
|
||||||
|
|
||||||
|
@param[in] thd
|
||||||
|
@param[in] event_subtype Type of general audit event.
|
||||||
|
@param[in] error_code Error code
|
||||||
|
@param[in] msg Message
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
void mysql_audit_general(THD *thd, uint event_subtype,
|
||||||
|
int error_code, const char *msg)
|
||||||
|
{
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
if (mysql_global_audit_mask[0] & MYSQL_AUDIT_GENERAL_CLASSMASK)
|
||||||
|
{
|
||||||
|
time_t time= my_time(0);
|
||||||
|
uint msglen= msg ? strlen(msg) : 0;
|
||||||
|
const char *query, *user;
|
||||||
|
uint querylen, userlen;
|
||||||
|
char user_buff[MAX_USER_HOST_SIZE];
|
||||||
|
CHARSET_INFO *clientcs;
|
||||||
|
ha_rows rows;
|
||||||
|
|
||||||
|
if (thd)
|
||||||
|
{
|
||||||
|
query= thd->query();
|
||||||
|
querylen= thd->query_length();
|
||||||
|
user= user_buff;
|
||||||
|
userlen= make_user_name(thd, user_buff);
|
||||||
|
clientcs= thd->variables.character_set_client;
|
||||||
|
rows= thd->warning_info->current_row_for_warning();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
query= user= 0;
|
||||||
|
querylen= userlen= 0;
|
||||||
|
clientcs= global_system_variables.character_set_client;
|
||||||
|
rows= 0;
|
||||||
|
}
|
||||||
|
|
||||||
mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, event_subtype,
|
mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, event_subtype,
|
||||||
error_code, time, user, userlen, cmd, cmdlen,
|
error_code, time, user, userlen, msg, msglen,
|
||||||
query, querylen, clientcs, rows);
|
query, querylen, clientcs, rows);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1485,13 +1485,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
close_thread_tables(thd);
|
close_thread_tables(thd);
|
||||||
|
|
||||||
if (!thd->is_error() && !thd->killed_errno())
|
if (!thd->is_error() && !thd->killed_errno())
|
||||||
{
|
mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_RESULT, 0, 0);
|
||||||
mysql_audit_general(thd,MYSQL_AUDIT_GENERAL_RESULT,0,my_time(0),
|
|
||||||
0,0,0,0,
|
|
||||||
thd->query(), thd->query_length(),
|
|
||||||
thd->variables.character_set_client,
|
|
||||||
thd->warning_info->current_row_for_warning());
|
|
||||||
}
|
|
||||||
|
|
||||||
log_slow_statement(thd);
|
log_slow_statement(thd);
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ static void reap_plugins(void);
|
|||||||
|
|
||||||
|
|
||||||
/* declared in set_var.cc */
|
/* declared in set_var.cc */
|
||||||
extern sys_var *intern_find_sys_var(const char *str, uint length, bool no_error);
|
extern sys_var *intern_find_sys_var(const char *str, uint length);
|
||||||
extern bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
|
extern bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
|
||||||
const char *name, longlong val);
|
const char *name, longlong val);
|
||||||
|
|
||||||
@ -1014,6 +1014,9 @@ static int plugin_initialize(struct st_plugin_int *plugin)
|
|||||||
DBUG_ENTER("plugin_initialize");
|
DBUG_ENTER("plugin_initialize");
|
||||||
|
|
||||||
safe_mutex_assert_owner(&LOCK_plugin);
|
safe_mutex_assert_owner(&LOCK_plugin);
|
||||||
|
DBUG_ASSERT(plugin->state == PLUGIN_IS_UNINITIALIZED);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&LOCK_plugin);
|
||||||
if (plugin_type_initialize[plugin->plugin->type])
|
if (plugin_type_initialize[plugin->plugin->type])
|
||||||
{
|
{
|
||||||
if ((*plugin_type_initialize[plugin->plugin->type])(plugin))
|
if ((*plugin_type_initialize[plugin->plugin->type])(plugin))
|
||||||
@ -1033,6 +1036,8 @@ static int plugin_initialize(struct st_plugin_int *plugin)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&LOCK_plugin);
|
||||||
|
|
||||||
plugin->state= PLUGIN_IS_READY;
|
plugin->state= PLUGIN_IS_READY;
|
||||||
|
|
||||||
if (plugin->plugin->status_vars)
|
if (plugin->plugin->status_vars)
|
||||||
@ -1050,9 +1055,10 @@ static int plugin_initialize(struct st_plugin_int *plugin)
|
|||||||
{0, 0, SHOW_UNDEF}
|
{0, 0, SHOW_UNDEF}
|
||||||
};
|
};
|
||||||
if (add_status_vars(array)) // add_status_vars makes a copy
|
if (add_status_vars(array)) // add_status_vars makes a copy
|
||||||
goto err;
|
goto err1;
|
||||||
#else
|
#else
|
||||||
add_status_vars(plugin->plugin->status_vars); // add_status_vars makes a copy
|
if (add_status_vars(plugin->plugin->status_vars))
|
||||||
|
goto err1;
|
||||||
#endif /* FIX_LATER */
|
#endif /* FIX_LATER */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1074,6 +1080,8 @@ static int plugin_initialize(struct st_plugin_int *plugin)
|
|||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
err:
|
err:
|
||||||
|
pthread_mutex_lock(&LOCK_plugin);
|
||||||
|
err1:
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1686,7 +1694,6 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(tmp->state == PLUGIN_IS_UNINITIALIZED);
|
|
||||||
if (plugin_initialize(tmp))
|
if (plugin_initialize(tmp))
|
||||||
{
|
{
|
||||||
my_error(ER_CANT_INITIALIZE_UDF, MYF(0), name->str,
|
my_error(ER_CANT_INITIALIZE_UDF, MYF(0), name->str,
|
||||||
@ -2164,7 +2171,7 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length)
|
|||||||
|
|
||||||
pthread_mutex_lock(&LOCK_plugin);
|
pthread_mutex_lock(&LOCK_plugin);
|
||||||
rw_rdlock(&LOCK_system_variables_hash);
|
rw_rdlock(&LOCK_system_variables_hash);
|
||||||
if ((var= intern_find_sys_var(str, length, false)) &&
|
if ((var= intern_find_sys_var(str, length)) &&
|
||||||
(pi= var->cast_pluginvar()))
|
(pi= var->cast_pluginvar()))
|
||||||
{
|
{
|
||||||
rw_unlock(&LOCK_system_variables_hash);
|
rw_unlock(&LOCK_system_variables_hash);
|
||||||
@ -2183,11 +2190,7 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length)
|
|||||||
rw_unlock(&LOCK_system_variables_hash);
|
rw_unlock(&LOCK_system_variables_hash);
|
||||||
pthread_mutex_unlock(&LOCK_plugin);
|
pthread_mutex_unlock(&LOCK_plugin);
|
||||||
|
|
||||||
/*
|
if (!var)
|
||||||
If the variable exists but the plugin it is associated with is not ready
|
|
||||||
then the intern_plugin_lock did not raise an error, so we do it here.
|
|
||||||
*/
|
|
||||||
if (pi && !var)
|
|
||||||
my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
|
my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
|
||||||
DBUG_RETURN(var);
|
DBUG_RETURN(var);
|
||||||
}
|
}
|
||||||
@ -2390,7 +2393,7 @@ static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
|
|||||||
st_bookmark *v= (st_bookmark*) my_hash_element(&bookmark_hash,idx);
|
st_bookmark *v= (st_bookmark*) my_hash_element(&bookmark_hash,idx);
|
||||||
|
|
||||||
if (v->version <= thd->variables.dynamic_variables_version ||
|
if (v->version <= thd->variables.dynamic_variables_version ||
|
||||||
!(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
|
!(var= intern_find_sys_var(v->key + 1, v->name_len)) ||
|
||||||
!(pi= var->cast_pluginvar()) ||
|
!(pi= var->cast_pluginvar()) ||
|
||||||
v->key[0] != (pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
|
v->key[0] != (pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
|
||||||
continue;
|
continue;
|
||||||
@ -2483,7 +2486,7 @@ static void cleanup_variables(THD *thd, struct system_variables *vars)
|
|||||||
{
|
{
|
||||||
v= (st_bookmark*) my_hash_element(&bookmark_hash, idx);
|
v= (st_bookmark*) my_hash_element(&bookmark_hash, idx);
|
||||||
if (v->version > vars->dynamic_variables_version ||
|
if (v->version > vars->dynamic_variables_version ||
|
||||||
!(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
|
!(var= intern_find_sys_var(v->key + 1, v->name_len)) ||
|
||||||
!(pivar= var->cast_pluginvar()) ||
|
!(pivar= var->cast_pluginvar()) ||
|
||||||
v->key[0] != (pivar->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
|
v->key[0] != (pivar->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
|
||||||
continue;
|
continue;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user