Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
1793646d
Commit
1793646d
authored
Jan 25, 2016
by
Alexey Botchkov
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '5.5' into 10.0
Conflicts: plugin/server_audit/server_audit.c
parents
74b1af19
9c9d10b4
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
1338 additions
and
279 deletions
+1338
-279
cmake/libutils.cmake
cmake/libutils.cmake
+5
-0
mysql-test/suite/plugins/r/server_audit.result
mysql-test/suite/plugins/r/server_audit.result
+4
-1
mysql-test/suite/plugins/r/thread_pool_server_audit.result
mysql-test/suite/plugins/r/thread_pool_server_audit.result
+6
-3
mysys/file_logger.c
mysys/file_logger.c
+2
-0
plugin/server_audit/CMakeLists.txt
plugin/server_audit/CMakeLists.txt
+4
-1
plugin/server_audit/plugin_audit_v4.h
plugin/server_audit/plugin_audit_v4.h
+561
-0
plugin/server_audit/server_audit.c
plugin/server_audit/server_audit.c
+594
-274
plugin/server_audit/test_audit_v4.c
plugin/server_audit/test_audit_v4.c
+162
-0
No files found.
cmake/libutils.cmake
View file @
1793646d
...
...
@@ -87,6 +87,11 @@ MACRO(CREATE_EXPORT_FILE VAR TARGET API_FUNCTIONS)
ENDFOREACH
()
SET
(
CONTENT
"
${
CONTENT
}
(void *)0
\n
}
\;
"
)
CONFIGURE_FILE_CONTENT
(
${
CONTENT
}
${
EXPORTS
}
)
# Avoid "function redeclared as variable" error
# when using gcc/clang option -flto(link time optimization)
IF
(
"
${
CMAKE_C_FLAGS
}
${
CMAKE_CXX_FLAGS
}
"
MATCHES
" -flto"
)
SET_SOURCE_FILES_PROPERTIES
(
${
EXPORTS
}
PROPERTIES COMPILE_FLAGS
"-fno-lto"
)
ENDIF
()
SET
(
${
VAR
}
${
EXPORTS
}
)
ENDIF
()
ENDMACRO
()
...
...
mysql-test/suite/plugins/r/server_audit.result
View file @
1793646d
...
...
@@ -8,6 +8,7 @@ server_audit_file_rotate_now OFF
server_audit_file_rotate_size 1000000
server_audit_file_rotations 9
server_audit_incl_users
server_audit_loc_info
server_audit_logging OFF
server_audit_mode 0
server_audit_output_type file
...
...
@@ -71,6 +72,7 @@ server_audit_file_rotate_now OFF
server_audit_file_rotate_size 1000000
server_audit_file_rotations 9
server_audit_incl_users odin, root, dva, tri
server_audit_loc_info
server_audit_logging ON
server_audit_mode 0
server_audit_output_type file
...
...
@@ -216,6 +218,7 @@ server_audit_file_rotate_now OFF
server_audit_file_rotate_size 1000000
server_audit_file_rotations 9
server_audit_incl_users odin, root, dva, tri
server_audit_loc_info
server_audit_logging ON
server_audit_mode 1
server_audit_output_type file
...
...
@@ -289,7 +292,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,READ,mysql,proc,
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,proc,
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,event,
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop database sa_db',0
TIME,HOSTNAME,root,localhost,ID,0,DISCONNECT,
sa_db
,,0
TIME,HOSTNAME,root,localhost,ID,0,DISCONNECT,,,0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'create database sa_db',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'use sa_db',0
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,user,
...
...
mysql-test/suite/plugins/r/thread_pool_server_audit.result
View file @
1793646d
...
...
@@ -8,6 +8,7 @@ server_audit_file_rotate_now OFF
server_audit_file_rotate_size 1000000
server_audit_file_rotations 9
server_audit_incl_users
server_audit_loc_info
server_audit_logging OFF
server_audit_mode 0
server_audit_output_type file
...
...
@@ -71,6 +72,7 @@ server_audit_file_rotate_now OFF
server_audit_file_rotate_size 1000000
server_audit_file_rotations 9
server_audit_incl_users odin, root, dva, tri
server_audit_loc_info
server_audit_logging ON
server_audit_mode 0
server_audit_output_type file
...
...
@@ -216,6 +218,7 @@ server_audit_file_rotate_now OFF
server_audit_file_rotate_size 1000000
server_audit_file_rotations 9
server_audit_incl_users odin, root, dva, tri
server_audit_loc_info
server_audit_logging ON
server_audit_mode 1
server_audit_output_type file
...
...
@@ -229,9 +232,9 @@ Warnings:
Warning 1620 Plugin is busy and will be uninstalled on shutdown
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_logging=on',0
TIME,HOSTNAME,root,localhost,ID,0,CONNECT,mysql,,0
TIME,HOSTNAME,
root,localhost,ID,0,DISCONNECT,mysql
,,0
TIME,HOSTNAME,
,,ID,0,DISCONNECT,
,,0
TIME,HOSTNAME,no_such_user,localhost,ID,0,FAILED_CONNECT,,,ID
TIME,HOSTNAME,
no_such_user,localhost
,ID,0,DISCONNECT,,,0
TIME,HOSTNAME,
,
,ID,0,DISCONNECT,,,0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_incl_users=\'odin, root, dva, tri\'',0
TIME,HOSTNAME,root,localhost,ID,ID,CREATE,test,t2,
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'create table t2 (id int)',0
...
...
@@ -289,7 +292,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,READ,mysql,proc,
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,proc,
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,event,
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop database sa_db',0
TIME,HOSTNAME,
root,localhost,ID,0,DISCONNECT,sa_db
,,0
TIME,HOSTNAME,
,,ID,0,DISCONNECT,
,,0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'create database sa_db',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'use sa_db',0
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,user,
...
...
mysys/file_logger.c
View file @
1793646d
...
...
@@ -14,11 +14,13 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef FLOGGER_SKIP_INCLUDES
#include "my_global.h"
#include <my_sys.h>
#include <m_string.h>
#include <mysql/service_logger.h>
#include <my_pthread.h>
#endif
/*FLOGGER_SKIP_INCLUDES*/
#ifndef flogger_mutex_init
#define flogger_mutex_init(A,B,C) mysql_mutex_init(A,B,C)
...
...
plugin/server_audit/CMakeLists.txt
View file @
1793646d
...
...
@@ -13,4 +13,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
MYSQL_ADD_PLUGIN
(
server_audit server_audit.c MODULE_ONLY
)
SET
(
SERVER_AUDIT_SOURCES
server_audit.c test_audit_v4.c plugin_audit_v4.h
)
MYSQL_ADD_PLUGIN
(
server_audit
${
SERVER_AUDIT_SOURCES
}
MODULE_ONLY
)
plugin/server_audit/plugin_audit_v4.h
0 → 100644
View file @
1793646d
/* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
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 */
#ifndef _my_audit_h
#define _my_audit_h
#ifndef PLUGIN_CONTEXT
#include "plugin.h"
#include "mysql/mysql_lex_string.h"
#ifndef MYSQL_ABI_CHECK
#include "m_string.h"
#endif
#include "my_command.h"
#include "my_sqlcommand.h"
#endif
/*PLUGIN_CONTEXT*/
#define MYSQL_AUDIT_INTERFACE_VERSION 0x0401
/**
@enum mysql_event_class_t
Audit event classes.
*/
typedef
enum
{
MYSQL_AUDIT_GENERAL_CLASS
=
0
,
MYSQL_AUDIT_CONNECTION_CLASS
=
1
,
MYSQL_AUDIT_PARSE_CLASS
=
2
,
MYSQL_AUDIT_AUTHORIZATION_CLASS
=
3
,
MYSQL_AUDIT_TABLE_ACCESS_CLASS
=
4
,
MYSQL_AUDIT_GLOBAL_VARIABLE_CLASS
=
5
,
MYSQL_AUDIT_SERVER_STARTUP_CLASS
=
6
,
MYSQL_AUDIT_SERVER_SHUTDOWN_CLASS
=
7
,
MYSQL_AUDIT_COMMAND_CLASS
=
8
,
MYSQL_AUDIT_QUERY_CLASS
=
9
,
MYSQL_AUDIT_STORED_PROGRAM_CLASS
=
10
,
/* This item must be last in the list. */
MYSQL_AUDIT_CLASS_MASK_SIZE
}
mysql_event_class_t
;
/**
@struct st_mysql_audit
The descriptor structure that is referred from st_mysql_plugin.
*/
struct
st_mysql_audit
{
/**
Interface version.
*/
int
interface_version
;
/**
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.
*/
void
(
*
release_thd
)(
MYSQL_THD
);
/**
Invoked whenever an event occurs which is of any
class for which the plugin has interest.The second argument
indicates the specific event class and the third argument is data
as required for that class.
*/
int
(
*
event_notify
)(
MYSQL_THD
,
mysql_event_class_t
,
const
void
*
);
/**
An array of bits used to indicate what event classes
that this plugin wants to receive.
*/
unsigned
long
class_mask
[
MYSQL_AUDIT_CLASS_MASK_SIZE
];
};
/**
@typedef enum_sql_command_t
SQL command type definition.
*/
typedef
enum
enum_sql_command
enum_sql_command_t
;
/**
@enum mysql_event_general_subclass_t
Events for the MYSQL_AUDIT_GENERAL_CLASS event class.
*/
typedef
enum
{
/** occurs before emitting to the general query log. */
MYSQL_AUDIT_GENERAL_LOG
=
1
<<
0
,
/** occurs before transmitting errors to the user. */
MYSQL_AUDIT_GENERAL_ERROR
=
1
<<
1
,
/** occurs after transmitting a resultset to the user. */
MYSQL_AUDIT_GENERAL_RESULT
=
1
<<
2
,
/** occurs after transmitting a resultset or errors */
MYSQL_AUDIT_GENERAL_STATUS
=
1
<<
3
}
mysql_event_general_subclass_t
;
#define MYSQL_AUDIT_GENERAL_ALL (MYSQL_AUDIT_GENERAL_LOG | \
MYSQL_AUDIT_GENERAL_ERROR | \
MYSQL_AUDIT_GENERAL_RESULT | \
MYSQL_AUDIT_GENERAL_STATUS)
/**
@struct mysql_event_general
Structure for the MYSQL_AUDIT_GENERAL_CLASS event class.
*/
struct
mysql_event_general
{
mysql_event_general_subclass_t
event_subclass
;
int
general_error_code
;
unsigned
long
general_thread_id
;
MYSQL_LEX_CSTRING
general_user
;
MYSQL_LEX_CSTRING
general_command
;
MYSQL_LEX_CSTRING
general_query
;
struct
charset_info_st
*
general_charset
;
unsigned
long
long
general_time
;
unsigned
long
long
general_rows
;
MYSQL_LEX_CSTRING
general_host
;
MYSQL_LEX_CSTRING
general_sql_command
;
MYSQL_LEX_CSTRING
general_external_user
;
MYSQL_LEX_CSTRING
general_ip
;
};
/**
@enum mysql_event_connection_subclass_t
Events for MYSQL_AUDIT_CONNECTION_CLASS event class.
*/
typedef
enum
{
/** occurs after authentication phase is completed. */
MYSQL_AUDIT_CONNECTION_CONNECT
=
1
<<
0
,
/** occurs after connection is terminated. */
MYSQL_AUDIT_CONNECTION_DISCONNECT
=
1
<<
1
,
/** occurs after COM_CHANGE_USER RPC is completed. */
MYSQL_AUDIT_CONNECTION_CHANGE_USER
=
1
<<
2
,
/** occurs before authentication. */
MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE
=
1
<<
3
}
mysql_event_connection_subclass_t
;
#define MYSQL_AUDIT_CONNECTION_ALL (MYSQL_AUDIT_CONNECTION_CONNECT | \
MYSQL_AUDIT_CONNECTION_DISCONNECT | \
MYSQL_AUDIT_CONNECTION_CHANGE_USER | \
MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE)
/**
@struct mysql_event_connection
Structure for the MYSQL_AUDIT_CONNECTION_CLASS event class.
*/
struct
mysql_event_connection
{
/** Event subclass. */
mysql_event_connection_subclass_t
event_subclass
;
/** Current status of the connection. */
int
status
;
/** Connection id. */
unsigned
long
connection_id
;
/** User name of this connection. */
MYSQL_LEX_CSTRING
user
;
/** Priv user name. */
MYSQL_LEX_CSTRING
priv_user
;
/** External user name. */
MYSQL_LEX_CSTRING
external_user
;
/** Proxy user used for this connection. */
MYSQL_LEX_CSTRING
proxy_user
;
/** Connection host. */
MYSQL_LEX_CSTRING
host
;
/** IP of the connection. */
MYSQL_LEX_CSTRING
ip
;
/** Database name specified at connection time. */
MYSQL_LEX_CSTRING
database
;
/** Connection type:
- 0 Undefined
- 1 TCP/IP
- 2 Socket
- 3 Named pipe
- 4 SSL
- 5 Shared memory
*/
int
connection_type
;
};
/**
@enum mysql_event_parse_subclass_t
Events for MYSQL_AUDIT_PARSE_CLASS event class.
*/
typedef
enum
{
/** occurs before the query parsing. */
MYSQL_AUDIT_PARSE_PREPARSE
=
1
<<
0
,
/** occurs after the query parsing. */
MYSQL_AUDIT_PARSE_POSTPARSE
=
1
<<
1
}
mysql_event_parse_subclass_t
;
#define MYSQL_AUDIT_PARSE_ALL (MYSQL_AUDIT_PARSE_PREPARSE | \
MYSQL_AUDIT_PARSE_POSTPARSE)
typedef
enum
{
MYSQL_AUDIT_PARSE_REWRITE_PLUGIN_NONE
=
0
,
/// mysql_event_parse::flags Must be set by a plugin if the query is rewritten.
MYSQL_AUDIT_PARSE_REWRITE_PLUGIN_QUERY_REWRITTEN
=
1
<<
0
,
/// mysql_event_parse::flags Is set by the server if the query is prepared statement.
MYSQL_AUDIT_PARSE_REWRITE_PLUGIN_IS_PREPARED_STATEMENT
=
1
<<
1
}
mysql_event_parse_rewrite_plugin_flag
;
/** Data for the MYSQL_AUDIT_PARSE events */
struct
mysql_event_parse
{
/** MYSQL_AUDIT_[PRE|POST]_PARSE event id */
mysql_event_parse_subclass_t
event_subclass
;
/** one of FLAG_REWRITE_PLUGIN_* */
mysql_event_parse_rewrite_plugin_flag
*
flags
;
/** input: the original query text */
MYSQL_LEX_CSTRING
query
;
/** output: returns the null-terminated rewriten query allocated by my_malloc() */
MYSQL_LEX_CSTRING
*
rewritten_query
;
};
/**
@enum mysql_event_authorization_subclass_t
Events for MYSQL_AUDIT_AUTHORIZATION_CLASS event class.
*/
typedef
enum
{
MYSQL_AUDIT_AUTHORIZATION_USER
=
1
<<
0
,
/** Occurs when database privilege is checked. */
MYSQL_AUDIT_AUTHORIZATION_DB
=
1
<<
1
,
/** Occurs when table privilege is checked. */
MYSQL_AUDIT_AUTHORIZATION_TABLE
=
1
<<
2
,
/** Occurs when column privilege is checked. */
MYSQL_AUDIT_AUTHORIZATION_COLUMN
=
1
<<
3
,
/** Occurs when procedure privilege is checked. */
MYSQL_AUDIT_AUTHORIZATION_PROCEDURE
=
1
<<
4
,
/** Occurs when proxy privilege is checked. */
MYSQL_AUDIT_AUTHORIZATION_PROXY
=
1
<<
5
}
mysql_event_authorization_subclass_t
;
#define MYSQL_AUDIT_AUTHORIZATION_ALL (MYSQL_AUDIT_AUTHORIZATION_USER | \
MYSQL_AUDIT_AUTHORIZATION_DB | \
MYSQL_AUDIT_AUTHORIZATION_TABLE | \
MYSQL_AUDIT_AUTHORIZATION_COLUMN | \
MYSQL_AUDIT_AUTHORIZATION_PROCEDURE | \
MYSQL_AUDIT_AUTHORIZATION_PROXY)
/**
@struct mysql_event_authorization
Structure for MYSQL_AUDIT_AUTHORIZATION_CLASS event class.
*/
struct
mysql_event_authorization
{
/** Event subclass. */
mysql_event_authorization_subclass_t
event_subclass
;
/** Event status. */
int
status
;
/** Connection id. */
unsigned
int
connection_id
;
/** SQL command id. */
enum_sql_command_t
sql_command_id
;
/** SQL query text. */
MYSQL_LEX_CSTRING
query
;
/** SQL query charset. */
const
struct
charset_info_st
*
query_charset
;
/** Database name. */
MYSQL_LEX_CSTRING
database
;
/** Table name. */
MYSQL_LEX_CSTRING
table
;
/** Other name associated with the event. */
MYSQL_LEX_CSTRING
object
;
/** Requested authorization privileges. */
unsigned
long
requested_privilege
;
/** Currently granted authorization privileges. */
unsigned
long
granted_privilege
;
};
/**
@enum mysql_event_table_row_access_subclass_t
Events for MYSQL_AUDIT_TABLE_ACCES_CLASS event class.
*/
typedef
enum
{
/** Occurs when table data are read. */
MYSQL_AUDIT_TABLE_ACCESS_READ
=
1
<<
0
,
/** Occurs when table data are inserted. */
MYSQL_AUDIT_TABLE_ACCESS_INSERT
=
1
<<
1
,
/** Occurs when table data are updated. */
MYSQL_AUDIT_TABLE_ACCESS_UPDATE
=
1
<<
2
,
/** Occurs when table data are deleted. */
MYSQL_AUDIT_TABLE_ACCESS_DELETE
=
1
<<
3
}
mysql_event_table_access_subclass_t
;
#define MYSQL_AUDIT_TABLE_ACCESS_ALL (MYSQL_AUDIT_TABLE_ACCESS_READ | \
MYSQL_AUDIT_TABLE_ACCESS_INSERT | \
MYSQL_AUDIT_TABLE_ACCESS_UPDATE | \
MYSQL_AUDIT_TABLE_ACCESS_DELETE)
/**
@struct mysql_event_table_row_access
Structure for MYSQL_AUDIT_TABLE_ACCES_CLASS event class.
*/
struct
mysql_event_table_access
{
/** Event subclass. */
mysql_event_table_access_subclass_t
event_subclass
;
/** Connection id. */
unsigned
long
connection_id
;
/** SQL command id. */
enum_sql_command_t
sql_command_id
;
/** SQL query. */
MYSQL_LEX_CSTRING
query
;
/** SQL query charset. */
const
struct
charset_info_st
*
query_charset
;
/** Database name. */
MYSQL_LEX_CSTRING
table_database
;
/** Table name. */
MYSQL_LEX_CSTRING
table_name
;
};
/**
@enum mysql_event_global_variable_subclass_t
Events for MYSQL_AUDIT_GLOBAL_VARIABLE_CLASS event class.
*/
typedef
enum
{
/** Occurs when global variable is retrieved. */
MYSQL_AUDIT_GLOBAL_VARIABLE_GET
=
1
<<
0
,
/** Occurs when global variable is set. */
MYSQL_AUDIT_GLOBAL_VARIABLE_SET
=
1
<<
1
}
mysql_event_global_variable_subclass_t
;
#define MYSQL_AUDIT_GLOBAL_VARIABLE_ALL (MYSQL_AUDIT_GLOBAL_VARIABLE_GET | \
MYSQL_AUDIT_GLOBAL_VARIABLE_SET)
/** Events for MYSQL_AUDIT_GLOBAL_VARIABLE_CLASS event class. */
struct
mysql_event_global_variable
{
/** Event subclass. */
mysql_event_global_variable_subclass_t
event_subclass
;
/** Connection id. */
unsigned
long
connection_id
;
/** SQL command id. */
enum_sql_command_t
sql_command_id
;
/** Variable name. */
MYSQL_LEX_CSTRING
variable_name
;
/** Variable value. */
MYSQL_LEX_CSTRING
variable_value
;
};
/**
@enum mysql_event_server_startup_subclass_t
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
=
1
<<
0
}
mysql_event_server_startup_subclass_t
;
#define MYSQL_AUDIT_SERVER_STARTUP_ALL (MYSQL_AUDIT_SERVER_STARTUP_STARTUP)
/**
@struct mysql_event_server_startup
Structure 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
;
};
/**
@enum mysql_event_server_shutdown_subclass_t
Events for MYSQL_AUDIT_SERVER_SHUTDOWN_CLASS event class.
*/
typedef
enum
{
/** Occurs when global variable is set. */
MYSQL_AUDIT_SERVER_SHUTDOWN_SHUTDOWN
=
1
<<
0
}
mysql_event_server_shutdown_subclass_t
;
#define MYSQL_AUDIT_SERVER_SHUTDOWN_ALL (MYSQL_AUDIT_SERVER_SHUTDOWN_SHUTDOWN)
/**
@enum mysql_server_shutdown_reason_t
Server shutdown reason.
*/
typedef
enum
{
/** User requested shut down. */
MYSQL_AUDIT_SERVER_SHUTDOWN_REASON_SHUTDOWN
,
/** The server aborts. */
MYSQL_AUDIT_SERVER_SHUTDOWN_REASON_ABORT
}
mysql_server_shutdown_reason_t
;
/**
@struct mysql_event_server_shutdown
Structure for MYSQL_AUDIT_SERVER_SHUTDOWN_CLASS event class.
*/
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. */
mysql_server_shutdown_reason_t
reason
;
};
/**
@enum mysql_event_command_subclass_t
Events for MYSQL_AUDIT_COMMAND_CLASS event class.
*/
typedef
enum
{
/** Command start event. */
MYSQL_AUDIT_COMMAND_START
=
1
<<
0
,
/** Command end event. */
MYSQL_AUDIT_COMMAND_END
=
1
<<
1
}
mysql_event_command_subclass_t
;
#define MYSQL_AUDIT_COMMAND_ALL (MYSQL_AUDIT_COMMAND_START | \
MYSQL_AUDIT_COMMAND_END)
/**
@typedef enum_server_command_t
Server command type definition.
*/
typedef
enum
enum_server_command
enum_server_command_t
;
/**
@struct mysql_event_command
Event for MYSQL_AUDIT_COMMAND_CLASS event class.
Events generated as a result of RPC command requests.
*/
struct
mysql_event_command
{
/** Command event subclass. */
mysql_event_command_subclass_t
event_subclass
;
/** Command event status. */
int
status
;
/** Connection id. */
unsigned
long
connection_id
;
/** Command id. */
enum_server_command_t
command_id
;
};
/**
@enum mysql_event_query_subclass_t
Events for MYSQL_AUDIT_QUERY_CLASS event class.
*/
typedef
enum
{
/** Query start event. */
MYSQL_AUDIT_QUERY_START
=
1
<<
0
,
/** Nested query start event. */
MYSQL_AUDIT_QUERY_NESTED_START
=
1
<<
1
,
/** Query post parse event. */
MYSQL_AUDIT_QUERY_STATUS_END
=
1
<<
2
,
/** Nested query status end event. */
MYSQL_AUDIT_QUERY_NESTED_STATUS_END
=
1
<<
3
}
mysql_event_query_subclass_t
;
#define MYSQL_AUDIT_QUERY_ALL (MYSQL_AUDIT_QUERY_START | \
MYSQL_AUDIT_QUERY_NESTED_START | \
MYSQL_AUDIT_QUERY_STATUS_END | \
MYSQL_AUDIT_QUERY_NESTED_STATUS_END)
/**
@struct mysql_event_command
Event for MYSQL_AUDIT_COMMAND_CLASS event class.
*/
struct
mysql_event_query
{
/** Event subclass. */
mysql_event_query_subclass_t
event_subclass
;
/** Event status. */
int
status
;
/** Connection id. */
unsigned
long
connection_id
;
/** SQL command id. */
enum_sql_command_t
sql_command_id
;
/** SQL query. */
MYSQL_LEX_CSTRING
query
;
/** SQL query charset. */
const
struct
charset_info_st
*
query_charset
;
};
/**
@enum mysql_event_stored_program_subclass_t
Events for MYSQL_AUDIT_STORED_PROGRAM_CLASS event class.
*/
typedef
enum
{
/** Stored program execution event. */
MYSQL_AUDIT_STORED_PROGRAM_EXECUTE
=
1
<<
0
}
mysql_event_stored_program_subclass_t
;
#define MYSQL_AUDIT_STORED_PROGRAM_ALL (MYSQL_AUDIT_STORED_PROGRAM_EXECUTE)
/**
@struct mysql_event_command
Event for MYSQL_AUDIT_COMMAND_CLASS event class.
*/
struct
mysql_event_stored_program
{
/** Event subclass. */
mysql_event_stored_program_subclass_t
event_subclass
;
/** Connection id. */
unsigned
long
connection_id
;
/** SQL command id. */
enum_sql_command_t
sql_command_id
;
/** SQL query text. */
MYSQL_LEX_CSTRING
query
;
/** SQL query charset. */
const
struct
charset_info_st
*
query_charset
;
/** The Database the procedure is defined in. */
MYSQL_LEX_CSTRING
database
;
/** Name of the stored program. */
MYSQL_LEX_CSTRING
name
;
/** Stored program parameters. */
void
*
parameters
;
};
#endif
plugin/server_audit/server_audit.c
View file @
1793646d
...
...
@@ -14,13 +14,16 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define PLUGIN_VERSION 0x103
#define PLUGIN_STR_VERSION "1.3.0"
#define PLUGIN_VERSION 0x104
#define PLUGIN_STR_VERSION "1.4.0"
#define _my_thread_var loc_thread_var
#include <my_config.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <fcntl.h>
#ifndef _WIN32
#include <syslog.h>
...
...
@@ -80,8 +83,7 @@ static void closelog() {}
#endif
/*MARIADB_ONLY*/
#include <my_base.h>
//#include <hash.h>
#include <my_dir.h>
//#include <my_dir.h>
#include <typelib.h>
#include <mysql/plugin.h>
#include <mysql/plugin_audit.h>
...
...
@@ -89,75 +91,176 @@ static void closelog() {}
#define RTLD_DEFAULT NULL
#endif
#undef my_init_dynamic_array_ci
#define init_dynamic_array2 loc_init_dynamic_array2
#define my_init_dynamic_array_ci(A,B,C,D) loc_init_dynamic_array2(A,B,NULL,C,D)
#define my_hash_init2 loc_my_hash_init
#define my_hash_search loc_my_hash_search
#define my_hash_insert loc_my_hash_insert
#define my_hash_delete loc_my_hash_delete
#define my_hash_update loc_my_hash_update
#define my_hash_free loc_my_hash_free
#define my_hash_first loc_my_hash_first
#define my_hash_reset loc_my_hash_reset
#define my_hash_search_using_hash_value loc_my_hash_search_using_hash_value
#define my_hash_first_from_hash_value loc_my_hash_first_from_hash_value
#define my_hash_sort loc_my_hash_sort
#undef my_hash_first_from_hash_value
#define my_hash_first_from_hash_value loc_my_my_hash_first_from_hash_value
#define my_hash_next loc_my_hash_next
#define my_hash_element loc_my_hash_element
#define my_hash_replace loc_my_hash_replace
#define my_hash_iterate loc_my_hash_iterate
#define alloc_dynamic loc_alloc_dynamic
#define pop_dynamic loc_pop_dynamic
#define delete_dynamic loc_delete_dynamic
void
*
loc_alloc_dynamic
(
DYNAMIC_ARRAY
*
array
);
#ifdef my_strnncoll
#undef my_strnncoll
#define my_strnncoll(s, a, b, c, d) (my_strnncoll_binary((s), (a), (b), (c), (d), 0))
#endif
static
int
my_strnncoll_binary
(
CHARSET_INFO
*
cs
__attribute__
((
unused
)),
const
uchar
*
s
,
size_t
slen
,
const
uchar
*
t
,
size_t
tlen
,
my_bool
t_is_prefix
)
{
size_t
len
=
slen
<
tlen
?
slen
:
tlen
;
int
cmp
=
memcmp
(
s
,
t
,
len
);
return
cmp
?
cmp
:
(
int
)((
t_is_prefix
?
len
:
slen
)
-
tlen
);
}
#include "../../mysys/array.c"
#include "../../mysys/hash.c"
#ifndef MARIADB_ONLY
#undef MYSQL_SERVICE_LOGGER_INCLUDED
#undef MYSQL_DYNAMIC_PLUGIN
#define FLOGGER_NO_PSI
/* How to access the pthread_mutex in mysql_mutex_t */
#ifdef SAFE_MUTEX
#define mysql_mutex_real_mutex(A) &(A)->m_mutex.mutex
#elif defined(MY_PTHREAD_FASTMUTEX)
#define mysql_mutex_real_mutex(A) &(A)->m_mutex.mutex
#else
//
#ifdef SAFE_MUTEX
//
#define mysql_mutex_real_mutex(A) &(A)->m_mutex.mutex
//
#elif defined(MY_PTHREAD_FASTMUTEX)
//
#define mysql_mutex_real_mutex(A) &(A)->m_mutex.mutex
//
#else
#define mysql_mutex_real_mutex(A) &(A)->m_mutex
#endif
//
#endif
#define flogger_mutex_init(A,B,C)
pthread_mutex_init(mysql_mutex_real_mutex(B), C
)
#define flogger_mutex_destroy(A)
pthread_mutex_destroy(mysql_mutex_real_mutex(A)
)
#define flogger_mutex_lock(A)
pthread_mutex_lock(mysql_mutex_real_mutex(A)
)
#define flogger_mutex_unlock(A)
pthread_mutex_unlock(mysql_mutex_real_mutex(A)
)
#define flogger_mutex_init(A,B,C)
do{}while(0
)
#define flogger_mutex_destroy(A)
do{}while(0
)
#define flogger_mutex_lock(A)
do{}while(0
)
#define flogger_mutex_unlock(A)
do{}while(0
)
static
char
**
int_mysql_data_home
;
static
char
*
default_home
=
(
char
*
)
"."
;
#define mysql_data_home (*int_mysql_data_home)
#define FLOGGER_SKIP_INCLUDES
#define my_open(A, B, C) loc_open(A, B)
#define my_close(A, B) loc_close(A)
#define my_rename(A, B, C) loc_rename(A, B)
#define my_tell(A, B) loc_tell(A)
#define my_write(A, B, C, D) loc_write(A, B, C)
#define my_malloc(A, B) malloc(A)
#define my_free(A) free(A)
#ifdef my_errno
#undef my_errno
#endif
static
int
loc_file_errno
;
#define my_errno loc_file_errno
#ifdef my_vsnprintf
#undef my_vsnprintf
#endif
#define my_vsnprintf vsnprintf
#define logger_open loc_logger_open
#define logger_close loc_logger_close
#define logger_write loc_logger_write
#define logger_rotate loc_logger_rotate
#define logger_init_mutexts loc_logger_init_mutexts
static
size_t
loc_write
(
File
Filedes
,
const
uchar
*
Buffer
,
size_t
Count
)
{
size_t
writtenbytes
;
#ifdef _WIN32
writtenbytes
=
my_win_write
(
Filedes
,
Buffer
,
Count
);
#else
writtenbytes
=
write
(
Filedes
,
Buffer
,
Count
);
#endif
return
writtenbytes
;
}
static
File
loc_open
(
const
char
*
FileName
,
int
Flags
)
/* Path-name of file */
/* Read | write .. */
/* Special flags */
{
File
fd
;
#if defined(_WIN32)
fd
=
my_win_open
(
FileName
,
Flags
);
#elif !defined(NO_OPEN_3)
fd
=
open
(
FileName
,
Flags
,
my_umask
);
/* Normal unix */
#else
fd
=
open
((
char
*
)
FileName
,
Flags
);
#endif
my_errno
=
errno
;
return
fd
;
}
static
int
loc_close
(
File
fd
)
{
int
err
;
#ifndef _WIN32
do
{
err
=
close
(
fd
);
}
while
(
err
==
-
1
&&
errno
==
EINTR
);
#else
err
=
my_win_close
(
fd
);
#endif
my_errno
=
errno
;
return
err
;
}
static
int
loc_rename
(
const
char
*
from
,
const
char
*
to
)
{
int
error
=
0
;
#if defined(__WIN__)
if
(
!
MoveFileEx
(
from
,
to
,
MOVEFILE_COPY_ALLOWED
|
MOVEFILE_REPLACE_EXISTING
))
{
my_osmaperr
(
GetLastError
());
#elif defined(HAVE_RENAME)
if
(
rename
(
from
,
to
))
{
#else
if
(
link
(
from
,
to
)
||
unlink
(
from
))
{
#endif
my_errno
=
errno
;
error
=
-
1
;
}
return
error
;
}
static
my_off_t
loc_seek
(
File
fd
,
my_off_t
pos
,
int
whence
)
{
os_off_t
newpos
=
-
1
;
#ifdef _WIN32
newpos
=
my_win_lseek
(
fd
,
pos
,
whence
);
#else
newpos
=
lseek
(
fd
,
pos
,
whence
);
#endif
if
(
newpos
==
(
os_off_t
)
-
1
)
{
my_errno
=
errno
;
return
MY_FILEPOS_ERROR
;
}
return
(
my_off_t
)
newpos
;
}
static
my_off_t
loc_tell
(
File
fd
)
{
os_off_t
pos
;
#if defined (HAVE_TELL) && !defined (_WIN32)
pos
=
tell
(
fd
);
#else
pos
=
loc_seek
(
fd
,
0L
,
MY_SEEK_CUR
);
#endif
if
(
pos
==
(
os_off_t
)
-
1
)
{
my_errno
=
errno
;
}
return
(
my_off_t
)
pos
;
}
#ifdef HAVE_PSI_INTERFACE
#undef HAVE_PSI_INTERFACE
#include <mysql/service_logger.h>
#include "../../mysys/file_logger.c"
#define HAVE_PSI_INTERFACE
#else
#include <mysql/service_logger.h>
#include "../../mysys/file_logger.c"
#endif
#endif
/*!MARIADB_ONLY*/
#undef flogger_mutex_init
#undef flogger_mutex_destroy
#undef flogger_mutex_lock
#undef flogger_mutex_unlock
#define flogger_mutex_init(A,B,C) pthread_mutex_init(mysql_mutex_real_mutex(B), C)
#define flogger_mutex_destroy(A) pthread_mutex_destroy(mysql_mutex_real_mutex(A))
#define flogger_mutex_lock(A) pthread_mutex_lock(mysql_mutex_real_mutex(A))
#define flogger_mutex_unlock(A) pthread_mutex_unlock(mysql_mutex_real_mutex(A))
#ifndef DBUG_OFF
#define PLUGIN_DEBUG_VERSION "-debug"
#else
...
...
@@ -178,7 +281,11 @@ static char *default_home= (char *)".";
extern
char
server_version
[];
static
const
char
*
serv_ver
=
NULL
;
static
int
started_mysql
=
0
;
static
int
mysql_57_started
=
0
;
static
int
debug_server_started
=
0
;
static
int
use_event_data_for_disconnect
=
0
;
static
int
started_mariadb
=
0
;
static
int
maria_55_started
=
0
;
static
int
maria_above_5
=
0
;
static
char
*
incl_users
,
*
excl_users
,
*
file_path
,
*
syslog_info
;
...
...
@@ -203,6 +310,27 @@ static char servhost[256];
static
size_t
servhost_len
;
static
char
*
syslog_ident
;
static
char
syslog_ident_buffer
[
128
]
=
"mysql-server_auditing"
;
struct
connection_info
{
int
header
;
unsigned
long
thread_id
;
unsigned
long
long
query_id
;
char
db
[
256
];
int
db_length
;
char
user
[
64
];
int
user_length
;
char
host
[
64
];
int
host_length
;
char
ip
[
64
];
int
ip_length
;
const
char
*
query
;
int
query_length
;
char
query_buffer
[
1024
];
time_t
query_time
;
int
log_always
;
};
#define DEFAULT_FILENAME_LEN 16
static
char
default_file_name
[
DEFAULT_FILENAME_LEN
+
1
]
=
"server_audit.log"
;
...
...
@@ -256,7 +384,8 @@ static TYPELIB events_typelib=
array_elements
(
event_names
)
-
1
,
""
,
event_names
,
NULL
};
static
MYSQL_SYSVAR_SET
(
events
,
events
,
PLUGIN_VAR_RQCMDARG
,
"Specifies the set of events to monitor. Can be CONNECT, QUERY, TABLE, QUERY_DDL, QUERY_DML."
,
"Specifies the set of events to monitor. Can be CONNECT, QUERY, TABLE,"
" QUERY_DDL, QUERY_DML, QUERY_DCL."
,
NULL
,
NULL
,
0
,
&
events_typelib
);
#define OUTPUT_SYSLOG 0
#define OUTPUT_FILE 1
...
...
@@ -297,6 +426,13 @@ static MYSQL_SYSVAR_UINT(query_log_limit, query_log_limit,
PLUGIN_VAR_OPCMDARG
,
"Limit on the length of the query string in a record."
,
NULL
,
NULL
,
1024
,
0
,
0x7FFFFFFF
,
1
);
char
locinfo_ini_value
[
sizeof
(
struct
connection_info
)
+
4
];
static
MYSQL_THDVAR_STR
(
loc_info
,
PLUGIN_VAR_READONLY
|
PLUGIN_VAR_MEMALLOC
,
"Auxiliary info."
,
NULL
,
NULL
,
locinfo_ini_value
);
static
const
char
*
syslog_facility_names
[]
=
{
"LOG_USER"
,
"LOG_MAIL"
,
"LOG_DAEMON"
,
"LOG_AUTH"
,
...
...
@@ -376,6 +512,7 @@ static struct st_mysql_sys_var* vars[] = {
MYSQL_SYSVAR
(
syslog_facility
),
MYSQL_SYSVAR
(
syslog_priority
),
MYSQL_SYSVAR
(
query_log_limit
),
MYSQL_SYSVAR
(
loc_info
),
NULL
};
...
...
@@ -386,6 +523,8 @@ static long log_write_failures= 0;
static
char
current_log_buf
[
FN_REFLEN
]
=
""
;
static
char
last_error_buf
[
512
]
=
""
;
extern
void
*
mysql_v4_descriptor
;
static
struct
st_mysql_show_var
audit_status
[]
=
{
{
"server_audit_active"
,
(
char
*
)
&
is_active
,
SHOW_BOOL
},
...
...
@@ -425,7 +564,7 @@ static uchar *getkey_user(const char *entry, size_t *length,
}
static
void
blank_user
(
u
char
*
user
)
static
void
blank_user
(
char
*
user
)
{
for
(;
*
user
&&
*
user
!=
','
;
user
++
)
*
user
=
' '
;
...
...
@@ -485,19 +624,98 @@ static void remove_blanks(char *user)
}
static
int
user_hash_fill
(
HASH
*
h
,
char
*
users
,
HASH
*
cmp_hash
,
int
take_over_cmp
)
struct
user_name
{
int
name_len
;
char
*
name
;
};
struct
user_coll
{
int
n_users
;
struct
user_name
*
users
;
int
n_alloced
;
};
static
void
coll_init
(
struct
user_coll
*
c
)
{
c
->
n_users
=
0
;
c
->
users
=
0
;
c
->
n_alloced
=
0
;
}
static
void
coll_free
(
struct
user_coll
*
c
)
{
if
(
c
->
users
)
{
free
(
c
->
users
);
coll_init
(
c
);
}
}
static
int
cmp_users
(
const
void
*
ia
,
const
void
*
ib
)
{
const
struct
user_name
*
a
=
(
const
struct
user_name
*
)
ia
;
const
struct
user_name
*
b
=
(
const
struct
user_name
*
)
ib
;
int
dl
=
a
->
name_len
-
b
->
name_len
;
if
(
dl
!=
0
)
return
dl
;
return
strncmp
(
a
->
name
,
b
->
name
,
a
->
name_len
);
}
static
char
*
coll_search
(
struct
user_coll
*
c
,
const
char
*
n
,
int
len
)
{
struct
user_name
un
;
struct
user_name
*
found
;
un
.
name_len
=
len
;
un
.
name
=
(
char
*
)
n
;
found
=
(
struct
user_name
*
)
bsearch
(
&
un
,
c
->
users
,
c
->
n_users
,
sizeof
(
c
->
users
[
0
]),
cmp_users
);
return
found
?
found
->
name
:
0
;
}
static
int
coll_insert
(
struct
user_coll
*
c
,
char
*
n
,
int
len
)
{
if
(
c
->
n_users
>=
c
->
n_alloced
)
{
c
->
n_alloced
+=
128
;
if
(
c
->
users
==
NULL
)
c
->
users
=
malloc
(
c
->
n_alloced
*
sizeof
(
c
->
users
[
0
]));
else
c
->
users
=
realloc
(
c
->
users
,
c
->
n_alloced
*
sizeof
(
c
->
users
[
0
]));
if
(
c
->
users
==
NULL
)
return
1
;
}
c
->
users
[
c
->
n_users
].
name
=
n
;
c
->
users
[
c
->
n_users
].
name_len
=
len
;
c
->
n_users
++
;
return
0
;
}
static
void
coll_sort
(
struct
user_coll
*
c
)
{
qsort
(
c
->
users
,
c
->
n_users
,
sizeof
(
c
->
users
[
0
]),
cmp_users
);
}
static
int
user_coll_fill
(
struct
user_coll
*
c
,
char
*
users
,
struct
user_coll
*
cmp_c
,
int
take_over_cmp
)
{
char
*
orig_users
=
users
;
u
char
*
cmp_user
=
0
;
char
*
cmp_user
=
0
;
size_t
cmp_length
;
int
refill_cmp_
hash
=
0
;
int
refill_cmp_
coll
=
0
;
if
(
my_hash_inited
(
h
))
my_hash_reset
(
h
);
else
loc_my_hash_init
(
h
,
0
,
&
my_charset_bin
,
0x100
,
0
,
0
,
(
my_hash_get_key
)
getkey_user
,
0
,
0
,
0
);
c
->
n_users
=
0
;
while
(
*
users
)
{
...
...
@@ -506,11 +724,10 @@ static int user_hash_fill(HASH *h, char *users,
if
(
!*
users
)
return
0
;
if
(
cmp_hash
)
{
(
void
)
getkey_user
(
users
,
&
cmp_length
,
FALSE
);
cmp_user
=
my_hash_search
(
cmp_hash
,
(
const
uchar
*
)
users
,
cmp_length
);
if
(
cmp_c
)
{
cmp_user
=
coll_search
(
cmp_c
,
users
,
cmp_length
);
if
(
cmp_user
&&
take_over_cmp
)
{
...
...
@@ -520,7 +737,7 @@ static int user_hash_fill(HASH *h, char *users,
MYF
(
ME_JUST_WARNING
),
(
int
)
cmp_length
,
users
);
internal_stop_logging
=
0
;
blank_user
(
cmp_user
);
refill_cmp_
hash
=
1
;
refill_cmp_
coll
=
1
;
}
else
if
(
cmp_user
)
{
...
...
@@ -532,7 +749,7 @@ static int user_hash_fill(HASH *h, char *users,
continue
;
}
}
if
(
my_hash_insert
(
h
,
(
const
uchar
*
)
users
))
if
(
coll_insert
(
c
,
users
,
cmp_length
))
return
1
;
while
(
*
users
&&
*
users
!=
','
)
users
++
;
...
...
@@ -541,15 +758,17 @@ static int user_hash_fill(HASH *h, char *users,
users
++
;
}
if
(
refill_cmp_
hash
)
if
(
refill_cmp_
coll
)
{
remove_blanks
(
excl_users
);
return
user_
hash_fill
(
cmp_hash
,
excl_users
,
0
,
0
);
return
user_
coll_fill
(
cmp_c
,
excl_users
,
0
,
0
);
}
if
(
users
>
orig_users
&&
users
[
-
1
]
==
','
)
users
[
-
1
]
=
0
;
coll_sort
(
c
);
return
0
;
}
...
...
@@ -678,48 +897,19 @@ static void error_header()
static
LOGGER_HANDLE
*
logfile
;
static
HASH
incl_user_hash
,
excl_user_hash
;
static
struct
user_coll
incl_user_coll
,
excl_user_coll
;
static
unsigned
long
long
query_counter
=
1
;
struct
connection_info
{
unsigned
long
thread_id
;
unsigned
long
long
query_id
;
char
db
[
256
];
int
db_length
;
char
user
[
64
];
int
user_length
;
char
host
[
64
];
int
host_length
;
char
ip
[
64
];
int
ip_length
;
const
char
*
query
;
int
query_length
;
char
query_buffer
[
1024
];
time_t
query_time
;
int
log_always
;
};
static
HASH
connection_hash
;
struct
connection_info
*
alloc_connection
()
{
return
malloc
(
ALIGN_SIZE
(
sizeof
(
struct
connection_info
)));
}
void
free_connection
(
void
*
pconn
)
static
struct
connection_info
*
get_loc_info
(
MYSQL_THD
thd
)
{
(
void
)
free
(
pconn
);
return
(
struct
connection_info
*
)
THDVAR
(
thd
,
loc_info
);
}
static
struct
connection_info
*
find_connection
(
unsigned
long
id
)
static
int
ci_needs_setup
(
const
struct
connection_info
*
ci
)
{
return
(
struct
connection_info
*
)
my_hash_search
(
&
connection_hash
,
(
const
uchar
*
)
&
id
,
sizeof
(
id
));
return
ci
->
header
!=
0
;
}
...
...
@@ -883,15 +1073,24 @@ static int stop_logging()
return
0
;
}
static
struct
connection_info
*
add_connection
(
const
struct
mysql_event_connection
*
event
)
static
void
setup_connection_simple
(
struct
connection_info
*
ci
)
{
ci
->
db_length
=
0
;
ci
->
user_length
=
0
;
ci
->
host_length
=
0
;
ci
->
ip_length
=
0
;
ci
->
query_length
=
0
;
ci
->
header
=
0
;
}
static
void
setup_connection_connect
(
struct
connection_info
*
cn
,
const
struct
mysql_event_connection
*
event
)
{
struct
connection_info
*
cn
=
alloc_connection
();
if
(
!
cn
)
return
0
;
cn
->
thread_id
=
event
->
thread_id
;
cn
->
query_id
=
0
;
cn
->
log_always
=
0
;
cn
->
thread_id
=
event
->
thread_id
;
get_str_n
(
cn
->
db
,
&
cn
->
db_length
,
sizeof
(
cn
->
db
),
event
->
database
,
event
->
database_length
);
get_str_n
(
cn
->
user
,
&
cn
->
user_length
,
sizeof
(
cn
->
db
),
...
...
@@ -900,11 +1099,7 @@ static struct connection_info *
event
->
host
,
event
->
host_length
);
get_str_n
(
cn
->
ip
,
&
cn
->
ip_length
,
sizeof
(
cn
->
ip
),
event
->
ip
,
event
->
ip_length
);
if
(
my_hash_insert
(
&
connection_hash
,
(
const
uchar
*
)
cn
))
return
0
;
return
cn
;
cn
->
header
=
0
;
}
...
...
@@ -927,46 +1122,43 @@ do { \
static
struct
connection_info
*
add_connection_initdb
(
const
struct
mysql_event_general
*
event
)
static
void
setup_connection_initdb
(
struct
connection_info
*
cn
,
const
struct
mysql_event_general
*
event
)
{
struct
connection_info
*
cn
;
size_t
user_len
,
host_len
,
ip_len
;
char
uh_buffer
[
512
];
if
(
get_user_host
(
event
->
general_user
,
event
->
general_user_length
,
uh_buffer
,
sizeof
(
uh_buffer
),
&
user_len
,
&
host_len
,
&
ip_len
)
||
(
cn
=
alloc_connection
())
==
NULL
)
return
0
;
cn
->
thread_id
=
event
->
general_thread_id
;
cn
->
query_id
=
0
;
cn
->
log_always
=
0
;
get_str_n
(
cn
->
db
,
&
cn
->
db_length
,
sizeof
(
cn
->
db
),
event
->
general_query
,
event
->
general_query_length
);
if
(
get_user_host
(
event
->
general_user
,
event
->
general_user_length
,
uh_buffer
,
sizeof
(
uh_buffer
),
&
user_len
,
&
host_len
,
&
ip_len
))
{
/* The user@host line is incorrect. */
cn
->
user_length
=
0
;
cn
->
host_length
=
0
;
cn
->
ip_length
=
0
;
}
else
{
get_str_n
(
cn
->
user
,
&
cn
->
user_length
,
sizeof
(
cn
->
db
),
uh_buffer
,
user_len
);
get_str_n
(
cn
->
host
,
&
cn
->
host_length
,
sizeof
(
cn
->
host
),
uh_buffer
+
user_len
+
1
,
host_len
);
get_str_n
(
cn
->
ip
,
&
cn
->
ip_length
,
sizeof
(
cn
->
ip
),
uh_buffer
+
user_len
+
1
+
host_len
+
1
,
ip_len
);
if
(
my_hash_insert
(
&
connection_hash
,
(
const
uchar
*
)
cn
))
return
0
;
return
cn
;
}
cn
->
header
=
0
;
}
static
struct
connection_info
*
add_connection_table
(
const
struct
mysql_event_table
*
event
)
static
void
setup_connection_table
(
struct
connection_info
*
cn
,
const
struct
mysql_event_table
*
event
)
{
struct
connection_info
*
cn
;
if
((
cn
=
alloc_connection
())
==
NULL
)
return
0
;
cn
->
thread_id
=
event
->
thread_id
;
cn
->
query_id
=
query_counter
++
;
cn
->
log_always
=
0
;
...
...
@@ -978,42 +1170,40 @@ static struct connection_info *
event
->
host
,
SAFE_STRLEN
(
event
->
host
));
get_str_n
(
cn
->
ip
,
&
cn
->
ip_length
,
sizeof
(
cn
->
ip
),
event
->
ip
,
SAFE_STRLEN
(
event
->
ip
));
if
(
my_hash_insert
(
&
connection_hash
,
(
const
uchar
*
)
cn
))
return
0
;
return
cn
;
cn
->
header
=
0
;
}
static
struct
connection_info
*
add_connection_query
(
const
struct
mysql_event_general
*
event
)
static
void
setup_connection_query
(
struct
connection_info
*
cn
,
const
struct
mysql_event_general
*
event
)
{
struct
connection_info
*
cn
;
size_t
user_len
,
host_len
,
ip_len
;
char
uh_buffer
[
512
];
if
(
get_user_host
(
event
->
general_user
,
event
->
general_user_length
,
uh_buffer
,
sizeof
(
uh_buffer
),
&
user_len
,
&
host_len
,
&
ip_len
)
||
(
cn
=
alloc_connection
())
==
NULL
)
return
0
;
cn
->
thread_id
=
event
->
general_thread_id
;
cn
->
query_id
=
query_counter
++
;
cn
->
log_always
=
0
;
get_str_n
(
cn
->
db
,
&
cn
->
db_length
,
sizeof
(
cn
->
db
),
""
,
0
);
if
(
get_user_host
(
event
->
general_user
,
event
->
general_user_length
,
uh_buffer
,
sizeof
(
uh_buffer
),
&
user_len
,
&
host_len
,
&
ip_len
))
{
/* The user@host line is incorrect. */
cn
->
user_length
=
0
;
cn
->
host_length
=
0
;
cn
->
ip_length
=
0
;
}
else
{
get_str_n
(
cn
->
user
,
&
cn
->
user_length
,
sizeof
(
cn
->
db
),
uh_buffer
,
user_len
);
get_str_n
(
cn
->
host
,
&
cn
->
host_length
,
sizeof
(
cn
->
host
),
uh_buffer
+
user_len
+
1
,
host_len
);
get_str_n
(
cn
->
ip
,
&
cn
->
ip_length
,
sizeof
(
cn
->
ip
),
uh_buffer
+
user_len
+
1
+
host_len
+
1
,
ip_len
);
if
(
my_hash_insert
(
&
connection_hash
,
(
const
uchar
*
)
cn
))
return
0
;
return
cn
;
}
cn
->
header
=
0
;
}
...
...
@@ -1105,6 +1295,27 @@ static int log_connection(const struct connection_info *cn,
}
static
int
log_connection_event
(
const
struct
mysql_event_connection
*
event
,
const
char
*
type
)
{
time_t
ctime
;
size_t
csize
;
char
message
[
1024
];
(
void
)
time
(
&
ctime
);
csize
=
log_header
(
message
,
sizeof
(
message
)
-
1
,
&
ctime
,
servhost
,
servhost_len
,
event
->
user
,
event
->
user_length
,
event
->
host
,
event
->
host_length
,
event
->
ip
,
event
->
ip_length
,
event
->
thread_id
,
0
,
type
);
csize
+=
my_snprintf
(
message
+
csize
,
sizeof
(
message
)
-
1
-
csize
,
",%.*s,,%d"
,
event
->
database_length
,
event
->
database
,
event
->
status
);
message
[
csize
]
=
'\n'
;
return
write_log
(
message
,
csize
+
1
);
}
static
size_t
escape_string
(
const
char
*
str
,
unsigned
int
len
,
char
*
result
,
size_t
result_len
)
{
...
...
@@ -1250,11 +1461,11 @@ static int do_log_user(const char *name)
return
0
;
len
=
strlen
(
name
);
if
(
incl_user_
hash
.
record
s
)
return
my_hash_search
(
&
incl_user_hash
,
(
const
uchar
*
)
name
,
len
)
!=
0
;
if
(
incl_user_
coll
.
n_user
s
)
return
coll_search
(
&
incl_user_coll
,
name
,
len
)
!=
0
;
if
(
excl_user_
hash
.
record
s
)
return
my_hash_search
(
&
excl_user_hash
,
(
const
uchar
*
)
name
,
len
)
==
0
;
if
(
excl_user_
coll
.
n_user
s
)
return
coll_search
(
&
excl_user_coll
,
name
,
len
)
==
0
;
return
1
;
}
...
...
@@ -1592,14 +1803,14 @@ static void update_general_user(struct connection_info *cn,
}
static
struct
connection_info
ci_disconnect_buffer
;
#define AA_FREE_CONNECTION 1
#define AA_CHANGE_USER 2
static
struct
connection_info
*
update_connection_hash
(
unsigned
int
event_class
,
const
void
*
ev
,
int
*
after_action
)
static
void
update_connection_info
(
struct
connection_info
*
cn
,
unsigned
int
event_class
,
const
void
*
ev
,
int
*
after_action
)
{
struct
connection_info
*
cn
=
NULL
;
*
after_action
=
0
;
switch
(
event_class
)
{
...
...
@@ -1612,11 +1823,15 @@ static struct connection_info *update_connection_hash(unsigned int event_class,
{
int
init_db_command
=
event
->
general_command_length
==
7
&&
strncmp
(
event
->
general_command
,
"Init DB"
,
7
)
==
0
;
if
(
(
cn
=
find_connection
(
event
->
general_thread_id
)
))
if
(
!
ci_needs_setup
(
cn
))
{
if
(
init_db_command
)
{
/* Change DB */
if
(
mysql_57_started
)
get_str_n
(
cn
->
db
,
&
cn
->
db_length
,
sizeof
(
cn
->
db
),
event
->
database
,
event
->
database_length
);
else
get_str_n
(
cn
->
db
,
&
cn
->
db_length
,
sizeof
(
cn
->
db
),
event
->
general_query
,
event
->
general_query_length
);
}
...
...
@@ -1627,18 +1842,19 @@ static struct connection_info *update_connection_hash(unsigned int event_class,
update_general_user
(
cn
,
event
);
}
else
if
(
init_db_command
)
cn
=
add_connection_initdb
(
event
);
setup_connection_initdb
(
cn
,
event
);
else
if
(
event_query_command
(
event
))
cn
=
add_connection_query
(
event
);
setup_connection_query
(
cn
,
event
);
else
setup_connection_simple
(
cn
);
break
;
}
case
MYSQL_AUDIT_GENERAL_STATUS
:
if
(
event_query_command
(
event
))
{
if
(
!
(
cn
=
find_connection
(
event
->
general_thread_id
))
&&
!
(
cn
=
add_connection_query
(
event
)))
return
0
;
if
(
ci_needs_setup
(
cn
))
setup_connection_query
(
cn
,
event
);
if
(
mode
==
0
&&
cn
->
db_length
==
0
&&
event
->
database_length
>
0
)
get_str_n
(
cn
->
db
,
&
cn
->
db_length
,
sizeof
(
cn
->
db
),
...
...
@@ -1664,13 +1880,13 @@ static struct connection_info *update_connection_hash(unsigned int event_class,
}
break
;
case
MYSQL_AUDIT_GENERAL_ERROR
:
/*
We need this because of a bug in the MariaDB */
/* that it returns NULL query field for the */
/* MYSQL_AUDIT_GENERAL_STATUS in the mysqld_stmt_prepare. */
/* As a result we get empty QUERY field for errors. */
if
(
!
(
cn
=
find_connection
(
event
->
general_thread_id
))
&&
!
(
cn
=
add_connection_query
(
event
)
))
return
0
;
/*
We need this because the MariaDB returns NULL query field for the
MYSQL_AUDIT_GENERAL_STATUS in the mysqld_stmt_prepare.
As a result we get empty QUERY field for errors.
*/
if
(
ci_needs_setup
(
cn
))
setup_connection_query
(
cn
,
event
)
;
cn
->
query_id
=
mode
?
query_counter
++
:
event
->
query_id
;
get_str_n
(
cn
->
query_buffer
,
&
cn
->
query_length
,
sizeof
(
cn
->
query_buffer
),
event
->
general_query
,
event
->
general_query_length
);
...
...
@@ -1685,9 +1901,9 @@ static struct connection_info *update_connection_hash(unsigned int event_class,
{
const
struct
mysql_event_table
*
event
=
(
const
struct
mysql_event_table
*
)
ev
;
if
(
!
(
cn
=
find_connection
(
event
->
thread_id
))
&&
!
(
cn
=
add_connection_table
(
event
)))
return
0
;
if
(
ci_needs_setup
(
cn
))
setup_connection_table
(
cn
,
event
);
if
(
cn
->
user_length
==
0
&&
cn
->
host_length
==
0
&&
cn
->
ip_length
==
0
)
{
get_str_n
(
cn
->
user
,
&
cn
->
user_length
,
sizeof
(
cn
->
user
),
...
...
@@ -1713,16 +1929,9 @@ static struct connection_info *update_connection_hash(unsigned int event_class,
switch
(
event
->
event_subclass
)
{
case
MYSQL_AUDIT_CONNECTION_CONNECT
:
cn
=
add_connection
(
ev
);
break
;
case
MYSQL_AUDIT_CONNECTION_DISCONNECT
:
cn
=
find_connection
(
event
->
thread_id
);
if
(
cn
)
*
after_action
=
AA_FREE_CONNECTION
;
setup_connection_connect
(
cn
,
event
);
break
;
case
MYSQL_AUDIT_CONNECTION_CHANGE_USER
:
cn
=
find_connection
(
event
->
thread_id
);
if
(
cn
)
*
after_action
=
AA_CHANGE_USER
;
break
;
default:
;
...
...
@@ -1732,17 +1941,17 @@ static struct connection_info *update_connection_hash(unsigned int event_class,
default:
break
;
}
return
cn
;
}
struct
connection_info
cn_error_buffer
;
#define FILTER(MASK) (events == 0 || (events & MASK))
static
void
auditing
(
MYSQL_THD
thd
__attribute__
((
unused
)),
unsigned
int
event_class
,
const
void
*
ev
)
void
auditing
(
MYSQL_THD
thd
,
unsigned
int
event_class
,
const
void
*
ev
)
{
struct
connection_info
*
cn
;
int
after_action
;
struct
connection_info
*
cn
=
0
;
int
after_action
=
0
;
/* That one is important as this function can be called with */
/* &lock_operations locked when the server logs an error reported */
...
...
@@ -1752,8 +1961,35 @@ static void auditing(MYSQL_THD thd __attribute__((unused)),
flogger_mutex_lock
(
&
lock_operations
);
if
(
!
(
cn
=
update_connection_hash
(
event_class
,
ev
,
&
after_action
)))
goto
exit_func
;
if
(
maria_55_started
&&
debug_server_started
&&
event_class
==
MYSQL_AUDIT_GENERAL_CLASS
)
{
/*
There's a bug in MariaDB 5.5 that prevents using thread local
variables in some cases.
The 'select * from notexisting_table;' query produces such case.
So just use the static buffer in this case.
*/
const
struct
mysql_event_general
*
event
=
(
const
struct
mysql_event_general
*
)
ev
;
if
(
event
->
event_subclass
==
MYSQL_AUDIT_GENERAL_ERROR
||
(
event
->
event_subclass
==
MYSQL_AUDIT_GENERAL_STATUS
&&
event
->
general_query_length
==
0
&&
cn_error_buffer
.
query_id
==
event
->
query_id
))
{
cn
=
&
cn_error_buffer
;
cn
->
header
=
1
;
}
else
cn
=
get_loc_info
(
thd
);
}
else
{
cn
=
get_loc_info
(
thd
);
}
update_connection_info
(
cn
,
event_class
,
ev
,
&
after_action
);
if
(
!
logging
)
goto
exit_func
;
...
...
@@ -1767,9 +2003,12 @@ static void auditing(MYSQL_THD thd __attribute__((unused)),
/*
Only one subclass is logged.
*/
if
(
event
->
event_subclass
==
MYSQL_AUDIT_GENERAL_STATUS
)
if
(
event
->
event_subclass
==
MYSQL_AUDIT_GENERAL_STATUS
&&
event_query_command
(
event
))
{
log_statement
(
cn
,
event
,
"QUERY"
);
}
}
else
if
(
event_class
==
MYSQL_AUDIT_TABLE_CLASS
&&
FILTER
(
EVENT_TABLE
)
&&
cn
)
{
const
struct
mysql_event_table
*
event
=
...
...
@@ -1809,7 +2048,10 @@ static void auditing(MYSQL_THD thd __attribute__((unused)),
log_connection
(
cn
,
event
,
event
->
status
?
"FAILED_CONNECT"
:
"CONNECT"
);
break
;
case
MYSQL_AUDIT_CONNECTION_DISCONNECT
:
log_connection
(
cn
,
event
,
"DISCONNECT"
);
if
(
use_event_data_for_disconnect
)
log_connection_event
(
event
,
"DISCONNECT"
);
else
log_connection
(
&
ci_disconnect_buffer
,
event
,
"DISCONNECT"
);
break
;
case
MYSQL_AUDIT_CONNECTION_CHANGE_USER
:
log_connection
(
cn
,
event
,
"CHANGEUSER"
);
...
...
@@ -1824,10 +2066,6 @@ exit_func:
if
(
after_action
)
{
switch
(
after_action
)
{
case
AA_FREE_CONNECTION
:
my_hash_delete
(
&
connection_hash
,
(
uchar
*
)
cn
);
cn
=
0
;
break
;
case
AA_CHANGE_USER
:
{
const
struct
mysql_event_connection
*
event
=
...
...
@@ -1845,28 +2083,6 @@ exit_func:
}
#ifdef DBUG_OFF
#ifdef __x86_64__
static
const
int
cmd_off
=
4200
;
static
const
int
db_off
=
120
;
static
const
int
db_len_off
=
128
;
#else
static
const
int
cmd_off
=
2668
;
static
const
int
db_off
=
60
;
static
const
int
db_len_off
=
64
;
#endif
/*x86_64*/
#else
#ifdef __x86_64__
static
const
int
cmd_off
=
4432
;
static
const
int
db_off
=
120
;
static
const
int
db_len_off
=
128
;
#else
static
const
int
cmd_off
=
2808
;
static
const
int
db_off
=
64
;
static
const
int
db_len_off
=
68
;
#endif
/*x86_64*/
#endif
/*DBUG_OFF*/
struct
mysql_event_general_v8
{
unsigned
int
event_class
;
...
...
@@ -1884,8 +2100,31 @@ struct mysql_event_general_v8
unsigned
long
long
general_rows
;
};
static
void
auditing_v8
(
MYSQL_THD
thd
,
struct
mysql_event_general_v8
*
ev_v8
)
{
#ifdef DBUG_OFF
#ifdef __x86_64__
static
const
int
cmd_off
=
4200
;
static
const
int
db_off
=
120
;
static
const
int
db_len_off
=
128
;
#else
static
const
int
cmd_off
=
2668
;
static
const
int
db_off
=
60
;
static
const
int
db_len_off
=
64
;
#endif
/*x86_64*/
#else
#ifdef __x86_64__
static
const
int
cmd_off
=
4432
;
static
const
int
db_off
=
120
;
static
const
int
db_len_off
=
128
;
#else
static
const
int
cmd_off
=
2808
;
static
const
int
db_off
=
64
;
static
const
int
db_len_off
=
68
;
#endif
/*x86_64*/
#endif
/*DBUG_OFF*/
struct
mysql_event_general
event
;
if
(
ev_v8
->
event_class
!=
MYSQL_AUDIT_GENERAL_CLASS
)
...
...
@@ -1944,6 +2183,41 @@ static void auditing_v13(MYSQL_THD thd, unsigned int *ev_v0)
}
int
get_db_mysql57
(
MYSQL_THD
thd
,
char
**
name
,
int
*
len
)
{
int
db_off
;
int
db_len_off
;
if
(
debug_server_started
)
{
#ifdef __x86_64__
db_off
=
608
;
db_len_off
=
616
;
#else
db_off
=
0
;
db_len_off
=
0
;
#endif
/*x86_64*/
}
else
{
#ifdef __x86_64__
db_off
=
536
;
db_len_off
=
544
;
#else
db_off
=
0
;
db_len_off
=
0
;
#endif
/*x86_64*/
}
#ifdef __linux__
*
name
=
*
(
char
**
)
(((
char
*
)
thd
)
+
db_off
);
*
len
=
*
((
int
*
)
(((
char
*
)
thd
)
+
db_len_off
));
if
(
*
name
&&
(
*
name
)[
*
len
]
!=
0
)
return
1
;
return
0
;
#else
return
1
;
#endif
}
/*
As it's just too difficult to #include "sql_class.h",
let's just copy the necessary part of the system_variables
...
...
@@ -2070,8 +2344,8 @@ static int server_audit_init(void *p __attribute__((unused)))
flogger_mutex_init
(
key_LOCK_operations
,
&
lock_operations
,
MY_MUTEX_INIT_FAST
);
flogger_mutex_init
(
key_LOCK_operations
,
&
lock_bigbuffer
,
MY_MUTEX_INIT_FAST
);
my_hash_clear
(
&
incl_user_hash
);
my_hash_clear
(
&
excl_user_hash
);
coll_init
(
&
incl_user_coll
);
coll_init
(
&
excl_user_coll
);
if
(
incl_users
)
{
...
...
@@ -2089,9 +2363,6 @@ static int server_audit_init(void *p __attribute__((unused)))
update_excl_users
(
NULL
,
NULL
,
NULL
,
&
excl_users
);
}
loc_my_hash_init
(
&
connection_hash
,
0
,
&
my_charset_bin
,
0x100
,
0
,
sizeof
(
unsigned
long
),
0
,
0
,
free_connection
,
0
);
error_header
();
fprintf
(
stderr
,
"MariaDB Audit Plugin version %s%s STARTED.
\n
"
,
PLUGIN_STR_VERSION
,
PLUGIN_DEBUG_VERSION
);
...
...
@@ -2115,6 +2386,16 @@ static int server_audit_init(void *p __attribute__((unused)))
}
}
ci_disconnect_buffer
.
header
=
10
;
ci_disconnect_buffer
.
thread_id
=
0
;
ci_disconnect_buffer
.
query_id
=
0
;
ci_disconnect_buffer
.
db_length
=
0
;
ci_disconnect_buffer
.
user_length
=
0
;
ci_disconnect_buffer
.
host_length
=
0
;
ci_disconnect_buffer
.
ip_length
=
0
;
ci_disconnect_buffer
.
query
=
empty_str
;
ci_disconnect_buffer
.
query_length
=
0
;
if
(
logging
)
start_logging
();
...
...
@@ -2133,13 +2414,8 @@ static int server_audit_init_mysql(void *p)
static
int
server_audit_deinit
(
void
*
p
__attribute__
((
unused
)))
{
if
(
my_hash_inited
(
&
incl_user_hash
))
my_hash_free
(
&
incl_user_hash
);
if
(
my_hash_inited
(
&
excl_user_hash
))
my_hash_free
(
&
excl_user_hash
);
my_hash_free
(
&
connection_hash
);
coll_free
(
&
incl_user_coll
);
coll_free
(
&
excl_user_coll
);
if
(
output_type
==
OUTPUT_FILE
&&
logfile
)
logger_close
(
logfile
);
...
...
@@ -2174,6 +2450,7 @@ static struct st_mysql_audit mysql_descriptor =
{
MYSQL_AUDIT_GENERAL_CLASSMASK
|
MYSQL_AUDIT_CONNECTION_CLASSMASK
}
};
mysql_declare_plugin
(
server_audit
)
{
MYSQL_AUDIT_PLUGIN
,
...
...
@@ -2224,22 +2501,21 @@ maria_declare_plugin_end;
static
void
mark_always_logged
(
MYSQL_THD
thd
)
{
struct
connection_info
*
cn
;
if
(
thd
&&
(
cn
=
find_connection
(
thd_get_thread_id
(
thd
)
)))
if
(
thd
&&
(
cn
=
get_loc_info
(
thd
)))
cn
->
log_always
=
1
;
}
static
void
log_current_query
(
MYSQL_THD
thd
)
{
unsigned
long
thd_id
;
struct
connection_info
*
cn
;
if
(
!
thd
||
!
(
cn
=
find_connection
((
thd_id
=
thd_get_thread_id
(
thd
)))))
if
(
!
thd
)
return
;
if
(
FILTER
(
EVENT_QUERY
)
&&
do_log_user
(
cn
->
user
))
cn
=
get_loc_info
(
thd
);
if
(
!
ci_needs_setup
(
cn
)
&&
FILTER
(
EVENT_QUERY
)
&&
do_log_user
(
cn
->
user
))
{
log_statement_ex
(
cn
,
cn
->
query_time
,
thd_
id
,
cn
->
query
,
cn
->
query_length
,
0
,
"QUERY"
);
log_statement_ex
(
cn
,
cn
->
query_time
,
thd_
get_thread_id
(
thd
)
,
cn
->
query
,
cn
->
query_length
,
0
,
"QUERY"
);
cn
->
log_always
=
1
;
}
}
...
...
@@ -2251,6 +2527,7 @@ static void update_file_path(MYSQL_THD thd,
{
char
*
new_name
=
(
*
(
char
**
)
save
)
?
*
(
char
**
)
save
:
empty_str
;
if
(
!
maria_55_started
||
!
debug_server_started
)
flogger_mutex_lock
(
&
lock_operations
);
internal_stop_logging
=
1
;
error_header
();
...
...
@@ -2287,6 +2564,7 @@ static void update_file_path(MYSQL_THD thd,
file_path
=
path_buffer
;
exit_func:
internal_stop_logging
=
0
;
if
(
!
maria_55_started
||
!
debug_server_started
)
flogger_mutex_unlock
(
&
lock_operations
);
}
...
...
@@ -2331,13 +2609,15 @@ static void update_incl_users(MYSQL_THD thd,
void
*
var_ptr
__attribute__
((
unused
)),
const
void
*
save
)
{
char
*
new_users
=
(
*
(
char
**
)
save
)
?
*
(
char
**
)
save
:
empty_str
;
if
(
!
maria_55_started
||
!
debug_server_started
)
flogger_mutex_lock
(
&
lock_operations
);
mark_always_logged
(
thd
);
strncpy
(
incl_user_buffer
,
new_users
,
sizeof
(
incl_user_buffer
));
incl_users
=
incl_user_buffer
;
user_
hash_fill
(
&
incl_user_hash
,
incl_users
,
&
excl_user_hash
,
1
);
user_
coll_fill
(
&
incl_user_coll
,
incl_users
,
&
excl_user_coll
,
1
);
error_header
();
fprintf
(
stderr
,
"server_audit_incl_users set to '%s'.
\n
"
,
incl_users
);
if
(
!
maria_55_started
||
!
debug_server_started
)
flogger_mutex_unlock
(
&
lock_operations
);
}
...
...
@@ -2347,13 +2627,15 @@ static void update_excl_users(MYSQL_THD thd __attribute__((unused)),
void
*
var_ptr
__attribute__
((
unused
)),
const
void
*
save
)
{
char
*
new_users
=
(
*
(
char
**
)
save
)
?
*
(
char
**
)
save
:
empty_str
;
if
(
!
maria_55_started
||
!
debug_server_started
)
flogger_mutex_lock
(
&
lock_operations
);
mark_always_logged
(
thd
);
strncpy
(
excl_user_buffer
,
new_users
,
sizeof
(
excl_user_buffer
));
excl_users
=
excl_user_buffer
;
user_
hash_fill
(
&
excl_user_hash
,
excl_users
,
&
incl_user_hash
,
0
);
user_
coll_fill
(
&
excl_user_coll
,
excl_users
,
&
incl_user_coll
,
0
);
error_header
();
fprintf
(
stderr
,
"server_audit_excl_users set to '%s'.
\n
"
,
excl_users
);
if
(
!
maria_55_started
||
!
debug_server_started
)
flogger_mutex_unlock
(
&
lock_operations
);
}
...
...
@@ -2430,6 +2712,7 @@ static void update_logging(MYSQL_THD thd,
if
(
new_logging
==
logging
)
return
;
if
(
!
maria_55_started
||
!
debug_server_started
)
flogger_mutex_lock
(
&
lock_operations
);
internal_stop_logging
=
1
;
if
((
logging
=
new_logging
))
...
...
@@ -2447,6 +2730,7 @@ static void update_logging(MYSQL_THD thd,
}
internal_stop_logging
=
0
;
if
(
!
maria_55_started
||
!
debug_server_started
)
flogger_mutex_unlock
(
&
lock_operations
);
}
...
...
@@ -2459,6 +2743,7 @@ static void update_mode(MYSQL_THD thd __attribute__((unused)),
if
(
mode_readonly
||
new_mode
==
mode
)
return
;
if
(
!
maria_55_started
||
!
debug_server_started
)
flogger_mutex_lock
(
&
lock_operations
);
internal_stop_logging
=
1
;
mark_always_logged
(
thd
);
...
...
@@ -2466,6 +2751,7 @@ static void update_mode(MYSQL_THD thd __attribute__((unused)),
fprintf
(
stderr
,
"Logging mode was changed from %d to %d.
\n
"
,
mode
,
new_mode
);
mode
=
new_mode
;
internal_stop_logging
=
0
;
if
(
!
maria_55_started
||
!
debug_server_started
)
flogger_mutex_unlock
(
&
lock_operations
);
}
...
...
@@ -2490,6 +2776,13 @@ static void update_syslog_ident(MYSQL_THD thd __attribute__((unused)),
}
struct
st_my_thread_var
*
loc_thread_var
(
void
)
{
return
0
;
}
#ifdef _WIN32
BOOL
WINAPI
DllMain
(
HINSTANCE
hinstDLL
,
DWORD
fdwReason
,
LPVOID
lpvReserved
)
{
...
...
@@ -2507,9 +2800,18 @@ void __attribute__ ((constructor)) audit_plugin_so_init(void)
goto
exit
;
started_mariadb
=
strstr
(
serv_ver
,
"MariaDB"
)
!=
0
;
debug_server_started
=
strstr
(
serv_ver
,
"debug"
)
!=
0
;
if
(
!
started_mariadb
)
if
(
started_mariadb
)
{
if
(
serv_ver
[
0
]
==
'1'
)
use_event_data_for_disconnect
=
1
;
else
maria_55_started
=
1
;
}
else
{
/* Started MySQL. */
if
(
serv_ver
[
0
]
==
'5'
&&
serv_ver
[
2
]
==
'5'
)
{
int
sc
=
serv_ver
[
4
]
-
'0'
;
...
...
@@ -2526,7 +2828,25 @@ void __attribute__ ((constructor)) audit_plugin_so_init(void)
mysql_descriptor
.
event_notify
=
(
void
*
)
auditing_v13
;
}
}
else
if
(
serv_ver
[
0
]
==
'5'
&&
serv_ver
[
2
]
==
'6'
)
{
int
sc
=
serv_ver
[
4
]
-
'0'
;
if
(
serv_ver
[
5
]
>=
'0'
&&
serv_ver
[
5
]
<=
'9'
)
sc
=
sc
*
10
+
serv_ver
[
5
]
-
'0'
;
if
(
sc
>=
24
)
use_event_data_for_disconnect
=
1
;
}
else
if
(
serv_ver
[
0
]
==
'5'
&&
serv_ver
[
2
]
==
'7'
)
{
mysql_57_started
=
1
;
_mysql_plugin_declarations_
[
0
].
info
=
mysql_v4_descriptor
;
use_event_data_for_disconnect
=
1
;
}
}
memset
(
locinfo_ini_value
,
'O'
,
sizeof
(
locinfo_ini_value
)
-
1
);
locinfo_ini_value
[
sizeof
(
locinfo_ini_value
)]
=
0
;
exit:
#ifdef _WIN32
return
1
;
...
...
plugin/server_audit/test_audit_v4.c
0 → 100644
View file @
1793646d
#define PLUGIN_CONTEXT
#include <stdio.h>
typedef
void
*
MYSQL_THD
;
struct
st_mysql_const_lex_string
{
const
char
*
str
;
size_t
length
;
};
typedef
struct
st_mysql_const_lex_string
MYSQL_LEX_CSTRING
;
enum
enum_sql_command
{
SQLCOM_A
,
SQLCOM_B
};
enum
enum_server_command
{
SERVCOM_A
,
SERVCOM_B
};
#include "plugin_audit_v4.h"
extern
void
auditing
(
MYSQL_THD
thd
,
unsigned
int
event_class
,
const
void
*
ev
);
extern
int
get_db_mysql57
(
MYSQL_THD
thd
,
char
**
name
,
int
*
len
);
struct
mysql_event_general_302
{
unsigned
int
event_subclass
;
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
;
unsigned
long
long
query_id
;
char
*
database
;
int
database_length
;
};
static
int
auditing_v4
(
MYSQL_THD
thd
,
mysql_event_class_t
class
,
const
void
*
ev
)
{
int
*
subclass
=
(
int
*
)
ev
;
struct
mysql_event_general_302
ev_302
;
int
subclass_v3
,
subclass_orig
;
if
(
class
!=
MYSQL_AUDIT_GENERAL_CLASS
&&
class
!=
MYSQL_AUDIT_CONNECTION_CLASS
)
return
0
;
subclass_orig
=
*
subclass
;
if
(
class
==
MYSQL_AUDIT_GENERAL_CLASS
)
{
struct
mysql_event_general
*
event
=
(
struct
mysql_event_general
*
)
ev
;
ev_302
.
general_error_code
=
event
->
general_error_code
;
ev_302
.
general_thread_id
=
event
->
general_thread_id
;
ev_302
.
general_user
=
event
->
general_user
.
str
;
ev_302
.
general_user_length
=
event
->
general_user
.
length
;
ev_302
.
general_command
=
event
->
general_command
.
str
;
ev_302
.
general_command_length
=
event
->
general_command
.
length
;
ev_302
.
general_query
=
event
->
general_query
.
str
;
ev_302
.
general_query_length
=
event
->
general_query
.
length
;
ev_302
.
general_charset
=
event
->
general_charset
;
ev_302
.
general_time
=
event
->
general_time
;
ev_302
.
general_rows
=
event
->
general_rows
;
if
(
get_db_mysql57
(
thd
,
&
ev_302
.
database
,
&
ev_302
.
database_length
))
{
ev_302
.
database
=
0
;
ev_302
.
database_length
=
0
;
}
ev
=
&
ev_302
;
switch
(
subclass_orig
)
{
case
MYSQL_AUDIT_GENERAL_LOG
:
subclass_v3
=
0
;
ev_302
.
event_subclass
=
0
;
break
;
case
MYSQL_AUDIT_GENERAL_ERROR
:
subclass_v3
=
1
;
ev_302
.
event_subclass
=
1
;
break
;
case
MYSQL_AUDIT_GENERAL_RESULT
:
subclass_v3
=
2
;
ev_302
.
event_subclass
=
2
;
break
;
case
MYSQL_AUDIT_GENERAL_STATUS
:
{
subclass_v3
=
3
;
ev_302
.
event_subclass
=
3
;
break
;
}
default:
return
0
;
}
}
else
/* if (class == MYSQL_AUDIT_CONNECTION_CLASS) */
{
switch
(
subclass_orig
)
{
case
MYSQL_AUDIT_CONNECTION_CONNECT
:
subclass_v3
=
0
;
break
;
case
MYSQL_AUDIT_CONNECTION_DISCONNECT
:
subclass_v3
=
1
;
break
;
default:
return
0
;
}
}
*
subclass
=
subclass_v3
;
auditing
(
thd
,
(
int
)
class
,
ev
);
*
subclass
=
subclass_orig
;
return
0
;
}
static
struct
st_mysql_audit
mysql_descriptor
=
{
MYSQL_AUDIT_INTERFACE_VERSION
,
NULL
,
auditing_v4
,
{
(
unsigned
long
)
MYSQL_AUDIT_GENERAL_ALL
,
(
unsigned
long
)
MYSQL_AUDIT_CONNECTION_ALL
,
(
unsigned
long
)
MYSQL_AUDIT_PARSE_ALL
,
0
,
/* This event class is currently not supported. */
0
,
/* This event class is currently not supported. */
(
unsigned
long
)
MYSQL_AUDIT_GLOBAL_VARIABLE_ALL
,
(
unsigned
long
)
MYSQL_AUDIT_SERVER_STARTUP_ALL
,
(
unsigned
long
)
MYSQL_AUDIT_SERVER_SHUTDOWN_ALL
,
(
unsigned
long
)
MYSQL_AUDIT_COMMAND_ALL
,
(
unsigned
long
)
MYSQL_AUDIT_QUERY_ALL
,
(
unsigned
long
)
MYSQL_AUDIT_STORED_PROGRAM_ALL
}
#ifdef WHEN_MYSQL_BUG_FIXED
/*
By this moment MySQL just sends no notifications at all
when we request only those we actually need.
So we have to request everything and filter them inside the
handling function.
*/
{
(
unsigned
long
)
MYSQL_AUDIT_GENERAL_ALL
,
(
unsigned
long
)
(
MYSQL_AUDIT_CONNECTION_CONNECT
|
MYSQL_AUDIT_CONNECTION_DISCONNECT
),
0
,
0
,
/* This event class is currently not supported. */
0
,
/* This event class is currently not supported. */
0
,
0
,
0
,
0
,
0
,
0
}
#endif
/*WHEN_MYSQL_BUG_FIXED*/
};
void
*
mysql_v4_descriptor
=
&
mysql_descriptor
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment