MySQL Lists are EOL. Please join:

List:Internals« Previous MessageNext Message »
From:Jim Winstead Date:August 12 2005 12:04am
Subject:bk commit into 5.0 tree (jimw:1.1978) BUG#12318
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of jimw. When jimw 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.1978 05/08/11 17:04:16 jimw@stripped +7 -0
  Avoid spurious error when restoring INFORMATION_SCHEMA as the current 
  database after failing to execute a stored procedure in an inaccessible
  database. (Bug #12318)

  sql/sql_parse.cc
    1.467 05/08/11 17:04:12 jimw@stripped +10 -8
    Add extra argument to mysql_change_db(), and call send_ok() after
    successful calls to same (since it no longer does it for us).

  sql/sql_db.cc
    1.110 05/08/11 17:04:12 jimw@stripped +28 -24
    Handle no_access_check flag to mysql_change_db, and remove the send_ok()
    call.

  sql/sp.h
    1.28 05/08/11 17:04:11 jimw@stripped +0 -4
    Get rid of sp_change_db().

  sql/sp.cc
    1.89 05/08/11 17:04:11 jimw@stripped +4 -106
    Use mysql_change_db(), get rid of sp_change_db().

  sql/mysql_priv.h
    1.340 05/08/11 17:04:11 jimw@stripped +1 -1
    Add additional argument to mysql_change_db()

  mysql-test/t/sp-security.test
    1.21 05/08/11 17:04:11 jimw@stripped +36 -0
    Add regression test

  mysql-test/r/sp-security.result
    1.19 05/08/11 17:04:11 jimw@stripped +13 -0
    Update results

# 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:	jimw
# Host:	rama.(none)
# Root:	/home/jimw/my/mysql-5.0-12318

--- 1.339/sql/mysql_priv.h	2005-08-09 00:37:42 -07:00
+++ 1.340/sql/mysql_priv.h	2005-08-11 17:04:11 -07:00
@@ -587,7 +587,7 @@
 		   const char *table_name);
 void close_cached_table(THD *thd, TABLE *table);
 bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
-bool mysql_change_db(THD *thd,const char *name);
+bool mysql_change_db(THD *thd,const char *name,bool no_access_check);
 void mysql_parse(THD *thd,char *inBuf,uint length);
 bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length);
 bool is_update_query(enum enum_sql_command command);

--- 1.109/sql/sql_db.cc	2005-05-20 14:31:13 -07:00
+++ 1.110/sql/sql_db.cc	2005-08-11 17:04:12 -07:00
@@ -996,8 +996,9 @@
 
   SYNOPSIS
     mysql_change_db()
-    thd		Thread handler
-    name	Databasename
+    thd			Thread handler
+    name		Databasename
+    no_access_check	True= don't do access check
 
   DESCRIPTION
     Becasue the database name may have been given directly from the
@@ -1009,15 +1010,16 @@
     replication slave SQL thread (for that thread, setting of thd->db is done
     in ::exec_event() methods of log_event.cc).
 
-    This function does not send the error message to the client, if that
-    should be sent to the client, call net_send_error after this function 
+    This function does not send anything, including error messages to the
+    client, if that should be sent to the client, call net_send_error after
+    this function.
 
   RETURN VALUES
     0	ok
     1	error
 */
 
-bool mysql_change_db(THD *thd, const char *name)
+bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
 {
   int length, db_length;
   char *dbname=my_strdup((char*) name,MYF(MY_WME));
@@ -1053,23 +1055,25 @@
   }
 
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-  if (test_all_bits(thd->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);
-  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,
-             dbname);
-    mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
-		    thd->priv_user,
-		    thd->priv_host,
-		    dbname);
-    my_free(dbname,MYF(0));
-    DBUG_RETURN(1);
+  if (!no_access_check) {
+    if (test_all_bits(thd->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);
+    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,
+               dbname);
+      mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
+                      thd->priv_user,
+                      thd->priv_host,
+                      dbname);
+      my_free(dbname,MYF(0));
+      DBUG_RETURN(1);
+    }
   }
 #endif
   (void) sprintf(path,"%s/%s",mysql_data_home,dbname);
@@ -1083,12 +1087,12 @@
     DBUG_RETURN(1);
   }
 end:
