aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/ri_triggers.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/ri_triggers.c')
-rw-r--r--src/backend/utils/adt/ri_triggers.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index e4d7b2c34b6..ed4a3769e45 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -2303,6 +2303,18 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
if (!ExecCheckRTPerms(list_make2(fkrte, pkrte), false))
return false;
+ /*
+ * Also punt if RLS is enabled on either table unless this role has the
+ * bypassrls right or is the table owner of the table(s) involved which
+ * have RLS enabled.
+ */
+ if (!has_bypassrls_privilege(GetUserId()) &&
+ ((pk_rel->rd_rel->relhasrowsecurity &&
+ !pg_class_ownercheck(pkrte->relid, GetUserId())) ||
+ (fk_rel->rd_rel->relhasrowsecurity &&
+ !pg_class_ownercheck(fkrte->relid, GetUserId()))))
+ return false;
+
/*----------
* The query string built is:
* SELECT fk.keycols FROM ONLY relname fk
@@ -2956,6 +2968,7 @@ ri_PlanCheck(const char *querystr, int nargs, Oid *argtypes,
Relation query_rel;
Oid save_userid;
int save_sec_context;
+ int temp_sec_context;
/*
* Use the query type code to determine whether the query is run against
@@ -2968,8 +2981,22 @@ ri_PlanCheck(const char *querystr, int nargs, Oid *argtypes,
/* Switch to proper UID to perform check as */
GetUserIdAndSecContext(&save_userid, &save_sec_context);
+
+ /*
+ * Row-level security should be disabled in the case where a foreign-key
+ * relation is queried to check existence of tuples that references the
+ * primary-key being modified.
+ */
+ temp_sec_context = save_sec_context | SECURITY_LOCAL_USERID_CHANGE;
+ if (qkey->constr_queryno == RI_PLAN_CHECK_LOOKUPPK
+ || qkey->constr_queryno == RI_PLAN_CHECK_LOOKUPPK_FROM_PK
+ || qkey->constr_queryno == RI_PLAN_RESTRICT_DEL_CHECKREF
+ || qkey->constr_queryno == RI_PLAN_RESTRICT_UPD_CHECKREF)
+ temp_sec_context |= SECURITY_ROW_LEVEL_DISABLED;
+
+
SetUserIdAndSecContext(RelationGetForm(query_rel)->relowner,
- save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
+ temp_sec_context);
/* Create the plan */
qplan = SPI_prepare(querystr, nargs, argtypes);