mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Bug#15298 SHOW GRANTS FOR CURRENT_USER: Incorrect output in DEFINER context
user name is calculated on function execution stage instead of parse stage
This commit is contained in:
@ -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|
|
|||||||
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,
|
|||||||
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,
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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++))
|
||||||
{
|
{
|
||||||
user_to= 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)))
|
||||||
|
{
|
||||||
|
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)
|
|||||||
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:
|
|||||||
|
|
||||||
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,9 +3975,13 @@ 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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)
|
|||||||
|
|
||||||
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:
|
|||||||
{
|
{
|
||||||
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:
|
|||||||
}
|
}
|
||||||
| 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) */
|
||||||
|
Reference in New Issue
Block a user