From b5b7b03ff3d0ec92e7bdf8cf2a0f0793b4f3b91d Mon Sep 17 00:00:00 2001 From: "evgen@moonbone.local" <> Date: Mon, 27 Nov 2006 16:15:32 +0300 Subject: [PATCH 1/2] Bug#17254: Error for DEFINER security on VIEW provides too much info If a view was created with the DEFINER security and later the definer user was dropped then a SELECT from the view throws the error message saying that there is no definer user is registered. This is ok for a root but too much for a mere user. Now the st_table_list::prepare_view_securety_context() function reveals the absence of the definer only to a superuser and throws the 'access denied' error to others. --- mysql-test/r/view_grant.result | 20 ++++++++++++++++++ mysql-test/t/view_grant.test | 37 ++++++++++++++++++++++++++++++++++ sql/table.cc | 13 +++++++++++- 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result index 35e7afc0a7b..422d6c5faaf 100644 --- a/mysql-test/r/view_grant.result +++ b/mysql-test/r/view_grant.result @@ -712,3 +712,23 @@ DROP FUNCTION f1; DROP VIEW v2; DROP VIEW v1; DROP USER mysqltest_u1@localhost; +CREATE DATABASE db17254; +USE db17254; +CREATE TABLE t1 (f1 INT); +INSERT INTO t1 VALUES (10),(20); +CREATE USER def_17254@localhost; +GRANT SELECT ON db17254.* TO def_17254@localhost; +CREATE USER inv_17254@localhost; +GRANT SELECT ON db17254.t1 TO inv_17254@localhost; +GRANT CREATE VIEW ON db17254.* TO def_17254@localhost; +CREATE VIEW v1 AS SELECT * FROM t1; +DROP USER def_17254@localhost; +for a user +SELECT * FROM v1; +ERROR 42000: SELECT command denied to user 'inv_17254'@'localhost' for table 'v1 +' +for a superuser +SELECT * FROM v1; +ERROR HY000: There is no 'def_17254'@'localhost' registered +DROP USER inv_17254@localhost; +DROP DATABASE db17254; diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test index 8bc34cfe148..1da2250f65a 100644 --- a/mysql-test/t/view_grant.test +++ b/mysql-test/t/view_grant.test @@ -927,4 +927,41 @@ DROP VIEW v2; DROP VIEW v1; DROP USER mysqltest_u1@localhost; +# +# Bug#17254: Error for DEFINER security on VIEW provides too much info +# +connect (root,localhost,root,,); +connection root; +CREATE DATABASE db17254; +USE db17254; +CREATE TABLE t1 (f1 INT); +INSERT INTO t1 VALUES (10),(20); +CREATE USER def_17254@localhost; +GRANT SELECT ON db17254.* TO def_17254@localhost; +CREATE USER inv_17254@localhost; +GRANT SELECT ON db17254.t1 TO inv_17254@localhost; +GRANT CREATE VIEW ON db17254.* TO def_17254@localhost; + +connect (def,localhost,def_17254,,db17254); +connection def; +CREATE VIEW v1 AS SELECT * FROM t1; + +connection root; +DROP USER def_17254@localhost; + +connect (inv,localhost,inv_17254,,db17254); +connection inv; +--echo for a user +--error 1142 +SELECT * FROM v1; + +connection root; +--echo for a superuser +--error 1449 +SELECT * FROM v1; +DROP USER inv_17254@localhost; +DROP DATABASE db17254; +disconnect def; +disconnect inv; + # End of 5.0 tests. diff --git a/sql/table.cc b/sql/table.cc index 5d5d5095e7c..6bc43e48110 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2458,7 +2458,18 @@ bool st_table_list::prepare_view_securety_context(THD *thd) } else { - my_error(ER_NO_SUCH_USER, MYF(0), definer.user.str, definer.host.str); + if (thd->security_ctx->master_access & SUPER_ACL) + { + my_error(ER_NO_SUCH_USER, MYF(0), definer.user.str, definer.host.str); + + } + else + { + my_error(ER_ACCESS_DENIED_ERROR, MYF(0), + thd->security_ctx->priv_user, + thd->security_ctx->priv_host, + (thd->password ? ER(ER_YES) : ER(ER_NO))); + } DBUG_RETURN(TRUE); } } From e851a9eaea77eb896c14b5d57a7acb6221fea2f9 Mon Sep 17 00:00:00 2001 From: "evgen@moonbone.local" <> Date: Wed, 29 Nov 2006 14:52:11 +0300 Subject: [PATCH 2/2] Bug#20327: Marking of a wrong field leads to a wrong result on select with view, prepared statement and subquery. When a field of a view from an outer select is resolved the find_field_in_view function creates an Item_direct_view_ref object that references the corresponding view underlying field. After that the view_ref is marked as a dependent one. While resolving view underlying field it also get marked as a dependent one due to current_select still points to the subselect. Marking the view underlying field is wrong and lead to attaching conditions to a wrong table and thus to the wrong result of the whole statement. Now mark_select_range_as_dependent() function isn't called for fields from a view underlying table. --- mysql-test/r/ps.result | 18 ++++++++++++++++++ mysql-test/t/ps.test | 22 ++++++++++++++++++++++ sql/sql_base.cc | 6 ++++++ 3 files changed, 46 insertions(+) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 048c3ae46d3..2493bd372ea 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1379,4 +1379,22 @@ i 1 DEALLOCATE PREPARE stmt; DROP TABLE t1, t2; +CREATE TABLE t1 (i INT); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 VALUES (1), (2); +SELECT t1.i FROM t1 JOIN v1 ON t1.i = v1.i +WHERE EXISTS (SELECT * FROM t1 WHERE v1.i = 1); +i +1 +PREPARE stmt FROM "SELECT t1.i FROM t1 JOIN v1 ON t1.i = v1.i +WHERE EXISTS (SELECT * FROM t1 WHERE v1.i = 1)"; +EXECUTE stmt; +i +1 +EXECUTE stmt; +i +1 +DEALLOCATE PREPARE stmt; +DROP VIEW v1; +DROP TABLE t1; End of 5.0 tests. diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index f1e8e77d94e..be77c2533e9 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1437,4 +1437,26 @@ DEALLOCATE PREPARE stmt; DROP TABLE t1, t2; +# +# BUG#20327: Marking of a wrong field leads to a wrong result on select with +# view, prepared statement and subquery. +# +CREATE TABLE t1 (i INT); +CREATE VIEW v1 AS SELECT * FROM t1; + +INSERT INTO t1 VALUES (1), (2); + +let $query = SELECT t1.i FROM t1 JOIN v1 ON t1.i = v1.i + WHERE EXISTS (SELECT * FROM t1 WHERE v1.i = 1); +eval $query; +eval PREPARE stmt FROM "$query"; +# Statement execution should return '1'. +EXECUTE stmt; +# Check re-execution. +EXECUTE stmt; + +DEALLOCATE PREPARE stmt; +DROP VIEW v1; +DROP TABLE t1; + --echo End of 5.0 tests. diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3984ceac6a9..314452fac89 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3303,6 +3303,12 @@ find_field_in_tables(THD *thd, Item_ident *item, { if (found == WRONG_GRANT) return (Field*) 0; + + /* + Only views fields should be marked as dependent, not an underlying + fields. + */ + if (!table_ref->belong_to_view) { SELECT_LEX *current_sel= thd->lex->current_select; SELECT_LEX *last_select= table_ref->select_lex;