List:Internals« Previous MessageNext Message »
From:sanja Date:September 14 2005 3:52am
Subject:bk commit into 5.0 tree (bell:1.1967)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of bell. When bell does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.1967 05/09/14 04:52:50 bell@stripped +29 -0
  WL#2787 (part 2, ver 2) changed securety context switching

  sql/sql_yacc.yy
    1.421 05/09/14 04:52:44 bell@stripped +17 -13
    changed securety context switching

  sql/sql_view.cc
    1.63 05/09/14 04:52:44 bell@stripped +9 -6
    changed securety context switching

  sql/sql_trigger.cc
    1.28 05/09/14 04:52:44 bell@stripped +1 -1
    changed securety context switching

  sql/sql_show.cc
    1.277 05/09/14 04:52:44 bell@stripped +30 -20
    changed securety context switching

  sql/sql_parse.cc
    1.485 05/09/14 04:52:44 bell@stripped +112 -102
    changed securety context switching

  sql/sql_insert.cc
    1.174 05/09/14 04:52:44 bell@stripped +6 -5
    changed securety context switching

  sql/sql_db.cc
    1.116 05/09/14 04:52:44 bell@stripped +9 -10
    changed securety context switching

  sql/sql_class.h
    1.264 05/09/14 04:52:44 bell@stripped +26 -11
    changed securety context switching

  sql/sql_class.cc
    1.210 05/09/14 04:52:44 bell@stripped +37 -11
    changed securety context switching

  sql/sql_base.cc
    1.299 05/09/14 04:52:44 bell@stripped +2 -1
    changed securety context switching

  sql/sql_acl.h
    1.47 05/09/14 04:52:44 bell@stripped +2 -1
    changed securety context switching

  sql/sql_acl.cc
    1.169 05/09/14 04:52:44 bell@stripped +105 -85
    changed securety context switching

  sql/sp_head.h
    1.69 05/09/14 04:52:43 bell@stripped +7 -15
    changed securety context switching

  sql/sp_head.cc
    1.183 05/09/14 04:52:43 bell@stripped +27 -41
    changed securety context switching

  sql/sp.cc
    1.93 05/09/14 04:52:43 bell@stripped +3 -2
    changed securety context switching

  sql/slave.cc
    1.256 05/09/14 04:52:43 bell@stripped +1 -8
    changed securety context switching

  sql/share/errmsg.txt
    1.44 05/09/14 04:52:43 bell@stripped +1 -1
    fixed warning text

  sql/set_var.cc
    1.140 05/09/14 04:52:43 bell@stripped +9 -8
    changed securety context switching

  sql/repl_failsafe.cc
    1.55 05/09/14 04:52:43 bell@stripped +1 -3
    changed securety context switching

  sql/mysqld.cc
    1.496 05/09/14 04:52:43 bell@stripped +5 -3
    changed securety context switching

  sql/mysql_priv.h
    1.350 05/09/14 04:52:43 bell@stripped +2 -1
    changed securety context switching

  sql/log.cc
    1.171 05/09/14 04:52:43 bell@stripped +7 -5
    changed securety context switching

  sql/item_strfunc.cc
    1.252 05/09/14 04:52:42 bell@stripped +7 -6
    changed securety context switching

  sql/item_func.cc
    1.251 05/09/14 04:52:42 bell@stripped +6 -6
    changed securety context switching

  sql/item.cc
    1.177 05/09/14 04:52:42 bell@stripped +2 -2
    changed securety context switching

  sql/ha_innodb.cc
    1.256 05/09/14 04:52:42 bell@stripped +10 -6
    changed securety context switching

  mysql-test/r/view.result
    1.111 05/09/14 04:52:42 bell@stripped +1 -1
    fixed warning text

  mysql-test/r/rpl_sp.result
    1.8 05/09/14 04:52:42 bell@stripped +1 -1
    now it show real information from changed security context of SP (checked)

  libmysqld/lib_sql.cc
    1.103 05/09/14 04:52:42 bell@stripped +3 -4
    changed securety context switching

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	bell
# Host:	sanja.is.com.ua
# Root:	/home/bell/mysql/bk/work-owner-5.0

--- 1.176/sql/item.cc	2005-09-09 15:50:02 +03:00
+++ 1.177/sql/item.cc	2005-09-14 04:52:42 +03:00
@@ -3434,8 +3434,8 @@
                             VIEW_ANY_ACL)))
     {
       my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
-               "ANY", thd->priv_user, thd->host_or_ip,
-               field_name, tab);
+               "ANY", thd->security_ctx->priv_user,
+               thd->security_ctx->host_or_ip, field_name, tab);
       goto error;
     }
   }

--- 1.250/sql/item_func.cc	2005-09-09 09:08:44 +03:00
+++ 1.251/sql/item_func.cc	2005-09-14 04:52:42 +03:00
@@ -4713,7 +4713,7 @@
   Sub_statement_state statement_state;
 
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-  st_sp_security_context save_ctx;
+  st_security_context *save_ctx;
 #endif
 
   if (! m_sp && ! (m_sp= sp_find_function(thd, m_name, TRUE)))
@@ -4723,11 +4723,11 @@
   }
 
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-  if (check_routine_access(thd, EXECUTE_ACL, 
-			   m_sp->m_db.str, m_sp->m_name.str, 0, 0))
+  if (check_routine_access(thd, EXECUTE_ACL,
+			   m_sp->m_db.str, m_sp->m_name.str, 0, 0) ||
+      sp_change_security_context(thd, m_sp, &save_ctx))
     goto error;
-  sp_change_security_context(thd, m_sp, &save_ctx);
-  if (save_ctx.changed && 
+  if (save_ctx && 
       check_routine_access(thd, EXECUTE_ACL, 
 			   m_sp->m_db.str, m_sp->m_name.str, 0, 0))
     goto error_check_ctx;
@@ -4750,7 +4750,7 @@
 
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
 error_check_ctx:
-  sp_restore_security_context(thd, m_sp, &save_ctx);
+  sp_restore_security_context(thd, save_ctx);
 #endif
 
 error:

--- 1.251/sql/item_strfunc.cc	2005-09-01 01:24:03 +03:00
+++ 1.252/sql/item_strfunc.cc	2005-09-14 04:52:42 +03:00
@@ -473,7 +473,8 @@
   {
     uint key_number=(uint) (*res)[0] & 127;
     // Check if automatic key and that we have privilege to uncompress using it
-    if (!(current_thd->master_access & SUPER_ACL) || key_number > 9)
+    if (!(current_thd->security_ctx->master_access & SUPER_ACL) ||
+        key_number > 9)
       goto error;
 
     VOID(pthread_mutex_lock(&LOCK_des_key_file));
@@ -1601,13 +1602,13 @@
 
   if (is_current)
   {
-    user= thd->priv_user;
-    host= thd->priv_host;
+    user= thd->security_ctx->priv_user;
+    host= thd->security_ctx->priv_host;
   }
   else
   {
-    user= thd->user;
-    host= thd->host_or_ip;
+    user= thd->main_security_ctx.user;
+    host= thd->main_security_ctx.priv_host;
   }
 
   // For system threads (e.g. replication SQL thread) user may be empty
@@ -2518,7 +2519,7 @@
 
   if (!(file_name= args[0]->val_str(str))
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-      || !(current_thd->master_access & FILE_ACL)
+      || !(current_thd->security_ctx->master_access & FILE_ACL)
 #endif
       )
     goto err;

--- 1.170/sql/log.cc	2005-09-07 18:39:41 +03:00
+++ 1.171/sql/log.cc	2005-09-14 04:52:43 +03:00
@@ -1476,7 +1476,7 @@
       {						// Normal thread
 	if ((thd->options & OPTION_LOG_OFF)
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-	    && (thd->master_access & SUPER_ACL)
+	    && (thd->security_ctx->master_access & SUPER_ACL)
 #endif
 )
 	{
@@ -1935,10 +1935,12 @@
           tmp_errno=errno;
       }
       if (my_b_printf(&log_file, "# User@Host: %s[%s] @ %s [%s]\n",
-                      thd->priv_user ? thd->priv_user : "",
-                      thd->user ? thd->user : "",
-                      thd->host ? thd->host : "",
-                      thd->ip ? thd->ip : "") == (uint) -1)
+                      thd->security_ctx->priv_user ?
+                      thd->security_ctx->priv_user : "",
+                      thd->security_ctx->user ? thd->security_ctx->user : "",
+                      thd->security_ctx->host ? thd->security_ctx->host : "",
+                      thd->security_ctx->ip ? thd->security_ctx->ip : "") ==
+          (uint) -1)
         tmp_errno=errno;
     }
     if (query_start_arg)

--- 1.349/sql/mysql_priv.h	2005-09-13 15:44:43 +03:00
+++ 1.350/sql/mysql_priv.h	2005-09-14 04:52:43 +03:00
@@ -484,6 +484,7 @@
 #include "protocol.h"
 #include "sql_udf.h"
 class user_var_entry;
+class st_security_context;
 enum enum_var_type
 {
   OPT_DEFAULT= 0, OPT_SESSION, OPT_GLOBAL
@@ -515,7 +516,7 @@
 bool insert_precheck(THD *thd, TABLE_LIST *tables);
 bool create_table_precheck(THD *thd, TABLE_LIST *tables,
                            TABLE_LIST *create_table);
-bool default_view_definer(THD *thd, st_lex_user *definer);
+bool default_view_definer(st_security_context *sctx, st_lex_user *definer);
 
 
 enum enum_mysql_completiontype {

--- 1.495/sql/mysqld.cc	2005-09-06 21:20:14 +03:00
+++ 1.496/sql/mysqld.cc	2005-09-14 04:52:43 +03:00
@@ -776,7 +776,9 @@
     {
       if (global_system_variables.log_warnings)
         sql_print_warning(ER(ER_FORCING_CLOSE),my_progname,
-                          tmp->thread_id,tmp->user ? tmp->user : "");
+                          tmp->thread_id,
+                          (tmp->security_ctx->user ?
+                           tmp->security_ctx->user : ""));
       close_connection(tmp,0,0);
     }
 #endif
@@ -3582,7 +3584,7 @@
   thd->client_capabilities=0;
   my_net_init(&thd->net,(st_vio*) 0);
   thd->max_client_packet_length= thd->net.max_packet;
-  thd->master_access= ~(ulong)0;
+  thd->security_ctx->master_access= ~(ulong)0;
   thd->thread_id=thread_id++;
   thread_count++;
 
@@ -3922,7 +3924,7 @@
       continue;
     }
     if (sock == unix_sock)
-      thd->host=(char*) my_localhost;
+      thd->security_ctx->host=(char*) my_localhost;
 #ifdef __WIN__
     /* Set default wait_timeout */
     ulong wait_timeout= global_system_variables.net_wait_timeout * 1000;

--- 1.255/sql/slave.cc	2005-08-11 14:02:44 +03:00
+++ 1.256/sql/slave.cc	2005-09-14 04:52:43 +03:00
@@ -2809,17 +2809,10 @@
   DBUG_ENTER("init_slave_thread");
   thd->system_thread = (thd_type == SLAVE_THD_SQL) ?
     SYSTEM_THREAD_SLAVE_SQL : SYSTEM_THREAD_SLAVE_IO; 
