Commit 02a72919 authored by Sergei Golubchik's avatar Sergei Golubchik

cleanup

sql/sp.cc:
  don't split "user@host" string in db_load_routine, because the caller needs to
  generate it from user and host. instead pass user and host directly into db_load_routine
sql/sql_parse.cc:
  1. REVOKE ALL doesn't need invoker.
  2. make sp_process_definer() reusable
sql/sql_trigger.cc:
  don't duplicate the code from sp_process_definer(), reuse it
sql/sql_view.cc:
  don't duplicate the code from sp_process_definer(), reuse it
parent ac6877d4
......@@ -50,7 +50,8 @@ db_load_routine(THD *thd, stored_procedure_type type, sp_name *name,
sp_head **sphp,
ulonglong sql_mode, const char *params, const char *returns,
const char *body, st_sp_chistics &chistics,
const char *definer, longlong created, longlong modified,
LEX_STRING *definer_user_name, LEX_STRING *definer_host_name,
longlong created, longlong modified,
Stored_program_creation_ctx *creation_ctx);
static const
......@@ -548,6 +549,10 @@ db_find_routine(THD *thd, stored_procedure_type type, sp_name *name,
ulonglong sql_mode, saved_mode= thd->variables.sql_mode;
Open_tables_backup open_tables_state_backup;
Stored_program_creation_ctx *creation_ctx;
char definer_user_name_holder[USERNAME_LENGTH + 1];
LEX_STRING definer_user_name= { definer_user_name_holder, USERNAME_LENGTH };
char definer_host_name_holder[HOSTNAME_LENGTH + 1];
LEX_STRING definer_host_name= { definer_host_name_holder, HOSTNAME_LENGTH };
DBUG_ENTER("db_find_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s",
......@@ -657,9 +662,14 @@ db_find_routine(THD *thd, stored_procedure_type type, sp_name *name,
close_system_tables(thd, &open_tables_state_backup);
table= 0;
parse_user(definer, strlen(definer),
definer_user_name.str, &definer_user_name.length,
definer_host_name.str, &definer_host_name.length);
ret= db_load_routine(thd, type, name, sphp,
sql_mode, params, returns, body, chistics,
definer, created, modified, creation_ctx);
&definer_user_name, &definer_host_name,
created, modified, creation_ctx);
done:
/*
Restore the time zone flag as the timezone usage in proc table
......@@ -804,7 +814,8 @@ db_load_routine(THD *thd, stored_procedure_type type,
sp_name *name, sp_head **sphp,
ulonglong sql_mode, const char *params, const char *returns,
const char *body, st_sp_chistics &chistics,
const char *definer, longlong created, longlong modified,
LEX_STRING *definer_user_name, LEX_STRING *definer_host_name,
longlong created, longlong modified,
Stored_program_creation_ctx *creation_ctx)
{
LEX *old_lex= thd->lex, newlex;
......@@ -814,22 +825,12 @@ db_load_routine(THD *thd, stored_procedure_type type,
{ saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
bool cur_db_changed;
Bad_db_error_handler db_not_exists_handler;
char definer_user_name_holder[USERNAME_LENGTH + 1];
LEX_STRING definer_user_name= { definer_user_name_holder,
USERNAME_LENGTH };
char definer_host_name_holder[HOSTNAME_LENGTH + 1];
LEX_STRING definer_host_name= { definer_host_name_holder, HOSTNAME_LENGTH };
int ret= 0;
thd->lex= &newlex;
newlex.current_select= NULL;
parse_user(definer, strlen(definer),
definer_user_name.str, &definer_user_name.length,
definer_host_name.str, &definer_host_name.length);
defstr.set_charset(creation_ctx->get_client_cs());
/*
......@@ -845,7 +846,7 @@ db_load_routine(THD *thd, stored_procedure_type type,
params, strlen(params),
returns, strlen(returns),
body, strlen(body),
&chistics, &definer_user_name, &definer_host_name,
&chistics, definer_user_name, definer_host_name,
sql_mode))
{
ret= SP_INTERNAL_ERROR;
......@@ -895,7 +896,7 @@ db_load_routine(THD *thd, stored_procedure_type type,
goto end;
}
(*sphp)->set_definer(&definer_user_name, &definer_host_name);
(*sphp)->set_definer(definer_user_name, definer_host_name);
(*sphp)->set_info(created, modified, &chistics, sql_mode);
(*sphp)->set_creation_ctx(creation_ctx);
(*sphp)->optimize();
......@@ -1648,7 +1649,6 @@ sp_find_routine(THD *thd, stored_procedure_type type, sp_name *name,
ulong level;
sp_head *new_sp;
const char *returns= "";
char definer[USER_HOST_BUFF_SIZE];
/*
String buffer for RETURNS data type must have system charset;
......@@ -1685,8 +1685,6 @@ sp_find_routine(THD *thd, stored_procedure_type type, sp_name *name,
DBUG_RETURN(0);
}
strxmov(definer, sp->m_definer_user.str, "@",
sp->m_definer_host.str, NullS);
if (type == TYPE_ENUM_FUNCTION)
{
sp_returns_type(thd, retstr, sp);
......@@ -1694,7 +1692,8 @@ sp_find_routine(THD *thd, stored_procedure_type type, sp_name *name,
}
if (db_load_routine(thd, type, name, &new_sp,
sp->m_sql_mode, sp->m_params.str, returns,
sp->m_body.str, *sp->m_chistics, definer,
sp->m_body.str, *sp->m_chistics,
&sp->m_definer_user, &sp->m_definer_host,
sp->m_created, sp->m_modified,
sp->get_creation_ctx()) == SP_OK)
{
......
......@@ -189,6 +189,7 @@ LEX_STRING *default_auth_plugin_name= &native_password_plugin_name;
usernames. Example: userA -- userA@%
*/
LEX_STRING host_not_specified= { C_STRING_WITH_LEN("%") };
/*
Constant used in the SET ROLE NONE command
*/
......@@ -359,16 +360,14 @@ class ACL_PROXY_USER :public ACL_ACCESS
bool with_grant_arg)
{
user= (user_arg && *user_arg) ? user_arg : NULL;
update_hostname (&host,
(host_arg && *host_arg) ? host_arg : NULL);
update_hostname (&host, (host_arg && *host_arg) ? host_arg : NULL);
proxied_user= (proxied_user_arg && *proxied_user_arg) ?
proxied_user_arg : NULL;
update_hostname (&proxied_host,
(proxied_host_arg && *proxied_host_arg) ?
proxied_host_arg : NULL);
with_grant= with_grant_arg;
sort= get_sort(4, host.hostname, user,
proxied_host.hostname, proxied_user);
sort= get_sort(4, host.hostname, user, proxied_host.hostname, proxied_user);
}
void init(MEM_ROOT *mem, const char *host_arg, const char *user_arg,
......@@ -432,16 +431,9 @@ class ACL_PROXY_USER :public ACL_ACCESS
"compare_hostname(%s,%s,%s) &&"
"wild_compare (%s,%s) &&"
"wild_compare (%s,%s)",
host.hostname ? host.hostname : "<NULL>",
host_arg ? host_arg : "<NULL>",
ip_arg ? ip_arg : "<NULL>",
proxied_host.hostname ? proxied_host.hostname : "<NULL>",
host_arg ? host_arg : "<NULL>",
ip_arg ? ip_arg : "<NULL>",
user_arg ? user_arg : "<NULL>",
user ? user : "<NULL>",
proxied_user_arg ? proxied_user_arg : "<NULL>",
proxied_user ? proxied_user : "<NULL>"));
host.hostname, host_arg, ip_arg, proxied_host.hostname,
host_arg, ip_arg, user_arg, user,
proxied_user_arg, proxied_user));
DBUG_RETURN(compare_hostname(&host, host_arg, ip_arg) &&
compare_hostname(&proxied_host, host_arg, ip_arg) &&
(!user ||
......@@ -465,21 +457,16 @@ class ACL_PROXY_USER :public ACL_ACCESS
"strcmp(%s,%s) &&"
"wild_compare (%s,%s) &&"
"wild_compare (%s,%s)",
user ? user : "<NULL>",
grant->user ? grant->user : "<NULL>",
proxied_user ? proxied_user : "<NULL>",
grant->proxied_user ? grant->proxied_user : "<NULL>",
host.hostname ? host.hostname : "<NULL>",
grant->host.hostname ? grant->host.hostname : "<NULL>",
proxied_host.hostname ? proxied_host.hostname : "<NULL>",
grant->proxied_host.hostname ?
grant->proxied_host.hostname : "<NULL>"));
DBUG_RETURN(auth_element_equals(user, grant->user) &&
user, grant->user, proxied_user, grant->proxied_user,
host.hostname, grant->host.hostname,
proxied_host.hostname, grant->proxied_host.hostname));
bool res= auth_element_equals(user, grant->user) &&
auth_element_equals(proxied_user, grant->proxied_user) &&
auth_element_equals(host.hostname, grant->host.hostname) &&
auth_element_equals(proxied_host.hostname,
grant->proxied_host.hostname));
grant->proxied_host.hostname);
DBUG_RETURN(res);
}
......@@ -524,10 +511,8 @@ class ACL_PROXY_USER :public ACL_ACCESS
{
DBUG_ENTER("ACL_PROXY_USER::store_pk");
DBUG_PRINT("info", ("host=%s, user=%s, proxied_host=%s, proxied_user=%s",
host->str ? host->str : "<NULL>",
user->str ? user->str : "<NULL>",
proxied_host->str ? proxied_host->str : "<NULL>",
proxied_user->str ? proxied_user->str : "<NULL>"));
host->str, user->str,
proxied_host->str, proxied_user->str));
if (table->field[MYSQL_PROXIES_PRIV_HOST]->store(host->str,
host->length,
system_charset_info))
......@@ -5124,10 +5109,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
}
else if (tables[2].table)
{
if ((replace_column_table(grant_table, tables[2].table, *Str,
columns,
db_name, table_name,
rights, revoke_grant)))
if (replace_column_table(grant_table, tables[2].table, *Str, columns,
db_name, table_name, rights, revoke_grant))
{
result= TRUE;
}
......@@ -5744,11 +5727,9 @@ static my_bool grant_load_procs_priv(TABLE *p_table)
THR_MALLOC);
DBUG_ENTER("grant_load_procs_priv");
(void) my_hash_init(&proc_priv_hash, &my_charset_utf8_bin,
0,0,0, (my_hash_get_key) get_grant_table,
0,0);
0,0,0, (my_hash_get_key) get_grant_table, 0,0);
(void) my_hash_init(&func_priv_hash, &my_charset_utf8_bin,
0,0,0, (my_hash_get_key) get_grant_table,
0,0);
0,0,0, (my_hash_get_key) get_grant_table, 0,0);
if (p_table->file->ha_index_init(0, 1))
DBUG_RETURN(TRUE);
......@@ -7926,7 +7907,7 @@ static int modify_grant_table(TABLE *table, Field *host_field,
privileges, column privileges, function and procedures privileges
*/
void merge_role_grant_privileges(ACL_ROLE *target, ACL_ROLE *source)
static void merge_role_grant_privileges(ACL_ROLE *target, ACL_ROLE *source)
{
DBUG_ASSERT(source->flags & ROLE_GRANTS_FINAL);
......@@ -8110,8 +8091,7 @@ static int handle_roles_mappings_table(TABLE *table, bool drop,
Field *role_field= table->field[2];
DBUG_PRINT("info", ("Rewriting entry in roles_mappings table: %s@%s",
user_from->user.str,
user_from->host.str));
user_from->user.str, user_from->host.str));
table->use_all_columns();
if ((error= table->file->ha_rnd_init(1)))
{
......@@ -8199,6 +8179,8 @@ static int handle_roles_mappings_table(TABLE *table, bool drop,
2 tables_priv
3 columns_priv
4 procs_priv
5 proxies_priv
6 roles_mapping
RETURN
> 0 At least one record matched.
......@@ -8214,8 +8196,8 @@ static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop,
TABLE *table= tables[table_no].table;
Field *host_field= table->field[0];
Field *user_field= table->field[table_no && table_no != 5 ? 2 : 1];
char *host_str= user_from->host.str;
char *user_str= user_from->user.str;
const char *host_str= user_from->host.str;
const char *user_str= user_from->user.str;
const char *host;
const char *user;
uchar user_key[MAX_KEY_LENGTH];
......@@ -8366,9 +8348,9 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
int result= 0;
int idx;
int elements;
const char *user;
const char *host;
const char *role;
const char *UNINIT_VAR(user);
const char *UNINIT_VAR(host);
const char *UNINIT_VAR(role);
uint role_not_matched= 1;
ACL_USER *acl_user= NULL;
ACL_ROLE *acl_role= NULL;
......@@ -8382,16 +8364,16 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
DBUG_PRINT("info",("scan struct: %u search: '%s'@'%s'",
struct_no, user_from->user.str, user_from->host.str));
LINT_INIT(user);
LINT_INIT(host);
LINT_INIT(role);
mysql_mutex_assert_owner(&acl_cache->lock);
/* No point in querying ROLE ACL if the user_from is not a role */
/* No point in querying ROLE ACL if user_from is not a role */
if (struct_no == ROLE_ACL && user_from->host.length)
DBUG_RETURN(0);
/* same. no roles in PROXY_USERS_ACL */
if (struct_no == PROXY_USERS_ACL && !user_from->host.length)
DBUG_RETURN(0);
if (struct_no == ROLE_ACL) //no need to scan the structures in this case
{
acl_role= find_acl_role(user_from->user.str);
......@@ -10201,9 +10183,7 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
Security_context *sctx= thd->security_ctx;
DBUG_ENTER("fill_effective_table_privileges");
DBUG_PRINT("enter", ("Host: '%s', Ip: '%s', User: '%s', table: `%s`.`%s`",
sctx->priv_host, (sctx->ip ? sctx->ip : "(NULL)"),
(sctx->priv_user ? sctx->priv_user : "(NULL)"),
db, table));
sctx->priv_host, sctx->ip, sctx->priv_user, db, table));
/* --skip-grants */
if (!initialized)
{
......
......@@ -1804,7 +1804,6 @@ static void reset_one_shot_variables(THD *thd)
}
static
bool sp_process_definer(THD *thd)
{
DBUG_ENTER("sp_process_definer");
......@@ -3767,9 +3766,6 @@ case SQLCOM_PREPARE:
check_global_access(thd,CREATE_USER_ACL))
break;
/* Replicate current user as grantor */
thd->binlog_invoker();
/* Conditionally writes to binlog */
if (!(res = mysql_revoke_all(thd, lex->users_list)))
my_ok(thd);
......
......@@ -67,6 +67,7 @@ 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);
bool sp_process_definer(THD *thd);
bool check_string_byte_length(LEX_STRING *str, const char *err_msg,
uint max_byte_length);
bool check_string_char_length(LEX_STRING *str, const char *err_msg,
......
......@@ -663,46 +663,8 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
return 1;
}
if (!lex->definer)
{
/*
DEFINER-clause is missing.
If we are in slave thread, this means that we received CREATE TRIGGER
from the master, that does not support definer in triggers. So, we
should mark this trigger as non-SUID. Note that this does not happen
when we parse triggers' definitions during opening .TRG file.
LEX::definer is ignored in that case.
Otherwise, we should use CURRENT_USER() as definer.
NOTE: when CREATE TRIGGER statement is allowed to be executed in PS/SP,
it will be required to create the definer below in persistent MEM_ROOT
of PS/SP.
*/
if (!thd->slave_thread)
{
if (!(lex->definer= create_default_definer(thd)))
if (sp_process_definer(thd))
return 1;
}
}
/*
If the specified definer differs from the current user, we should check
that the current user has SUPER privilege (in order to create trigger
under another user one must have SUPER privilege).
*/
if (lex->definer &&
(strcmp(lex->definer->user.str, thd->security_ctx->priv_user) ||
my_strcasecmp(system_charset_info,
lex->definer->host.str,
thd->security_ctx->priv_host)))
{
if (check_global_access(thd, SUPER_ACL))
return TRUE;
}
/*
Let us check if all references to fields in old/new versions of row in
......@@ -794,20 +756,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
*trg_sql_mode= thd->variables.sql_mode;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (lex->definer && !is_acl_user(lex->definer->host.str,
lex->definer->user.str))
{
push_warning_printf(thd,
MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_NO_SUCH_USER,
ER(ER_NO_SUCH_USER),
lex->definer->user.str,
lex->definer->host.str);
}
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
if (lex->definer)
if (lex->sphead->m_chistics->suid != SP_IS_NOT_SUID)
{
/* SUID trigger. */
......@@ -854,7 +803,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
stmt_query->append(STRING_WITH_LEN("CREATE "));
if (trg_definer)
if (lex->sphead->m_chistics->suid != SP_IS_NOT_SUID)
{
/*
Append definer-clause if the trigger is SUID (a usual trigger in
......
......@@ -39,8 +39,7 @@
const LEX_STRING view_type= { C_STRING_WITH_LEN("VIEW") };
static int mysql_register_view(THD *thd, TABLE_LIST *view,
enum_view_create_mode mode);
static int mysql_register_view(THD *, TABLE_LIST *, enum_view_create_mode);
/*
Make a unique name for an anonymous view column
......@@ -466,60 +465,9 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
}
sp_cache_invalidate();
if (!lex->definer)
{
/*
DEFINER-clause is missing; we have to create default definer in
persistent arena to be PS/SP friendly.
If this is an ALTER VIEW then the current user should be set as
the definer.
*/
Query_arena original_arena;
Query_arena *ps_arena = thd->activate_stmt_arena_if_needed(&original_arena);
if (!(lex->definer= create_default_definer(thd)))
res= TRUE;
if (ps_arena)
thd->restore_active_arena(ps_arena, &original_arena);
if (res)
if (sp_process_definer(thd))
goto err;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/*
check definer of view:
- same as current user
- current user has SUPER_ACL
*/
if (lex->definer &&
(strcmp(lex->definer->user.str, thd->security_ctx->priv_user) != 0 ||
my_strcasecmp(system_charset_info,
lex->definer->host.str,
thd->security_ctx->priv_host) != 0))
{
if (!(thd->security_ctx->master_access & SUPER_ACL))
{
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
res= TRUE;
goto err;
}
else
{
if (!is_acl_user(lex->definer->host.str,
lex->definer->user.str))
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_NO_SUCH_USER,
ER(ER_NO_SUCH_USER),
lex->definer->user.str,
lex->definer->host.str);
}
}
}
#endif
/*
check that tables are not temporary and this VIEW do not used in query
(it is possible with ALTERing VIEW).
......@@ -1069,19 +1017,16 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
uint flags)
{
SELECT_LEX *end, *view_select;
SELECT_LEX *end, *UNINIT_VAR(view_select);
LEX *old_lex, *lex;
Query_arena *arena, backup;
TABLE_LIST *top_view= table->top_table();
bool parse_status;
bool UNINIT_VAR(parse_status);
bool result, view_is_mergeable;
TABLE_LIST *UNINIT_VAR(view_main_select_tables);
DBUG_ENTER("mysql_make_view");
DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name));
LINT_INIT(parse_status);
LINT_INIT(view_select);
if (table->view)
{
/*
......
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