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
This commit is contained in:
Robert Haas 2024-03-29 08:44:45 -04:00
parent 0075d78947
commit d3ae2a24f2
6 changed files with 82 additions and 1 deletions

View File

@ -199,7 +199,8 @@ shared_buffers = 128MB
<para>
External tools may also
modify <filename>postgresql.auto.conf</filename>. It is not
recommended to do this while the server is running, since a
recommended to do this while the server is running unless <xref
linkend="guc-allow-alter-system"/> is set to <literal>off</literal>, since a
concurrent <command>ALTER SYSTEM</command> command could overwrite
such changes. Such tools might simply append new settings to the end,
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'
</listitem>
</varlistentry>
<varlistentry id="guc-allow-alter-system" xreflabel="allow_alter_system">
<term><varname>allow_alter_system</varname> (<type>boolean</type>)
<indexterm>
<primary><varname>allow_alter_system</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
When <literal>allow_alter_system</literal> is set to
<literal>off</literal>, an error is returned if the <command>ALTER
SYSTEM</command> command is executed. This parameter can only be set in
the <filename>postgresql.conf</filename> file or on the server command
line. The default value is <literal>on</literal>.
</para>
<para>
Note that this setting must not be regarded as a security feature. It
only disables the <literal>ALTER SYSTEM</literal> command. It does not
prevent a superuser from changing the configuration using other SQL
commands. A superuser has many ways of executing shell commands at
the operating system level, and can therefore modify
<literal>postgresql.auto.conf</literal> regardless of the value of
this setting.
</para>
<para>
Turning this setting off is intended for environments where the
configuration of <productname>PostgreSQL</productname> is managed by
some external tool.
In such environments, a well intentioned superuser might
<emphasis>mistakenly</emphasis> use <command>ALTER SYSTEM</command>
to change the configuration instead of using the external tool.
This might result in unintended behavior, such as the external tool
overwriting the change at some later point in time when it updates the
configuration.
Setting this parameter to <literal>off</literal> can
help avoid such mistakes.
</para>
<para>
This parameter only controls the use of <command>ALTER SYSTEM</command>.
The settings stored in <filename>postgresql.auto.conf</filename>
take effect even if <literal>allow_alter_system</literal> is set to
<literal>off</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>
</sect2>
</sect1>

View File

@ -104,6 +104,7 @@ ALTER SYSTEM RESET ALL
<para>
This command can't be used to set <xref linkend="guc-data-directory"/>,
<xref linkend="guc-allow-alter-system"/>,
nor parameters that are not allowed in <filename>postgresql.conf</filename>
(e.g., <link linkend="runtime-config-preset">preset options</link>).
</para>
@ -111,6 +112,13 @@ ALTER SYSTEM RESET ALL
<para>
See <xref linkend="config-setting"/> for other ways to set the parameters.
</para>
<para>
<literal>ALTER SYSTEM</literal> can be disabled by setting
<xref linkend="guc-allow-alter-system"/> to <literal>off</literal>, but this
is not a security mechanism (as explained in detail in the documentation for
this parameter).
</para>
</refsect1>
<refsect1>

View File

@ -4563,6 +4563,11 @@ AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt)
*/
name = altersysstmt->setstmt->name;
if (!AllowAlterSystem)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("ALTER SYSTEM is not allowed in this environment")));
switch (altersysstmt->setstmt->kind)
{
case VAR_SET_VALUE:

View File

@ -494,6 +494,7 @@ extern const struct config_enum_entry dynamic_shared_memory_options[];
/*
* GUC option variables that are exported from this module
*/
bool AllowAlterSystem = true;
bool log_duration = false;
bool Debug_print_plan = false;
bool Debug_print_parse = false;
@ -1040,6 +1041,22 @@ struct config_bool ConfigureNamesBool[] =
false,
NULL, NULL, NULL
},
{
/*
* This setting itself cannot be set by ALTER SYSTEM to avoid an
* operator turning this setting off by using ALTER SYSTEM, without a
* way to turn it back on.
*/
{"allow_alter_system", PGC_SIGHUP, COMPAT_OPTIONS_OTHER,
gettext_noop("Allows running the ALTER SYSTEM command."),
gettext_noop("Can be set to off for environments where global configuration "
"changes should be made using a different method."),
GUC_DISALLOW_IN_AUTO_FILE
},
&AllowAlterSystem,
true,
NULL, NULL, NULL
},
{
{"bonjour", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
gettext_noop("Enables advertising the server via Bonjour."),

View File

@ -805,6 +805,7 @@
# - Other Platforms and Clients -
#transform_null_equals = off
#allow_alter_system = on
#------------------------------------------------------------------------------

View File

@ -254,6 +254,7 @@ extern PGDLLIMPORT bool log_btree_build_stats;
extern PGDLLIMPORT bool check_function_bodies;
extern PGDLLIMPORT bool current_role_is_superuser;
extern PGDLLIMPORT bool AllowAlterSystem;
extern PGDLLIMPORT bool log_duration;
extern PGDLLIMPORT int log_parameter_max_length;
extern PGDLLIMPORT int log_parameter_max_length_on_error;