Commit 728371c5 authored by unknown's avatar unknown

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
...@@ -206,3 +206,17 @@ drop procedure bug10100pd| ...@@ -206,3 +206,17 @@ drop procedure bug10100pd|
drop procedure bug10100pc| drop procedure bug10100pc|
drop view v1| drop view v1|
drop table t3| 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;
...@@ -265,3 +265,23 @@ drop view v1| ...@@ -265,3 +265,23 @@ drop view v1|
drop table t3| drop table t3|
delimiter ;| 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;
...@@ -537,6 +537,7 @@ int append_query_string(CHARSET_INFO *csinfo, ...@@ -537,6 +537,7 @@ int append_query_string(CHARSET_INFO *csinfo,
void get_default_definer(THD *thd, LEX_USER *definer); void get_default_definer(THD *thd, LEX_USER *definer);
LEX_USER *create_default_definer(THD *thd); LEX_USER *create_default_definer(THD *thd);
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name); 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 { enum enum_mysql_completiontype {
ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7, ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7,
......
...@@ -2766,7 +2766,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, ...@@ -2766,7 +2766,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
{ {
ulong column_priv= 0; ulong column_priv= 0;
List_iterator <LEX_USER> str_list (user_list); List_iterator <LEX_USER> str_list (user_list);
LEX_USER *Str; LEX_USER *Str, *tmp_Str;
TABLE_LIST tables[3]; TABLE_LIST tables[3];
bool create_new_users=0; bool create_new_users=0;
char *db_name, *table_name; char *db_name, *table_name;
...@@ -2891,10 +2891,15 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, ...@@ -2891,10 +2891,15 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
thd->mem_root= &memex; thd->mem_root= &memex;
grant_version++; grant_version++;
while ((Str = str_list++)) while ((tmp_Str = str_list++))
{ {
int error; int error;
GRANT_TABLE *grant_table; GRANT_TABLE *grant_table;
if (!(Str= get_current_user(thd, tmp_Str)))
{
result= TRUE;
continue;
}
if (Str->host.length > HOSTNAME_LENGTH || if (Str->host.length > HOSTNAME_LENGTH ||
Str->user.length > USERNAME_LENGTH) Str->user.length > USERNAME_LENGTH)
{ {
...@@ -3030,7 +3035,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, ...@@ -3030,7 +3035,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
bool revoke_grant, bool no_error) bool revoke_grant, bool no_error)
{ {
List_iterator <LEX_USER> str_list (user_list); List_iterator <LEX_USER> str_list (user_list);
LEX_USER *Str; LEX_USER *Str, *tmp_Str;
TABLE_LIST tables[2]; TABLE_LIST tables[2];
bool create_new_users=0, result=0; bool create_new_users=0, result=0;
char *db_name, *table_name; char *db_name, *table_name;
...@@ -3098,10 +3103,15 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, ...@@ -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")); DBUG_PRINT("info",("now time to iterate and add users"));
while ((Str= str_list++)) while ((tmp_Str= str_list++))
{ {
int error; int error;
GRANT_NAME *grant_name; GRANT_NAME *grant_name;
if (!(Str= get_current_user(thd, tmp_Str)))
{
result= TRUE;
continue;
}
if (Str->host.length > HOSTNAME_LENGTH || if (Str->host.length > HOSTNAME_LENGTH ||
Str->user.length > USERNAME_LENGTH) Str->user.length > USERNAME_LENGTH)
{ {
...@@ -3170,7 +3180,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, ...@@ -3170,7 +3180,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
ulong rights, bool revoke_grant) ulong rights, bool revoke_grant)
{ {
List_iterator <LEX_USER> str_list (list); List_iterator <LEX_USER> str_list (list);
LEX_USER *Str; LEX_USER *Str, *tmp_Str;
char tmp_db[NAME_LEN+1]; char tmp_db[NAME_LEN+1];
bool create_new_users=0; bool create_new_users=0;
TABLE_LIST tables[2]; TABLE_LIST tables[2];
...@@ -3229,8 +3239,13 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, ...@@ -3229,8 +3239,13 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
grant_version++; grant_version++;
int result=0; 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 || if (Str->host.length > HOSTNAME_LENGTH ||
Str->user.length > USERNAME_LENGTH) Str->user.length > USERNAME_LENGTH)
{ {
...@@ -5187,7 +5202,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list) ...@@ -5187,7 +5202,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
int result; int result;
String wrong_users; String wrong_users;
ulong sql_mode; ulong sql_mode;
LEX_USER *user_name; LEX_USER *user_name, *tmp_user_name;
List_iterator <LEX_USER> user_list(list); List_iterator <LEX_USER> user_list(list);
TABLE_LIST tables[GRANT_TABLES]; TABLE_LIST tables[GRANT_TABLES];
DBUG_ENTER("mysql_create_user"); DBUG_ENTER("mysql_create_user");
...@@ -5199,8 +5214,13 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list) ...@@ -5199,8 +5214,13 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
rw_wrlock(&LOCK_grant); rw_wrlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock)); 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 Search all in-memory structures and grant tables
for a mention of the new user name. for a mention of the new user name.
...@@ -5246,7 +5266,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) ...@@ -5246,7 +5266,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
{ {
int result; int result;
String wrong_users; String wrong_users;
LEX_USER *user_name; LEX_USER *user_name, *tmp_user_name;
List_iterator <LEX_USER> user_list(list); List_iterator <LEX_USER> user_list(list);
TABLE_LIST tables[GRANT_TABLES]; TABLE_LIST tables[GRANT_TABLES];
DBUG_ENTER("mysql_drop_user"); DBUG_ENTER("mysql_drop_user");
...@@ -5258,8 +5278,14 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) ...@@ -5258,8 +5278,14 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
rw_wrlock(&LOCK_grant); rw_wrlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock)); 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) if (handle_grant_data(tables, 1, user_name, NULL) <= 0)
{ {
append_user(&wrong_users, user_name); append_user(&wrong_users, user_name);
...@@ -5296,8 +5322,8 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list) ...@@ -5296,8 +5322,8 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
{ {
int result; int result;
String wrong_users; String wrong_users;
LEX_USER *user_from; LEX_USER *user_from, *tmp_user_from;
LEX_USER *user_to; LEX_USER *user_to, *tmp_user_to;
List_iterator <LEX_USER> user_list(list); List_iterator <LEX_USER> user_list(list);
TABLE_LIST tables[GRANT_TABLES]; TABLE_LIST tables[GRANT_TABLES];
DBUG_ENTER("mysql_rename_user"); DBUG_ENTER("mysql_rename_user");
...@@ -5309,9 +5335,19 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list) ...@@ -5309,9 +5335,19 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
rw_wrlock(&LOCK_grant); rw_wrlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock)); 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. */ DBUG_ASSERT(user_to != 0); /* Syntax enforces pairs of users. */
/* /*
...@@ -5366,10 +5402,15 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) ...@@ -5366,10 +5402,15 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
rw_wrlock(&LOCK_grant); rw_wrlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock)); 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); 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)) 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 " sql_print_error("REVOKE ALL PRIVILEGES, GRANT: User '%s'@'%s' does not "
......
...@@ -3887,11 +3887,13 @@ end_with_restore_list: ...@@ -3887,11 +3887,13 @@ end_with_restore_list:
if (thd->security_ctx->user) // If not replication 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); 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 && if (specialflag & SPECIAL_NO_RESOLVE &&
hostname_requires_resolving(user->host.str)) hostname_requires_resolving(user->host.str))
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
...@@ -3973,12 +3975,16 @@ end_with_restore_list: ...@@ -3973,12 +3975,16 @@ end_with_restore_list:
if (lex->sql_command == SQLCOM_GRANT) if (lex->sql_command == SQLCOM_GRANT)
{ {
List_iterator <LEX_USER> str_list(lex->users_list); List_iterator <LEX_USER> str_list(lex->users_list);
LEX_USER *user; LEX_USER *user, *tmp_user;
while ((user=str_list++)) while ((tmp_user=str_list++))
{
if (!(user= get_current_user(thd, tmp_user)))
goto error;
reset_mqh(user); reset_mqh(user);
} }
} }
} }
}
break; break;
} }
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/ #endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
...@@ -4030,13 +4036,18 @@ end_with_restore_list: ...@@ -4030,13 +4036,18 @@ end_with_restore_list:
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
case SQLCOM_SHOW_GRANTS: 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 && 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)) !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; break;
}
#endif #endif
case SQLCOM_HA_OPEN: case SQLCOM_HA_OPEN:
DBUG_ASSERT(first_table == all_tables && first_table != 0); 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) ...@@ -7495,3 +7506,34 @@ LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
return definer; 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;
}
...@@ -6510,24 +6510,10 @@ show_param: ...@@ -6510,24 +6510,10 @@ show_param:
{ {
LEX *lex=Lex; LEX *lex=Lex;
lex->sql_command= SQLCOM_SHOW_GRANTS; lex->sql_command= SQLCOM_SHOW_GRANTS;
THD *thd= lex->thd;
Security_context *sctx= thd->security_ctx;
LEX_USER *curr_user; LEX_USER *curr_user;
if (!(curr_user= (LEX_USER*) thd->alloc(sizeof(st_lex_user)))) if (!(curr_user= (LEX_USER*) lex->thd->alloc(sizeof(st_lex_user))))
YYABORT; YYABORT;
curr_user->user.str= sctx->priv_user; bzero(curr_user, sizeof(st_lex_user));
curr_user->user.length= strlen(sctx->priv_user);
if (*sctx->priv_host != 0)
{
curr_user->host.str= sctx->priv_host;
curr_user->host.length= strlen(sctx->priv_host);
}
else
{
curr_user->host.str= (char *) "%";
curr_user->host.length= 1;
}
curr_user->password=null_lex_str;
lex->grant_user= curr_user; lex->grant_user= curr_user;
} }
| GRANTS FOR_SYM user | GRANTS FOR_SYM user
...@@ -7477,22 +7463,14 @@ user: ...@@ -7477,22 +7463,14 @@ user:
} }
| CURRENT_USER optional_braces | CURRENT_USER optional_braces
{ {
THD *thd= YYTHD; if (!($$=(LEX_USER*) YYTHD->alloc(sizeof(st_lex_user))))
Security_context *sctx= thd->security_ctx;
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
YYABORT; YYABORT;
$$->user.str= sctx->priv_user; /*
$$->user.length= strlen(sctx->priv_user); empty LEX_USER means current_user and
if (*sctx->priv_host != 0) will be handled in the get_current_user() function
{ later
$$->host.str= sctx->priv_host; */
$$->host.length= strlen(sctx->priv_host); bzero($$, sizeof(LEX_USER));
}
else
{
$$->host.str= (char *) "%";
$$->host.length= 1;
}
}; };
/* Keyword that we allow for identifiers (except SP labels) */ /* Keyword that we allow for identifiers (except SP labels) */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment