summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorgi Kodinov <joro@sun.com>2009-08-19 15:14:57 +0300
committerGeorgi Kodinov <joro@sun.com>2009-08-19 15:14:57 +0300
commit0665536995fa1afe4ac71e13451dd8258063ff36 (patch)
treeec3d6929232f89d5951fb478830ddf37d9aa403b
parent40defb1d53e6978bdfcd4fc67f638cb56fa58ebb (diff)
downloadmariadb-git-0665536995fa1afe4ac71e13451dd8258063ff36.tar.gz
Bug #46019: ERROR 1356 When selecting from within another
view that has Group By Table access rights checking function check_grant() assumed that no view is opened when it's called. This is not true with nested views where the inner view needs materialization. In this case the view is already materialized when check_grant() is called for it. This caused check_grant() to not look for table level grants on the materialized view table. Fixed by checking if a view is already materialized and if it is check table level grants using the original table name (not the ones of the materialized temp table).
-rw-r--r--mysql-test/r/view_grant.result24
-rw-r--r--mysql-test/t/view_grant.test36
-rw-r--r--sql/sql_acl.cc12
-rw-r--r--sql/table.h23
4 files changed, 91 insertions, 4 deletions
diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result
index e7a50451cec..c9b31b00f69 100644
--- a/mysql-test/r/view_grant.result
+++ b/mysql-test/r/view_grant.result
@@ -945,4 +945,28 @@ DROP USER foo;
DROP VIEW db1.v1;
DROP TABLE db1.t1;
DROP DATABASE db1;
+#
+# Bug #46019: ERROR 1356 When selecting from within another
+# view that has Group By
+#
+CREATE DATABASE db1;
+USE db1;
+CREATE TABLE t1 (a INT);
+CREATE SQL SECURITY INVOKER VIEW v1 AS
+SELECT a FROM t1 GROUP BY a;
+CREATE SQL SECURITY INVOKER VIEW v2 AS
+SELECT a FROM v1;
+CREATE USER u1;
+GRANT SELECT ON TABLE t1 TO u1;
+GRANT SELECT, SHOW VIEW ON TABLE v1 TO u1;
+GRANT SELECT, SHOW VIEW ON TABLE v2 TO u1;
+SELECT a FROM v1;
+a
+SELECT a FROM v2;
+a
+DROP USER u1;
+DROP VIEW v1,v2;
+DROP TABLE t1;
+USE test;
+DROP DATABASE db1;
End of 5.0 tests.
diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test
index ff17cde5184..0a8456afec2 100644
--- a/mysql-test/t/view_grant.test
+++ b/mysql-test/t/view_grant.test
@@ -1232,6 +1232,42 @@ DROP TABLE db1.t1;
DROP DATABASE db1;
connection default;
+
+--echo #
+--echo # Bug #46019: ERROR 1356 When selecting from within another
+--echo # view that has Group By
+--echo #
+
+CREATE DATABASE db1;
+USE db1;
+
+CREATE TABLE t1 (a INT);
+
+CREATE SQL SECURITY INVOKER VIEW v1 AS
+ SELECT a FROM t1 GROUP BY a;
+
+CREATE SQL SECURITY INVOKER VIEW v2 AS
+ SELECT a FROM v1;
+
+CREATE USER u1;
+
+GRANT SELECT ON TABLE t1 TO u1;
+GRANT SELECT, SHOW VIEW ON TABLE v1 TO u1;
+GRANT SELECT, SHOW VIEW ON TABLE v2 TO u1;
+
+CONNECT (u1, localhost, u1,,db1);
+CONNECTION u1;
+
+SELECT a FROM v1;
+SELECT a FROM v2;
+
+CONNECTION default;
+DISCONNECT u1;
+DROP USER u1;
+DROP VIEW v1,v2;
+DROP TABLE t1;
+USE test;
+DROP DATABASE db1;
--echo End of 5.0 tests.
# Wait till we reached the initial number of concurrent sessions
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index ab4e518d5dd..a411101fcfd 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -3650,11 +3650,14 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
continue; // ok
if (!(~table->grant.privilege & want_access) ||
- table->derived || table->schema_table)
+ table->is_non_materialized_derived_table() || table->schema_table)
{
/*
It is subquery in the FROM clause. VIEW set table->derived after
- table opening, but this function always called before table opening.
+ table opening, but this function is mostly called before table opening.
+ When it's called after table opening e.g. for nested views with
+ materialization we shoud check the materialized table for access as
+ any other table.
*/
if (!table->referencing_view)
{
@@ -3667,9 +3670,10 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
}
continue;
}
+
if (!(grant_table= table_hash_search(sctx->host, sctx->ip,
- table->db, sctx->priv_user,
- table->table_name,0)))
+ table->get_db_name(), sctx->priv_user,
+ table->get_table_name(), 0)))
{
want_access &= ~table->grant.privilege;
goto err; // No grants
diff --git a/sql/table.h b/sql/table.h
index db996d45320..ce9364fad4d 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -771,6 +771,29 @@ struct TABLE_LIST
void reinit_before_use(THD *thd);
Item_subselect *containing_subselect();
+ /**
+ @brief True if this TABLE_LIST represents an not yet materialized
+ derived table, i.e. the result of a subquery or view execution.
+ */
+ bool is_non_materialized_derived_table() const
+ {
+ return derived && !derived_result;
+ }
+
+ /**
+ @brief Returns the name of the database that the referenced table belongs
+ to.
+ */
+ char *get_db_name() { return view != NULL ? view_db.str : db; }
+
+ /**
+ @brief Returns the name of the table that this TABLE_LIST represents.
+
+ @details The unqualified table name or view name for a table or view,
+ respectively.
+ */
+ char *get_table_name() { return view != NULL ? view_name.str : table_name; }
+
private:
bool prep_check_option(THD *thd, uint8 check_opt_type);
bool prep_where(THD *thd, Item **conds, bool no_where_clause);