summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2009-10-03 18:04:57 +0000
committerTom Lane2009-10-03 18:04:57 +0000
commit6d3a1e3b941d8581ab5dcc1dbfcb423a5329020c (patch)
treefa6b120075d1d2e26476696f92c5ae5e94bffb61
parent2db81dd6cbeeb79f196be812cca2849e5526863c (diff)
Fix a couple of issues in recent patch to print updates to postgresql.conf
settings: avoid calling superuser() in contexts where it's not defined, don't leak the transient copies of GetConfigOption output, and avoid the whole exercise in postmaster child processes. I found that actually no current caller of GetConfigOption has any use for its internal check of GUC_SUPERUSER_ONLY. But rather than just remove that entirely, it seemed better to add a parameter indicating whether to enforce the check. Per report from Simon and subsequent testing.
-rw-r--r--src/backend/utils/misc/guc-file.l17
-rw-r--r--src/backend/utils/misc/guc.c10
-rw-r--r--src/include/utils/guc.h2
-rw-r--r--src/timezone/pgtz.c4
4 files changed, 22 insertions, 11 deletions
diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l
index 57c8686823..3170096b19 100644
--- a/src/backend/utils/misc/guc-file.l
+++ b/src/backend/utils/misc/guc-file.l
@@ -312,21 +312,26 @@ ProcessConfigFile(GucContext context)
/* If we got here all the options checked out okay, so apply them. */
for (item = head; item; item = item->next)
{
- char *pre_value = NULL;
+ char *pre_value = NULL;
- if (context == PGC_SIGHUP)
- pre_value = pstrdup(GetConfigOption(item->name));
+ /* In SIGHUP cases in the postmaster, report changes */
+ if (context == PGC_SIGHUP && !IsUnderPostmaster)
+ pre_value = pstrdup(GetConfigOption(item->name, false));
if (set_config_option(item->name, item->value, context,
PGC_S_FILE, GUC_ACTION_SET, true))
{
- if (pre_value && strcmp(pre_value, GetConfigOption(item->name)) != 0)
+ set_config_sourcefile(item->name, item->filename,
+ item->sourceline);
+ if (pre_value &&
+ strcmp(pre_value, GetConfigOption(item->name, false)) != 0)
ereport(elevel,
(errmsg("parameter \"%s\" changed to \"%s\"",
item->name, item->value)));
- set_config_sourcefile(item->name, item->filename,
- item->sourceline);
}
+
+ if (pre_value)
+ pfree(pre_value);
}
/* Remember when we last successfully loaded the config file. */
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index fc55e9017a..1f63e06962 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -5197,11 +5197,15 @@ SetConfigOption(const char *name, const char *value,
* Fetch the current value of the option `name'. If the option doesn't exist,
* throw an ereport and don't return.
*
+ * If restrict_superuser is true, we also enforce that only superusers can
+ * see GUC_SUPERUSER_ONLY variables. This should only be passed as true
+ * in user-driven calls.
+ *
* The string is *not* allocated for modification and is really only
* valid until the next call to configuration related functions.
*/
const char *
-GetConfigOption(const char *name)
+GetConfigOption(const char *name, bool restrict_superuser)
{
struct config_generic *record;
static char buffer[256];
@@ -5211,7 +5215,9 @@ GetConfigOption(const char *name)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("unrecognized configuration parameter \"%s\"", name)));
- if ((record->flags & GUC_SUPERUSER_ONLY) && !superuser())
+ if (restrict_superuser &&
+ (record->flags & GUC_SUPERUSER_ONLY) &&
+ !superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to examine \"%s\"", name)));
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 7abe41ac73..17a0985ad6 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -249,7 +249,7 @@ extern void DefineCustomEnumVariable(
extern void EmitWarningsOnPlaceholders(const char *className);
-extern const char *GetConfigOption(const char *name);
+extern const char *GetConfigOption(const char *name, bool restrict_superuser);
extern const char *GetConfigOptionResetString(const char *name);
extern void ProcessConfigFile(GucContext context);
extern void InitializeGUCOptions(void);
diff --git a/src/timezone/pgtz.c b/src/timezone/pgtz.c
index b14f2d631a..32ccc9ae97 100644
--- a/src/timezone/pgtz.c
+++ b/src/timezone/pgtz.c
@@ -1366,7 +1366,7 @@ pg_timezone_initialize(void)
pg_tz *def_tz = NULL;
/* Do we need to try to figure the session timezone? */
- if (pg_strcasecmp(GetConfigOption("timezone"), "UNKNOWN") == 0)
+ if (pg_strcasecmp(GetConfigOption("timezone", false), "UNKNOWN") == 0)
{
/* Select setting */
def_tz = select_default_timezone();
@@ -1377,7 +1377,7 @@ pg_timezone_initialize(void)
}
/* What about the log timezone? */
- if (pg_strcasecmp(GetConfigOption("log_timezone"), "UNKNOWN") == 0)
+ if (pg_strcasecmp(GetConfigOption("log_timezone", false), "UNKNOWN") == 0)
{
/* Select setting, but don't duplicate work */
if (!def_tz)