First step done,
authorMarc G. Fournier <scrappy@hub.org>
Sat, 21 Feb 1998 06:32:15 +0000 (06:32 +0000)
committerMarc G. Fournier <scrappy@hub.org>
Sat, 21 Feb 1998 06:32:15 +0000 (06:32 +0000)
    below  is  the patch to have views to override the permission
    checks for the accessed tables. Now we can do the following:

    CREATE VIEW db_user AS SELECT
         usename,
         usesysid,
         usecreatedb,
         usetrace,
         usecatupd,
         '**********'::text as passwd,
         valuntil
        FROM pg_user;

    REVOKE ALL ON pg_user FROM public;
    REVOKE ALL ON db_user FROM public;
    GRANT SELECT ON db_user TO public;

src/backend/executor/execMain.c
src/backend/nodes/copyfuncs.c
src/backend/parser/gram.c
src/backend/parser/scan.c
src/backend/rewrite/rewriteHandler.c
src/include/nodes/parsenodes.h
src/interfaces/ecpg/Makefile

index 8702ede2483763efc43bfcbc8f954ad05316e392..760d277dee948ca7d5490aa2c0aef8ce9fa5ae79 100644 (file)
@@ -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),
index 35dec7f1d96d3ec18668d4454d83fc44d28bebc3..344b409519008a2638e5e29786fb4d28f3a3059a 100644 (file)
@@ -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;
index 142f33fc236e67b2a383614d35c1cab0076d08b5..cbf49d2b60d124b4f599b368039330bd4c4254b2 100644 (file)
  *
  *
  * 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
 \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 *.
@@ -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"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
index 6abb33ffdab87d0e282b352c430e8fcba97ca84f..4fda82c9550e0f9ce02712f449fae24475bf6e13 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
index 415ce6e80f8fbcb83492d3bb0d110e321e73256e..1191507685b078f0c1c0b11ba89649c798d17ed1 100644 (file)
@@ -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"
 #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]);
+       }
+   }
+}
+
+
+
index 108949f8c783eadc80d5175235dbfd6934b23963..f91e1153732ed5b7db2508a3eeefd75f667f658c 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.47 1998/02/10 16:04:26 momjian Exp $
+ * $Id: parsenodes.h,v 1.48 1998/02/21 06:32:02 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -864,6 +864,7 @@ typedef struct RangeTblEntry
    Oid         relid;
    bool        inh;            /* inheritance? */
    bool        inFromCl;       /* comes from From Clause */
+   bool        skipAcl;        /* skip ACL check in executor */
 } RangeTblEntry;
 
 /*
index 7c2df8122ea7164a3f51714ea0d73f35d7bf0640..ee99aaeab500dae25f3e2096e00e0edb4e4db06b 100644 (file)
@@ -1,7 +1,5 @@
 SUBDIRS = include lib preproc doc
 
 all install uninstall clean:
-   $(MAKE) -C include $@
    $(MAKE) -C lib $@
    $(MAKE) -C preproc $@
-#  $(MAKE) -C doc $@