Code review for GRANT CONNECT patch. Spell the privilege as CONNECT not
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 30 Apr 2006 21:15:33 +0000 (21:15 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 30 Apr 2006 21:15:33 +0000 (21:15 +0000)
CONNECTION, fix a number of places that were missed (eg pg_dump support),
avoid executing an extra search of pg_database during startup.

12 files changed:
doc/src/sgml/client-auth.sgml
doc/src/sgml/ddl.sgml
doc/src/sgml/func.sgml
doc/src/sgml/ref/grant.sgml
doc/src/sgml/ref/revoke.sgml
doc/src/sgml/user-manag.sgml
src/backend/catalog/aclchk.c
src/backend/utils/adt/acl.c
src/backend/utils/init/postinit.c
src/bin/pg_dump/dumputils.c
src/bin/psql/tab-complete.c
src/include/utils/acl.h

index 2185eebeb05cd8e21223cc528cb3707f9e59192e..22fe521bfb05c7874a5f2c61c7ca4eb96c3a40a8 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.88 2006/04/30 02:09:06 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.89 2006/04/30 21:15:32 tgl Exp $ -->
 
 <chapter id="client-authentication">
  <title>Client Authentication</title>
@@ -206,8 +206,6 @@ hostnossl  <replaceable>database</replaceable>  <replaceable>user</replaceable>
        Multiple user names can be supplied by separating them with commas.
        A separate file containing user names can be specified by preceding the
        file name with <literal>@</>.
-       User and group connectivity can also be restricted by <command>GRANT
-       CONNECTION ON DATABASE</>.
       </para>
      </listitem>
     </varlistentry>
@@ -436,6 +434,17 @@ hostnossl  <replaceable>database</replaceable>  <replaceable>user</replaceable>
    re-read the file.
   </para>
 
+  <tip>
+   <para>
+    To connect to a particular database, a user must not only pass the
+    <filename>pg_hba.conf</filename> checks, but must have the
+    <literal>CONNECT</> privilege for the database.  If you wish to
+    restrict which users can connect to which databases, it's usually
+    easier to control this by granting/revoking <literal>CONNECT</> privilege
+    than to put the rules into <filename>pg_hba.conf</filename> entries.
+   </para>
+  </tip>
+
   <para>
    Some examples of <filename>pg_hba.conf</filename> entries are shown in
    <xref linkend="example-pg-hba.conf">. See the next section for details on the
index 77bc1dd4970d2e5621de205a8964cda4c557a42b..a6fb4b3691f90c005ba1057939e18bdeeec361eb 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/ddl.sgml,v 1.56 2006/04/23 03:39:50 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/ddl.sgml,v 1.57 2006/04/30 21:15:32 tgl Exp $ -->
 
 <chapter id="ddl">
  <title>Data Definition</title>
@@ -1343,8 +1343,9 @@ ALTER TABLE products RENAME TO items;
    There are several different privileges: <literal>SELECT</>,
    <literal>INSERT</>, <literal>UPDATE</>, <literal>DELETE</>,
    <literal>RULE</>, <literal>REFERENCES</>, <literal>TRIGGER</>,
-   <literal>CREATE</>, <literal>TEMPORARY</>, <literal>EXECUTE</>, and
-   <literal>USAGE</>.  The privileges applicable to a particular
+   <literal>CREATE</>, <literal>CONNECT</>, <literal>TEMPORARY</>,
+   <literal>EXECUTE</>, and <literal>USAGE</>.
+   The privileges applicable to a particular
    object vary depending on the object's type (table, function, etc).
    For complete information on the different types of privileges
    supported by <productname>PostgreSQL</productname>, refer to the
index b53bdca6fc397b4e0d786d0952da8a114212e3f4..1c6738b8cb4b3a22e3cb805213509ed8c1c50c93 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.315 2006/04/25 00:25:15 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.316 2006/04/30 21:15:32 tgl Exp $ -->
 
  <chapter id="functions">
   <title>Functions and Operators</title>
@@ -9227,6 +9227,7 @@ SELECT has_table_privilege('myschema.mytable', 'select');
     arguments are analogous to <function>has_table_privilege</function>.
     The desired access privilege type must evaluate to
     <literal>CREATE</literal>,
+    <literal>CONNECT</literal>,
     <literal>TEMPORARY</literal>, or
     <literal>TEMP</literal> (which is equivalent to
     <literal>TEMPORARY</literal>).
index 03060f97212957c50a4d03e477768145a446385e..c6073dc35e451d7714f47835cf758edb760c9a5f 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.53 2006/04/30 02:09:06 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.54 2006/04/30 21:15:33 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -30,7 +30,7 @@ GRANT { { USAGE | SELECT | UPDATE }
     ON SEQUENCE <replaceable class="PARAMETER">sequencename</replaceable> [, ...]
     TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
 
-GRANT { { CREATE | TEMPORARY | TEMP | CONNECTION } [,...] | ALL [ PRIVILEGES ] }
+GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
     ON DATABASE <replaceable>dbname</replaceable> [, ...]
     TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
 
@@ -118,7 +118,8 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...]
    Depending on the type of object, the initial default privileges may
    include granting some privileges to <literal>PUBLIC</literal>.
    The default is no public access for tables, schemas, and tablespaces;
-   <literal>TEMP</> table creation privilege for databases;
+   <literal>CONNECT</> privilege and <literal>TEMP</> table creation privilege
+   for databases;
    <literal>EXECUTE</> privilege for functions; and
    <literal>USAGE</> privilege for languages.
    The object owner may of course revoke these privileges.  (For maximum
@@ -230,13 +231,12 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...]
     </varlistentry>
 
     <varlistentry>
-     <term>CONNECTION</term>
+     <term>CONNECT</term>
      <listitem>
       <para>
-       Allows the ability to connect to the specified database.
-       By default, Grant permissions allow users to connect to any database,
-       though <filename>pg_hba.conf</> can add additional connection
-       restrictions.
+       Allows the user to connect to the specified database.  This
+       privilege is checked at connection startup (in addition to checking
+       any restrictions imposed by <filename>pg_hba.conf</>).
       </para>
      </listitem>
     </varlistentry>
@@ -429,7 +429,7 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...]
                   X -- EXECUTE
                   U -- USAGE
                   C -- CREATE
