List:Commits« Previous MessageNext Message »
From:ahristov Date:June 21 2006 7:46pm
Subject:bk commit into 5.1 tree (andrey:1.2225) BUG#16425
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of andrey. When andrey 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.2225 06/06/21 19:46:18 andrey@lmy004. +4 -0
  fix for bug #16425 Events: no DEFINER clause
  
  Added parsing and storing the value of DEFINER clause for CREATE EVENT
  like CREATE DEFINER=user@host EVENT ....
  This is needed for replication and point in time recovery.
  Only users that have SUPER_ACL can create events on the behalf of others,
  just like with SP/SF.
  The DEFINER clause is not obligatory.

  sql/sql_yacc.yy
    1.484 06/06/21 19:46:08 andrey@lmy004. +44 -37
    add event to view_or_trigger_or_sp_or_event_tail

  sql/event_timed.cc
    1.57 06/06/21 19:46:08 andrey@lmy004. +26 -9
    Handle the case when thd->lex->definer is initialized,
    that is there is a DEFINER clause for CREATE EVENT

  mysql-test/t/events_bugs.test
    1.8 06/06/21 19:46:07 andrey@lmy004. +30 -0
    add a test case for bug#16425 Events: no DEFINER clause
    - test creation of an event for another user when the current user has SUPER
      and in the case the user does not have it.
    - test with passing CURRENT_USER()

  mysql-test/r/events_bugs.result
    1.11 06/06/21 19:46:07 andrey@lmy004. +30 -0
    update result

# 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:	andrey
# Host:	lmy004.
# Root:	/work/mysql-5.1-runtime-bug16425

--- 1.483/sql/sql_yacc.yy	2006-06-20 17:09:42 +02:00
+++ 1.484/sql/sql_yacc.yy	2006-06-21 19:46:08 +02:00
@@ -880,7 +880,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 	sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa
         load_data opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
         definer view_replace_or_algorithm view_replace view_algorithm_opt
-        view_algorithm view_or_trigger_or_sp view_or_trigger_or_sp_tail
+        view_algorithm view_or_trigger_or_sp view_or_trigger_or_sp_or_event_tail
         view_suid view_tail view_list_opt view_list view_select
         view_check_option trigger_tail sp_tail
         install uninstall partition_entry binlog_base64_event
@@ -1257,7 +1257,32 @@ create:
 	    lex->name=$4.str;
             lex->create_info.options=$3;
 	  }
-	| CREATE EVENT_SYM opt_if_not_exists sp_name
+	| CREATE
+	  {
+            Lex->create_view_mode= VIEW_CREATE_NEW;
+            Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
+            Lex->create_view_suid= TRUE;
+	  }
+	  view_or_trigger_or_sp
+	  {}
+	| CREATE USER clear_privileges grant_list
+	  {
+	    Lex->sql_command = SQLCOM_CREATE_USER;
+          }
+	| CREATE LOGFILE_SYM GROUP logfile_group_info 
+          {
+            LEX *lex= Lex;
+            lex->alter_tablespace_info->ts_cmd_type= CREATE_LOGFILE_GROUP;
+          }
+        | CREATE TABLESPACE tablespace_info
+          {
+            LEX *lex= Lex;
+            lex->alter_tablespace_info->ts_cmd_type= CREATE_TABLESPACE;
+          }
+	;
+
+event_tail:
+	  EVENT_SYM opt_if_not_exists sp_name
           /*
              BE CAREFUL when you add a new rule to update the block where
              YYTHD->client_capabilities is set back to original value
@@ -1276,7 +1301,7 @@ create:
               YYABORT;
             }
 
-            lex->create_info.options= $3;
+            lex->create_info.options= $2;
 
             if (!(lex->et= new(YYTHD->mem_root) Event_timed())) // implicitly calls
Event_timed::init()
               YYABORT;
@@ -1291,8 +1316,9 @@ create:
 
             if (!lex->et_compile_phase)
             {
-              lex->et->init_name(YYTHD, $4);
-              lex->et->init_definer(YYTHD);
+              lex->et->init_name(YYTHD, $3);
+              if (lex->et->init_definer(YYTHD))
+                YYABORT;
             }
           }
           ON SCHEDULE_SYM ev_schedule_time
@@ -1303,13 +1329,12 @@ create:
           {
             /*
               Restore flag if it was cleared above
-              $1 - CREATE
-              $2 - EVENT_SYM
-              $3 - opt_if_not_exists
-              $4 - sp_name
-              $5 - the block above
+              $1 - EVENT_SYM
+              $2 - opt_if_not_exists
+              $3 - sp_name
+              $4 - the block above
             */
-            YYTHD->client_capabilities |= $<ulong_num>5;
+            YYTHD->client_capabilities |= $<ulong_num>4;
 
             /*
               sql_command is set here because some rules in ev_sql_stmt
@@ -1317,30 +1342,7 @@ create:
             */
             Lex->sql_command= SQLCOM_CREATE_EVENT;
           }
