*
*
* 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
-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.
#endif
#endif
\f
-#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 *.
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"
\f
yyvsp -= yylen;
yyssp -= yylen;
*
*
* 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"
#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 -
*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)
{
RewriteRule *rule,
int rt_index,
int relation_level,
+ Relation relation,
int *modified)
{
Query *rule_action = NULL;
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
{
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;
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]);
+ }
+ }
+}
+
+
+