List:Commits« Previous MessageNext Message »
From:kroki Date:February 2 2007 6:43pm
Subject:bk commit into 5.1 tree (kroki:1.2416) BUG#16425
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of tomash. When tomash 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@stripped, 2007-02-02 20:43:33+03:00, kroki@stripped +5 -0
  BUG#16425: Events: no DEFINER clause
  
  There was already support for CREATE DEFINER=... EVENT syntax in the
  parser, but DEFINER information was ignored.
  
  This patch adds processing of DEFINER, and a new ALTER DEFINER=...
  EVENT syntax.

  mysql-test/r/events_bugs.result@stripped, 2007-02-02 20:43:26+03:00, kroki@stripped
+53 -0
    Add result for bug#16425: Events: no DEFINER clause.

  mysql-test/t/events_bugs.test@stripped, 2007-02-02 20:43:26+03:00, kroki@stripped +57
-0
    Add test case for bug#16425: Events: no DEFINER clause.

  sql/event_data_objects.cc@stripped, 2007-02-02 20:43:26+03:00, kroki@stripped +11 -10
    Event_parse_data::init_definer() looks for DEFINER in
    thd->lex->definer, which is always set now.

  sql/sql_parse.cc@stripped, 2007-02-02 20:43:26+03:00, kroki@stripped +92 -77
    Move DEFINER processing into the sp_process_definer().  Call this
    function for CREATE EVENT/ALTER EVENT, as well as for CREATE
    PROCEDURE/FUNCTION.

  sql/sql_yacc.yy@stripped, 2007-02-02 20:43:26+03:00, kroki@stripped +8 -7
    Add 'alter DEFINER=... event', update rule references accordingly.

# 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:	kroki
# Host:	moonlight.home
# Root:	/home/tomash/src/mysql_ab/mysql-5.1-bug16425

--- 1.621/sql/sql_parse.cc	2007-02-02 20:43:43 +03:00
+++ 1.622/sql/sql_parse.cc	2007-02-02 20:43:43 +03:00
@@ -2492,6 +2492,91 @@ static void reset_one_shot_variables(THD
 }
 
 
