diff options
Diffstat (limited to 'plugin/server_audit/server_audit.c')
-rw-r--r-- | plugin/server_audit/server_audit.c | 177 |
1 files changed, 114 insertions, 63 deletions
diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index c9e7e3a532a..e143f56b415 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -15,7 +15,7 @@ #define PLUGIN_VERSION 0x104 -#define PLUGIN_STR_VERSION "1.4.4" +#define PLUGIN_STR_VERSION "1.4.6" #define _my_thread_var loc_thread_var @@ -24,6 +24,7 @@ #include <time.h> #include <string.h> #include <fcntl.h> +#include <assert.h> #ifndef _WIN32 #include <syslog.h> @@ -97,7 +98,7 @@ static void closelog() {} #define FLOGGER_NO_PSI /* How to access the pthread_mutex in mysql_mutex_t */ -#if defined(SAFE_MUTEX) || defined(MY_PTHREAD_FASTMUTEX) +#ifdef SAFE_MUTEX #define mysql_mutex_real_mutex(A) &(A)->m_mutex.mutex #else #define mysql_mutex_real_mutex(A) &(A)->m_mutex @@ -140,7 +141,7 @@ 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); + writtenbytes= (size_t)_write(Filedes, Buffer, (unsigned int)Count); #else writtenbytes= write(Filedes, Buffer, Count); #endif @@ -154,10 +155,29 @@ static File loc_open(const char *FileName, int Flags) /* Special flags */ { File fd; -#if defined(_WIN32) - fd= my_win_open(FileName, Flags); +#ifdef _WIN32 + HANDLE h; + /* + We could just use _open() here. but prefer to open in unix-similar way + just like my_open() does it on Windows. + This gives atomic multiprocess-safe appends, and possibility to rename + or even delete file while it is open, and CRT lacks this features. + */ + assert(Flags == (O_APPEND | O_CREAT | O_WRONLY)); + h= CreateFile(FileName, FILE_APPEND_DATA, + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (h == INVALID_HANDLE_VALUE) + { + fd= -1; + my_osmaperr(GetLastError()); + } + else + { + fd= _open_osfhandle((intptr)h, O_WRONLY|O_BINARY); + } #else - fd = open(FileName, Flags, my_umask); + fd= open(FileName, Flags, my_umask); #endif my_errno= errno; return fd; @@ -173,7 +193,7 @@ static int loc_close(File fd) err= close(fd); } while (err == -1 && errno == EINTR); #else - err= my_win_close(fd); + err= close(fd); #endif my_errno=errno; return err; @@ -203,32 +223,9 @@ static int loc_rename(const char *from, const char *to) } -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 + os_off_t pos= IF_WIN(_telli64(fd),lseek(fd, 0, SEEK_CUR)); if (pos == (os_off_t) -1) { my_errno= errno; @@ -303,7 +300,7 @@ static size_t big_buffer_alloced= 0; static unsigned int query_log_limit= 0; static char servhost[256]; -static size_t servhost_len; +static uint servhost_len; static char *syslog_ident; static char syslog_ident_buffer[128]= "mysql-server_auditing"; @@ -338,6 +335,10 @@ static void update_file_rotations(MYSQL_THD thd, struct st_mysql_sys_var *var, void *var_ptr, const void *save); static void update_incl_users(MYSQL_THD thd, struct st_mysql_sys_var *var, void *var_ptr, const void *save); +static int check_incl_users(MYSQL_THD thd, struct st_mysql_sys_var *var, void *save, + struct st_mysql_value *value); +static int check_excl_users(MYSQL_THD thd, struct st_mysql_sys_var *var, void *save, + struct st_mysql_value *value); static void update_excl_users(MYSQL_THD thd, struct st_mysql_sys_var *var, void *var_ptr, const void *save); static void update_output_type(MYSQL_THD thd, struct st_mysql_sys_var *var, @@ -357,10 +358,10 @@ static void rotate_log(MYSQL_THD thd, struct st_mysql_sys_var *var, static MYSQL_SYSVAR_STR(incl_users, incl_users, PLUGIN_VAR_RQCMDARG, "Comma separated list of users to monitor.", - NULL, update_incl_users, NULL); + check_incl_users, update_incl_users, NULL); static MYSQL_SYSVAR_STR(excl_users, excl_users, PLUGIN_VAR_RQCMDARG, "Comma separated list of users to exclude from auditing.", - NULL, update_excl_users, NULL); + check_excl_users, update_excl_users, NULL); /* bits in the event filter. */ #define EVENT_CONNECT 1 #define EVENT_QUERY_ALL 2 @@ -626,7 +627,7 @@ static void remove_blanks(char *user) struct user_name { - int name_len; + size_t name_len; char *name; }; @@ -661,7 +662,7 @@ 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; + int dl= (int)(a->name_len - b->name_len); if (dl != 0) return dl; @@ -669,7 +670,7 @@ static int cmp_users(const void *ia, const void *ib) } -static char *coll_search(struct user_coll *c, const char *n, int len) +static char *coll_search(struct user_coll *c, const char *n, size_t len) { struct user_name un; struct user_name *found; @@ -681,7 +682,7 @@ static char *coll_search(struct user_coll *c, const char *n, int len) } -static int coll_insert(struct user_coll *c, char *n, int len) +static int coll_insert(struct user_coll *c, char *n, size_t len) { if (c->n_users >= c->n_alloced) { @@ -936,7 +937,7 @@ static void get_str_n(char *dest, int *dest_len, size_t dest_size, memcpy(dest, src, src_len); dest[src_len]= 0; - *dest_len= src_len; + *dest_len= (int)src_len; } @@ -1008,7 +1009,7 @@ static int start_logging() if (output_type == OUTPUT_FILE) { char alt_path_buffer[FN_REFLEN+1+DEFAULT_FILENAME_LEN]; - MY_STAT *f_stat; + struct stat *f_stat= (struct stat *)alt_path_buffer; const char *alt_fname= file_path; while (*alt_fname == ' ') @@ -1023,7 +1024,7 @@ static int start_logging() { /* See if the directory exists with the name of file_path. */ /* Log file name should be [file_path]/server_audit.log then. */ - if ((f_stat= my_stat(file_path, (MY_STAT *)alt_path_buffer, MYF(0))) && + if (stat(file_path, (struct stat *)alt_path_buffer) == 0 && S_ISDIR(f_stat->st_mode)) { size_t p_len= strlen(file_path); @@ -1252,12 +1253,12 @@ static void change_connection(struct connection_info *cn, event->ip, event->ip_length); } -static int write_log(const char *message, int len) +static int write_log(const char *message, size_t len) { if (output_type == OUTPUT_FILE) { if (logfile && - (is_active= (logger_write(logfile, message, len) == len))) + (is_active= (logger_write(logfile, message, len) == (int)len))) return 0; ++log_write_failures; return 1; @@ -1266,7 +1267,7 @@ static int write_log(const char *message, int len) { syslog(syslog_facility_codes[syslog_facility] | syslog_priority_codes[syslog_priority], - "%s %.*s", syslog_info, len, message); + "%s %.*s", syslog_info, (int)len, message); } return 0; } @@ -1450,7 +1451,7 @@ static size_t escape_string_hide_passwords(const char *str, unsigned int len, } next_s++; } - len-= next_s - str; + len-= (uint)(next_s - str); str= next_s; continue; } @@ -1622,7 +1623,7 @@ static int log_statement_ex(const struct connection_info *cn, } if (query && !(events & EVENT_QUERY_ALL) && - (events & EVENT_QUERY)) + (events & EVENT_QUERY && !cn->log_always)) { const char *orig_query= query; @@ -1764,9 +1765,9 @@ static int log_table(const struct connection_info *cn, (void) time(&ctime); csize= log_header(message, sizeof(message)-1, &ctime, servhost, servhost_len, - event->user, SAFE_STRLEN(event->user), - event->host, SAFE_STRLEN(event->host), - event->ip, SAFE_STRLEN(event->ip), + event->user, (unsigned int)SAFE_STRLEN(event->user), + event->host, (unsigned int)SAFE_STRLEN(event->host), + event->ip, (unsigned int)SAFE_STRLEN(event->ip), event->thread_id, cn->query_id, type); csize+= my_snprintf(message+csize, sizeof(message) - 1 - csize, ",%.*s,%.*s,",event->database_length, event->database, @@ -1786,9 +1787,9 @@ static int log_rename(const struct connection_info *cn, (void) time(&ctime); csize= log_header(message, sizeof(message)-1, &ctime, servhost, servhost_len, - event->user, SAFE_STRLEN(event->user), - event->host, SAFE_STRLEN(event->host), - event->ip, SAFE_STRLEN(event->ip), + event->user, (unsigned int)SAFE_STRLEN(event->user), + event->host, (unsigned int)SAFE_STRLEN(event->host), + event->ip, (unsigned int)SAFE_STRLEN(event->ip), event->thread_id, cn->query_id, "RENAME"); csize+= my_snprintf(message+csize, sizeof(message) - 1 - csize, ",%.*s,%.*s|%.*s.%.*s,",event->database_length, event->database, @@ -2021,10 +2022,14 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) update_connection_info(cn, event_class, ev, &after_action); if (!logging) + { + if (cn) + cn->log_always= 0; goto exit_func; + } if (event_class == MYSQL_AUDIT_GENERAL_CLASS && FILTER(EVENT_QUERY) && - cn && do_log_user(cn->user)) + cn && (cn->log_always || do_log_user(cn->user))) { const struct mysql_event_general *event = (const struct mysql_event_general *) ev; @@ -2037,6 +2042,7 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) { log_statement(cn, event, "QUERY"); cn->query_length= 0; /* So the log_current_query() won't log this again. */ + cn->log_always= 0; } } else if (event_class == MYSQL_AUDIT_TABLE_CLASS && FILTER(EVENT_TABLE) && cn) @@ -2107,8 +2113,6 @@ exit_func: break; } } - if (cn) - cn->log_always= 0; flogger_mutex_unlock(&lock_operations); } @@ -2369,7 +2373,7 @@ static int server_audit_init(void *p __attribute__((unused))) if (gethostname(servhost, sizeof(servhost))) strcpy(servhost, "unknown"); - servhost_len= strlen(servhost); + servhost_len= (uint)strlen(servhost); logger_init_mutexes(); #if defined(HAVE_PSI_INTERFACE) && !defined(FLOGGER_NO_PSI) @@ -2552,12 +2556,12 @@ static void log_current_query(MYSQL_THD thd) if (!thd) return; cn= get_loc_info(thd); - if (!ci_needs_setup(cn) && cn->query_length && - FILTER(EVENT_QUERY) && do_log_user(cn->user)) + if (!ci_needs_setup(cn) && cn->query_length) { + cn->log_always= 1; log_statement_ex(cn, cn->query_time, thd_get_thread_id(thd), cn->query, cn->query_length, 0, "QUERY"); - cn->log_always= 1; + cn->log_always= 0; } } @@ -2646,16 +2650,56 @@ static void update_file_rotate_size(MYSQL_THD thd __attribute__((unused)), } +static int check_users(void *save, struct st_mysql_value *value, + size_t s, const char *name) +{ + const char *users; + int len= 0; + + users= value->val_str(value, NULL, &len); + if ((size_t) len > s) + { + error_header(); + fprintf(stderr, + "server_audit_%s_users value can't be longer than %zu characters.\n", + name, s); + return 1; + } + *((const char**)save)= users; + return 0; +} + +static int check_incl_users(MYSQL_THD thd __attribute__((unused)), + struct st_mysql_sys_var *var __attribute__((unused)), + void *save, struct st_mysql_value *value) +{ + return check_users(save, value, sizeof(incl_user_buffer), "incl"); +} + +static int check_excl_users(MYSQL_THD thd __attribute__((unused)), + struct st_mysql_sys_var *var __attribute__((unused)), + void *save, struct st_mysql_value *value) +{ + return check_users(save, value, sizeof(excl_user_buffer), "excl"); +} + + static void update_incl_users(MYSQL_THD thd, struct st_mysql_sys_var *var __attribute__((unused)), void *var_ptr __attribute__((unused)), const void *save) { char *new_users= (*(char **) save) ? *(char **) save : empty_str; + size_t new_len= strlen(new_users) + 1; 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)-1); - incl_user_buffer[sizeof(incl_user_buffer)-1]= 0; + + if (new_len > sizeof(incl_user_buffer)) + new_len= sizeof(incl_user_buffer); + + memcpy(incl_user_buffer, new_users, new_len - 1); + incl_user_buffer[new_len - 1]= 0; + incl_users= incl_user_buffer; user_coll_fill(&incl_user_coll, incl_users, &excl_user_coll, 1); error_header(); @@ -2670,11 +2714,17 @@ 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; + size_t new_len= strlen(new_users) + 1; 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)-1); - excl_user_buffer[sizeof(excl_user_buffer)-1]= 0; + + if (new_len > sizeof(excl_user_buffer)) + new_len= sizeof(excl_user_buffer); + + memcpy(excl_user_buffer, new_users, new_len - 1); + excl_user_buffer[new_len - 1]= 0; + excl_users= excl_user_buffer; user_coll_fill(&excl_user_coll, excl_users, &incl_user_coll, 0); error_header(); @@ -2766,6 +2816,7 @@ static void update_logging(MYSQL_THD thd, { CLIENT_ERROR(1, "Logging was disabled.", MYF(ME_JUST_WARNING)); } + mark_always_logged(thd); } else { |