aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/ri_triggers.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2010-07-22 00:47:59 +0000
committerRobert Haas <rhaas@postgresql.org>2010-07-22 00:47:59 +0000
commitb8c6c71d1c513391975fc107a95f104aeeac3117 (patch)
treefac8a1a04bed94bd5944f1a3773aa4c4609e5f51 /src/backend/utils/adt/ri_triggers.c
parent9f8cf32b341f3af070c512c7d6ad7f6a5aa7505b (diff)
downloadpostgresql-b8c6c71d1c513391975fc107a95f104aeeac3117.tar.gz
postgresql-b8c6c71d1c513391975fc107a95f104aeeac3117.zip
Centralize DML permissions-checking logic.
Remove bespoke code in DoCopy and RI_Initial_Check, which now instead fabricate call ExecCheckRTPerms with a manufactured RangeTblEntry. This is intended to make it feasible for an enhanced security provider to actually make use of ExecutorCheckPerms_hook, but also has the advantage that RI_Initial_Check can allow use of the fast-path when column-level but not table-level permissions are present. KaiGai Kohei. Reviewed (in an earlier version) by Stephen Frost, and by me. Some further changes to the comments by me.
Diffstat (limited to 'src/backend/utils/adt/ri_triggers.c')
-rw-r--r--src/backend/utils/adt/ri_triggers.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index 2d0ab44b7de..080cb9c1ac2 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -15,7 +15,7 @@
*
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.118 2010/02/14 18:42:16 rhaas Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.119 2010/07/22 00:47:52 rhaas Exp $
*
* ----------
*/
@@ -31,10 +31,12 @@
#include "postgres.h"
#include "access/xact.h"
+#include "access/sysattr.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_type.h"
#include "commands/trigger.h"
+#include "executor/executor.h"
#include "executor/spi.h"
#include "parser/parse_coerce.h"
#include "parser/parse_relation.h"
@@ -2624,6 +2626,8 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
char fkrelname[MAX_QUOTED_REL_NAME_LEN];
char pkattname[MAX_QUOTED_NAME_LEN + 3];
char fkattname[MAX_QUOTED_NAME_LEN + 3];
+ RangeTblEntry *pkrte;
+ RangeTblEntry *fkrte;
const char *sep;
int i;
int old_work_mem;
@@ -2631,6 +2635,9 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
int spi_result;
SPIPlanPtr qplan;
+ /* Fetch constraint info. */
+ ri_FetchConstraintInfo(&riinfo, trigger, fk_rel, false);
+
/*
* Check to make sure current user has enough permissions to do the test
* query. (If not, caller can fall back to the trigger method, which
@@ -2638,12 +2645,29 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
*
* XXX are there any other show-stopper conditions to check?
*/
- if (pg_class_aclcheck(RelationGetRelid(fk_rel), GetUserId(), ACL_SELECT) != ACLCHECK_OK)
- return false;
- if (pg_class_aclcheck(RelationGetRelid(pk_rel), GetUserId(), ACL_SELECT) != ACLCHECK_OK)
- return false;
+ pkrte = makeNode(RangeTblEntry);
+ pkrte->rtekind = RTE_RELATION;
+ pkrte->relid = RelationGetRelid(pk_rel);
+ pkrte->requiredPerms = ACL_SELECT;
- ri_FetchConstraintInfo(&riinfo, trigger, fk_rel, false);
+ fkrte = makeNode(RangeTblEntry);
+ fkrte->rtekind = RTE_RELATION;
+ fkrte->relid = RelationGetRelid(fk_rel);
+ fkrte->requiredPerms = ACL_SELECT;
+
+ for (i = 0; i < riinfo.nkeys; i++)
+ {
+ int attno;
+
+ attno = riinfo.pk_attnums[i] - FirstLowInvalidHeapAttributeNumber;
+ pkrte->selectedCols = bms_add_member(pkrte->selectedCols, attno);
+
+ attno = riinfo.fk_attnums[i] - FirstLowInvalidHeapAttributeNumber;
+ fkrte->selectedCols = bms_add_member(fkrte->selectedCols, attno);
+ }
+
+ if (!ExecCheckRTPerms(list_make2(fkrte, pkrte), false))
+ return false;
/*----------
* The query string built is: