From: Sergey Vojtovich Date: December 14 2010 2:39pm Subject: bzr commit into mysql-trunk-bugfixing branch (sergey.vojtovich:3429) WL#5571 List-Archive: http://lists.mysql.com/commits/126778 Message-Id: <201012141431.oBEEVlLe012259@rcsinet13.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============8281545203822971515==" --===============8281545203822971515== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/svoj/mysql/server/mysql-trunk-bugfixing-push/ based on revid:bar@stripped 3429 Sergey Vojtovich 2010-12-14 [merge] Merge WL#5571 to trunk-bugfixing. modified: include/mysql/plugin_audit.h include/mysql/plugin_audit.h.pp sql/mysqld.cc sql/sql_audit.cc sql/sql_audit.h sql/sql_connect.cc sql/sql_parse.cc === modified file 'include/mysql/plugin_audit.h' --- a/include/mysql/plugin_audit.h 2010-04-15 09:05:17 +0000 +++ b/include/mysql/plugin_audit.h 2010-12-14 14:34:23 +0000 @@ -42,6 +42,8 @@ struct mysql_event LOG events occurs before emitting to the general query log. ERROR events occur before transmitting errors to the user. RESULT events occur after transmitting a resultset to the user. + STATUS events occur after transmitting a resultset or errors + to the user. */ #define MYSQL_AUDIT_GENERAL_CLASS 0 @@ -49,6 +51,7 @@ struct mysql_event #define MYSQL_AUDIT_GENERAL_LOG 0 #define MYSQL_AUDIT_GENERAL_ERROR 1 #define MYSQL_AUDIT_GENERAL_RESULT 2 +#define MYSQL_AUDIT_GENERAL_STATUS 3 struct mysql_event_general { @@ -68,6 +71,43 @@ struct mysql_event_general }; +/* + AUDIT CLASS : CONNECTION + + CONNECT occurs after authentication phase is completed. + DISCONNECT occurs after connection is terminated. + CHANGE_USER occurs after COM_CHANGE_USER RPC is completed. +*/ + +#define MYSQL_AUDIT_CONNECTION_CLASS 1 +#define MYSQL_AUDIT_CONNECTION_CLASSMASK (1 << MYSQL_AUDIT_CONNECTION_CLASS) +#define MYSQL_AUDIT_CONNECTION_CONNECT 0 +#define MYSQL_AUDIT_CONNECTION_DISCONNECT 1 +#define MYSQL_AUDIT_CONNECTION_CHANGE_USER 2 + +struct mysql_event_connection +{ + unsigned int event_class; + unsigned int event_subclass; + int status; + unsigned long thread_id; + const char *user; + unsigned int user_length; + const char *priv_user; + unsigned int priv_user_length; + const char *external_user; + unsigned int external_user_length; + const char *proxy_user; + unsigned int proxy_user_length; + const char *host; + unsigned int host_length; + const char *ip; + unsigned int ip_length; + const char *database; + unsigned int database_length; +}; + + /************************************************************************* Here we define the descriptor structure, that is referred from st_mysql_plugin. === modified file 'include/mysql/plugin_audit.h.pp' --- a/include/mysql/plugin_audit.h.pp 2010-08-30 14:07:40 +0000 +++ b/include/mysql/plugin_audit.h.pp 2010-12-14 14:34:23 +0000 @@ -208,6 +208,27 @@ struct mysql_event_general unsigned long long general_time; unsigned long long general_rows; }; +struct mysql_event_connection +{ + unsigned int event_class; + unsigned int event_subclass; + int status; + unsigned long thread_id; + const char *user; + unsigned int user_length; + const char *priv_user; + unsigned int priv_user_length; + const char *external_user; + unsigned int external_user_length; + const char *proxy_user; + unsigned int proxy_user_length; + const char *host; + unsigned int host_length; + const char *ip; + unsigned int ip_length; + const char *database; + unsigned int database_length; +}; struct st_mysql_audit { int interface_version; === modified file 'sql/mysqld.cc' --- a/sql/mysqld.cc 2010-12-07 18:11:49 +0000 +++ b/sql/mysqld.cc 2010-12-14 14:38:42 +0000 @@ -1993,6 +1993,7 @@ void close_connection(THD *thd, uint err { sleep(0); /* Workaround to avoid tailcall optimisation */ } + MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, errcode); DBUG_VOID_RETURN; } #endif /* EMBEDDED_LIBRARY */ === modified file 'sql/sql_audit.cc' --- a/sql/sql_audit.cc 2010-11-05 22:14:29 +0000 +++ b/sql/sql_audit.cc 2010-12-14 14:38:42 +0000 @@ -81,9 +81,34 @@ static void general_class_handler(THD *t } +static void connection_class_handler(THD *thd, uint event_subclass, va_list ap) +{ + mysql_event_connection event; + event.event_class= MYSQL_AUDIT_CONNECTION_CLASS; + event.event_subclass= event_subclass; + event.status= va_arg(ap, int); + event.thread_id= va_arg(ap, unsigned long); + event.user= va_arg(ap, const char *); + event.user_length= va_arg(ap, unsigned int); + event.priv_user= va_arg(ap, const char *); + event.priv_user_length= va_arg(ap, unsigned int); + event.external_user= va_arg(ap, const char *); + event.external_user_length= va_arg(ap, unsigned int); + event.proxy_user= va_arg(ap, const char *); + event.proxy_user_length= va_arg(ap, unsigned int); + event.host= va_arg(ap, const char *); + event.host_length= va_arg(ap, unsigned int); + event.ip= va_arg(ap, const char *); + event.ip_length= va_arg(ap, unsigned int); + event.database= va_arg(ap, const char *); + event.database_length= va_arg(ap, unsigned int); + event_class_dispatch(thd, (const mysql_event *) &event); +} + + static audit_handler_t audit_handlers[] = { - general_class_handler + general_class_handler, connection_class_handler }; static const uint audit_handlers_count= === modified file 'sql/sql_audit.h' --- a/sql/sql_audit.h 2010-11-18 14:39:28 +0000 +++ b/sql/sql_audit.h 2010-12-14 14:38:42 +0000 @@ -32,8 +32,12 @@ extern void mysql_audit_free_thd(THD *th extern void mysql_audit_acquire_plugins(THD *thd, uint event_class); +#ifndef EMBEDDED_LIBRARY extern void mysql_audit_notify(THD *thd, uint event_class, uint event_subtype, ...); +#else +#define mysql_audit_notify(...) +#endif extern void mysql_audit_release(THD *thd); #define MAX_USER_HOST_SIZE 512 @@ -84,6 +88,7 @@ void mysql_audit_general_log(THD *thd, t event_subtype should be set to one of: MYSQL_AUDIT_GENERAL_ERROR MYSQL_AUDIT_GENERAL_RESULT + MYSQL_AUDIT_GENERAL_STATUS @param[in] thd @param[in] event_subtype Type of general audit event. @@ -126,5 +131,41 @@ void mysql_audit_general(THD *thd, uint #endif } +#define MYSQL_AUDIT_NOTIFY_CONNECTION_CONNECT(thd) mysql_audit_notify(\ + (thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_CONNECT,\ + (thd)->stmt_da->is_error() ? (thd)->stmt_da->sql_errno() : 0,\ + (thd)->thread_id, (thd)->security_ctx->user,\ + (thd)->security_ctx->user ? strlen((thd)->security_ctx->user) : 0,\ + (thd)->security_ctx->priv_user, strlen((thd)->security_ctx->priv_user),\ + (thd)->security_ctx->external_user,\ + (thd)->security_ctx->external_user ?\ + strlen((thd)->security_ctx->external_user) : 0,\ + (thd)->security_ctx->proxy_user, strlen((thd)->security_ctx->proxy_user),\ + (thd)->security_ctx->host,\ + (thd)->security_ctx->host ? strlen((thd)->security_ctx->host) : 0,\ + (thd)->security_ctx->ip,\ + (thd)->security_ctx->ip ? strlen((thd)->security_ctx->ip) : 0,\ + (thd)->db, (thd)->db ? strlen((thd)->db) : 0) + +#define MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, errcode)\ + mysql_audit_notify(\ + (thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_DISCONNECT,\ + (errcode), (thd)->thread_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +#define MYSQL_AUDIT_NOTIFY_CONNECTION_CHANGE_USER(thd) mysql_audit_notify(\ + (thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_CHANGE_USER,\ + (thd)->stmt_da->is_error() ? (thd)->stmt_da->sql_errno() : 0,\ + (thd)->thread_id, (thd)->security_ctx->user,\ + (thd)->security_ctx->user ? strlen((thd)->security_ctx->user) : 0,\ + (thd)->security_ctx->priv_user, strlen((thd)->security_ctx->priv_user),\ + (thd)->security_ctx->external_user,\ + (thd)->security_ctx->external_user ?\ + strlen((thd)->security_ctx->external_user) : 0,\ + (thd)->security_ctx->proxy_user, strlen((thd)->security_ctx->proxy_user),\ + (thd)->security_ctx->host,\ + (thd)->security_ctx->host ? strlen((thd)->security_ctx->host) : 0,\ + (thd)->security_ctx->ip,\ + (thd)->security_ctx->ip ? strlen((thd)->security_ctx->ip) : 0,\ + (thd)->db, (thd)->db ? strlen((thd)->db) : 0) #endif /* SQL_AUDIT_INCLUDED */ === modified file 'sql/sql_connect.cc' --- a/sql/sql_connect.cc 2010-11-25 04:41:58 +0000 +++ b/sql/sql_connect.cc 2010-12-14 14:38:42 +0000 @@ -728,9 +728,12 @@ void do_handle_one_connection(THD *thd_a for (;;) { NET *net= &thd->net; + bool rc; lex_start(thd); - if (login_connection(thd)) + rc= login_connection(thd); + MYSQL_AUDIT_NOTIFY_CONNECTION_CONNECT(thd); + if (rc) goto end_thread; MYSQL_CONNECTION_START(thd->thread_id, thd->security_ctx->priv_user, === modified file 'sql/sql_parse.cc' --- a/sql/sql_parse.cc 2010-12-14 11:15:13 +0000 +++ b/sql/sql_parse.cc 2010-12-14 14:38:42 +0000 @@ -980,6 +980,7 @@ bool dispatch_command(enum enum_server_c #endif case COM_CHANGE_USER: { + bool rc; status_var_increment(thd->status_var.com_other); thd->change_user(); @@ -999,7 +1000,9 @@ bool dispatch_command(enum enum_server_c CHARSET_INFO *save_character_set_results= thd->variables.character_set_results; - if (acl_authenticate(thd, 0, packet_length)) + rc= acl_authenticate(thd, 0, packet_length); + MYSQL_AUDIT_NOTIFY_CONNECTION_CHANGE_USER(thd); + if (rc) { my_free(thd->security_ctx->user); *thd->security_ctx= save_security_ctx; @@ -1438,6 +1441,10 @@ bool dispatch_command(enum enum_server_c if (!thd->is_error() && !thd->killed_errno()) mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_RESULT, 0, 0); + mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_STATUS, + thd->stmt_da->is_error() ? thd->stmt_da->sql_errno() : 0, + command_name[command].str); + log_slow_statement(thd); thd_proc_info(thd, "cleaning up"); --===============8281545203822971515== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/sergey.vojtovich@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: sergey.vojtovich@stripped\ # g8ok0ubzzdvkgqlz # target_branch: file:///home/svoj/mysql/server/mysql-trunk-bugfixing-\ # push/ # testament_sha1: 9caaac4c0070a0b57393a81f363ab1e67a9dfc03 # timestamp: 2010-12-14 17:39:20 +0300 # source_branch: file:///home/svoj/mysql/server/mysql-5.5-bugteam-\ # push/ # base_revision_id: bar@stripped # # Begin bundle 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 LuSKcKEg/6TXMg== --===============8281545203822971515==--