mirror of
https://github.com/postgres/postgres.git
synced 2025-07-03 20:02:46 +03: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:
@ -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">
|
<chapter id="client-authentication">
|
||||||
<title>Client Authentication</title>
|
<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.
|
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>
|
|||||||
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
|
||||||
|
@ -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">
|
<chapter id="ddl">
|
||||||
<title>Data Definition</title>
|
<title>Data Definition</title>
|
||||||
@ -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
|
||||||
|
@ -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">
|
<chapter id="functions">
|
||||||
<title>Functions and Operators</title>
|
<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>.
|
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>).
|
||||||
|
@ -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
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -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> [, ...]
|
|||||||
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> [, ...]
|
|||||||
</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> [, ...]
|
|||||||
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
|
||||||
|
@ -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
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -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 ]
|
||||||
|
@ -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">
|
<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;
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
(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);
|
||||||
|
|
||||||
aclDatum = heap_getattr(tuple, Anum_pg_database_datacl,
|
systable_endscan(scan);
|
||||||
RelationGetDescr(pg_database), &isNull);
|
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)
|
if (isNull)
|
||||||
{
|
{
|
||||||
@ -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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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 @@
|
|||||||
|
|
||||||
|
|
||||||
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)
|
|||||||
* 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)
|
|||||||
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)
|
|||||||
* 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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
/* 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)
|
|||||||
* 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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
/* 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 @@
|
|||||||
* 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 { \
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
* 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)
|
|||||||
{
|
{
|
||||||
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 @@
|
|||||||
* 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 @@
|
|||||||
#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"
|
||||||
|
|
||||||
@ -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,
|
||||||
|
Reference in New Issue
Block a user