-  /*
-    The two next lines are needed for replication of SP (CREATE PROCEDURE
-    needs a valid user to store in mysql.proc).
-  */
-  thd->priv_user= (char *) "";
-  thd->priv_host[0]= '\0';
-  thd->host_or_ip= "";
+  thd->security_ctx->skip_grants();
   thd->client_capabilities = 0;
   my_net_init(&thd->net, 0);
   thd->net.read_timeout = slave_net_timeout;
-  thd->master_access= ~(ulong)0;
   thd->slave_thread = 1;
   set_slave_thread_options(thd);
   /* 

--- 1.168/sql/sql_acl.cc	2005-09-13 15:44:43 +03:00
+++ 1.169/sql/sql_acl.cc	2005-09-14 04:52:44 +03:00
@@ -719,6 +719,7 @@
   ulong user_access= NO_ACCESS;
   int res= 1;
   ACL_USER *acl_user= 0;
+  st_security_context *sctx= thd->security_ctx;
   DBUG_ENTER("acl_getroot");
 
   if (!initialized)
@@ -726,10 +727,7 @@
     /* 
       here if mysqld's been started with --skip-grant-tables option.
     */
-    thd->priv_user= (char *) "";                // privileges for
-    *thd->priv_host= '\0';                      // the user are unknown
-    thd->master_access= ~NO_ACCESS;             // everything is allowed
-    bzero((char*) mqh, sizeof(*mqh));
+    sctx->skip_grants();
     DBUG_RETURN(0);
   }
 
@@ -744,9 +742,9 @@
   for (uint i=0 ; i < acl_users.elements ; i++)
   {
     ACL_USER *acl_user_tmp= dynamic_element(&acl_users,i,ACL_USER*);
-    if (!acl_user_tmp->user || !strcmp(thd->user, acl_user_tmp->user))
+    if (!acl_user_tmp->user || !strcmp(sctx->user, acl_user_tmp->user))
     {
-      if (compare_hostname(&acl_user_tmp->host, thd->host, thd->ip))
+      if (compare_hostname(&acl_user_tmp->host, sctx->host, sctx->ip))
       {
         /* check password: it should be empty or valid */
         if (passwd_len == acl_user_tmp->salt_len)
@@ -893,14 +891,14 @@
       break;
 #endif /* HAVE_OPENSSL */
     }
-    thd->master_access= user_access;
-    thd->priv_user= acl_user->user ? thd->user : (char *) "";
+    sctx->master_access= user_access;
+    sctx->priv_user= acl_user->user ? sctx->user : (char *) "";
     *mqh= acl_user->user_resource;
 
     if (acl_user->host.hostname)
-      strmake(thd->priv_host, acl_user->host.hostname, MAX_HOSTNAME);
+      strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME);
     else
-      *thd->priv_host= 0;
+      *sctx->priv_host= 0;
   }
   VOID(pthread_mutex_unlock(&acl_cache->lock));
   DBUG_RETURN(res);
@@ -913,42 +911,46 @@
  * Used to get access rights for SQL SECURITY DEFINER invocation of
  * stored procedures.
  */
-int acl_getroot_no_password(THD *thd)
+int acl_getroot_no_password(st_security_context *sctx, char *user, char *host,
+                            char *ip, char *db)
 {
   int res= 1;
   uint i;
   ACL_USER *acl_user= 0;
   DBUG_ENTER("acl_getroot_no_password");
 
+  sctx->user= user;
+  sctx->host= host;
+  sctx->ip= ip;
+  sctx->host_or_ip= host ? host : (ip ? ip : "");
+
   if (!initialized)
   {
-    /* 
+    /*
       here if mysqld's been started with --skip-grant-tables option.
     */
-    thd->priv_user= (char *) "";                // privileges for
-    *thd->priv_host= '\0';                      // the user are unknown
-    thd->master_access= ~NO_ACCESS;             // everything is allowed
+    sctx->skip_grants();
     DBUG_RETURN(0);
   }
 
   VOID(pthread_mutex_lock(&acl_cache->lock));
 
-  thd->master_access= 0;
-  thd->db_access= 0;
+  sctx->master_access= 0;
+  sctx->db_access= 0;
 
   /*
      Find acl entry in user database.
      This is specially tailored to suit the check we do for CALL of
-     a stored procedure; thd->user is set to what is actually a
+     a stored procedure; user is set to what is actually a
      priv_user, which can be ''.
   */
   for (i=0 ; i < acl_users.elements ; i++)
   {
     acl_user= dynamic_element(&acl_users,i,ACL_USER*);
-    if ((!acl_user->user && (!thd->user || !thd->user[0])) ||
-	(acl_user->user && strcmp(thd->user, acl_user->user) == 0))
+    if ((!acl_user->user && (!user || !user[0])) ||
+	(acl_user->user && strcmp(user, acl_user->user) == 0))
     {
-      if (compare_hostname(&acl_user->host, thd->host, thd->ip))
+      if (compare_hostname(&acl_user->host, host, ip))
       {
 	res= 0;
 	break;
@@ -962,25 +964,25 @@
     {
       ACL_DB *acl_db= dynamic_element(&acl_dbs, i, ACL_DB*);
       if (!acl_db->user ||
-	  (thd->user && thd->user[0] && !strcmp(thd->user,
acl_db->user)))
+	  (user && user[0] && !strcmp(user, acl_db->user)))
       {
-	if (compare_hostname(&acl_db->host, thd->host, thd->ip))
+	if (compare_hostname(&acl_db->host, host, ip))
 	{
-	  if (!acl_db->db || (thd->db && !strcmp(acl_db->db, thd->db)))
+	  if (!acl_db->db || (db && !strcmp(acl_db->db, db)))
 	  {
-	    thd->db_access= acl_db->access;
+	    sctx->db_access= acl_db->access;
 	    break;
 	  }
 	}
       }
     }
-    thd->master_access= acl_user->access;
-    thd->priv_user= acl_user->user ? thd->user : (char *) "";
+    sctx->master_access= acl_user->access;
+    sctx->priv_user= acl_user->user ? user : (char *) "";
 
     if (acl_user->host.hostname)
-      strmake(thd->priv_host, acl_user->host.hostname, MAX_HOSTNAME);
+      strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME);
     else
-      *thd->priv_host= 0;
+      *sctx->priv_host= 0;
   }
   VOID(pthread_mutex_unlock(&acl_cache->lock));
   DBUG_RETURN(res);
@@ -1334,13 +1336,13 @@
     return(1);
   }
   if (!thd->slave_thread &&
-      (strcmp(thd->user,user) ||
-       my_strcasecmp(system_charset_info, host, thd->priv_host)))
+      (strcmp(thd->security_ctx->user, user) ||
+       my_strcasecmp(system_charset_info, host, thd->security_ctx->priv_host)))
   {
     if (check_access(thd, UPDATE_ACL, "mysql",0,1,0))
       return(1);
   }
-  if (!thd->slave_thread && !thd->user[0])
+  if (!thd->slave_thread && !thd->security_ctx->user[0])
   {
     my_message(ER_PASSWORD_ANONYMOUS_USER, ER(ER_PASSWORD_ANONYMOUS_USER),
                MYF(0));
@@ -1646,9 +1648,10 @@
 
 static bool test_if_create_new_users(THD *thd)
 {
-  bool create_new_users= test(thd->master_access & INSERT_ACL) ||
+  st_security_context *sctx= thd->security_ctx;
+  bool create_new_users= test(sctx->master_access & INSERT_ACL) ||
                          (!opt_safe_user_create &&
-                          test(thd->master_access & CREATE_USER_ACL));
+                          test(sctx->master_access & CREATE_USER_ACL));
   if (!create_new_users)
   {
     TABLE_LIST tl;
@@ -1658,8 +1661,8 @@
     tl.table_name=  (char*) "user";
     create_new_users= 1;
 
-    db_access=acl_get(thd->host, thd->ip,
-		      thd->priv_user, tl.db, 0);
+    db_access=acl_get(sctx->host, sctx->ip,
+		      sctx->priv_user, tl.db, 0);
     if (!(db_access & INSERT_ACL))
     {
       if (check_grant(thd, INSERT_ACL, &tl, 0, UINT_MAX, 1))
@@ -1738,7 +1741,7 @@
     else if (!can_create_user)
     {
       my_error(ER_CANT_CREATE_USER_WITH_GRANT, MYF(0),
-               thd->user, thd->host_or_ip);
+               thd->security_ctx->user, thd->security_ctx->host_or_ip);
       goto end;
     }
     old_row_exists = 0;
@@ -2450,7 +2453,8 @@
   byte user_key[MAX_KEY_LENGTH];
   DBUG_ENTER("replace_table_table");
 
-  strxmov(grantor, thd->user, "@", thd->host_or_ip, NullS);
+  strxmov(grantor, thd->security_ctx->user, "@",
+          thd->security_ctx->host_or_ip, NullS);
 
   /*
     The following should always succeed as new users are created before
@@ -2572,7 +2576,8 @@
     DBUG_RETURN(-1);
   }
 
-  strxmov(grantor, thd->user, "@", thd->host_or_ip, NullS);
+  strxmov(grantor, thd->security_ctx->user, "@",
+          thd->security_ctx->host_or_ip, NullS);
 
   /*
     The following should always succeed as new users are created before
@@ -2762,7 +2767,8 @@
         get_privilege_desc(command, sizeof(command),
                            table_list->grant.want_privilege);
         my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
-                 command, thd->priv_user, thd->host_or_ip, table_list->alias);
+                 command, thd->security_ctx->priv_user,
+                 thd->security_ctx->host_or_ip, table_list->alias);
         DBUG_RETURN(-1);
       }
     }
@@ -3485,11 +3491,11 @@
 		 uint show_table, uint number, bool no_errors)
 {
   TABLE_LIST *table;
-  char *user = thd->priv_user;
+  st_security_context *sctx= thd->security_ctx;
   DBUG_ENTER("check_grant");
   DBUG_ASSERT(number > 0);
 
-  want_access&= ~thd->master_access;
+  want_access&= ~sctx->master_access;
   if (!want_access)
     DBUG_RETURN(0);                             // ok
 
@@ -3507,8 +3513,9 @@
       table->grant.want_privilege= 0;
       continue;					// Already checked
     }
-    if (!(grant_table= table_hash_search(thd->host,thd->ip,
-                                         table->db,user, table->table_name,0)))
+    if (!(grant_table= table_hash_search(sctx->host, sctx->ip,
+                                         table->db, sctx->priv_user,
+                                         table->table_name,0)))
     {
       want_access &= ~table->grant.privilege;
       goto err;					// No grants
@@ -3542,8 +3549,8 @@
     get_privilege_desc(command, sizeof(command), want_access);
     my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
              command,
-             thd->priv_user,
-             thd->host_or_ip,
+             sctx->priv_user,
+             sctx->host_or_ip,
              table ? table->table_name : "unknown");
   }
   DBUG_RETURN(1);
@@ -3554,6 +3561,7 @@
 			const char *db_name, const char *table_name,
 			const char *name, uint length, uint show_tables)
 {
+  st_security_context *sctx= thd->security_ctx;
   GRANT_TABLE *grant_table;
   GRANT_COLUMN *grant_column;
   ulong want_access= grant->want_privilege & ~grant->privilege;
@@ -3570,8 +3578,8 @@
   if (grant->version != grant_version)
   {
     grant->grant_table=
-      table_hash_search(thd->host, thd->ip, db_name,
-			thd->priv_user,
+      table_hash_search(sctx->host, sctx->ip, db_name,
+			sctx->priv_user,
 			table_name, 0);         /* purecov: inspected */
     grant->version= grant_version;		/* purecov: inspected */
   }
@@ -3600,8 +3608,8 @@
     get_privilege_desc(command, sizeof(command), want_access);
     my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
              command,
-             thd->priv_user,
-             thd->host_or_ip,
+             sctx->priv_user,
+             sctx->host_or_ip,
              name,
              table_name);
   }
