From 2f2be9ff0d2d04dffe1af7d18b9a46f76770b315 Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Fri, 8 Sep 2023 20:25:36 +0200 Subject: [PATCH v5] Add `enable_alter_system` GUC Introduce the `enable_alter_system` GUC (by default set to `on`). This GUC can be used as a guard rail to prevent accidental usages of ALTER SYSTEM in environments where that is not the intended way to make global configuration changes. Author: Gabriele Bartolini Author: Jelte Fennema-Nio --- doc/src/sgml/config.sgml | 59 +++++++++++++++++++ src/backend/utils/errcodes.txt | 1 + src/backend/utils/misc/guc.c | 9 +++ src/backend/utils/misc/guc_tables.c | 12 ++++ src/backend/utils/misc/postgresql.conf.sample | 5 ++ src/include/utils/guc_tables.h | 4 ++ src/test/regress/expected/sysviews.out | 3 +- 7 files changed, 92 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 65a6e6c4086..3f016f11eb1 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -631,6 +631,65 @@ include_dir 'conf.d' + + Guard Rails + + Configuration parameters in this section are intended to act as guard + rails to prevent accidental usage of PostgreSQL + features that can have unexpected consequences in certain environments. + These parameters are not security features. A + superuser has many ways to work around these guard rails if they really + want to do so. + + + + + enable_alter_system (boolean) + + enable_alter_system configuration parameter + + + + + When enable_alter_system is set to + off, an error is returned if the ALTER + SYSTEM command is used. This parameter can only be set in + the postgresql.conf file or on the server command + line. The default value is on. + + + + Note that this setting cannot be regarded as a security feature. It + only disables the ALTER SYSTEM command. It does not + prevent a superuser from changing the configuration remotely using + other means. A superuser has many ways of executing shell commands at + the operating system level, and can therefore modify + postgresql.auto.conf regardless of the value of + this setting. The purpose of the setting is to prevent + accidental modifications via ALTER + SYSTEM in environments where PostgreSQL's + configuration is managed by some outside mechanism. In such + environments, using ALTER SYSTEM to make + configuration changes might appear to work, but then may be discarded + at some point in the future when that outside mechanism updates the + configuration. Setting this parameter to false can + help to avoid such mistakes. + + + + This parameter only controls the use of ALTER SYSTEM. + The settings stored in postgresql.auto.conf always + take effect, even if enable_alter_system is set to + off. So, changes made to + postgresql.auto.conf are not rolled back by + setting enable_alter_system to + off. + + + + + + Connections and Authentication diff --git a/src/backend/utils/errcodes.txt b/src/backend/utils/errcodes.txt index 3250d539e1c..4b1f08a1818 100644 --- a/src/backend/utils/errcodes.txt +++ b/src/backend/utils/errcodes.txt @@ -431,6 +431,7 @@ Section: Class 57 - Operator Intervention 57P03 E ERRCODE_CANNOT_CONNECT_NOW cannot_connect_now 57P04 E ERRCODE_DATABASE_DROPPED database_dropped 57P05 E ERRCODE_IDLE_SESSION_TIMEOUT idle_session_timeout +57P06 E ERRCODE_GUARD_RAIL guard_rail Section: Class 58 - System Error (errors external to PostgreSQL itself) diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 391866145ee..f6d46936807 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -4563,6 +4563,15 @@ AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt) */ name = altersysstmt->setstmt->name; + if (!EnableAlterSystem) + { + + ereport(ERROR, + (errcode(ERRCODE_GUARD_RAIL), + errmsg("ALTER SYSTEM is disabled using enable_alter_system=off"), + errhint("You should probably make global configuration changes through a configuration system outside of PostgreSQL"))); + } + switch (altersysstmt->setstmt->kind) { case VAR_SET_VALUE: diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 57d9de4dd92..8ed6cd5b020 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -494,6 +494,7 @@ extern const struct config_enum_entry dynamic_shared_memory_options[]; /* * GUC option variables that are exported from this module */ +bool EnableAlterSystem = true; bool log_duration = false; bool Debug_print_plan = false; bool Debug_print_parse = false; @@ -677,6 +678,7 @@ const char *const config_group_names[] = [CONN_AUTH_TCP] = gettext_noop("Connections and Authentication / TCP Settings"), [CONN_AUTH_AUTH] = gettext_noop("Connections and Authentication / Authentication"), [CONN_AUTH_SSL] = gettext_noop("Connections and Authentication / SSL"), + [GUARD_RAILS] = gettext_noop("Guard Rails"), [RESOURCES_MEM] = gettext_noop("Resource Usage / Memory"), [RESOURCES_DISK] = gettext_noop("Resource Usage / Disk"), [RESOURCES_KERNEL] = gettext_noop("Resource Usage / Kernel Resources"), @@ -1040,6 +1042,16 @@ struct config_bool ConfigureNamesBool[] = false, NULL, NULL, NULL }, + { + {"enable_alter_system", PGC_SIGHUP, GUARD_RAILS, + gettext_noop("Enable ALTER SYSTEM command"), + NULL, + GUC_DISALLOW_IN_AUTO_FILE + }, + &EnableAlterSystem, + true, + NULL, NULL, NULL + }, { {"bonjour", PGC_POSTMASTER, CONN_AUTH_SETTINGS, gettext_noop("Enables advertising the server via Bonjour."), diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 2244ee52f79..1d2aec2aa54 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -128,6 +128,11 @@ #ssl_passphrase_command = '' #ssl_passphrase_command_supports_reload = off +#------------------------------------------------------------------------------ +# GUARD RAILS +#------------------------------------------------------------------------------ + +#enable_alter_system = on #------------------------------------------------------------------------------ # RESOURCE USAGE (except WAL) diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h index 0a2e274ebb2..8f1b03b2e9b 100644 --- a/src/include/utils/guc_tables.h +++ b/src/include/utils/guc_tables.h @@ -60,6 +60,7 @@ enum config_group CONN_AUTH_TCP, CONN_AUTH_AUTH, CONN_AUTH_SSL, + GUARD_RAILS, RESOURCES_MEM, RESOURCES_DISK, RESOURCES_KERNEL, @@ -320,4 +321,7 @@ extern char *config_enum_get_options(struct config_enum *record, const char *suffix, const char *separator); +/* GUC reference to enable/disable alter system */ +extern PGDLLIMPORT bool EnableAlterSystem; + #endif /* GUC_TABLES_H */ diff --git a/src/test/regress/expected/sysviews.out b/src/test/regress/expected/sysviews.out index 9be7aca2b8a..a4aa012b36f 100644 --- a/src/test/regress/expected/sysviews.out +++ b/src/test/regress/expected/sysviews.out @@ -111,6 +111,7 @@ select count(*) = 0 as ok from pg_stat_wal_receiver; select name, setting from pg_settings where name like 'enable%'; name | setting --------------------------------+--------- + enable_alter_system | on enable_async_append | on enable_bitmapscan | on enable_gathermerge | on @@ -134,7 +135,7 @@ select name, setting from pg_settings where name like 'enable%'; enable_seqscan | on enable_sort | on enable_tidscan | on -(23 rows) +(24 rows) -- There are always wait event descriptions for various types. select type, count(*) > 0 as ok FROM pg_wait_events base-commit: 6b3678d3474ff456b3229e4829c595be1c0c2888 -- 2.34.1