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#12318 | Jim Winstead | 12 Aug |