diff options
Diffstat (limited to 'src/backend/rewrite/rowsecurity.c')
-rw-r--r-- | src/backend/rewrite/rowsecurity.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/backend/rewrite/rowsecurity.c b/src/backend/rewrite/rowsecurity.c index b96c29d8f64..c20a17802b1 100644 --- a/src/backend/rewrite/rowsecurity.c +++ b/src/backend/rewrite/rowsecurity.c @@ -187,6 +187,33 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index, hasSubLinks); /* + * For the target relation, when there is a returning list, we need to + * collect up CMD_SELECT policies and add them via add_security_quals. + * This is because, for the RETURNING case, we have to filter any records + * which are not visible through an ALL or SELECT USING policy. + * + * We don't need to worry about the non-target relation case because we are + * checking the ALL and SELECT policies for those relations anyway (see + * above). + */ + if (root->returningList != NIL && + (commandType == CMD_UPDATE || commandType == CMD_DELETE)) + { + List *returning_permissive_policies; + List *returning_restrictive_policies; + + get_policies_for_relation(rel, CMD_SELECT, user_id, + &returning_permissive_policies, + &returning_restrictive_policies); + + add_security_quals(rt_index, + returning_permissive_policies, + returning_restrictive_policies, + securityQuals, + hasSubLinks); + } + + /* * For INSERT and UPDATE, add withCheckOptions to verify that any new * records added are consistent with the security policies. This will use * each policy's WITH CHECK clause, or its USING clause if no explicit @@ -233,6 +260,26 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index, withCheckOptions, hasSubLinks); + /* + * Get and add ALL/SELECT policies, if there is a RETURNING clause, + * also as WCO policies, again, to avoid silently dropping data. + */ + if (root->returningList != NIL) + { + List *conflict_returning_permissive_policies = NIL; + List *conflict_returning_restrictive_policies = NIL; + + get_policies_for_relation(rel, CMD_SELECT, user_id, + &conflict_returning_permissive_policies, + &conflict_returning_restrictive_policies); + add_with_check_options(rel, rt_index, + WCO_RLS_CONFLICT_CHECK, + conflict_returning_permissive_policies, + conflict_returning_restrictive_policies, + withCheckOptions, + hasSubLinks); + } + /* Enforce the WITH CHECK clauses of the UPDATE policies */ add_with_check_options(rel, rt_index, WCO_RLS_UPDATE_CHECK, |