From 9da451eddf23ac96bd7e3db1408e6beaf24d28a0 Mon Sep 17 00:00:00 2001
From: Mark Dilger <mark.dilger@enterprisedb.com>
Date: Wed, 20 Oct 2021 07:50:45 -0700
Subject: [PATCH v1 07/12] Adding role pg_manage_connection_settings

This new role can SET and ALTER SYSTEM SET any GUC variable which
controls connection or authentication behavior or resource usage.
---
 doc/src/sgml/user-manag.sgml            |  9 ++-
 src/backend/utils/misc/guc.c            | 72 +++++++++++----------
 src/include/catalog/pg_authid.dat       |  5 ++
 src/include/utils/guc.h                 |  1 +
 src/test/regress/expected/guc_privs.out | 85 +++++++++++++++++++++++++
 src/test/regress/sql/guc_privs.sql      | 55 ++++++++++++++++
 6 files changed, 191 insertions(+), 36 deletions(-)

diff --git a/doc/src/sgml/user-manag.sgml b/doc/src/sgml/user-manag.sgml
index ed586cc260..827312d3f0 100644
--- a/doc/src/sgml/user-manag.sgml
+++ b/doc/src/sgml/user-manag.sgml
@@ -602,6 +602,10 @@ DROP ROLE doomed_role;
        <entry>pg_manage_replication_settings</entry>
        <entry>Allow changing settings which control replication behavior.</entry>
       </row>
+      <row>
+       <entry>pg_manage_connection_settings</entry>
+       <entry>Allow changing settings which control connections and authentication.</entry>
+      </row>
      </tbody>
     </tgroup>
    </table>
@@ -650,8 +654,9 @@ DROP ROLE doomed_role;
   The <literal>pg_manage_host_resource_settings</literal>,
   <literal>pg_manage_vacuum_settings</literal>,
   <literal>pg_manage_autovacuum_settings</literal>,
