summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/tcop/postgres.c97
-rw-r--r--src/backend/utils/misc/guc.c17
-rw-r--r--src/include/utils/guc.h7
3 files changed, 78 insertions, 43 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 9b3c14399c9..893a7b95cdc 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.438 2004/11/20 00:48:58 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.439 2004/11/24 19:50:59 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@@ -2205,7 +2205,7 @@ PostgresMain(int argc, char *argv[], const char *username)
bool secure;
int errs = 0;
int debug_flag = -1; /* -1 means not given */
- List *guc_names = NIL; /* for possibly-SUSET options */
+ List *guc_names = NIL; /* for SUSET options */
List *guc_values = NIL;
GucContext ctx;
GucSource gucsource;
@@ -2456,8 +2456,15 @@ PostgresMain(int argc, char *argv[], const char *username)
/*
* s - report usage statistics (timings) after each query
+ *
+ * Since log options are SUSET, we need to postpone unless
+ * still in secure context
*/
- PendingConfigOption("log_statement_stats", "true");
+ if (ctx == PGC_BACKEND)
+ PendingConfigOption("log_statement_stats", "true");
+ else
+ SetConfigOption("log_statement_stats", "true",
+ ctx, gucsource);
break;
case 't':
@@ -2490,7 +2497,12 @@ PostgresMain(int argc, char *argv[], const char *username)
break;
}
if (tmp)
- PendingConfigOption(tmp, "true");
+ {
+ if (ctx == PGC_BACKEND)
+ PendingConfigOption(tmp, "true");
+ else
+ SetConfigOption(tmp, "true", ctx, gucsource);
+ }
break;
case 'v':
@@ -2527,7 +2539,14 @@ PostgresMain(int argc, char *argv[], const char *username)
optarg)));
}
- PendingConfigOption(name, value);
+ /*
+ * If a SUSET option, must postpone evaluation, unless
+ * we are still reading secure switches.
+ */
+ if (ctx == PGC_BACKEND && IsSuperuserConfigOption(name))
+ PendingConfigOption(name, value);
+ else
+ SetConfigOption(name, value, ctx, gucsource);
free(name);
if (value)
free(value);
@@ -2540,6 +2559,32 @@ PostgresMain(int argc, char *argv[], const char *username)
}
}
+ /*
+ * Process any additional GUC variable settings passed in startup
+ * packet. These are handled exactly like command-line variables.
+ */
+ if (MyProcPort != NULL)
+ {
+ ListCell *gucopts = list_head(MyProcPort->guc_options);
+
+ while (gucopts)
+ {
+ char *name;
+ char *value;
+
+ name = lfirst(gucopts);
+ gucopts = lnext(gucopts);
+
+ value = lfirst(gucopts);
+ gucopts = lnext(gucopts);
+
+ if (IsSuperuserConfigOption(name))
+ PendingConfigOption(name, value);
+ else
+ SetConfigOption(name, value, PGC_BACKEND, PGC_S_CLIENT);
+ }
+ }
+
/* Acquire configuration parameters, unless inherited from postmaster */
if (!IsUnderPostmaster)
{
@@ -2677,10 +2722,8 @@ PostgresMain(int argc, char *argv[], const char *username)
SetProcessingMode(NormalProcessing);
/*
- * Now that we know if client is a superuser, we can apply GUC options
- * that came from the client. (For option switches that are definitely
- * not SUSET, we just went ahead and applied them above, but anything
- * that is or might be SUSET has to be postponed to here.)
+ * Now that we know if client is a superuser, we can try to apply SUSET
+ * GUC options that came from the client.
*/
ctx = am_superuser ? PGC_SUSET : PGC_USERSET;
@@ -2704,41 +2747,19 @@ PostgresMain(int argc, char *argv[], const char *username)
}
/*
- * Process any additional GUC variable settings passed in startup
- * packet.
- */
- if (MyProcPort != NULL)
- {
- ListCell *gucopts = list_head(MyProcPort->guc_options);
-
- while (gucopts)
- {
- char *name;
- char *value;
-
- name = lfirst(gucopts);
- gucopts = lnext(gucopts);
-
- value = lfirst(gucopts);
- gucopts = lnext(gucopts);
-
- SetConfigOption(name, value, ctx, PGC_S_CLIENT);
- }
-
- /*
- * set up handler to log session end.
- */
- if (IsUnderPostmaster && Log_disconnections)
- on_proc_exit(log_disconnections, 0);
- }
-
- /*
* Now all GUC states are fully set up. Report them to client if
* appropriate.
*/
BeginReportingGUCOptions();
/*
+ * Also set up handler to log session end; we have to wait till now
+ * to be sure Log_disconnections has its final value.
+ */
+ if (IsUnderPostmaster && Log_disconnections)
+ on_proc_exit(log_disconnections, 0);
+
+ /*
* Send this backend's cancellation info to the frontend.
*/
if (whereToSendOutput == Remote &&
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 581a96caa26..fd13c41a35b 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.249 2004/11/14 19:35:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.250 2004/11/24 19:51:03 tgl Exp $
*
*--------------------------------------------------------------------
*/
@@ -3864,6 +3864,21 @@ GetConfigOptionResetString(const char *name)
return NULL;
}
+/*
+ * Detect whether the given configuration option can only be set by
+ * a superuser.
+ */
+bool
+IsSuperuserConfigOption(const char *name)
+{
+ struct config_generic *record;
+
+ record = find_option(name, ERROR);
+ /* On an unrecognized name, don't error, just return false. */
+ if (record == NULL)
+ return false;
+ return (record->context == PGC_SUSET);
+}
/*
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index f5f4a78fe4d..786d6966203 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -7,7 +7,7 @@
* Copyright (c) 2000-2004, PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
- * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.56 2004/11/14 19:35:35 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.57 2004/11/24 19:51:05 tgl Exp $
*--------------------------------------------------------------------
*/
#ifndef GUC_H
@@ -44,9 +44,7 @@
* given backend once it's started, but they can vary across backends.
*
* SUSET options can be set at postmaster startup, with the SIGHUP
- * mechanism, or from SQL if you're a superuser. These options cannot
- * be set in the connection startup packet, because when it is processed
- * we don't yet know if the user is a superuser.
+ * mechanism, or from SQL if you're a superuser.
*
* USERSET options can be set by anyone any time.
*/
@@ -177,6 +175,7 @@ extern void EmitWarningsOnPlaceholders(const char *className);
extern const char *GetConfigOption(const char *name);
extern const char *GetConfigOptionResetString(const char *name);
+extern bool IsSuperuserConfigOption(const char *name);
extern void ProcessConfigFile(GucContext context);
extern void InitializeGUCOptions(void);
extern bool SelectConfigFiles(const char *userDoption, const char *progname);