Commit 540f8521 authored by Sergey Vojtovich's avatar Sergey Vojtovich

Backport from 6.0-codebase.

WL#3771
  "Audit Plugin Interface"
  Implement new plug-in type - AUDIT
  New plug-in: audit_null
    simply increments counter for how many times it was called.

include/Makefile.am:
  wl3771
    add new headers to distribution
include/mysql/plugin.h:
  wl3771
    define new AUDIT plugin type
    Split out fulltext plugin type into its own header
include/mysql/plugin.h.pp:
  wl3771
    no real API change, just re-arranged some code
include/mysql/plugin_audit.h:
  wl3771
    pluggable audit interface
include/mysql/plugin_ftparser.h:
  wl3771
    Split out fulltext plugin type into its own header
libmysqld/CMakeLists.txt:
  wl3771
    add sql_audit.cc to build
libmysqld/Makefile.am:
  wl3771
    add sql_audit.cc to build
plugin/audit_null:
  wl3771
    an example plugin for testing pluggable audit interface
plugin/audit_null/Makefile.am:
  wl3771
    an example plugin for testing pluggable audit interface
plugin/audit_null/audit_null.c:
  wl3771
    an example plugin for testing pluggable audit interface
plugin/audit_null/plug.in:
  wl3771
    an example plugin for testing pluggable audit interface
sql/CMakeLists.txt:
  wl3771
    add sql_audit.cc to build
sql/Makefile.am:
  wl3771
    add sql_audit.cc to build
sql/event_queue.cc:
  wl3771
    release audit resources before waiting
sql/log.cc:
  wl3771
    add general audit call for log
sql/mysqld.cc:
  wl3771
    add audit initialize/finalize
    add general audit call for error
sql/sql_audit.cc:
  wl3771
    pluggable audit interface implementation
sql/sql_audit.h:
  wl3771
    pluggable audit interface implementation
sql/sql_class.cc:
  wl3771
    add thd audit init/deinit calls
sql/sql_class.h:
  wl3771
    add required data structures for audit to THD
sql/sql_connect.cc:
  wl3771
    release audit resources before waiting
sql/sql_insert.cc:
  wl3771
    release audit plugins before waiting
sql/sql_parse.cc:
  wl3771
    add general audit call for results
sql/sql_plugin.cc:
  wl3771
    add declarations for audit plugin type
