diff options
author | Sergey Vojtovich <svoj@sun.com> | 2009-12-16 15:56:36 +0400 |
---|---|---|
committer | Sergey Vojtovich <svoj@sun.com> | 2009-12-16 15:56:36 +0400 |
commit | 9130563708cbdbb488e5361af79eb9f4b9dab0ea (patch) | |
tree | 8df7485477b00a145ea370f2c5fa7822e249b010 /sql | |
parent | 45f2e0a7aad762af94eedd70b6fc0b91ae8e3376 (diff) | |
download | mariadb-git-9130563708cbdbb488e5361af79eb9f4b9dab0ea.tar.gz |
Backport from 6.0-codebase.
Bug #36098 Audit plugin (wl 3771) feature disabled in 6.0
avoid recusrive locking of LOCK_plugin
include/mysql/plugin_audit.h:
fix incorrect version
sql/log.cc:
move the common code to a shared header
sql/mysqld.cc:
restore the deleted functionality
sql/set_var.cc:
remove unused parameter
sql/sql_audit.h:
two inline convenience functions
sql/sql_parse.cc:
use a simplified convenience call
sql/sql_plugin.cc:
unlock LOCK_plugin for plugin->init() call, add missing OOM check,
issue "unknown variable" error in find_sys_var, not down the stack
Diffstat (limited to 'sql')
-rw-r--r-- | sql/log.cc | 20 | ||||
-rw-r--r-- | sql/mysqld.cc | 9 | ||||
-rw-r--r-- | sql/set_var.cc | 6 | ||||
-rw-r--r-- | sql/sql_audit.h | 87 | ||||
-rw-r--r-- | sql/sql_parse.cc | 8 | ||||
-rw-r--r-- | sql/sql_plugin.cc | 27 |
6 files changed, 95 insertions, 62 deletions
diff --git a/sql/log.cc b/sql/log.cc index ce309a0d1b2..267ca90db29 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -43,7 +43,6 @@ /* max size of the log message */ #define MAX_LOG_BUFFER_SIZE 1024 -#define MAX_USER_HOST_SIZE 512 #define MAX_TIME_SIZE 32 #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; Log_event_handler **current_handler= general_log_handler_list; char user_host_buff[MAX_USER_HOST_SIZE + 1]; - Security_context *sctx= thd->security_ctx; uint user_host_len= 0; time_t current_time; @@ -1081,21 +1079,15 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command, unlock(); return 0; } - user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE, - sctx->priv_user ? sctx->priv_user : "", "[", - sctx->user ? sctx->user : "", "] @ ", - sctx->host ? sctx->host : "", " [", - sctx->ip ? sctx->ip : "", "]", NullS) - - user_host_buff; + user_host_len= make_user_name(thd, user_host_buff); current_time= my_time(0); - mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_LOG, 0, current_time, - user_host_buff, user_host_len, - command_name[(uint) command].str, - command_name[(uint) command].length, - query, query_length, - thd->variables.character_set_client,0); + mysql_audit_general_log(thd, current_time, + user_host_buff, user_host_len, + command_name[(uint) command].str, + command_name[(uint) command].length, + query, query_length); while (*current_handler) error|= (*current_handler++)-> diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6803e0ef8a9..860dc0389d0 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2923,15 +2923,10 @@ void my_message_sql(uint error, const char *str, myf MyFlags) error= ER_UNKNOWN_ERROR; } + mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_ERROR, error, str); + 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) thd->is_fatal_error= 1; (void) thd->raise_condition(error, diff --git a/sql/set_var.cc b/sql/set_var.cc index 7a0325c3e68..86b1ef21032 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -3519,7 +3519,6 @@ void set_var_free() @param str Name of system variable to find @param length Length of variable. zero means that we should use strlen() on the variable - @param no_error Refuse to emit an error, even if one occurred. @retval pointer pointer to variable definitions @@ -3527,7 +3526,7 @@ void set_var_free() 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; @@ -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, (uchar*) str, length ? length : strlen(str)); - if (!(var || no_error)) - my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str); - return var; } diff --git a/sql/sql_audit.h b/sql/sql_audit.h index 155211e7ba5..c25011d0d59 100644 --- a/sql/sql_audit.h +++ b/sql/sql_audit.h @@ -34,18 +34,21 @@ extern void mysql_audit_notify(THD *thd, uint event_class, uint event_subtype, ...); 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. - event_subtype should be set to one of: - MYSQL_AUDIT_GENERAL_LOG - MYSQL_AUDIT_GENERAL_ERROR - MYSQL_AUDIT_GENERAL_RESULT + Call audit plugins of GENERAL audit class, MYSQL_AUDIT_GENERAL_LOG subtype. @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] user User name @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] query Query string @param[in] querylen Query string length - @param[in] clientcs Charset of query string - @param[in] rows Number of affected rows */ static inline +void mysql_audit_general_log(THD *thd, time_t time, + const char *user, uint userlen, + const char *cmd, uint cmdlen, + const char *query, uint querylen) +{ +#ifndef EMBEDDED_LIBRARY + 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, time_t time, - const char *user, uint userlen, - const char *cmd, uint cmdlen, - const char *query, uint querylen, - CHARSET_INFO *clientcs, - ha_rows rows) + 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, - error_code, time, user, userlen, cmd, cmdlen, + error_code, time, user, userlen, msg, msglen, query, querylen, clientcs, rows); + } #endif } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9328b29f182..eeaefde6588 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1485,13 +1485,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, close_thread_tables(thd); if (!thd->is_error() && !thd->killed_errno()) - { - 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()); - } + mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_RESULT, 0, 0); log_slow_statement(thd); diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index bcaeb452894..9e8b8785d5a 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -229,7 +229,7 @@ static void reap_plugins(void); /* 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, const char *name, longlong val); @@ -1014,6 +1014,9 @@ static int plugin_initialize(struct st_plugin_int *plugin) DBUG_ENTER("plugin_initialize"); 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])(plugin)) @@ -1033,6 +1036,8 @@ static int plugin_initialize(struct st_plugin_int *plugin) } } + pthread_mutex_lock(&LOCK_plugin); + plugin->state= PLUGIN_IS_READY; if (plugin->plugin->status_vars) @@ -1050,9 +1055,10 @@ static int plugin_initialize(struct st_plugin_int *plugin) {0, 0, SHOW_UNDEF} }; if (add_status_vars(array)) // add_status_vars makes a copy - goto err; + goto err1; #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 */ } @@ -1074,6 +1080,8 @@ static int plugin_initialize(struct st_plugin_int *plugin) DBUG_RETURN(0); err: + pthread_mutex_lock(&LOCK_plugin); +err1: DBUG_RETURN(1); } @@ -1686,7 +1694,6 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl } else { - DBUG_ASSERT(tmp->state == PLUGIN_IS_UNINITIALIZED); if (plugin_initialize(tmp)) { 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); 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())) { 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); pthread_mutex_unlock(&LOCK_plugin); - /* - 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) + if (!var) my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str); 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); 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()) || v->key[0] != (pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK)) continue; @@ -2483,7 +2486,7 @@ static void cleanup_variables(THD *thd, struct system_variables *vars) { v= (st_bookmark*) my_hash_element(&bookmark_hash, idx); 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()) || v->key[0] != (pivar->plugin_var->flags & PLUGIN_VAR_TYPEMASK)) continue; |