Commit 2a5fa3cf authored by unknown's avatar unknown
Browse files

Merge mysql.com:/home/tomash/src/mysql_ab/mysql-5.0

into  mysql.com:/home/tomash/src/mysql_ab/mysql-5.0-bug20570


sql/item_strfunc.cc:
  Auto merged
sql/item_strfunc.h:
  Auto merged
sql/sql_yacc.yy:
  Auto merged
mysql-test/r/view_grant.result:
  Manual merge.
mysql-test/t/view_grant.test:
  Manual merge.
parents 6a8f2ee2 a2fc4843
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
@@ -659,3 +659,56 @@ DROP VIEW test2.t3;
DROP TABLE test2.t1, test1.t0;
DROP DATABASE test2;
DROP DATABASE test1;
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 mysqltest_u1@localhost;
GRANT ALL ON test.* TO mysqltest_u1@localhost;

The following tests should all return 1.

SELECT CURRENT_USER() = 'mysqltest_u1@localhost';
CURRENT_USER() = 'mysqltest_u1@localhost'
1
SELECT f1() = 'mysqltest_u1@localhost';
f1() = 'mysqltest_u1@localhost'
1
CALL p1(@cu);
SELECT @cu = 'mysqltest_u1@localhost';
@cu = 'mysqltest_u1@localhost'
1
SELECT f2() = 'mysqltest_u1@localhost';
f2() = 'mysqltest_u1@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 mysqltest_u1@localhost;
+62 −0
Original line number Diff line number Diff line
@@ -866,3 +866,65 @@ DROP VIEW test2.t3;
DROP TABLE test2.t1, test1.t0;
DROP DATABASE test2;
DROP DATABASE test1;


#
# 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 mysqltest_u1@localhost;
GRANT ALL ON test.* TO mysqltest_u1@localhost;

connect (conn1, localhost, mysqltest_u1,,);

--echo
--echo The following tests should all return 1.
--echo
SELECT CURRENT_USER() = 'mysqltest_u1@localhost';
SELECT f1() = 'mysqltest_u1@localhost';
CALL p1(@cu);
SELECT @cu = 'mysqltest_u1@localhost';
SELECT f2() = 'mysqltest_u1@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 mysqltest_u1@localhost;

# End of 5.0 tests.
+0 −6
Original line number Diff line number Diff line
@@ -296,12 +296,6 @@ Item *create_func_pow(Item* a, Item *b)
  return new Item_func_pow(a,b);
}

Item *create_func_current_user()
{
  current_thd->lex->safe_to_cache_query= 0;
  return new Item_func_user(TRUE);
}

Item *create_func_radians(Item *a)
{
  return new Item_func_units((char*) "radians",a,M_PI/180,0.0);
+0 −1
Original line number Diff line number Diff line
@@ -73,7 +73,6 @@ Item *create_func_period_add(Item* a, Item *b);
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_radians(Item *a);
Item *create_func_release_lock(Item* a);
Item *create_func_repeat(Item* a, Item *b);
+37 −28
Original line number Diff line number Diff line
@@ -1670,42 +1670,51 @@ String *Item_func_database::val_str(String *str)
  return str;
}

// TODO: make USER() replicate properly (currently it is replicated to "")

String *Item_func_user::val_str(String *str)
/*
  TODO: make USER() replicate properly (currently it is replicated to "")
*/
bool Item_func_user::init(const char *user, const char *host)
{
  DBUG_ASSERT(fixed == 1);
  THD          *thd=current_thd;
  CHARSET_INFO *cs= system_charset_info;
  const char   *host, *user;
  uint		res_length;

  if (is_current)
  // For system threads (e.g. replication SQL thread) user may be empty
  if (user)
  {
    user= thd->security_ctx->priv_user;
    host= thd->security_ctx->priv_host;
  }
  else
    CHARSET_INFO *cs= str_value.charset();
    uint res_length= (strlen(user)+strlen(host)+2) * cs->mbmaxlen;

    if (str_value.alloc(res_length))
    {
    user= thd->main_security_ctx.user;
    host= thd->main_security_ctx.host_or_ip;
      null_value=1;
      return TRUE;
    }

    res_length=cs->cset->snprintf(cs, (char*)str_value.ptr(), res_length,
                                  "%s@%s", user, host);
    str_value.length(res_length);
    str_value.mark_as_const();
  }
  return FALSE;
}

  // For system threads (e.g. replication SQL thread) user may be empty
  if (!user)
    return &my_empty_string;
  res_length= (strlen(user)+strlen(host)+2) * cs->mbmaxlen;

  if (str->alloc(res_length))
bool Item_func_user::fix_fields(THD *thd, Item **ref)
{
    null_value=1;
    return 0;
  return (Item_func_sysconst::fix_fields(thd, ref) ||
          init(thd->main_security_ctx.user,
               thd->main_security_ctx.host_or_ip));
}
  res_length=cs->cset->snprintf(cs, (char*)str->ptr(), res_length, "%s@%s",
			        user, host);
  str->length(res_length);
  str->set_charset(cs);
  return str;


bool Item_func_current_user::fix_fields(THD *thd, Item **ref)
{
  if (Item_func_sysconst::fix_fields(thd, ref))
    return TRUE;

  Security_context *ctx= (context->security_ctx
                          ? context->security_ctx : thd->security_ctx);
  return init(ctx->priv_user, ctx->priv_host);
}


Loading