-  <literal>pg_manage_logging_settings</literal> and
-  <literal>pg_manage_replication_settings</literal> roles are intended to allow
+  <literal>pg_manage_logging_settings</literal>,
+  <literal>pg_manage_replication_settings</literal> and
+  <literal>pg_manage_connection_settings</literal> roles are intended to allow
   administrators to have trusted, but non-superuser, roles to configure the
   server.
   </para>
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index e40445f06a..f87c2d390e 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -1219,7 +1219,7 @@ static struct config_bool ConfigureNamesBool[] =
 		{"bonjour", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
 			gettext_noop("Enables advertising the server via Bonjour."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&enable_bonjour,
 		false,
@@ -1239,7 +1239,7 @@ static struct config_bool ConfigureNamesBool[] =
 		{"ssl", PGC_SIGHUP, CONN_AUTH_SSL,
 			gettext_noop("Enables SSL connections."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&EnableSSL,
 		false,
@@ -1249,7 +1249,7 @@ static struct config_bool ConfigureNamesBool[] =
 		{"ssl_passphrase_command_supports_reload", PGC_SIGHUP, CONN_AUTH_SSL,
 			gettext_noop("Also use ssl_passphrase_command during server reload."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&ssl_passphrase_command_supports_reload,
 		false,
@@ -1259,7 +1259,7 @@ static struct config_bool ConfigureNamesBool[] =
 		{"ssl_prefer_server_ciphers", PGC_SIGHUP, CONN_AUTH_SSL,
 			gettext_noop("Give priority to server ciphersuite order."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&SSLPreferServerCiphers,
 		true,
@@ -1748,7 +1748,7 @@ static struct config_bool ConfigureNamesBool[] =
 		{"db_user_namespace", PGC_SIGHUP, CONN_AUTH_AUTH,
 			gettext_noop("Enables per-database user names."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&Db_user_namespace,
 		false,
@@ -1942,7 +1942,7 @@ static struct config_bool ConfigureNamesBool[] =
 		{"krb_caseins_users", PGC_SIGHUP, CONN_AUTH_AUTH,
 			gettext_noop("Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&pg_krb_caseins_users,
 		false,
@@ -2421,7 +2421,7 @@ static struct config_int ConfigureNamesInt[] =
 		{"max_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
 			gettext_noop("Sets the maximum number of concurrent connections."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&MaxConnections,
 		100, 1, MAX_BACKENDS,
@@ -2433,7 +2433,7 @@ static struct config_int ConfigureNamesInt[] =
 		{"superuser_reserved_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
 			gettext_noop("Sets the number of connection slots reserved for superusers."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&ReservedBackends,
 		3, 0, MAX_BACKENDS,
@@ -2508,7 +2508,7 @@ static struct config_int ConfigureNamesInt[] =
 		{"port", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
 			gettext_noop("Sets the TCP port the server listens on."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&PostPortNumber,
 		DEF_PGPORT, 1, 65535,
@@ -2524,7 +2524,7 @@ static struct config_int ConfigureNamesInt[] =
 						 "accepted by the chmod and umask system calls. "
 						 "(To use the customary octal format the number must "
 						 "start with a 0 (zero).)"),
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&Unix_socket_permissions,
 		0777, 0000, 0777,
@@ -2915,7 +2915,7 @@ static struct config_int ConfigureNamesInt[] =
 		{"authentication_timeout", PGC_SIGHUP, CONN_AUTH_AUTH,
 			gettext_noop("Sets the maximum allowed time to complete client authentication."),
 			NULL,
-			GUC_SUPERUSER_ONLY,
+			GUC_MANAGE_CONNECTION_SETTINGS,
 			GUC_UNIT_S
 		},
 		&AuthenticationTimeout,
@@ -3603,7 +3603,7 @@ static struct config_int ConfigureNamesInt[] =
 		{"tcp_keepalives_idle", PGC_USERSET, CONN_AUTH_SETTINGS,
 			gettext_noop("Time between issuing TCP keepalives."),
 			gettext_noop("A value of 0 uses the system default."),
-			GUC_SUPERUSER_ONLY,
+			GUC_MANAGE_CONNECTION_SETTINGS,
 			GUC_UNIT_S
 		},
 		&tcp_keepalives_idle,
@@ -3615,7 +3615,7 @@ static struct config_int ConfigureNamesInt[] =
 		{"tcp_keepalives_interval", PGC_USERSET, CONN_AUTH_SETTINGS,
 			gettext_noop("Time between TCP keepalive retransmits."),
 			gettext_noop("A value of 0 uses the system default."),
-			GUC_SUPERUSER_ONLY,
+			GUC_MANAGE_CONNECTION_SETTINGS,
 			GUC_UNIT_S
 		},
 		&tcp_keepalives_interval,
@@ -3627,7 +3627,7 @@ static struct config_int ConfigureNamesInt[] =
 		{"ssl_renegotiation_limit", PGC_USERSET, CONN_AUTH_SSL,
 			gettext_noop("SSL renegotiation is no longer supported; this can only be 0."),
 			NULL,
-			GUC_SUPERUSER_ONLY,
+			GUC_MANAGE_CONNECTION_SETTINGS,
 			GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE,
 		},
 		&ssl_renegotiation_limit,
@@ -3641,7 +3641,7 @@ static struct config_int ConfigureNamesInt[] =
 			gettext_noop("This controls the number of consecutive keepalive retransmits that can be "
 						 "lost before a connection is considered dead. A value of 0 uses the "
 						 "system default."),
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&tcp_keepalives_count,
 		0, 0, INT_MAX,
@@ -3750,7 +3750,7 @@ static struct config_int ConfigureNamesInt[] =
 		{"tcp_user_timeout", PGC_USERSET, CONN_AUTH_SETTINGS,
 			gettext_noop("TCP user timeout."),
 			gettext_noop("A value of 0 uses the system default."),
-			GUC_SUPERUSER_ONLY,
+			GUC_MANAGE_CONNECTION_SETTINGS,
 			GUC_UNIT_MS
 		},
 		&tcp_user_timeout,
@@ -3798,7 +3798,7 @@ static struct config_int ConfigureNamesInt[] =
 		{"client_connection_check_interval", PGC_USERSET, CONN_AUTH_SETTINGS,
 			gettext_noop("Sets the time interval between checks for disconnection while running queries."),
 			NULL,
-			GUC_SUPERUSER_ONLY,
+			GUC_MANAGE_CONNECTION_SETTINGS,
 			GUC_UNIT_MS
 		},
 		&client_connection_check_interval,
@@ -4348,7 +4348,7 @@ static struct config_string ConfigureNamesString[] =
 		{"krb_server_keyfile", PGC_SIGHUP, CONN_AUTH_AUTH,
 			gettext_noop("Sets the location of the Kerberos server key file."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&pg_krb_server_keyfile,
 		PG_KRB_SRVTAB,
@@ -4359,7 +4359,7 @@ static struct config_string ConfigureNamesString[] =
 		{"bonjour_name", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
 			gettext_noop("Sets the Bonjour service name."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&bonjour_name,
 		"",
@@ -4622,7 +4622,7 @@ static struct config_string ConfigureNamesString[] =
 			gettext_noop("Sets the owning group of the Unix-domain socket."),
 			gettext_noop("The owning user of the socket is always the user "
 						 "that starts the server."),
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&Unix_socket_group,
 		"",
@@ -4633,7 +4633,7 @@ static struct config_string ConfigureNamesString[] =
 		{"unix_socket_directories", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
 			gettext_noop("Sets the directories where Unix-domain sockets will be created."),
 			NULL,
-			GUC_SUPERUSER_ONLY,
+			GUC_MANAGE_CONNECTION_SETTINGS,
 			GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY
 		},
 		&Unix_socket_directories,
@@ -4649,7 +4649,7 @@ static struct config_string ConfigureNamesString[] =
 		{"listen_addresses", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
 			gettext_noop("Sets the host name or IP address(es) to listen to."),
 			NULL,
-			GUC_SUPERUSER_ONLY,
+			GUC_MANAGE_CONNECTION_SETTINGS,
 			GUC_LIST_INPUT
 		},
 		&ListenAddresses,
@@ -4738,7 +4738,7 @@ static struct config_string ConfigureNamesString[] =
 		{"ssl_cert_file", PGC_SIGHUP, CONN_AUTH_SSL,
 			gettext_noop("Location of the SSL server certificate file."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&ssl_cert_file,
 		"server.crt",
@@ -4749,7 +4749,7 @@ static struct config_string ConfigureNamesString[] =
 		{"ssl_key_file", PGC_SIGHUP, CONN_AUTH_SSL,
 			gettext_noop("Location of the SSL server private key file."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&ssl_key_file,
 		"server.key",
@@ -4760,7 +4760,7 @@ static struct config_string ConfigureNamesString[] =
 		{"ssl_ca_file", PGC_SIGHUP, CONN_AUTH_SSL,
 			gettext_noop("Location of the SSL certificate authority file."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&ssl_ca_file,
 		"",
@@ -4771,7 +4771,7 @@ static struct config_string ConfigureNamesString[] =
 		{"ssl_crl_file", PGC_SIGHUP, CONN_AUTH_SSL,
 			gettext_noop("Location of the SSL certificate revocation list file."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&ssl_crl_file,
 		"",
@@ -4782,7 +4782,7 @@ static struct config_string ConfigureNamesString[] =
 		{"ssl_crl_dir", PGC_SIGHUP, CONN_AUTH_SSL,
 			gettext_noop("Location of the SSL certificate revocation list directory."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&ssl_crl_dir,
 		"",
@@ -4827,7 +4827,7 @@ static struct config_string ConfigureNamesString[] =
 		{"ssl_ciphers", PGC_SIGHUP, CONN_AUTH_SSL,
 			gettext_noop("Sets the list of allowed SSL ciphers."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&SSLCipherSuites,
 #ifdef USE_OPENSSL
@@ -4842,7 +4842,7 @@ static struct config_string ConfigureNamesString[] =
 		{"ssl_ecdh_curve", PGC_SIGHUP, CONN_AUTH_SSL,
 			gettext_noop("Sets the curve to use for ECDH."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&SSLECDHCurve,
 #ifdef USE_SSL
@@ -4857,7 +4857,7 @@ static struct config_string ConfigureNamesString[] =
 		{"ssl_dh_params_file", PGC_SIGHUP, CONN_AUTH_SSL,
 			gettext_noop("Location of the SSL DH parameters file."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&ssl_dh_params_file,
 		"",
@@ -4868,7 +4868,7 @@ static struct config_string ConfigureNamesString[] =
 		{"ssl_passphrase_command", PGC_SIGHUP, CONN_AUTH_SSL,
 			gettext_noop("Command to obtain passphrases for SSL."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&ssl_passphrase_command,
 		"",
@@ -5287,7 +5287,7 @@ static struct config_enum ConfigureNamesEnum[] =
 		{"password_encryption", PGC_USERSET, CONN_AUTH_AUTH,
 			gettext_noop("Chooses the algorithm for encrypting passwords."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&Password_encryption,
 		PASSWORD_TYPE_SCRAM_SHA_256, password_encryption_options,
@@ -5312,7 +5312,7 @@ static struct config_enum ConfigureNamesEnum[] =
 		{"ssl_min_protocol_version", PGC_SIGHUP, CONN_AUTH_SSL,
 			gettext_noop("Sets the minimum SSL/TLS protocol version to use."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_MANAGE_CONNECTION_SETTINGS
 		},
 		&ssl_min_protocol_version,
 		PG_TLS1_2_VERSION,
@@ -5324,7 +5324,7 @@ static struct config_enum ConfigureNamesEnum[] =
 		{"ssl_max_protocol_version", PGC_SIGHUP, CONN_AUTH_SSL,
 			gettext_noop("Sets the maximum SSL/TLS protocol version to use."),
 			NULL,
-			GUC_MANAGE_LOGGING_SETTINGS | GUC_WRITE_SERVER_FILES,
+			GUC_MANAGE_CONNECTION_SETTINGS,
 			GUC_SUPERUSER_ONLY
 		},
 		&ssl_max_protocol_version,
@@ -7651,6 +7651,10 @@ role_has_privileges(Oid roleid, int privileges)
 		! has_privs_of_role(roleid, ROLE_PG_MANAGE_REPLICATION_SETTINGS))
 		return false;
 
+	if ((privileges & GUC_MANAGE_CONNECTION_SETTINGS) &&
+		! has_privs_of_role(roleid, ROLE_PG_MANAGE_CONNECTION_SETTINGS))
+		return false;
+
 	return true;
 }
 
diff --git a/src/include/catalog/pg_authid.dat b/src/include/catalog/pg_authid.dat
index b36c81bf95..1885823710 100644
--- a/src/include/catalog/pg_authid.dat
+++ b/src/include/catalog/pg_authid.dat
@@ -104,5 +104,10 @@
   rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
   rolreplication => 'f', rolbypassrls => 't', rolconnlimit => '-1',
   rolpassword => '_null_', rolvaliduntil => '_null_' },
+{ oid => '9284', oid_symbol => 'ROLE_PG_MANAGE_CONNECTION_SETTINGS',
+  rolname => 'pg_manage_connection_settings', rolsuper => 'f', rolinherit => 't',
+  rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
+  rolreplication => 'f', rolbypassrls => 't', rolconnlimit => '-1',
+  rolpassword => '_null_', rolvaliduntil => '_null_' },
 
 ]
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index ad75ac1e97..507ef40a5d 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -207,6 +207,7 @@ typedef enum
 #define GUC_MANAGE_LOGGING_SETTINGS			0x0008
 #define GUC_WRITE_SERVER_FILES				0x0010
 #define GUC_MANAGE_REPLICATION_SETTINGS		0x0020
+#define GUC_MANAGE_CONNECTION_SETTINGS		0x0040
 
 /*
  * bit values in "flags" of a GUC variable
diff --git a/src/test/regress/expected/guc_privs.out b/src/test/regress/expected/guc_privs.out
index 82dcdb7133..02f9b89e17 100644
--- a/src/test/regress/expected/guc_privs.out
+++ b/src/test/regress/expected/guc_privs.out
@@ -581,3 +581,88 @@ ALTER SYSTEM RESET wal_sender_timeout;  -- ok
 RESET statement_timeout;
 RESET SESSION AUTHORIZATION;
 DROP ROLE regress_replication_admin;
+-- Test role pg_manage_connection_settings
+-- Non-superuser with privileges to configure connections and authentication
+CREATE ROLE regress_connection_admin NOSUPERUSER;
+GRANT pg_manage_connection_settings TO regress_connection_admin;
+-- Perform all operations as user 'regress_connection_admin' --
+SET SESSION AUTHORIZATION regress_connection_admin;
+-- PGC_BACKEND
+SET ignore_system_indexes = OFF;  -- fail, cannot be set after connection start
+ERROR:  parameter "ignore_system_indexes" cannot be set after connection start
+RESET ignore_system_indexes;  -- fail, cannot be set after connection start
+ERROR:  parameter "ignore_system_indexes" cannot be set after connection start
+ALTER SYSTEM SET ignore_system_indexes = OFF;  -- fail, regress_connection_admin has insufficient privileges
+ERROR:  permission denied to set parameter "ignore_system_indexes"
+ALTER SYSTEM RESET ignore_system_indexes;  -- fail, regress_connection_admin has insufficient privileges
+ERROR:  permission denied to set parameter "ignore_system_indexes"
+-- PGC_INTERNAL
+SET block_size = 50;  -- fail, cannot be changed
+ERROR:  parameter "block_size" cannot be changed
+RESET block_size;  -- fail, cannot be changed
+ERROR:  parameter "block_size" cannot be changed
+ALTER SYSTEM SET block_size = 50;  -- fail, cannot be changed
+ERROR:  parameter "block_size" cannot be changed
+ALTER SYSTEM RESET block_size;  -- fail, cannot be changed
+ERROR:  parameter "block_size" cannot be changed
+-- PGC_POSTMASTER
+SET autovacuum_freeze_max_age = 1000050000;  -- fail, requires restart
+ERROR:  parameter "autovacuum_freeze_max_age" cannot be changed without restarting the server
+RESET autovacuum_freeze_max_age;  -- fail, requires restart
+ERROR:  parameter "autovacuum_freeze_max_age" cannot be changed without restarting the server
+ALTER SYSTEM SET autovacuum_freeze_max_age = 1000050000;  -- fail, regress_connection_admin has insufficient privileges
+ERROR:  permission denied to set parameter "autovacuum_freeze_max_age"
+ALTER SYSTEM RESET autovacuum_freeze_max_age;  -- fail, regress_connection_admin has insufficient privileges
+ERROR:  permission denied to set parameter "autovacuum_freeze_max_age"
+ALTER SYSTEM SET bonjour = OFF;  -- ok
+ALTER SYSTEM RESET bonjour;  -- ok
+ALTER SYSTEM SET config_file = '/usr/local/data/postgresql.conf';  -- fail, cannot be changed
+ERROR:  parameter "config_file" cannot be changed
+ALTER SYSTEM RESET config_file;  -- fail, cannot be changed
+ERROR:  parameter "config_file" cannot be changed
+-- PGC_SIGHUP
+SET autovacuum = OFF;  -- fail, requires reload
+ERROR:  parameter "autovacuum" cannot be changed now
+RESET autovacuum;  -- fail, requires reload
+ERROR:  parameter "autovacuum" cannot be changed now
+ALTER SYSTEM SET autovacuum = OFF;  -- fail, regress_connection_admin has insufficient privileges
+ERROR:  permission denied to set parameter "autovacuum"
+ALTER SYSTEM RESET autovacuum;  -- fail, regress_connection_admin has insufficient privileges
+ERROR:  permission denied to set parameter "autovacuum"
+ALTER SYSTEM SET authentication_timeout = 50;  -- ok
+ALTER SYSTEM RESET authentication_timeout;  -- ok
+-- PGC_SUSET
+SET lc_messages = 'en_US.UTF-8';  -- fail, regress_connection_admin has insufficient privileges
+ERROR:  permission denied to set parameter "lc_messages"
+RESET lc_messages;  -- fail, regress_connection_admin has insufficient privileges
+ERROR:  permission denied to set parameter "lc_messages"
+ALTER SYSTEM SET lc_messages = 'en_US.UTF-8';  -- fail, regress_connection_admin has insufficient privileges
+ERROR:  permission denied to set parameter "lc_messages"
+ALTER SYSTEM RESET lc_messages;  -- fail, regress_connection_admin has insufficient privileges
+ERROR:  permission denied to set parameter "lc_messages"
+-- PGC_SU_BACKEND
+SET jit_debugging_support = OFF;  -- fail, cannot be set after connection start
+ERROR:  parameter "jit_debugging_support" cannot be set after connection start
+RESET jit_debugging_support;  -- fail, cannot be set after connection start
+ERROR:  parameter "jit_debugging_support" cannot be set after connection start
+ALTER SYSTEM SET jit_debugging_support = OFF;  -- fail, regress_connection_admin has insufficient privileges
+ERROR:  permission denied to set parameter "jit_debugging_support"
+ALTER SYSTEM RESET jit_debugging_support;  -- fail, regress_connection_admin has insufficient privileges
+ERROR:  permission denied to set parameter "jit_debugging_support"
+-- PGC_USERSET
+SET DateStyle = 'ISO, MDY';  -- ok
+RESET DateStyle;  -- ok
+ALTER SYSTEM SET DateStyle = 'ISO, MDY';  -- fail, regress_connection_admin has insufficient privileges
+ERROR:  permission denied to set parameter "datestyle"
+ALTER SYSTEM RESET DateStyle;  -- fail, regress_connection_admin has insufficient privileges
+ERROR:  permission denied to set parameter "datestyle"
+ALTER SYSTEM SET password_encryption = 'scram-sha-256';  -- ok
+ALTER SYSTEM RESET password_encryption;  -- ok
+ALTER SYSTEM SET ssl_renegotiation_limit = 0;  -- fail, cannot be changed
+ERROR:  parameter "ssl_renegotiation_limit" cannot be changed
+ALTER SYSTEM RESET ssl_renegotiation_limit;  -- fail, cannot be changed
+ERROR:  parameter "ssl_renegotiation_limit" cannot be changed
+-- Finished testing role pg_manage_connection_settings
+RESET statement_timeout;
+RESET SESSION AUTHORIZATION;
+DROP ROLE regress_connection_admin;
diff --git a/src/test/regress/sql/guc_privs.sql b/src/test/regress/sql/guc_privs.sql
index 3b652fea2d..9dfe504c69 100644
--- a/src/test/regress/sql/guc_privs.sql
+++ b/src/test/regress/sql/guc_privs.sql
@@ -385,3 +385,58 @@ ALTER SYSTEM RESET wal_sender_timeout;  -- ok
 RESET statement_timeout;
 RESET SESSION AUTHORIZATION;
 DROP ROLE regress_replication_admin;
+-- Test role pg_manage_connection_settings
+-- Non-superuser with privileges to configure connections and authentication
+CREATE ROLE regress_connection_admin NOSUPERUSER;
+GRANT pg_manage_connection_settings TO regress_connection_admin;
+-- Perform all operations as user 'regress_connection_admin' --
+SET SESSION AUTHORIZATION regress_connection_admin;
+-- PGC_BACKEND
+SET ignore_system_indexes = OFF;  -- fail, cannot be set after connection start
+RESET ignore_system_indexes;  -- fail, cannot be set after connection start
+ALTER SYSTEM SET ignore_system_indexes = OFF;  -- fail, regress_connection_admin has insufficient privileges
+ALTER SYSTEM RESET ignore_system_indexes;  -- fail, regress_connection_admin has insufficient privileges
+-- PGC_INTERNAL
+SET block_size = 50;  -- fail, cannot be changed
+RESET block_size;  -- fail, cannot be changed
+ALTER SYSTEM SET block_size = 50;  -- fail, cannot be changed
+ALTER SYSTEM RESET block_size;  -- fail, cannot be changed
+-- PGC_POSTMASTER
+SET autovacuum_freeze_max_age = 1000050000;  -- fail, requires restart
+RESET autovacuum_freeze_max_age;  -- fail, requires restart
+ALTER SYSTEM SET autovacuum_freeze_max_age = 1000050000;  -- fail, regress_connection_admin has insufficient privileges
+ALTER SYSTEM RESET autovacuum_freeze_max_age;  -- fail, regress_connection_admin has insufficient privileges
+ALTER SYSTEM SET bonjour = OFF;  -- ok
+ALTER SYSTEM RESET bonjour;  -- ok
+ALTER SYSTEM SET config_file = '/usr/local/data/postgresql.conf';  -- fail, cannot be changed
+ALTER SYSTEM RESET config_file;  -- fail, cannot be changed
+-- PGC_SIGHUP
+SET autovacuum = OFF;  -- fail, requires reload
+RESET autovacuum;  -- fail, requires reload
+ALTER SYSTEM SET autovacuum = OFF;  -- fail, regress_connection_admin has insufficient privileges
+ALTER SYSTEM RESET autovacuum;  -- fail, regress_connection_admin has insufficient privileges
+ALTER SYSTEM SET authentication_timeout = 50;  -- ok
+ALTER SYSTEM RESET authentication_timeout;  -- ok
+-- PGC_SUSET
+SET lc_messages = 'en_US.UTF-8';  -- fail, regress_connection_admin has insufficient privileges
+RESET lc_messages;  -- fail, regress_connection_admin has insufficient privileges
+ALTER SYSTEM SET lc_messages = 'en_US.UTF-8';  -- fail, regress_connection_admin has insufficient privileges
+ALTER SYSTEM RESET lc_messages;  -- fail, regress_connection_admin has insufficient privileges
+-- PGC_SU_BACKEND
+SET jit_debugging_support = OFF;  -- fail, cannot be set after connection start
+RESET jit_debugging_support;  -- fail, cannot be set after connection start
+ALTER SYSTEM SET jit_debugging_support = OFF;  -- fail, regress_connection_admin has insufficient privileges
+ALTER SYSTEM RESET jit_debugging_support;  -- fail, regress_connection_admin has insufficient privileges
+-- PGC_USERSET
+SET DateStyle = 'ISO, MDY';  -- ok
+RESET DateStyle;  -- ok
+ALTER SYSTEM SET DateStyle = 'ISO, MDY';  -- fail, regress_connection_admin has insufficient privileges
+ALTER SYSTEM RESET DateStyle;  -- fail, regress_connection_admin has insufficient privileges
+ALTER SYSTEM SET password_encryption = 'scram-sha-256';  -- ok
+ALTER SYSTEM RESET password_encryption;  -- ok
+ALTER SYSTEM SET ssl_renegotiation_limit = 0;  -- fail, cannot be changed
+ALTER SYSTEM RESET ssl_renegotiation_limit;  -- fail, cannot be changed
+-- Finished testing role pg_manage_connection_settings
+RESET statement_timeout;
+RESET SESSION AUTHORIZATION;
+DROP ROLE regress_connection_admin;
-- 
2.21.1 (Apple Git-122.3)

