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-1335  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 
30 static volatile int ncalls; /* for SHOW STATUS, see below */
31 static volatile int ncalls_general_log;
32 static volatile int ncalls_general_error;
33 static volatile int ncalls_general_result;
34 
35 FILE *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 
51 static 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 
79 static 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 
96 static 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 
166 static 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 
176 static 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 
190 mysql_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 }
206 mysql_declare_plugin_end;
207 
208