mirror of
https://github.com/MariaDB/server.git
synced 2025-01-28 09:44:17 +01:00
Bug#35996: SELECT + SHOW VIEW should be enough to display
view definition During SHOW CREATE VIEW there is no reason to 'anonymize' errors that name objects that a user does not have access to. Moreover it was inconsistently implemented. For example base tables being referenced from a view appear to be ok, but not views. The manual on the other hand is clear: If a user has the privileges SELECT and SHOW VIEW, the view definition is available to that user, period. The fix changes the behavior to support the manual. mysql-test/r/information_schema_db.result: Bug#35996: Changed warnings. mysql-test/r/view_grant.result: Bug#35996: Changed warnings, test result. mysql-test/t/information_schema_db.test: Bug#35996: Changed test case to reflect new behavior. mysql-test/t/view_grant.test: Bug#35996: Test case. sql/sql_acl.cc: Bug#35996: Code no longer necessary, we may as well exempt SHOW CREATE VIEW from this check. sql/sql_show.cc: Bug#35996: The fix: An Internal_error_handler that hides most errors raised by access checking as they are not relevant to SHOW CREATE VIEW. sql/table.cc: Bug#35996: Restricting this hack to act only when there is no Internal_error_handler.
This commit is contained in:
parent
96665fd9cc
commit
e86f08d054
7 changed files with 437 additions and 29 deletions
|
@ -139,7 +139,7 @@ show create view testdb_1.v7;
|
|||
View Create View character_set_client collation_connection
|
||||
v7 CREATE ALGORITHM=UNDEFINED DEFINER=`no_such_user`@`no_such_host` SQL SECURITY DEFINER VIEW `v7` AS select `testdb_1`.`t2`.`f1` AS `f1` from `t2` latin1 latin1_swedish_ci
|
||||
Warnings:
|
||||
Warning 1356 View 'testdb_1.v7' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
Note 1449 The user specified as a definer ('no_such_user'@'no_such_host') does not exist
|
||||
show fields from testdb_1.v7;
|
||||
Field Type Null Key Default Extra
|
||||
f1 char(4) YES NULL
|
||||
|
@ -169,7 +169,7 @@ show create view testdb_1.v7;
|
|||
View Create View character_set_client collation_connection
|
||||
v7 CREATE ALGORITHM=UNDEFINED DEFINER=`no_such_user`@`no_such_host` SQL SECURITY DEFINER VIEW `v7` AS select `testdb_1`.`t2`.`f1` AS `f1` from `t2` latin1 latin1_swedish_ci
|
||||
Warnings:
|
||||
Warning 1356 View 'testdb_1.v7' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
Note 1449 The user specified as a definer ('no_such_user'@'no_such_host') does not exist
|
||||
revoke insert(f1) on v3 from testdb_2@localhost;
|
||||
revoke show view on v5 from testdb_2@localhost;
|
||||
use testdb_1;
|
||||
|
@ -187,7 +187,8 @@ ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v7'
|
|||
show create view testdb_1.v7;
|
||||
ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v7'
|
||||
show create view v4;
|
||||
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
|
||||
View Create View character_set_client collation_connection
|
||||
v4 CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_2`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS select `v3`.`f1` AS `f1`,`v3`.`f2` AS `f2` from `testdb_1`.`v3` latin1 latin1_swedish_ci
|
||||
show fields from v4;
|
||||
Field Type Null Key Default Extra
|
||||
f1 char(4) YES NULL
|
||||
|
|
|
@ -606,7 +606,7 @@ SHOW CREATE VIEW v;
|
|||
View Create View character_set_client collation_connection
|
||||
v CREATE ALGORITHM=UNDEFINED DEFINER=`no-such-user`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `test`.`t1`.`a` AS `a` from `t1` latin1 latin1_swedish_ci
|
||||
Warnings:
|
||||
Warning 1356 View 'test.v' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
Note 1449 The user specified as a definer ('no-such-user'@'localhost') does not exist
|
||||
SELECT * FROM v;
|
||||
ERROR HY000: The user specified as a definer ('no-such-user'@'localhost') does not exist
|
||||
DROP VIEW v;
|
||||
|
@ -963,7 +963,7 @@ SHOW CREATE VIEW v1;
|
|||
View Create View character_set_client collation_connection
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`no_such`@`user_1` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
|
||||
Warnings:
|
||||
Warning 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
Note 1449 The user specified as a definer ('no_such'@'user_1') does not exist
|
||||
ALTER ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
|
||||
Warnings:
|
||||
Note 1449 The user specified as a definer ('no_such'@'user_1') does not exist
|
||||
|
@ -971,7 +971,7 @@ SHOW CREATE VIEW v1;
|
|||
View Create View character_set_client collation_connection
|
||||
v1 CREATE ALGORITHM=MERGE DEFINER=`no_such`@`user_1` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
|
||||
Warnings:
|
||||
Warning 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
Note 1449 The user specified as a definer ('no_such'@'user_1') does not exist
|
||||
ALTER ALGORITHM=TEMPTABLE DEFINER=no_such@user_2 VIEW v1 AS SELECT * FROM t1;
|
||||
Warnings:
|
||||
Note 1449 The user specified as a definer ('no_such'@'user_2') does not exist
|
||||
|
@ -979,7 +979,7 @@ SHOW CREATE VIEW v1;
|
|||
View Create View character_set_client collation_connection
|
||||
v1 CREATE ALGORITHM=TEMPTABLE DEFINER=`no_such`@`user_2` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
|
||||
Warnings:
|
||||
Warning 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
Note 1449 The user specified as a definer ('no_such'@'user_2') does not exist
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
CREATE USER mysqluser1@localhost;
|
||||
|
@ -1044,3 +1044,177 @@ DROP DATABASE mysqltest1;
|
|||
DROP VIEW test.v3;
|
||||
DROP USER mysqluser1@localhost;
|
||||
USE test;
|
||||
#
|
||||
# Bug#35996: SELECT + SHOW VIEW should be enough to display view
|
||||
# definition
|
||||
#
|
||||
CREATE USER mysqluser1@localhost;
|
||||
CREATE DATABASE mysqltest1;
|
||||
CREATE DATABASE mysqltest2;
|
||||
GRANT USAGE, SELECT, CREATE VIEW, SHOW VIEW
|
||||
ON mysqltest2.* TO mysqluser1@localhost;
|
||||
USE mysqltest1;
|
||||
CREATE TABLE t1( a INT );
|
||||
CREATE TABLE t2( a INT, b INT );
|
||||
CREATE FUNCTION f1() RETURNS INT RETURN 1;
|
||||
CREATE VIEW v1 AS SELECT 1 AS a;
|
||||
CREATE VIEW v2 AS SELECT 1 AS a, 2 AS b;
|
||||
GRANT SELECT ON TABLE t1 TO mysqluser1@localhost;
|
||||
GRANT SELECT (a, b) ON TABLE t2 TO mysqluser1@localhost;
|
||||
GRANT EXECUTE ON FUNCTION f1 TO mysqluser1@localhost;
|
||||
GRANT SELECT ON TABLE v1 TO mysqluser1@localhost;
|
||||
GRANT SELECT (a, b) ON TABLE v2 TO mysqluser1@localhost;
|
||||
CREATE VIEW v_t1 AS SELECT * FROM t1;
|
||||
CREATE VIEW v_t2 AS SELECT * FROM t2;
|
||||
CREATE VIEW v_f1 AS SELECT f1() AS a;
|
||||
CREATE VIEW v_v1 AS SELECT * FROM v1;
|
||||
CREATE VIEW v_v2 AS SELECT * FROM v2;
|
||||
GRANT SELECT, SHOW VIEW ON v_t1 TO mysqluser1@localhost;
|
||||
GRANT SELECT, SHOW VIEW ON v_t2 TO mysqluser1@localhost;
|
||||
GRANT SELECT, SHOW VIEW ON v_f1 TO mysqluser1@localhost;
|
||||
GRANT SELECT, SHOW VIEW ON v_v1 TO mysqluser1@localhost;
|
||||
GRANT SELECT, SHOW VIEW ON v_v2 TO mysqluser1@localhost;
|
||||
CREATE VIEW v_mysqluser1_t1 AS SELECT * FROM mysqltest1.t1;
|
||||
CREATE VIEW v_mysqluser1_t2 AS SELECT * FROM mysqltest1.t2;
|
||||
CREATE VIEW v_mysqluser1_f1 AS SELECT mysqltest1.f1() AS a;
|
||||
CREATE VIEW v_mysqluser1_v1 AS SELECT * FROM mysqltest1.v1;
|
||||
CREATE VIEW v_mysqluser1_v2 AS SELECT * FROM mysqltest1.v2;
|
||||
SHOW CREATE VIEW mysqltest1.v_t1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_t1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW mysqltest1.v_t2;
|
||||
View Create View character_set_client collation_connection
|
||||
v_t2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_t2` AS select `mysqltest1`.`t2`.`a` AS `a`,`mysqltest1`.`t2`.`b` AS `b` from `mysqltest1`.`t2` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW mysqltest1.v_f1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_f1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_f1` AS select `f1`() AS `a` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW mysqltest1.v_v1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW mysqltest1.v_v2;
|
||||
View Create View character_set_client collation_connection
|
||||
v_v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_v2` AS select `v2`.`a` AS `a`,`v2`.`b` AS `b` from `mysqltest1`.`v2` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW v_mysqluser1_t1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_mysqluser1_t1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW v_mysqluser1_t2;
|
||||
View Create View character_set_client collation_connection
|
||||
v_mysqluser1_t2 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t2` AS select `mysqltest1`.`t2`.`a` AS `a`,`mysqltest1`.`t2`.`b` AS `b` from `mysqltest1`.`t2` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW v_mysqluser1_f1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_mysqluser1_f1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_f1` AS select `mysqltest1`.`f1`() AS `a` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW v_mysqluser1_v1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_mysqluser1_v1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW v_mysqluser1_v2;
|
||||
View Create View character_set_client collation_connection
|
||||
v_mysqluser1_v2 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v2` AS select `v2`.`a` AS `a`,`v2`.`b` AS `b` from `mysqltest1`.`v2` latin1 latin1_swedish_ci
|
||||
REVOKE SELECT ON TABLE t1 FROM mysqluser1@localhost;
|
||||
REVOKE SELECT (a) ON TABLE t2 FROM mysqluser1@localhost;
|
||||
REVOKE EXECUTE ON FUNCTION f1 FROM mysqluser1@localhost;
|
||||
REVOKE SELECT ON TABLE v1 FROM mysqluser1@localhost;
|
||||
SHOW CREATE VIEW mysqltest1.v_t1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_t1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW mysqltest1.v_t2;
|
||||
View Create View character_set_client collation_connection
|
||||
v_t2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_t2` AS select `mysqltest1`.`t2`.`a` AS `a`,`mysqltest1`.`t2`.`b` AS `b` from `mysqltest1`.`t2` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW mysqltest1.v_f1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_f1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_f1` AS select `f1`() AS `a` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW mysqltest1.v_v1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW mysqltest1.v_v2;
|
||||
View Create View character_set_client collation_connection
|
||||
v_v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_v2` AS select `v2`.`a` AS `a`,`v2`.`b` AS `b` from `mysqltest1`.`v2` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW v_mysqluser1_t1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_mysqluser1_t1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW v_mysqluser1_t2;
|
||||
View Create View character_set_client collation_connection
|
||||
v_mysqluser1_t2 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t2` AS select `mysqltest1`.`t2`.`a` AS `a`,`mysqltest1`.`t2`.`b` AS `b` from `mysqltest1`.`t2` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW v_mysqluser1_f1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_mysqluser1_f1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_f1` AS select `mysqltest1`.`f1`() AS `a` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW v_mysqluser1_v1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_mysqluser1_v1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1` latin1 latin1_swedish_ci
|
||||
SHOW CREATE VIEW v_mysqluser1_v2;
|
||||
View Create View character_set_client collation_connection
|
||||
v_mysqluser1_v2 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v2` AS select `v2`.`a` AS `a`,`v2`.`b` AS `b` from `mysqltest1`.`v2` latin1 latin1_swedish_ci
|
||||
# Testing the case when the views reference missing objects.
|
||||
# Obviously, there are no privileges to check for, so we
|
||||
# need only each object type once.
|
||||
DROP TABLE t1;
|
||||
DROP FUNCTION f1;
|
||||
DROP VIEW v1;
|
||||
SHOW CREATE VIEW mysqltest1.v_t1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_t1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
|
||||
Warnings:
|
||||
Warning 1356 View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
SHOW CREATE VIEW mysqltest1.v_f1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_f1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_f1` AS select `f1`() AS `a` latin1 latin1_swedish_ci
|
||||
Warnings:
|
||||
Warning 1356 View 'mysqltest1.v_f1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
SHOW CREATE VIEW mysqltest1.v_v1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1` latin1 latin1_swedish_ci
|
||||
Warnings:
|
||||
Warning 1356 View 'mysqltest1.v_v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
SHOW CREATE VIEW v_mysqluser1_t1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_mysqluser1_t1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
|
||||
Warnings:
|
||||
Warning 1356 View 'mysqltest2.v_mysqluser1_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
SHOW CREATE VIEW v_mysqluser1_f1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_mysqluser1_f1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_f1` AS select `mysqltest1`.`f1`() AS `a` latin1 latin1_swedish_ci
|
||||
Warnings:
|
||||
Warning 1356 View 'mysqltest2.v_mysqluser1_f1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
SHOW CREATE VIEW v_mysqluser1_v1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_mysqluser1_v1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1` latin1 latin1_swedish_ci
|
||||
Warnings:
|
||||
Warning 1356 View 'mysqltest2.v_mysqluser1_v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
REVOKE SHOW VIEW ON v_t1 FROM mysqluser1@localhost;
|
||||
REVOKE SHOW VIEW ON v_f1 FROM mysqluser1@localhost;
|
||||
REVOKE SHOW VIEW ON v_v1 FROM mysqluser1@localhost;
|
||||
SHOW CREATE VIEW mysqltest1.v_t1;
|
||||
ERROR 42000: SHOW VIEW command denied to user 'mysqluser1'@'localhost' for table 'v_t1'
|
||||
SHOW CREATE VIEW mysqltest1.v_f1;
|
||||
ERROR 42000: SHOW VIEW command denied to user 'mysqluser1'@'localhost' for table 'v_f1'
|
||||
SHOW CREATE VIEW mysqltest1.v_v1;
|
||||
ERROR 42000: SHOW VIEW command denied to user 'mysqluser1'@'localhost' for table 'v_v1'
|
||||
SHOW CREATE VIEW v_mysqluser1_t1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_mysqluser1_t1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
|
||||
Warnings:
|
||||
Warning 1356 View 'mysqltest2.v_mysqluser1_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
SHOW CREATE VIEW v_mysqluser1_f1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_mysqluser1_f1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_f1` AS select `mysqltest1`.`f1`() AS `a` latin1 latin1_swedish_ci
|
||||
Warnings:
|
||||
Warning 1356 View 'mysqltest2.v_mysqluser1_f1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
SHOW CREATE VIEW v_mysqluser1_v1;
|
||||
View Create View character_set_client collation_connection
|
||||
v_mysqluser1_v1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1` latin1 latin1_swedish_ci
|
||||
Warnings:
|
||||
Warning 1356 View 'mysqltest2.v_mysqluser1_v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
DROP USER mysqluser1@localhost;
|
||||
DROP DATABASE mysqltest1;
|
||||
DROP DATABASE mysqltest2;
|
||||
USE test;
|
||||
CREATE TABLE t1( a INT );
|
||||
CREATE DEFINER = no_such_user@no_such_host VIEW v1 AS SELECT * FROM t1;
|
||||
Warnings:
|
||||
Note 1449 The user specified as a definer ('no_such_user'@'no_such_host') does not exist
|
||||
SHOW CREATE VIEW v1;
|
||||
View Create View character_set_client collation_connection
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`no_such_user`@`no_such_host` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`a` AS `a` from `t1` latin1 latin1_swedish_ci
|
||||
Warnings:
|
||||
Note 1449 The user specified as a definer ('no_such_user'@'no_such_host') does not exist
|
||||
DROP TABLE t1;
|
||||
DROP VIEW v1;
|
||||
|
|
|
@ -184,7 +184,6 @@ show fields from testdb_1.v7;
|
|||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
show create view testdb_1.v7;
|
||||
|
||||
--error ER_VIEW_NO_EXPLAIN
|
||||
show create view v4;
|
||||
#--error ER_VIEW_NO_EXPLAIN
|
||||
show fields from v4;
|
||||
|
|
|
@ -1382,6 +1382,127 @@ DROP VIEW test.v3;
|
|||
DROP USER mysqluser1@localhost;
|
||||
USE test;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#35996: SELECT + SHOW VIEW should be enough to display view
|
||||
--echo # definition
|
||||
--echo #
|
||||
-- source include/not_embedded.inc
|
||||
CREATE USER mysqluser1@localhost;
|
||||
CREATE DATABASE mysqltest1;
|
||||
CREATE DATABASE mysqltest2;
|
||||
GRANT USAGE, SELECT, CREATE VIEW, SHOW VIEW
|
||||
ON mysqltest2.* TO mysqluser1@localhost;
|
||||
|
||||
USE mysqltest1;
|
||||
|
||||
CREATE TABLE t1( a INT );
|
||||
CREATE TABLE t2( a INT, b INT );
|
||||
CREATE FUNCTION f1() RETURNS INT RETURN 1;
|
||||
CREATE VIEW v1 AS SELECT 1 AS a;
|
||||
CREATE VIEW v2 AS SELECT 1 AS a, 2 AS b;
|
||||
|
||||
GRANT SELECT ON TABLE t1 TO mysqluser1@localhost;
|
||||
GRANT SELECT (a, b) ON TABLE t2 TO mysqluser1@localhost;
|
||||
GRANT EXECUTE ON FUNCTION f1 TO mysqluser1@localhost;
|
||||
GRANT SELECT ON TABLE v1 TO mysqluser1@localhost;
|
||||
GRANT SELECT (a, b) ON TABLE v2 TO mysqluser1@localhost;
|
||||
|
||||
CREATE VIEW v_t1 AS SELECT * FROM t1;
|
||||
CREATE VIEW v_t2 AS SELECT * FROM t2;
|
||||
CREATE VIEW v_f1 AS SELECT f1() AS a;
|
||||
CREATE VIEW v_v1 AS SELECT * FROM v1;
|
||||
CREATE VIEW v_v2 AS SELECT * FROM v2;
|
||||
|
||||
GRANT SELECT, SHOW VIEW ON v_t1 TO mysqluser1@localhost;
|
||||
GRANT SELECT, SHOW VIEW ON v_t2 TO mysqluser1@localhost;
|
||||
GRANT SELECT, SHOW VIEW ON v_f1 TO mysqluser1@localhost;
|
||||
GRANT SELECT, SHOW VIEW ON v_v1 TO mysqluser1@localhost;
|
||||
GRANT SELECT, SHOW VIEW ON v_v2 TO mysqluser1@localhost;
|
||||
|
||||
--connect (connection1, localhost, mysqluser1,, mysqltest2)
|
||||
CREATE VIEW v_mysqluser1_t1 AS SELECT * FROM mysqltest1.t1;
|
||||
CREATE VIEW v_mysqluser1_t2 AS SELECT * FROM mysqltest1.t2;
|
||||
CREATE VIEW v_mysqluser1_f1 AS SELECT mysqltest1.f1() AS a;
|
||||
CREATE VIEW v_mysqluser1_v1 AS SELECT * FROM mysqltest1.v1;
|
||||
CREATE VIEW v_mysqluser1_v2 AS SELECT * FROM mysqltest1.v2;
|
||||
|
||||
SHOW CREATE VIEW mysqltest1.v_t1;
|
||||
SHOW CREATE VIEW mysqltest1.v_t2;
|
||||
SHOW CREATE VIEW mysqltest1.v_f1;
|
||||
SHOW CREATE VIEW mysqltest1.v_v1;
|
||||
SHOW CREATE VIEW mysqltest1.v_v2;
|
||||
|
||||
SHOW CREATE VIEW v_mysqluser1_t1;
|
||||
SHOW CREATE VIEW v_mysqluser1_t2;
|
||||
SHOW CREATE VIEW v_mysqluser1_f1;
|
||||
SHOW CREATE VIEW v_mysqluser1_v1;
|
||||
SHOW CREATE VIEW v_mysqluser1_v2;
|
||||
|
||||
--connection default
|
||||
REVOKE SELECT ON TABLE t1 FROM mysqluser1@localhost;
|
||||
REVOKE SELECT (a) ON TABLE t2 FROM mysqluser1@localhost;
|
||||
REVOKE EXECUTE ON FUNCTION f1 FROM mysqluser1@localhost;
|
||||
REVOKE SELECT ON TABLE v1 FROM mysqluser1@localhost;
|
||||
|
||||
--connection connection1
|
||||
SHOW CREATE VIEW mysqltest1.v_t1;
|
||||
SHOW CREATE VIEW mysqltest1.v_t2;
|
||||
SHOW CREATE VIEW mysqltest1.v_f1;
|
||||
SHOW CREATE VIEW mysqltest1.v_v1;
|
||||
SHOW CREATE VIEW mysqltest1.v_v2;
|
||||
|
||||
SHOW CREATE VIEW v_mysqluser1_t1;
|
||||
SHOW CREATE VIEW v_mysqluser1_t2;
|
||||
SHOW CREATE VIEW v_mysqluser1_f1;
|
||||
SHOW CREATE VIEW v_mysqluser1_v1;
|
||||
SHOW CREATE VIEW v_mysqluser1_v2;
|
||||
|
||||
--connection default
|
||||
--echo # Testing the case when the views reference missing objects.
|
||||
--echo # Obviously, there are no privileges to check for, so we
|
||||
--echo # need only each object type once.
|
||||
DROP TABLE t1;
|
||||
DROP FUNCTION f1;
|
||||
DROP VIEW v1;
|
||||
|
||||
--connection connection1
|
||||
SHOW CREATE VIEW mysqltest1.v_t1;
|
||||
SHOW CREATE VIEW mysqltest1.v_f1;
|
||||
SHOW CREATE VIEW mysqltest1.v_v1;
|
||||
|
||||
SHOW CREATE VIEW v_mysqluser1_t1;
|
||||
SHOW CREATE VIEW v_mysqluser1_f1;
|
||||
SHOW CREATE VIEW v_mysqluser1_v1;
|
||||
|
||||
--connection default
|
||||
REVOKE SHOW VIEW ON v_t1 FROM mysqluser1@localhost;
|
||||
REVOKE SHOW VIEW ON v_f1 FROM mysqluser1@localhost;
|
||||
REVOKE SHOW VIEW ON v_v1 FROM mysqluser1@localhost;
|
||||
|
||||
--connection connection1
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
SHOW CREATE VIEW mysqltest1.v_t1;
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
SHOW CREATE VIEW mysqltest1.v_f1;
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
SHOW CREATE VIEW mysqltest1.v_v1;
|
||||
SHOW CREATE VIEW v_mysqluser1_t1;
|
||||
SHOW CREATE VIEW v_mysqluser1_f1;
|
||||
SHOW CREATE VIEW v_mysqluser1_v1;
|
||||
|
||||
--disconnect connection1
|
||||
--connection default
|
||||
DROP USER mysqluser1@localhost;
|
||||
DROP DATABASE mysqltest1;
|
||||
DROP DATABASE mysqltest2;
|
||||
USE test;
|
||||
|
||||
CREATE TABLE t1( a INT );
|
||||
CREATE DEFINER = no_such_user@no_such_host VIEW v1 AS SELECT * FROM t1;
|
||||
SHOW CREATE VIEW v1;
|
||||
DROP TABLE t1;
|
||||
DROP VIEW v1;
|
||||
|
||||
# Wait till we reached the initial number of concurrent sessions
|
||||
--source include/wait_until_count_sessions.inc
|
||||
|
||||
|
|
|
@ -4072,8 +4072,7 @@ bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
|
|||
db_name= table_ref->view_db.str;
|
||||
table_name= table_ref->view_name.str;
|
||||
if (table_ref->belong_to_view &&
|
||||
(thd->lex->sql_command == SQLCOM_SHOW_FIELDS ||
|
||||
thd->lex->sql_command == SQLCOM_SHOW_CREATE))
|
||||
thd->lex->sql_command == SQLCOM_SHOW_FIELDS)
|
||||
{
|
||||
view_privs= get_column_grant(thd, grant, db_name, table_name, name);
|
||||
if (view_privs & VIEW_ANY_ACL)
|
||||
|
|
143
sql/sql_show.cc
143
sql/sql_show.cc
|
@ -581,6 +581,126 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
An Internal_error_handler that suppresses errors regarding views'
|
||||
underlying tables that occur during privilege checking within SHOW CREATE
|
||||
VIEW commands. This happens in the cases when
|
||||
|
||||
- A view's underlying table (e.g. referenced in its SELECT list) does not
|
||||
exist. There should not be an error as no attempt was made to access it
|
||||
per se.
|
||||
|
||||
- Access is denied for some table, column, function or stored procedure
|
||||
such as mentioned above. This error gets raised automatically, since we
|
||||
can't untangle its access checking from that of the view itself.
|
||||
*/
|
||||
class Show_create_error_handler : public Internal_error_handler {
|
||||
|
||||
TABLE_LIST *m_top_view;
|
||||
bool m_handling;
|
||||
Security_context *m_sctx;
|
||||
|
||||
char m_view_access_denied_message[MYSQL_ERRMSG_SIZE];
|
||||
char *m_view_access_denied_message_ptr;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
Creates a new Show_create_error_handler for the particular security
|
||||
context and view.
|
||||
|
||||
@thd Thread context, used for security context information if needed.
|
||||
@top_view The view. We do not verify at this point that top_view is in
|
||||
fact a view since, alas, these things do not stay constant.
|
||||
*/
|
||||
explicit Show_create_error_handler(THD *thd, TABLE_LIST *top_view) :
|
||||
m_top_view(top_view), m_handling(FALSE),
|
||||
m_view_access_denied_message_ptr(NULL)
|
||||
{
|
||||
|
||||
m_sctx = test(m_top_view->security_ctx) ?
|
||||
m_top_view->security_ctx : thd->security_ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
Lazy instantiation of 'view access denied' message. The purpose of the
|
||||
Show_create_error_handler is to hide details of underlying tables for
|
||||
which we have no privileges behind ER_VIEW_INVALID messages. But this
|
||||
obviously does not apply if we lack privileges on the view itself.
|
||||
Unfortunately the information about for which table privilege checking
|
||||
failed is not available at this point. The only way for us to check is by
|
||||
reconstructing the actual error message and see if it's the same.
|
||||
*/
|
||||
char* get_view_access_denied_message()
|
||||
{
|
||||
if (!m_view_access_denied_message_ptr)
|
||||
{
|
||||
m_view_access_denied_message_ptr= m_view_access_denied_message;
|
||||
my_snprintf(m_view_access_denied_message, MYSQL_ERRMSG_SIZE,
|
||||
ER(ER_TABLEACCESS_DENIED_ERROR), "SHOW VIEW",
|
||||
m_sctx->priv_user,
|
||||
m_sctx->host_or_ip, m_top_view->get_table_name());
|
||||
}
|
||||
return m_view_access_denied_message_ptr;
|
||||
}
|
||||
|
||||
bool handle_error(uint sql_errno, const char *message,
|
||||
MYSQL_ERROR::enum_warning_level level, THD *thd) {
|
||||
/*
|
||||
The handler does not handle the errors raised by itself.
|
||||
At this point we know if top_view is really a view.
|
||||
*/
|
||||
if (m_handling || !m_top_view->view)
|
||||
return FALSE;
|
||||
|
||||
m_handling= TRUE;
|
||||
|
||||
bool is_handled;
|
||||
|
||||
switch (sql_errno)
|
||||
{
|
||||
case ER_TABLEACCESS_DENIED_ERROR:
|
||||
if (!strcmp(get_view_access_denied_message(), message))
|
||||
{
|
||||
/* Access to top view is not granted, don't interfere. */
|
||||
is_handled= FALSE;
|
||||
break;
|
||||
}
|
||||
case ER_COLUMNACCESS_DENIED_ERROR:
|
||||
case ER_VIEW_NO_EXPLAIN: /* Error was anonymized, ignore all the same. */
|
||||
case ER_PROCACCESS_DENIED_ERROR:
|
||||
is_handled= TRUE;
|
||||
break;
|
||||
|
||||
case ER_NO_SUCH_TABLE:
|
||||
/* Established behavior: warn if underlying tables are missing. */
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_VIEW_INVALID,
|
||||
ER(ER_VIEW_INVALID),
|
||||
m_top_view->get_db_name(),
|
||||
m_top_view->get_table_name());
|
||||
is_handled= TRUE;
|
||||
break;
|
||||
|
||||
case ER_SP_DOES_NOT_EXIST:
|
||||
/* Established behavior: warn if underlying functions are missing. */
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_VIEW_INVALID,
|
||||
ER(ER_VIEW_INVALID),
|
||||
m_top_view->get_db_name(),
|
||||
m_top_view->get_table_name());
|
||||
is_handled= TRUE;
|
||||
break;
|
||||
default:
|
||||
is_handled= FALSE;
|
||||
}
|
||||
|
||||
m_handling= FALSE;
|
||||
return is_handled;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
bool
|
||||
mysqld_show_create(THD *thd, TABLE_LIST *table_list)
|
||||
{
|
||||
|
@ -594,26 +714,13 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
|
|||
/* We want to preserve the tree for views. */
|
||||
thd->lex->view_prepare_mode= TRUE;
|
||||
|
||||
/* Only one table for now, but VIEW can involve several tables */
|
||||
if (open_normal_and_derived_tables(thd, table_list, 0))
|
||||
{
|
||||
if (!table_list->view ||
|
||||
(thd->is_error() && thd->main_da.sql_errno() != ER_VIEW_INVALID))
|
||||
Show_create_error_handler view_error_suppressor(thd, table_list);
|
||||
thd->push_internal_handler(&view_error_suppressor);
|
||||
bool error= open_normal_and_derived_tables(thd, table_list, 0);
|
||||
thd->pop_internal_handler();
|
||||
if (error && thd->main_da.is_error())
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
/*
|
||||
Clear all messages with 'error' level status and
|
||||
issue a warning with 'warning' level status in
|
||||
case of invalid view and last error is ER_VIEW_INVALID
|
||||
*/
|
||||
mysql_reset_errors(thd, true);
|
||||
thd->clear_error();
|
||||
|
||||
push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_VIEW_INVALID,
|
||||
ER(ER_VIEW_INVALID),
|
||||
table_list->view_db.str,
|
||||
table_list->view_name.str);
|
||||
}
|
||||
|
||||
/* TODO: add environment variables show when it become possible */
|
||||
|
|
|
@ -3338,7 +3338,12 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
|
|||
|
||||
|
||||
/**
|
||||
Hide errors which show view underlying table information
|
||||
Hide errors which show view underlying table information.
|
||||
There are currently two mechanisms at work that handle errors for views,
|
||||
this one and a more general mechanism based on an Internal_error_handler,
|
||||
see Show_create_error_handler. The latter handles errors encountered during
|
||||
execution of SHOW CREATE VIEW, while the machanism using this method is
|
||||
handles SELECT from views. The two methods should not clash.
|
||||
|
||||
@param[in,out] thd thread handler
|
||||
|
||||
|
@ -3347,6 +3352,8 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
|
|||
|
||||
void TABLE_LIST::hide_view_error(THD *thd)
|
||||
{
|
||||
if (thd->get_internal_handler())
|
||||
return;
|
||||
/* Hide "Unknown column" or "Unknown function" error */
|
||||
DBUG_ASSERT(thd->is_error());
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue