superuser_is_not_enuf.patch
application/octet-stream
Filename: superuser_is_not_enuf.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| doc/src/sgml/config.sgml | 2 | 1 |
| src/backend/utils/init/postinit.c | 31 | 20 |
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 1bea0d9..c5692ba 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -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>
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 40a196a..179d009 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -618,6 +618,37 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
}
/*
+ * 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.
*/
@@ -779,26 +810,6 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
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
* because we didn't know if client is a superuser.