@@ -3613,6 +3621,7 @@
                              const char* db_name, const char *table_name,
                              Field_iterator *fields)
 {
+  st_security_context *sctx= thd->security_ctx;
   GRANT_TABLE *grant_table;
   GRANT_COLUMN *grant_column;
 
@@ -3629,8 +3638,8 @@
   if (grant->version != grant_version)
   {
     grant->grant_table=
-      table_hash_search(thd->host, thd->ip, db_name,
-			thd->priv_user,
+      table_hash_search(sctx->host, sctx->ip, db_name,
+			sctx->priv_user,
 			table_name, 0);	/* purecov: inspected */
     grant->version= grant_version;		/* purecov: inspected */
   }
@@ -3656,8 +3665,8 @@
   get_privilege_desc(command, sizeof(command), want_access);
   my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
            command,
-           thd->priv_user,
-           thd->host_or_ip,
+           sctx->priv_user,
+           sctx->host_or_ip,
            fields->name(),
            table_name);
   return 1;
@@ -3672,11 +3681,12 @@
 
 bool check_grant_db(THD *thd,const char *db)
 {
+  st_security_context *sctx= thd->security_ctx;
   char helping [NAME_LEN+USERNAME_LENGTH+2];
   uint len;
   bool error= 1;
 
-  len= (uint) (strmov(strmov(helping,thd->priv_user)+1,db)-helping)+ 1;
+  len= (uint) (strmov(strmov(helping, sctx->priv_user) + 1, db) - helping) + 1;
   rw_rdlock(&LOCK_grant);
 
   for (uint idx=0 ; idx < column_priv_hash.records ; idx++)
@@ -3685,7 +3695,7 @@
 							  idx);
     if (len < grant_table->key_length &&
 	!memcmp(grant_table->hash_key,helping,len) &&
-        compare_hostname(&grant_table->host, thd->host, thd->ip))
+        compare_hostname(&grant_table->host, sctx->host, sctx->ip))
     {
       error=0;					// Found match
       break;
@@ -3713,15 +3723,16 @@
      1  Error: User did not have the requested privielges
 ****************************************************************************/
 
-bool check_grant_routine(THD *thd, ulong want_access, 
+bool check_grant_routine(THD *thd, ulong want_access,
 			 TABLE_LIST *procs, bool is_proc, bool no_errors)
 {
   TABLE_LIST *table;
-  char *user= thd->priv_user;
-  char *host= thd->priv_host;
+  st_security_context *sctx= thd->security_ctx;
+  char *user= sctx->priv_user;
+  char *host= sctx->priv_host;
   DBUG_ENTER("check_grant_routine");
 
-  want_access&= ~thd->master_access;
+  want_access&= ~sctx->master_access;
   if (!want_access)
     DBUG_RETURN(0);                             // ok
 
@@ -3729,7 +3740,7 @@
   for (table= procs; table; table= table->next_global)
   {
     GRANT_NAME *grant_proc;
-    if ((grant_proc= routine_hash_search(host,thd->ip, table->db, user,
+    if ((grant_proc= routine_hash_search(host, sctx->ip, table->db, user,
 					 table->table_name, is_proc, 0)))
       table->grant.privilege|= grant_proc->privs;
 
@@ -3785,8 +3796,10 @@
   {
     GRANT_NAME *grant_proc;
     rw_rdlock(&LOCK_grant);
-    if ((grant_proc= routine_hash_search(thd->priv_host, thd->ip, db,
-                                         thd->priv_user, name, is_proc, 0)))
+    if ((grant_proc= routine_hash_search(thd->security_ctx->priv_host,
+                                         thd->security_ctx->ip, db,
+                                         thd->security_ctx->priv_user,
+                                         name, is_proc, 0)))
       no_routine_acl= !(grant_proc->privs & SHOW_PROC_ACLS);
     rw_unlock(&LOCK_grant);
   }
@@ -3801,7 +3814,7 @@
 ulong get_table_grant(THD *thd, TABLE_LIST *table)
 {
   ulong privilege;
-  char *user = thd->priv_user;
+  st_security_context *sctx= thd->security_ctx;
   const char *db = table->db ? table->db : thd->db;
   GRANT_TABLE *grant_table;
 
@@ -3809,7 +3822,7 @@
 #ifdef EMBEDDED_LIBRARY
   grant_table= NULL;
 #else
-  grant_table= table_hash_search(thd->host, thd->ip, db, user,
+  grant_table= table_hash_search(sctx->host, sctx->ip, db, sctx->priv_user,
 				 table->table_name, 0);
 #endif
   table->grant.grant_table=grant_table; // Remember for column test
@@ -3853,8 +3866,8 @@
   if (grant->version != grant_version)
   {
     grant->grant_table=
-      table_hash_search(thd->host, thd->ip, db_name,
-			thd->priv_user,
+      table_hash_search(thd->security_ctx->host, thd->security_ctx->ip,
+                        db_name, thd->security_ctx->priv_user,
 			table_name, 0);	        /* purecov: inspected */
     grant->version= grant_version;              /* purecov: inspected */
   }
@@ -5424,22 +5437,24 @@
 bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
                          bool is_proc)
 {
+  st_security_context *sctx= thd->security_ctx;
   LEX_USER *combo;
   TABLE_LIST tables[1];
   List<LEX_USER> user_list;
   bool result;
-  DBUG_ENTER("sp_grant_privileges");  
+  DBUG_ENTER("sp_grant_privileges");
 
   if (!(combo=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
     DBUG_RETURN(TRUE);
 
-  combo->user.str= thd->user;
+  combo->user.str= sctx->user;
   
-  if (!find_acl_user(combo->host.str=(char*)thd->host_or_ip, combo->user.str,
+  if (!find_acl_user(combo->host.str=(char*)sctx->host_or_ip, combo->user.str,
+                     FALSE) &&
+      !find_acl_user(combo->host.str=(char*)sctx->host, combo->user.str,
                      FALSE) &&
-      !find_acl_user(combo->host.str=(char*)thd->host, combo->user.str,
+      !find_acl_user(combo->host.str=(char*)sctx->ip, combo->user.str,
                      FALSE) &&
-      !find_acl_user(combo->host.str=(char*)thd->ip, combo->user.str, FALSE)
&&
       !find_acl_user(combo->host.str=(char*)"%", combo->user.str, FALSE))
     DBUG_RETURN(TRUE);
 
@@ -5556,7 +5571,8 @@
   char buff[100];
   TABLE *table= tables->table;
   bool no_global_access= check_access(thd, SELECT_ACL, "mysql",0,1,1);
-  char *curr_host= thd->priv_host ? thd->priv_host : (char *) "%";
+  char *curr_host= (thd->security_ctx->priv_host ?
+                    thd->security_ctx->priv_host : (char *) "%");
   DBUG_ENTER("fill_schema_user_privileges");
 
   for (counter=0 ; counter < acl_users.elements ; counter++)
@@ -5569,7 +5585,7 @@
       host= "";
 
     if (no_global_access &&
-        (strcmp(thd->priv_user, user) ||
+        (strcmp(thd->security_ctx->priv_user, user) ||
          my_strcasecmp(system_charset_info, curr_host, host)))
       continue;
       
@@ -5609,7 +5625,8 @@
   char buff[100];
   TABLE *table= tables->table;
   bool no_global_access= check_access(thd, SELECT_ACL, "mysql",0,1,1);
-  char *curr_host= thd->priv_host ? thd->priv_host : (char *) "%";
+  char *curr_host= (thd->security_ctx->priv_host ?
+                    thd->security_ctx->priv_host : (char *) "%");
   DBUG_ENTER("fill_schema_schema_privileges");
 
   for (counter=0 ; counter < acl_dbs.elements ; counter++)
@@ -5623,7 +5640,7 @@
       host= "";
 
     if (no_global_access &&
-        (strcmp(thd->priv_user, user) ||
+        (strcmp(thd->security_ctx->priv_user, user) ||
          my_strcasecmp(system_charset_info, curr_host, host)))
       continue;
 
@@ -5664,7 +5681,8 @@
   char buff[100];
   TABLE *table= tables->table;
   bool no_global_access= check_access(thd, SELECT_ACL, "mysql",0,1,1);
-  char *curr_host= thd->priv_host ? thd->priv_host : (char *) "%";
+  char *curr_host= (thd->security_ctx->priv_host ?
+                    thd->security_ctx->priv_host : (char *) "%");
   DBUG_ENTER("fill_schema_table_privileges");
 
   for (index=0 ; index < column_priv_hash.records ; index++)
@@ -5676,7 +5694,7 @@
       user= "";
 
     if (no_global_access &&
-        (strcmp(thd->priv_user, user) ||
+        (strcmp(thd->security_ctx->priv_user, user) ||
          my_strcasecmp(system_charset_info, curr_host,
                        grant_table->host.hostname)))
       continue;
@@ -5726,7 +5744,8 @@
   char buff[100];
   TABLE *table= tables->table;
   bool no_global_access= check_access(thd, SELECT_ACL, "mysql",0,1,1);
-  char *curr_host= thd->priv_host ? thd->priv_host : (char *) "%";
+  char *curr_host= (thd->security_ctx->priv_host ?
+                    thd->security_ctx->priv_host : (char *) "%");
   DBUG_ENTER("fill_schema_table_privileges");
 
   for (index=0 ; index < column_priv_hash.records ; index++)
@@ -5738,7 +5757,7 @@
       user= "";
 
     if (no_global_access &&
-        (strcmp(thd->priv_user, user) ||
+        (strcmp(thd->security_ctx->priv_user, user) ||
          my_strcasecmp(system_charset_info, curr_host,
                        grant_table->host.hostname)))
       continue;
@@ -5802,6 +5821,7 @@
 void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
                                      const char *db, const char *table)
 {
+  st_security_context *sctx= thd->security_ctx;
   /* --skip-grants */
   if (!initialized)
   {
@@ -5810,13 +5830,13 @@
   }
 
   /* global privileges */
-  grant->privilege= thd->master_access;
+  grant->privilege= sctx->master_access;
 
-  if (!thd->priv_user)
+  if (!sctx->priv_user)
     return;                                   // it is slave
 
   /* db privileges */
-  grant->privilege|= acl_get(thd->host, thd->ip, thd->priv_user, db, 0);
+  grant->privilege|= acl_get(sctx->host, sctx->ip, sctx->priv_user, db, 0);
 
   if (!grant_option)
     return;
@@ -5826,8 +5846,8 @@
   {
     rw_rdlock(&LOCK_grant);
     grant->grant_table=
-      table_hash_search(thd->host, thd->ip, db,
-			thd->priv_user,
+      table_hash_search(sctx->host, sctx->ip, db,
+			sctx->priv_user,
 			table, 0);              /* purecov: inspected */
     grant->version= grant_version;              /* purecov: inspected */
     rw_unlock(&LOCK_grant);

--- 1.46/sql/sql_acl.h	2005-09-13 15:44:43 +03:00
+++ 1.47/sql/sql_acl.h	2005-09-14 04:52:44 +03:00
@@ -181,7 +181,8 @@
 	      const char *user, const char *db, my_bool db_is_pattern);
 int acl_getroot(THD *thd, USER_RESOURCES *mqh, const char *passwd,
                 uint passwd_len);
-int acl_getroot_no_password(THD *thd);
+int acl_getroot_no_password(st_security_context *sctx, char *user, char *host,
+                            char *ip, char *db);
 bool acl_check_host(const char *host, const char *ip);
 bool check_change_password(THD *thd, const char *host, const char *user,
                            char *password, uint password_len);

--- 1.298/sql/sql_base.cc	2005-09-09 10:10:53 +03:00
+++ 1.299/sql/sql_base.cc	2005-09-14 04:52:44 +03:00
@@ -4494,7 +4494,8 @@
                VIEW_ANY_ACL)))
         {
           my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), "ANY",
-                   thd->priv_user, thd->host_or_ip,
+                   thd->security_ctx->priv_user,
+                   thd->security_ctx->host_or_ip,
                    fld->field_name, field_table_name);
           DBUG_RETURN(TRUE);
         }

--- 1.209/sql/sql_class.cc	2005-09-09 10:44:07 +03:00
+++ 1.210/sql/sql_class.cc	2005-09-14 04:52:44 +03:00
@@ -181,9 +181,10 @@
    spcont(NULL)
 {
   stmt_arena= this;
-  host= user= priv_user= db= ip= 0;
+  db= 0;
   catalog= (char*)"std"; // the only catalog we have for now
-  host_or_ip= "connecting host";
+  main_security_ctx.init();
+  security_ctx= &main_security_ctx;
   locked=some_tables_deleted=no_errors=password= 0;
   query_start_used= 0;
   count_cuted_fields= CHECK_FIELD_IGNORE;
@@ -236,9 +237,6 @@
   server_id = ::server_id;
   slave_net = 0;
   command=COM_CONNECT;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-  db_access=NO_ACCESS;
-#endif
   *scramble= '\0';
 
   init();
@@ -426,12 +424,8 @@
 
   ha_close_connection(this);
 
-  DBUG_PRINT("info", ("freeing host"));
-  if (host != my_localhost)			// If not pointer to constant
-    safeFree(host);
-  if (user != delayed_user)
-    safeFree(user);
-  safeFree(ip);
+  DBUG_PRINT("info", ("freeing security context"));
+  main_security_ctx.destroy();
   safeFree(db);
   free_root(&warn_root,MYF(0));
 #ifdef USING_TRANSACTIONS
@@ -1800,6 +1794,38 @@
 {
   bzero((char*) &status_var, sizeof(status_var));
 }
+
+
+void st_security_context::init()
+{
+  host= user= priv_user= ip= 0;
+  host_or_ip= "connecting host";
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+  db_access= NO_ACCESS;
+#endif
+}
+
+
+void st_security_context::destroy()
+{
+  // If not pointer to constant
+  if (host != my_localhost)
+    safeFree(host);
+  if (user != delayed_user)
+    safeFree(user);
+  safeFree(ip);
+}
+
+
+void st_security_context::skip_grants()
+{
+  /* privileges for the user are unknown everything is allowed */
+  host_or_ip= "";
+  master_access= ~NO_ACCESS;
+  priv_user= "";
+  *priv_host= '\0';
+}
+
 
 /****************************************************************************
   Handling of open and locked tables states.

--- 1.263/sql/sql_class.h	2005-09-07 18:39:41 +03:00
+++ 1.264/sql/sql_class.h	2005-09-14 04:52:44 +03:00
@@ -941,6 +941,28 @@
 bool xid_cache_insert(XID_STATE *xid_state);
 void xid_cache_delete(XID_STATE *xid_state);
 
+
+struct st_security_context {
+  /*
+    host - host of the client
+    user - user of the client, set to NULL until the user has been read from
+    the connection
+    priv_user - The user privilege we are using. May be '' for anonymous user.
+    ip - client IP
+  */
+  char   *host, *user, *priv_user, *ip;
+  char   priv_host[MAX_HOSTNAME];
+  /* points to host if host is available, otherwise points to ip */
+  const char *host_or_ip;
+  ulong master_access;                 /* Global privileges from mysql.user */
+  ulong db_access;                     /* Privileges for current db */
+
+  void init();
+  void destroy();
+  void skip_grants();
+};
+
+
 /*
   A registry for item tree transformations performed during
   query optimization. We register only those changes which require
@@ -1113,13 +1135,8 @@
   char	  *thread_stack;
 
   /*
-    host - host of the client
-    user - user of the client, set to NULL until the user has been read from
-     the connection
-    priv_user - The user privilege we are using. May be '' for anonymous user.
     db - currently selected database
     catalog - currently selected catalog
-    ip - client IP
     WARNING: some members of THD (currently 'db', 'catalog' and 'query')  are
     set and alloced by the slave SQL thread (for the THD of that thread); that
     thread is (and must remain, for now) the only responsible for freeing these
@@ -1128,8 +1145,10 @@
     properly. For details see the 'err:' label of the pthread_handler_decl of
     the slave SQL thread, in sql/slave.cc.
    */
-  char	  *host,*user,*priv_user,*db,*catalog,*ip;
-  char	  priv_host[MAX_HOSTNAME];
+  char   *db, *catalog;
+  st_security_context main_security_ctx;
+  st_security_context *security_ctx;
+
   /* remote (peer) port */
   uint16 peer_port;
   /*
@@ -1138,13 +1157,9 @@
     a time-consuming piece that MySQL can get stuck in for a long time.
   */
   const char *proc_info;
-  /* points to host if host is available, otherwise points to ip */
-  const char *host_or_ip;
 
   ulong client_capabilities;		/* What the client supports */
   ulong max_client_packet_length;
-  ulong master_access;			/* Global privileges from mysql.user */
-  ulong db_access;			/* Privileges for current db */
 
   HASH		handler_tables_hash;
   /*

--- 1.115/sql/sql_db.cc	2005-08-26 14:28:00 +03:00
+++ 1.116/sql/sql_db.cc	2005-09-14 04:52:44 +03:00
@@ -1089,6 +1089,7 @@
   bool system_db= 0;
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
   ulong db_access;
+  st_security_context *sctx= thd->security_ctx;
 #endif
   DBUG_ENTER("mysql_change_db");
   DBUG_PRINT("enter",("name: '%s'",name));
@@ -1126,22 +1127,20 @@
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
   if (!no_access_check)
   {
-    if (test_all_bits(thd->master_access,DB_ACLS))
+    if (test_all_bits(sctx->master_access,DB_ACLS))
       db_access=DB_ACLS;
     else
-      db_access= (acl_get(thd->host,thd->ip, thd->priv_user,dbname,0) |
-                  thd->master_access);
+      db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname, 0) |
+                  sctx->master_access);
     if (!(db_access & DB_ACLS) && (!grant_option ||
                                    check_grant_db(thd,dbname)))
     {
       my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-               thd->priv_user,
-               thd->priv_host,
+               sctx->priv_user,
+               sctx->priv_host,
                dbname);
-      mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
-                      thd->priv_user,
-                      thd->priv_host,
-                      dbname);
+      mysql_log.write(thd, COM_INIT_DB, ER(ER_DBACCESS_DENIED_ERROR),
+                      sctx->priv_user, sctx->priv_host, dbname);
       my_free(dbname,MYF(0));
       DBUG_RETURN(1);
     }
@@ -1163,7 +1162,7 @@
   thd->db_length=db_length;
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
   if (!no_access_check)
-    thd->db_access=db_access;
+    sctx->db_access=db_access;
 #endif
   if (system_db)
   {

--- 1.173/sql/sql_insert.cc	2005-09-02 09:50:10 +03:00
+++ 1.174/sql/sql_insert.cc	2005-09-14 04:52:44 +03:00
@@ -272,7 +272,8 @@
     By default, both logs are enabled (this won't cause problems if the server
     runs without --log-update or --log-bin).
   */
-  bool log_on= (thd->options & OPTION_BIN_LOG) || (!(thd->master_access &
SUPER_ACL));
+  bool log_on= (thd->options & OPTION_BIN_LOG) ||
+    (!(thd->security_ctx->master_access & SUPER_ACL));
   bool transactional_table;
   uint value_count;
   ulong counter = 1;
@@ -1264,8 +1265,8 @@
      table(0),tables_in_use(0),stacked_inserts(0), status(0), dead(0),
      group_count(0)
   {
-    thd.user=thd.priv_user=(char*) delayed_user;
-    thd.host=(char*) my_localhost;
+    thd.security_ctx->user=thd.security_ctx->priv_user=(char*) delayed_user;
+    thd.security_ctx->host=(char*) my_localhost;
     thd.current_tablenr=0;
     thd.version=refresh_version;
     thd.command=COM_DELAYED_INSERT;
@@ -1275,7 +1276,7 @@
     bzero((char*) &thd.net, sizeof(thd.net));		// Safety
     bzero((char*) &table_list, sizeof(table_list));	// Safety
     thd.system_thread= SYSTEM_THREAD_DELAYED_INSERT;
-    thd.host_or_ip= "";
+    thd.security_ctx->host_or_ip= "";
     bzero((char*) &info,sizeof(info));
     pthread_mutex_init(&mutex,MY_MUTEX_INIT_FAST);
     pthread_cond_init(&cond,NULL);
@@ -1298,7 +1299,7 @@
     pthread_cond_destroy(&cond_client);
     thd.unlink();				// Must be unlinked under lock
     x_free(thd.query);
-    thd.user=thd.host=0;
+    thd.security_ctx->user= thd.security_ctx->host=0;
     thread_count--;
     delayed_insert_threads--;
     VOID(pthread_mutex_unlock(&LOCK_thread_count));

--- 1.484/sql/sql_parse.cc	2005-09-13 15:44:43 +03:00
+++ 1.485/sql/sql_parse.cc	2005-09-14 04:52:44 +03:00
@@ -270,10 +270,11 @@
 	       const char *passwd, uint passwd_len, const char *db,
 	       bool check_count)
 {
+  st_security_context *sctx= thd->security_ctx;
   DBUG_ENTER("check_user");
   
 #ifdef NO_EMBEDDED_ACCESS_CHECKS
-  thd->master_access= GLOBAL_ACLS;			// Full rights
+  sctx->master_access= GLOBAL_ACLS;			// Full rights
   /* Change database if necessary */
   if (db && db[0])
   {
@@ -340,9 +341,9 @@
     if (opt_secure_auth_local)
     {
       net_printf_error(thd, ER_SERVER_IS_IN_SECURE_AUTH_MODE,
-                       thd->user, thd->host_or_ip);
+                       sctx->user, sctx->host_or_ip);
       mysql_log.write(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE),
-                      thd->user, thd->host_or_ip);
+                      sctx->user, sctx->host_or_ip);
       DBUG_RETURN(-1);
     }
     /* We have to read very specific packet size */
@@ -360,22 +361,22 @@
   /* here res is always >= 0 */
   if (res == 0)
   {
-    if (!(thd->master_access & NO_ACCESS)) // authentication is OK 
+    if (!(sctx->master_access & NO_ACCESS)) // authentication is OK 
     {
       DBUG_PRINT("info",
                  ("Capabilities: %d  packet_length: %ld  Host: '%s'  "
                   "Login user: '%s' Priv_user: '%s'  Using password: %s "
                   "Access: %u  db: '%s'",
                   thd->client_capabilities, thd->max_client_packet_length,
-                  thd->host_or_ip, thd->user, thd->priv_user,
+                  sctx->host_or_ip, sctx->user, sctx->priv_user,
                   passwd_len ? "yes": "no",
-                  thd->master_access, thd->db ? thd->db : "*none*"));
+                  sctx->master_access, thd->db ? thd->db : "*none*"));
 
       if (check_count)
       {
         VOID(pthread_mutex_lock(&LOCK_thread_count));
         bool count_ok= thread_count <= max_connections + delayed_insert_threads
-                       || (thd->master_access & SUPER_ACL);
+                       || (sctx->master_access & SUPER_ACL);
         VOID(pthread_mutex_unlock(&LOCK_thread_count));
         if (!count_ok)
         {                                         // too many connections
@@ -385,11 +386,11 @@
       }
 
       /* Why logging is performed before all checks've passed? */
-      mysql_log.write(thd,command,
-                      (thd->priv_user == thd->user ?
+      mysql_log.write(thd, command,
+                      (sctx->priv_user == sctx->user ?
                        (char*) "%s@%s on %s" :
                        (char*) "%s@%s as anonymous on %s"),
-                      thd->user, thd->host_or_ip,
+                      sctx->user, sctx->host_or_ip,
                       db ? db : (char*) "");
 
       /*
@@ -397,14 +398,14 @@
         set to 0 here because we don't have an active database yet (and we
         may not have an active database to set.
       */
-      thd->db_access=0;
+      sctx->db_access=0;
 
       /* Don't allow user to connect if he has done too many queries */
       if ((ur.questions || ur.updates || ur.conn_per_hour || ur.user_conn ||
 	   max_user_connections) &&
 	  get_or_create_user_conn(thd,
-            opt_old_style_user_limits ? thd->user : thd->priv_user,
-            opt_old_style_user_limits ? thd->host_or_ip : thd->priv_host,
+            (opt_old_style_user_limits ? sctx->user : sctx->priv_user),
+            (opt_old_style_user_limits ? sctx->host_or_ip : sctx->priv_host),
             &ur))
 	DBUG_RETURN(-1);
       if (thd->user_connect &&
@@ -439,12 +440,12 @@
     DBUG_RETURN(-1);
   }
   net_printf_error(thd, ER_ACCESS_DENIED_ERROR,
-                   thd->user,
-                   thd->host_or_ip,
+                   sctx->user,
+                   sctx->host_or_ip,
                    passwd_len ? ER(ER_YES) : ER(ER_NO));
   mysql_log.write(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
-                  thd->user,
-                  thd->host_or_ip,
+                  sctx->user,
+                  sctx->host_or_ip,
                   passwd_len ? ER(ER_YES) : ER(ER_NO));
   DBUG_RETURN(-1);
 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
@@ -764,45 +765,46 @@
   NET *net= &thd->net;
   ulong pkt_len= 0;
   char *end;
+  st_security_context *sctx= thd->security_ctx;
 
   DBUG_PRINT("info",
              ("New connection received on %s", vio_description(net->vio)));
 
-  if (!thd->host)                           // If TCP/IP connection
+  if (!sctx->host)                           // If TCP/IP connection
   {
     char ip[30];
 
     if (vio_peer_addr(net->vio, ip, &thd->peer_port))
       return (ER_BAD_HOST_ERROR);
-    if (!(thd->ip= my_strdup(ip,MYF(0))))
+    if (!(sctx->ip= my_strdup(ip,MYF(0))))
       return (ER_OUT_OF_RESOURCES);
-    thd->host_or_ip= thd->ip;
+    sctx->host_or_ip= sctx->ip;
     vio_in_addr(net->vio,&thd->remote.sin_addr);
     if (!(specialflag & SPECIAL_NO_RESOLVE))
     {
       vio_in_addr(net->vio,&thd->remote.sin_addr);
-      thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors);
+      sctx->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors);
       /* Cut very long hostnames to avoid possible overflows */
-      if (thd->host)
+      if (sctx->host)
       {
-        if (thd->host != my_localhost)
-          thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0;
-        thd->host_or_ip= thd->host;
+        if (sctx->host != my_localhost)
+          sctx->host[min(strlen(sctx->host), HOSTNAME_LENGTH)]= 0;
+        sctx->host_or_ip= sctx->host;
       }
       if (connect_errors > max_connect_errors)
         return(ER_HOST_IS_BLOCKED);
     }
     DBUG_PRINT("info",("Host: %s  ip: %s",
-		       thd->host ? thd->host : "unknown host",
-		       thd->ip ? thd->ip : "unknown ip"));
-    if (acl_check_host(thd->host,thd->ip))
+		       sctx->host ? sctx->host : "unknown host",
+		       sctx->ip ? sctx->ip : "unknown ip"));
+    if (acl_check_host(sctx->host, sctx->ip))
       return(ER_HOST_NOT_PRIVILEGED);
   }
   else /* Hostname given means that the connection was on a socket */
   {
-    DBUG_PRINT("info",("Host: %s",thd->host));
-    thd->host_or_ip= thd->host;
-    thd->ip= 0;
+    DBUG_PRINT("info",("Host: %s", sctx->host));
+    sctx->host_or_ip= sctx->host;
+    sctx->ip= 0;
     /* Reset sin_addr */
     bzero((char*) &thd->remote, sizeof(thd->remote));
   }
@@ -985,9 +987,9 @@
                              thd->charset(), &dummy_errors)]= '\0';
   user= user_buff;
 
-  if (thd->user)
-    x_free(thd->user);
-  if (!(thd->user= my_strdup(user, MYF(0))))
+  if (sctx->user)
+    x_free(sctx->user);
+  if (!(sctx->user= my_strdup(user, MYF(0))))
     return (ER_OUT_OF_RESOURCES);
   return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE);
 }
@@ -1075,13 +1077,14 @@
   {
     int error;
     NET *net= &thd->net;
+    st_security_context *sctx= thd->security_ctx;
     thd->thread_stack= (char*) &thd;
     net->no_send_error= 0;
 
     if ((error=check_connection(thd)))
     {						// Wrong permissions
       if (error > 0)
-	net_printf_error(thd, error, thd->host_or_ip);
+	net_printf_error(thd, error, sctx->host_or_ip);
 #ifdef __NT__
       if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE)
 	my_sleep(1000);				/* must wait after eof() */
@@ -1090,7 +1093,7 @@
       goto end_thread;
     }
 #ifdef __NETWARE__
-    netware_reg_user(thd->ip, thd->user, "MySQL");
+    netware_reg_user(sctx->ip, sctx->user, "MySQL");
 #endif
     if (thd->variables.max_join_size == HA_POS_ERROR)
       thd->options |= OPTION_BIG_SELECTS;
@@ -1103,7 +1106,7 @@
     thd->set_time();
     thd->init_for_queries();
 
-    if (sys_init_connect.value_length && !(thd->master_access &
SUPER_ACL))
+    if (sys_init_connect.value_length && !(sctx->master_access &
SUPER_ACL))
     {
       execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect);
       if (thd->query_error)
@@ -1127,8 +1130,8 @@
       if (!thd->killed && thd->variables.log_warnings > 1)
 	sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
                           thd->thread_id,(thd->db ? thd->db : "unconnected"),
-                          thd->user ? thd->user : "unauthenticated",
-                          thd->host_or_ip,
+                          sctx->user ? sctx->user : "unauthenticated",
+                          sctx->host_or_ip,
                           (net->last_errno ? ER(net->last_errno) :
                            ER(ER_UNKNOWN_ERROR)));
       net_send_error(thd, net->last_errno, NullS);
@@ -1191,7 +1194,8 @@
 
   thd->proc_info=0;
   thd->version=refresh_version;
-  thd->priv_user=thd->user=(char*) my_strdup("boot", MYF(MY_WME));
+  thd->security_ctx->priv_user=
+    thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
 
   buff= (char*) thd->net.buff;
   thd->init_for_queries();
@@ -1586,17 +1590,14 @@
     db= db_buff;
 
     /* Save user and privileges */
-    uint save_master_access= thd->master_access;
-    uint save_db_access= thd->db_access;
     uint save_db_length= thd->db_length;
-    char *save_user= thd->user;
-    char *save_priv_user= thd->priv_user;
     char *save_db= thd->db;
+    st_security_context save_security_ctx= *thd->security_ctx;
     USER_CONN *save_user_connect= thd->user_connect;
-    
-    if (!(thd->user= my_strdup(user, MYF(0))))
+
+    if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
     {
-      thd->user= save_user;
+      thd->security_ctx->user= save_security_ctx.user;
       my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
       break;
     }
@@ -1610,12 +1611,9 @@
       /* authentication failure, we shall restore old user */
       if (res > 0)
         my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-      x_free(thd->user);
-      thd->user= save_user;
-      thd->priv_user= save_priv_user;
+      x_free(thd->security_ctx->user);
+      *thd->security_ctx= save_security_ctx;
       thd->user_connect= save_user_connect;
-      thd->master_access= save_master_access;
-      thd->db_access= save_db_access;
       thd->db= save_db;
       thd->db_length= save_db_length;
     }
@@ -1625,7 +1623,7 @@
       if (save_user_connect)
 	decrease_user_connections(save_user_connect);
       x_free((gptr) save_db);
-      x_free((gptr) save_user);
+      x_free((gptr)  save_security_ctx.user);
     }
     break;
   }
@@ -1967,12 +1965,13 @@
   case COM_PROCESS_INFO:
     statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST],
 			&LOCK_status);
-    if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL))
+    if (!thd->security_ctx->priv_user[0] &&
+        check_global_access(thd, PROCESS_ACL))
       break;
     mysql_log.write(thd,command,NullS);
     mysqld_list_processes(thd,
-			  thd->master_access & PROCESS_ACL ? 
-			  NullS : thd->priv_user, 0);
+			  thd->security_ctx->master_access & PROCESS_ACL ? 
+			  NullS : thd->security_ctx->priv_user, 0);
     break;
   case COM_PROCESS_KILL:
   {
@@ -2139,7 +2138,8 @@
       if (!thd->col_access && check_grant_db(thd,db))
       {
 	my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-                 thd->priv_user, thd->priv_host, db);
+                 thd->security_ctx->priv_user, thd->security_ctx->priv_host,
+                 db);
 	DBUG_RETURN(1);
       }
       /*
@@ -2396,7 +2396,8 @@
     Except for the replication thread and the 'super' users.
   */
   if (opt_readonly &&
-      !(thd->slave_thread || (thd->master_access & SUPER_ACL)) &&
+      !(thd->slave_thread ||
+        (thd->security_ctx->master_access & SUPER_ACL)) &&
       uc_update_queries[lex->sql_command])
   {
     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
@@ -3368,11 +3369,14 @@
       res = mysql_drop_index(thd, first_table, &lex->alter_info);
     break;
   case SQLCOM_SHOW_PROCESSLIST:
-    if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL))
+    if (!thd->security_ctx->priv_user[0] &&
+        check_global_access(thd,PROCESS_ACL))
       break;
     mysqld_list_processes(thd,
-			  thd->master_access & PROCESS_ACL ? NullS :
-			  thd->priv_user,lex->verbose);
+			  (thd->security_ctx->master_access & PROCESS_ACL ?
+                           NullS :
+                           thd->security_ctx->priv_user),
+                          lex->verbose);
     break;
   case SQLCOM_SHOW_STORAGE_ENGINES:
     res= mysqld_show_storage_engines(thd);
