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