-                  c -- CONNECTION
+                  c -- CONNECT
                   T -- TEMPORARY
             arwdRxt -- ALL PRIVILEGES (for tables)
                   * -- grant option for preceding privilege
index 034b946111c7a693b7372d14e174ab29eebc10c0..bccb8010b5f803d5f01cec8652bf90d64962a46e 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.37 2006/04/30 02:09:06 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.38 2006/04/30 21:15:33 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -35,7 +35,7 @@ REVOKE [ GRANT OPTION FOR ]
     [ CASCADE | RESTRICT ]
 
 REVOKE [ GRANT OPTION FOR ]
-    { { CREATE | TEMPORARY | TEMP | CONNECTION } [,...] | ALL [ PRIVILEGES ] }
+    { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
     ON DATABASE <replaceable>dbname</replaceable> [, ...]
     FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
     [ CASCADE | RESTRICT ]
index d05a9d3b047896a0503f9003ee10be965f8bf2df..41e6020091993e3607a50586ac3b172a85fd0fa0 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/user-manag.sgml,v 1.34 2006/03/10 19:10:49 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/user-manag.sgml,v 1.35 2006/04/30 21:15:32 tgl Exp $ -->
 
 <chapter id="user-manag">
  <title>Database Roles and Privileges</title>
@@ -294,9 +294,9 @@ ALTER ROLE myname SET enable_indexscan TO off;
    There are several different kinds of privilege: <literal>SELECT</>,
    <literal>INSERT</>, <literal>UPDATE</>, <literal>DELETE</>,
    <literal>RULE</>, <literal>REFERENCES</>, <literal>TRIGGER</>,
-   <literal>CREATE</>, <literal>TEMPORARY</>, <literal>EXECUTE</>,
-   and <literal>USAGE</>. For more
-   information on the different types of privileges supported by
+   <literal>CREATE</>, <literal>CONNECT</>, <literal>TEMPORARY</>,
+   <literal>EXECUTE</>, and <literal>USAGE</>.
+   For more information on the different types of privileges supported by
    <productname>PostgreSQL</productname>, see the
    <xref linkend="sql-grant" endterm="sql-grant-title"> reference page.
   </para>
index 3b9701db077bf038cfdcd4d43d79c2e8f360dc02..a74c28e5b3d1c3ea9b9f1680fb695cc171a25be9 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.126 2006/04/30 02:09:07 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.127 2006/04/30 21:15:33 tgl Exp $
  *
  * NOTES
  *   See acl.h.
@@ -1368,7 +1368,7 @@ string_to_privilege(const char *privname)
        return ACL_CREATE_TEMP;
    if (strcmp(privname, "temp") == 0)
        return ACL_CREATE_TEMP;
-   if (strcmp(privname, "connection") == 0)
+   if (strcmp(privname, "connect") == 0)
        return ACL_CONNECT;
    ereport(ERROR,
            (errcode(ERRCODE_SYNTAX_ERROR),
@@ -1404,7 +1404,7 @@ privilege_to_string(AclMode privilege)
        case ACL_CREATE_TEMP:
            return "TEMP";
        case ACL_CONNECT:
-           return "CONNECTION";
+           return "CONNECT";
        default:
            elog(ERROR, "unrecognized privilege: %d", (int) privilege);
    }
@@ -1661,10 +1661,6 @@ pg_database_aclmask(Oid db_oid, Oid roleid,
    ScanKeyData entry[1];
    SysScanDesc scan;
    HeapTuple   tuple;
-   Datum       aclDatum;
-   bool        isNull;
-   Acl        *acl;
-   Oid         ownerId;
 
    /* Superusers bypass all permission checking. */
    if (superuser_arg(roleid))
@@ -1688,10 +1684,33 @@ pg_database_aclmask(Oid db_oid, Oid roleid,
                (errcode(ERRCODE_UNDEFINED_DATABASE),
                 errmsg("database with OID %u does not exist", db_oid)));
 
-   ownerId = ((Form_pg_database) GETSTRUCT(tuple))->datdba;
+   result = pg_database_tuple_aclmask(tuple, RelationGetDescr(pg_database),
+                                      roleid, mask, how);
+
+   systable_endscan(scan);
+   heap_close(pg_database, AccessShareLock);
+
+   return result;
+}
+
+/*
+ * This is split out so that ReverifyMyDatabase can perform an ACL check
+ * without a whole extra search of pg_database
+ */
+AclMode
+pg_database_tuple_aclmask(HeapTuple db_tuple, TupleDesc tupdesc,
+                         Oid roleid, AclMode mask, AclMaskHow how)
+{
+   AclMode     result;
+   Datum       aclDatum;
+   bool        isNull;
+   Acl        *acl;
+   Oid         ownerId;
+
+   ownerId = ((Form_pg_database) GETSTRUCT(db_tuple))->datdba;
 
-   aclDatum = heap_getattr(tuple, Anum_pg_database_datacl,
-                           RelationGetDescr(pg_database), &isNull);
+   aclDatum = heap_getattr(db_tuple, Anum_pg_database_datacl,
+                           tupdesc, &isNull);
 
    if (isNull)
    {
@@ -1711,9 +1730,6 @@ pg_database_aclmask(Oid db_oid, Oid roleid,
    if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
        pfree(acl);
 
-   systable_endscan(scan);
-   heap_close(pg_database, AccessShareLock);
-
    return result;
 }
 
index 4f64104ad3de7f1cf600031d229933438c9c0a42..0fa61196ea7c7be9cacda971d411a709e292fa86 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.132 2006/04/30 02:09:07 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.133 2006/04/30 21:15:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -553,7 +553,8 @@ acldefault(GrantObjectType objtype, Oid ownerId)
            owner_default = ACL_ALL_RIGHTS_SEQUENCE;
            break;
        case ACL_OBJECT_DATABASE:
-           world_default = ACL_CREATE_TEMP | ACL_CONNECT;  /* not NO_RIGHTS! */
+           /* for backwards compatibility, grant some rights by default */
+           world_default = ACL_CREATE_TEMP | ACL_CONNECT;
            owner_default = ACL_ALL_RIGHTS_DATABASE;
            break;
        case ACL_OBJECT_FUNCTION:
@@ -1341,6 +1342,8 @@ convert_priv_string(text *priv_type_text)
        return ACL_CREATE_TEMP;
    if (pg_strcasecmp(priv_type, "TEMPORARY") == 0)
        return ACL_CREATE_TEMP;
+   if (pg_strcasecmp(priv_type, "CONNECT") == 0)
+       return ACL_CONNECT;
 
    ereport(ERROR,
            (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@@ -1778,6 +1781,11 @@ convert_database_priv_string(text *priv_type_text)
    if (pg_strcasecmp(priv_type, "TEMP WITH GRANT OPTION") == 0)
        return ACL_GRANT_OPTION_FOR(ACL_CREATE_TEMP);
 
+   if (pg_strcasecmp(priv_type, "CONNECT") == 0)
+       return ACL_CONNECT;
+   if (pg_strcasecmp(priv_type, "CONNECT WITH GRANT OPTION") == 0)
+       return ACL_GRANT_OPTION_FOR(ACL_CONNECT);
+
    ereport(ERROR,
            (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
             errmsg("unrecognized privilege type: \"%s\"", priv_type)));
index 63135d2d1e305862030a43cfc13403c0f80b383c..e89df5bb3afa19a5ecbba40ce9d61408a29f52b9 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.163 2006/04/30 02:09:07 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.164 2006/04/30 21:15:33 tgl Exp $
  *
  *
  *-------------------------------------------------------------------------
@@ -51,7 +51,7 @@
 
 
 static bool FindMyDatabase(const char *name, Oid *db_id, Oid *db_tablespace);
-static void ReverifyMyDatabase(const char *name, const char *user_name);
+static void ReverifyMyDatabase(const char *name, bool am_superuser);
 static void InitCommunication(void);
 static void ShutdownPostgres(int code, Datum arg);
 static bool ThereIsAtLeastOneRole(void);
@@ -127,12 +127,11 @@ FindMyDatabase(const char *name, Oid *db_id, Oid *db_tablespace)
  * of pg_database.
  *
  * To avoid having to read pg_database more times than necessary
- * during session startup, this place is also fitting to set up any
- * database-specific configuration variables.
+ * during session startup, this place is also fitting to check CONNECT
+ * privilege and set up any database-specific configuration variables.
  */
 static void
-ReverifyMyDatabase(const char *name, const char *user_name)
+ReverifyMyDatabase(const char *name, bool am_superuser)
 {
    Relation    pgdbrel;
    SysScanDesc pgdbscan;
@@ -195,6 +194,22 @@ ReverifyMyDatabase(const char *name, const char *user_name)
             errmsg("database \"%s\" is not currently accepting connections",
                    name)));
 
+       /*
+        * Check privilege to connect to the database.  To avoid making
+        * a whole extra search of pg_database here, we don't go through
+        * pg_database_aclcheck, but instead use a lower-level routine
+        * that we can pass the pg_database tuple to.
+        */
+       if (!am_superuser &&
+           pg_database_tuple_aclmask(tup, RelationGetDescr(pgdbrel),
+                                     GetUserId(),
+                                     ACL_CONNECT, ACLMASK_ANY) == 0)
+           ereport(FATAL,
+                   (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                    errmsg("permission denied for database %s",
+                           NameStr(dbform->datname)),
+                    errdetail("User does not have CONNECT privilege.")));
+
        /*
         * Check connection limit for this database.
         *
@@ -206,29 +221,12 @@ ReverifyMyDatabase(const char *name, const char *user_name)
         * just document that the connection limit is approximate.
         */
        if (dbform->datconnlimit >= 0 &&
-           !superuser() &&
+           !am_superuser &&
            CountDBBackends(MyDatabaseId) > dbform->datconnlimit)
            ereport(FATAL,
                    (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
                     errmsg("too many connections for database \"%s\"",
                            name)));
-
-       /*
-        * Checking for privilege to connect to the database
-        * We want to bypass the test if we are running in bootstrap mode
-        */
-       if (!IsBootstrapProcessingMode())
-       {
-               if(pg_database_aclcheck(MyDatabaseId,GetUserId()
-                   ,ACL_CONNECT) != ACLCHECK_OK )
-               {
-                   ereport(FATAL,
-                           (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-                               errmsg("couldn't connect to database %s", NameStr(dbform->datname)),
-                               errdetail("User %s doesn't have the CONNECTION privilege for database %s.",
-                                user_name, NameStr(dbform->datname))));                
-               }
-       }
    }
 
    /*
@@ -476,15 +474,20 @@ InitPostgres(const char *dbname, const char *username)
    RelationCacheInitializePhase2();
 
    /*
-    * Figure out our postgres user id.  In standalone mode and in the
-    * autovacuum process, we use a fixed id, otherwise we figure it out from
-    * the authenticated user name.
+    * Figure out our postgres user id, and see if we are a superuser.
+    *
+    * In standalone mode and in the autovacuum process, we use a fixed id,
+    * otherwise we figure it out from the authenticated user name.
     */
    if (bootstrap || autovacuum)
+   {
        InitializeSessionUserIdStandalone();
+       am_superuser = true;
+   }
    else if (!IsUnderPostmaster)
    {
        InitializeSessionUserIdStandalone();
+       am_superuser = true;
        if (!ThereIsAtLeastOneRole())
            ereport(WARNING,
                    (errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -496,8 +499,12 @@ InitPostgres(const char *dbname, const char *username)
    {
        /* normal multiuser case */
        InitializeSessionUserId(username);
+       am_superuser = superuser();
    }
 
+   /* set up ACL framework (so ReverifyMyDatabase can check permissions) */
+   initialize_acl();
+
    /*
     * Unless we are bootstrapping, double-check that InitMyDatabaseInfo() got
     * a correct result.  We can't do this until all the database-access
@@ -505,7 +512,7 @@ InitPostgres(const char *dbname, const char *username)
     * superuser, so the above stuff has to happen first.)
     */
    if (!bootstrap)
-       ReverifyMyDatabase(dbname,username);
+       ReverifyMyDatabase(dbname, am_superuser);
 
    /*
     * Final phase of relation cache startup: write a new cache file if
@@ -514,14 +521,6 @@ InitPostgres(const char *dbname, const char *username)
     */
    RelationCacheInitializePhase3();
 
-   /*
-    * Check if user is a superuser.
-    */
-   if (bootstrap || autovacuum)
-       am_superuser = true;
-   else
-       am_superuser = superuser();
-
    /*
     * Check a normal user hasn't connected to a superuser reserved slot.
     */
@@ -540,9 +539,6 @@ InitPostgres(const char *dbname, const char *username)
    /* set default namespace search path */
    InitializeSearchPath();
 
-   /* set up ACL framework (currently just sets RolMemCache callback) */
-   initialize_acl();
-
    /* initialize client encoding */
    InitializeClientEncoding();
 
index 77e6d43fe020fc71b670891e41894deaf953bd43..86c930b8add3642c613b600b13b916c71312df91 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.26 2006/03/05 15:58:50 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.27 2006/04/30 21:15:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -605,6 +605,7 @@ do { \
    else if (strcmp(type, "DATABASE") == 0)
    {
        CONVERT_PRIV('C', "CREATE");
+       CONVERT_PRIV('c', "CONNECT");
        CONVERT_PRIV('T', "TEMPORARY");
    }
    else if (strcmp(type, "TABLESPACE") == 0)
index a90d7eb72cfb4f03f11cc2bd69e8215ea7db0ba6..ad8f0f841b238741afc768534818403e3f2a36d8 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2006, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.150 2006/04/02 09:02:41 alvherre Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.151 2006/04/30 21:15:33 tgl Exp $
  */
 
 /*----------------------------------------------------------------------
@@ -1373,7 +1373,8 @@ psql_completion(char *text, int start, int end)
    {
        static const char *const list_privileg[] =
        {"SELECT", "INSERT", "UPDATE", "DELETE", "RULE", "REFERENCES",
-       "TRIGGER", "CREATE", "TEMPORARY", "EXECUTE", "USAGE", "ALL", NULL};
+        "TRIGGER", "CREATE", "CONNECT", "TEMPORARY", "EXECUTE", "USAGE",
+        "ALL", NULL};
 
        COMPLETE_WITH_LIST(list_privileg);
    }
index c329b6aab81d16a2d9ece7352d5d016c5306e475..7651fba290c1148c5e046ef5816bdcdddc6a6936 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.94 2006/04/30 02:09:07 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.95 2006/04/30 21:15:33 tgl Exp $
  *
  * NOTES
  *   An ACL array is simply an array of AclItems, representing the union
@@ -24,6 +24,8 @@
 #ifndef ACL_H
 #define ACL_H
 
+#include "access/htup.h"
+#include "access/tupdesc.h"
 #include "nodes/parsenodes.h"
 #include "utils/array.h"
 
@@ -145,7 +147,7 @@ typedef ArrayType Acl;
  */
 #define ACL_ALL_RIGHTS_RELATION        (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_RULE|ACL_REFERENCES|ACL_TRIGGER)
 #define ACL_ALL_RIGHTS_SEQUENCE        (ACL_USAGE|ACL_SELECT|ACL_UPDATE)
-#define ACL_ALL_RIGHTS_DATABASE        (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT )
+#define ACL_ALL_RIGHTS_DATABASE        (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)
 #define ACL_ALL_RIGHTS_FUNCTION        (ACL_EXECUTE)
 #define ACL_ALL_RIGHTS_LANGUAGE        (ACL_USAGE)
 #define ACL_ALL_RIGHTS_NAMESPACE   (ACL_USAGE|ACL_CREATE)
@@ -250,6 +252,8 @@ extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid,
                 AclMode mask, AclMaskHow how);
 extern AclMode pg_database_aclmask(Oid db_oid, Oid roleid,
                    AclMode mask, AclMaskHow how);
+extern AclMode pg_database_tuple_aclmask(HeapTuple db_tuple, TupleDesc tupdesc,
+                   Oid roleid, AclMode mask, AclMaskHow how);
 extern AclMode pg_proc_aclmask(Oid proc_oid, Oid roleid,
                AclMode mask, AclMaskHow how);
 extern AclMode pg_language_aclmask(Oid lang_oid, Oid roleid,