Commit 728371c5 authored by unknown's avatar unknown
Browse files

Bug#15298 SHOW GRANTS FOR CURRENT_USER: Incorrect output in DEFINER context

user name is calculated on function execution stage instead of parse stage


mysql-test/r/sp_notembedded.result:
  Bug#15298 SHOW GRANTS FOR CURRENT_USER: Incorrect output in DEFINER context
  test case
mysql-test/t/sp_notembedded.test:
  Bug#15298 SHOW GRANTS FOR CURRENT_USER: Incorrect output in DEFINER context
  test case
sql/mysql_priv.h:
  Bug#15298 SHOW GRANTS FOR CURRENT_USER: Incorrect output in DEFINER context
  new get_current_user(THD *thd, LEX_USER *user) function
sql/sql_acl.cc:
  Bug#15298 SHOW GRANTS FOR CURRENT_USER: Incorrect output in DEFINER context
  user name is calculated using get_current_user() function
sql/sql_parse.cc:
  Bug#15298 SHOW GRANTS FOR CURRENT_USER: Incorrect output in DEFINER context
  new get_current_user() function
  user name is calculated using get_current_user() function
sql/sql_yacc.yy:
  Bug#15298 SHOW GRANTS FOR CURRENT_USER: Incorrect output in DEFINER context
  empty LEX_USER struct for CURRENT USER, 
  user name is calculated on function execution stage
parent b5f89708
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -206,3 +206,17 @@ drop procedure bug10100pd|
drop procedure bug10100pc|
drop view v1|
drop table t3|
drop procedure if exists bug15298_1;
drop procedure if exists bug15298_2;
grant all privileges on test.* to 'mysqltest_1'@'localhost';
create procedure 15298_1 () sql security definer show grants for current_user;
create procedure 15298_2 () sql security definer show grants;
call 15298_1();
Grants for root@localhost
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
call 15298_2();
Grants for root@localhost
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
drop user mysqltest_1@localhost;
drop procedure 15298_1;
drop procedure 15298_2;
+20 −0
Original line number Diff line number Diff line
@@ -265,3 +265,23 @@ drop view v1|
drop table t3|

delimiter ;|

#
# Bug#15298 SHOW GRANTS FOR CURRENT_USER: Incorrect output in DEFINER context
#
--disable_warnings
drop procedure if exists bug15298_1;
drop procedure if exists bug15298_2;
--enable_warnings
grant all privileges on test.* to 'mysqltest_1'@'localhost';
create procedure 15298_1 () sql security definer show grants for current_user;
create procedure 15298_2 () sql security definer show grants;

connect (con1,localhost,mysqltest_1,,test);
call 15298_1();
call 15298_2();

connection default;
drop user mysqltest_1@localhost;
drop procedure 15298_1;
drop procedure 15298_2;
+1 −0
Original line number Diff line number Diff line
@@ -537,6 +537,7 @@ int append_query_string(CHARSET_INFO *csinfo,
void get_default_definer(THD *thd, LEX_USER *definer);
LEX_USER *create_default_definer(THD *thd);
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name);
LEX_USER *get_current_user(THD *thd, LEX_USER *user);

