Skip to content

Commit d3ae2a2

Browse files
committed
Add allow_alter_system GUC.
This is marked PGC_SIGHUP, so it can only be set in a configuration file, not anywhere else; and it is also marked GUC_DISALLOW_IN_AUTO_FILE, so it can't be set using ALTER SYSTEM. When set to false, the ALTER SYSTEM command is disallowed. There was considerable concern that this would be misinterpreted as a security feature, which it is not, because a determined superuser has various ways of bypassing it. Hence, a lot of work has gone into wordsmithing the documentation, in the hopes of avoiding any such confusion. Jelte Fennemia-Nio and Gabriele Bartolini, with wording suggestions for the documentation from many others. Discussion: http://postgr.es/m/CA%2BVUV5rEKt2%2BCdC_KUaPoihMu%2Bi5ChT4WVNTr4CD5-xXZUfuQw%40mail.gmail.com
1 parent 0075d78 commit d3ae2a2

File tree

6 files changed

+82
-1
lines changed

6 files changed

+82
-1
lines changed

doc/src/sgml/config.sgml

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,8 @@ shared_buffers = 128MB
199199
<para>
200200
External tools may also
201201
modify <filename>postgresql.auto.conf</filename>. It is not
202-
recommended to do this while the server is running, since a
202+
recommended to do this while the server is running unless <xref
203+
linkend="guc-allow-alter-system"/> is set to <literal>off</literal>, since a
203204
concurrent <command>ALTER SYSTEM</command> command could overwrite
204205
such changes. Such tools might simply append new settings to the end,
205206
or they might choose to remove duplicate settings and/or comments
@@ -10767,6 +10768,54 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
1076710768
</listitem>
1076810769
</varlistentry>
1076910770

10771+
<varlistentry id="guc-allow-alter-system" xreflabel="allow_alter_system">
10772+
<term><varname>allow_alter_system</varname> (<type>boolean</type>)
10773+
<indexterm>
10774+
<primary><varname>allow_alter_system</varname> configuration parameter</primary>
10775+
</indexterm>
10776+
</term>
10777+
<listitem>
10778+
<para>
10779+
When <literal>allow_alter_system</literal> is set to
10780+
<literal>off</literal>, an error is returned if the <command>ALTER
10781+
SYSTEM</command> command is executed. This parameter can only be set in
10782+
the <filename>postgresql.conf</filename> file or on the server command
10783+
line. The default value is <literal>on</literal>.
10784+
</para>
10785+
10786+
<para>
10787+
Note that this setting must not be regarded as a security feature. It
10788+
only disables the <literal>ALTER SYSTEM</literal> command. It does not
10789+
prevent a superuser from changing the configuration using other SQL
10790+
commands. A superuser has many ways of executing shell commands at
10791+
the operating system level, and can therefore modify
10792+
<literal>postgresql.auto.conf</literal> regardless of the value of
10793+
this setting.
10794+
</para>
10795+
10796+
<para>
10797+
Turning this setting off is intended for environments where the
10798+
configuration of <productname>PostgreSQL</productname> is managed by
10799+
some external tool.
10800+
In such environments, a well intentioned superuser might
10801+
<emphasis>mistakenly</emphasis> use <command>ALTER SYSTEM</command>
10802+
to change the configuration instead of using the external tool.
10803+
This might result in unintended behavior, such as the external tool
10804+
overwriting the change at some later point in time when it updates the
10805+
configuration.
10806+
Setting this parameter to <literal>off</literal> can
10807+
help avoid such mistakes.
10808+
</para>
10809+
10810+
<para>
10811+
This parameter only controls the use of <command>ALTER SYSTEM</command>.
10812+
The settings stored in <filename>postgresql.auto.conf</filename>
10813+
take effect even if <literal>allow_alter_system</literal> is set to
10814+
<literal>off</literal>.
10815+
</para>
10816+
</listitem>
10817+
</varlistentry>
10818+
1077010819
</variablelist>
1077110820
</sect2>
1077210821
</sect1>

doc/src/sgml/ref/alter_system.sgml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,21 @@ ALTER SYSTEM RESET ALL
104104

105105
<para>
106106
This command can't be used to set <xref linkend="guc-data-directory"/>,
107+
<xref linkend="guc-allow-alter-system"/>,
107108
nor parameters that are not allowed in <filename>postgresql.conf</filename>
108109
(e.g., <link linkend="runtime-config-preset">preset options</link>).
109110
</para>
110111

111112
<para>
112113
See <xref linkend="config-setting"/> for other ways to set the parameters.
113114
</para>
115+
116+
<para>
117+
<literal>ALTER SYSTEM</literal> can be disabled by setting
118+
<xref linkend="guc-allow-alter-system"/> to <literal>off</literal>, but this
119+
is not a security mechanism (as explained in detail in the documentation for
120+
this parameter).
121+
</para>
114122
</refsect1>
115123

116124
<refsect1>

src/backend/utils/misc/guc.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4563,6 +4563,11 @@ AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt)
45634563
*/
45644564
name = altersysstmt->setstmt->name;
45654565

4566+
if (!AllowAlterSystem)
4567+
ereport(ERROR,
4568+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4569+
errmsg("ALTER SYSTEM is not allowed in this environment")));
4570+
45664571
switch (altersysstmt->setstmt->kind)
45674572
{
45684573
case VAR_SET_VALUE:

src/backend/utils/misc/guc_tables.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,7 @@ extern const struct config_enum_entry dynamic_shared_memory_options[];
494494
/*
495495
* GUC option variables that are exported from this module
496496
*/
497+
bool AllowAlterSystem = true;
497498
bool log_duration = false;
498499
bool Debug_print_plan = false;
499500
bool Debug_print_parse = false;
@@ -1040,6 +1041,22 @@ struct config_bool ConfigureNamesBool[] =
10401041
false,
10411042
NULL, NULL, NULL
10421043
},
1044+
{
1045+
/*
1046+
* This setting itself cannot be set by ALTER SYSTEM to avoid an
1047+
* operator turning this setting off by using ALTER SYSTEM, without a
1048+
* way to turn it back on.
1049+
*/
1050+
{"allow_alter_system", PGC_SIGHUP, COMPAT_OPTIONS_OTHER,
1051+
gettext_noop("Allows running the ALTER SYSTEM command."),
1052+
gettext_noop("Can be set to off for environments where global configuration "
1053+
"changes should be made using a different method."),
1054+
GUC_DISALLOW_IN_AUTO_FILE
1055+
},
1056+
&AllowAlterSystem,
1057+
true,
1058+
NULL, NULL, NULL
1059+
},
10431060
{
10441061
{"bonjour", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
10451062
gettext_noop("Enables advertising the server via Bonjour."),

src/backend/utils/misc/postgresql.conf.sample

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,7 @@
805805
# - Other Platforms and Clients -
806806

807807
#transform_null_equals = off
808+
#allow_alter_system = on
808809

809810

810811
#------------------------------------------------------------------------------

src/include/utils/guc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ extern PGDLLIMPORT bool log_btree_build_stats;
254254
extern PGDLLIMPORT bool check_function_bodies;
255255
extern PGDLLIMPORT bool current_role_is_superuser;
256256

257+
extern PGDLLIMPORT bool AllowAlterSystem;
257258
extern PGDLLIMPORT bool log_duration;
258259
extern PGDLLIMPORT int log_parameter_max_length;
259260
extern PGDLLIMPORT int log_parameter_max_length_on_error;

0 commit comments

Comments
 (0)