diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index cd8587f0230..86fc04b3622 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -457,7 +457,7 @@ bool check_procedure_access(THD *thd,ulong want_access,char *db,char *name, bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table); bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list); -bool check_some_routine_access(THD *thd, char *db, char *name); +bool check_some_routine_access(THD *thd, const char *db, const char *name); bool multi_update_precheck(THD *thd, TABLE_LIST *tables); bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count); bool mysql_multi_update_prepare(THD *thd); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 2097e55d4e3..89c4b2dbaac 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1016,23 +1016,31 @@ sp_head::restore_thd_mem_root(THD *thd) } -bool check_show_routine_acceess(THD *thd, sp_head *sp, bool *full_access) +/* + Check if a user has access right to a routine + + SYNOPSIS + check_show_routine_access() + thd Thread handler + sp SP + full_access Set to 1 if the user has SELECT right to the + 'mysql.proc' able or is the owner of the routine + RETURN + 0 ok + 1 error +*/ + +bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access) { TABLE_LIST tables; bzero((char*) &tables,sizeof(tables)); tables.db= (char*) "mysql"; tables.table_name= tables.alias= (char*) "proc"; - *full_access= !check_table_access(thd, SELECT_ACL, &tables, 1); - if (!(*full_access)) - *full_access= (!strcmp(sp->m_definer_user.str, thd->priv_user) && - !strcmp(sp->m_definer_host.str, thd->priv_host)); - if (!(*full_access)) - { -#ifndef NO_EMBEDDED_ACCESS_CHECKS - return check_some_routine_access(thd, (char * )sp->m_db.str, - (char * ) sp->m_name.str); -#endif - } + *full_access= (!check_table_access(thd, SELECT_ACL, &tables, 1) || + (!strcmp(sp->m_definer_user.str, thd->priv_user) && + !strcmp(sp->m_definer_host.str, thd->priv_host))); + if (!*full_access) + return check_some_routine_access(thd, sp->m_db.str, sp->m_name.str); return 0; } @@ -1056,7 +1064,7 @@ sp_head::show_create_procedure(THD *thd) LINT_INIT(sql_mode_str); LINT_INIT(sql_mode_len); - if (check_show_routine_acceess(thd, this, &full_access)) + if (check_show_routine_access(thd, this, &full_access)) return 1; old_sql_mode= thd->variables.sql_mode; @@ -1129,7 +1137,7 @@ sp_head::show_create_function(THD *thd) LINT_INIT(sql_mode_str); LINT_INIT(sql_mode_len); - if (check_show_routine_acceess(thd, this, &full_access)) + if (check_show_routine_access(thd, this, &full_access)) return 1; old_sql_mode= thd->variables.sql_mode; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 3db219b5fdc..3759840d3bb 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2125,7 +2125,7 @@ static GRANT_NAME *name_hash_search(HASH *name_hash, inline GRANT_NAME * proc_hash_search(const char *host, const char *ip, const char *db, - const char *user, const char *tname, bool exact) + const char *user, const char *tname, bool exact) { return (GRANT_TABLE*) name_hash_search(&proc_priv_hash, host, ip, db, user, tname, exact); @@ -3594,11 +3594,11 @@ err: name Routine name RETURN - 1 error 0 Ok + 1 error */ -bool check_routine_level_acl(THD *thd, char *db, char *name) +bool check_routine_level_acl(THD *thd, const char *db, const char *name) { bool no_routine_acl= 1; if (grant_option) @@ -5570,4 +5570,16 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant, grant->privilege|= grant->grant_table->privs; } } + +#else /* NO_EMBEDDED_ACCESS_CHECKS */ + +/**************************************************************************** + Dummy wrappers when we don't have any access checks +****************************************************************************/ + +bool check_routine_level_acl(THD *thd, const char *db, const char *name) +{ + return FALSE; +} + #endif diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 30e335c7afd..24916fd4385 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -219,7 +219,7 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant, const char *db, const char *table); bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name); bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name); -bool check_routine_level_acl(THD *thd, char *db, char *name); +bool check_routine_level_acl(THD *thd, const char *db, const char *name); #ifdef NO_EMBEDDED_ACCESS_CHECKS #define check_grant(A,B,C,D,E,F) 0 diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d5ed8c8efb0..c1793f0b026 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4760,7 +4760,7 @@ check_procedure_access(THD *thd, ulong want_access,char *db, char *name, 1 error */ -bool check_some_routine_access(THD *thd, char *db, char *name) +bool check_some_routine_access(THD *thd, const char *db, const char *name) { ulong save_priv; if (thd->master_access & SHOW_PROC_ACLS) @@ -4768,12 +4768,7 @@ bool check_some_routine_access(THD *thd, char *db, char *name) if (!check_access(thd, SHOW_PROC_ACLS, db, &save_priv, 0, 1) || (save_priv & SHOW_PROC_ACLS)) return FALSE; -#ifndef NO_EMBEDDED_ACCESS_CHECKS - if (grant_option) - return check_routine_level_acl(thd, db, name); -#endif - - return FALSE; + return check_routine_level_acl(thd, db, name); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 277c9970595..162e5b887ab 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4987,7 +4987,7 @@ bool store_val_in_field(Field *field,Item *item) { bool error; - THD *thd=current_thd; + THD *thd= field->table->in_use; ha_rows cuted_fields=thd->cuted_fields; /* we should restore old value of count_cuted_fields because @@ -5182,6 +5182,7 @@ make_outerjoin_info(JOIN *join) static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) { + THD *thd= join->thd; DBUG_ENTER("make_join_select"); if (select) { @@ -5191,8 +5192,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) if (join->tables > 1) cond->update_used_tables(); // Tablenr may have changed if (join->const_tables == join->tables && - join->thd->lex->current_select->master_unit() == - &join->thd->lex->unit) // not upper level SELECT + thd->lex->current_select->master_unit() == + &thd->lex->unit) // not upper level SELECT join->const_table_map|=RAND_TABLE_BIT; { // Check const tables COND *const_cond= @@ -5288,7 +5289,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) { DBUG_EXECUTE("where",print_where(tmp,tab->table->alias);); SQL_SELECT *sel=tab->select=(SQL_SELECT*) - join->thd->memdup((gptr) select, sizeof(SQL_SELECT)); + thd->memdup((gptr) select, sizeof(SQL_SELECT)); if (!sel) DBUG_RETURN(1); // End of memory /* @@ -5298,14 +5299,15 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) the first match for outer tables is encountered. */ if (cond) - {/* + { + /* Because of QUICK_GROUP_MIN_MAX_SELECT there may be a select without a cond, so neutralize the hack above. */ if (!(tmp= add_found_match_trig_cond(first_inner_tab, tmp, 0))) DBUG_RETURN(1); tab->select_cond=sel->cond=tmp; - if (join->thd->variables.engine_condition_pushdown) + if (thd->variables.engine_condition_pushdown) { tab->table->file->pushed_cond= NULL; /* Push condition to handler */ @@ -5375,7 +5377,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) if (sel->cond && !sel->cond->fixed) sel->cond->quick_fix_field(); - if (sel->test_quick_select(join->thd, tab->keys, + if (sel->test_quick_select(thd, tab->keys, used_tables & ~ current_map, (join->select_options & OPTION_FOUND_ROWS ? @@ -5388,7 +5390,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) */ sel->cond=orig_cond; if (!*tab->on_expr_ref || - sel->test_quick_select(join->thd, tab->keys, + sel->test_quick_select(thd, tab->keys, used_tables & ~ current_map, (join->select_options & OPTION_FOUND_ROWS ? @@ -5430,10 +5432,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) { DBUG_EXECUTE("where",print_where(tmp,"cache");); tab->cache.select=(SQL_SELECT*) - join->thd->memdup((gptr) sel, sizeof(SQL_SELECT)); + thd->memdup((gptr) sel, sizeof(SQL_SELECT)); tab->cache.select->cond=tmp; tab->cache.select->read_tables=join->const_table_map; - if (join->thd->variables.engine_condition_pushdown && + if (thd->variables.engine_condition_pushdown && (!tab->table->file->pushed_cond)) { /* Push condition to handler */ @@ -5443,7 +5445,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) } } } - } + } /* Push down all predicates from on expressions. @@ -11909,7 +11911,7 @@ calc_group_buffer(JOIN *join,ORDER *group) { /* This case should never be choosen */ DBUG_ASSERT(0); - current_thd->fatal_error(); + join->thd->fatal_error(); } parts++; if ((*group->item)->maybe_null) @@ -13237,6 +13239,7 @@ void st_table_list::print(THD *thd, String *str) void st_select_lex::print(THD *thd, String *str) { + /* QQ: thd may not be set for sub queries, but this should be fixed */ if (!thd) thd= current_thd; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 4ffe7110cfa..79526808aec 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2481,13 +2481,8 @@ void store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, definer= get_field(thd->mem_root, proc_table->field[11]); if (!full_access) full_access= !strcmp(sp_user, definer); - if (!full_access) - { -#ifndef NO_EMBEDDED_ACCESS_CHECKS - if (check_some_routine_access(thd, (char * )sp_db, (char * )sp_name)) - return; -#endif - } + if (!full_access && check_some_routine_access(thd, sp_db, sp_name)) + return; if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC && proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE || @@ -2499,36 +2494,30 @@ void store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, if (!wild || !wild[0] || !wild_compare(sp_name, wild, 0)) { table->field[3]->store(sp_name, strlen(sp_name), cs); - tmp_string.length(0); get_field(thd->mem_root, proc_table->field[3], &tmp_string); table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs); table->field[2]->store(sp_db, strlen(sp_db), cs); - tmp_string.length(0); get_field(thd->mem_root, proc_table->field[2], &tmp_string); table->field[4]->store(tmp_string.ptr(), tmp_string.length(), cs); if (proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION) { - tmp_string.length(0); get_field(thd->mem_root, proc_table->field[9], &tmp_string); table->field[5]->store(tmp_string.ptr(), tmp_string.length(), cs); table->field[5]->set_notnull(); } if (full_access) { - tmp_string.length(0); get_field(thd->mem_root, proc_table->field[10], &tmp_string); table->field[7]->store(tmp_string.ptr(), tmp_string.length(), cs); } table->field[6]->store("SQL", 3, cs); table->field[10]->store("SQL", 3, cs); - tmp_string.length(0); get_field(thd->mem_root, proc_table->field[6], &tmp_string); table->field[11]->store(tmp_string.ptr(), tmp_string.length(), cs); if (proc_table->field[5]->val_int() == SP_CONTAINS_SQL) { table->field[12]->store("CONTAINS SQL", 12 , cs); } - tmp_string.length(0); get_field(thd->mem_root, proc_table->field[7], &tmp_string); table->field[14]->store(tmp_string.ptr(), tmp_string.length(), cs); bzero((char *)&time, sizeof(time)); @@ -2537,10 +2526,8 @@ void store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, bzero((char *)&time, sizeof(time)); ((Field_timestamp *) proc_table->field[13])->get_time(&time); table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); - tmp_string.length(0); get_field(thd->mem_root, proc_table->field[14], &tmp_string); table->field[17]->store(tmp_string.ptr(), tmp_string.length(), cs); - tmp_string.length(0); get_field(thd->mem_root, proc_table->field[15], &tmp_string); table->field[18]->store(tmp_string.ptr(), tmp_string.length(), cs); table->field[19]->store(definer, strlen(definer), cs); diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 1d14d037c47..3340c46bb6b 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -110,15 +110,15 @@ static char *init_syms(udf_func *tmp, char *nm) */ if (!tmp->func_init && !tmp->func_deinit && tmp->type != UDFTYPE_AGGREGATE) { - if (opt_allow_suspicious_udfs) - sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), nm); - else + if (!opt_allow_suspicious_udfs) return nm; + if (current_thd->variables.log_warnings) + sql_print_warning(ER(ER_CANT_FIND_DL_ENTRY), nm); } - return 0; } + extern "C" byte* get_hash_key(const byte *buff,uint *length, my_bool not_used __attribute__((unused))) { @@ -127,9 +127,10 @@ extern "C" byte* get_hash_key(const byte *buff,uint *length, return (byte*) udf->name.str; } + /* -** Read all predeclared functions from mysql.func and accept all that -** can be used. + Read all predeclared functions from mysql.func and accept all that + can be used. */ void udf_init() diff --git a/sql/table.cc b/sql/table.cc index 63da10c687a..939690395d4 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1390,8 +1390,12 @@ bool get_field(MEM_ROOT *mem, Field *field, String *res) field->val_str(&str); if (!(length= str.length())) + { + res->length(0); return 1; - to= strmake_root(mem, str.ptr(), length); + } + if (!(to= strmake_root(mem, str.ptr(), length))) + length= 0; // Safety fix res->set(to, length, ((Field_str*)field)->charset()); return 0; }