enum enum_mysql_completiontype {
  ROLLBACK_RELEASE=-2, ROLLBACK=1,  ROLLBACK_AND_CHAIN=7,
+57 −16
Original line number Diff line number Diff line
@@ -2766,7 +2766,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
{
  ulong column_priv= 0;
  List_iterator <LEX_USER> str_list (user_list);
  LEX_USER *Str;
  LEX_USER *Str, *tmp_Str;
  TABLE_LIST tables[3];
  bool create_new_users=0;
  char *db_name, *table_name;
@@ -2891,10 +2891,15 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
  thd->mem_root= &memex;
  grant_version++;

  while ((Str = str_list++))
  while ((tmp_Str = str_list++))
  {
    int error;
    GRANT_TABLE *grant_table;
    if (!(Str= get_current_user(thd, tmp_Str)))
    {
      result= TRUE;
      continue;
    }  
    if (Str->host.length > HOSTNAME_LENGTH ||
	Str->user.length > USERNAME_LENGTH)
    {
@@ -3030,7 +3035,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
			 bool revoke_grant, bool no_error)
{
  List_iterator <LEX_USER> str_list (user_list);
  LEX_USER *Str;
  LEX_USER *Str, *tmp_Str;
  TABLE_LIST tables[2];
  bool create_new_users=0, result=0;
  char *db_name, *table_name;
@@ -3098,10 +3103,15 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,

  DBUG_PRINT("info",("now time to iterate and add users"));

  while ((Str= str_list++))
  while ((tmp_Str= str_list++))
  {
    int error;
    GRANT_NAME *grant_name;
    if (!(Str= get_current_user(thd, tmp_Str)))
    {
      result= TRUE;
      continue;
    }  
    if (Str->host.length > HOSTNAME_LENGTH ||
	Str->user.length > USERNAME_LENGTH)
    {
@@ -3170,7 +3180,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
                 ulong rights, bool revoke_grant)
{
  List_iterator <LEX_USER> str_list (list);
  LEX_USER *Str;
  LEX_USER *Str, *tmp_Str;
  char tmp_db[NAME_LEN+1];
  bool create_new_users=0;
  TABLE_LIST tables[2];
@@ -3229,8 +3239,13 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
  grant_version++;

  int result=0;
  while ((Str = str_list++))
  while ((tmp_Str = str_list++))
  {
    if (!(Str= get_current_user(thd, tmp_Str)))
    {
      result= TRUE;
      continue;
    }  
    if (Str->host.length > HOSTNAME_LENGTH ||
	Str->user.length > USERNAME_LENGTH)
    {
@@ -5187,7 +5202,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
  int result;
  String wrong_users;
  ulong sql_mode;
  LEX_USER *user_name;
  LEX_USER *user_name, *tmp_user_name;
  List_iterator <LEX_USER> user_list(list);
  TABLE_LIST tables[GRANT_TABLES];
  DBUG_ENTER("mysql_create_user");
@@ -5199,8 +5214,13 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
  rw_wrlock(&LOCK_grant);
  VOID(pthread_mutex_lock(&acl_cache->lock));

  while ((user_name= user_list++))
  while ((tmp_user_name= user_list++))
  {
    if (!(user_name= get_current_user(thd, tmp_user_name)))
    {
      result= TRUE;
      continue;
    }  
    /*
      Search all in-memory structures and grant tables
      for a mention of the new user name.
@@ -5246,7 +5266,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
{
  int result;
  String wrong_users;
  LEX_USER *user_name;
  LEX_USER *user_name, *tmp_user_name;
  List_iterator <LEX_USER> user_list(list);
  TABLE_LIST tables[GRANT_TABLES];
  DBUG_ENTER("mysql_drop_user");
@@ -5258,8 +5278,14 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
  rw_wrlock(&LOCK_grant);
  VOID(pthread_mutex_lock(&acl_cache->lock));

  while ((user_name= user_list++))
  while ((tmp_user_name= user_list++))
  {
    user_name= get_current_user(thd, tmp_user_name);
    if (!(user_name= get_current_user(thd, tmp_user_name)))
    {
      result= TRUE;
      continue;
    }  
    if (handle_grant_data(tables, 1, user_name, NULL) <= 0)
    {
      append_user(&wrong_users, user_name);
@@ -5296,8 +5322,8 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
{
  int result;
  String wrong_users;
  LEX_USER *user_from;
  LEX_USER *user_to;
  LEX_USER *user_from, *tmp_user_from;
  LEX_USER *user_to, *tmp_user_to;
  List_iterator <LEX_USER> user_list(list);
  TABLE_LIST tables[GRANT_TABLES];
  DBUG_ENTER("mysql_rename_user");
@@ -5309,9 +5335,19 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
  rw_wrlock(&LOCK_grant);
  VOID(pthread_mutex_lock(&acl_cache->lock));

  while ((user_from= user_list++))
  while ((tmp_user_from= user_list++))
  {
    if (!(user_from= get_current_user(thd, tmp_user_from)))
    {
      result= TRUE;
      continue;
    }  
    tmp_user_to= user_list++;
    if (!(user_to= get_current_user(thd, tmp_user_to)))
    {
    user_to= user_list++;
      result= TRUE;
      continue;
    }  
    DBUG_ASSERT(user_to != 0); /* Syntax enforces pairs of users. */

    /*
@@ -5366,10 +5402,15 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
  rw_wrlock(&LOCK_grant);
  VOID(pthread_mutex_lock(&acl_cache->lock));

  LEX_USER *lex_user;
  LEX_USER *lex_user, *tmp_lex_user;
  List_iterator <LEX_USER> user_list(list);
  while ((lex_user=user_list++))
  while ((tmp_lex_user= user_list++))
  {
    if (!(lex_user= get_current_user(thd, tmp_lex_user)))
    {
      result= -1;
      continue;
    }  
    if (!find_acl_user(lex_user->host.str, lex_user->user.str, TRUE))
    {
      sql_print_error("REVOKE ALL PRIVILEGES, GRANT: User '%s'@'%s' does not "
+48 −6
Original line number Diff line number Diff line
@@ -3887,11 +3887,13 @@ mysql_execute_command(THD *thd)

    if (thd->security_ctx->user)              // If not replication
    {
      LEX_USER *user;
      LEX_USER *user, *tmp_user;

      List_iterator <LEX_USER> user_list(lex->users_list);
      while ((user= user_list++))
      while ((tmp_user= user_list++))
      {
        if (!(user= get_current_user(thd, tmp_user)))
          goto error;
        if (specialflag & SPECIAL_NO_RESOLVE &&
            hostname_requires_resolving(user->host.str))
          push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
@@ -3973,12 +3975,16 @@ mysql_execute_command(THD *thd)
	if (lex->sql_command == SQLCOM_GRANT)
	{
	  List_iterator <LEX_USER> str_list(lex->users_list);
	  LEX_USER *user;
	  while ((user=str_list++))
	  LEX_USER *user, *tmp_user;
	  while ((tmp_user=str_list++))
          {
            if (!(user= get_current_user(thd, tmp_user)))
              goto error;
	    reset_mqh(user);
          }
	}
      }
    }
    break;
  }
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
@@ -4030,13 +4036,18 @@ mysql_execute_command(THD *thd)
  }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
  case SQLCOM_SHOW_GRANTS:
  {
    LEX_USER *grant_user= get_current_user(thd, lex->grant_user);
    if (!grant_user)
      goto error;
    if ((thd->security_ctx->priv_user &&
	 !strcmp(thd->security_ctx->priv_user, lex->grant_user->user.str)) ||
	 !strcmp(thd->security_ctx->priv_user, grant_user->user.str)) ||
	!check_access(thd, SELECT_ACL, "mysql",0,1,0,0))
    {
      res = mysql_show_grants(thd,lex->grant_user);
      res = mysql_show_grants(thd, grant_user);
    }
    break;
  }
#endif
  case SQLCOM_HA_OPEN:
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
@@ -7495,3 +7506,34 @@ LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)

  return definer;
}


/*
  Retuns information about user or current user.

  SYNOPSIS
    get_current_user()
    thd         [in] thread handler
    user        [in] user

  RETURN
    On success, return a valid pointer to initialized
    LEX_USER, which contains user information.
    On error, return 0.
*/

LEX_USER *get_current_user(THD *thd, LEX_USER *user)
{
  LEX_USER *curr_user;
  if (!user->user.str)  // current_user
  {
    if (!(curr_user= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
    {
      my_error(ER_OUTOFMEMORY, MYF(0), sizeof(LEX_USER));
      return 0;
    }
    get_default_definer(thd, curr_user);
    return curr_user;
  }
  return user;
}
Loading