+static
+bool sp_process_definer(THD *thd)
+{
+  DBUG_ENTER("sp_process_definer");
+
+  LEX *lex= thd->lex;
+
+  /*
+    If the definer is not specified, this means that CREATE-statement missed
+    DEFINER-clause. DEFINER-clause can be missed in two cases:
+
+      - The user submitted a statement w/o the clause. This is a normal
+        case, we should assign CURRENT_USER as definer.
+
+      - Our slave received an updated from the master, that does not
+        replicate definer for stored rountines. We should also assign
+        CURRENT_USER as definer here, but also we should mark this routine
+        as NON-SUID. This is essential for the sake of backward
+        compatibility.
+
+        The problem is the slave thread is running under "special" user (@),
+        that actually does not exist. In the older versions we do not fail
+        execution of a stored routine if its definer does not exist and
+        continue the execution under the authorization of the invoker
+        (BUG#13198). And now if we try to switch to slave-current-user (@),
+        we will fail.
+
+        Actually, this leads to the inconsistent state of master and
+        slave (different definers, different SUID behaviour), but it seems,
+        this is the best we can do.
+  */
+
+  if (!lex->definer)
+  {
+    Query_arena original_arena;
+    Query_arena *ps_arena= thd->activate_stmt_arena_if_needed(&original_arena);
+
+    lex->definer= create_default_definer(thd);
+
+    if (ps_arena)
+      thd->restore_active_arena(ps_arena, &original_arena);
+
+    /* Error has been already reported. */
+    if (lex->definer == NULL)
+      DBUG_RETURN(TRUE);
+
+    if (thd->slave_thread)
+      lex->sphead->m_chistics->suid= SP_IS_NOT_SUID;
+  }
+  else
+  {
+    /*
+      If the specified definer differs from the current user, we
+      should check that the current user has SUPER privilege (in order
+      to create a stored routine under another user one must have
+      SUPER privilege).
+    */
+    if ((strcmp(lex->definer->user.str, thd->security_ctx->priv_user) ||
+         my_strcasecmp(system_charset_info, lex->definer->host.str,
+                       thd->security_ctx->priv_host)) &&
+        check_global_access(thd, SUPER_ACL))
+    {
+      my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
+      DBUG_RETURN(TRUE);
+    }
+  }
+
+  /* Check that the specified definer exists. Emit a warning if not. */
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+  if (!is_acl_user(lex->definer->host.str, lex->definer->user.str))
+  {
+    push_warning_printf(thd,
+                        MYSQL_ERROR::WARN_LEVEL_NOTE,
+                        ER_NO_SUCH_USER,
+                        ER(ER_NO_SUCH_USER),
+                        lex->definer->user.str,
+                        lex->definer->host.str);
+  }
+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
+
+  DBUG_RETURN(FALSE);
+}
+
+
 /*
   Execute command saved in thd and lex->sql_command
 
@@ -3992,6 +4077,11 @@ end_with_restore_list:
                "function calls as part of this statement");
       break;
     }
+
+    res= sp_process_definer(thd);
+    if (res)
+      break;
+
     switch (lex->sql_command) {
     case SQLCOM_CREATE_EVENT:
       res= Events::get_instance()->
@@ -4487,83 +4577,8 @@ end_with_restore_list:
     }
 #endif
 
-    /*
-      If the definer is not specified, this means that CREATE-statement missed
-      DEFINER-clause. DEFINER-clause can be missed in two cases:
-
-        - The user submitted a statement w/o the clause. This is a normal
-          case, we should assign CURRENT_USER as definer.
-
-        - Our slave received an updated from the master, that does not
-          replicate definer for stored rountines. We should also assign
-          CURRENT_USER as definer here, but also we should mark this routine
-          as NON-SUID. This is essential for the sake of backward
-          compatibility.
-
-          The problem is the slave thread is running under "special" user (@),
-          that actually does not exist. In the older versions we do not fail
-          execution of a stored routine if its definer does not exist and
-          continue the execution under the authorization of the invoker
-          (BUG#13198). And now if we try to switch to slave-current-user (@),
-          we will fail.
-
-          Actually, this leads to the inconsistent state of master and
-          slave (different definers, different SUID behaviour), but it seems,
-          this is the best we can do.
-    */
-
-    if (!lex->definer)
-    {
-      bool res= FALSE;
-      Query_arena original_arena;
-      Query_arena *ps_arena = thd->activate_stmt_arena_if_needed(&original_arena);
-
-      if (!(lex->definer= create_default_definer(thd)))
-        res= TRUE;
-
-      if (ps_arena)
-        thd->restore_active_arena(ps_arena, &original_arena);
-
-      /* Error has been already reported. */
-      if (res)
-        goto create_sp_error;
-
-      if (thd->slave_thread)
-        lex->sphead->m_chistics->suid= SP_IS_NOT_SUID;
-    }
-
-    /*
-      If the specified definer differs from the current user, we should check
-      that the current user has SUPER privilege (in order to create a stored
-      routine under another user one must have SUPER privilege).
-    */
-
-    else if (strcmp(lex->definer->user.str, thd->security_ctx->priv_user) ||
-        my_strcasecmp(system_charset_info,
-                      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");
-        goto create_sp_error;
-      }
-    }
-
-    /* Check that the specified definer exists. Emit a warning if not. */
-
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-    if (!is_acl_user(lex->definer->host.str,
-                     lex->definer->user.str))
-    {
-      push_warning_printf(thd,
-                          MYSQL_ERROR::WARN_LEVEL_NOTE,
-                          ER_NO_SUCH_USER,
-                          ER(ER_NO_SUCH_USER),
-                          lex->definer->user.str,
-                          lex->definer->host.str);
-    }
-#endif /* NO_EMBEDDED_ACCESS_CHECKS */
+    if (sp_process_definer(thd))
+      goto create_sp_error;
 
     res= (result= lex->sphead->create(thd));
     switch (result) {

--- 1.537/sql/sql_yacc.yy	2007-02-02 20:43:43 +03:00
+++ 1.538/sql/sql_yacc.yy	2007-02-02 20:43:43 +03:00
@@ -5104,7 +5104,7 @@ alter:
 	  }
 	  view_list_opt AS view_select view_check_option
 	  {}
