1/* Copyright (c) 2006, 2011, Oracle and/or its affiliates.
2 Copyright (c) 2012, 2013, Monty Program Ab.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; version 2 of
7 the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
17
18#include <stdio.h>
19#include <mysql/plugin.h>
20#include <mysql/plugin_audit.h>
21
22#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
23#define __attribute__(A)
24#endif
25
26#ifdef _MSC_VER
27#define snprintf _snprintf
28#endif
29
30static volatile int ncalls; /* for SHOW STATUS, see below */
31static volatile int ncalls_general_log;
32static volatile int ncalls_general_error;
33static volatile int ncalls_general_result;
34
35FILE *f;
36
37/*
38 Initialize the plugin at server start or plugin installation.
39
40 SYNOPSIS
41 audit_null_plugin_init()
42
43 DESCRIPTION
44 Does nothing.
45
46 RETURN VALUE
47 0 success
48 1 failure (cannot happen)
49*/
50
51static int audit_null_plugin_init(void *arg __attribute__((unused)))
52{
53 ncalls= 0;
54 ncalls_general_log= 0;
55 ncalls_general_error= 0;
56 ncalls_general_result= 0;
57
58 f = fopen("audit_null_tables.log", "w");
59 if (!f)
60 return 1;
61
62 return 0;
63}
64
65
66/*
67 Terminate the plugin at server shutdown or plugin deinstallation.
68
69 SYNOPSIS
70 audit_null_plugin_deinit()
71 Does nothing.
72
73 RETURN VALUE
74 0 success
75 1 failure (cannot happen)
76
77*/
78
79static int audit_null_plugin_deinit(void *arg __attribute__((unused)))
80{
81 fclose(f);
82 return 0;
83}
84
85
86/*
87 Foo
88
89 SYNOPSIS
90 audit_null_notify()
91 thd connection context
92
93 DESCRIPTION
94*/
95
96static void audit_null_notify(MYSQL_THD thd __attribute__((unused)),
97 unsigned int event_class,
98 const void *event)
99{
100 /* prone to races, oh well */
101 ncalls++;
102 if (event_class == MYSQL_AUDIT_GENERAL_CLASS)
103 {
104 const struct mysql_event_general *event_general=
105 (const struct mysql_event_general *) event;
106 switch (event_general->event_subclass)
107 {
108 case MYSQL_AUDIT_GENERAL_LOG:
109 ncalls_general_log++;
110 fprintf(f, "%s\t>> %s\n", event_general->general_user,
111 event_general->general_query);
112 break;
113 case MYSQL_AUDIT_GENERAL_ERROR:
114 ncalls_general_error++;
115 break;
116 case MYSQL_AUDIT_GENERAL_RESULT:
117 ncalls_general_result++;
118 break;
119 default:
120 break;
121 }
122 }
123 else
124 if (event_class == MYSQL_AUDIT_TABLE_CLASS)
125 {
126 const struct mysql_event_table *event_table=
127 (const struct mysql_event_table *) event;
128 const char *ip= event_table->ip ? event_table->ip : "";
129 const char *op= 0;
130 char buf[1024];
131
132 switch (event_table->event_subclass)
133 {
134 case MYSQL_AUDIT_TABLE_LOCK:
135 op= event_table->read_only ? "read" : "write";
136 break;
137 case MYSQL_AUDIT_TABLE_CREATE:
138 op= "create";
139 break;
140 case MYSQL_AUDIT_TABLE_DROP:
141 op= "drop";
142 break;
143 case MYSQL_AUDIT_TABLE_ALTER:
144 op= "alter";
145 break;
146 case MYSQL_AUDIT_TABLE_RENAME:
147 snprintf(buf, sizeof(buf), "rename to %s.%s",
148 event_table->new_database.str, event_table->new_table.str);
149 buf[sizeof(buf)-1]= 0;
150 op= buf;
151 break;
152 }
153
154 fprintf(f, "%s[%s] @ %s [%s]\t%s.%s : %s\n",
155 event_table->priv_user, event_table->user,
156 event_table->host, ip,
157 event_table->database.str, event_table->table.str, op);
158 }
159}
160
161
162/*
163 Plugin type-specific descriptor
164*/
165
166static struct st_mysql_audit audit_null_descriptor=
167{
168 MYSQL_AUDIT_INTERFACE_VERSION, NULL, audit_null_notify,
169 { MYSQL_AUDIT_GENERAL_CLASSMASK | MYSQL_AUDIT_TABLE_CLASSMASK }
170};
171
172/*
173 Plugin status variables for SHOW STATUS
174*/
175
176static struct st_mysql_show_var simple_status[]=
177{
178 { "called", (char *) &ncalls, SHOW_INT },
179 { "general_error", (char *) &ncalls_general_error, SHOW_INT },
180 { "general_log", (char *) &ncalls_general_log, SHOW_INT },
181 { "general_result", (char *) &ncalls_general_result, SHOW_INT },
182 { 0, 0, 0}
183};
184
185
186/*
187 Plugin library descriptor
188*/
189
190mysql_declare_plugin(audit_null)
191{
192 MYSQL_AUDIT_PLUGIN, /* type */
193 &audit_null_descriptor, /* descriptor */
194 "AUDIT_NULL", /* name */
195 "Oracle Corp", /* author */
196 "Simple NULL Audit", /* description */
197 PLUGIN_LICENSE_GPL,
198 audit_null_plugin_init, /* init function (when loaded) */
199 audit_null_plugin_deinit, /* deinit function (when unloaded) */
200 0x0002, /* version */
201 simple_status, /* status variables */
202 NULL, /* system variables */
203 NULL,
204 0,
205}
206mysql_declare_plugin_end;
207
208