From: Dmitry Lenev Date: March 26 2011 4:51pm Subject: bzr commit into mysql-trunk branch (Dmitry.Lenev:3533) Bug#11746602 List-Archive: http://lists.mysql.com/commits/133940 X-Bug: 11746602 Message-Id: <20110326165120.A179A7406EF@bandersnatch> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0764653737==" --===============0764653737== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/dlenev/src/bzr/mysql-trunk-bug27480/ based on revid:dmitry.lenev@stripped 3533 Dmitry Lenev 2011-03-26 A follow-up for the patch for Bug#11746602 (27480: Extend CREATE TEMPORARY TABLES privilege to allow temp table operations). After main patch for this bug additional check for privileges required for SHOW statements might require opening and closing of temporary tables. Since doing this from within check_table_access() function looks like a dangerous thing, the current patch moves this additional check outside of this function. To support this change it also removes some duplicated code. @ sql/sql_parse.cc - Moved code responsible for the first stage of checking privileges for SELECT statement (global, db and table-level privileges) to a separate function - select_precheck(). Adjusted code for select-like statements to use this function. - Got rid of duplicate code handling SHOW EVENTS and SHOW PROCEDURE/FUNCTION STATUS. As a side-effect of this change now these statements reset last_query_cost status variable like most of other SHOW statements. - Moved code which performs additional check for privileges required to perform SHOW statement from check_table_access() function to newly created select_precheck() function. Doing this privilege check, which might require opening and closing of temporary tables, inside of check_table_access() looks like a dangerous thing. - Got rid of redundant code in check_show_access() which automatically granted SELECT_ACL on I_S table for SHOW statement. This is already done for all I_S tables in IS_internal_schema_access::check() member function. @ sql/sql_parse.h Introduced select_precheck() function which performs first stage of privilege checking for SELECT statements. @ sql/sql_prepare.cc Code responsible for the first stage of checking privileges for SELECT statements (global, db and table-level privileges) has been moved to new function select_precheck(). modified: sql/sql_parse.cc sql/sql_parse.h sql/sql_prepare.cc === modified file 'sql/sql_parse.cc' --- a/sql/sql_parse.cc 2011-03-26 10:56:27 +0000 +++ b/sql/sql_parse.cc 2011-03-26 16:51:13 +0000 @@ -113,6 +113,7 @@ "FUNCTION" : "PROCEDURE") static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables); +static bool check_show_access(THD *thd, TABLE_LIST *table); static void sql_kill(THD *thd, ulong id, bool only_kill_query); static bool lock_tables_precheck(THD *thd, TABLE_LIST *tables); @@ -2109,25 +2110,14 @@ mysql_execute_command(THD *thd) switch (lex->sql_command) { - case SQLCOM_SHOW_EVENTS: -#ifndef HAVE_EVENT_SCHEDULER - my_error(ER_NOT_SUPPORTED_YET, MYF(0), "embedded server"); - break; -#endif - case SQLCOM_SHOW_STATUS_PROC: - case SQLCOM_SHOW_STATUS_FUNC: - if ((res= check_table_access(thd, SELECT_ACL, all_tables, FALSE, - UINT_MAX, FALSE))) - goto error; - res= execute_sqlcom_select(thd, all_tables); - break; case SQLCOM_SHOW_STATUS: { system_status_var old_status_var= thd->status_var; thd->initial_status_var= &old_status_var; - if (!(res= check_table_access(thd, SELECT_ACL, all_tables, FALSE, - UINT_MAX, FALSE))) + + if (!(res= select_precheck(thd, lex, all_tables, first_table))) res= execute_sqlcom_select(thd, all_tables); + /* Don't log SHOW STATUS commands to slow query log */ thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED); @@ -2142,6 +2132,13 @@ mysql_execute_command(THD *thd) mysql_mutex_unlock(&LOCK_status); break; } + case SQLCOM_SHOW_EVENTS: +#ifndef HAVE_EVENT_SCHEDULER + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "embedded server"); + break; +#endif + case SQLCOM_SHOW_STATUS_PROC: + case SQLCOM_SHOW_STATUS_FUNC: case SQLCOM_SHOW_DATABASES: case SQLCOM_SHOW_TABLES: case SQLCOM_SHOW_TRIGGERS: @@ -2159,21 +2156,7 @@ mysql_execute_command(THD *thd) { thd->status_var.last_query_cost= 0.0; - /* - lex->exchange != NULL implies SELECT .. INTO OUTFILE and this - requires FILE_ACL access. - */ - ulong privileges_requested= lex->exchange ? SELECT_ACL | FILE_ACL : - SELECT_ACL; - - if (all_tables) - res= check_table_access(thd, - privileges_requested, - all_tables, FALSE, UINT_MAX, FALSE); - else - res= check_access(thd, privileges_requested, any_db, NULL, NULL, 0, 0); - - if (res) + if ((res= select_precheck(thd, lex, all_tables, first_table))) break; res= execute_sqlcom_select(thd, all_tables); @@ -4937,20 +4920,19 @@ check_access(THD *thd, ulong want_access } +/** + Check if user has enough privileges for execution of SHOW statement, + which was converted to query to one of I_S tables. + + @param thd Thread context. + @param table Table list element for I_S table to be queried.. + + @retval FALSE - Success. + @retval TRUE - Failure. +*/ + static bool check_show_access(THD *thd, TABLE_LIST *table) { - /* - This is a SHOW command using an INFORMATION_SCHEMA table. - check_access() has not been called for 'table', - and SELECT is currently always granted on the I_S, so we automatically - grant SELECT on table here, to bypass a call to check_access(). - Note that not calling check_access(table) is an optimization, - which needs to be revisited if the INFORMATION_SCHEMA does - not always automatically grant SELECT but use the grant tables. - See Bug#38837 need a way to disable information_schema for security - */ - table->grant.privilege= SELECT_ACL; - switch (get_schema_table_idx(table->schema_table)) { case SCH_SCHEMATA: return (specialflag & SPECIAL_SKIP_SHOW_DB) && @@ -5088,13 +5070,6 @@ check_table_access(THD *thd, ulong requi */ tables->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL); - if (tables->schema_table_reformed) - { - if (check_show_access(thd, tables)) - goto deny; - continue; - } - DBUG_PRINT("info", ("derived: %d view: %d", tables->derived != 0, tables->view != 0)); @@ -5223,6 +5198,13 @@ bool check_some_access(THD *thd, ulong w DBUG_RETURN(1); } +#else + +static bool check_show_access(THD *thd, TABLE_LIST *table) +{ + return false; +} + #endif /*NO_EMBEDDED_ACCESS_CHECKS*/ @@ -6672,6 +6654,45 @@ Item * all_any_subquery_creator(Item *le /** + Perform first stage of privilege checking for SELECT statement. + + @param thd Thread context. + @param lex LEX for SELECT statement. + @param tables List of tables used by statement. + @param first_table First table in the main SELECT of the SELECT + statement. + + @retval FALSE - Success (column-level privilege checks might be required). + @retval TRUE - Failure, privileges are insufficient. +*/ + +bool select_precheck(THD *thd, LEX *lex, TABLE_LIST *tables, + TABLE_LIST *first_table) +{ + bool res; + /* + lex->exchange != NULL implies SELECT .. INTO OUTFILE and this + requires FILE_ACL access. + */ + ulong privileges_requested= lex->exchange ? SELECT_ACL | FILE_ACL : + SELECT_ACL; + + if (tables) + { + res= check_table_access(thd, + privileges_requested, + tables, FALSE, UINT_MAX, FALSE) || + (first_table && first_table->schema_table_reformed && + check_show_access(thd, first_table)); + } + else + res= check_access(thd, privileges_requested, any_db, NULL, NULL, 0, 0); + + return res; +} + + +/** Multi update query pre-check. @param thd Thread handler === modified file 'sql/sql_parse.h' --- a/sql/sql_parse.h 2011-02-18 09:56:51 +0000 +++ b/sql/sql_parse.h 2011-03-26 16:51:13 +0000 @@ -35,6 +35,8 @@ enum enum_mysql_completiontype { extern "C" int test_if_data_home_dir(const char *dir); +bool select_precheck(THD *thd, LEX *lex, TABLE_LIST *tables, + TABLE_LIST *first_table); bool multi_update_precheck(THD *thd, TABLE_LIST *tables); bool multi_delete_precheck(THD *thd, TABLE_LIST *tables); int mysql_multi_update_prepare(THD *thd); === modified file 'sql/sql_prepare.cc' --- a/sql/sql_prepare.cc 2011-03-26 10:56:27 +0000 +++ b/sql/sql_prepare.cc 2011-03-26 16:51:13 +0000 @@ -1457,13 +1457,7 @@ static int mysql_test_select(Prepared_st lex->select_lex.context.resolve_in_select_list= TRUE; - ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL; - if (tables) - { - if (check_table_access(thd, privilege, tables, FALSE, UINT_MAX, FALSE)) - goto error; - } - else if (check_access(thd, privilege, any_db, NULL, NULL, 0, 0)) + if (select_precheck(thd, lex, tables, lex->select_lex.table_list.first)) goto error; if (!lex->result && !(lex->result= new (stmt->mem_root) select_send)) --===============0764653737== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/dmitry.lenev@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: dmitry.lenev@stripped # target_branch: file:///home/dlenev/src/bzr/mysql-trunk-bug27480/ # testament_sha1: b49c567ab43217086f26b8a35b1dcdb721293989 # timestamp: 2011-03-26 19:51:20 +0300 # base_revision_id: dmitry.lenev@stripped\ # xizjmzr2ijakdoub # # Begin bundle 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 --===============0764653737==--