-  send_ok(thd);
   x_free(thd->db);
   thd->db=dbname;				// THD::~THD will free this
   thd->db_length=db_length;
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-  thd->db_access=db_access;
+  if (!no_access_check)
+    thd->db_access=db_access;
 #endif
   if (schema_db)
   {

--- 1.466/sql/sql_parse.cc	2005-08-11 04:02:45 -07:00
+++ 1.467/sql/sql_parse.cc	2005-08-11 17:04:12 -07:00
@@ -275,7 +275,7 @@
   {
     thd->db= 0;
     thd->db_length= 0;
-    if (mysql_change_db(thd, db))
+    if (mysql_change_db(thd, db, FALSE))
     {
       /* Send the error to the client */
       net_send_error(thd);
@@ -284,8 +284,7 @@
       DBUG_RETURN(-1);
     }
   }
-  else
-    send_ok(thd);
+  send_ok(thd);
   DBUG_RETURN(0);
 #else
 
@@ -410,7 +409,7 @@
       /* Change database if necessary */
       if (db && db[0])
       {
-        if (mysql_change_db(thd, db))
+        if (mysql_change_db(thd, db, FALSE))
         {
           /* Send error to the client */
           net_send_error(thd);
@@ -419,8 +418,7 @@
           DBUG_RETURN(-1);
         }
       }
-      else
-	send_ok(thd);
+      send_ok(thd);
       thd->password= test(passwd_len);          // remember for error messages 
       /* Ready to handle queries */
       DBUG_RETURN(0);
@@ -1514,8 +1512,11 @@
 			&LOCK_status);
     thd->convert_string(&tmp, system_charset_info,
 			packet, strlen(packet), thd->charset());
-    if (!mysql_change_db(thd, tmp.str))
+    if (!mysql_change_db(thd, tmp.str, FALSE))
+    {
       mysql_log.write(thd,command,"%s",thd->db);
+      send_ok(thd);
+    }
     break;
   }
 #ifdef HAVE_REPLICATION
@@ -3407,7 +3408,8 @@
     }
 #endif
   case SQLCOM_CHANGE_DB:
-    mysql_change_db(thd,select_lex->db);
+    if (!mysql_change_db(thd,select_lex->db,FALSE))
+      send_ok(thd);
     break;
 
   case SQLCOM_LOAD:

--- 1.18/mysql-test/r/sp-security.result	2005-08-02 20:37:27 -07:00
+++ 1.19/mysql-test/r/sp-security.result	2005-08-11 17:04:11 -07:00
@@ -236,3 +236,16 @@
 drop procedure bug7291_0;
 REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1@localhost;
 drop user user1@localhost;
+drop database if exists mysqltest_1;
+create database mysqltest_1;
+create procedure mysqltest_1.p1()
+begin
+select 1 from dual;
+end//
+grant usage on *.* to mysqltest_1@localhost;
+call mysqltest_1.p1();
+ERROR 42000: execute command denied to user 'mysqltest_1'@'localhost' for routine 'mysqltest_1.p1'
+drop procedure mysqltest_1.p1;
+drop database mysqltest_1;
+revoke usage on *.* from mysqltest_1@localhost;
+drop user mysqltest_1@localhost;

--- 1.20/mysql-test/t/sp-security.test	2005-08-02 20:37:27 -07:00
+++ 1.21/mysql-test/t/sp-security.test	2005-08-11 17:04:11 -07:00
@@ -371,3 +371,39 @@
 disconnect user1;
 REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1@localhost;
 drop user user1@localhost;
+
+#
+# Bug #12318: Wrong error message when accessing an inaccessible stored
+# procedure in another database when the current database is
+# information_schema.
+# 
+
+--disable_warnings
+drop database if exists mysqltest_1;
+--enable_warnings
+
+create database mysqltest_1;
+delimiter //;
+create procedure mysqltest_1.p1()
+begin
+   select 1 from dual;
+end//
+delimiter ;//
+
+grant usage on *.* to mysqltest_1@localhost;
+
+connect (n1,localhost,mysqltest_1,,information_schema,$MASTER_MYPORT,$MASTER_MYSOCK);
+connection n1;
+--error 1370
+call mysqltest_1.p1();
+disconnect n1;
+
+connection default;
+
+drop procedure mysqltest_1.p1;
+drop database mysqltest_1;
+
+revoke usage on *.* from mysqltest_1@localhost;
+drop user mysqltest_1@localhost;
+
+# End of 5.0 bugs.

--- 1.88/sql/sp.cc	2005-08-10 14:17:50 -07:00
+++ 1.89/sql/sp.cc	2005-08-11 17:04:11 -07:00
@@ -427,7 +427,7 @@
       LEX *newlex= thd->lex;
       sp_head *sp= newlex->sphead;
 
