diff options
-rw-r--r-- | mysql-test/main/flush_notembedded.result | 28 | ||||
-rw-r--r-- | mysql-test/main/flush_notembedded.test | 32 | ||||
-rw-r--r-- | sql/privilege.h | 1 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/sql_reload.cc | 26 |
5 files changed, 74 insertions, 15 deletions
diff --git a/mysql-test/main/flush_notembedded.result b/mysql-test/main/flush_notembedded.result new file mode 100644 index 00000000000..2790b9145a1 --- /dev/null +++ b/mysql-test/main/flush_notembedded.result @@ -0,0 +1,28 @@ +# +# MDEV-15888 Implement FLUSH TABLES tbl_name [, tbl_name] ... WITH READ LOCK for views. +# +# +# privilege checks with views +# +create database mysqltest1; +create table mysqltest1.t1 (a int); +create user u1@localhost; +grant reload on *.* to u1@localhost; +grant select on mysqltest1.* to u1@localhost; +connect u1,localhost,u1; +flush tables mysqltest1.t1 for export; +ERROR 42000: Access denied for user 'u1'@'localhost' to database 'mysqltest1' +create view v as select * from mysqltest1.t1; +create view v2 as select * from v; +flush tables v for export; +ERROR 42000: Access denied for user 'u1'@'localhost' to database 'mysqltest1' +flush tables v2 for export; +ERROR 42000: Access denied for user 'u1'@'localhost' to database 'mysqltest1' +disconnect u1; +connection default; +drop database mysqltest1; +drop view v, v2; +drop user u1@localhost; +# +# End of 10.6 tests +# diff --git a/mysql-test/main/flush_notembedded.test b/mysql-test/main/flush_notembedded.test new file mode 100644 index 00000000000..233e1e5d958 --- /dev/null +++ b/mysql-test/main/flush_notembedded.test @@ -0,0 +1,32 @@ +source include/not_embedded.inc; + +--echo # +--echo # MDEV-15888 Implement FLUSH TABLES tbl_name [, tbl_name] ... WITH READ LOCK for views. +--echo # + +--echo # +--echo # privilege checks with views +--echo # +create database mysqltest1; +create table mysqltest1.t1 (a int); +create user u1@localhost; +grant reload on *.* to u1@localhost; +grant select on mysqltest1.* to u1@localhost; +connect u1,localhost,u1; +error ER_DBACCESS_DENIED_ERROR; +flush tables mysqltest1.t1 for export; +create view v as select * from mysqltest1.t1; +create view v2 as select * from v; +error ER_DBACCESS_DENIED_ERROR; +flush tables v for export; +error ER_DBACCESS_DENIED_ERROR; +flush tables v2 for export; +disconnect u1; +connection default; +drop database mysqltest1; +drop view v, v2; +drop user u1@localhost; + +--echo # +--echo # End of 10.6 tests +--echo # diff --git a/sql/privilege.h b/sql/privilege.h index 3e4c2526c6c..c1233102522 100644 --- a/sql/privilege.h +++ b/sql/privilege.h @@ -296,6 +296,7 @@ constexpr privilege_t TMP_TABLE_ACLS= COL_DML_ACLS | ALL_TABLE_DDL_ACLS; +constexpr privilege_t PRIV_LOCK_TABLES= SELECT_ACL | LOCK_TABLES_ACL; /* Allow to set an object definer: diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8307cd0ed4d..2c6df6dbb03 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -98,8 +98,6 @@ #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 diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 0fa2fa10df8..64544e42d30 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -24,6 +24,7 @@ #include "sql_connect.h" // reset_mqh #include "thread_cache.h" #include "sql_base.h" // close_cached_tables +#include "sql_parse.h" // check_single_table_access #include "sql_db.h" // my_dbopt_cleanup #include "hostname.h" // hostname_cache_refresh #include "sql_repl.h" // reset_master, reset_slave @@ -586,28 +587,27 @@ bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables) &lock_tables_prelocking_strategy)) goto error_reset_bits; - if (thd->lex->type & REFRESH_FOR_EXPORT) + if (thd->lex->type & (REFRESH_FOR_EXPORT|REFRESH_READ_LOCK)) { - // Check if all storage engines support FOR EXPORT. for (TABLE_LIST *table_list= all_tables; table_list; table_list= table_list->next_global) { - if (!(table_list->is_view() || - table_list->table->file->ha_table_flags() & HA_CAN_EXPORT)) + if (table_list->belong_to_view && + check_single_table_access(thd, PRIV_LOCK_TABLES, table_list, FALSE)) + { + table_list->hide_view_error(thd); + goto error_reset_bits; + } + if (table_list->is_view()) + continue; + if (thd->lex->type & REFRESH_FOR_EXPORT && + !(table_list->table->file->ha_table_flags() & HA_CAN_EXPORT)) { my_error(ER_ILLEGAL_HA, MYF(0),table_list->table->file->table_type(), table_list->db.str, table_list->table_name.str); goto error_reset_bits; } - } - } - - if (thd->lex->type & REFRESH_READ_LOCK) - { - for (auto table_list= all_tables; table_list; - table_list= table_list->next_global) - { - if (!table_list->is_view() && + if (thd->lex->type & REFRESH_READ_LOCK && table_list->table->file->extra(HA_EXTRA_FLUSH)) goto error_reset_bits; } |