#At file:///Users/thek/Development/mysql-6.0-bugteam/ based on revid:v.narayanan@stripped
3334 Kristofer Pettersson 2009-05-29 [merge]
merge from 5.1-bugteam to 6.0-bugteam
modified:
mysql-test/r/grant.result
mysql-test/t/grant.test
sql/sp.cc
sql/sp.h
sql/sql_acl.cc
sql/sql_acl.h
sql/sql_class.h
sql/sql_parse.cc
=== modified file 'mysql-test/r/grant.result'
--- a/mysql-test/r/grant.result 2009-03-27 22:06:26 +0000
+++ b/mysql-test/r/grant.result 2009-05-29 15:06:21 +0000
@@ -1359,6 +1359,61 @@ DROP USER 'userbug33464'@'localhost';
USE test;
DROP DATABASE dbbug33464;
SET @@global.log_bin_trust_function_creators= @old_log_bin_trust_function_creators;
+CREATE USER user1;
+CREATE USER user2;
+GRANT CREATE ON db1.* TO 'user1'@'localhost';
+GRANT CREATE ROUTINE ON db1.* TO 'user1'@'localhost';
+GRANT CREATE ON db1.* TO 'user2'@'%';
+GRANT CREATE ROUTINE ON db1.* TO 'user2'@'%';
+FLUSH PRIVILEGES;
+SHOW GRANTS FOR 'user1'@'localhost';
+Grants for user1@localhost
+GRANT USAGE ON *.* TO 'user1'@'localhost'
+GRANT CREATE, CREATE ROUTINE ON `db1`.* TO 'user1'@'localhost'
+** Connect as user1 and create a procedure.
+** The creation will imply implicitly assigned
+** EXECUTE and ALTER ROUTINE privileges to
+** the current user user1@localhost.
+SELECT @@GLOBAL.sql_mode;
+@@GLOBAL.sql_mode
+
+SELECT @@SESSION.sql_mode;
+@@SESSION.sql_mode
+
+CREATE DATABASE db1;
+CREATE PROCEDURE db1.proc1(p1 INT)
+BEGIN
+SET @x = 0;
+REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
+END ;||
+** Connect as user2 and create a procedure.
+** Implicitly assignment of privileges will
+** fail because the user2@localhost is an
+** unknown user.
+CREATE PROCEDURE db1.proc2(p1 INT)
+BEGIN
+SET @x = 0;
+REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
+END ;||
+Warnings:
+Warning 1404 Failed to grant EXECUTE and ALTER ROUTINE privileges
+SHOW GRANTS FOR 'user1'@'localhost';
+Grants for user1@localhost
+GRANT USAGE ON *.* TO 'user1'@'localhost'
+GRANT CREATE, CREATE ROUTINE ON `db1`.* TO 'user1'@'localhost'
+GRANT EXECUTE, ALTER ROUTINE ON PROCEDURE `db1`.`proc1` TO 'user1'@'localhost'
+SHOW GRANTS FOR 'user2';
+Grants for user2@%
+GRANT USAGE ON *.* TO 'user2'@'%'
+GRANT CREATE, CREATE ROUTINE ON `db1`.* TO 'user2'@'%'
+DROP PROCEDURE db1.proc1;
+DROP PROCEDURE db1.proc2;
+REVOKE ALL ON db1.* FROM 'user1'@'localhost';
+REVOKE ALL ON db1.* FROM 'user2'@'%';
+DROP USER 'user1';
+DROP USER 'user1'@'localhost';
+DROP USER 'user2';
+DROP DATABASE db1;
#########################################################################
#
# Bug#38347: ALTER ROUTINE privilege allows SHOW CREATE TABLE.
=== modified file 'mysql-test/t/grant.test'
--- a/mysql-test/t/grant.test 2009-03-26 06:08:24 +0000
+++ b/mysql-test/t/grant.test 2009-05-29 15:06:21 +0000
@@ -1471,6 +1471,60 @@ DROP DATABASE dbbug33464;
SET @@global.log_bin_trust_function_creators= @old_log_bin_trust_function_creators;
+#
+# Bug#44658 Create procedure makes server crash when user does not have ALL privilege
+#
+CREATE USER user1;
+CREATE USER user2;
+GRANT CREATE ON db1.* TO 'user1'@'localhost';
+GRANT CREATE ROUTINE ON db1.* TO 'user1'@'localhost';
+GRANT CREATE ON db1.* TO 'user2'@'%';
+GRANT CREATE ROUTINE ON db1.* TO 'user2'@'%';
+FLUSH PRIVILEGES;
+SHOW GRANTS FOR 'user1'@'localhost';
+connect (con1,localhost,user1,,);
+--echo ** Connect as user1 and create a procedure.
+--echo ** The creation will imply implicitly assigned
+--echo ** EXECUTE and ALTER ROUTINE privileges to
+--echo ** the current user user1@localhost.
+SELECT @@GLOBAL.sql_mode;
+SELECT @@SESSION.sql_mode;
+CREATE DATABASE db1;
+DELIMITER ||;
+CREATE PROCEDURE db1.proc1(p1 INT)
+ BEGIN
+ SET @x = 0;
+ REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
+ END ;||
+DELIMITER ;||
+
+connect (con2,localhost,user2,,);
+--echo ** Connect as user2 and create a procedure.
+--echo ** Implicitly assignment of privileges will
+--echo ** fail because the user2@localhost is an
+--echo ** unknown user.
+DELIMITER ||;
+CREATE PROCEDURE db1.proc2(p1 INT)
+ BEGIN
+ SET @x = 0;
+ REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
+ END ;||
+DELIMITER ;||
+
+connection default;
+SHOW GRANTS FOR 'user1'@'localhost';
+SHOW GRANTS FOR 'user2';
+disconnect con1;
+disconnect con2;
+DROP PROCEDURE db1.proc1;
+DROP PROCEDURE db1.proc2;
+REVOKE ALL ON db1.* FROM 'user1'@'localhost';
+REVOKE ALL ON db1.* FROM 'user2'@'%';
+DROP USER 'user1';
+DROP USER 'user1'@'localhost';
+DROP USER 'user2';
+DROP DATABASE db1;
+
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc
=== modified file 'sql/sp.cc'
--- a/sql/sp.cc 2009-04-08 23:46:45 +0000
+++ b/sql/sp.cc 2009-05-29 15:06:21 +0000
@@ -1321,13 +1321,20 @@ sp_find_routine(THD *thd, int type, sp_n
/**
This is used by sql_acl.cc:mysql_routine_grant() and is used to find
the routines in 'routines'.
+
+ @param thd Thread handler
+ @param routines List of needles in the hay stack
+ @param any Any of the needles are good enough
+
+ @return
+ @retval FALSE Found.
+ @retval TRUE Not found
*/
-int
-sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any, bool no_error)
+bool
+sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any)
{
TABLE_LIST *routine;
- bool result= 0;
bool sp_object_found;
DBUG_ENTER("sp_exists_routine");
for (routine= routines; routine; routine= routine->next_global)
@@ -1349,21 +1356,16 @@ sp_exist_routines(THD *thd, TABLE_LIST *
if (sp_object_found)
{
if (any)
- DBUG_RETURN(1);
- result= 1;
+ break;
}
else if (!any)
{
- if (!no_error)
- {
- my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION or PROCEDURE",
- routine->table_name);
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(0);
+ my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION or PROCEDURE",
+ routine->table_name);
+ DBUG_RETURN(TRUE);
}
}
- DBUG_RETURN(result);
+ DBUG_RETURN(FALSE);
}
=== modified file 'sql/sp.h'
--- a/sql/sp.h 2008-04-08 16:36:01 +0000
+++ b/sql/sp.h 2009-05-29 15:06:21 +0000
@@ -67,8 +67,8 @@ sp_head *
sp_find_routine(THD *thd, int type, sp_name *name,
sp_cache **cp, bool cache_only);
-int
-sp_exist_routines(THD *thd, TABLE_LIST *procs, bool any, bool no_error);
+bool
+sp_exist_routines(THD *thd, TABLE_LIST *procs, bool any);
int
sp_routine_exists_in_table(THD *thd, int type, sp_name *name);
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2009-05-25 15:13:48 +0000
+++ b/sql/sql_acl.cc 2009-05-29 15:06:21 +0000
@@ -3211,26 +3211,24 @@ int mysql_table_grant(THD *thd, TABLE_LI
}
-/*
+/**
Store routine level grants in the privilege tables
- SYNOPSIS
- mysql_routine_grant()
- thd Thread handle
- table_list List of routines to give grant
- is_proc true indicates routine list are procedures
- user_list List of users to give grant
- rights Table level grant
- revoke_grant Set to 1 if this is a REVOKE command
+ @param thd Thread handle
+ @param table_list List of routines to give grant
+ @param is_proc Is this a list of procedures?
+ @param user_list List of users to give grant
+ @param rights Table level grant
+ @param revoke_grant Is this is a REVOKE command?
- RETURN
- 0 ok
- 1 error
+ @return
+ @retval FALSE Success.
+ @retval TRUE An error occurred.
*/
bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
List <LEX_USER> &user_list, ulong rights,
- bool revoke_grant, bool no_error)
+ bool revoke_grant, bool write_to_binlog)
{
List_iterator <LEX_USER> str_list (user_list);
LEX_USER *Str, *tmp_Str;
@@ -3241,22 +3239,20 @@ bool mysql_routine_grant(THD *thd, TABLE
if (!initialized)
{
- if (!no_error)
- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
- "--skip-grant-tables");
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
+ "--skip-grant-tables");
DBUG_RETURN(TRUE);
}
if (rights & ~PROC_ACLS)
{
- if (!no_error)
- my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE),
- MYF(0));
+ my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE),
+ MYF(0));
DBUG_RETURN(TRUE);
}
if (!revoke_grant)
{
- if (sp_exist_routines(thd, table_list, is_proc, no_error)<0)
+ if (sp_exist_routines(thd, table_list, is_proc))
DBUG_RETURN(TRUE);
}
@@ -3338,9 +3334,8 @@ bool mysql_routine_grant(THD *thd, TABLE
{
if (revoke_grant)
{
- if (!no_error)
- my_error(ER_NONEXISTING_PROC_GRANT, MYF(0),
- Str->user.str, Str->host.str, table_name);
+ my_error(ER_NONEXISTING_PROC_GRANT, MYF(0),
+ Str->user.str, Str->host.str, table_name);
result= TRUE;
continue;
}
@@ -3365,16 +3360,14 @@ bool mysql_routine_grant(THD *thd, TABLE
}
thd->mem_root= old_root;
pthread_mutex_unlock(&acl_cache->lock);
- if (!result && !no_error)
+
+ if (write_to_binlog)
{
write_bin_log(thd, TRUE, thd->query, thd->query_length);
}
rw_unlock(&LOCK_grant);
- if (!result && !no_error)
- my_ok(thd);
-
/* Tables are automatically closed */
DBUG_RETURN(result);
}
@@ -6301,21 +6294,20 @@ bool sp_revoke_privileges(THD *thd, cons
}
-/*
+/**
Grant EXECUTE,ALTER privilege for a stored procedure
- SYNOPSIS
- sp_grant_privileges()
- thd The current thread.
- db DB of the stored procedure
- name Name of the stored procedure
+ @param thd The current thread.
+ @param sp_db
+ @param sp_name
+ @param is_proc
- RETURN
- 0 OK.
- < 0 Error. Error message not yet sent.
+ @return
+ @retval FALSE Success
+ @retval TRUE An error occured. Error message not yet sent.
*/
-int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
+bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool is_proc)
{
Security_context *sctx= thd->security_ctx;
@@ -6325,6 +6317,7 @@ int sp_grant_privileges(THD *thd, const
bool result;
ACL_USER *au;
char passwd_buff[SCRAMBLED_PASSWORD_CHAR_LENGTH+1];
+ Dummy_error_handler error_handler;
DBUG_ENTER("sp_grant_privileges");
if (!(combo=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
@@ -6375,8 +6368,11 @@ int sp_grant_privileges(THD *thd, const
}
else
{
- my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH);
- return -1;
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_PASSWD_LENGTH,
+ ER(ER_PASSWD_LENGTH),
+ SCRAMBLED_PASSWORD_CHAR_LENGTH);
+ return TRUE;
}
combo->password.str= passwd_buff;
}
@@ -6392,8 +6388,14 @@ int sp_grant_privileges(THD *thd, const
thd->lex->ssl_type= SSL_TYPE_NOT_SPECIFIED;
bzero((char*) &thd->lex->mqh, sizeof(thd->lex->mqh));
+ /*
+ Only care about whether the operation failed or succeeded
+ as all errors will be handled later.
+ */
+ thd->push_internal_handler(&error_handler);
result= mysql_routine_grant(thd, tables, is_proc, user_list,
- DEFAULT_CREATE_PROC_ACLS, 0, 1);
+ DEFAULT_CREATE_PROC_ACLS, FALSE, FALSE);
+ thd->pop_internal_handler();
DBUG_RETURN(result);
}
=== modified file 'sql/sql_acl.h'
--- a/sql/sql_acl.h 2009-04-02 08:50:24 +0000
+++ b/sql/sql_acl.h 2009-05-29 15:06:21 +0000
@@ -240,7 +240,7 @@ int mysql_table_grant(THD *thd, TABLE_LI
bool revoke);
bool mysql_routine_grant(THD *thd, TABLE_LIST *table, bool is_proc,
List <LEX_USER> &user_list, ulong rights,
- bool revoke, bool no_error);
+ bool revoke, bool write_to_binlog);
my_bool grant_init();
void grant_free(void);
my_bool grant_reload(THD *thd);
@@ -271,7 +271,7 @@ void fill_effective_table_privileges(THD
const char *db, const char *table);
bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool is_proc);
-int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
+bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool is_proc);
bool check_routine_level_acl(THD *thd, const char *db, const char *name,
bool is_proc);
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2009-05-25 10:10:18 +0000
+++ b/sql/sql_class.h 2009-05-29 15:06:21 +0000
@@ -1155,6 +1155,27 @@ private:
/**
+ Implements the trivial error handler which cancels all error states
+ and prevents an SQLSTATE to be set.
+*/
+
+class Dummy_error_handler : public Internal_error_handler
+{
+public:
+ bool handle_condition(THD *thd,
+ uint sql_errno,
+ const char* sqlstate,
+ MYSQL_ERROR::enum_warning_level level,
+ const char* msg,
+ MYSQL_ERROR ** cond_hdl)
+ {
+ /* Ignore error */
+ return TRUE;
+ }
+};
+
+
+/**
This class is an internal error handler implementation for DROP DATABASE
and DROP TABLE statements. The thing is that there may be warnings during
execution of these statements, which should not be exposed to the user.
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2009-05-25 10:10:18 +0000
+++ b/sql/sql_parse.cc 2009-05-29 15:06:21 +0000
@@ -4025,7 +4025,9 @@ end_with_restore_list:
res= mysql_routine_grant(thd, all_tables,
lex->type == TYPE_ENUM_PROCEDURE,
lex->users_list, grants,
- lex->sql_command == SQLCOM_REVOKE, 0);
+ lex->sql_command == SQLCOM_REVOKE, TRUE);
+ if (!res)
+ my_ok(thd);
}
else
{
Attachment: [text/bzr-bundle]
| Thread |
|---|
| • bzr commit into mysql-6.0-bugteam branch (kristofer.pettersson:3334) | Kristofer Pettersson | 29 May |