From d0f127e6de2422343bc3855d1ac798195435ee06 Mon Sep 17 00:00:00 2001 From: Gabriele Bartolini Date: Fri, 8 Sep 2023 20:25:36 +0200 Subject: [PATCH v6 2/2] Add `externally_managed_configuration` GUC Introduce the `externally_managed_configuration` GUC (by default set to `off`). This GUC can be used as a guard rail to prevent accidental usage 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 | 45 +++++++++++++++++++ src/backend/utils/misc/guc.c | 9 ++++ src/backend/utils/misc/guc_tables.c | 16 +++++++ src/backend/utils/misc/postgresql.conf.sample | 2 +- src/include/utils/guc_tables.h | 3 ++ 5 files changed, 74 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 65a6e6c4086..71b6440440e 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -10767,6 +10767,51 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + externally_managed_configuration (boolean) + + externally_managed_configuration configuration parameter + + + + + When externally_managed_configuration is set to + on, 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 off. + + + + 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 its 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 + on 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 externally_managed_configuration is set to + on. So, changes made to + postgresql.auto.conf are not rolled back by + setting externally_managed_configuration to + on. + + + + diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 391866145ee..3d2af401100 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 (ExternallyManagedConfiguration) + { + + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("system configuration is managed externally"), + errhint("Global configuration changes should be made through a configuration system outside of PostgreSQL, not by using ALTER SYSTEM."))); + } + 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 b777902d665..8ffce338a27 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 ExternallyManagedConfiguration = true; bool log_duration = false; bool Debug_print_plan = false; bool Debug_print_parse = false; @@ -1040,6 +1041,21 @@ struct config_bool ConfigureNamesBool[] = false, NULL, NULL, NULL }, + { + /* + * This setting itself cannot be set by ALTER SYSTEM to avoid an + * operator turning this setting on with ALTER SYSTEM, without a way + * to turn it back off. + */ + {"externally_managed_configuration", PGC_SIGHUP, COMPAT_OPTIONS_OTHER, + gettext_noop("Notifies the server that the configuration is managed externally"), + gettext_noop("This disables the ALTER SYSTEM command"), + GUC_DISALLOW_IN_AUTO_FILE + }, + &ExternallyManagedConfiguration, + false, + 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..81fe3d49b6d 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -128,7 +128,6 @@ #ssl_passphrase_command = '' #ssl_passphrase_command_supports_reload = off - #------------------------------------------------------------------------------ # RESOURCE USAGE (except WAL) #------------------------------------------------------------------------------ @@ -805,6 +804,7 @@ # - Other Platforms and Clients - #transform_null_equals = off +#externally_managed_configuration = off #------------------------------------------------------------------------------ diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h index 0c0277c4230..81f5eb8ded3 100644 --- a/src/include/utils/guc_tables.h +++ b/src/include/utils/guc_tables.h @@ -320,4 +320,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 ExternallyManagedConfiguration; + #endif /* GUC_TABLES_H */ -- 2.34.1