parent dee03a1c
......@@ -19,7 +19,8 @@ BUILT_SOURCES = $(HEADERS_GEN_MAKE) link_sources probes_mysql_nodtrace.h
HEADERS_GEN_CONFIGURE = mysql_version.h
HEADERS_GEN_MAKE = my_config.h
HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \
my_list.h my_alloc.h typelib.h mysql/plugin.h
my_list.h my_alloc.h typelib.h mysql/plugin.h \
mysql/plugin_audit.h mysql/plugin_ftparser.h
pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
my_xml.h mysql_embed.h mysql/services.h \
mysql/service_my_snprintf.h mysql/service_thd_alloc.h \
......
......@@ -66,8 +66,9 @@ typedef struct st_mysql_xid MYSQL_XID;
#define MYSQL_FTPARSER_PLUGIN 2 /* Full-text parser plugin */
#define MYSQL_DAEMON_PLUGIN 3 /* The daemon/raw plugin type */
#define MYSQL_INFORMATION_SCHEMA_PLUGIN 4 /* The I_S plugin type */
#define MYSQL_REPLICATION_PLUGIN 5 /* The replication plugin type */
#define MYSQL_MAX_PLUGIN_TYPE_NUM 6 /* The number of plugin types */
#define MYSQL_AUDIT_PLUGIN 5 /* The Audit plugin type */
#define MYSQL_REPLICATION_PLUGIN 6 /* The replication plugin type */
#define MYSQL_MAX_PLUGIN_TYPE_NUM 7 /* The number of plugin types */
/* We use the following strings to define licenses for plugins */
#define PLUGIN_LICENSE_PROPRIETARY 0
......@@ -403,205 +404,43 @@ struct st_mysql_plugin
/*************************************************************************
API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)
*/
#include "plugin_ftparser.h"
#define MYSQL_FTPARSER_INTERFACE_VERSION 0x0100
/* Parsing modes. Set in MYSQL_FTPARSER_PARAM::mode */
enum enum_ftparser_mode
{
/*
Fast and simple mode. This mode is used for indexing, and natural
language queries.
The parser is expected to return only those words that go into the
index. Stopwords or too short/long words should not be returned. The
'boolean_info' argument of mysql_add_word() does not have to be set.
*/
MYSQL_FTPARSER_SIMPLE_MODE= 0,
/*
Parse with stopwords mode. This mode is used in boolean searches for
"phrase matching."
The parser is not allowed to ignore words in this mode. Every word
should be returned, including stopwords and words that are too short
or long. The 'boolean_info' argument of mysql_add_word() does not
have to be set.
/*************************************************************************
API for Storage Engine plugin. (MYSQL_DAEMON_PLUGIN)
*/
MYSQL_FTPARSER_WITH_STOPWORDS= 1,
/*
Parse in boolean mode. This mode is used to parse a boolean query string.
The parser should provide a valid MYSQL_FTPARSER_BOOLEAN_INFO
structure in the 'boolean_info' argument to mysql_add_word().
Usually that means that the parser should recognize boolean operators
in the parsing stream and set appropriate fields in
MYSQL_FTPARSER_BOOLEAN_INFO structure accordingly. As for
MYSQL_FTPARSER_WITH_STOPWORDS mode, no word should be ignored.
Instead, use FT_TOKEN_STOPWORD for the token type of such a word.
*/
MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
};
/* handlertons of different MySQL releases are incompatible */
#define MYSQL_DAEMON_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
/*
Token types for boolean mode searching (used for the type member of
MYSQL_FTPARSER_BOOLEAN_INFO struct)
FT_TOKEN_EOF: End of data.
FT_TOKEN_WORD: Regular word.
FT_TOKEN_LEFT_PAREN: Left parenthesis (start of group/sub-expression).
FT_TOKEN_RIGHT_PAREN: Right parenthesis (end of group/sub-expression).
FT_TOKEN_STOPWORD: Stopword.
Here we define only the descriptor structure, that is referred from
st_mysql_plugin.
*/
enum enum_ft_token_type
struct st_mysql_daemon
{
FT_TOKEN_EOF= 0,
FT_TOKEN_WORD= 1,
FT_TOKEN_LEFT_PAREN= 2,
FT_TOKEN_RIGHT_PAREN= 3,
FT_TOKEN_STOPWORD= 4
int interface_version;
};
/*
This structure is used in boolean search mode only. It conveys
boolean-mode metadata to the MySQL search engine for every word in
the search query. A valid instance of this structure must be filled
in by the plugin parser and passed as an argument in the call to
mysql_add_word (the callback function in the MYSQL_FTPARSER_PARAM
structure) when a query is parsed in boolean mode.
type: The token type. Should be one of the enum_ft_token_type values.
yesno: Whether the word must be present for a match to occur:
>0 Must be present
<0 Must not be present
0 Neither; the word is optional but its presence increases the relevance
With the default settings of the ft_boolean_syntax system variable,
>0 corresponds to the '+' operator, <0 corrresponds to the '-' operator,
and 0 means neither operator was used.
weight_adjust: A weighting factor that determines how much a match
for the word counts. Positive values increase, negative - decrease the
relative word's importance in the query.
wasign: The sign of the word's weight in the query. If it's non-negative
the match for the word will increase document relevance, if it's
negative - decrease (the word becomes a "noise word", the less of it the
better).
trunc: Corresponds to the '*' operator in the default setting of the
ft_boolean_syntax system variable.
*/
typedef struct st_mysql_ftparser_boolean_info
{
enum enum_ft_token_type type;
int yesno;
int weight_adjust;
char wasign;
char trunc;
/* These are parser state and must be removed. */
char prev;
char *quot;
} MYSQL_FTPARSER_BOOLEAN_INFO;
/*
The following flag means that buffer with a string (document, word)
may be overwritten by the caller before the end of the parsing (that is
before st_mysql_ftparser::deinit() call). If one needs the string
to survive between two successive calls of the parsing function, she
needs to save a copy of it. The flag may be set by MySQL before calling
st_mysql_ftparser::parse(), or it may be set by a plugin before calling
st_mysql_ftparser_param::mysql_parse() or
st_mysql_ftparser_param::mysql_add_word().
*/
#define MYSQL_FTFLAGS_NEED_COPY 1
/*
An argument of the full-text parser plugin. This structure is
filled in by MySQL server and passed to the parsing function of the
plugin as an in/out parameter.
mysql_parse: A pointer to the built-in parser implementation of the
server. It's set by the server and can be used by the parser plugin
to invoke the MySQL default parser. If plugin's role is to extract
textual data from .doc, .pdf or .xml content, it might extract
plaintext from the content, and then pass the text to the default
MySQL parser to be parsed.
mysql_add_word: A server callback to add a new word. When parsing
a document, the server sets this to point at a function that adds
the word to MySQL full-text index. When parsing a search query,
this function will add the new word to the list of words to search
for. The boolean_info argument can be NULL for all cases except
when mode is MYSQL_FTPARSER_FULL_BOOLEAN_INFO.
ftparser_state: A generic pointer. The plugin can set it to point
to information to be used internally for its own purposes.
mysql_ftparam: This is set by the server. It is used by MySQL functions
called via mysql_parse() and mysql_add_word() callback. The plugin
should not modify it.
cs: Information about the character set of the document or query string.
doc: A pointer to the document or query string to be parsed.
length: Length of the document or query string, in bytes.
flags: See MYSQL_FTFLAGS_* constants above.
mode: The parsing mode. With boolean operators, with stopwords, or
nothing. See enum_ftparser_mode above.
/*************************************************************************
API for I_S plugin. (MYSQL_INFORMATION_SCHEMA_PLUGIN)
*/
typedef struct st_mysql_ftparser_param
{
int (*mysql_parse)(struct st_mysql_ftparser_param *,
char *doc, int doc_len);
int (*mysql_add_word)(struct st_mysql_ftparser_param *,
char *word, int word_len,
MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
void *ftparser_state;
void *mysql_ftparam;
struct charset_info_st *cs;
char *doc;
int length;
int flags;
enum enum_ftparser_mode mode;
} MYSQL_FTPARSER_PARAM;
/* handlertons of different MySQL releases are incompatible */
#define MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
/*
Full-text parser descriptor.
interface_version is, e.g., MYSQL_FTPARSER_INTERFACE_VERSION.
The parsing, initialization, and deinitialization functions are
invoked per SQL statement for which the parser is used.
Here we define only the descriptor structure, that is referred from
st_mysql_plugin.
*/
struct st_mysql_ftparser
struct st_mysql_information_schema
{
int interface_version;
int (*parse)(MYSQL_FTPARSER_PARAM *param);
int (*init)(MYSQL_FTPARSER_PARAM *param);
int (*deinit)(MYSQL_FTPARSER_PARAM *param);
};
/*************************************************************************
API for Storage Engine plugin. (MYSQL_DAEMON_PLUGIN)
*/
/* handlertons of different MySQL releases are incompatible */
#define MYSQL_DAEMON_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
/*************************************************************************
API for I_S plugin. (MYSQL_INFORMATION_SCHEMA_PLUGIN)
*/
/* handlertons of different MySQL releases are incompatible */
#define MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
/*************************************************************************
API for Storage Engine plugin. (MYSQL_STORAGE_ENGINE_PLUGIN)
......@@ -623,25 +462,6 @@ struct st_mysql_storage_engine
struct handlerton;
/*
Here we define only the descriptor structure, that is referred from
st_mysql_plugin.
*/
struct st_mysql_daemon
{
int interface_version;
};
/*
Here we define only the descriptor structure, that is referred from
st_mysql_plugin.
*/
struct st_mysql_information_schema
{
int interface_version;
};
/*
API for Replication plugin. (MYSQL_REPLICATION_PLUGIN)
......@@ -655,7 +475,7 @@ struct st_mysql_information_schema
int interface_version;
};
/*
/*************************************************************************
st_mysql_value struct for reading values from mysqld.
Used by server variables framework to parse user-provided values.
Will be used for arguments when implementing UDFs.
......
......@@ -76,6 +76,8 @@ struct st_mysql_plugin
struct st_mysql_sys_var **system_vars;
void * __reserved1;
};
#include "plugin_ftparser.h"
#include "plugin.h"
enum enum_ftparser_mode
{
MYSQL_FTPARSER_SIMPLE_MODE= 0,
......@@ -122,19 +124,19 @@ struct st_mysql_ftparser
int (*init)(MYSQL_FTPARSER_PARAM *param);
int (*deinit)(MYSQL_FTPARSER_PARAM *param);
};
struct st_mysql_storage_engine
struct st_mysql_daemon
{
int interface_version;
};
struct handlerton;
struct st_mysql_daemon
struct st_mysql_information_schema
{
int interface_version;
};
struct st_mysql_information_schema
struct st_mysql_storage_engine
{
int interface_version;
};
struct handlerton;
struct Mysql_replication {
int interface_version;
};
......
/* Copyright (C) 2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _my_audit_h
#define _my_audit_h
/*************************************************************************
API for Audit plugin. (MYSQL_AUDIT_PLUGIN)
*/
#include "plugin.h"
#define MYSQL_AUDIT_CLASS_MASK_SIZE 1
#define MYSQL_AUDIT_INTERFACE_VERSION ( 0x010000 | MYSQL_AUDIT_CLASS_MASK_SIZE )
/*
The first word in every event class struct indicates the specific
class of the event.
*/
struct mysql_event
{
int event_class;
};
/*************************************************************************
AUDIT CLASS : GENERAL
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.
*/
#define MYSQL_AUDIT_GENERAL_CLASS 0
#define MYSQL_AUDIT_GENERAL_CLASSMASK (1 << MYSQL_AUDIT_GENERAL_CLASS)
#define MYSQL_AUDIT_GENERAL_LOG 0
#define MYSQL_AUDIT_GENERAL_ERROR 1
#define MYSQL_AUDIT_GENERAL_RESULT 2
struct mysql_event_general
{
int event_class;
int general_error_code;
unsigned long general_thread_id;
const char *general_user;
unsigned int general_user_length;
const char *general_command;
unsigned int general_command_length;
const char *general_query;
unsigned int general_query_length;
struct charset_info_st *general_charset;
unsigned long long general_time;
unsigned long long general_rows;
};
/*************************************************************************
Here we define the descriptor structure, that is referred from
st_mysql_plugin.
release_thd() event occurs when the event class consumer is to be
disassociated from the specified THD. This would typically occur
before some operation which may require sleeping - such as when
waiting for the next query from the client.
event_notify() is invoked whenever an event occurs which is of any
class for which the plugin has interest. The first word of the
mysql_event argument indicates the specific event class and the
remainder of the structure is as required for that class.
class_mask is an array of bits used to indicate what event classes
that this plugin wants to receive.
*/
struct st_mysql_audit
{
int interface_version;
void (*release_thd)(MYSQL_THD);
void (*event_notify)(MYSQL_THD, const struct mysql_event *);
unsigned long class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
};
#endif
/* Copyright (C) 2005 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _my_plugin_ftparser_h
#define _my_plugin_ftparser_h
#include "plugin.h"
/*************************************************************************
API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)
*/
#define MYSQL_FTPARSER_INTERFACE_VERSION 0x0100
/* Parsing modes. Set in MYSQL_FTPARSER_PARAM::mode */
enum enum_ftparser_mode
{
/*
Fast and simple mode. This mode is used for indexing, and natural
language queries.
The parser is expected to return only those words that go into the
index. Stopwords or too short/long words should not be returned. The
'boolean_info' argument of mysql_add_word() does not have to be set.
*/
MYSQL_FTPARSER_SIMPLE_MODE= 0,
/*
Parse with stopwords mode. This mode is used in boolean searches for
"phrase matching."
The parser is not allowed to ignore words in this mode. Every word
should be returned, including stopwords and words that are too short
or long. The 'boolean_info' argument of mysql_add_word() does not
have to be set.
*/
MYSQL_FTPARSER_WITH_STOPWORDS= 1,
/*
Parse in boolean mode. This mode is used to parse a boolean query string.
The parser should provide a valid MYSQL_FTPARSER_BOOLEAN_INFO
structure in the 'boolean_info' argument to mysql_add_word().
Usually that means that the parser should recognize boolean operators
in the parsing stream and set appropriate fields in
MYSQL_FTPARSER_BOOLEAN_INFO structure accordingly. As for
MYSQL_FTPARSER_WITH_STOPWORDS mode, no word should be ignored.
Instead, use FT_TOKEN_STOPWORD for the token type of such a word.
*/
MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
};
/*
Token types for boolean mode searching (used for the type member of
MYSQL_FTPARSER_BOOLEAN_INFO struct)
FT_TOKEN_EOF: End of data.
FT_TOKEN_WORD: Regular word.
FT_TOKEN_LEFT_PAREN: Left parenthesis (start of group/sub-expression).
FT_TOKEN_RIGHT_PAREN: Right parenthesis (end of group/sub-expression).
FT_TOKEN_STOPWORD: Stopword.
*/
enum enum_ft_token_type
{
FT_TOKEN_EOF= 0,
FT_TOKEN_WORD= 1,
FT_TOKEN_LEFT_PAREN= 2,
FT_TOKEN_RIGHT_PAREN= 3,
FT_TOKEN_STOPWORD= 4
};
/*
This structure is used in boolean search mode only. It conveys
boolean-mode metadata to the MySQL search engine for every word in
the search query. A valid instance of this structure must be filled
in by the plugin parser and passed as an argument in the call to
mysql_add_word (the callback function in the MYSQL_FTPARSER_PARAM
structure) when a query is parsed in boolean mode.
type: The token type. Should be one of the enum_ft_token_type values.
yesno: Whether the word must be present for a match to occur:
>0 Must be present
<0 Must not be present
0 Neither; the word is optional but its presence increases the relevance
With the default settings of the ft_boolean_syntax system variable,
>0 corresponds to the '+' operator, <0 corrresponds to the '-' operator,
and 0 means neither operator was used.
weight_adjust: A weighting factor that determines how much a match
for the word counts. Positive values increase, negative - decrease the
relative word's importance in the query.
wasign: The sign of the word's weight in the query. If it's non-negative
the match for the word will increase document relevance, if it's
negative - decrease (the word becomes a "noise word", the less of it the
better).
trunc: Corresponds to the '*' operator in the default setting of the
ft_boolean_syntax system variable.
*/
typedef struct st_mysql_ftparser_boolean_info
{
enum enum_ft_token_type type;
int yesno;
int weight_adjust;
char wasign;
char trunc;
/* These are parser state and must be removed. */
char prev;
char *quot;
} MYSQL_FTPARSER_BOOLEAN_INFO;
/*
The following flag means that buffer with a string (document, word)
may be overwritten by the caller before the end of the parsing (that is
before st_mysql_ftparser::deinit() call). If one needs the string
to survive between two successive calls of the parsing function, she
needs to save a copy of it. The flag may be set by MySQL before calling
st_mysql_ftparser::parse(), or it may be set by a plugin before calling
st_mysql_ftparser_param::mysql_parse() or
st_mysql_ftparser_param::mysql_add_word().
*/
#define MYSQL_FTFLAGS_NEED_COPY 1
/*
An argument of the full-text parser plugin. This structure is
filled in by MySQL server and passed to the parsing function of the
plugin as an in/out parameter.
mysql_parse: A pointer to the built-in parser implementation of the
server. It's set by the server and can be used by the parser plugin
to invoke the MySQL default parser. If plugin's role is to extract
textual data from .doc, .pdf or .xml content, it might extract
plaintext from the content, and then pass the text to the default
MySQL parser to be parsed.
mysql_add_word: A server callback to add a new word. When parsing
a document, the server sets this to point at a function that adds
the word to MySQL full-text index. When parsing a search query,
this function will add the new word to the list of words to search
for. The boolean_info argument can be NULL for all cases except
when mode is MYSQL_FTPARSER_FULL_BOOLEAN_INFO.
ftparser_state: A generic pointer. The plugin can set it to point
to information to be used internally for its own purposes.
mysql_ftparam: This is set by the server. It is used by MySQL functions
called via mysql_parse() and mysql_add_word() callback. The plugin
should not modify it.
cs: Information about the character set of the document or query string.
doc: A pointer to the document or query string to be parsed.
length: Length of the document or query string, in bytes.
flags: See MYSQL_FTFLAGS_* constants above.
mode: The parsing mode. With boolean operators, with stopwords, or
nothing. See enum_ftparser_mode above.
*/
typedef struct st_mysql_ftparser_param
{
int (*mysql_parse)(struct st_mysql_ftparser_param *,
char *doc, int doc_len);
int (*mysql_add_word)(struct st_mysql_ftparser_param *,
char *word, int word_len,
MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
void *ftparser_state;
void *mysql_ftparam;
struct charset_info_st *cs;
char *doc;
int length;
int flags;
enum enum_ftparser_mode mode;
} MYSQL_FTPARSER_PARAM;
/*
Full-text parser descriptor.
interface_version is, e.g., MYSQL_FTPARSER_INTERFACE_VERSION.
The parsing, initialization, and deinitialization functions are
invoked per SQL statement for which the parser is used.
*/
struct st_mysql_ftparser
{
int interface_version;
int (*parse)(MYSQL_FTPARSER_PARAM *param);
int (*init)(MYSQL_FTPARSER_PARAM *param);
int (*deinit)(MYSQL_FTPARSER_PARAM *param);
};
#endif
......@@ -131,7 +131,8 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/strfunc.cc ../sql/table.cc ../sql/thr_malloc.cc
../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc
../sql/partition_info.cc ../sql/sql_connect.cc
../sql/scheduler.cc ../sql/event_parse_data.cc
../sql/scheduler.cc ../sql/sql_audit.cc
../sql/event_parse_data.cc
../sql/sql_signal.cc ../sql/rpl_handler.cc
${GEN_SOURCES}
${LIB_SOURCES})
......
......@@ -78,8 +78,8 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
debug_sync.cc \
sql_tablespace.cc \
rpl_injector.cc my_user.c partition_info.cc \
sql_servers.cc event_parse_data.cc sql_signal.cc \
rpl_handler.cc
sql_servers.cc sql_audit.cc event_parse_data.cc \
sql_signal.cc rpl_handler.cc
libmysqld_int_a_SOURCES= $(libmysqld_sources)
nodist_libmysqld_int_a_SOURCES= $(libmysqlsources) $(sqlsources)
......
# Copyright (C) 2007 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#Makefile.am example for a plugin
pkgplugindir= $(pkglibdir)/plugin
AM_CPPFLAGS = -I$(top_srcdir)/include
EXTRA_LTLIBRARIES= adt_null.la
pkgplugin_LTLIBRARIES= @plugin_audit_null_shared_target@
adt_null_la_LDFLAGS= -module -rpath $(pkgplugindir)
adt_null_la_CPPFLAGS= $(AM_CPPFLAGS) -DMYSQL_DYNAMIC_PLUGIN
adt_null_la_SOURCES= audit_null.c
EXTRA_LIBRARIES= libadtnull.a
noinst_LIBRARIES= @plugin_audit_null_static_target@
libadtnull_a_SOURCES= audit_null.c
EXTRA_DIST= plug.in
/* Copyright (C) 2006-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <stdio.h>
#include <mysql/plugin.h>
#include <mysql/plugin_audit.h>
#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
#define __attribute__(A)
#endif
static volatile int number_of_calls; /* for SHOW STATUS, see below */
/*
Initialize the plugin at server start or plugin installation.
SYNOPSIS
audit_null_plugin_init()
DESCRIPTION
Does nothing.
RETURN VALUE
0 success
1 failure (cannot happen)
*/
static int audit_null_plugin_init(void *arg __attribute__((unused)))
{
number_of_calls= 0;
return(0);
}
/*
Terminate the plugin at server shutdown or plugin deinstallation.
SYNOPSIS
audit_null_plugin_deinit()
Does nothing.
RETURN VALUE
0 success
1 failure (cannot happen)
*/
static int audit_null_plugin_deinit(void *arg __attribute__((unused)))
{
printf("audit_null was invoked %u times\n", number_of_calls);
return(0);
}
/*
Foo
SYNOPSIS
audit_null_notify()
thd connection context
DESCRIPTION
*/
static void audit_null_notify(MYSQL_THD thd __attribute__((unused)),
const struct mysql_event *event
__attribute__((unused)))
{
/* prone to races, oh well */
number_of_calls++;
}
/*
Plugin type-specific descriptor
*/
static struct st_mysql_audit audit_null_descriptor=
{
MYSQL_AUDIT_INTERFACE_VERSION, /* interface version */
NULL, /* release_thd function */
audit_null_notify, /* notify function */
{ (unsigned long) -1 } /* class mask */
};
/*
Plugin status variables for SHOW STATUS
*/
static struct st_mysql_show_var simple_status[]=
{
{"audit_null_called", (char *)&number_of_calls, SHOW_INT},
{0,0,0}
};
/*
Plugin library descriptor
*/
mysql_declare_plugin(audit_null)
{
MYSQL_AUDIT_PLUGIN, /* type */
&audit_null_descriptor, /* descriptor */
"NULL_AUDIT", /* name */
"MySQL AB", /* author */
"Simple NULL Audit", /* description */
PLUGIN_LICENSE_GPL,
audit_null_plugin_init, /* init function (when loaded) */
audit_null_plugin_deinit, /* deinit function (when unloaded) */
0x0001, /* version */
simple_status, /* status variables */
NULL, /* system variables */
NULL
}
mysql_declare_plugin_end;
MYSQL_PLUGIN(audit_null, [NULL Audit Plug-in],
[Simple black-hole Audit example plug-in])
MYSQL_PLUGIN_DYNAMIC(audit_null, [adt_null.la])
MYSQL_PLUGIN_STATIC(audit_null, [libadtnull.a])
......@@ -73,7 +73,7 @@ SET (SQL_SOURCE
event_queue.cc event_db_repository.cc
sql_tablespace.cc events.cc ../sql-common/my_user.c
partition_info.cc rpl_utility.cc rpl_injector.cc sql_locale.cc
rpl_rli.cc rpl_mi.cc sql_servers.cc
rpl_rli.cc rpl_mi.cc sql_servers.cc sql_audit.cc
sql_connect.cc scheduler.cc
sql_profile.cc event_parse_data.cc
sql_signal.cc rpl_handler.cc
......
......@@ -111,6 +111,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
sql_plugin.h authors.h event_parse_data.h \
event_data_objects.h event_scheduler.h \
sql_partition.h partition_info.h partition_element.h \
sql_audit.h \
contributors.h sql_servers.h sql_signal.h records.h \
sql_prepare.h rpl_handler.h replication.h
......@@ -157,7 +158,8 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
event_queue.cc event_db_repository.cc events.cc \
sql_plugin.cc sql_binlog.cc \
sql_builtin.cc sql_tablespace.cc partition_info.cc \
sql_servers.cc event_parse_data.cc sql_signal.cc \
sql_servers.cc sql_audit.cc \
event_parse_data.cc sql_signal.cc \
rpl_handler.cc
nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c
......
......@@ -16,6 +16,7 @@
#include "mysql_priv.h"
#include "event_queue.h"
#include "event_data_objects.h"
#include "sql_audit.h"
/**
@addtogroup Event_Scheduler
......@@ -581,6 +582,9 @@ Event_queue::get_top_for_execution_if_time(THD *thd,
/* There are no events in the queue */
next_activation_at= 0;
/* Release any held audit resources before waiting */
mysql_audit_release(thd);
/* Wait on condition until signaled. Release LOCK_queue while waiting. */
cond_wait(thd, NULL, queue_empty_msg, SCHED_FUNC, __LINE__);
......@@ -600,6 +604,10 @@ Event_queue::get_top_for_execution_if_time(THD *thd,
*/
struct timespec top_time;
set_timespec(top_time, next_activation_at - thd->query_start());
/* Release any held audit resources before waiting */
mysql_audit_release(thd);
cond_wait(thd, &top_time, queue_wait_msg, SCHED_FUNC, __LINE__);
continue;
......
......@@ -28,6 +28,7 @@
#include "sql_repl.h"
#include "rpl_filter.h"
#include "rpl_rli.h"
#include "sql_audit.h"
#include <my_dir.h>
#include <stdarg.h>
......@@ -1088,6 +1089,14 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
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);
while (*current_handler)
error|= (*current_handler++)->
log_general(thd, current_time, user_host_buff,
......
......@@ -26,6 +26,7 @@
#include "mysqld_suffix.h"
#include "mysys_err.h"
#include "events.h"
#include "sql_audit.h"
#include "probes_mysql.h"
#include "debug_sync.h"
......@@ -834,6 +835,7 @@ static void close_server_sock();
static void clean_up_mutexes(void);
static void wait_for_signal_thread_to_end(void);
static void create_pid_file();
static void mysqld_exit(int exit_code) __attribute__((noreturn));
static void end_ssl();
#endif
......@@ -1243,6 +1245,7 @@ void unireg_end(void)
#endif
}
extern "C" void unireg_abort(int exit_code)
{
DBUG_ENTER("unireg_abort");
......@@ -1253,14 +1256,19 @@ extern "C" void unireg_abort(int exit_code)
sql_print_error("Aborting\n");
clean_up(!opt_help && (exit_code || !opt_bootstrap)); /* purecov: inspected */
DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
mysqld_exit(exit_code);
}
static void mysqld_exit(int exit_code)
{
wait_for_signal_thread_to_end();
mysql_audit_finalize();
clean_up_mutexes();
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
exit(exit_code); /* purecov: inspected */
}
#endif /*EMBEDDED_LIBRARY*/
#endif /* !EMBEDDED_LIBRARY */
void clean_up(bool print_message)
{
......@@ -2917,6 +2925,13 @@ void my_message_sql(uint error, const char *str, myf MyFlags)
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,
......@@ -4323,6 +4338,9 @@ int main(int argc, char **argv)
thr_kill_signal= SIGINT;
#endif
/* Initialize audit interface globals. Audit plugins are inited later. */
mysql_audit_initialize();
/*
Perform basic logger initialization logger. Should be called after
MY_INIT, as it initializes mutexes. Log tables are inited later.
......@@ -4589,15 +4607,10 @@ int main(int argc, char **argv)
}
#endif
clean_up(1);
wait_for_signal_thread_to_end();
clean_up_mutexes();
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
exit(0);
return(0); /* purecov: deadcode */
mysqld_exit(0);
}
#endif /* EMBEDDED_LIBRARY */
#endif /* !EMBEDDED_LIBRARY */
/****************************************************************************
......
This diff is collapsed.
#ifndef SQL_AUDIT_INCLUDED
#define SQL_AUDIT_INCLUDED
/* Copyright (C) 2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <mysql/plugin_audit.h>
extern unsigned long mysql_global_audit_mask[];
extern void mysql_audit_initialize();
extern void mysql_audit_finalize();
extern void mysql_audit_init_thd(THD *thd);
extern void mysql_audit_free_thd(THD *thd);
extern void mysql_audit_notify(THD *thd, uint event_class,
uint event_subtype, ...);
extern void mysql_audit_release(THD *thd);
/**
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
@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
@param[in] cmd Command name
@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(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)
{
#ifndef EMBEDDED_LIBRARY
if (mysql_global_audit_mask[0] & MYSQL_AUDIT_GENERAL_CLASSMASK)
mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, event_subtype,
error_code, time, user, userlen, cmd, cmdlen,
query, querylen, clientcs, rows);
#endif
}
#endif /* SQL_AUDIT_INCLUDED */
......@@ -32,6 +32,7 @@
#include "slave.h"
#include <my_bitmap.h>
#include "log_event.h"
#include "sql_audit.h"
#include <m_ctype.h>
#include <sys/stat.h>
#include <thr_alarm.h>
......@@ -519,6 +520,7 @@ THD::THD()
dbug_sentry=THD_SENTRY_MAGIC;
#endif
#ifndef EMBEDDED_LIBRARY
mysql_audit_init_thd(this);
net.vio=0;
#endif
client_capabilities= 0; // minimalistic client
......@@ -1052,6 +1054,7 @@ THD::~THD()
cleanup();
ha_close_connection(this);
mysql_audit_release(this);
plugin_thdvar_cleanup(this);
DBUG_PRINT("info", ("freeing security context"));
......@@ -1069,6 +1072,8 @@ THD::~THD()
delete rli_fake;
rli_fake= NULL;
}
mysql_audit_free_thd(this);
#endif
free_root(&main_mem_root, MYF(0));
......
......@@ -23,6 +23,7 @@
#pragma interface /* gcc class implementation */
#endif
#include <mysql/plugin_audit.h>
#include "log.h"
#include "rpl_tblmap.h"
......@@ -1803,6 +1804,20 @@ class THD :public Statement,
partition_info *work_part_info;
#endif
#ifndef EMBEDDED_LIBRARY
/**
Array of active audit plugins which have been used by this THD.
This list is later iterated to invoke release_thd() on those
plugins.
*/
DYNAMIC_ARRAY audit_class_plugins;
/**
Array of bits indicating which audit classes have already been
added to the list of audit plugins which are currently in use.
*/
unsigned long audit_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
#endif
#if defined(ENABLED_DEBUG_SYNC)
/* Debug Sync facility. See debug_sync.cc. */
struct st_debug_sync_control *debug_sync_control;
......
......@@ -19,6 +19,7 @@
*/
#include "mysql_priv.h"
#include "sql_audit.h"
#include "probes_mysql.h"
#ifdef HAVE_OPENSSL
......@@ -1160,6 +1161,7 @@ pthread_handler_t handle_one_connection(void *arg)
while (!net->error && net->vio != 0 &&
!(thd->killed == THD::KILL_CONNECTION))
{
mysql_audit_release(thd);
if (do_command(thd))
break;
}
......
......@@ -61,6 +61,7 @@
#include "sql_show.h"
#include "slave.h"
#include "rpl_mi.h"
#include "sql_audit.h"
#ifndef EMBEDDED_LIBRARY
static bool delayed_get_table(THD *thd, TABLE_LIST *table_list);
......@@ -2431,6 +2432,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
while (!thd->killed)
{
int error;
mysql_audit_release(thd);
#if defined(HAVE_BROKEN_COND_TIMEDWAIT)
error=pthread_cond_wait(&di->cond,&di->mutex);
#else
......@@ -2512,6 +2514,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
mysql_unlock_tables(thd, lock);
ha_autocommit_or_rollback(thd, 0);
di->group_count=0;
mysql_audit_release(thd);
pthread_mutex_lock(&di->mutex);
}
if (di->tables_in_use)
......
......@@ -28,6 +28,7 @@
#include "sp_cache.h"
#include "events.h"
#include "sql_trigger.h"
#include "sql_audit.h"
#include "sql_prepare.h"
#include "probes_mysql.h"
......@@ -1483,6 +1484,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
/* Free tables */
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());
}
log_slow_statement(thd);
thd_proc_info(thd, "cleaning up");
......
......@@ -16,6 +16,7 @@
#include "mysql_priv.h"
#include <my_pthread.h>
#include <my_getopt.h>
#include <mysql/plugin_audit.h>
#define REPORT_TO_LOG 1
#define REPORT_TO_USER 2
......@@ -47,12 +48,16 @@ const LEX_STRING plugin_type_names[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{ C_STRING_WITH_LEN("FTPARSER") },
{ C_STRING_WITH_LEN("DAEMON") },
{ C_STRING_WITH_LEN("INFORMATION SCHEMA") },
{ C_STRING_WITH_LEN("AUDIT") },
{ C_STRING_WITH_LEN("REPLICATION") },
};
extern int initialize_schema_table(st_plugin_int *plugin);
extern int finalize_schema_table(st_plugin_int *plugin);
extern int initialize_audit_plugin(st_plugin_int *plugin);
extern int finalize_audit_plugin(st_plugin_int *plugin);
/*
The number of elements in both plugin_type_initialize and
plugin_type_deinitialize should equal to the number of plugins
......@@ -60,12 +65,14 @@ extern int finalize_schema_table(st_plugin_int *plugin);
*/
plugin_type_init plugin_type_initialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
0,ha_initialize_handlerton,0,0,initialize_schema_table
0,ha_initialize_handlerton,0,0,initialize_schema_table,
initialize_audit_plugin
};
plugin_type_init plugin_type_deinitialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
0,ha_finalize_handlerton,0,0,finalize_schema_table
0,ha_finalize_handlerton,0,0,finalize_schema_table,
finalize_audit_plugin
};
#ifdef HAVE_DLOPEN
......@@ -87,6 +94,7 @@ static int min_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
MYSQL_FTPARSER_INTERFACE_VERSION,
MYSQL_DAEMON_INTERFACE_VERSION,
MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
MYSQL_AUDIT_INTERFACE_VERSION,
MYSQL_REPLICATION_INTERFACE_VERSION,
};
static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
......@@ -96,6 +104,7 @@ static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
MYSQL_FTPARSER_INTERFACE_VERSION,
MYSQL_DAEMON_INTERFACE_VERSION,
MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
MYSQL_AUDIT_INTERFACE_VERSION,
MYSQL_REPLICATION_INTERFACE_VERSION,
};
......@@ -1341,26 +1350,22 @@ bool plugin_register_builtin(THD *thd, struct st_mysql_plugin *plugin)
*/
static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
{
THD thd;
TABLE_LIST tables;
TABLE *table;
READ_RECORD read_record_info;
int error;
THD *new_thd;
THD *new_thd= &thd;
#ifdef EMBEDDED_LIBRARY
bool table_exists;
#endif /* EMBEDDED_LIBRARY */
DBUG_ENTER("plugin_load");
if (!(new_thd= new THD))
{
sql_print_error("Can't allocate memory for plugin structures");
delete new_thd;
DBUG_VOID_RETURN;
}
new_thd->thread_stack= (char*) &tables;
new_thd->store_globals();
new_thd->db= my_strdup("mysql", MYF(0));
new_thd->db_length= 5;
bzero((char*) &thd.net, sizeof(thd.net));
bzero((uchar*)&tables, sizeof(tables));
tables.alias= tables.table_name= (char*)"plugin";
tables.lock_type= TL_READ;
......@@ -1418,7 +1423,6 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
new_thd->version--; // Force close to free memory
end:
close_thread_tables(new_thd);
delete new_thd;
/* Remember that we don't have a THD */
my_pthread_setspecific_ptr(THR_THD, 0);
DBUG_VOID_RETURN;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment