diff options
Diffstat (limited to 'sql/sql_connect.cc')
-rw-r--r-- | sql/sql_connect.cc | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 4ae267a880c..959209df412 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -61,7 +61,7 @@ static int get_or_create_user_conn(THD *thd, const char *user, user_len= strlen(user); temp_len= (strmov(strmov(temp_user, user)+1, host) - temp_user)+1; (void) pthread_mutex_lock(&LOCK_user_conn); - if (!(uc = (struct user_conn *) hash_search(&hash_user_connections, + if (!(uc = (struct user_conn *) my_hash_search(&hash_user_connections, (uchar*) temp_user, temp_len))) { /* First connection for user; Create a user connection object */ @@ -151,7 +151,15 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc) end: if (error) + { uc->connections--; // no need for decrease_user_connections() here + /* + The thread may returned back to the pool and assigned to a user + that doesn't have a limit. Ensure the user is not using resources + of someone else. + */ + thd->user_connect= NULL; + } (void) pthread_mutex_unlock(&LOCK_user_conn); DBUG_RETURN(error); } @@ -183,7 +191,7 @@ void decrease_user_connections(USER_CONN *uc) if (!--uc->connections && !mqh_used) { /* Last connection for user; Delete it */ - (void) hash_delete(&hash_user_connections,(uchar*) uc); + (void) my_hash_delete(&hash_user_connections,(uchar*) uc); } (void) pthread_mutex_unlock(&LOCK_user_conn); DBUG_VOID_RETURN; @@ -462,7 +470,10 @@ check_user(THD *thd, enum enum_server_command command, { /* mysql_change_db() has pushed the error message. */ if (thd->user_connect) + { decrease_user_connections(thd->user_connect); + thd->user_connect= 0; + } DBUG_RETURN(1); } } @@ -486,6 +497,18 @@ check_user(THD *thd, enum enum_server_command command, thd->main_security_ctx.user, thd->main_security_ctx.host_or_ip, passwd_len ? ER(ER_YES) : ER(ER_NO)); + /* + log access denied messages to the error log when log-warnings = 2 + so that the overhead of the general query log is not required to track + failed connections + */ + if (global_system_variables.log_warnings > 1) + { + sql_print_warning(ER(ER_ACCESS_DENIED_ERROR), + thd->main_security_ctx.user, + thd->main_security_ctx.host_or_ip, + passwd_len ? ER(ER_YES) : ER(ER_NO)); + } DBUG_RETURN(1); #endif /* NO_EMBEDDED_ACCESS_CHECKS */ } @@ -513,10 +536,10 @@ extern "C" void free_user(struct user_conn *uc) void init_max_user_conn(void) { #ifndef NO_EMBEDDED_ACCESS_CHECKS - (void) hash_init(&hash_user_connections,system_charset_info,max_connections, - 0,0, - (hash_get_key) get_key_conn, (hash_free_key) free_user, - 0); + (void) + my_hash_init(&hash_user_connections,system_charset_info,max_connections, + 0,0, (my_hash_get_key) get_key_conn, + (my_hash_free_key) free_user, 0); #endif } @@ -524,7 +547,7 @@ void init_max_user_conn(void) void free_max_user_conn(void) { #ifndef NO_EMBEDDED_ACCESS_CHECKS - hash_free(&hash_user_connections); + my_hash_free(&hash_user_connections); #endif /* NO_EMBEDDED_ACCESS_CHECKS */ } @@ -542,8 +565,9 @@ void reset_mqh(LEX_USER *lu, bool get_them= 0) memcpy(temp_user,lu->user.str,lu->user.length); memcpy(temp_user+lu->user.length+1,lu->host.str,lu->host.length); temp_user[lu->user.length]='\0'; temp_user[temp_len-1]=0; - if ((uc = (struct user_conn *) hash_search(&hash_user_connections, - (uchar*) temp_user, temp_len))) + if ((uc = (struct user_conn *) my_hash_search(&hash_user_connections, + (uchar*) temp_user, + temp_len))) { uc->questions=0; get_mqh(temp_user,&temp_user[lu->user.length+1],uc); @@ -556,8 +580,8 @@ void reset_mqh(LEX_USER *lu, bool get_them= 0) /* for FLUSH PRIVILEGES and FLUSH USER_RESOURCES */ for (uint idx=0;idx < hash_user_connections.records; idx++) { - USER_CONN *uc=(struct user_conn *) hash_element(&hash_user_connections, - idx); + USER_CONN *uc=(struct user_conn *) + my_hash_element(&hash_user_connections, idx); if (get_them) get_mqh(uc->user,uc->host,uc); uc->questions=0; @@ -945,7 +969,7 @@ static bool login_connection(THD *thd) my_net_set_write_timeout(net, connect_timeout); error= check_connection(thd); - net_end_statement(thd); + thd->protocol->end_statement(); if (error) { // Wrong permissions @@ -975,9 +999,17 @@ static void end_connection(THD *thd) NET *net= &thd->net; plugin_thdvar_cleanup(thd); if (thd->user_connect) + { decrease_user_connections(thd->user_connect); + /* + The thread may returned back to the pool and assigned to a user + that doesn't have a limit. Ensure the user is not using resources + of someone else. + */ + thd->user_connect= NULL; + } - if (thd->killed || net->error && net->vio != 0) + if (thd->killed || (net->error && net->vio != 0)) { statistic_increment(aborted_threads,&LOCK_status); } |