mirror of
https://github.com/postgres/postgres.git
synced 2025-04-21 12:05:57 +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:
parent
1c7a47cea4
commit
ea23ec82c2
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.291 2004/11/05 19:15:49 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.292 2004/11/14 19:35:28 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<Chapter Id="runtime">
|
<Chapter Id="runtime">
|
||||||
@ -2150,7 +2150,7 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"' # Win32
|
|||||||
to the log. The default is <literal>NOTICE</>. Note that
|
to the log. The default is <literal>NOTICE</>. Note that
|
||||||
<literal>LOG</> has a different rank here than in
|
<literal>LOG</> has a different rank here than in
|
||||||
<varname>client_min_messages</>.
|
<varname>client_min_messages</>.
|
||||||
Only superusers can increase this option.
|
Only superusers can change this setting.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -2186,7 +2186,7 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"' # Win32
|
|||||||
SQL statements causing errors, fatal errors, or panics will be
|
SQL statements causing errors, fatal errors, or panics will be
|
||||||
logged. Enabling this option can be helpful in tracking down
|
logged. Enabling this option can be helpful in tracking down
|
||||||
the source of any errors that appear in the server log.
|
the source of any errors that appear in the server log.
|
||||||
Only superusers can increase this option.
|
Only superusers can change this setting.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -2204,8 +2204,7 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"' # Win32
|
|||||||
<literal>250</literal> then all SQL statements that run 250ms
|
<literal>250</literal> then all SQL statements that run 250ms
|
||||||
or longer will be logged. Enabling this option can be
|
or longer will be logged. Enabling this option can be
|
||||||
useful in tracking down unoptimized queries in your applications.
|
useful in tracking down unoptimized queries in your applications.
|
||||||
Only superusers can increase this or set it to minus-one if this
|
Only superusers can change this setting.
|
||||||
option is set by the administrator.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -2332,7 +2331,7 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"' # Win32
|
|||||||
these displays to produce a more readable but much longer
|
these displays to produce a more readable but much longer
|
||||||
output format. <varname>client_min_messages</varname> or
|
output format. <varname>client_min_messages</varname> or
|
||||||
<varname>log_min_messages</varname> must be
|
<varname>log_min_messages</varname> must be
|
||||||
<literal>DEBUG1</literal> or lower to send output to the
|
<literal>DEBUG1</literal> or lower to send the output to the
|
||||||
client or server logs. These options are off by default.
|
client or server logs. These options are off by default.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
@ -2372,10 +2371,9 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"' # Win32
|
|||||||
<varname>log_statement</> to be logged. When using this option,
|
<varname>log_statement</> to be logged. When using this option,
|
||||||
if you are not using <application>syslog</>, it is recommended
|
if you are not using <application>syslog</>, it is recommended
|
||||||
that you log the PID or session ID using <varname>log_line_prefix</>
|
that you log the PID or session ID using <varname>log_line_prefix</>
|
||||||
or log the session ID so that you can link the statement to the
|
so that you can link the statement to the
|
||||||
duration using the process ID or session ID. The default is off.
|
duration using the process ID or session ID. The default is off.
|
||||||
Only superusers can turn off this option if it is enabled by the
|
Only superusers can change this setting.
|
||||||
administrator.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -2487,35 +2485,35 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"' # Win32
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Controls which SQL statements are logged. Valid values are
|
Controls which SQL statements are logged. Valid values are
|
||||||
<literal>all</>, <literal>ddl</>, <literal>mod</>, and
|
<literal>none</>, <literal>ddl</>, <literal>mod</>, and
|
||||||
<literal>none</>. <literal>ddl</> logs all data definition
|
<literal>all</>. <literal>ddl</> logs all data definition
|
||||||
commands like <literal>CREATE</>, <literal>ALTER</>, and
|
commands like <literal>CREATE</>, <literal>ALTER</>, and
|
||||||
<literal>DROP</> commands. <literal>mod</> logs all
|
<literal>DROP</> commands. <literal>mod</> logs all
|
||||||
<literal>ddl</> statements, plus <literal>INSERT</>,
|
<literal>ddl</> statements, plus <literal>INSERT</>,
|
||||||
<literal>UPDATE</>, <literal>DELETE</>, <literal>TRUNCATE</>,
|
<literal>UPDATE</>, <literal>DELETE</>, <literal>TRUNCATE</>,
|
||||||
and <literal>COPY FROM</>. <literal>PREPARE</> and
|
and <literal>COPY FROM</>. <literal>PREPARE</> and
|
||||||
<literal>EXPLAIN ANALYZE</> statements are also considered for
|
<literal>EXPLAIN ANALYZE</> statements are also logged if their
|
||||||
appropriate commands.
|
contained command is of an appropriate type.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The default is <literal>none</>. Only superusers can reduce
|
The default is <literal>none</>. Only superusers can change this
|
||||||
the detail of this option if it has been set by an administrator.
|
setting.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
The <command>EXECUTE</command> statement not considered a
|
The <command>EXECUTE</command> statement is not considered a
|
||||||
<literal>ddl</> or <literal>mod</> statement. When it is logged,
|
<literal>ddl</> or <literal>mod</> statement. When it is logged,
|
||||||
only the name of the prepared statement is reported, not the
|
only the name of the prepared statement is reported, not the
|
||||||
actual prepared statement.
|
actual prepared statement.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
When a function is defined in a server-side language like
|
When a function is defined in the
|
||||||
<application>PL/pgSQL</application>, any queries executed by
|
<application>PL/pgSQL</application>server-side language, any queries
|
||||||
the function will only be logged the first time that the
|
executed by the function will only be logged the first time that the
|
||||||
function is invoked in a particular session. This is because
|
function is invoked in a particular session. This is because
|
||||||
the <application>PL/pgSQL</application> keeps a cache of the
|
<application>PL/pgSQL</application> keeps a cache of the
|
||||||
query plans produced for the SQL statements in the function.
|
query plans produced for the SQL statements in the function.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
@ -2556,11 +2554,10 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"' # Win32
|
|||||||
For each query, write performance statistics of the respective
|
For each query, write performance statistics of the respective
|
||||||
module to the server log. This is a crude profiling
|
module to the server log. This is a crude profiling
|
||||||
instrument. <varname>log_statement_stats</varname> reports total
|
instrument. <varname>log_statement_stats</varname> reports total
|
||||||
statement statistics, while the others report per-state statistics.
|
statement statistics, while the others report per-module statistics.
|
||||||
<varname>log_statement_stats</varname> can not be enabled with
|
<varname>log_statement_stats</varname> cannot be enabled together with
|
||||||
the other options. All of these options are disabled by default.
|
any of the per-module options. All of these options are disabled by
|
||||||
Only superusers can turn off any of these options if they have
|
default. Only superusers can change these settings.
|
||||||
been enabled by the administrator.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.195 2004/10/10 23:37:16 neilc Exp $
|
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.196 2004/11/14 19:35:29 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -424,7 +424,7 @@ BootstrapMain(int argc, char *argv[])
|
|||||||
/*
|
/*
|
||||||
* backend initialization
|
* backend initialization
|
||||||
*/
|
*/
|
||||||
InitPostgres(dbname, NULL);
|
(void) InitPostgres(dbname, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In NOP mode, all we really want to do is create shared memory and
|
* In NOP mode, all we really want to do is create shared memory and
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.437 2004/11/09 13:01:26 petere Exp $
|
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.438 2004/11/14 19:35:30 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
*
|
*
|
||||||
@ -223,8 +223,6 @@ bool ClientAuthInProgress = false; /* T during new-client
|
|||||||
*/
|
*/
|
||||||
static unsigned int random_seed = 0;
|
static unsigned int random_seed = 0;
|
||||||
|
|
||||||
static int debug_flag = 0;
|
|
||||||
|
|
||||||
extern char *optarg;
|
extern char *optarg;
|
||||||
extern int optind,
|
extern int optind,
|
||||||
opterr;
|
opterr;
|
||||||
@ -401,17 +399,8 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
userDoption = optarg;
|
userDoption = optarg;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
{
|
set_debug_options(atoi(optarg), PGC_POSTMASTER, PGC_S_ARGV);
|
||||||
/* Turn on debugging for the postmaster. */
|
break;
|
||||||
char *debugstr = palloc(strlen("debug") + strlen(optarg) + 1);
|
|
||||||
|
|
||||||
sprintf(debugstr, "debug%s", optarg);
|
|
||||||
SetConfigOption("log_min_messages", debugstr,
|
|
||||||
PGC_POSTMASTER, PGC_S_ARGV);
|
|
||||||
pfree(debugstr);
|
|
||||||
debug_flag = atoi(optarg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'F':
|
case 'F':
|
||||||
SetConfigOption("fsync", "false", PGC_POSTMASTER, PGC_S_ARGV);
|
SetConfigOption("fsync", "false", PGC_POSTMASTER, PGC_S_ARGV);
|
||||||
break;
|
break;
|
||||||
@ -2511,7 +2500,6 @@ BackendRun(Port *port)
|
|||||||
char **av;
|
char **av;
|
||||||
int maxac;
|
int maxac;
|
||||||
int ac;
|
int ac;
|
||||||
char debugbuf[32];
|
|
||||||
char protobuf[32];
|
char protobuf[32];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -2707,15 +2695,6 @@ BackendRun(Port *port)
|
|||||||
|
|
||||||
av[ac++] = "postgres";
|
av[ac++] = "postgres";
|
||||||
|
|
||||||
/*
|
|
||||||
* Pass the requested debugging level along to the backend.
|
|
||||||
*/
|
|
||||||
if (debug_flag > 0)
|
|
||||||
{
|
|
||||||
snprintf(debugbuf, sizeof(debugbuf), "-d%d", debug_flag);
|
|
||||||
av[ac++] = debugbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pass any backend switches specified with -o in the postmaster's own
|
* Pass any backend switches specified with -o in the postmaster's own
|
||||||
* command line. We assume these are secure. (It's OK to mangle
|
* command line. We assume these are secure. (It's OK to mangle
|
||||||
@ -3404,7 +3383,6 @@ write_backend_variables(char *filename, Port *port)
|
|||||||
write_var(ProcStructLock, fp);
|
write_var(ProcStructLock, fp);
|
||||||
write_var(pgStatSock, fp);
|
write_var(pgStatSock, fp);
|
||||||
|
|
||||||
write_var(debug_flag, fp);
|
|
||||||
write_var(PostmasterPid, fp);
|
write_var(PostmasterPid, fp);
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
write_var(PostmasterHandle, fp);
|
write_var(PostmasterHandle, fp);
|
||||||
@ -3478,7 +3456,6 @@ read_backend_variables(char *filename, Port *port)
|
|||||||
read_var(ProcStructLock, fp);
|
read_var(ProcStructLock, fp);
|
||||||
read_var(pgStatSock, fp);
|
read_var(pgStatSock, fp);
|
||||||
|
|
||||||
read_var(debug_flag, fp);
|
|
||||||
read_var(PostmasterPid, fp);
|
read_var(PostmasterPid, fp);
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
read_var(PostmasterHandle, fp);
|
read_var(PostmasterHandle, fp);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* this is the "main" module of the postgres backend and
|
* 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
|
* PostgresMain
|
||||||
* postgres main loop -- all backends, interactive or otherwise start here
|
* 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;
|
char *userDoption = NULL;
|
||||||
bool secure;
|
bool secure;
|
||||||
int errs = 0;
|
int errs = 0;
|
||||||
int debug_flag = 0;
|
int debug_flag = -1; /* -1 means not given */
|
||||||
GucContext ctx,
|
List *guc_names = NIL; /* for possibly-SUSET options */
|
||||||
debug_context;
|
List *guc_values = NIL;
|
||||||
|
GucContext ctx;
|
||||||
GucSource gucsource;
|
GucSource gucsource;
|
||||||
|
bool am_superuser;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
int firstchar;
|
int firstchar;
|
||||||
char stack_base;
|
char stack_base;
|
||||||
@ -2180,6 +2217,10 @@ PostgresMain(int argc, char *argv[], const char *username)
|
|||||||
sigjmp_buf local_sigjmp_buf;
|
sigjmp_buf local_sigjmp_buf;
|
||||||
volatile bool send_rfq = true;
|
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
|
* Catch standard options before doing much else. This even works on
|
||||||
* systems without getopt_long.
|
* systems without getopt_long.
|
||||||
@ -2257,10 +2298,11 @@ PostgresMain(int argc, char *argv[], const char *username)
|
|||||||
|
|
||||||
/* all options are allowed until '-p' */
|
/* all options are allowed until '-p' */
|
||||||
secure = true;
|
secure = true;
|
||||||
ctx = debug_context = PGC_POSTMASTER;
|
ctx = PGC_POSTMASTER;
|
||||||
gucsource = PGC_S_ARGV; /* initial switches came from command line */
|
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)
|
while ((flag = getopt(argc, argv, "A:B:c:D:d:Eef:FiNOPo:p:S:st:v:W:-:")) != -1)
|
||||||
|
{
|
||||||
switch (flag)
|
switch (flag)
|
||||||
{
|
{
|
||||||
case 'A':
|
case 'A':
|
||||||
@ -2287,40 +2329,7 @@ PostgresMain(int argc, char *argv[], const char *username)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd': /* debug level */
|
case 'd': /* debug level */
|
||||||
{
|
debug_flag = atoi(optarg);
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'E':
|
case 'E':
|
||||||
@ -2448,7 +2457,7 @@ PostgresMain(int argc, char *argv[], const char *username)
|
|||||||
/*
|
/*
|
||||||
* s - report usage statistics (timings) after each query
|
* s - report usage statistics (timings) after each query
|
||||||
*/
|
*/
|
||||||
SetConfigOption("log_statement_stats", "true", ctx, gucsource);
|
PendingConfigOption("log_statement_stats", "true");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
@ -2481,7 +2490,7 @@ PostgresMain(int argc, char *argv[], const char *username)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (tmp)
|
if (tmp)
|
||||||
SetConfigOption(tmp, "true", ctx, gucsource);
|
PendingConfigOption(tmp, "true");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'v':
|
case 'v':
|
||||||
@ -2518,7 +2527,7 @@ PostgresMain(int argc, char *argv[], const char *username)
|
|||||||
optarg)));
|
optarg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
SetConfigOption(name, value, ctx, gucsource);
|
PendingConfigOption(name, value);
|
||||||
free(name);
|
free(name);
|
||||||
if (value)
|
if (value)
|
||||||
free(value);
|
free(value);
|
||||||
@ -2529,53 +2538,6 @@ PostgresMain(int argc, char *argv[], const char *username)
|
|||||||
errs++;
|
errs++;
|
||||||
break;
|
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 */
|
/* Acquire configuration parameters, unless inherited from postmaster */
|
||||||
@ -2710,10 +2672,72 @@ PostgresMain(int argc, char *argv[], const char *username)
|
|||||||
*/
|
*/
|
||||||
ereport(DEBUG3,
|
ereport(DEBUG3,
|
||||||
(errmsg_internal("InitPostgres")));
|
(errmsg_internal("InitPostgres")));
|
||||||
InitPostgres(dbname, username);
|
am_superuser = InitPostgres(dbname, username);
|
||||||
|
|
||||||
SetProcessingMode(NormalProcessing);
|
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.
|
* Send this backend's cancellation info to the frontend.
|
||||||
*/
|
*/
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.137 2004/08/29 05:06:51 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.138 2004/11/14 19:35:32 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
@ -221,14 +221,21 @@ BaseInit(void)
|
|||||||
* InitPostgres
|
* InitPostgres
|
||||||
* Initialize POSTGRES.
|
* Initialize POSTGRES.
|
||||||
*
|
*
|
||||||
|
* In bootstrap mode neither of the parameters are used.
|
||||||
|
*
|
||||||
|
* The return value indicates whether the userID is a superuser. (That
|
||||||
|
* can only be tested inside a transaction, so we want to do it during
|
||||||
|
* the startup transaction rather than doing a separate one in postgres.c.)
|
||||||
|
*
|
||||||
* Note:
|
* Note:
|
||||||
* Be very careful with the order of calls in the InitPostgres function.
|
* Be very careful with the order of calls in the InitPostgres function.
|
||||||
* --------------------------------
|
* --------------------------------
|
||||||
*/
|
*/
|
||||||
void
|
bool
|
||||||
InitPostgres(const char *dbname, const char *username)
|
InitPostgres(const char *dbname, const char *username)
|
||||||
{
|
{
|
||||||
bool bootstrap = IsBootstrapProcessingMode();
|
bool bootstrap = IsBootstrapProcessingMode();
|
||||||
|
bool am_superuser;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up the global variables holding database id and path.
|
* Set up the global variables holding database id and path.
|
||||||
@ -398,15 +405,19 @@ InitPostgres(const char *dbname, const char *username)
|
|||||||
RelationCacheInitializePhase3();
|
RelationCacheInitializePhase3();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check a normal user hasn't connected to a superuser reserved slot.
|
* Check if user is a superuser.
|
||||||
* We can't do this till after we've read the user information, and we
|
|
||||||
* must do it inside a transaction since checking superuserness may
|
|
||||||
* require database access. The superuser check is probably the most
|
|
||||||
* expensive part; don't do it until necessary.
|
|
||||||
*/
|
*/
|
||||||
if (ReservedBackends > 0 &&
|
if (bootstrap)
|
||||||
CountEmptyBackendSlots() < ReservedBackends &&
|
am_superuser = true;
|
||||||
!superuser())
|
else
|
||||||
|
am_superuser = superuser();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check a normal user hasn't connected to a superuser reserved slot.
|
||||||
|
*/
|
||||||
|
if (!am_superuser &&
|
||||||
|
ReservedBackends > 0 &&
|
||||||
|
CountEmptyBackendSlots() < ReservedBackends)
|
||||||
ereport(FATAL,
|
ereport(FATAL,
|
||||||
(errcode(ERRCODE_TOO_MANY_CONNECTIONS),
|
(errcode(ERRCODE_TOO_MANY_CONNECTIONS),
|
||||||
errmsg("connection limit exceeded for non-superusers")));
|
errmsg("connection limit exceeded for non-superusers")));
|
||||||
@ -422,12 +433,6 @@ InitPostgres(const char *dbname, const char *username)
|
|||||||
/* initialize client encoding */
|
/* initialize client encoding */
|
||||||
InitializeClientEncoding();
|
InitializeClientEncoding();
|
||||||
|
|
||||||
/*
|
|
||||||
* Now all default states are fully set up. Report them to client if
|
|
||||||
* appropriate.
|
|
||||||
*/
|
|
||||||
BeginReportingGUCOptions();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up process-exit callback to do pre-shutdown cleanup. This
|
* Set up process-exit callback to do pre-shutdown cleanup. This
|
||||||
* should be last because we want shmem_exit to call this routine
|
* should be last because we want shmem_exit to call this routine
|
||||||
@ -440,6 +445,8 @@ InitPostgres(const char *dbname, const char *username)
|
|||||||
/* close the transaction we started above */
|
/* close the transaction we started above */
|
||||||
if (!bootstrap)
|
if (!bootstrap)
|
||||||
CommitTransactionCommand();
|
CommitTransactionCommand();
|
||||||
|
|
||||||
|
return am_superuser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.248 2004/11/05 19:16:16 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.249 2004/11/14 19:35:33 tgl Exp $
|
||||||
*
|
*
|
||||||
*--------------------------------------------------------------------
|
*--------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -105,8 +105,6 @@ static const char *assign_log_error_verbosity(const char *newval, bool doit,
|
|||||||
GucSource source);
|
GucSource source);
|
||||||
static const char *assign_log_statement(const char *newval, bool doit,
|
static const char *assign_log_statement(const char *newval, bool doit,
|
||||||
GucSource source);
|
GucSource source);
|
||||||
static const char *assign_log_stmtlvl(int *var, const char *newval,
|
|
||||||
bool doit, GucSource source);
|
|
||||||
static bool assign_phony_autocommit(bool newval, bool doit, GucSource source);
|
static bool assign_phony_autocommit(bool newval, bool doit, GucSource source);
|
||||||
static const char *assign_custom_variable_classes(const char *newval, bool doit,
|
static const char *assign_custom_variable_classes(const char *newval, bool doit,
|
||||||
GucSource source);
|
GucSource source);
|
||||||
@ -204,7 +202,6 @@ const char *const GucContext_Names[] =
|
|||||||
/* PGC_SIGHUP */ "sighup",
|
/* PGC_SIGHUP */ "sighup",
|
||||||
/* PGC_BACKEND */ "backend",
|
/* PGC_BACKEND */ "backend",
|
||||||
/* PGC_SUSET */ "superuser",
|
/* PGC_SUSET */ "superuser",
|
||||||
/* PGC_USERLIMIT */ "userlimit",
|
|
||||||
/* PGC_USERSET */ "user"
|
/* PGC_USERSET */ "user"
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -219,7 +216,6 @@ const char *const GucSource_Names[] =
|
|||||||
/* PGC_S_ENV_VAR */ "environment variable",
|
/* PGC_S_ENV_VAR */ "environment variable",
|
||||||
/* PGC_S_FILE */ "configuration file",
|
/* PGC_S_FILE */ "configuration file",
|
||||||
/* PGC_S_ARGV */ "command line",
|
/* PGC_S_ARGV */ "command line",
|
||||||
/* PGC_S_UNPRIVILEGED */ "unprivileged",
|
|
||||||
/* PGC_S_DATABASE */ "database",
|
/* PGC_S_DATABASE */ "database",
|
||||||
/* PGC_S_USER */ "user",
|
/* PGC_S_USER */ "user",
|
||||||
/* PGC_S_CLIENT */ "client",
|
/* PGC_S_CLIENT */ "client",
|
||||||
@ -520,8 +516,8 @@ static struct config_bool ConfigureNamesBool[] =
|
|||||||
false, NULL, NULL
|
false, NULL, NULL
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{"log_duration", PGC_USERLIMIT, LOGGING_WHAT,
|
{"log_duration", PGC_SUSET, LOGGING_WHAT,
|
||||||
gettext_noop("Logs the duration each completed SQL statement."),
|
gettext_noop("Logs the duration of each completed SQL statement."),
|
||||||
NULL
|
NULL
|
||||||
},
|
},
|
||||||
&log_duration,
|
&log_duration,
|
||||||
@ -560,7 +556,7 @@ static struct config_bool ConfigureNamesBool[] =
|
|||||||
false, NULL, NULL
|
false, NULL, NULL
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{"log_parser_stats", PGC_USERLIMIT, STATS_MONITORING,
|
{"log_parser_stats", PGC_SUSET, STATS_MONITORING,
|
||||||
gettext_noop("Writes parser performance statistics to the server log."),
|
gettext_noop("Writes parser performance statistics to the server log."),
|
||||||
NULL
|
NULL
|
||||||
},
|
},
|
||||||
@ -568,7 +564,7 @@ static struct config_bool ConfigureNamesBool[] =
|
|||||||
false, assign_stage_log_stats, NULL
|
false, assign_stage_log_stats, NULL
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{"log_planner_stats", PGC_USERLIMIT, STATS_MONITORING,
|
{"log_planner_stats", PGC_SUSET, STATS_MONITORING,
|
||||||
gettext_noop("Writes planner performance statistics to the server log."),
|
gettext_noop("Writes planner performance statistics to the server log."),
|
||||||
NULL
|
NULL
|
||||||
},
|
},
|
||||||
@ -576,7 +572,7 @@ static struct config_bool ConfigureNamesBool[] =
|
|||||||
false, assign_stage_log_stats, NULL
|
false, assign_stage_log_stats, NULL
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{"log_executor_stats", PGC_USERLIMIT, STATS_MONITORING,
|
{"log_executor_stats", PGC_SUSET, STATS_MONITORING,
|
||||||
gettext_noop("Writes executor performance statistics to the server log."),
|
gettext_noop("Writes executor performance statistics to the server log."),
|
||||||
NULL
|
NULL
|
||||||
},
|
},
|
||||||
@ -584,7 +580,7 @@ static struct config_bool ConfigureNamesBool[] =
|
|||||||
false, assign_stage_log_stats, NULL
|
false, assign_stage_log_stats, NULL
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{"log_statement_stats", PGC_USERLIMIT, STATS_MONITORING,
|
{"log_statement_stats", PGC_SUSET, STATS_MONITORING,
|
||||||
gettext_noop("Writes cumulative performance statistics to the server log."),
|
gettext_noop("Writes cumulative performance statistics to the server log."),
|
||||||
NULL
|
NULL
|
||||||
},
|
},
|
||||||
@ -1225,7 +1221,7 @@ static struct config_int ConfigureNamesInt[] =
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{"log_min_duration_statement", PGC_USERLIMIT, LOGGING_WHEN,
|
{"log_min_duration_statement", PGC_SUSET, LOGGING_WHEN,
|
||||||
gettext_noop("Sets the minimum execution time in milliseconds above which statements will "
|
gettext_noop("Sets the minimum execution time in milliseconds above which statements will "
|
||||||
"be logged."),
|
"be logged."),
|
||||||
gettext_noop("Zero prints all queries. The default is -1 (turning this feature off).")
|
gettext_noop("Zero prints all queries. The default is -1 (turning this feature off).")
|
||||||
@ -1449,7 +1445,7 @@ static struct config_string ConfigureNamesString[] =
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{"log_min_messages", PGC_USERLIMIT, LOGGING_WHEN,
|
{"log_min_messages", PGC_SUSET, LOGGING_WHEN,
|
||||||
gettext_noop("Sets the message levels that are logged."),
|
gettext_noop("Sets the message levels that are logged."),
|
||||||
gettext_noop("Valid values are DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1, "
|
gettext_noop("Valid values are DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1, "
|
||||||
"INFO, NOTICE, WARNING, ERROR, LOG, FATAL, and PANIC. Each level "
|
"INFO, NOTICE, WARNING, ERROR, LOG, FATAL, and PANIC. Each level "
|
||||||
@ -1468,16 +1464,16 @@ static struct config_string ConfigureNamesString[] =
|
|||||||
"default", assign_log_error_verbosity, NULL
|
"default", assign_log_error_verbosity, NULL
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{"log_statement", PGC_USERLIMIT, LOGGING_WHAT,
|
{"log_statement", PGC_SUSET, LOGGING_WHAT,
|
||||||
gettext_noop("Sets the type of statements logged."),
|
gettext_noop("Sets the type of statements logged."),
|
||||||
gettext_noop("Valid values are \"none\", \"mod\", \"ddl\", and \"all\".")
|
gettext_noop("Valid values are \"none\", \"ddl\", \"mod\", and \"all\".")
|
||||||
},
|
},
|
||||||
&log_statement_str,
|
&log_statement_str,
|
||||||
"none", assign_log_statement, NULL
|
"none", assign_log_statement, NULL
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{"log_min_error_statement", PGC_USERLIMIT, LOGGING_WHEN,
|
{"log_min_error_statement", PGC_SUSET, LOGGING_WHEN,
|
||||||
gettext_noop("Causes all statements generating error at or above this level to be logged."),
|
gettext_noop("Causes all statements generating error at or above this level to be logged."),
|
||||||
gettext_noop("All SQL statements that cause an error of the "
|
gettext_noop("All SQL statements that cause an error of the "
|
||||||
"specified level or a higher level are logged.")
|
"specified level or a higher level are logged.")
|
||||||
@ -1896,10 +1892,6 @@ static void ReportGUCOption(struct config_generic * record);
|
|||||||
static void ShowGUCConfigOption(const char *name, DestReceiver *dest);
|
static void ShowGUCConfigOption(const char *name, DestReceiver *dest);
|
||||||
static void ShowAllGUCConfig(DestReceiver *dest);
|
static void ShowAllGUCConfig(DestReceiver *dest);
|
||||||
static char *_ShowOption(struct config_generic * record);
|
static char *_ShowOption(struct config_generic * record);
|
||||||
static bool check_userlimit_privilege(struct config_generic *record,
|
|
||||||
GucSource source, int elevel);
|
|
||||||
static bool check_userlimit_override(struct config_generic *record,
|
|
||||||
GucSource source);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2345,13 +2337,6 @@ InitializeGUCOptions(void)
|
|||||||
|
|
||||||
Assert(conf->reset_val >= conf->min);
|
Assert(conf->reset_val >= conf->min);
|
||||||
Assert(conf->reset_val <= conf->max);
|
Assert(conf->reset_val <= conf->max);
|
||||||
|
|
||||||
/*
|
|
||||||
* Check to make sure we only have valid
|
|
||||||
* PGC_USERLIMITs
|
|
||||||
*/
|
|
||||||
Assert(conf->gen.context != PGC_USERLIMIT ||
|
|
||||||
strcmp(conf->gen.name, "log_min_duration_statement") == 0);
|
|
||||||
if (conf->assign_hook)
|
if (conf->assign_hook)
|
||||||
if (!(*conf->assign_hook) (conf->reset_val, true,
|
if (!(*conf->assign_hook) (conf->reset_val, true,
|
||||||
PGC_S_DEFAULT))
|
PGC_S_DEFAULT))
|
||||||
@ -2366,7 +2351,6 @@ InitializeGUCOptions(void)
|
|||||||
|
|
||||||
Assert(conf->reset_val >= conf->min);
|
Assert(conf->reset_val >= conf->min);
|
||||||
Assert(conf->reset_val <= conf->max);
|
Assert(conf->reset_val <= conf->max);
|
||||||
Assert(conf->gen.context != PGC_USERLIMIT);
|
|
||||||
if (conf->assign_hook)
|
if (conf->assign_hook)
|
||||||
if (!(*conf->assign_hook) (conf->reset_val, true,
|
if (!(*conf->assign_hook) (conf->reset_val, true,
|
||||||
PGC_S_DEFAULT))
|
PGC_S_DEFAULT))
|
||||||
@ -2380,14 +2364,6 @@ InitializeGUCOptions(void)
|
|||||||
struct config_string *conf = (struct config_string *) gconf;
|
struct config_string *conf = (struct config_string *) gconf;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
/*
|
|
||||||
* Check to make sure we only have valid
|
|
||||||
* PGC_USERLIMITs
|
|
||||||
*/
|
|
||||||
Assert(conf->gen.context != PGC_USERLIMIT ||
|
|
||||||
conf->assign_hook == assign_log_min_messages ||
|
|
||||||
conf->assign_hook == assign_min_error_statement ||
|
|
||||||
conf->assign_hook == assign_log_statement);
|
|
||||||
*conf->variable = NULL;
|
*conf->variable = NULL;
|
||||||
conf->reset_val = NULL;
|
conf->reset_val = NULL;
|
||||||
conf->tentative_val = NULL;
|
conf->tentative_val = NULL;
|
||||||
@ -2628,7 +2604,6 @@ ResetAllOptions(void)
|
|||||||
|
|
||||||
/* Don't reset non-SET-able values */
|
/* Don't reset non-SET-able values */
|
||||||
if (gconf->context != PGC_SUSET &&
|
if (gconf->context != PGC_SUSET &&
|
||||||
gconf->context != PGC_USERLIMIT &&
|
|
||||||
gconf->context != PGC_USERSET)
|
gconf->context != PGC_USERSET)
|
||||||
continue;
|
continue;
|
||||||
/* Don't reset if special exclusion from RESET ALL */
|
/* Don't reset if special exclusion from RESET ALL */
|
||||||
@ -3276,8 +3251,7 @@ set_config_option(const char *name, const char *value,
|
|||||||
{
|
{
|
||||||
struct config_generic *record;
|
struct config_generic *record;
|
||||||
int elevel;
|
int elevel;
|
||||||
bool makeDefault,
|
bool makeDefault;
|
||||||
changeValOrig = changeVal;
|
|
||||||
|
|
||||||
if (context == PGC_SIGHUP || source == PGC_S_DEFAULT)
|
if (context == PGC_SIGHUP || source == PGC_S_DEFAULT)
|
||||||
{
|
{
|
||||||
@ -3383,9 +3357,6 @@ set_config_option(const char *name, const char *value,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PGC_USERLIMIT:
|
|
||||||
/* USERLIMIT permissions checked below */
|
|
||||||
break;
|
|
||||||
case PGC_USERSET:
|
case PGC_USERSET:
|
||||||
/* always okay */
|
/* always okay */
|
||||||
break;
|
break;
|
||||||
@ -3413,14 +3384,11 @@ set_config_option(const char *name, const char *value,
|
|||||||
name);
|
name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
changeVal = false; /* this might be reset in USERLIMIT */
|
changeVal = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Evaluate value and set variable. USERLIMIT checks two things: 1)
|
* Evaluate value and set variable.
|
||||||
* is the user making a change that is blocked by an administrator
|
|
||||||
* setting. 2) is the administrator changing a setting and doing a
|
|
||||||
* SIGHUP that requires us to override a user setting.
|
|
||||||
*/
|
*/
|
||||||
switch (record->vartype)
|
switch (record->vartype)
|
||||||
{
|
{
|
||||||
@ -3439,22 +3407,6 @@ set_config_option(const char *name, const char *value,
|
|||||||
name)));
|
name)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (record->context == PGC_USERLIMIT)
|
|
||||||
{
|
|
||||||
if (newval < conf->reset_val)
|
|
||||||
{
|
|
||||||
/* Limit non-superuser changes */
|
|
||||||
if (!check_userlimit_privilege(record, source,
|
|
||||||
elevel))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (newval > *conf->variable)
|
|
||||||
{
|
|
||||||
/* Allow change if admin should override */
|
|
||||||
if (check_userlimit_override(record, source))
|
|
||||||
changeVal = changeValOrig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3539,30 +3491,6 @@ set_config_option(const char *name, const char *value,
|
|||||||
newval, name, conf->min, conf->max)));
|
newval, name, conf->min, conf->max)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (record->context == PGC_USERLIMIT)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* handle log_min_duration_statement: if it's enabled
|
|
||||||
* then either turning it off or increasing it
|
|
||||||
* requires privileges.
|
|
||||||
*/
|
|
||||||
if (conf->reset_val != -1 &&
|
|
||||||
(newval == -1 || newval > conf->reset_val))
|
|
||||||
{
|
|
||||||
/* Limit non-superuser changes */
|
|
||||||
if (!check_userlimit_privilege(record, source,
|
|
||||||
elevel))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
/* Admin override includes turning on or decreasing */
|
|
||||||
if (newval != -1 &&
|
|
||||||
(*conf->variable == -1 || newval < *conf->variable))
|
|
||||||
{
|
|
||||||
/* Allow change if admin should override */
|
|
||||||
if (check_userlimit_override(record, source))
|
|
||||||
changeVal = changeValOrig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3647,23 +3575,6 @@ set_config_option(const char *name, const char *value,
|
|||||||
newval, name, conf->min, conf->max)));
|
newval, name, conf->min, conf->max)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (record->context == PGC_USERLIMIT)
|
|
||||||
{
|
|
||||||
/* No REAL PGC_USERLIMIT at present */
|
|
||||||
if (newval < conf->reset_val)
|
|
||||||
{
|
|
||||||
/* Limit non-superuser changes */
|
|
||||||
if (!check_userlimit_privilege(record, source,
|
|
||||||
elevel))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (newval > *conf->variable)
|
|
||||||
{
|
|
||||||
/* Allow change if admin should override */
|
|
||||||
if (check_userlimit_override(record, source))
|
|
||||||
changeVal = changeValOrig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3735,40 +3646,6 @@ set_config_option(const char *name, const char *value,
|
|||||||
newval = guc_strdup(elevel, value);
|
newval = guc_strdup(elevel, value);
|
||||||
if (newval == NULL)
|
if (newval == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (record->context == PGC_USERLIMIT)
|
|
||||||
{
|
|
||||||
int var_value,
|
|
||||||
reset_value,
|
|
||||||
new_value;
|
|
||||||
const char *(*var_hook) (int *var, const char *newval,
|
|
||||||
bool doit, GucSource source);
|
|
||||||
|
|
||||||
if (conf->assign_hook == assign_log_statement)
|
|
||||||
var_hook = assign_log_stmtlvl;
|
|
||||||
else
|
|
||||||
var_hook = assign_msglvl;
|
|
||||||
|
|
||||||
(*var_hook) (&new_value, newval, true, source);
|
|
||||||
(*var_hook) (&reset_value, conf->reset_val, true,
|
|
||||||
source);
|
|
||||||
(*var_hook) (&var_value, *conf->variable, true,
|
|
||||||
source);
|
|
||||||
|
|
||||||
if (new_value > reset_value)
|
|
||||||
{
|
|
||||||
/* Limit non-superuser changes */
|
|
||||||
if (!check_userlimit_privilege(record, source,
|
|
||||||
elevel))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (new_value < var_value)
|
|
||||||
{
|
|
||||||
/* Allow change if admin should override */
|
|
||||||
if (check_userlimit_override(record, source))
|
|
||||||
changeVal = changeValOrig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (conf->reset_val)
|
else if (conf->reset_val)
|
||||||
{
|
{
|
||||||
@ -3888,72 +3765,6 @@ set_config_option(const char *name, const char *value,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Check whether we should allow a USERLIMIT parameter to be set
|
|
||||||
*
|
|
||||||
* This is invoked only when the desired new setting is "less" than the
|
|
||||||
* old and so appropriate privileges are needed. If the setting should
|
|
||||||
* be disallowed, either throw an error (in interactive case) or return false.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
check_userlimit_privilege(struct config_generic *record, GucSource source,
|
|
||||||
int elevel)
|
|
||||||
{
|
|
||||||
/* Allow if trusted source (e.g., config file) */
|
|
||||||
if (source < PGC_S_UNPRIVILEGED)
|
|
||||||
return true;
|
|
||||||
/*
|
|
||||||
* Allow if superuser. We can only check this inside a transaction,
|
|
||||||
* though, so assume not-superuser otherwise. (In practice this means
|
|
||||||
* that settings coming from PGOPTIONS will be treated as non-superuser)
|
|
||||||
*/
|
|
||||||
if (IsTransactionState() && superuser())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
ereport(elevel,
|
|
||||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
|
||||||
errmsg("permission denied to set parameter \"%s\"",
|
|
||||||
record->name),
|
|
||||||
(record->vartype == PGC_BOOL) ?
|
|
||||||
errhint("Must be superuser to change this value to false.")
|
|
||||||
: ((record->vartype == PGC_INT) ?
|
|
||||||
errhint("Must be superuser to increase this value or turn it off.")
|
|
||||||
: errhint("Must be superuser to increase this value."))));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check whether we should allow a USERLIMIT parameter to be overridden
|
|
||||||
*
|
|
||||||
* This is invoked when the desired new setting is "greater" than the
|
|
||||||
* old; if the old setting was unprivileged and the new one is privileged,
|
|
||||||
* we should apply it, even though the normal rule would be not to.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
check_userlimit_override(struct config_generic *record, GucSource source)
|
|
||||||
{
|
|
||||||
/* Unprivileged source never gets to override this way */
|
|
||||||
if (source > PGC_S_UNPRIVILEGED)
|
|
||||||
return false;
|
|
||||||
/* If existing setting is from privileged source, keep it */
|
|
||||||
if (record->source < PGC_S_UNPRIVILEGED)
|
|
||||||
return false;
|
|
||||||
/*
|
|
||||||
* If user is a superuser, he gets to keep his setting. We can't check
|
|
||||||
* this unless inside a transaction, though. XXX in practice that
|
|
||||||
* restriction means this code is essentially worthless, because the
|
|
||||||
* result will depend on whether we happen to be inside a transaction
|
|
||||||
* block when SIGHUP arrives. Dike out until we can think of something
|
|
||||||
* that actually works.
|
|
||||||
*/
|
|
||||||
#ifdef NOT_USED
|
|
||||||
if (IsTransactionState() && superuser())
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
/* Otherwise override */
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set a config option to the given value. See also set_config_option,
|
* Set a config option to the given value. See also set_config_option,
|
||||||
@ -5635,32 +5446,26 @@ assign_log_error_verbosity(const char *newval, bool doit, GucSource source)
|
|||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
assign_log_statement(const char *newval, bool doit, GucSource source)
|
assign_log_statement(const char *newval, bool doit, GucSource source)
|
||||||
{
|
|
||||||
return (assign_log_stmtlvl((int *) &log_statement, newval, doit, source));
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
assign_log_stmtlvl(int *var, const char *newval, bool doit, GucSource source)
|
|
||||||
{
|
{
|
||||||
if (pg_strcasecmp(newval, "none") == 0)
|
if (pg_strcasecmp(newval, "none") == 0)
|
||||||
{
|
{
|
||||||
if (doit)
|
if (doit)
|
||||||
(*var) = LOGSTMT_NONE;
|
log_statement = LOGSTMT_NONE;
|
||||||
}
|
|
||||||
else if (pg_strcasecmp(newval, "mod") == 0)
|
|
||||||
{
|
|
||||||
if (doit)
|
|
||||||
(*var) = LOGSTMT_MOD;
|
|
||||||
}
|
}
|
||||||
else if (pg_strcasecmp(newval, "ddl") == 0)
|
else if (pg_strcasecmp(newval, "ddl") == 0)
|
||||||
{
|
{
|
||||||
if (doit)
|
if (doit)
|
||||||
(*var) = LOGSTMT_DDL;
|
log_statement = LOGSTMT_DDL;
|
||||||
|
}
|
||||||
|
else if (pg_strcasecmp(newval, "mod") == 0)
|
||||||
|
{
|
||||||
|
if (doit)
|
||||||
|
log_statement = LOGSTMT_MOD;
|
||||||
}
|
}
|
||||||
else if (pg_strcasecmp(newval, "all") == 0)
|
else if (pg_strcasecmp(newval, "all") == 0)
|
||||||
{
|
{
|
||||||
if (doit)
|
if (doit)
|
||||||
(*var) = LOGSTMT_ALL;
|
log_statement = LOGSTMT_ALL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return NULL; /* fail */
|
return NULL; /* fail */
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.172 2004/10/22 22:33:58 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.173 2004/11/14 19:35:34 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* some of the information in this file should be moved to other files.
|
* some of the information in this file should be moved to other files.
|
||||||
@ -302,7 +302,7 @@ extern ProcessingMode Mode;
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/* in utils/init/postinit.c */
|
/* in utils/init/postinit.c */
|
||||||
extern void InitPostgres(const char *dbname, const char *username);
|
extern bool InitPostgres(const char *dbname, const char *username);
|
||||||
extern void BaseInit(void);
|
extern void BaseInit(void);
|
||||||
|
|
||||||
/* in utils/init/miscinit.c */
|
/* in utils/init/miscinit.c */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/tcop/tcopprot.h,v 1.71 2004/08/29 05:06:58 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/tcop/tcopprot.h,v 1.72 2004/11/14 19:35:35 tgl Exp $
|
||||||
*
|
*
|
||||||
* OLD COMMENTS
|
* OLD COMMENTS
|
||||||
* This file was created so that other c files could get the two
|
* This file was created so that other c files could get the two
|
||||||
@ -33,11 +33,10 @@ extern int max_stack_depth;
|
|||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
/* Reverse order so GUC USERLIMIT is easier */
|
LOGSTMT_NONE, /* log no statements */
|
||||||
LOGSTMT_ALL, /* log all statements */
|
|
||||||
LOGSTMT_DDL, /* log data definition statements */
|
LOGSTMT_DDL, /* log data definition statements */
|
||||||
LOGSTMT_MOD, /* log modification statements, plus DDL */
|
LOGSTMT_MOD, /* log modification statements, plus DDL */
|
||||||
LOGSTMT_NONE /* log no statements */
|
LOGSTMT_ALL /* log all statements */
|
||||||
} LogStmtLevel;
|
} LogStmtLevel;
|
||||||
|
|
||||||
extern LogStmtLevel log_statement;
|
extern LogStmtLevel log_statement;
|
||||||
@ -63,5 +62,7 @@ extern void authdie(SIGNAL_ARGS);
|
|||||||
extern int PostgresMain(int argc, char *argv[], const char *username);
|
extern int PostgresMain(int argc, char *argv[], const char *username);
|
||||||
extern void ResetUsage(void);
|
extern void ResetUsage(void);
|
||||||
extern void ShowUsage(const char *title);
|
extern void ShowUsage(const char *title);
|
||||||
|
extern void set_debug_options(int debug_flag,
|
||||||
|
GucContext context, GucSource source);
|
||||||
|
|
||||||
#endif /* TCOPPROT_H */
|
#endif /* TCOPPROT_H */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Copyright (c) 2000-2004, PostgreSQL Global Development Group
|
* Copyright (c) 2000-2004, PostgreSQL Global Development Group
|
||||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.55 2004/11/05 19:16:41 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.56 2004/11/14 19:35:35 tgl Exp $
|
||||||
*--------------------------------------------------------------------
|
*--------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#ifndef GUC_H
|
#ifndef GUC_H
|
||||||
@ -48,9 +48,6 @@
|
|||||||
* be set in the connection startup packet, because when it is processed
|
* be set in the connection startup packet, because when it is processed
|
||||||
* we don't yet know if the user is a superuser.
|
* we don't yet know if the user is a superuser.
|
||||||
*
|
*
|
||||||
* USERLIMIT options can only be manipulated in certain ways by
|
|
||||||
* non-superusers.
|
|
||||||
*
|
|
||||||
* USERSET options can be set by anyone any time.
|
* USERSET options can be set by anyone any time.
|
||||||
*/
|
*/
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -60,7 +57,6 @@ typedef enum
|
|||||||
PGC_SIGHUP,
|
PGC_SIGHUP,
|
||||||
PGC_BACKEND,
|
PGC_BACKEND,
|
||||||
PGC_SUSET,
|
PGC_SUSET,
|
||||||
PGC_USERLIMIT,
|
|
||||||
PGC_USERSET
|
PGC_USERSET
|
||||||
} GucContext;
|
} GucContext;
|
||||||
|
|
||||||
@ -74,9 +70,7 @@ typedef enum
|
|||||||
* as the current value. Note that source == PGC_S_OVERRIDE should be
|
* as the current value. Note that source == PGC_S_OVERRIDE should be
|
||||||
* used when setting a PGC_INTERNAL option.
|
* used when setting a PGC_INTERNAL option.
|
||||||
*
|
*
|
||||||
* PGC_S_UNPRIVILEGED isn't actually a source value, but the dividing line
|
* PGC_S_INTERACTIVE isn't actually a source value, but is the
|
||||||
* between privileged and unprivileged sources for USERLIMIT purposes.
|
|
||||||
* Similarly, PGC_S_INTERACTIVE isn't a real source value, but is the
|
|
||||||
* dividing line between "interactive" and "non-interactive" sources for
|
* dividing line between "interactive" and "non-interactive" sources for
|
||||||
* error reporting purposes.
|
* error reporting purposes.
|
||||||
*
|
*
|
||||||
@ -92,7 +86,6 @@ typedef enum
|
|||||||
PGC_S_ENV_VAR, /* postmaster environment variable */
|
PGC_S_ENV_VAR, /* postmaster environment variable */
|
||||||
PGC_S_FILE, /* postgresql.conf */
|
PGC_S_FILE, /* postgresql.conf */
|
||||||
PGC_S_ARGV, /* postmaster command line */
|
PGC_S_ARGV, /* postmaster command line */
|
||||||
PGC_S_UNPRIVILEGED, /* dividing line for USERLIMIT */
|
|
||||||
PGC_S_DATABASE, /* per-database setting */
|
PGC_S_DATABASE, /* per-database setting */
|
||||||
PGC_S_USER, /* per-user setting */
|
PGC_S_USER, /* per-user setting */
|
||||||
PGC_S_CLIENT, /* from client connection request */
|
PGC_S_CLIENT, /* from client connection request */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user