List:Commits« Previous MessageNext Message »
From:kroki Date:June 21 2006 11:34am
Subject:bk commit into 5.0 tree (kroki:1.2168) BUG#20570
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 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
  1.2168 06/06/21 15:33:57 kroki@stripped +7 -0
  Bug#20570: CURRENT_USER() in a VIEW with SQL SECURITY DEFINER returns
             invoker name
  
  The bug was fixed similar to how context switch is handled in
  Item_func_sp::execute_impl(): we store pointer to current
  Name_resolution_context in Item_func_user class, and use its
  Security_context in Item_func_user::val_str().
  
  
  NOTE FOR THE REVIEWER:
  
  Approach with infecting selected functions with context switch is error-prone.
  For instance, thd->security_ctx is used in Item_func_des_decrypt::val_str()
  and Item_load_file::val_str(), and I'm not sure it they should switch context
  too.  Perhaps more robust approach would be to switch the context as soon as
  its becomes clear that it should be done.  However, I was unable to find such
  single point (but will try harder if you request).
  
  But if we choose to stick to the current solution, then I think Item_func_user
  class should be split into two (separate for USER() and CURRENT_USER()), and
  the value should be computed in fix_fileds() method.

  sql/sql_yacc.yy
    1.470 06/06/21 15:33:51 kroki@stripped +2 -2
    Pass current Name_resolution_context to create_func_current_user.

  sql/item_strfunc.h
    1.107 06/06/21 15:33:51 kroki@stripped +5 -2
    Add field 'context' to Item_func_user.
    Use Item_func_user() constructor for USER() function.
    Use Item_func_user(Name_resolution_context *) for CURRENT_USER() function.

  sql/item_strfunc.cc
    1.267 06/06/21 15:33:50 kroki@stripped +4 -2
    If current Name_resolution_context have different Security_context, use it.

  sql/item_create.h
    1.44 06/06/21 15:33:50 kroki@stripped +1 -1
    Change ptototype for create_func_current_user().

  sql/item_create.cc
    1.60 06/06/21 15:33:50 kroki@stripped +2 -2
    Pass current Name_resolution_context to Item_func_user for CURRENT_USER().

  mysql-test/t/view_grant.test
    1.14 06/06/21 13:08:56 kroki@stripped +62 -0
    Add test case for bug#20570.

  mysql-test/r/view_grant.result
    1.16 06/06/21 13:08:55 kroki@stripped +53 -0
    Add result for bug#20570.

# 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.intranet
# Root:	/home/tomash/src/mysql_ab/mysql-5.0-bug20570

--- 1.59/sql/item_create.cc	2006-04-12 19:30:51 +04:00
+++ 1.60/sql/item_create.cc	2006-06-21 15:33:50 +04:00
@@ -296,10 +296,10 @@
   return new Item_func_pow(a,b);
 }
 
-Item *create_func_current_user()
+Item *create_func_current_user(Name_resolution_context *ctx)
 {
   current_thd->lex->safe_to_cache_query= 0;
-  return new Item_func_user(TRUE);
+  return new Item_func_user(ctx);
 }
 
 Item *create_func_radians(Item *a)

--- 1.43/sql/item_create.h	2005-08-25 17:34:13 +04:00
+++ 1.44/sql/item_create.h	2006-06-21 15:33:50 +04:00
@@ -73,7 +73,7 @@
 Item *create_func_period_diff(Item* a, Item *b);
 Item *create_func_pi(void);
 Item *create_func_pow(Item* a, Item *b);
-Item *create_func_current_user(void);
+Item *create_func_current_user(Name_resolution_context *ctx);
 Item *create_func_radians(Item *a);
 Item *create_func_release_lock(Item* a);
 Item *create_func_repeat(Item* a, Item *b);