-	| CREATE
-	  {
-            Lex->create_view_mode= VIEW_CREATE_NEW;
-            Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
-            Lex->create_view_suid= TRUE;
-	  }
-	  view_or_trigger_or_sp
-	  {}
-	| CREATE USER clear_privileges grant_list
-	  {
-	    Lex->sql_command = SQLCOM_CREATE_USER;
-          }
-	| CREATE LOGFILE_SYM GROUP logfile_group_info 
-          {
-            LEX *lex= Lex;
-            lex->alter_tablespace_info->ts_cmd_type= CREATE_LOGFILE_GROUP;
-          }
-        | CREATE TABLESPACE tablespace_info
-          {
-            LEX *lex= Lex;
-            lex->alter_tablespace_info->ts_cmd_type= CREATE_TABLESPACE;
-          }
-	;
-
+        ;
 
 ev_schedule_time: EVERY_SYM expr interval
 	  {
@@ -4734,6 +4736,7 @@ alter:
 
             if (!lex->et_compile_phase)
             {
+              lex->definer= NULL;
               et->init_definer(YYTHD);
               et->init_name(YYTHD, $3);
             }
@@ -7679,6 +7682,7 @@ drop:
             if (!lex->et_compile_phase)
             {
               lex->et->init_name(YYTHD, $4);
+              lex->definer= NULL;
               lex->et->init_definer(YYTHD);
             }
 
@@ -8435,6 +8439,7 @@ show_param:
             Lex->et= new (YYTHD->mem_root) Event_timed();
             if (!Lex->et)
               YYABORT;
+            Lex->definer= NULL;
             Lex->et->init_definer(YYTHD);
           }
       ;
@@ -10767,19 +10772,21 @@ subselect_end:
 **************************************************************************/
 
 view_or_trigger_or_sp:
-	definer view_or_trigger_or_sp_tail
+	definer view_or_trigger_or_sp_or_event_tail
 	{}
 	| view_replace_or_algorithm definer view_tail
 	{}
 	;
 
-view_or_trigger_or_sp_tail:
+view_or_trigger_or_sp_or_event_tail:
 	view_tail
 	{}
 	| trigger_tail
 	{}
 	| sp_tail
 	{}
