aboutsummaryrefslogtreecommitdiff
path: root/src/backend/rewrite/locks.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/rewrite/locks.c')
-rw-r--r--src/backend/rewrite/locks.c103
1 files changed, 102 insertions, 1 deletions
diff --git a/src/backend/rewrite/locks.c b/src/backend/rewrite/locks.c
index 04698be13e3..46727d94c6e 100644
--- a/src/backend/rewrite/locks.c
+++ b/src/backend/rewrite/locks.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.10 1998/06/15 19:29:06 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.11 1998/08/24 01:37:56 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,6 +18,14 @@
#include "utils/syscache.h" /* for SearchSysCache */
#include "rewrite/locks.h" /* for rewrite specific lock defns */
+#include "access/heapam.h" /* for ACL checking */
+#include "utils/syscache.h"
+#include "utils/acl.h"
+#include "utils/builtins.h"
+#include "catalog/pg_shadow.h"
+
+static void checkLockPerms(List *locks, Query *parsetree, int rt_index);
+
/*
* ThisLockWasTriggered
*
@@ -156,5 +164,98 @@ matchLocks(CmdType event,
}
}
+ checkLockPerms(real_locks, parsetree, varno);
+
return (real_locks);
}
+
+
+static void
+checkLockPerms(List *locks, Query *parsetree, int rt_index)
+{
+ Relation ev_rel;
+ HeapTuple usertup;
+ char *evowner;
+ RangeTblEntry *rte;
+ int32 reqperm;
+ int32 aclcheck_res;
+ int i;
+ List *l;
+
+ if (locks == NIL)
+ return;
+
+ /*
+ * Get the usename of the rules event relation owner
+ */
+ rte = (RangeTblEntry *)nth(rt_index - 1, parsetree->rtable);
+ ev_rel = heap_openr(rte->relname);
+ usertup = SearchSysCacheTuple(USESYSID,
+ ObjectIdGetDatum(ev_rel->rd_rel->relowner),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(usertup))
+ {
+ elog(ERROR, "cache lookup for userid %d failed",
+ ev_rel->rd_rel->relowner);
+ }
+ heap_close(ev_rel);
+ evowner = nameout(&(((Form_pg_shadow) GETSTRUCT(usertup))->usename));
+
+ /*
+ * Check all the locks, that should get fired on this query
+ */
+ foreach (l, locks) {
+ RewriteRule *onelock = (RewriteRule *)lfirst(l);
+ List *action;
+
+ /*
+ * In each lock check every action
+ */
+ foreach (action, onelock->actions) {
+ Query *query = (Query *)lfirst(action);
+
+ /*
+ * In each action check every rangetable entry
+ * for read/write permission of the event relations
+ * owner depending on if it's the result relation
+ * (write) or not (read)
+ */
+ for (i = 2; i < length(query->rtable); i++) {
+ if (i + 1 == query->resultRelation)
+ switch (query->resultRelation) {
+ case CMD_INSERT:
+ reqperm = ACL_AP;
+ break;
+ default:
+ reqperm = ACL_WR;
+ break;
+ }
+ else
+ reqperm = ACL_RD;
+
+ rte = (RangeTblEntry *)nth(i, query->rtable);
+ aclcheck_res = pg_aclcheck(rte->relname,
+ evowner, reqperm);
+ if (aclcheck_res != ACLCHECK_OK) {
+ elog(ERROR, "%s: %s",
+ rte->relname,
+ aclcheck_error_strings[aclcheck_res]);
+ }
+
+ /*
+ * So this is allowed due to the permissions
+ * of the rules event relation owner. But
+ * let's see if the next one too
+ */
+ rte->skipAcl = TRUE;
+ }
+ }
+ }
+
+ /*
+ * Phew, that was close
+ */
+ return;
+}
+
+