mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-04 00:02:52 -05:00 
			
		
		
		
	Code review for GRANT CONNECT patch. Spell the privilege as CONNECT not
CONNECTION, fix a number of places that were missed (eg pg_dump support), avoid executing an extra search of pg_database during startup.
This commit is contained in:
		
							parent
							
								
									986085a7f0
								
							
						
					
					
						commit
						82a2881c5b
					
				@ -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
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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>).
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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 ]
 | 
			
		||||
 | 
			
		||||
@ -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>
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
	aclDatum = heap_getattr(tuple, Anum_pg_database_datacl,
 | 
			
		||||
							RelationGetDescr(pg_database), &isNull);
 | 
			
		||||
	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(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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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)));
 | 
			
		||||
 | 
			
		||||
@ -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();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user