+        | event_tail
+        {}
 	;
 
 /**************************************************************************

--- 1.10/mysql-test/r/events_bugs.result	2006-05-22 21:54:46 +02:00
+++ 1.11/mysql-test/r/events_bugs.result	2006-06-21 19:46:07 +02:00
@@ -178,4 +178,34 @@ drop procedure ee_16407_6_pendant;
 set global event_scheduler= 2;
 drop table events_smode_test;
 set sql_mode=@old_sql_mode;
+create definer=mysqltest_user1@localhost event mysqltest_user1_event on schedule every 10
minute do select 42;
+select db, name, body, definer, interval_value, interval_field, status from mysql.event
order by db, name, definer;
+db	name	body	definer	interval_value	interval_field	status
+events_test	mysqltest_user1_event	select 42	mysqltest_user1@localhost	10	MINUTE	ENABLED
+select event_schema, event_name, sql_mode from information_schema.events order by
event_schema, event_name;
+event_schema	event_name	sql_mode
+events_test	mysqltest_user1_event	
+drop event mysqltest_user1_event;
+create definer=current_user() event mysqltest_user1_event on schedule every 10 minute do
select 42;
+select db, name, body, definer, interval_value, interval_field, status from mysql.event
order by db, name, definer;
+db	name	body	definer	interval_value	interval_field	status
+events_test	mysqltest_user1_event	select 42	@	10	MINUTE	ENABLED
+select event_schema, event_name, sql_mode from information_schema.events order by
event_schema, event_name;
+event_schema	event_name	sql_mode
+events_test	mysqltest_user1_event	
+drop event mysqltest_user1_event;
+create definer=current_user event mysqltest_user1_event on schedule every 10 minute do
select 42;
+select db, name, body, definer, interval_value, interval_field, status from mysql.event
order by db, name, definer;
+db	name	body	definer	interval_value	interval_field	status
+events_test	mysqltest_user1_event	select 42	@	10	MINUTE	ENABLED
+select event_schema, event_name, sql_mode from information_schema.events order by
event_schema, event_name;
+event_schema	event_name	sql_mode
+events_test	mysqltest_user1_event	
+drop event mysqltest_user1_event;
+"Now test that we need SUPER for this action"
+create user mysqltest_user1@localhost;
+grant event on events_test.* to mysqltest_user1@localhost;
+create definer=mysqltest_another_user@localhost event mysqltest_user1_event on schedule
every 10 minute do select 42;
+ERROR 42000: Access denied; you need the SUPER privilege for this operation
+drop user mysqltest_user1@localhost;
 drop database events_test;

--- 1.7/mysql-test/t/events_bugs.test	2006-05-22 20:45:57 +02:00
+++ 1.8/mysql-test/t/events_bugs.test	2006-06-21 19:46:07 +02:00
@@ -172,4 +172,34 @@ set sql_mode=@old_sql_mode;
 #
 # End  - 16407: Events: Changes in sql_mode won't be taken into account  
 #
+
+#
+# Start - 16425: Events: no DEFINER clause
+#
+create definer=mysqltest_user1@localhost event mysqltest_user1_event on schedule every 10
minute do select 42;
+select db, name, body, definer, interval_value, interval_field, status from mysql.event
order by db, name, definer;
+select event_schema, event_name, sql_mode from information_schema.events order by
event_schema, event_name;
+drop event mysqltest_user1_event;
+create definer=current_user() event mysqltest_user1_event on schedule every 10 minute do
select 42;
+select db, name, body, definer, interval_value, interval_field, status from mysql.event
order by db, name, definer;
+select event_schema, event_name, sql_mode from information_schema.events order by
event_schema, event_name;
+drop event mysqltest_user1_event;
+create definer=current_user event mysqltest_user1_event on schedule every 10 minute do
select 42;
+select db, name, body, definer, interval_value, interval_field, status from mysql.event
order by db, name, definer;
+select event_schema, event_name, sql_mode from information_schema.events order by
event_schema, event_name;
+drop event mysqltest_user1_event;
+
+--echo "Now test that we need SUPER for this action"
+create user mysqltest_user1@localhost;
+grant event on events_test.* to mysqltest_user1@localhost;
+connect (conn1,localhost,mysqltest_user1,,events_test);
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+create definer=mysqltest_another_user@localhost event mysqltest_user1_event on schedule
every 10 minute do select 42;
+disconnect conn1;
+connection default;
+drop user mysqltest_user1@localhost;
+#
+# Start - 16425: Events: no DEFINER clause
+#
+
 drop database events_test;

--- 1.56/sql/event_timed.cc	2006-06-08 23:06:36 +02:00
+++ 1.57/sql/event_timed.cc	2006-06-21 19:46:08 +02:00
@@ -587,17 +587,35 @@ Event_timed::init_definer(THD *thd)
   DBUG_PRINT("info",("init definer_user thd->mem_root=0x%lx "
                      "thd->sec_ctx->priv_user=0x%lx", thd->mem_root,
                      thd->security_ctx->priv_user));
-  definer_user.str= strdup_root(thd->mem_root, thd->security_ctx->priv_user);
-  definer_user.length= strlen(thd->security_ctx->priv_user);
+  if (!thd->lex->definer)
+  {
+    definer_user.str= thd->strdup(thd->security_ctx->priv_user);
+    definer_user.length= strlen(thd->security_ctx->priv_user);
 
-  DBUG_PRINT("info",("init definer_host thd->s_c->priv_host=0x%lx",
+    DBUG_PRINT("info",("init definer_host thd->s_c->priv_host=0x%lx",
                      thd->security_ctx->priv_host));
-  definer_host.str= strdup_root(thd->mem_root, thd->security_ctx->priv_host);
-  definer_host.length= strlen(thd->security_ctx->priv_host);
-
+    definer_host.str= thd->strdup(thd->security_ctx->priv_host);
+    definer_host.length= strlen(thd->security_ctx->priv_host);
+  }
+  else if (strcmp(thd->lex->definer->user.str,
thd->security_ctx->priv_user) ||
+           my_strcasecmp(system_charset_info, thd->lex->definer->host.str,
+                         thd->security_ctx->priv_host))
+  {
+    if (check_global_access(thd, SUPER_ACL))
+    {
+      my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
+      DBUG_RETURN(1);
+    }
+    definer_user.str= thd->strdup(thd->lex->definer->user.str);
+    definer_user.length= thd->lex->definer->user.length;
+    definer_host.str= thd->strdup(thd->lex->definer->host.str);
+    definer_host.length= thd->lex->definer->host.length;
+  }
+  
+  
   DBUG_PRINT("info",("init definer as whole"));
   definer.length= definer_user.length + definer_host.length + 1;
-  definer.str= alloc_root(thd->mem_root, definer.length + 1);
+  definer.str= thd->alloc(definer.length + 1);
 
   DBUG_PRINT("info",("copy the user"));
   memcpy(definer.str, definer_user.str, definer_user.length);
@@ -1814,8 +1832,7 @@ bool
 event_timed_identifier_equal(Event_timed *a, Event_timed *b)
 {
   return event_timed_name_equal(a, &b->name) &&
-         event_timed_db_equal(a, &b->dbname) &&
-         event_timed_definer_equal(a, &b->definer);
+         event_timed_db_equal(a, &b->dbname);
 }
 
 
Thread
bk commit into 5.1 tree (andrey:1.2225) BUG#16425ahristov21 Jun