diff options
-rw-r--r-- | sql/sp.cc | 37 | ||||
-rw-r--r-- | sql/sql_acl.cc | 92 | ||||
-rw-r--r-- | sql/sql_parse.cc | 4 | ||||
-rw-r--r-- | sql/sql_parse.h | 1 | ||||
-rw-r--r-- | sql/sql_trigger.cc | 59 | ||||
-rw-r--r-- | sql/sql_view.cc | 65 |
6 files changed, 64 insertions, 194 deletions
diff --git a/sql/sp.cc b/sql/sp.cc index 56565f1d11e..ca0cd553716 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -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) { diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 3179d853a87..d6f1c7f01a2 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -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 @@ public: 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 @@ public: "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 @@ public: "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>")); + user, grant->user, proxied_user, grant->proxied_user, + host.hostname, grant->host.hostname, + proxied_host.hostname, grant->proxied_host.hostname)); - DBUG_RETURN(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)); + 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); + DBUG_RETURN(res); } @@ -524,10 +511,8 @@ public: { 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) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e414921765d..3ac90ea2b7c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -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 @@ end_with_restore_list: 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); diff --git a/sql/sql_parse.h b/sql/sql_parse.h index 25c41cc624c..c87e290119e 100644 --- a/sql/sql_parse.h +++ b/sql/sql_parse.h @@ -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, diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 022c4ff4ea5..e0898740047 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -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))) - 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; - } + if (sp_process_definer(thd)) + return 1; /* 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 diff --git a/sql/sql_view.cc b/sql/sql_view.cc index a4bf0ed63d0..65151d503a4 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -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 (sp_process_definer(thd)) + goto err; - 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) - 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 @@ err: 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) { /* |