@@ -3708,7 +3712,7 @@
 		     first_table ? 0 : 1, 0))
       goto error;
 
-    if (thd->user)				// If not replication
+    if (thd->security_ctx->user)              // If not replication
     {
       LEX_USER *user;
       uint counter;
@@ -3724,9 +3728,9 @@
                               user->host.str);
         // Are we trying to change a password of another user
         DBUG_ASSERT(user->host.str != 0);
-        if (strcmp(thd->user, user->user.str) ||
+        if (strcmp(thd->security_ctx->user, user->user.str) ||
             my_strcasecmp(system_charset_info,
-                          user->host.str, thd->host_or_ip))
+                          user->host.str, thd->security_ctx->host_or_ip))
         {
           // TODO: use check_change_password()
           if (check_acl_user(user, &counter) && user->password.str
&&
@@ -3853,8 +3857,9 @@
   }
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
   case SQLCOM_SHOW_GRANTS:
-    if ((thd->priv_user &&
-	 !strcmp(thd->priv_user,lex->grant_user->user.str)) ||
+    if ((thd->security_ctx->priv_user &&
+	 !strcmp(thd->security_ctx->priv_user,
+                 lex->grant_user->user.str)) ||
 	!check_access(thd, SELECT_ACL, "mysql",0,1,0))
     {
       res = mysql_show_grants(thd,lex->grant_user);
@@ -4124,7 +4129,7 @@
       else
       {
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-	st_sp_security_context save_ctx;
+	st_security_context *save_ctx;
 #endif
 	ha_rows select_limit;
         /* bits that should be cleared in thd->server_status */
@@ -4170,23 +4175,23 @@
 	}
 
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-	if (check_routine_access(thd, EXECUTE_ACL, 
-				 sp->m_db.str, sp->m_name.str, TRUE, 0))
+	if (check_routine_access(thd, EXECUTE_ACL,
+				 sp->m_db.str, sp->m_name.str, TRUE, 0) ||
+          sp_change_security_context(thd, sp, &save_ctx))
 	{
 #ifndef EMBEDDED_LIBRARY
 	  thd->net.no_send_ok= nsok;
 #endif
 	  goto error;
 	}
-	sp_change_security_context(thd, sp, &save_ctx);
-	if (save_ctx.changed && 
-	    check_routine_access(thd, EXECUTE_ACL, 
-				   sp->m_db.str, sp->m_name.str, TRUE, 0))
+	if (save_ctx &&
+            check_routine_access(thd, EXECUTE_ACL,
+                                 sp->m_db.str, sp->m_name.str, TRUE, 0))
 	{
 #ifndef EMBEDDED_LIBRARY
 	  thd->net.no_send_ok= nsok;
 #endif
-	  sp_restore_security_context(thd, sp, &save_ctx);
+	  sp_restore_security_context(thd, save_ctx);
 	  goto error;
 	}
 
@@ -4226,7 +4231,7 @@
 
 	thd->variables.select_limit= select_limit;
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-	sp_restore_security_context(thd, sp, &save_ctx);
+	sp_restore_security_context(thd, save_ctx);
 #endif
 
 #ifndef EMBEDDED_LIBRARY
@@ -4781,6 +4786,7 @@
 check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
 	     bool dont_check_global_grants, bool no_errors)
 {
+  st_security_context *sctx= thd->security_ctx;
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
   ulong db_access;
   bool  db_is_pattern= test(want_access & GRANT_ACL);
@@ -4788,7 +4794,7 @@
   ulong dummy;
   DBUG_ENTER("check_access");
   DBUG_PRINT("enter",("db: %s  want_access: %lu  master_access: %lu",
-                      db ? db : "", want_access, thd->master_access));
+                      db ? db : "", want_access, sctx->master_access));
   if (save_priv)
     *save_priv=0;
   else
@@ -4806,28 +4812,29 @@
 #ifdef NO_EMBEDDED_ACCESS_CHECKS
   DBUG_RETURN(0);
 #else
-  if ((thd->master_access & want_access) == want_access)
+  if ((sctx->master_access & want_access) == want_access)
   {
     /*
       If we don't have a global SELECT privilege, we have to get the database
       specific access rights to be able to handle queries of type
       UPDATE t1 SET a=1 WHERE b > 0
     */
-    db_access= thd->db_access;
-    if (!(thd->master_access & SELECT_ACL) &&
+    db_access= sctx->db_access;
+    if (!(sctx->master_access & SELECT_ACL) &&
 	(db && (!thd->db || db_is_pattern || strcmp(db,thd->db))))
-      db_access=acl_get(thd->host, thd->ip, thd->priv_user, db, db_is_pattern);
-    *save_priv=thd->master_access | db_access;
+      db_access=acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
+                        db_is_pattern);
+    *save_priv=sctx->master_access | db_access;
     DBUG_RETURN(FALSE);
   }
-  if (((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL)) ||
+  if (((want_access & ~sctx->master_access) & ~(DB_ACLS | EXTRA_ACL)) ||
       ! db && dont_check_global_grants)
   {						// We can never grant this
     DBUG_PRINT("error",("No possible access"));
     if (!no_errors)
       my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
-               thd->priv_user,
-               thd->priv_host,
+               sctx->priv_user,
+               sctx->priv_host,
                (thd->password ?
                 ER(ER_YES) :
                 ER(ER_NO)));                    /* purecov: tested */
@@ -4838,15 +4845,16 @@
     DBUG_RETURN(FALSE);				// Allow select on anything
 
   if (db && (!thd->db || db_is_pattern || strcmp(db,thd->db)))
-    db_access=acl_get(thd->host, thd->ip, thd->priv_user, db, db_is_pattern);
+    db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
+                       db_is_pattern);
   else
-    db_access=thd->db_access;
+    db_access= sctx->db_access;
   DBUG_PRINT("info",("db_access: %lu", db_access));
   /* Remove SHOW attribute and access rights we already have */
-  want_access &= ~(thd->master_access | EXTRA_ACL);
+  want_access &= ~(sctx->master_access | EXTRA_ACL);
   DBUG_PRINT("info",("db_access: %lu  want_access: %lu",
                      db_access, want_access));
-  db_access= ((*save_priv=(db_access | thd->master_access)) & want_access);
+  db_access= ((*save_priv=(db_access | sctx->master_access)) & want_access);
 
   /* grant_option is set if there exists a single table or column grant */
   if (db_access == want_access ||
@@ -4857,8 +4865,7 @@
   DBUG_PRINT("error",("Access denied"));
   if (!no_errors)
     my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-             thd->priv_user,
-             thd->priv_host,
+             sctx->priv_user, sctx->priv_host,
              (db ? db : (thd->db ?
                          thd->db :
                          "unknown")));          /* purecov: tested */
@@ -4892,7 +4899,7 @@
   return 0;
 #else
   char command[128];
-  if ((thd->master_access & want_access))
+  if ((thd->security_ctx->master_access & want_access))
     return 0;
   get_privilege_desc(command, sizeof(command), want_access);
   my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
@@ -4920,7 +4927,8 @@
         my_tz_check_n_skip_implicit_tables(&tables,
                                            thd->lex->time_zone_tables_used))
       continue;
