From 9ba78fb0b9e6c5a7115592c2c3116fca16b5184e Mon Sep 17 00:00:00 2001
From: Fujii Masao <fujii@postgresql.org>
Date: Thu, 19 Jun 2014 20:31:20 +0900
Subject: [PATCH] Don't allow data_directory to be set in postgresql.auto.conf
 by ALTER SYSTEM.

data_directory could be set both in postgresql.conf and postgresql.auto.conf so far.
This could cause some problematic situations like circular definition. To avoid such
situations, this commit forbids a user to set data_directory in postgresql.auto.conf.

Backpatch this to 9.4 where ALTER SYSTEM command was introduced.

Amit Kapila, reviewed by Abhijit Menon-Sen, with minor adjustments by me.
---
 doc/src/sgml/ref/alter_system.sgml | 10 ++++++++++
 src/backend/utils/misc/guc.c       | 21 +++++++++++++++------
 src/include/utils/guc.h            |  1 +
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/doc/src/sgml/ref/alter_system.sgml b/doc/src/sgml/ref/alter_system.sgml
index 081b3722a0b..d11f6beeed7 100644
--- a/doc/src/sgml/ref/alter_system.sgml
+++ b/doc/src/sgml/ref/alter_system.sgml
@@ -76,6 +76,16 @@ ALTER SYSTEM SET <replaceable class="PARAMETER">configuration_parameter</replace
   </variablelist>
  </refsect1>
 
+ <refsect1>
+  <title>Notes</title>
+
+  <para>
+    This command can't be used to set <xref linkend="guc-data-directory">
+    and any parameters (e.g., <link linkend="runtime-config-preset">preset options</>)
+    that are not allowed in <filename>postgresql.conf</>.
+  </para>
+ </refsect1>
+  
  <refsect1>
   <title>Examples</title>
 
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 1d094f00c61..8ca065b7fee 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -3095,10 +3095,14 @@ static struct config_string ConfigureNamesString[] =
 	},
 
 	{
+		/*
+		 * Can't be set by ALTER SYSTEM as it can lead to recursive definition
+		 * of data_directory.
+		 */
 		{"data_directory", PGC_POSTMASTER, FILE_LOCATIONS,
 			gettext_noop("Sets the server's data directory."),
 			NULL,
-			GUC_SUPERUSER_ONLY
+			GUC_SUPERUSER_ONLY | GUC_DISALLOW_IN_AUTO_FILE
 		},
 		&data_directory,
 		NULL,
@@ -6735,12 +6739,17 @@ AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt)
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 			   errmsg("unrecognized configuration parameter \"%s\"", name)));
 
+	/*
+	 * Don't allow the parameters which can't be set in configuration
+	 * files to be set in PG_AUTOCONF_FILENAME file.
+	 */
 	if ((record->context == PGC_INTERNAL) ||
-		(record->flags & GUC_DISALLOW_IN_FILE))
-		ereport(ERROR,
-				(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
-				 errmsg("parameter \"%s\" cannot be changed",
-						name)));
+		(record->flags & GUC_DISALLOW_IN_FILE) ||
+		(record->flags & GUC_DISALLOW_IN_AUTO_FILE))
+		 ereport(ERROR,
+				 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
+				  errmsg("parameter \"%s\" cannot be changed",
+						 name)));
 
 	if (!validate_conf_option(record, name, value, PGC_S_FILE,
 							  ERROR, true, NULL,
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index c15a5bbb7b3..1493d2cb79c 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -195,6 +195,7 @@ typedef enum
 #define GUC_UNIT_TIME			0x7000	/* mask for MS, S, MIN */
 
 #define GUC_NOT_WHILE_SEC_REST	0x8000	/* can't set if security restricted */
+#define GUC_DISALLOW_IN_AUTO_FILE	0x00010000	/* can't set in PG_AUTOCONF_FILENAME */
 
 /* GUC vars that are actually declared in guc.c, rather than elsewhere */
 extern bool log_duration;
-- 
GitLab