1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-13 07:41:39 +03:00

Remove GUC USERLIMIT variable category, making the affected variables

plain SUSET instead.  Also delay processing of options received in
client connection request until after we know if the user is a superuser,
so that SUSET values can be set that way by legitimate superusers.
Per recent discussion.
This commit is contained in:
Tom Lane
2004-11-14 19:35:35 +00:00
parent 1c7a47cea4
commit ea23ec82c2
9 changed files with 196 additions and 392 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.436 2004/10/15 16:50:31 momjian Exp $
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.437 2004/11/14 19:35:31 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@ -2151,6 +2151,41 @@ usage(const char *progname)
}
/*
* set_debug_options --- apply "-d N" command line option
*
* -d is not quite the same as setting log_min_messages because it enables
* other output options.
*/
void
set_debug_options(int debug_flag, GucContext context, GucSource source)
{
if (debug_flag > 0)
{
char debugstr[64];
sprintf(debugstr, "debug%d", debug_flag);
SetConfigOption("log_min_messages", debugstr, context, source);
}
else
SetConfigOption("log_min_messages", "notice", context, source);
if (debug_flag >= 1 && context == PGC_POSTMASTER)
{
SetConfigOption("log_connections", "true", context, source);
SetConfigOption("log_disconnections", "true", context, source);
}
if (debug_flag >= 2)
SetConfigOption("log_statement", "all", context, source);
if (debug_flag >= 3)
SetConfigOption("debug_print_parse", "true", context, source);
if (debug_flag >= 4)
SetConfigOption("debug_print_plan", "true", context, source);
if (debug_flag >= 5)
SetConfigOption("debug_print_rewritten", "true", context, source);
}
/* ----------------------------------------------------------------
* PostgresMain
* postgres main loop -- all backends, interactive or otherwise start here
@ -2169,10 +2204,12 @@ PostgresMain(int argc, char *argv[], const char *username)
char *userDoption = NULL;
bool secure;
int errs = 0;
int debug_flag = 0;
GucContext ctx,
debug_context;
int debug_flag = -1; /* -1 means not given */
List *guc_names = NIL; /* for possibly-SUSET options */
List *guc_values = NIL;
GucContext ctx;
GucSource gucsource;
bool am_superuser;
char *tmp;
int firstchar;
char stack_base;
@ -2180,6 +2217,10 @@ PostgresMain(int argc, char *argv[], const char *username)
sigjmp_buf local_sigjmp_buf;
volatile bool send_rfq = true;
#define PendingConfigOption(name,val) \
(guc_names = lappend(guc_names, pstrdup(name)), \
guc_values = lappend(guc_values, pstrdup(val)))
/*
* Catch standard options before doing much else. This even works on
* systems without getopt_long.
@ -2257,10 +2298,11 @@ PostgresMain(int argc, char *argv[], const char *username)
/* all options are allowed until '-p' */
secure = true;
ctx = debug_context = PGC_POSTMASTER;
ctx = PGC_POSTMASTER;
gucsource = PGC_S_ARGV; /* initial switches came from command line */
while ((flag = getopt(argc, argv, "A:B:c:D:d:Eef:FiNOPo:p:S:st:v:W:-:")) != -1)
{
switch (flag)
{
case 'A':
@ -2287,40 +2329,7 @@ PostgresMain(int argc, char *argv[], const char *username)
break;
case 'd': /* debug level */
{
/*
* Client option can't decrease debug level. We have
* to do the test here because we group priv and
* client set GUC calls below, after we know the final
* debug value.
*/
if (ctx != PGC_BACKEND || atoi(optarg) > debug_flag)
{
debug_flag = atoi(optarg);
debug_context = ctx; /* save context for use
* below */
/* Set server debugging level. */
if (debug_flag != 0)
{
char *debugstr = palloc(strlen("debug") + strlen(optarg) + 1);
sprintf(debugstr, "debug%s", optarg);
SetConfigOption("log_min_messages", debugstr, ctx, gucsource);
pfree(debugstr);
}
else
/*
* -d0 allows user to prevent postmaster debug
* from propagating to backend. It would be
* nice to set it to the postgresql.conf value
* here.
*/
SetConfigOption("log_min_messages", "notice",
ctx, gucsource);
}
}
debug_flag = atoi(optarg);
break;
case 'E':
@ -2448,7 +2457,7 @@ PostgresMain(int argc, char *argv[], const char *username)
/*
* s - report usage statistics (timings) after each query
*/
SetConfigOption("log_statement_stats", "true", ctx, gucsource);
PendingConfigOption("log_statement_stats", "true");
break;
case 't':
@ -2481,7 +2490,7 @@ PostgresMain(int argc, char *argv[], const char *username)
break;
}
if (tmp)
SetConfigOption(tmp, "true", ctx, gucsource);
PendingConfigOption(tmp, "true");
break;
case 'v':
@ -2518,7 +2527,7 @@ PostgresMain(int argc, char *argv[], const char *username)
optarg)));
}
SetConfigOption(name, value, ctx, gucsource);
PendingConfigOption(name, value);
free(name);
if (value)
free(value);
@ -2529,53 +2538,6 @@ PostgresMain(int argc, char *argv[], const char *username)
errs++;
break;
}
/*
* -d is not the same as setting log_min_messages because it enables
* other output options.
*/
if (debug_flag >= 1)
{
SetConfigOption("log_connections", "true", debug_context, gucsource);
SetConfigOption("log_disconnections", "true", debug_context, gucsource);
}
if (debug_flag >= 2)
SetConfigOption("log_statement", "all", debug_context, gucsource);
if (debug_flag >= 3)
SetConfigOption("debug_print_parse", "true", debug_context, gucsource);
if (debug_flag >= 4)
SetConfigOption("debug_print_plan", "true", debug_context, gucsource);
if (debug_flag >= 5)
SetConfigOption("debug_print_rewritten", "true", debug_context, gucsource);
/*
* 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, PGC_BACKEND, PGC_S_CLIENT);
}
/*
* set up handler to log session end.
*/
if (IsUnderPostmaster && Log_disconnections)
on_proc_exit(log_disconnections, 0);
}
/* Acquire configuration parameters, unless inherited from postmaster */
@ -2710,10 +2672,72 @@ PostgresMain(int argc, char *argv[], const char *username)
*/
ereport(DEBUG3,
(errmsg_internal("InitPostgres")));
InitPostgres(dbname, username);
am_superuser = InitPostgres(dbname, 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.)
*/
ctx = am_superuser ? PGC_SUSET : PGC_USERSET;
if (debug_flag >= 0)
set_debug_options(debug_flag, ctx, PGC_S_CLIENT);
if (guc_names != NIL)
{
ListCell *namcell,
*valcell;
forboth(namcell, guc_names, valcell, guc_values)
{
char *name = (char *) lfirst(namcell);
char *value = (char *) lfirst(valcell);
SetConfigOption(name, value, ctx, PGC_S_CLIENT);
pfree(name);
pfree(value);
}
}
/*
* 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();
/*
* Send this backend's cancellation info to the frontend.
*/