--- 1.266/sql/item_strfunc.cc	2006-05-12 11:15:11 +04:00
+++ 1.267/sql/item_strfunc.cc	2006-06-21 15:33:50 +04:00
@@ -1662,8 +1662,10 @@
 
   if (is_current)
   {
-    user= thd->security_ctx->priv_user;
-    host= thd->security_ctx->priv_host;
+    Security_context *ctx= (context->security_ctx
+                            ? context->security_ctx : thd->security_ctx);
+    user= ctx->priv_user;
+    host= ctx->priv_host;
   }
   else
   {

--- 1.106/sql/item_strfunc.h	2006-05-18 21:33:57 +04:00
+++ 1.107/sql/item_strfunc.h	2006-06-21 15:33:51 +04:00
@@ -385,11 +385,14 @@
 
 class Item_func_user :public Item_func_sysconst
 {
+  Name_resolution_context *context;
   bool is_current;
 
 public:
-  Item_func_user(bool is_current_arg)
-    :Item_func_sysconst(), is_current(is_current_arg) {}
+  Item_func_user()
+    :Item_func_sysconst(), context(0), is_current(false) {}
+  Item_func_user(Name_resolution_context *ctx)
+    :Item_func_sysconst(), context(ctx), is_current(true) {}
   String *val_str(String *);
   void fix_length_and_dec()
   {

--- 1.469/sql/sql_yacc.yy	2006-05-15 00:51:02 +04:00
+++ 1.470/sql/sql_yacc.yy	2006-06-21 15:33:51 +04:00
@@ -4413,7 +4413,7 @@
 	    Lex->safe_to_cache_query=0;
 	  }
 	| CURRENT_USER optional_braces
-          { $$= create_func_current_user(); }
+          { $$= create_func_current_user(Lex->current_context()); }
 	| DATE_ADD_INTERVAL '(' expr ',' interval_expr interval ')'
 	  { $$= new Item_date_add_interval($3,$5,$6,0); }
 	| DATE_SUB_INTERVAL '(' expr ',' interval_expr interval ')'
@@ -4764,7 +4764,7 @@
 	| UNIX_TIMESTAMP '(' expr ')'
 	  { $$= new Item_func_unix_timestamp($3); }
 	| USER '(' ')'
-	  { $$= new Item_func_user(FALSE); Lex->safe_to_cache_query=0; }
+	  { $$= new Item_func_user(); Lex->safe_to_cache_query=0; }
 	| UTC_DATE_SYM optional_braces
 	  { $$= new Item_func_curdate_utc(); Lex->safe_to_cache_query=0;}
 	| UTC_TIME_SYM optional_braces

--- 1.15/mysql-test/r/view_grant.result	2006-05-26 12:57:52 +04:00
+++ 1.16/mysql-test/r/view_grant.result	2006-06-21 13:08:55 +04:00
@@ -618,3 +618,56 @@
 DROP VIEW v;
 DROP TABLE t1;
 USE test;
+DROP VIEW IF EXISTS v1;
+DROP VIEW IF EXISTS v2;
+DROP VIEW IF EXISTS v3;
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP PROCEDURE IF EXISTS p1;
+CREATE SQL SECURITY DEFINER VIEW v1 AS SELECT CURRENT_USER() AS cu;
+CREATE FUNCTION f1() RETURNS VARCHAR(77) SQL SECURITY INVOKER
+RETURN CURRENT_USER();
+CREATE SQL SECURITY DEFINER VIEW v2 AS SELECT f1() AS cu;
+CREATE PROCEDURE p1(OUT cu VARCHAR(77)) SQL SECURITY INVOKER
+SET cu= CURRENT_USER();
+CREATE FUNCTION f2() RETURNS VARCHAR(77) SQL SECURITY INVOKER
+BEGIN
+DECLARE cu VARCHAR(77);
+CALL p1(cu);
+RETURN cu;
+END|
+CREATE SQL SECURITY DEFINER VIEW v3 AS SELECT f2() AS cu;
+CREATE USER testuser1@localhost;
+GRANT ALL ON test.* TO testuser1@localhost;
+
+The following tests should all return 1.
+
+SELECT CURRENT_USER() = 'testuser1@localhost';
+CURRENT_USER() = 'testuser1@localhost'
+1
+SELECT f1() = 'testuser1@localhost';
+f1() = 'testuser1@localhost'
+1
+CALL p1(@cu);
+SELECT @cu = 'testuser1@localhost';
+@cu = 'testuser1@localhost'
+1
+SELECT f2() = 'testuser1@localhost';
+f2() = 'testuser1@localhost'
+1
+SELECT cu = 'root@localhost' FROM v1;
+cu = 'root@localhost'
+1
+SELECT cu = 'root@localhost' FROM v2;
+cu = 'root@localhost'
+1
+SELECT cu = 'root@localhost' FROM v3;
+cu = 'root@localhost'
+1
+DROP VIEW v3;
+DROP FUNCTION f2;
+DROP PROCEDURE p1;
+DROP FUNCTION f1;
+DROP VIEW v2;
+DROP VIEW v1;
+DROP USER testuser1@localhost;

--- 1.13/mysql-test/t/view_grant.test	2006-05-26 12:57:52 +04:00
+++ 1.14/mysql-test/t/view_grant.test	2006-06-21 13:08:56 +04:00
@@ -807,3 +807,65 @@
 DROP VIEW v;
 DROP TABLE t1;
 USE test;
+
+
+#
+# BUG#20570: CURRENT_USER() in a VIEW with SQL SECURITY DEFINER
+# returns invoker name
+#
+--disable_warnings
+DROP VIEW IF EXISTS v1;
+DROP VIEW IF EXISTS v2;
+DROP VIEW IF EXISTS v3;
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP PROCEDURE IF EXISTS p1;
+--enable_warnings
+
+CREATE SQL SECURITY DEFINER VIEW v1 AS SELECT CURRENT_USER() AS cu;
+
+CREATE FUNCTION f1() RETURNS VARCHAR(77) SQL SECURITY INVOKER
+  RETURN CURRENT_USER();
+CREATE SQL SECURITY DEFINER VIEW v2 AS SELECT f1() AS cu;
+
+CREATE PROCEDURE p1(OUT cu VARCHAR(77)) SQL SECURITY INVOKER
+  SET cu= CURRENT_USER();
+delimiter |;
+CREATE FUNCTION f2() RETURNS VARCHAR(77) SQL SECURITY INVOKER
+BEGIN
+  DECLARE cu VARCHAR(77);
+  CALL p1(cu);
+  RETURN cu;
+END|
+delimiter ;|
+CREATE SQL SECURITY DEFINER VIEW v3 AS SELECT f2() AS cu;
+
+CREATE USER testuser1@localhost;
+GRANT ALL ON test.* TO testuser1@localhost;
+
+connect (conn1, localhost, testuser1,,);
+
+--echo
+--echo The following tests should all return 1.
+--echo
+SELECT CURRENT_USER() = 'testuser1@localhost';
+SELECT f1() = 'testuser1@localhost';
+CALL p1(@cu);
+SELECT @cu = 'testuser1@localhost';
+SELECT f2() = 'testuser1@localhost';
+SELECT cu = 'root@localhost' FROM v1;
+SELECT cu = 'root@localhost' FROM v2;
+SELECT cu = 'root@localhost' FROM v3;
+
+disconnect conn1;
+connection default;
+
+DROP VIEW v3;
+DROP FUNCTION f2;
+DROP PROCEDURE p1;
+DROP FUNCTION f1;
+DROP VIEW v2;
+DROP VIEW v1;
+DROP USER testuser1@localhost;
+
+# End of 5.0 tests.
Thread
bk commit into 5.0 tree (kroki:1.2168) BUG#20570kroki21 Jun