-    if ((thd->master_access & want_access) == (want_access & ~EXTRA_ACL)
&&
+    if ((thd->security_ctx->master_access & want_access) ==
+        (want_access & ~EXTRA_ACL) &&
 	thd->db)
       tables->grant.privilege= want_access;
     else if (tables->db && tables->db == thd->db)
@@ -4957,7 +4965,8 @@
   tables->db= db;
   tables->table_name= tables->alias= name;
   
-  if ((thd->master_access & want_access) == want_access && !thd->db)
+  if ((thd->security_ctx->master_access & want_access) == want_access
&&
+      !thd->db)
     tables->grant.privilege= want_access;
   else if (check_access(thd,want_access,db,&tables->grant.privilege,
 			0, no_errors))
@@ -4990,7 +4999,7 @@
                                bool is_proc)
 {
   ulong save_priv;
-  if (thd->master_access & SHOW_PROC_ACLS)
+  if (thd->security_ctx->master_access & SHOW_PROC_ACLS)
     return FALSE;
   if (!check_access(thd, SHOW_PROC_ACLS, db, &save_priv, 0, 1) ||
       (save_priv & SHOW_PROC_ACLS))
@@ -5182,6 +5191,7 @@
   thd->server_status&= ~ (SERVER_MORE_RESULTS_EXISTS | 
                           SERVER_QUERY_NO_INDEX_USED |
                           SERVER_QUERY_NO_GOOD_INDEX_USED);
+  thd->security_ctx= &thd->main_security_ctx;
   thd->tmp_table_used= 0;
   if (!thd->in_sub_stmt)
   {
@@ -6703,8 +6713,8 @@
   VOID(pthread_mutex_unlock(&LOCK_thread_count));
   if (tmp)
   {
-    if ((thd->master_access & SUPER_ACL) ||
-	!strcmp(thd->user,tmp->user))
+    if ((thd->security_ctx->master_access & SUPER_ACL) ||
+	!strcmp(thd->security_ctx->user, tmp->security_ctx->user))
     {
       tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
       error=0;
@@ -7332,14 +7342,14 @@
     TRUE    Error
 */
 
-bool default_view_definer(THD *thd, st_lex_user *definer)
+bool default_view_definer(st_security_context *sctx, st_lex_user *definer)
 {
-  definer->user.str= thd->priv_user;
-  definer->user.length= strlen(thd->priv_user);
-  if (*thd->priv_host != 0)
+  definer->user.str= sctx->priv_user;
+  definer->user.length= strlen(sctx->priv_user);
+  if (*sctx->priv_host != 0)
   {
-    definer->host.str= thd->priv_host;
-    definer->host.length= strlen(thd->priv_host);
+    definer->host.str= sctx->priv_host;
+    definer->host.length= strlen(sctx->priv_host);
   }
   else
   {

--- 1.276/sql/sql_show.cc	2005-09-13 15:44:43 +03:00
+++ 1.277/sql/sql_show.cc	2005-09-14 04:52:44 +03:00
@@ -425,8 +425,9 @@
 bool mysqld_show_create_db(THD *thd, char *dbname,
                            HA_CREATE_INFO *create_info)
 {
+  st_security_context *sctx= thd->security_ctx;
   int length;
-  char	path[FN_REFLEN];
+  char path[FN_REFLEN];
   char buff[2048];
   String buffer(buff, sizeof(buff), system_charset_info);
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -445,17 +446,17 @@
   }
 
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-  if (test_all_bits(thd->master_access,DB_ACLS))
+  if (test_all_bits(sctx->master_access,DB_ACLS))
     db_access=DB_ACLS;
   else
-    db_access= (acl_get(thd->host,thd->ip, thd->priv_user,dbname,0) |
-		thd->master_access);
+    db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname, 0) |
+		sctx->master_access);
   if (!(db_access & DB_ACLS) && (!grant_option ||
check_grant_db(thd,dbname)))
   {
     my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-             thd->priv_user, thd->host_or_ip, dbname);
+             sctx->priv_user, sctx->host_or_ip, dbname);
     mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
-		    thd->priv_user, thd->host_or_ip, dbname);
+		    sctx->priv_user, sctx->host_or_ip, dbname);
     DBUG_RETURN(TRUE);
   }
 #endif