-      if (dbchanged && (ret= sp_change_db(thd, olddb, 1)))
+      if (dbchanged && (ret= mysql_change_db(thd, olddb, 1)))
 	goto done;
       if (sp)
       {
@@ -438,7 +438,7 @@
     }
     else
     {
-      if (dbchanged && (ret= sp_change_db(thd, olddb, 1)))
+      if (dbchanged && (ret= mysql_change_db(thd, olddb, 1)))
 	goto done;
       *sphp= thd->lex->sphead;
       (*sphp)->set_info((char *)definer, (uint)strlen(definer),
@@ -594,7 +594,7 @@
 done:
   close_thread_tables(thd);
   if (dbchanged)
-    (void)sp_change_db(thd, olddb, 1);
+    (void)mysql_change_db(thd, olddb, 1);
   DBUG_RETURN(ret);
 }
 
@@ -1612,112 +1612,10 @@
   }
   else
   {
-    int ret= sp_change_db(thd, newdb, no_access_check);
+    int ret= mysql_change_db(thd, newdb, no_access_check);
 
     if (! ret)
       *dbchangedp= TRUE;
     DBUG_RETURN(ret);
   }
-}
-
-/*
-  Change database.
-
-  SYNOPSIS
-    sp_change_db()
-    thd		    Thread handler
-    name	    Database name
-    empty_is_ok     True= it's ok with "" as name
-    no_access_check True= don't do access check
-
-  DESCRIPTION
-    This is the same as mysql_change_db(), but with some extra
-    arguments for Stored Procedure usage; doing implicit "use" 
-    when executing an SP in a different database.
-    We also use different error routines, since this might be
-    invoked from a function when executing a query or statement.
-    Note: We would have prefered to reuse mysql_change_db(), but
-      the error handling in particular made that too awkward, so
-      we (reluctantly) have a "copy" here.
-
-  RETURN VALUES
-    0	ok
-    1	error
-*/
-
-int
-sp_change_db(THD *thd, char *name, bool no_access_check)
-{
-  int length, db_length;
-  char *dbname=my_strdup((char*) name,MYF(MY_WME));
-  char	path[FN_REFLEN];
-  HA_CREATE_INFO create;
-  DBUG_ENTER("sp_change_db");
-  DBUG_PRINT("enter", ("db: %s, no_access_check: %d", name, no_access_check));
-
-  db_length= (!dbname ? 0 : strip_sp(dbname));
-  if (dbname && db_length)
-  {
-    if ((db_length > NAME_LEN) || check_db_name(dbname))
-    {
-      my_error(ER_WRONG_DB_NAME, MYF(0), dbname);
-      x_free(dbname);
-      DBUG_RETURN(1);
-    }
-  }
-
-  if (dbname && db_length)
-  {
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-    if (! no_access_check)
-    {
-      ulong db_access;
-
-      if (test_all_bits(thd->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);  
-      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,
-                 dbname);
-	mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
-			thd->priv_user,
-			thd->priv_host,
-			dbname);
-	my_free(dbname,MYF(0));
-	DBUG_RETURN(1);
-      }
-    }
-#endif
-    (void) sprintf(path,"%s/%s",mysql_data_home,dbname);
-    length=unpack_dirname(path,path);		// Convert if not unix
-    if (length && path[length-1] == FN_LIBCHAR)
-      path[length-1]=0;				// remove ending '\'
-    if (access(path,F_OK))
-    {
-      my_error(ER_BAD_DB_ERROR, MYF(0), dbname);
-      my_free(dbname,MYF(0));
-      DBUG_RETURN(1);
-    }
-  }
-
-  x_free(thd->db);
-  thd->db=dbname;				// THD::~THD will free this
-  thd->db_length=db_length;
-
-  if (dbname && db_length)
-  {
-    strmov(path+unpack_dirname(path,path), MY_DB_OPT_FILE);
-    load_db_opt(thd, path, &create);
-    thd->db_charset= create.default_table_charset ?
-      create.default_table_charset :
-      thd->variables.collation_server;
-    thd->variables.collation_database= thd->db_charset;
-  }
-  DBUG_RETURN(0);
 }

--- 1.27/sql/sp.h	2005-08-09 00:37:42 -07:00
+++ 1.28/sql/sp.h	2005-08-11 17:04:11 -07:00
@@ -112,8 +112,4 @@
 sp_use_new_db(THD *thd, char *newdb, char *olddb, uint olddbmax,
 	      bool no_access_check, bool *dbchangedp);
 
-// Like mysql_change_db() but handles empty db name and the  send_ok() problem.
-int
-sp_change_db(THD *thd, char *db, bool no_access_check);
-
 #endif /* _SP_H_ */
Thread
bk commit into 5.0 tree (jimw:1.1978) BUG#12318Jim Winstead12 Aug