Commit 06e16b8c authored by Sergei Golubchik's avatar Sergei Golubchik

cannot use lex->grant_user= &current_user, where LEX_USER current_user is a global constant,

because parser might modify the lex->user (e.g. set lex->user-password).
switch to use LEX_STRING current_user string, and also change other similar constants
to be LEX_STRING's for consistency.
parent cdb55102
......@@ -61,9 +61,9 @@ GRANT test_role1 TO 'test_user'@'localhost'
GRANT test_role2 TO 'test_user'@'localhost'
show grants for test_user@localhost;
Grants for test_user@localhost
GRANT test_role2 TO 'test_user'@'localhost'
GRANT test_role1 TO 'test_user'@'localhost'
GRANT USAGE ON *.* TO 'test_user'@'localhost'
GRANT test_role1 TO 'test_user'@'localhost'
GRANT test_role2 TO 'test_user'@'localhost'
show grants for test_role1;
ERROR 42000: Access denied for user 'test_user'@'localhost' to database 'mysql'
show grants for test_role2;
......
......@@ -40,6 +40,7 @@ select current_user(), current_role();
--sorted_result
show grants;
--sorted_result
show grants for test_user@localhost;
--error ER_DBACCESS_DENIED_ERROR
show grants for test_role1;
......
......@@ -2345,9 +2345,16 @@ bool Item_func_current_role::fix_fields(THD *thd, Item **ref)
Security_context *ctx= context->security_ctx
? context->security_ctx : thd->security_ctx;
const char *role= ctx->priv_role[0] ? ctx->priv_role : NONE_ROLE;
LEX_STRING role;
if (ctx->priv_role[0])
{
role.str= ctx->priv_role;
role.length= strlen(role.str);
}
else
role= none_role;
if (str_value.copy(role, strlen(role), system_charset_info))
if (str_value.copy(role.str, role.length, system_charset_info))
return 1;
str_value.mark_as_const();
......
......@@ -841,12 +841,9 @@ int set_var_password::check(THD *thd)
user->host.length= strlen(thd->security_ctx->priv_host);
}
else
{
user->host.str= (char *)"%";
user->host.length= 1;
}
user->host= host_not_specified;
}
if (!user->user.str)
if (user->user.str == current_user.str)
{
DBUG_ASSERT(thd->security_ctx->user);
user->user.str= (char *) thd->security_ctx->user;
......
......@@ -188,17 +188,19 @@ LEX_STRING *default_auth_plugin_name= &native_password_plugin_name;
Constant used for differentiating specified user names and non specified
usernames. Example: userA -- userA@%
*/
const char *HOST_NOT_SPECIFIED= "%";
LEX_STRING host_not_specified= { C_STRING_WITH_LEN("%") };
/*
Constant used in the SET ROLE NONE command
*/
const char *NONE_ROLE= "NONE";
LEX_STRING none_role= { C_STRING_WITH_LEN("NONE") };
/*
Constants, used in the SHOW GRANTS command
Constants, used in the SHOW GRANTS command.
Their actual string values are irrelevant, they're always compared
as pointers to these string constants.
*/
LEX_USER current_user;
LEX_USER current_role;
LEX_USER current_user_and_current_role;
LEX_STRING current_user= { C_STRING_WITH_LEN("*current_user") };
LEX_STRING current_role= { C_STRING_WITH_LEN("*current_role") };
LEX_STRING current_user_and_current_role= { C_STRING_WITH_LEN("*current_user_and_current_role") };
#ifndef NO_EMBEDDED_ACCESS_CHECKS
......@@ -5178,7 +5180,7 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list)
List_iterator <LEX_USER> user_list(list);
granted_role= user_list++;
if (granted_role == &current_role)
if (granted_role->user.str == current_role.str)
{
rolename= thd->security_ctx->priv_role;
if (!rolename[0])
......@@ -5206,7 +5208,7 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list)
{
handle_as_role= FALSE;
/* current_role is treated slightly different */
if (user == &current_role)
if (user->user.str == current_role.str)
{
handle_as_role= TRUE;
/* current_role is NONE */
......@@ -5223,7 +5225,7 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list)
continue;
}
/* can not grant current_role to current_role */
if (granted_role == &current_role)
if (granted_role->user.str == current_role.str)
{
append_user(&wrong_users, thd->security_ctx->priv_role, "", TRUE);
result= 1;
......@@ -5236,7 +5238,7 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list)
{
username= user->user.str;
hostname= user->host.str;
if (hostname == HOST_NOT_SPECIFIED)
if (user->host.str == host_not_specified.str)
{
if ((role_as_user= find_acl_role(username)))
{
......@@ -5388,7 +5390,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
They did GRANT ... TO CURRENT_USER() IDENTIFIED BY ... !
Get the current user, and shallow-copy the new password to them!
*/
if (!tmp_Str->user.str && tmp_Str->password.str)
if (tmp_Str->user.str == current_user.str && tmp_Str->password.str)
Str->password= tmp_Str->password;
if (replace_user_table(thd, tables[0].table, *Str,
(!db ? rights : 0), revoke_grant, create_new_users,
......@@ -6708,23 +6710,24 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user)
mysql_rwlock_rdlock(&LOCK_grant);
mysql_mutex_lock(&acl_cache->lock);
if (lex_user == &current_user || lex_user == &current_role ||
lex_user == &current_user_and_current_role)
if (lex_user->user.str == current_user.str ||
lex_user->user.str == current_role.str ||
lex_user->user.str == current_user_and_current_role.str)
{
username= thd->security_ctx->priv_user;
hostname= thd->security_ctx->priv_host;
rolename= thd->security_ctx->priv_role;
}
if (lex_user == &current_user)
if (lex_user->user.str == current_user.str)
{
print_user_entry= TRUE;
}
else if (lex_user == &current_role)
else if (lex_user->user.str == current_role.str)
{
print_role_entry= TRUE;
}
else if (lex_user == &current_user_and_current_role)
else if (lex_user->user.str == current_user_and_current_role.str)
{
print_user_entry= TRUE;
print_role_entry= TRUE;
......@@ -6732,7 +6735,7 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user)
else
{
/* this lex_user could represent a role */
if (lex_user->host.str == HOST_NOT_SPECIFIED &&
if (lex_user->host.str == host_not_specified.str &&
find_acl_role(lex_user->user.str))
{
rolename= lex_user->user.str;
......@@ -6854,7 +6857,7 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user)
}
else
{
if (lex_user == &current_role)
if (lex_user->user.str == current_role.str)
{
mysql_mutex_unlock(&acl_cache->lock);
mysql_rwlock_unlock(&LOCK_grant);
......
......@@ -173,11 +173,11 @@ enum mysql_db_table_field
extern const TABLE_FIELD_DEF mysql_db_table_def;
extern bool mysql_user_table_is_in_short_password_format;
extern const char *HOST_NOT_SPECIFIED;
extern const char *NONE_ROLE;
extern LEX_USER current_user;
extern LEX_USER current_role;
extern LEX_USER current_user_and_current_role;
extern LEX_STRING host_not_specified;
extern LEX_STRING none_role;
extern LEX_STRING current_user;
extern LEX_STRING current_role;
extern LEX_STRING current_user_and_current_role;
static inline int access_denied_error_code(int passwd_used)
......
......@@ -4004,11 +4004,11 @@ case SQLCOM_PREPARE:
if (grant_user->user.str &&
!strcmp(thd->security_ctx->priv_user, grant_user->user.str))
grant_user= &current_user;
grant_user->user= current_user;
if (grant_user == &current_user ||
grant_user == &current_role ||
grant_user == &current_user_and_current_role ||
if (grant_user->user.str == current_user.str ||
grant_user->user.str == current_role.str ||
grant_user->user.str == current_user_and_current_role.str ||
!check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 0))
{
res = mysql_show_grants(thd, grant_user);
......@@ -7757,7 +7757,7 @@ LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
LEX_USER *get_current_user(THD *thd, LEX_USER *user)
{
if (user == &current_user) // current_user
if (user->user.str == current_user.str) // current_user
return create_default_definer(thd);
return user;
......
......@@ -1570,7 +1570,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <symbol> keyword keyword_sp
%type <lex_user> user grant_user grant_role user_or_role
%type <lex_user> user grant_user grant_role user_or_role current_role
%type <charset>
opt_collate
......@@ -11766,22 +11766,16 @@ show_param:
}
| GRANTS
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_SHOW_GRANTS;
lex->grant_user= &current_user_and_current_role;
Lex->sql_command= SQLCOM_SHOW_GRANTS;
if (!(Lex->grant_user= (LEX_USER*)thd->alloc(sizeof(LEX_USER))))
MYSQL_YYABORT;
Lex->grant_user->user= current_user_and_current_role;
}
| GRANTS FOR_SYM user
| GRANTS FOR_SYM user_or_role
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_SHOW_GRANTS;
lex->grant_user=$3;
lex->grant_user->password=null_lex_str;
}
| GRANTS FOR_SYM CURRENT_ROLE optional_braces
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_SHOW_GRANTS;
lex->grant_user= &current_role;
}
| CREATE DATABASE opt_if_not_exists ident
{
......@@ -13179,8 +13173,7 @@ user:
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
MYSQL_YYABORT;
$$->user = $1;
$$->host.str= (char *)HOST_NOT_SPECIFIED;
$$->host.length= 1;
$$->host= host_not_specified;
$$->password= null_lex_str;
$$->plugin= empty_lex_str;
$$->auth= empty_lex_str;
......@@ -13213,19 +13206,13 @@ user:
}
| CURRENT_USER optional_braces
{
$$= &current_user;
if (!($$=(LEX_USER*)thd->calloc(sizeof(LEX_USER))))
MYSQL_YYABORT;
$$->user= current_user;
}
;
user_or_role:
user
{
$$=$1;
}
| CURRENT_ROLE optional_braces
{
$$= &current_role;
}
user_or_role: user | current_role;
/* Keyword that we allow for identifiers (except SP labels) */
keyword:
......@@ -14337,14 +14324,22 @@ role_list:
}
;
current_role:
CURRENT_ROLE optional_braces
{
if (!($$=(LEX_USER*) thd->alloc(sizeof(LEX_USER))))
MYSQL_YYABORT;
$$->user= current_role;
}
;
grant_role:
ident_or_text
{
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
MYSQL_YYABORT;
$$->user = $1;
$$->host.str= (char *)HOST_NOT_SPECIFIED;
$$->host.length= 1;
$$->host= host_not_specified;
$$->password= null_lex_str;
$$->plugin= empty_lex_str;
$$->auth= empty_lex_str;
......@@ -14354,10 +14349,7 @@ grant_role:
system_charset_info, 0))
MYSQL_YYABORT;
}
| CURRENT_ROLE optional_braces
{
$$=&current_role;
}
| current_role
;
opt_table:
......
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