WL#7254: Audit log API extension

Affects: Server-5.7   —   Status: Complete

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.

Contents


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