From 2f01aa9727e4c062b382d53bd871d7fdaf3802b6 Mon Sep 17 00:00:00 2001
From: Konstantin Osipov <kostja@sun.com>
Date: Wed, 14 Oct 2009 00:16:41 +0400
Subject: [PATCH] ----------------------------------------------------------
 revno: 2630.2.16 committer: Konstantin Osipov <konstantin@mysql.com> branch
 nick: mysql-6.0-runtime timestamp: Fri 2008-06-27 13:26:03 +0400 message:  
 Fix max_user_connections_func failure on Solaris.   A connection that failed
 to log in due to a resource limit could   be returned to the thread pool with
 a dangling link to user_connect   structure of an old user. Later on it could
 be authenticated   to a user that doesn't have a resource limit, so this
 dangling   link won't be reset. --pool-of-threads mode made the situation  
 easy to reproduce, and thus highlighted a bug that has been   around forever.
   Make sure there are no dangling links.

---
 sql/sql_connect.cc | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 4ae267a880c..6cfb28278e7 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -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);
 }
@@ -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);
         }
       }
@@ -975,7 +986,15 @@ 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)
   {
-- 
2.30.9