From 39e2d2893a37a43b6f4226d01d2fbbc1cea0b8e8 Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Fri, 8 Sep 2023 20:25:36 +0200 Subject: [PATCH v4] 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 | 57 +++++++++++++++++++ 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, 90 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 65a6e6c4086..b75c3c024ff 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -631,6 +631,63 @@ 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 and 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. + + + + This paramater is not a security feature. Instead + setting this parameter to off should be considered a + guard rail against accidental use of ALTER SYSTEM. + Such a guard rail can be useful in environments where global + configuration changes are made through 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. The configurations changed by + ALTER SYSTEM may also be represented incorrectly in + a management dashboard if that dashboard is based on the values in the + outside configuration mechanism, rather than values directly from + Postgres. + + + + 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: 071e3ad59d6fd2d6d1277b2bd9579397d10ded28 -- 2.34.1