]> granicus.if.org Git - postgresql/commitdiff
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 $@