Commit 82a2881c authored by Tom Lane's avatar Tom Lane

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.
parent 986085a7
<!-- $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"> <chapter id="client-authentication">
<title>Client Authentication</title> <title>Client Authentication</title>
...@@ -206,8 +206,6 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> ...@@ -206,8 +206,6 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
Multiple user names can be supplied by separating them with commas. Multiple user names can be supplied by separating them with commas.
A separate file containing user names can be specified by preceding the A separate file containing user names can be specified by preceding the
file name with <literal>@</>. file name with <literal>@</>.
User and group connectivity can also be restricted by <command>GRANT
CONNECTION ON DATABASE</>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -436,6 +434,17 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> ...@@ -436,6 +434,17 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
re-read the file. re-read the file.
</para> </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> <para>
Some examples of <filename>pg_hba.conf</filename> entries are shown in 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 <xref linkend="example-pg-hba.conf">. See the next section for details on the
......
<!-- $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"> <chapter id="ddl">
<title>Data Definition</title> <title>Data Definition</title>
...@@ -1343,8 +1343,9 @@ ALTER TABLE products RENAME TO items; ...@@ -1343,8 +1343,9 @@ ALTER TABLE products RENAME TO items;
There are several different privileges: <literal>SELECT</>, There are several different privileges: <literal>SELECT</>,
<literal>INSERT</>, <literal>UPDATE</>, <literal>DELETE</>, <literal>INSERT</>, <literal>UPDATE</>, <literal>DELETE</>,
<literal>RULE</>, <literal>REFERENCES</>, <literal>TRIGGER</>, <literal>RULE</>, <literal>REFERENCES</>, <literal>TRIGGER</>,
<literal>CREATE</>, <literal>TEMPORARY</>, <literal>EXECUTE</>, and <literal>CREATE</>, <literal>CONNECT</>, <literal>TEMPORARY</>,
<literal>USAGE</>. The privileges applicable to a particular <literal>EXECUTE</>, and <literal>USAGE</>.
The privileges applicable to a particular
object vary depending on the object's type (table, function, etc). object vary depending on the object's type (table, function, etc).
For complete information on the different types of privileges For complete information on the different types of privileges
supported by <productname>PostgreSQL</productname>, refer to the supported by <productname>PostgreSQL</productname>, refer to the
......
<!-- $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"> <chapter id="functions">
<title>Functions and Operators</title> <title>Functions and Operators</title>
...@@ -9227,6 +9227,7 @@ SELECT has_table_privilege('myschema.mytable', 'select'); ...@@ -9227,6 +9227,7 @@ SELECT has_table_privilege('myschema.mytable', 'select');
arguments are analogous to <function>has_table_privilege</function>. arguments are analogous to <function>has_table_privilege</function>.
The desired access privilege type must evaluate to The desired access privilege type must evaluate to
<literal>CREATE</literal>, <literal>CREATE</literal>,
<literal>CONNECT</literal>,
<literal>TEMPORARY</literal>, or <literal>TEMPORARY</literal>, or
<literal>TEMP</literal> (which is equivalent to <literal>TEMP</literal> (which is equivalent to
<literal>TEMPORARY</literal>). <literal>TEMPORARY</literal>).
......
<!-- <!--
$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 PostgreSQL documentation
--> -->
...@@ -30,7 +30,7 @@ GRANT { { USAGE | SELECT | UPDATE } ...@@ -30,7 +30,7 @@ GRANT { { USAGE | SELECT | UPDATE }
ON SEQUENCE <replaceable class="PARAMETER">sequencename</replaceable> [, ...] ON SEQUENCE <replaceable class="PARAMETER">sequencename</replaceable> [, ...]
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] 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> [, ...] ON DATABASE <replaceable>dbname</replaceable> [, ...]
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] 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> [, ...] ...@@ -118,7 +118,8 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...]
Depending on the type of object, the initial default privileges may Depending on the type of object, the initial default privileges may
include granting some privileges to <literal>PUBLIC</literal>. include granting some privileges to <literal>PUBLIC</literal>.
The default is no public access for tables, schemas, and tablespaces; 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>EXECUTE</> privilege for functions; and
<literal>USAGE</> privilege for languages. <literal>USAGE</> privilege for languages.
The object owner may of course revoke these privileges. (For maximum The object owner may of course revoke these privileges. (For maximum
...@@ -230,13 +231,12 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...] ...@@ -230,13 +231,12 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...]
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term>CONNECTION</term> <term>CONNECT</term>
<listitem> <listitem>
<para> <para>
Allows the ability to connect to the specified database. Allows the user to connect to the specified database. This
By default, Grant permissions allow users to connect to any database, privilege is checked at connection startup (in addition to checking
though <filename>pg_hba.conf</> can add additional connection any restrictions imposed by <filename>pg_hba.conf</>).
restrictions.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -429,7 +429,7 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...] ...@@ -429,7 +429,7 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...]
X -- EXECUTE X -- EXECUTE
U -- USAGE U -- USAGE
C -- CREATE C -- CREATE
c -- CONNECTION c -- CONNECT
T -- TEMPORARY T -- TEMPORARY
arwdRxt -- ALL PRIVILEGES (for tables) arwdRxt -- ALL PRIVILEGES (for tables)
* -- grant option for preceding privilege * -- grant option for preceding privilege
......
<!-- <!--
$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 PostgreSQL documentation
--> -->
...@@ -35,7 +35,7 @@ REVOKE [ GRANT OPTION FOR ] ...@@ -35,7 +35,7 @@ REVOKE [ GRANT OPTION FOR ]
[ CASCADE | RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ]
{ { CREATE | TEMPORARY | TEMP | CONNECTION } [,...] | ALL [ PRIVILEGES ] } { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
ON DATABASE <replaceable>dbname</replaceable> [, ...] ON DATABASE <replaceable>dbname</replaceable> [, ...]
FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
[ CASCADE | RESTRICT ] [ CASCADE | RESTRICT ]
......
<!-- $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"> <chapter id="user-manag">
<title>Database Roles and Privileges</title> <title>Database Roles and Privileges</title>
...@@ -294,9 +294,9 @@ ALTER ROLE myname SET enable_indexscan TO off; ...@@ -294,9 +294,9 @@ ALTER ROLE myname SET enable_indexscan TO off;
There are several different kinds of privilege: <literal>SELECT</>, There are several different kinds of privilege: <literal>SELECT</>,
<literal>INSERT</>, <literal>UPDATE</>, <literal>DELETE</>, <literal>INSERT</>, <literal>UPDATE</>, <literal>DELETE</>,
<literal>RULE</>, <literal>REFERENCES</>, <literal>TRIGGER</>, <literal>RULE</>, <literal>REFERENCES</>, <literal>TRIGGER</>,
<literal>CREATE</>, <literal>TEMPORARY</>, <literal>EXECUTE</>, <literal>CREATE</>, <literal>CONNECT</>, <literal>TEMPORARY</>,
and <literal>USAGE</>. For more <literal>EXECUTE</>, and <literal>USAGE</>.
information on the different types of privileges supported by For more information on the different types of privileges supported by
<productname>PostgreSQL</productname>, see the <productname>PostgreSQL</productname>, see the
<xref linkend="sql-grant" endterm="sql-grant-title"> reference page. <xref linkend="sql-grant" endterm="sql-grant-title"> reference page.
</para> </para>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* See acl.h. * See acl.h.
...@@ -1368,7 +1368,7 @@ string_to_privilege(const char *privname) ...@@ -1368,7 +1368,7 @@ string_to_privilege(const char *privname)
return ACL_CREATE_TEMP; return ACL_CREATE_TEMP;
if (strcmp(privname, "temp") == 0) if (strcmp(privname, "temp") == 0)
return ACL_CREATE_TEMP; return ACL_CREATE_TEMP;
if (strcmp(privname, "connection") == 0) if (strcmp(privname, "connect") == 0)
return ACL_CONNECT; return ACL_CONNECT;
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
...@@ -1404,7 +1404,7 @@ privilege_to_string(AclMode privilege) ...@@ -1404,7 +1404,7 @@ privilege_to_string(AclMode privilege)
case ACL_CREATE_TEMP: case ACL_CREATE_TEMP:
return "TEMP"; return "TEMP";
case ACL_CONNECT: case ACL_CONNECT:
return "CONNECTION"; return "CONNECT";
default: default:
elog(ERROR, "unrecognized privilege: %d", (int) privilege); elog(ERROR, "unrecognized privilege: %d", (int) privilege);
} }
...@@ -1661,10 +1661,6 @@ pg_database_aclmask(Oid db_oid, Oid roleid, ...@@ -1661,10 +1661,6 @@ pg_database_aclmask(Oid db_oid, Oid roleid,
ScanKeyData entry[1]; ScanKeyData entry[1];
SysScanDesc scan; SysScanDesc scan;
HeapTuple tuple; HeapTuple tuple;
Datum aclDatum;
bool isNull;
Acl *acl;
Oid ownerId;
/* Superusers bypass all permission checking. */ /* Superusers bypass all permission checking. */
if (superuser_arg(roleid)) if (superuser_arg(roleid))
...@@ -1688,10 +1684,33 @@ pg_database_aclmask(Oid db_oid, Oid roleid, ...@@ -1688,10 +1684,33 @@ pg_database_aclmask(Oid db_oid, Oid roleid,
(errcode(ERRCODE_UNDEFINED_DATABASE), (errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database with OID %u does not exist", db_oid))); 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, aclDatum = heap_getattr(db_tuple, Anum_pg_database_datacl,
RelationGetDescr(pg_database), &isNull); tupdesc, &isNull);
if (isNull) if (isNull)
{ {
...@@ -1711,9 +1730,6 @@ pg_database_aclmask(Oid db_oid, Oid roleid, ...@@ -1711,9 +1730,6 @@ pg_database_aclmask(Oid db_oid, Oid roleid,
if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
pfree(acl); pfree(acl);
systable_endscan(scan);
heap_close(pg_database, AccessShareLock);
return result; return result;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -553,7 +553,8 @@ acldefault(GrantObjectType objtype, Oid ownerId)
owner_default = ACL_ALL_RIGHTS_SEQUENCE; owner_default = ACL_ALL_RIGHTS_SEQUENCE;
break; break;
case ACL_OBJECT_DATABASE: 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; owner_default = ACL_ALL_RIGHTS_DATABASE;
break; break;
case ACL_OBJECT_FUNCTION: case ACL_OBJECT_FUNCTION:
...@@ -1341,6 +1342,8 @@ convert_priv_string(text *priv_type_text) ...@@ -1341,6 +1342,8 @@ convert_priv_string(text *priv_type_text)
return ACL_CREATE_TEMP; return ACL_CREATE_TEMP;
if (pg_strcasecmp(priv_type, "TEMPORARY") == 0) if (pg_strcasecmp(priv_type, "TEMPORARY") == 0)
return ACL_CREATE_TEMP; return ACL_CREATE_TEMP;
if (pg_strcasecmp(priv_type, "CONNECT") == 0)
return ACL_CONNECT;
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
...@@ -1778,6 +1781,11 @@ convert_database_priv_string(text *priv_type_text) ...@@ -1778,6 +1781,11 @@ convert_database_priv_string(text *priv_type_text)
if (pg_strcasecmp(priv_type, "TEMP WITH GRANT OPTION") == 0) if (pg_strcasecmp(priv_type, "TEMP WITH GRANT OPTION") == 0)
return ACL_GRANT_OPTION_FOR(ACL_CREATE_TEMP); 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, ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unrecognized privilege type: \"%s\"", priv_type))); errmsg("unrecognized privilege type: \"%s\"", priv_type)));
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -51,7 +51,7 @@
static bool FindMyDatabase(const char *name, Oid *db_id, Oid *db_tablespace); 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 InitCommunication(void);
static void ShutdownPostgres(int code, Datum arg); static void ShutdownPostgres(int code, Datum arg);
static bool ThereIsAtLeastOneRole(void); static bool ThereIsAtLeastOneRole(void);
...@@ -127,12 +127,11 @@ FindMyDatabase(const char *name, Oid *db_id, Oid *db_tablespace) ...@@ -127,12 +127,11 @@ FindMyDatabase(const char *name, Oid *db_id, Oid *db_tablespace)
* of pg_database. * of pg_database.
* *
* To avoid having to read pg_database more times than necessary * To avoid having to read pg_database more times than necessary
* during session startup, this place is also fitting to set up any * during session startup, this place is also fitting to check CONNECT
* database-specific configuration variables. * privilege and set up any database-specific configuration variables.
*/ */
static void static void
ReverifyMyDatabase(const char *name, const char *user_name) ReverifyMyDatabase(const char *name, bool am_superuser)
{ {
Relation pgdbrel; Relation pgdbrel;
SysScanDesc pgdbscan; SysScanDesc pgdbscan;
...@@ -195,6 +194,22 @@ ReverifyMyDatabase(const char *name, const char *user_name) ...@@ -195,6 +194,22 @@ ReverifyMyDatabase(const char *name, const char *user_name)
errmsg("database \"%s\" is not currently accepting connections", errmsg("database \"%s\" is not currently accepting connections",
name))); 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. * Check connection limit for this database.
* *
...@@ -206,29 +221,12 @@ ReverifyMyDatabase(const char *name, const char *user_name) ...@@ -206,29 +221,12 @@ ReverifyMyDatabase(const char *name, const char *user_name)
* just document that the connection limit is approximate. * just document that the connection limit is approximate.
*/ */
if (dbform->datconnlimit >= 0 && if (dbform->datconnlimit >= 0 &&
!superuser() && !am_superuser &&
CountDBBackends(MyDatabaseId) > dbform->datconnlimit) CountDBBackends(MyDatabaseId) > dbform->datconnlimit)
ereport(FATAL, ereport(FATAL,
(errcode(ERRCODE_TOO_MANY_CONNECTIONS), (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
errmsg("too many connections for database \"%s\"", errmsg("too many connections for database \"%s\"",
name))); 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) ...@@ -476,15 +474,20 @@ InitPostgres(const char *dbname, const char *username)
RelationCacheInitializePhase2(); RelationCacheInitializePhase2();
/* /*
* Figure out our postgres user id. In standalone mode and in the * Figure out our postgres user id, and see if we are a superuser.
* autovacuum process, we use a fixed id, otherwise we figure it out from *
* the authenticated user name. * 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) if (bootstrap || autovacuum)
{
InitializeSessionUserIdStandalone(); InitializeSessionUserIdStandalone();
am_superuser = true;
}
else if (!IsUnderPostmaster) else if (!IsUnderPostmaster)
{ {
InitializeSessionUserIdStandalone(); InitializeSessionUserIdStandalone();
am_superuser = true;
if (!ThereIsAtLeastOneRole()) if (!ThereIsAtLeastOneRole())
ereport(WARNING, ereport(WARNING,
(errcode(ERRCODE_UNDEFINED_OBJECT), (errcode(ERRCODE_UNDEFINED_OBJECT),
...@@ -496,8 +499,12 @@ InitPostgres(const char *dbname, const char *username) ...@@ -496,8 +499,12 @@ InitPostgres(const char *dbname, const char *username)
{ {
/* normal multiuser case */ /* normal multiuser case */
InitializeSessionUserId(username); 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 * Unless we are bootstrapping, double-check that InitMyDatabaseInfo() got
* a correct result. We can't do this until all the database-access * a correct result. We can't do this until all the database-access
...@@ -505,7 +512,7 @@ InitPostgres(const char *dbname, const char *username) ...@@ -505,7 +512,7 @@ InitPostgres(const char *dbname, const char *username)
* superuser, so the above stuff has to happen first.) * superuser, so the above stuff has to happen first.)
*/ */
if (!bootstrap) if (!bootstrap)
ReverifyMyDatabase(dbname,username); ReverifyMyDatabase(dbname, am_superuser);
/* /*
* Final phase of relation cache startup: write a new cache file if * Final phase of relation cache startup: write a new cache file if
...@@ -514,14 +521,6 @@ InitPostgres(const char *dbname, const char *username) ...@@ -514,14 +521,6 @@ InitPostgres(const char *dbname, const char *username)
*/ */
RelationCacheInitializePhase3(); 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. * Check a normal user hasn't connected to a superuser reserved slot.
*/ */
...@@ -540,9 +539,6 @@ InitPostgres(const char *dbname, const char *username) ...@@ -540,9 +539,6 @@ InitPostgres(const char *dbname, const char *username)
/* set default namespace search path */ /* set default namespace search path */
InitializeSearchPath(); InitializeSearchPath();
/* set up ACL framework (currently just sets RolMemCache callback) */
initialize_acl();
/* initialize client encoding */ /* initialize client encoding */
InitializeClientEncoding(); InitializeClientEncoding();
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 { \ ...@@ -605,6 +605,7 @@ do { \
else if (strcmp(type, "DATABASE") == 0) else if (strcmp(type, "DATABASE") == 0)
{ {
CONVERT_PRIV('C', "CREATE"); CONVERT_PRIV('C', "CREATE");
CONVERT_PRIV('c', "CONNECT");
CONVERT_PRIV('T', "TEMPORARY"); CONVERT_PRIV('T', "TEMPORARY");
} }
else if (strcmp(type, "TABLESPACE") == 0) else if (strcmp(type, "TABLESPACE") == 0)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2006, PostgreSQL Global Development Group * 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) ...@@ -1373,7 +1373,8 @@ psql_completion(char *text, int start, int end)
{ {
static const char *const list_privileg[] = static const char *const list_privileg[] =
{"SELECT", "INSERT", "UPDATE", "DELETE", "RULE", "REFERENCES", {"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); COMPLETE_WITH_LIST(list_privileg);
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* An ACL array is simply an array of AclItems, representing the union * An ACL array is simply an array of AclItems, representing the union
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#ifndef ACL_H #ifndef ACL_H
#define ACL_H #define ACL_H
#include "access/htup.h"
#include "access/tupdesc.h"
#include "nodes/parsenodes.h" #include "nodes/parsenodes.h"
#include "utils/array.h" #include "utils/array.h"
...@@ -145,7 +147,7 @@ typedef ArrayType Acl; ...@@ -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_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_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_FUNCTION (ACL_EXECUTE)
#define ACL_ALL_RIGHTS_LANGUAGE (ACL_USAGE) #define ACL_ALL_RIGHTS_LANGUAGE (ACL_USAGE)
#define ACL_ALL_RIGHTS_NAMESPACE (ACL_USAGE|ACL_CREATE) #define ACL_ALL_RIGHTS_NAMESPACE (ACL_USAGE|ACL_CREATE)
...@@ -250,6 +252,8 @@ extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid, ...@@ -250,6 +252,8 @@ extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid,
AclMode mask, AclMaskHow how); AclMode mask, AclMaskHow how);
extern AclMode pg_database_aclmask(Oid db_oid, Oid roleid, extern AclMode pg_database_aclmask(Oid db_oid, Oid roleid,
AclMode mask, AclMaskHow how); 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, extern AclMode pg_proc_aclmask(Oid proc_oid, Oid roleid,
AclMode mask, AclMaskHow how); AclMode mask, AclMaskHow how);
extern AclMode pg_language_aclmask(Oid lang_oid, Oid roleid, extern AclMode pg_language_aclmask(Oid lang_oid, Oid roleid,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment