When we're restricting who can connect, don't allow new walsenders.
authorRobert Haas <rhaas@postgresql.org>
Mon, 26 Apr 2010 10:52:00 +0000 (10:52 +0000)
committerRobert Haas <rhaas@postgresql.org>
Mon, 26 Apr 2010 10:52:00 +0000 (10:52 +0000)
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.

doc/src/sgml/config.sgml
src/backend/utils/init/postinit.c

index e1372bf4a89824c3c987d314945cf26de8448a10..71bab707da856f5c62ae92b0109a9f6a4bee3308 100644 (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>
index b812c40ac0ee6506d6c9e678b34ac035358f08b9..dab7694f700fdaf2a283fd22835f698d8e919c81 100644 (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