WL#7254: Audit log API extension
This worklog to implements some changes to the Audit log API.
User Documentation
Contents |
Functional Requirements - Audit API
AA-FR-1 Extend Audit API to support variety of auditing areas such as:
- AA-FR-1-1 Connectivity
- AA-FR-1-2 Privilege (authorization, grant check)
- AA-FR-1-3 Table row access (update, insert, delete)
- AA-FR-1-4 SQL query execution (sql parse, start, end)
- AA-FR-1-5 RPC command execution (start, end)
- AA-FR-1-6 Generic logging
- AA-FR-1-7 Server initialization and shutdown
- AA-FR-1-8 Global variable access
- AA-FR-1-9 Stored program execution
AA-FR-2 Extend the plugin configuration that allows the plugin to subscribe to specific events of the class.
AA-FR-3 Extend the Audit API that the plugin handling mechanism could abort further execution the of current flow.
- AA-FR-3-1 Aborted execution breaks with the general error code/message. The plugin abort with custom code/message.
Functional Requirements - Security Context Service
SC-FR-1 Expose the Security Context as a Plugin Service.
Non-Functional Requirements - Audit API
AA-NFR-1 Decompose heavy event objects into smaller, context specific ones.
AA-NFR-2 Events should carry only data required within the given context.
AA-NFR-3 Event objects should minimize utilization of the intermediate structures that exist only during event signalling.
AA-NFR-4 Changes, extensions must not influence implementation of the existing plugins. Only minimal adjustments are allowed that applies structure extensions or minor changes.
AA-NFR-5 Guarantee proper versioning of the plugin in order to prevent incompatible (older) plugins from loading.
Non-Functional Requirements - Security Context Service
SC-NFR-1 Security Context exposed as a Plugin Service must not be sensitive to the interface changes of the Security Context.
Contents |
New event classes
We will have the following new audit events (in addition to the connection events and the statement events we have now):
1. Privilege check class with the following events:
- per-user grant check - database grant check - table grant check - column grant check - procedure grant check - proxy grant check
We will be passing object name, connection id, command id, query id for these
2. Table row access class with the following events:
- row updated - row inserted - row deleted
We will be passing table name, connection id, command id, query id, pre-image (?), post-image(?)
3. We will have a new SQL query class with the following events:
- query start - query post-parse-and-name-resolution-pre-execution - query row send - query status send
We will be passing connection id, command id, query id, SQL statement text
4. We will have the following new connection event:
- post-connection pre-authentication
We will be passing connection id, host/ip to this
5. We will create a "command class" that will have the following events:
- command start - command end
We will be passing connection id, command id, status to this
6. We will create a new "server log" class with the following events:
- log event
We will be passing event log level, event text to this
7. We will create a new "server startup" class with the following events:
- server startup
We will be passing startup parameters to this.
8. We will create a new "server shutdown" class with the following events:
- server shutdown
We will be passing shutdown reason to this
9. We will create a new "global variable" class with the following events:
- set - read
We will be passing connection id, command id, query id, variable name, variable value to this
10. We will create a new "stored program" class with the following events:
- execute
11. We will mark the "general" event class as deprecated (to be removed in 5.8)
Note that all of the strings that don't have a designated character set will be expected to be in the system character set.
How filtering works
Event filtering will be done on two stages. First the server will do basic filtering over the event classes. Next the plugin(s) may do advanced filtering over the data they receive as arguments to the events and as results of calling plugin services. Plugins may decide to do stateful filtering, e.g. have outer events (e.g. query events) filtered on the data for inner events (e.g. individual table access).
Filtering done on Server Side
For each event the server will filter only the audit plugins that are interested into a particular event class and a particular event ID mask (!)
Each of the events will be sent out to the plugin
Filtering done in plugins. An example.
This section is informational only and serves to explain the design of the APIs for this worklog ! Plugins may implement other schemes as well. Or none at all
The plugin will maintain a boolean session variable called "log events". Each of the events will be able to turn this variable on or off based on filtering rules for that event.
Events will not be logged if that variable is off. Events will be logged otherwise.
Since the events are nested (i.e. we first get a connection event, then a command (RPC) event, then a SQL query start event, then several grants check events, then a sql query-post-parse event, then several table row access events, then a query row send event etc) the filtering checks will happen only at the relevant level (i.e. we won't be checking user account names for each of the SQL execution events, but instead will turn off the variable at the connect event).
We can have more per-session variables that we can use to pass down data from the "outer" events like e.g. the user name, host name etc.
In this way each of the events can concentrate only on the data it adds and re-use the data from the other events.
Changes to the audit API hooks signature
We will ensure that all audit API hooks support the plugins returning an error condition that prevents further execution of the audited action.
Changes to server side plugin pickup
The server will filter the plugin sets on event classes and event masks. Plugins will declare what event classes and what events are they interested in receiving. The server will pre-filter the plugins for each larger unit of work (e.g. on session level) and will only not grab the plugin mutex again to search for plugins on each of the more frequent events.
New security context plugin service
This service will provide clean way of accessing and manipulating the security context of a thread (corresponding to the Security_context server class).
The design is using named attributes for the get/set methods (instead of the hard coded class functions in Security_context) so it's extendable even without breaking the API.
It also contains a function to do the same lookup as it's done at login time. Without the authentication of course.
Stretch goal: plugin service to expose the connection attributes
Depending on the time we will also try to provide a plugin service to allow read-only access to the connection attributes.
The Audit API changes
To allow plugin to express interest not in the class of events but in particular events we need to make the event mask more granular. In the following approach each event correspond to a separate bit in the event mask.
#define MYSQL_AUDIT_GENERAL_CLASS 0 #define MYSQL_AUDIT_GENERAL_LOG MYSQL_AUDIT_GENERAL_CLASS + 0 #define MYSQL_AUDIT_GENERAL_ERROR MYSQL_AUDIT_GENERAL_CLASS + 1 #define MYSQL_AUDIT_GENERAL_RESULT MYSQL_AUDIT_GENERAL_CLASS + 2 #define MYSQL_AUDIT_GENERAL_STATUS MYSQL_AUDIT_GENERAL_CLASS + 3 #define MYSQL_AUDIT_GENERAL_CLASS_NUMBER_OF_EVENTS 4
Server Startup
Server startup event is signalled after successful initialization of the internal components (init_server_components() function). If the initialization of the components fails, the event is not signalled and MYSQL_AUDIT_SERVER_SHUTDOWN_SHUTDOWN event is signalled.
The event handler can return non zero value to initiate the server shutdown process. MYSQL_AUDIT_SERVER_SHUTDOWN_SHUTDOWN event is sent as a result of the forced shutdown.
MYSQL_AUDIT_SERVER_STARTUP_STARTUP is a first event signalled by the system after successful initialization.
Events
/** Events for MYSQL_AUDIT_SERVER_STARTUP_CLASS event class. */ typedef enum { /** Occurs after all subsystem are initialized during system start. */ MYSQL_AUDIT_SERVER_STARTUP_STARTUP = 0 } mysql_event_server_startup_subclass_t;
Structure
/** Event for MYSQL_AUDIT_SERVER_STARTUP_CLASS event class. */ struct mysql_event_server_startup { /** Event subclass. */ mysql_event_server_startup_subclass_t event_subclass; /** Command line arguments. */ const char **argv; /** Command line arguments count. */ unsigned int argc; };
Structure Fields Usage
MYSQL_AUDIT_SERVER_STARTUP_[CLASS] | |||||
---|---|---|---|---|---|
name | type | STARTUP [0] | |||
event_subclass | mysql_event_server_startup_subclass_t | + | |||
MYSQL_AUDIT_SERVER_STARTUP_STARTUP event. | |||||
argv | const char ** | + | |||
Zero terminated string arguments as provided by the main() function. | |||||
argc | unsigned int | + | |||
Argument count as provided by the main() function. |
Server Shutdown
Server shutdown event signals initiation of the server shutdown process. The event appears on failure at the server startup with appropriate exit_code and shutdown reason fields filled.
The event also appears, when the server shutdown request is made. Value of the exit_code is 0 in such case and the reason is set to "Shuting down".
Events
/** Events for MYSQL_AUDIT_SERVER_SHUTDOWN_CLASS event class. */ typedef enum { /** Occurs when global variable is set. */ MYSQL_AUDIT_SERVER_SHUTDOWN_SHUTDOWN = 0 } mysql_event_server_shutdown_subclass_t;
Structure
struct mysql_event_server_shutdown { /** Shutdown event. */ mysql_event_server_shutdown_subclass_t event_subclass; /** Exit code associated with the shutdown event. */ int exit_code; /** Shutdown reason message. */ MYSQL_LEX_CSTRING reason; };
Structure Fields Usage
MYSQL_AUDIT_SERVER_SHUTDOWN_[CLASS] | |||||
---|---|---|---|---|---|
name | type | SHUTDOWN [0] | |||
event_subclass | unsigned int | + | |||
MYSQL_AUDIT_SERVER_SHUTDOWN_SHUTDOWN event. | |||||
exit_code | int | + | |||
Exit code associated with the shutdown. | |||||
reason | MYSQL_LEX_CSTRING | + | |||
Shutdown reason message. |
Connection
This section describes connection and authentication related events:
- MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE is a first event after the client connects to the server. It carries only host and IP information of the client's host. The event appears before the authentication takes place.
- MYSQL_AUDIT_CONNECTION_CONNECT signals the result for the authentication process (status field; 0 - succeeded).
- MYSQL_AUDIT_CONNECTION_CHANGE_USER event notifies about the authentication related to the user change command. This event is similar to the MYSQL_AUDIT_CONNECTION_CONNECT, but the network connection remains the same.
- MYSQL_AUDIT_CONNECTION_DISCONNECT notifies that the connection with the client ends. status field carries status associated with the event.
Note. Authentication process also involves initialization of the connection to use the specified database. Initial database value is specified in the database field. Database access audit should be done in the MYSQL_AUDIT_CONNECTION_CONNECT or the MYSQL_AUDIT_CONNECTION_CHANGE_USER events. MYSQL_AUDIT_AUTHORIZATION_DB is not involved into database initialization for this connection.
Events
/** Events for MYSQL_AUDIT_CONNECTION_CLASS event class */ typedef enum { /** occurs after authentication phase is completed. */ MYSQL_AUDIT_CONNECTION_CONNECT = 0, /** occurs after connection is terminated. */ MYSQL_AUDIT_CONNECTION_DISCONNECT = 1, /** occurs after COM_CHANGE_USER RPC is completed. */ MYSQL_AUDIT_CONNECTION_CHANGE_USER = 2, /** occurs before authentication. */ MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE = 3 } mysql_event_connection_subclass_t;
Structure
struct mysql_event_connection { mysql_event_connection_subclass_t event_subclass; int status; unsigned long connection_id; MYSQL_LEX_CSTRING user; MYSQL_LEX_CSTRING priv_user; MYSQL_LEX_CSTRING external_user; MYSQL_LEX_CSTRING proxy_user; MYSQL_LEX_CSTRING host; MYSQL_LEX_CSTRING ip; MYSQL_LEX_CSTRING database; };
Structure Fields Usage
MYSQL_AUDIT_CONNECTION_[CLASS] | |||||
---|---|---|---|---|---|
name | type | CONNECT [0] | DISCONNECT [1-] | CHANGE_USER [2] | PRE_AUTHENTICATE [3] |
event_subclass | mysql_event_connection_subclass_t | + | + | + | + |
Connection event. | |||||
status | int | + | + | + | |
Status. | |||||
connection_id | unsigned long | + | + | + | + |
Connection id. | |||||
user | MYSQL_LEX_CSTRING | + | + | + | |
User. | |||||
priv_user | MYSQL_LEX_CSTRING | + | + | + | |
Priv user. | |||||
external_user | MYSQL_LEX_CSTRING | + | + | + | |
External user. | |||||
proxy_user | MYSQL_LEX_CSTRING | + | + | + | |
Proxy user. | |||||
host | MYSQL_LEX_CSTRING | + | + | + | + |
Host. | |||||
ip | MYSQL_LEX_CSTRING | + | + | + | + |
IP. | |||||
database | MYSQL_LEX_CSTRING | + | + | + | |
Database. |
Command
Command event signals beginning and end of the executing command. Start event is signalled with the MYSQL_AUDIT_COMMAND_START event_subclass value, while end of the command is signalled with the MYSQL_AUDIT_COMMAND_END value.
Command event handler, which handle start event (MYSQL_AUDIT_COMMAND_START), can abort execution of the command, by returning a non zero value from the handler.
Some commands, such as client disconnect, cannot be aborted. Command handler return value does not take any effect.
Command | Can abort | Description |
---|---|---|
COM_SLEEP | No | Deprecated |
COM_QUIT | No | Disconnect client. |
COM_INIT_DB | Yes | |
COM_QUERY | Yes | |
COM_FIELD_LIST | Yes | |
COM_CREATE_DB | Yes | |
COM_DROP_DB | Yes | |
COM_REFRESH | Yes | |
COM_SHUTDOWN | Yes | |
COM_STATISTICS | Yes | |
COM_PROCESS_INFO | Yes | |
COM_CONNECT | No | Not possible at this stage. |
COM_PROCESS_KILL | Yes | |
COM_DEBUG | Yes | |
COM_PING | No | |
COM_TIME | No | Deprecated |
COM_DELAYED_INSERT | No | Deprecated |
COM_CHANGE_USER | Yes | |
COM_BINLOG_DUMP | Yes | |
COM_TABLE_DUMP | Yes | |
COM_CONNECT_OUT | Yes | |
COM_REGISTER_SLAVE | Yes | |
COM_STMT_PREPARE | Yes | |
COM_STMT_EXECUTE | Yes | |
COM_STMT_SEND_LONG_DATA | Yes | |
COM_STMT_CLOSE | Yes | |
COM_STMT_RESET | Yes | |
COM_SET_OPTION | Yes | |
COM_STMT_FETCH | Yes | |
COM_DAEMON | Yes | |
COM_BINLOG_DUMP_GTID | Yes | |
COM_RESET_CONNECTION | Yes |
Events
typedef enum { MYSQL_AUDIT_COMMAND_START = 0, MYSQL_AUDIT_COMMAND_END = 1 } mysql_event_command_subclass_t;
Structure
struct mysql_event_command { mysql_event_command_subclass_t event_subclass; int status; unsigned long connection_id; enum_server_command_t command_id; };
Structure Fields Usage
MYSQL_AUDIT_COMMAND_[CLASS] | |||||
---|---|---|---|---|---|
name | type | START [0] | END [1-] | ||
event_subclass | unsigned int | + | + | ||
status | int | Always 0 | + | ||
Status value associated with the event. | |||||
connection_id | unsigned int | + | + | ||
Connection id associated with the event. | |||||
command_id | enum_server_command | + | + | ||
Command id associated with the event. |
Query
Query notification event.
Event
typedef enum { /** Query start event. */ MYSQL_AUDIT_QUERY_START = 0, /** Nested query start event. */ MYSQL_AUDIT_QUERY_NESTED_START = 1, /** Query post parse event. */ MYSQL_AUDIT_QUERY_POST_PARSE = 2, /** Not implemented yet. */ /*MYSQL_AUDIT_QUERY_ROW_SEND = 3,*/ /** Query status end event. */ MYSQL_AUDIT_QUERY_STATUS_END = 4, /** Nested query status end event. */ MYSQL_AUDIT_QUERY_NESTED_STATUS_END = 5 } mysql_event_query_subclass_t;
Structure
struct mysql_event_query { mysql_event_query_subclass_t event_subclass; int status; unsigned long connection_id; enum_sql_command_t sql_command_id; MYSQL_LEX_CSTRING query; const struct charset_info_st *query_charset; };
Structure Fields Usage
MYSQL_AUDIT_QUERY_[CLASS] | ||||||
---|---|---|---|---|---|---|
name | type | START [0] | NESTED_START [1] | POST_PARSE [2] | STATUS_END [3] | NESTED_STATUS_END [4] |
event_subclass | mysql_event_table_row_access_subclass_t | + | + | + | + | + |
Query event subclass value. | ||||||
connection_id | unsigned int | + | + | + | + | + |
Connection id associated with the event. | ||||||
sql_command_id | enum_sql_command_t | + | + | + | + | + |
SQL command id. | ||||||
query | MYSQL_LEX_CSTRING | + | + | + | + | + |
SQL query. | ||||||
query_charset | const CHARSET_INFO* | + | + | + | + | + |
SQL query charset info. |
Table Access
Table Access event is triggered when the query attempts to perform read, update, insert or delete operation on a given table(s). The event specifies table name and a related database name.
The event is always triggered as a subevent of the MYSQL_AUDIT_COMMAND_CLASS and the MYSQL_AUDIT_SQL_QUERY_CLASS class events.
The MYSQL_AUDIT_TABLE_ACCESS_READ event can be triggered multiple times for a single query, because multiple tables can participate in the operation, e.g.:
USE my_database; SELECT t1.a, t2.a FROM t1, t2;
The MYSQL_AUDIT_TABLE_ACCESS_READ event for the above select statement will be called twice with 'my_database.t1' table (first event) and 'my_database.t2' (second event).
MYSQL_AUDIT_TABLE_ACCESS_INSERT event can be followed by MYSQL_AUDIT_TABLE_ACCESS_READ events in case of the query that performs both access types, e.g.:
INSERT INTO table_1 SELECT * FROM table_2;
Events
/** Events for MYSQL_AUDIT_TABLE_ACCES_CLASS event class */ typedef enum { /** occurs when table data are read. */ MYSQL_AUDIT_TABLE_ACCESS_READ = 0, /** occurs when table data are inserted. */ MYSQL_AUDIT_TABLE_ACCESS_INSERT = 1, /** occurs when table data are updated. */ MYSQL_AUDIT_TABLE_ACCESS_UPDATE = 2, /** occurs when table data are deleted. */ MYSQL_AUDIT_TABLE_ACCESS_DELETE = 3 } mysql_event_table_access_subclass_t;
Structure
struct mysql_event_table_access { mysql_event_table_access_subclass_t event_subclass; int status; unsigned long connection_id; enum_sql_command_t sql_command_id; MYSQL_LEX_CSTRING query; const CHARSET_INFO *query_charset; MYSQL_LEX_CSTRING table_database; MYSQL_LEX_CSTRING table_name; };
Structure Fields Usage
MYSQL_AUDIT_TABLE_ACCESS_[CLASS] | |||||
---|---|---|---|---|---|
name | type | READ [0] | INSERT [1] | UPDATE [2] | DELETE [3] |
event_subclass | mysql_event_table_access_subclass_t | + | + | + | + |
Table access subclass value (read, insert, update or delete). | |||||
connection_id | unsigned int | + | + | + | + |
Connection id associated with the event. | |||||
sql_command_id | enum_sql_command_t | + | + | + | + |
SQL command id. | |||||
query | MYSQL_LEX_CSTRING | + | + | + | + |
SQL query. | |||||
query_charset | const CHARSET_INFO* | + | + | + | + |
SQL query charset info. | |||||
table_database | MYSQL_LEX_CSTRING | + | + | + | + |
Database name associated with the event. | |||||
table_name | MYSQL_LEX_CSTRING | + | + | + | + |
Table name associated with the event. |
Authorization Check
Authorization event signals the access to the database object, which is specified by the event_subclass variable.
Authorization Events
typedef enum { MYSQL_AUDIT_AUTHORIZATION_USER = 0, // TODO: Move it to User Auth Check MYSQL_AUDIT_AUTHORIZATION_DB = 1, MYSQL_AUDIT_AUTHORIZATION_TABLE = 2, MYSQL_AUDIT_AUTHORIZATION_COLUMN = 3, MYSQL_AUDIT_AUTHORIZATION_PROCEDURE = 4, MYSQL_AUDIT_AUTHORIZATION_PROXY = 5 // TODO: Move it to User Auth Check } mysql_event_authorization_subclass_t;
Event Structure
struct mysql_event_authorization { mysql_event_authorization_subclass_t event_subclass; unsigned int connection_id; enum_sql_command_t sql_command_id; MYSQL_LEX_CSTRING query; const struct charset_info_st *query_charset; MYSQL_LEX_CSTRING database; MYSQL_LEX_CSTRING table; MYSQL_LEX_CSTRING object; };
Structure Fields Usage
MYSQL_AUDIT_AUTHORIZATION_[CLASS] | |||||
---|---|---|---|---|---|
name | type | DB [0] | TABLE [1] | COLUMN [2] | PROCEDURE [3] |
event_subclass | mysql_event_authorization_subclass_t | + | + | + | + |
Authorization object subclass value. | |||||
connection_id | unsigned int | + | + | + | + |
Connection id associated with the event. | |||||
sql_command_id | enum_sql_command_t | + | + | + | + |
Sql command id value. | |||||
query | MYSQL_LEX_CSTRING | + | + | + | + |
SQL query. | |||||
query_charset | const struct charset_info_st* | + | + | + | + |
SQL query charset. | |||||
database | MYSQL_LEX_CSTRING | + | + | + | + |
Database name associated with the event. | |||||
table | MYSQL_LEX_CSTRING | + | + | ||
Table name associated with the event. | |||||
object | MYSQL_LEX_CSTRING | + | + | ||
Object (column or procedure) name associated with the event. |
Log
#define MYSQL_AUDIT_SERVER_LOG_CLASS MYSQL_AUDIT_COMMAND_CLASS \ + MYSQL_AUDIT_COMMAND_NUMBER_OF_EVENTS #define MYSQL_AUDIT_SERVER_LOG MYSQL_AUDIT_SERVER_LOG_CLASS + 0 #define MYSQL_AUDIT_SERVER_LOG_NUMBER_OF_EVENTS 1 struct mysql_event_server_log { unsigned int event_subclass; unsigned int level; const char* text; unsigned int text_length; };
Global Variable
Global variable event signals access to the global variable. Global variable read is notified with the MYSQL_AUDIT_GLOBAL_VARIABLE_GET event and the write operation is notified with the MYSQL_AUDIT_GLOBAL_VARIABLE_SET event. Global variables can be accessed in the following ways:
Get (MYSQL_AUDIT_GLOBAL_VARIABLE_GET):
- SELECT @@GLOBAL.sql_mode; - SHOW GLOBAL VARIABLES; - SHOW GLOBAL VARIABLES LIKE 'xxx';
Set (MYSQL_AUDIT_GLOBAL_VARIABLE_SET):
- SET @@GLOBAL.sql_mode = '';
Events
/** Events for MYSQL_AUDIT_GLOBAL_VARIABLE_CLASS event class. */ typedef enum { /** Occurs when global variable is retrieved. */ MYSQL_AUDIT_GLOBAL_VARIABLE_GET = 0, /** Occurs when global variable is set. */ MYSQL_AUDIT_GLOBAL_VARIABLE_SET = 1 } mysql_event_global_variable_subclass_t;
Structure
struct mysql_event_global_variable { mysql_event_global_variable_subclass_t event_subclass; unsigned int connection_id; enum_sql_command_t sql_command_id; MYSQL_LEX_CSTRING query; const struct charset_info_st *query_charset; MYSQL_LEX_CSTRING variable_name; MYSQL_LEX_CSTRING variable_value; };
Structure Fields Usage
MYSQL_AUDIT_GLOBAL_VARIABLE_[CLASS] | |||
---|---|---|---|
name | type | GET [0] | SET [1] |
event_subclass | mysql_event_global_variable_subclass_t | + | + |
Global variable access subclass value (get, set). | |||
connection_id | unsigned int | + | + |
Connection id associated with the event. | |||
sql_command_id | enum_sql_command_t | + | + |
SQL command value. | |||
query | MYSQL_LEX_CSTRING | + | + |
SQL query. | |||
query_charset | const struct charset_info_st* | + | + |
SQL query charset. | |||
variable_name | MYSQL_LEX_CSTRING | + | + |
Variable name. | |||
variable_value | MYSQL_LEX_CSTRING | + | + |
Variable value. |
Stored Program
An event signalling execution of the stored procedure or function using CALL syntax.
Stored Program Event
typedef enum { MYSQL_AUDIT_STORED_PROGRAM_EXECUTE = 0 } mysql_event_stored_program_subclass_t;
Event Structure
struct mysql_event_stored_program { mysql_event_stored_program_subclass_t event_subclass; unsigned long connection_id; enum_sql_command_t sql_command_id; MYSQL_LEX_CSTRING query; const struct charset_info_st *query_charset; MYSQL_LEX_CSTRING database; MYSQL_LEX_CSTRING name; MYSQL_LEX_CSTRING parameters; };
Event structure fields
MYSQL_AUDIT_STORED_PROGRAM_[CLASS] | ||
---|---|---|
name | type | EXECUTE [0] |
event_subclass | mysql_event_stored_program_subclass_t | + |
Authorization object subclass value. | ||
connection_id | unsigned int | + |
Connection id associated with the event. | ||
sql_command_id | enum_sql_command_t | + |
SQL command id. | ||
query | MYSQL_LEX_CSTRING | + |
SQL query. | ||
query_charset | const struct charset_info_st* | + |
SQL query charset info. | ||
database | MYSQL_LEX_CSTRING | + |
Database name associated with the event. | ||
name | MYSQL_LEX_CSTRING | + |
Table name associated with the event. | ||
parameters | MYSQL_LEX_CSTRING | + |
Procedure or function parameters definition. |
Audit API Error Handling
The Audit API Event Handling routine can report error in two ways:
- Exit the Event Handling routine with the non zero value. MySQL server will abort current operation and the default error message will be logged:
ERROR HY000: Aborted by Audit API ('<event_subclass_value>';<nonzero_value_returned>).
e.g.:
ERROR HY000: Aborted by Audit API ('MYSQL_AUDIT_CONNECTION_CONNECT';100).
- Use my_message from within the Event Handling function. This allows to apply custom error code as well as the custom error message. All available error codes are defined in the errmsg-utf8.txt file.
my_message(ER_AUDIT_API_ABORT, "This user cannot update mysql.user table. Operation aborted.", MYF(0));
Returning nonzero value from the Error Handling function, when the my_message was called before, is not taken into consideration by the server. The error state has been already set by my_message function call, which has greater precedence over the returned value.
Server operation can be already in error state, when notifying an event. Error state cannot be overwritten by plugin. Plugin must perform check, whether the error state can be set with (is_error()) function call:
if (!thd->get_stmt_da()->is_error()) { my_message(ER_AUDIT_API_ABORT, "This user cannot update mysql.user table. Operation aborted.", MYF(0)); }
Note 1: Some notifications, such as MYSQL_AUDIT_CONNECTION_DISCONNECT, cannot be aborted. Returning a non zero value or reporting error using my_message does not take any effect.
Audit Events Hierarchy
/* Initialization of the server failed. */ MYSQL_AUDIT_SERVER_SHUTDOWN_SHUTDOWN (reason = "Aborting", exit_code = MYSQLD_ABORT_EXIT [1]) | MYSQL_AUDIT_SERVER_STARTUP_STARTUP (argv = <mysqld arguments>, argc = <mysqld argument count>) [ /* A user connecting. */ MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE (/* TODO */) MYSQL_AUDIT_CONNECTION_CONNECT (/* TODO */) [ /* Change user command. */ MYSQL_AUDIT_COMMAND_START (command_id = COM_CHANGE_USER) MYSQL_AUDIT_CONNECTION_CHANGE_USER (status = <status of the change user command>) MYSQL_AUDIT_COMMAND_END ] | [ /* Execute query. */ MYSQL_AUDIT_COMMAND_START(command_id = COM_QUERY) MYSQL_QUERY_POST_PARSE (/* TODO */) MYSQL_QUERY_START (/* TODO */) MYSQL_QUERY_STATUS_END (/* TODO */) MYSQL_AUDIT_COMMAND_END ] MYSQL_AUDIT_CONNECTION_DISCONNECT (/* TODO */ status = <disconnect code>) ] MYSQL_AUDIT_SERVER_SHUTDOWN_SHUTDOWN (reason = "Shutting down", exit_code = MYSQL_SUCCESS_EXIT [0])
The security context service
thd_get_security_context(thd, out_ctx)
Gets the security context for the thread.
@param[in] thd The thread to get the context from @param[out] out_ctx placeholder for the security context handle @retval true failure @retval false success
thd_set_security_context(thd, ctx)
Sets a new security context for the thread.
@param[in] thd The thread to set the context to @param[in] ctx The handle of the new security context @retval true failure @retval false success
security_context_create(out_ctx)
Creates a new security context and initializes it with the defaults (no access, no user etc)
@param[out] out_ctx placeholder for the newly created security context handle @retval true failure @retval false success
security_context_destroy(ctx)
Deallocates a security context.
@param[in] ctx The handle of the security context to destroy @retval true failure @retval false success
security_context_copy(ctx)
Duplicates a security context.
@param[in] ctx The handle of the security context to copy @param[out] out_ctx placeholder for the handle of the copied security context @retval true failure @retval false success
security_context_lookup(ctx, user, host, ip, db)
Looks up in the defined user accounts an account based on the user@host[ip] combo supplied and checks if the user has access to the database requested. The lookup is done in exactly the same way as at login time.
@param[in] ctx The handle of the security context to update @param[in] user The user name to look up @param[in] host The host name to look up @param[in] ip The ip of the incoming connection @param[in] db The database to check access to @retval true failure @retval false success
security_context_get_option(ctx, name, value)
Reads a named security context attribute and retuns its value. Currently defined names are:
user MYSQL_LEX_CSTRING * login user (a.k.a. the user's part of USER()) host MYSQL_LEX_CSTRING * login host (a.k.a. the host's part of USER()) ip MYSQL_LEX_CSTRING * login client ip host_or_ip MYSQL_LEX_CSTRING * host, if present, ip if not. priv_user MYSQL_LEX_CSTRING * authenticated user (a.k.a. the user's part of CURRENT_USER()) priv_host MYSQL_LEX_CSTRING * authenticated host (a.k.a. the host's part of CURRENT_USER()) proxy_user MYSQL_LEX_CSTRING * the proxy user used in authenticating privilege_super my_bool True if the user account has supper privilege
@param[in] ctx The handle of the security context to read from @param[in] name The option name to read @param[out] value The value of the option. Type depens on the name. @retval true failure @retval false success
security_context_set_option(ctx, name, value)
Sets a value for a named security context attribute Currently defined names are:
user MYSQL_LEX_CSTRING * login user (a.k.a. the user's part of USER()) host MYSQL_LEX_CSTRING * login host (a.k.a. the host's part of USER()) ip MYSQL_LEX_CSTRING * login client ip priv_user MYSQL_LEX_CSTRING * authenticated user (a.k.a. the user's part of CURRENT_USER()) priv_host MYSQL_LEX_CSTRING * authenticated host (a.k.a. the host's part of CURRENT_USER()) proxy_user MYSQL_LEX_CSTRING * the proxy user used in authenticating privilege_super my_bool True if the user account has supper privilege
@param[in] ctx The handle of the security context to set into @param[in] name The option name to set @param[in] value The value of the option. Type depens on the name. @retval true failure @retval false success