When we're restricting who can connect, don't allow new walsenders.

Normal superuser processes are allowed to connect even when the database
system is shutting down, or when fewer than superuser_reserved_connection
slots remain.  This is intended to make sure an administrator can log in
and troubleshoot, so don't extend these same courtesies to users connecting
for replication.
This commit is contained in:
Robert Haas 2010-04-26 10:52:00 +00:00
parent 22da73198f
commit ab93cd9b05
2 changed files with 35 additions and 23 deletions

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.269 2010/04/20 11:15:06 rhaas Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.270 2010/04/26 10:51:59 rhaas Exp $ -->
<chapter Id="runtime-config">
<title>Server Configuration</title>
@ -401,7 +401,8 @@ SET ENABLE_SEQSCAN TO OFF;
number of active concurrent connections is at least
<varname>max_connections</> minus
<varname>superuser_reserved_connections</varname>, new
connections will be accepted only for superusers.
connections will be accepted only for superusers, and no
new replication connections will be accepted.
</para>
<para>

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.211 2010/04/21 00:51:57 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.212 2010/04/26 10:52:00 rhaas Exp $
*
*
*-------------------------------------------------------------------------
@ -617,6 +617,37 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
am_superuser = superuser();
}
/*
* If we're trying to shut down, only superusers can connect, and
* new replication connections are not allowed.
*/
if ((!am_superuser || am_walsender) &&
MyProcPort != NULL &&
MyProcPort->canAcceptConnections == CAC_WAITBACKUP)
{
if (am_walsender)
ereport(FATAL,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("new replication connections are not allowed during database shutdown")));
else
ereport(FATAL,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to connect during database shutdown")));
}
/*
* The last few connections slots are reserved for superusers.
* Although replication connections currently require superuser
* privileges, we don't allow them to consume the reserved slots,
* which are intended for interactive use.
*/
if ((!am_superuser || am_walsender) &&
ReservedBackends > 0 &&
!HaveNFreeProcs(ReservedBackends))
ereport(FATAL,
(errcode(ERRCODE_TOO_MANY_CONNECTIONS),
errmsg("remaining connection slots are reserved for non-replication superuser connections")));
/*
* If walsender, we're done here --- we don't want to connect to any
* particular database.
@ -778,26 +809,6 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
if (!bootstrap)
CheckMyDatabase(dbname, am_superuser);
/*
* If we're trying to shut down, only superusers can connect.
*/
if (!am_superuser &&
MyProcPort != NULL &&
MyProcPort->canAcceptConnections == CAC_WAITBACKUP)
ereport(FATAL,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to connect during database shutdown")));
/*
* Check a normal user hasn't connected to a superuser reserved slot.
*/
if (!am_superuser &&
ReservedBackends > 0 &&
!HaveNFreeProcs(ReservedBackends))
ereport(FATAL,
(errcode(ERRCODE_TOO_MANY_CONNECTIONS),
errmsg("connection limit exceeded for non-superusers")));
/*
* Now process any command-line switches that were included in the startup
* packet, if we are in a regular backend. We couldn't do this before