diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2020-11-01 14:26:15 +0100 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2020-11-01 14:26:15 +0100 |
commit | 8e1e2856f2523c225a81840059e93fa9f61fbacf (patch) | |
tree | f1c708faf5aaeb27f255531d8c0f9dac32833b5b /sql/sql_parse.cc | |
parent | b0ff791618d97487fb7515d3f785b37f46eba132 (diff) | |
parent | 80c951ce2875aac521b82323b5b6ebf638593445 (diff) | |
download | mariadb-git-8e1e2856f2523c225a81840059e93fa9f61fbacf.tar.gz |
Merge branch '10.4' into 10.5
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r-- | sql/sql_parse.cc | 64 |
1 files changed, 46 insertions, 18 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3d43305431b..a364097931e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -98,6 +98,8 @@ #include "my_json_writer.h" +#define PRIV_LOCK_TABLES (SELECT_ACL | LOCK_TABLES_ACL) + #define FLAGSTR(V,F) ((V)&(F)?#F" ":"") #ifdef WITH_ARIA_STORAGE_ENGINE @@ -1097,7 +1099,6 @@ int bootstrap(MYSQL_FILE *file) thd->reset_kill_query(); /* Ensure that killed_errmsg is released */ free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); - thd->transaction->free(); thd->lex->restore_set_statement_var(); } delete thd; @@ -2977,6 +2978,36 @@ retry: goto err; } } + /* + Check privileges of view tables here, after views were opened. + Either definer or invoker has to have PRIV_LOCK_TABLES to be able + to lock view and its tables. For mysqldump (that locks views + before dumping their structures) compatibility we allow locking + views that select from I_S or P_S tables, but downrade the lock + to TL_READ + */ + if (table->belong_to_view && + check_single_table_access(thd, PRIV_LOCK_TABLES, table, 1)) + { + if (table->grant.m_internal.m_schema_access) + table->lock_type= TL_READ; + else + { + bool error= true; + if (Security_context *sctx= table->security_ctx) + { + table->security_ctx= 0; + error= check_single_table_access(thd, PRIV_LOCK_TABLES, table, 1); + table->security_ctx= sctx; + } + if (error) + { + my_error(ER_VIEW_INVALID, MYF(0), table->belong_to_view->view_db.str, + table->belong_to_view->view_name.str); + goto err; + } + } + } } if (lock_tables(thd, tables, counter, 0) || @@ -5390,7 +5421,7 @@ mysql_execute_command(THD *thd) if (first_table && lex->type & (REFRESH_READ_LOCK|REFRESH_FOR_EXPORT)) { /* Check table-level privileges. */ - if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, + if (check_table_access(thd, PRIV_LOCK_TABLES, all_tables, FALSE, UINT_MAX, FALSE)) goto error; @@ -6851,7 +6882,7 @@ check_access(THD *thd, privilege_t want_access, @param thd Thread handler @param privilege requested privilege - @param all_tables global table list of query + @param tables global table list of query @param no_errors FALSE/TRUE - report/don't report error to the client (using my_error() call). @@ -6861,28 +6892,25 @@ check_access(THD *thd, privilege_t want_access, 1 access denied, error is sent to client */ -bool check_single_table_access(THD *thd, privilege_t privilege, - TABLE_LIST *all_tables, bool no_errors) +bool check_single_table_access(THD *thd, privilege_t privilege, + TABLE_LIST *tables, bool no_errors) { - Switch_to_definer_security_ctx backup_sctx(thd, all_tables); + Switch_to_definer_security_ctx backup_sctx(thd, tables); const char *db_name; - if ((all_tables->view || all_tables->field_translation) && - !all_tables->schema_table) - db_name= all_tables->view_db.str; + if ((tables->view || tables->field_translation) && !tables->schema_table) + db_name= tables->view_db.str; else - db_name= all_tables->db.str; + db_name= tables->db.str; - if (check_access(thd, privilege, db_name, - &all_tables->grant.privilege, - &all_tables->grant.m_internal, - 0, no_errors)) + if (check_access(thd, privilege, db_name, &tables->grant.privilege, + &tables->grant.m_internal, 0, no_errors)) return 1; /* Show only 1 table for check_grant */ - if (!(all_tables->belong_to_view && - (thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) && - check_grant(thd, privilege, all_tables, FALSE, 1, no_errors)) + if (!(tables->belong_to_view && + (thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) && + check_grant(thd, privilege, tables, FALSE, 1, no_errors)) return 1; return 0; @@ -9976,7 +10004,7 @@ static bool lock_tables_precheck(THD *thd, TABLE_LIST *tables) if (is_temporary_table(table)) continue; - if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, table, + if (check_table_access(thd, PRIV_LOCK_TABLES, table, FALSE, 1, FALSE)) return TRUE; } |