diff --git a/src/backend/rewrite/rowsecurity.c b/src/backend/rewrite/rowsecurity.c index 835540cd33..e9f532ce69 100644 --- a/src/backend/rewrite/rowsecurity.c +++ b/src/backend/rewrite/rowsecurity.c @@ -47,6 +47,7 @@ #include "nodes/pg_list.h" #include "nodes/plannodes.h" #include "parser/parsetree.h" +#include "rewrite/rewriteDefine.h" #include "rewrite/rewriteHandler.h" #include "rewrite/rewriteManip.h" #include "rewrite/rowsecurity.h" @@ -381,6 +382,13 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index, table_close(rel, NoLock); + /* + * Copy checkAsUser to the row security quals and WithCheckOption checks, + * in case they contain any subqueries referring to other relations. + */ + setRuleCheckAsUser((Node *) *securityQuals, rte->checkAsUser); + setRuleCheckAsUser((Node *) *withCheckOptions, rte->checkAsUser); + /* * Mark this query as having row security, so plancache can invalidate it * when necessary (eg: role changes) diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out index 4b53401b00..d764991d7b 100644 --- a/src/test/regress/expected/rowsecurity.out +++ b/src/test/regress/expected/rowsecurity.out @@ -3910,6 +3910,33 @@ DROP OWNED BY regress_rls_dob_role1; DROP POLICY p1 ON dob_t2; -- should succeed DROP USER regress_rls_dob_role1; DROP USER regress_rls_dob_role2; +-- Bug #15708: view + table with RLS should check policies as view owner +CREATE TABLE ref_tbl (a int); +INSERT INTO ref_tbl VALUES (1); +CREATE TABLE rls_tbl (a int); +INSERT INTO rls_tbl VALUES (10); +ALTER TABLE rls_tbl ENABLE ROW LEVEL SECURITY; +CREATE POLICY p1 ON rls_tbl USING (EXISTS (SELECT 1 FROM ref_tbl)); +GRANT SELECT ON ref_tbl TO regress_rls_bob; +GRANT SELECT ON rls_tbl TO regress_rls_bob; +CREATE VIEW rls_view AS SELECT * FROM rls_tbl; +ALTER VIEW rls_view OWNER TO regress_rls_bob; +GRANT SELECT ON rls_view TO regress_rls_alice; +SET SESSION AUTHORIZATION regress_rls_alice; +SELECT * FROM ref_tbl; -- Permission denied +ERROR: permission denied for table ref_tbl +SELECT * FROM rls_tbl; -- Permission denied +ERROR: permission denied for table rls_tbl +SELECT * FROM rls_view; -- OK + a +---- + 10 +(1 row) + +RESET SESSION AUTHORIZATION; +DROP VIEW rls_view; +DROP TABLE rls_tbl; +DROP TABLE ref_tbl; -- -- Clean up objects -- diff --git a/src/test/regress/sql/rowsecurity.sql b/src/test/regress/sql/rowsecurity.sql index ea83153e96..df8fe11db1 100644 --- a/src/test/regress/sql/rowsecurity.sql +++ b/src/test/regress/sql/rowsecurity.sql @@ -1764,6 +1764,32 @@ DROP POLICY p1 ON dob_t2; -- should succeed DROP USER regress_rls_dob_role1; DROP USER regress_rls_dob_role2; +-- Bug #15708: view + table with RLS should check policies as view owner +CREATE TABLE ref_tbl (a int); +INSERT INTO ref_tbl VALUES (1); + +CREATE TABLE rls_tbl (a int); +INSERT INTO rls_tbl VALUES (10); +ALTER TABLE rls_tbl ENABLE ROW LEVEL SECURITY; +CREATE POLICY p1 ON rls_tbl USING (EXISTS (SELECT 1 FROM ref_tbl)); + +GRANT SELECT ON ref_tbl TO regress_rls_bob; +GRANT SELECT ON rls_tbl TO regress_rls_bob; + +CREATE VIEW rls_view AS SELECT * FROM rls_tbl; +ALTER VIEW rls_view OWNER TO regress_rls_bob; +GRANT SELECT ON rls_view TO regress_rls_alice; + +SET SESSION AUTHORIZATION regress_rls_alice; +SELECT * FROM ref_tbl; -- Permission denied +SELECT * FROM rls_tbl; -- Permission denied +SELECT * FROM rls_view; -- OK +RESET SESSION AUTHORIZATION; + +DROP VIEW rls_view; +DROP TABLE rls_tbl; +DROP TABLE ref_tbl; + -- -- Clean up objects --