aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/executor/execMain.c13
-rw-r--r--src/backend/nodes/copyfuncs.c3
-rw-r--r--src/backend/parser/gram.c8
-rw-r--r--src/backend/parser/scan.c4
-rw-r--r--src/backend/rewrite/rewriteHandler.c110
5 files changed, 124 insertions, 14 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 8702ede2483..760d277dee9 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -26,7 +26,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.42 1998/02/13 03:26:38 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.43 1998/02/21 06:31:37 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -299,6 +299,17 @@ ExecCheckPerms(CmdType operation,
{
RangeTblEntry *rte = lfirst(lp);
+ if (rte->skipAcl)
+ {
+ /*
+ * This happens if the access to this table is due
+ * to a view query rewriting - the rewrite handler
+ * checked the permissions against the view owner,
+ * so we just skip this entry.
+ */
+ continue;
+ }
+
relid = rte->relid;
htp = SearchSysCacheTuple(RELOID,
ObjectIdGetDatum(relid),
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 35dec7f1d96..344b4095190 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.38 1998/02/13 03:27:42 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.39 1998/02/21 06:31:40 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1495,6 +1495,7 @@ _copyRangeTblEntry(RangeTblEntry *from)
newnode->relid = from->relid;
newnode->inh = from->inh;
newnode->inFromCl = from->inFromCl;
+ newnode->skipAcl = from->skipAcl;
return newnode;
diff --git a/src/backend/parser/gram.c b/src/backend/parser/gram.c
index 142f33fc236..cbf49d2b60d 100644
--- a/src/backend/parser/gram.c
+++ b/src/backend/parser/gram.c
@@ -210,7 +210,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/Attic/gram.c,v 2.1 1998/02/18 07:28:06 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/Attic/gram.c,v 2.2 1998/02/21 06:31:46 scrappy Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -3753,7 +3753,7 @@ static const short yycheck[] = { 3,
-1, -1, -1, 172
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/lib/bison.simple"
+#line 3 "/usr/share/misc/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
@@ -3946,7 +3946,7 @@ __yy_memcpy (char *to, char *from, int count)
#endif
#endif
-#line 196 "/usr/lib/bison.simple"
+#line 196 "/usr/share/misc/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
@@ -9401,7 +9401,7 @@ case 842:
break;}
}
/* the action file gets copied in in place of this dollarsign */
-#line 498 "/usr/lib/bison.simple"
+#line 498 "/usr/share/misc/bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
diff --git a/src/backend/parser/scan.c b/src/backend/parser/scan.c
index 6abb33ffdab..4fda82c9550 100644
--- a/src/backend/parser/scan.c
+++ b/src/backend/parser/scan.c
@@ -1,7 +1,7 @@
/* A lexical scanner generated by flex */
/* Scanner skeleton version:
- * $Header: /cvsroot/pgsql/src/backend/parser/Attic/scan.c,v 1.14 1998/02/18 07:23:22 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/Attic/scan.c,v 1.15 1998/02/21 06:31:52 scrappy Exp $
*/
#define FLEX_SCANNER
@@ -547,7 +547,7 @@ char *yytext;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/Attic/scan.c,v 1.14 1998/02/18 07:23:22 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/Attic/scan.c,v 1.15 1998/02/21 06:31:52 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 415ce6e80f8..1191507685b 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -6,10 +6,11 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.11 1998/01/21 04:24:36 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.12 1998/02/21 06:31:57 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
+#include <string.h>
#include "postgres.h"
#include "miscadmin.h"
#include "utils/palloc.h"
@@ -29,13 +30,19 @@
#include "commands/creatinh.h"
#include "access/heapam.h"
+#include "utils/syscache.h"
+#include "utils/acl.h"
+#include "catalog/pg_user.h"
+
static void ApplyRetrieveRule(Query *parsetree, RewriteRule *rule,
- int rt_index, int relation_level, int *modified);
+ int rt_index, int relation_level,
+ Relation relation, int *modified);
static List *fireRules(Query *parsetree, int rt_index, CmdType event,
bool *instead_flag, List *locks, List **qual_products);
static void QueryRewriteSubLink(Node *node);
static List *QueryRewriteOne(Query *parsetree);
static List *deepRewriteQuery(Query *parsetree);
+static void CheckViewPerms(Relation view, List *rtable);
/*
* gatherRewriteMeta -
@@ -219,7 +226,7 @@ FireRetrieveRulesAtQuery(Query *parsetree,
*instead_flag = TRUE;
return rule_lock->actions;
}
- ApplyRetrieveRule(parsetree, rule_lock, rt_index, relation_level,
+ ApplyRetrieveRule(parsetree, rule_lock, rt_index, relation_level, relation,
&modified);
if (modified)
{
@@ -247,6 +254,7 @@ ApplyRetrieveRule(Query *parsetree,
RewriteRule *rule,
int rt_index,
int relation_level,
+ Relation relation,
int *modified)
{
Query *rule_action = NULL;
@@ -256,16 +264,41 @@ ApplyRetrieveRule(Query *parsetree,
int nothing,
rt_length;
int badsql = FALSE;
+ int viewAclOverride = FALSE;
rule_qual = rule->qual;
if (rule->actions)
{
if (length(rule->actions) > 1) /* ??? because we don't handle
- * rules with more than one
- * action? -ay */
+ * rules with more than one
+ * action? -ay */
+
+ /* WARNING!!!
+ * If we sometimes handle
+ * rules with more than one
+ * action, the view acl checks
+ * might get broken.
+ * viewAclOverride should only
+ * become true (below) if this
+ * is a relation_level, instead,
+ * select query - Jan
+ */
return;
rule_action = copyObject(lfirst(rule->actions));
nothing = FALSE;
+
+ /*
+ * If this rule is on the relation level, the rule action
+ * is a select and the rule is instead then it must be
+ * a view. Permissions for views now follow the owner of
+ * the view, not the current user.
+ */
+ if (relation_level && rule_action->commandType == CMD_SELECT
+ && rule->isInstead)
+ {
+ CheckViewPerms(relation, rule_action->rtable);
+ viewAclOverride = TRUE;
+ }
}
else
{
@@ -284,7 +317,30 @@ ApplyRetrieveRule(Query *parsetree,
rte->inFromCl = false;
}
rt_length = length(rtable);
- rtable = nconc(rtable, copyObject(rule_action->rtable));
+
+ if (viewAclOverride)
+ {
+ List *rule_rtable, *rule_rt;
+ RangeTblEntry *rte;
+
+ rule_rtable = copyObject(rule_action->rtable);
+ foreach(rule_rt, rule_rtable)
+ {
+ rte = lfirst(rule_rt);
+
+ /*
+ * tell the executor that the ACL check on this
+ * range table entry is already done
+ */
+ rte->skipAcl = true;
+ }
+
+ rtable = nconc(rtable, rule_rtable);
+ }
+ else
+ {
+ rtable = nconc(rtable, copyObject(rule_action->rtable));
+ }
parsetree->rtable = rtable;
rule_action->rtable = rtable;
@@ -750,3 +806,45 @@ deepRewriteQuery(Query *parsetree)
return rewritten;
}
+
+
+static void
+CheckViewPerms(Relation view, List *rtable)
+{
+ HeapTuple utup;
+ NameData uname;
+ List *rt;
+ RangeTblEntry *rte;
+ int32 aclcheck_res;
+
+ /*
+ * get the usename of the view's owner
+ */
+ utup = SearchSysCacheTuple(USESYSID, view->rd_rel->relowner, 0, 0, 0);
+ if (!HeapTupleIsValid(utup))
+ {
+ elog(ERROR, "cache lookup for userid %d failed",
+ view->rd_rel->relowner);
+ }
+ StrNCpy(uname.data,
+ ((Form_pg_user) GETSTRUCT(utup))->usename.data,
+ NAMEDATALEN);
+
+ /*
+ * check that we have read access to all the
+ * classes in the range table of the view
+ */
+ foreach(rt, rtable)
+ {
+ rte = (RangeTblEntry *)lfirst(rt);
+
+ aclcheck_res = pg_aclcheck(rte->relname, uname.data, ACL_RD);
+ if (aclcheck_res != ACLCHECK_OK)
+ {
+ elog(ERROR, "%s: %s", rte->relname, aclcheck_error_strings[aclcheck_res]);
+ }
+ }
+}
+
+
+