@@ -1169,24 +1170,26 @@
     THD *tmp;
     while ((tmp=it++))
     {
+      st_security_context *tmp_sctx= tmp->security_ctx;
       struct st_my_thread_var *mysys_var;
       if ((tmp->vio_ok() || tmp->system_thread) &&
-          (!user || (tmp->user && !strcmp(tmp->user,user))))
+          (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
       {
-        thread_info *thd_info=new thread_info;
+        thread_info *thd_info= new thread_info;
 
         thd_info->thread_id=tmp->thread_id;
-        thd_info->user=thd->strdup(tmp->user ? tmp->user :
-				   (tmp->system_thread ?
-				    "system user" : "unauthenticated user"));
-	if (tmp->peer_port && (tmp->host || tmp->ip) &&
thd->host_or_ip[0])
+        thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
+                                    (tmp->system_thread ?
+                                     "system user" : "unauthenticated user"));
+	if (tmp->peer_port && (tmp_sctx->host || tmp_sctx->ip) &&
+            thd->security_ctx->host_or_ip[0])
 	{
 	  if ((thd_info->host= thd->alloc(LIST_PROCESS_HOST_LEN+1)))
 	    my_snprintf((char *) thd_info->host, LIST_PROCESS_HOST_LEN,
-			"%s:%u", tmp->host_or_ip, tmp->peer_port);
+			"%s:%u", tmp_sctx->host_or_ip, tmp->peer_port);
 	}
 	else
-	  thd_info->host= thd->strdup(tmp->host_or_ip);
+	  thd_info->host= thd->strdup(tmp_sctx->host_or_ip);
         if ((thd_info->db=tmp->db))             // Safe test
           thd_info->db=thd->strdup(thd_info->db);
         thd_info->command=(int) tmp->command;
@@ -1237,6 +1240,9 @@
   VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
   thread_info *thd_info;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+  st_security_context *sctx;
+#endif
   time_t now= time(0);
   while ((thd_info=thread_infos.get()))
   {
@@ -1969,7 +1975,8 @@
   enum enum_schema_tables schema_table_idx;
   List<char> bases;
   List_iterator_fast<char> it(bases);
-  COND *partial_cond; 
+  COND *partial_cond;
+  st_security_context *sctx= thd->security_ctx;
   uint derived_tables= lex->derived_tables; 
   int error= 1;
   Open_tables_state open_tables_state_backup;
@@ -2041,8 +2048,9 @@
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
     if (with_i_schema ||   // don't check the rights if information schema db
         !check_access(thd,SELECT_ACL, base_name, &thd->col_access,0,1) ||
-        thd->master_access & (DB_ACLS | SHOW_DB_ACL) ||
-	acl_get(thd->host, thd->ip, thd->priv_user, base_name,0) ||
+        sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
+	acl_get(sctx->host, sctx->ip,
+                sctx->priv_user, base_name, 0) ||
 	(grant_option && !check_grant_db(thd, base_name)))
 #endif
     {
@@ -2174,6 +2182,7 @@
   bool with_i_schema;
   HA_CREATE_INFO create;
   TABLE *table= tables->table;
+  st_security_context *sctx= thd->security_ctx;
   DBUG_ENTER("fill_schema_shemata");
 
   if (make_db_list(thd, &files, &idx_field_vals,
@@ -2192,8 +2201,8 @@
       continue;
     }
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-    if (thd->master_access & (DB_ACLS | SHOW_DB_ACL) ||
-	acl_get(thd->host, thd->ip, thd->priv_user, file_name,0) ||
+    if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
+	acl_get(sctx->host, sctx->ip, sctx->priv_user, file_name,0) ||
 	(grant_option && !check_grant_db(thd, file_name)))
 #endif
     {
@@ -2799,7 +2808,8 @@
   Open_tables_state open_tables_state_backup;
   DBUG_ENTER("fill_schema_proc");
 
-  strxmov(definer, thd->priv_user, "@", thd->priv_host, NullS);
+  strxmov(definer, thd->security_ctx->priv_user, "@",
+          thd->security_ctx->priv_host, NullS);
   /* We use this TABLE_LIST instance only for checking of privileges. */
   bzero((char*) &proc_tables,sizeof(proc_tables));
   proc_tables.db= (char*) "mysql";

--- 1.420/sql/sql_yacc.yy	2005-09-13 15:44:43 +03:00
+++ 1.421/sql/sql_yacc.yy	2005-09-14 04:52:44 +03:00
@@ -6548,15 +6548,16 @@
 	    LEX *lex=Lex;
 	    lex->sql_command= SQLCOM_SHOW_GRANTS;
 	    THD *thd= lex->thd;
+            st_security_context *sctx= thd->security_ctx;
 	    LEX_USER *curr_user;
             if (!(curr_user= (LEX_USER*) thd->alloc(sizeof(st_lex_user))))
               YYABORT;
-            curr_user->user.str= thd->priv_user;
-            curr_user->user.length= strlen(thd->priv_user);
-            if (*thd->priv_host != 0)
+            curr_user->user.str= sctx->priv_user;
+            curr_user->user.length= strlen(sctx->priv_user);
+            if (*sctx->priv_host != 0)
             {
-              curr_user->host.str= thd->priv_host;
-              curr_user->host.length= strlen(thd->priv_host);
+              curr_user->host.str= sctx->priv_host;
+              curr_user->host.length= strlen(sctx->priv_host);
             }
             else
             {
@@ -7457,14 +7458,15 @@
 	| CURRENT_USER optional_braces
 	{
           THD *thd= YYTHD;
+          st_security_context *sctx= thd->security_ctx;
           if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
             YYABORT;
-          $$->user.str= thd->priv_user;
-          $$->user.length= strlen(thd->priv_user);
-          if (*thd->priv_host != 0)
+          $$->user.str= sctx->priv_user;
+          $$->user.length= strlen(sctx->priv_user);
+          if (*sctx->priv_host != 0)
           {
-            $$->host.str= thd->priv_host;
-            $$->host.length= strlen(thd->priv_host);
+            $$->host.str= sctx->priv_host;
+            $$->host.length= strlen(sctx->priv_host);
           }
           else
           {
@@ -7981,7 +7983,7 @@
 	    if (!(user=(LEX_USER*) thd->alloc(sizeof(LEX_USER))))
 	      YYABORT;
 	    user->host=null_lex_str;
-	    user->user.str=thd->priv_user;
+	    user->user.str=thd->security_ctx->priv_user;
 	    thd->lex->var_list.push_back(new set_var_password(user, $3));
 	  }
 	| PASSWORD FOR_SYM user equal text_or_password
@@ -8906,7 +8908,8 @@
             if (!(thd->lex->create_view_definer=
                   (LEX_USER*) thd->alloc(sizeof(st_lex_user))))
               YYABORT;
-            if (default_view_definer(thd, thd->lex->create_view_definer))
+            if (default_view_definer(thd->security_ctx,
+                                     thd->lex->create_view_definer))
               YYABORT;
           }
         | CURRENT_USER optional_braces
@@ -8915,7 +8918,8 @@
             if (!(thd->lex->create_view_definer=
                   (LEX_USER*) thd->alloc(sizeof(st_lex_user))))
               YYABORT;
-            if (default_view_definer(thd, thd->lex->create_view_definer))
+            if (default_view_definer(thd->security_ctx,
+                                     thd->lex->create_view_definer))
               YYABORT;
           }
 	| DEFINER_SYM EQ ident_or_text '@' ident_or_text

--- 1.43/sql/share/errmsg.txt	2005-09-13 15:44:43 +03:00
+++ 1.44/sql/share/errmsg.txt	2005-09-14 04:52:43 +03:00
@@ -5410,4 +5410,4 @@
 ER_VIEW_OTHER_USER
         eng "You need the SUPER privilege for creation view with %-.64s@%-.64s definer"
 ER_NO_SUCH_USER
-        eng "there are not %-.64s@%-.64s registered"
+        eng "There are not %-.64s@%-.64s registered"

--- 1.110/mysql-test/r/view.result	2005-09-13 15:44:43 +03:00
+++ 1.111/mysql-test/r/view.result	2005-09-14 04:52:42 +03:00
@@ -2190,7 +2190,7 @@
 ERROR HY000: View definer is not fully qualified
 create definer=some_user@localhost sql security invoker view v1 as select 1;
 Warnings:
-Note	1448	there are not some_user@localhost registered
+Note	1448	There are not some_user@localhost registered
 show create view v1;
 View	Create View
 v1	CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`localhost` SQL SECURITY INVOKER VIEW
`test`.`v1` AS select 1 AS `1`

--- 1.62/sql/sql_view.cc	2005-09-13 15:44:43 +03:00
+++ 1.63/sql/sql_view.cc	2005-09-14 04:52:44 +03:00
@@ -214,12 +214,13 @@
       - same as current user
       - current user has SUPER_ACL
   */
-  if (strcmp(lex->create_view_definer->user.str, thd->priv_user) != 0 ||
+  if (strcmp(lex->create_view_definer->user.str,
+             thd->security_ctx->priv_user) != 0 ||
       my_strcasecmp(system_charset_info,
                     lex->create_view_definer->host.str,
-                    thd->priv_host) != 0)
+                    thd->security_ctx->priv_host) != 0)
   {
-    if (!(thd->master_access & SUPER_ACL))
+    if (!(thd->security_ctx->master_access & SUPER_ACL))
     {
       my_error(ER_VIEW_OTHER_USER, MYF(0), lex->create_view_definer->user.str,
                lex->create_view_definer->host.str);
@@ -275,7 +276,8 @@
       if (check_some_access(thd, VIEW_ANY_ACL, tbl))
       {
         my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
-                 "ANY", thd->priv_user, thd->host_or_ip, tbl->table_name);
+                 "ANY", thd->security_ctx->priv_user,
+                 thd->security_ctx->priv_host, tbl->table_name);
         res= TRUE;
         goto err;
       }
@@ -441,7 +443,8 @@
         {
           /* VIEW column has more privileges */
           my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
-                   "create view", thd->priv_user, thd->host_or_ip, item->name,
+                   "create view", thd->security_ctx->priv_user,
+                   thd->security_ctx->priv_host, item->name,
                    view->table_name);
           res= TRUE;
           goto err;
@@ -786,7 +789,7 @@
     push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                         ER_VIEW_FRM_NO_USER, ER(ER_VIEW_FRM_NO_USER),
                         table->db, table->table_name);
-    if (default_view_definer(thd, &table->definer))
+    if (default_view_definer(thd->security_ctx, &table->definer))
       goto err;
   }
 

--- 1.27/sql/sql_trigger.cc	2005-08-15 18:15:04 +03:00
+++ 1.28/sql/sql_trigger.cc	2005-09-14 04:52:44 +03:00
@@ -172,7 +172,7 @@
     stronger test will be removed, the test below will hold.
   */
   if (!trust_routine_creators && mysql_bin_log.is_open() &&
-      !(thd->master_access & SUPER_ACL))
+      !(thd->security_ctx->master_access & SUPER_ACL))
   {
     my_message(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER,
 	       ER(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER), MYF(0));

--- 1.7/mysql-test/r/rpl_sp.result	2005-08-25 16:34:13 +03:00
+++ 1.8/mysql-test/r/rpl_sp.result	2005-09-14 04:52:42 +03:00
@@ -121,7 +121,7 @@
 Got one of the listed errors
 show warnings;
 Level	Code	Message
-Error	1142	INSERT command denied to user 'zedjzlcsjhd'@'localhost' for table 't1'
+Error	1142	INSERT command denied to user 'zedjzlcsjhd'@'127.0.0.1' for table 't1'
 Warning	1417	A routine failed and has neither NO SQL nor READS SQL DATA in its
declaration and binary logging is enabled; if non-transactional tables were updated, the
binary log will miss their changes
 alter procedure foo4 sql security invoker;
 call foo4();

--- 1.255/sql/ha_innodb.cc	2005-09-06 14:38:17 +03:00
+++ 1.256/sql/ha_innodb.cc	2005-09-14 04:52:42 +03:00
@@ -563,25 +563,29 @@
 				   use the default max length */
 {
 	const THD*	thd;
+        const st_security_context *sctx;
 	const char*	s;
 
         thd = (const THD*) input_thd;
+        /* We probably want to have original user as part of debug output. */
+        sctx = &thd->main_security_ctx;
+
 
   	fprintf(f, "MySQL thread id %lu, query id %lu",
 		thd->thread_id, (ulong) thd->query_id);
-	if (thd->host) {
+	if (sctx->host) {
 		putc(' ', f);
-		fputs(thd->host, f);
+		fputs(sctx->host, f);
 	}
 
-	if (thd->ip) {
+	if (sctx->ip) {
 		putc(' ', f);
-		fputs(thd->ip, f);
+		fputs(sctx->ip, f);
 	}
 
-  	if (thd->user) {
+        if (sctx->user) {
 		putc(' ', f);
-		fputs(thd->user, f);
+		fputs(sctx->user, f);
   	}
 
 	if ((s = thd->proc_info)) {

--- 1.139/sql/set_var.cc	2005-09-07 13:36:58 +03:00
+++ 1.140/sql/set_var.cc	2005-09-14 04:52:43 +03:00
@@ -1092,9 +1092,10 @@
 
 static int sys_check_ftb_syntax(THD *thd,  set_var *var)
 {
-  if (thd->master_access & SUPER_ACL)
-    return ft_boolean_check_syntax_string((byte*) var->value->str_value.c_ptr()) ?
-      -1 : 0;
+  if (thd->security_ctx->master_access & SUPER_ACL)
+    return (ft_boolean_check_syntax_string((byte*)
+                                           var->value->str_value.c_ptr()) ?
+            -1 : 0);
   else
   {
     my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
@@ -2689,7 +2690,7 @@
 static int check_log_update(THD *thd, set_var *var)
 {
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-  if (!(thd->master_access & SUPER_ACL))
+  if (!(thd->security_ctx->master_access & SUPER_ACL))
   {
     my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
     return 1;
@@ -2735,7 +2736,7 @@
 {
   var->save_result.ulonglong_value= var->value->val_int();
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-  if (thd->master_access & SUPER_ACL)
+  if (thd->security_ctx->master_access & SUPER_ACL)
     return 0;
   else
   {
@@ -3100,10 +3101,10 @@
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
   if (!user->host.str)
   {
-    if (thd->priv_host != 0)
+    if (thd->security_ctx->priv_host != 0)
     {
-      user->host.str= (char *) thd->priv_host;
-      user->host.length= strlen(thd->priv_host);
+      user->host.str= (char *) thd->security_ctx->priv_host;
+      user->host.length= strlen(thd->security_ctx->priv_host);
     }
     else
     {

--- 1.102/libmysqld/lib_sql.cc	2005-08-04 14:25:02 +03:00
+++ 1.103/libmysqld/lib_sql.cc	2005-09-14 04:52:42 +03:00
@@ -532,10 +532,9 @@
 int check_embedded_connection(MYSQL *mysql)
 {
   THD *thd= (THD*)mysql->thd;
-  thd->host= (char*)my_localhost;
-  thd->host_or_ip= thd->host;
-  thd->user= my_strdup(mysql->user, MYF(0));
-  thd->priv_user= thd->user;
+  st_security_context *sctx= thd->security_ctx;
+  sctx->host_or_ip= sctx->host= (char*)my_localhost;
+  sctx->priv_user= sctx->user= my_strdup(mysql->user, MYF(0));
   return check_user(thd, COM_CONNECT, NULL, 0, thd->db, true);
 }
 

--- 1.92/sql/sp.cc	2005-09-02 16:21:07 +03:00
+++ 1.93/sql/sp.cc	2005-09-14 04:52:43 +03:00
@@ -494,7 +494,8 @@
   else
   {
     restore_record(table, s->default_values); // Get default values for fields
-    strxmov(definer, thd->priv_user, "@", thd->priv_host, NullS);
+    strxmov(definer, thd->security_ctx->priv_user, "@",
+            thd->security_ctx->priv_host, NullS);
 
     if (table->s->fields != MYSQL_PROC_FIELD_COUNT)
     {
@@ -569,7 +570,7 @@
 	  goto done;
 	}
       }
-      if (!(thd->master_access & SUPER_ACL))
+      if (!(thd->security_ctx->master_access & SUPER_ACL))
       {
 	my_message(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER,
 		   ER(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER), MYF(0));

--- 1.182/sql/sp_head.cc	2005-09-09 19:09:33 +03:00
+++ 1.183/sql/sp_head.cc	2005-09-14 04:52:43 +03:00
@@ -1653,8 +1653,10 @@
   tables.db= (char*) "mysql";
   tables.table_name= tables.alias= (char*) "proc";
   *full_access= (!check_table_access(thd, SELECT_ACL, &tables, 1) ||
-                 (!strcmp(sp->m_definer_user.str, thd->priv_user) &&
-                  !strcmp(sp->m_definer_host.str, thd->priv_host)));
+                 (!strcmp(sp->m_definer_user.str,
+                          thd->security_ctx->priv_user) &&
+                  !strcmp(sp->m_definer_host.str,
+                          thd->security_ctx->priv_host)));
   if (!*full_access)
     return check_some_routine_access(thd, sp->m_db.str, sp->m_name.str,
                                      sp->m_type == TYPE_ENUM_PROCEDURE);
@@ -2666,54 +2668,38 @@
 */
 
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-void
-sp_change_security_context(THD *thd, sp_head *sp, st_sp_security_context *ctxp)
+bool
+sp_change_security_context(THD *thd, sp_head *sp, st_security_context **backup)
 {
-  ctxp->changed= (sp->m_chistics->suid != SP_IS_NOT_SUID &&
-		   (strcmp(sp->m_definer_user.str, thd->priv_user) ||
-		    strcmp(sp->m_definer_host.str, thd->priv_host)));
+  bool changed= (sp->m_chistics->suid != SP_IS_NOT_SUID &&
+                 (strcmp(sp->m_definer_user.str,
+                         thd->security_ctx->priv_user) ||
+                  my_strcasecmp(system_charset_info, sp->m_definer_host.str,
+                                thd->security_ctx->priv_host)));
 
-  if (ctxp->changed)
+  *backup= 0;
+  if (changed)
   {
-    ctxp->master_access= thd->master_access;
-    ctxp->db_access= thd->db_access;
-    ctxp->priv_user= thd->priv_user;
-    strncpy(ctxp->priv_host, thd->priv_host, sizeof(ctxp->priv_host));
-    ctxp->user= thd->user;
-    ctxp->host= thd->host;
-    ctxp->ip= thd->ip;
-
-    /* Change thise just to do the acl_getroot_no_password */
-    thd->user= sp->m_definer_user.str;
-    thd->host= thd->ip = sp->m_definer_host.str;
-
-    if (acl_getroot_no_password(thd))
-    {			// Failed, run as invoker for now
-      ctxp->changed= FALSE;
-      thd->master_access= ctxp->master_access;
-      thd->db_access= ctxp->db_access;
-      thd->priv_user= ctxp->priv_user;
-      strncpy(thd->priv_host, ctxp->priv_host, sizeof(thd->priv_host));
+    if (acl_getroot_no_password(&sp->m_security_ctx, sp->m_definer_user.str,
+                                sp->m_definer_host.str,
+                                sp->m_definer_host.str,
+                                sp->m_db.str))
+    {
+      my_error(ER_NO_SUCH_USER, MYF(0), sp->m_definer_user.str,
+               sp->m_definer_host.str);
+      return TRUE;
     }
-
-    /* Restore these immiediately */
-    thd->user= ctxp->user;
-    thd->host= ctxp->host;
-    thd->ip= ctxp->ip;
+    *backup= thd->security_ctx;
+    thd->security_ctx= &sp->m_security_ctx;
   }
+  return FALSE;
 }
 
 void
-sp_restore_security_context(THD *thd, sp_head *sp, st_sp_security_context *ctxp)
+sp_restore_security_context(THD *thd, st_security_context *backup)
 {
-  if (ctxp->changed)
-  {
-    ctxp->changed= FALSE;
-    thd->master_access= ctxp->master_access;
-    thd->db_access= ctxp->db_access;
-    thd->priv_user= ctxp->priv_user;
-    strncpy(thd->priv_host, ctxp->priv_host, sizeof(thd->priv_host));
-  }
+  if (backup)
+    thd->security_ctx= backup;
 }
 
 #endif /* NO_EMBEDDED_ACCESS_CHECKS */

--- 1.68/sql/sp_head.h	2005-09-07 18:39:41 +03:00
+++ 1.69/sql/sp_head.h	2005-09-14 04:52:43 +03:00
@@ -150,6 +150,9 @@
   // Pointers set during parsing
   uchar *m_param_begin, *m_param_end, *m_body_begin;
 
+  /* security context for SP procedure/function in case we switch it*/
+  st_security_context m_security_ctx;
+
   static void *
   operator new(size_t size);
 
@@ -1013,23 +1016,12 @@
 }; // class sp_instr_error : public sp_instr
 
 
-struct st_sp_security_context
-{
-  bool changed;
-  uint master_access;
-  uint db_access;
-  char *priv_user;
-  char priv_host[MAX_HOSTNAME];
-  char *user;
-  char *host;
-  char *ip;
-};
-
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
+bool
+sp_change_security_context(THD *thd, sp_head *sp,
+                           st_security_context **backup);
 void
-sp_change_security_context(THD *thd, sp_head *sp, st_sp_security_context *ctxp);
-void
-sp_restore_security_context(THD *thd, sp_head *sp,st_sp_security_context *ctxp);
+sp_restore_security_context(THD *thd, st_security_context *backup);
 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
 
 TABLE_LIST *

--- 1.54/sql/repl_failsafe.cc	2005-06-02 07:15:15 +03:00
+++ 1.55/sql/repl_failsafe.cc	2005-09-14 04:52:43 +03:00
@@ -66,13 +66,11 @@
     this thread has no other error reporting method).
   */
   thd->system_thread = thd->bootstrap = 1;
-  thd->host_or_ip= "";
+  thd->security_ctx->skip_grants();
   thd->client_capabilities = 0;
   my_net_init(&thd->net, 0);
   thd->net.read_timeout = slave_net_timeout;
   thd->max_client_packet_length=thd->net.max_packet;
-  thd->master_access= ~(ulong)0;
-  thd->priv_user = 0;
   pthread_mutex_lock(&LOCK_thread_count);
   thd->thread_id = thread_id++;
   pthread_mutex_unlock(&LOCK_thread_count);
Thread
bk commit into 5.0 tree (bell:1.1967)sanja14 Sep