-	| ALTER EVENT_SYM sp_name
+	| ALTER definer EVENT_SYM sp_name
           /*
             BE CAREFUL when you add a new rule to update the block where
             YYTHD->client_capabilities is set back to original value
@@ -5120,7 +5120,7 @@ alter:
 
             if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD)))
               YYABORT;
-            Lex->event_parse_data->identifier= $3;
+            Lex->event_parse_data->identifier= $4;
 
             /*
               We have to turn off CLIENT_MULTI_QUERIES while parsing a
@@ -5140,13 +5140,14 @@ alter:
           {
             /*
               $1 - ALTER
-              $2 - EVENT_SYM
-              $3 - sp_name
-              $4 - the block above
+              $2 - definer
+              $3 - EVENT_SYM
+              $4 - sp_name
+              $5 - the block above
             */
-            YYTHD->client_capabilities |= $<ulong_num>4;
+            YYTHD->client_capabilities |= $<ulong_num>5;
 
-            if (!($5 || $6 || $7 || $8 || $9))
+            if (!($6 || $7 || $8 || $9 || $10))
             {
 	      yyerror(ER(ER_SYNTAX_ERROR));
               YYABORT;

--- 1.24/mysql-test/r/events_bugs.result	2007-02-02 20:43:43 +03:00
+++ 1.25/mysql-test/r/events_bugs.result	2007-02-02 20:43:43 +03:00
@@ -325,4 +325,57 @@ drop event e22830_3;
 drop event e22830_4;
 drop table t1;
 drop table t2;
+DROP USER mysqltest_u1@localhost;
+CREATE USER mysqltest_u1@localhost;
+GRANT EVENT ON events_test.* TO mysqltest_u1@localhost;
+CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS;
+event_name	definer
+e1	root@localhost
+DROP EVENT e1;
+CREATE DEFINER=CURRENT_USER EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS;
+event_name	definer
+e1	root@localhost
+ALTER DEFINER=mysqltest_u1@localhost EVENT e1 ON SCHEDULE EVERY 1 HOUR;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS;
+event_name	definer
+e1	mysqltest_u1@localhost
+DROP EVENT e1;
+CREATE DEFINER=CURRENT_USER() EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS;
+event_name	definer
+e1	root@localhost
+DROP EVENT e1;
+CREATE DEFINER=mysqltest_u1@localhost EVENT e1 ON SCHEDULE EVERY 1 DAY DO
+SELECT 1;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS;
+event_name	definer
+e1	mysqltest_u1@localhost
+DROP EVENT e1;
+CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS;
+event_name	definer
+e1	mysqltest_u1@localhost
+DROP EVENT e1;
+CREATE DEFINER=CURRENT_USER EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS;
+event_name	definer
+e1	mysqltest_u1@localhost
+ALTER DEFINER=root@localhost EVENT e1 ON SCHEDULE EVERY 1 HOUR;
+ERROR 42000: Access denied; you need the SUPER privilege for this operation
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS;
+event_name	definer
+e1	mysqltest_u1@localhost
+DROP EVENT e1;
+CREATE DEFINER=CURRENT_USER() EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS;
+event_name	definer
+e1	mysqltest_u1@localhost
+DROP EVENT e1;
+CREATE DEFINER=root@localhost EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
+ERROR 42000: Access denied; you need the SUPER privilege for this operation
+DROP EVENT e1;
+ERROR HY000: Unknown event 'e1'
+DROP USER mysqltest_u1@localhost;
 drop database events_test;

--- 1.23/mysql-test/t/events_bugs.test	2007-02-02 20:43:43 +03:00
+++ 1.24/mysql-test/t/events_bugs.test	2007-02-02 20:43:43 +03:00
@@ -364,6 +364,63 @@ drop event e22830_4;
 drop table t1;
 drop table t2;
 
+
+#
+# BUG#16425: Events: no DEFINER clause
+#
+--error 0,ER_CANNOT_USER
+DROP USER mysqltest_u1@localhost;
+
+CREATE USER mysqltest_u1@localhost;
+GRANT EVENT ON events_test.* TO mysqltest_u1@localhost;
+
+CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS; 
+DROP EVENT e1;
+
+CREATE DEFINER=CURRENT_USER EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS; 
+ALTER DEFINER=mysqltest_u1@localhost EVENT e1 ON SCHEDULE EVERY 1 HOUR;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS; 
+DROP EVENT e1;
+
+CREATE DEFINER=CURRENT_USER() EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS; 
+DROP EVENT e1;
+
+CREATE DEFINER=mysqltest_u1@localhost EVENT e1 ON SCHEDULE EVERY 1 DAY DO
+  SELECT 1;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS; 
+DROP EVENT e1;
+
+connect (conn1, localhost, mysqltest_u1, , events_test);
+
+CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS; 
+DROP EVENT e1;
+
+CREATE DEFINER=CURRENT_USER EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS; 
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+ALTER DEFINER=root@localhost EVENT e1 ON SCHEDULE EVERY 1 HOUR;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS; 
+DROP EVENT e1;
+
+CREATE DEFINER=CURRENT_USER() EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
+SELECT event_name, definer FROM INFORMATION_SCHEMA.EVENTS; 
+DROP EVENT e1;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+CREATE DEFINER=root@localhost EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
+--error ER_EVENT_DOES_NOT_EXIST
+DROP EVENT e1;
+
+disconnect conn1;
+connection default;
+
+DROP USER mysqltest_u1@localhost;
+
+
 #
 # End of tests
 #

--- 1.85/sql/event_data_objects.cc	2007-02-02 20:43:43 +03:00
+++ 1.86/sql/event_data_objects.cc	2007-02-02 20:43:43 +03:00
@@ -611,16 +611,18 @@ Event_parse_data::check_parse_data(THD *
 void
 Event_parse_data::init_definer(THD *thd)
 {
-  int definer_user_len;
-  int definer_host_len;
   DBUG_ENTER("Event_parse_data::init_definer");
 
-  DBUG_PRINT("info",("init definer_user thd->mem_root: 0x%lx  "
-                     "thd->sec_ctx->priv_user: 0x%lx", (long) thd->mem_root,
-                     (long) thd->security_ctx->priv_user));
+  DBUG_ASSERT(thd->lex->definer);
+
+  const char *definer_user= thd->lex->definer->user.str;
+  const char *definer_host= thd->lex->definer->host.str;
+  int definer_user_len= thd->lex->definer->user.length;
+  int definer_host_len= thd->lex->definer->host.length;
 
-  definer_user_len= strlen(thd->security_ctx->priv_user);
-  definer_host_len= strlen(thd->security_ctx->priv_host);
+  DBUG_PRINT("info",("init definer_user thd->mem_root: 0x%lx  "
+                     "definer_user: 0x%lx", (long) thd->mem_root,
+                     (long) definer_user));
 
   /* + 1 for @ */
   DBUG_PRINT("info",("init definer as whole"));
@@ -628,12 +630,11 @@ Event_parse_data::init_definer(THD *thd)
   definer.str= thd->alloc(definer.length + 1);
 
   DBUG_PRINT("info",("copy the user"));
-  memcpy(definer.str, thd->security_ctx->priv_user, definer_user_len);
+  memcpy(definer.str, definer_user, definer_user_len);
   definer.str[definer_user_len]= '@';
 
   DBUG_PRINT("info",("copy the host"));
-  memcpy(definer.str + definer_user_len + 1, thd->security_ctx->priv_host,
-         definer_host_len);
+  memcpy(definer.str + definer_user_len + 1, definer_host, definer_host_len);
   definer.str[definer.length]= '\0';
   DBUG_PRINT("info",("definer [%s] initted", definer.str));
 
Thread
bk commit into 5.1 tree (kroki:1.2416) BUG#16425kroki2 Feb