Commit a12fc7da authored by Bruce Momjian's avatar Bruce Momjian

Improve handling of GUC USERLIMIT variables by reorganizing code. Also,

handle new postgresql.conf values with SIGHUP better by better enforcing
USERLIMIT settings on existing non-super-user backends.
parent 53ddde5b
...@@ -10,7 +10,7 @@ ...@@ -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.195 2004/04/01 21:28:45 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.196 2004/04/05 02:48:09 momjian Exp $
* *
*-------------------------------------------------------------------- *--------------------------------------------------------------------
*/ */
...@@ -2571,8 +2571,7 @@ set_config_option(const char *name, const char *value, ...@@ -2571,8 +2571,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;
bool changeVal_orig;
if (context == PGC_SIGHUP || source == PGC_S_DEFAULT) if (context == PGC_SIGHUP || source == PGC_S_DEFAULT)
elevel = DEBUG2; elevel = DEBUG2;
...@@ -2694,7 +2693,6 @@ set_config_option(const char *name, const char *value, ...@@ -2694,7 +2693,6 @@ set_config_option(const char *name, const char *value,
* to set the reset/session values even if we can't set the variable * to set the reset/session values even if we can't set the variable
* itself. * itself.
*/ */
changeVal_orig = changeVal; /* we might have to reverse this later */
if (record->source > source) if (record->source > source)
{ {
if (changeVal && !makeDefault) if (changeVal && !makeDefault)
...@@ -2703,11 +2701,15 @@ set_config_option(const char *name, const char *value, ...@@ -2703,11 +2701,15 @@ set_config_option(const char *name, const char *value,
name); name);
return true; return true;
} }
changeVal = false; /* we won't change the variable itself */ changeVal = false; /* this might be reset in USERLIMIT */
} }
/* /*
* Evaluate value and set variable * Evaluate value and set variable.
* USERLIMIT checks two things: 1) 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)
{ {
...@@ -2726,26 +2728,30 @@ set_config_option(const char *name, const char *value, ...@@ -2726,26 +2728,30 @@ set_config_option(const char *name, const char *value,
name))); name)));
return false; return false;
} }
/* Limit non-superuser changes */
if (record->context == PGC_USERLIMIT && if (record->context == PGC_USERLIMIT &&
source > PGC_S_UNPRIVILEGED && IsUnderPostmaster && !superuser())
newval < conf->reset_val &&
!superuser())
{ {
ereport(elevel, if (newval < conf->reset_val)
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), {
errmsg("permission denied to set parameter \"%s\"", /* Limit non-superuser changes */
name), if (source > PGC_S_UNPRIVILEGED)
errhint("Must be superuser to change this value to false."))); {
return false; ereport(elevel,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied to set parameter \"%s\"",
name),
errhint("Must be superuser to change this value to false.")));
return false;
}
}
if (newval > *conf->variable)
{
/* Allow change if admin should override */
if (source < PGC_S_UNPRIVILEGED &&
record->source > PGC_S_UNPRIVILEGED)
changeVal = changeValOrig;
}
} }
/* Honor change to config file with SIGHUP */
if (record->context == PGC_USERLIMIT &&
source < PGC_S_UNPRIVILEGED &&
record->reset_source > PGC_S_UNPRIVILEGED &&
newval > conf->reset_val &&
!superuser())
changeVal = changeVal_orig;
} }
else else
{ {
...@@ -2822,27 +2828,35 @@ set_config_option(const char *name, const char *value, ...@@ -2822,27 +2828,35 @@ 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;
} }
/* Limit non-superuser changes */
if (record->context == PGC_USERLIMIT && if (record->context == PGC_USERLIMIT &&
source > PGC_S_UNPRIVILEGED && IsUnderPostmaster && !superuser())
conf->reset_val != 0 &&
(newval > conf->reset_val || newval == 0) &&
!superuser())
{ {
ereport(elevel, /* handle log_min_duration_statement, -1=disable */
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), if ((newval != -1 && conf->reset_val != -1 &&
errmsg("permission denied to set parameter \"%s\"", newval > conf->reset_val) || /* increase duration */
name), (newval == -1 && conf->reset_val != -1)) /* turn off */
errhint("Must be superuser to increase this value or set it to zero."))); {
return false; /* Limit non-superuser changes */
if (source > PGC_S_UNPRIVILEGED)
{
ereport(elevel,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied to set parameter \"%s\"",
name),
errhint("Must be superuser to increase this value or turn it off.")));
return false;
}
}
/* Allow change if admin should override */
if ((newval != -1 && *conf->variable != -1 &&
newval < *conf->variable) || /* decrease duration */
(newval != -1 && *conf->variable == -1)) /* turn on */
{
if (source < PGC_S_UNPRIVILEGED &&
record->source > PGC_S_UNPRIVILEGED)
changeVal = changeValOrig;
}
} }
/* Honor change to config file with SIGHUP */
if (record->context == PGC_USERLIMIT &&
source < PGC_S_UNPRIVILEGED &&
record->reset_source > PGC_S_UNPRIVILEGED &&
newval < conf->reset_val && newval != 0 &&
!superuser())
changeVal = changeVal_orig;
} }
else else
{ {
...@@ -2919,26 +2933,25 @@ set_config_option(const char *name, const char *value, ...@@ -2919,26 +2933,25 @@ 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;
} }
/* Limit non-superuser changes */
if (record->context == PGC_USERLIMIT && if (record->context == PGC_USERLIMIT &&
source > PGC_S_UNPRIVILEGED && IsUnderPostmaster && !superuser())
newval > conf->reset_val && /* No REAL PGC_USERLIMIT */
!superuser())
{ {
ereport(elevel, /* Limit non-superuser changes */
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), if (source > PGC_S_UNPRIVILEGED)
errmsg("permission denied to set parameter \"%s\"", {
name), ereport(elevel,
errhint("Must be superuser to increase this value."))); (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
return false; errmsg("permission denied to set parameter \"%s\"",
name),
errhint("Must be superuser to increase this value or turn it off.")));
return false;
}
/* Allow change if admin should override */
if (source < PGC_S_UNPRIVILEGED &&
record->source > PGC_S_UNPRIVILEGED)
changeVal = false;
} }
/* Honor change to config file with SIGHUP */
if (record->context == PGC_USERLIMIT &&
source < PGC_S_UNPRIVILEGED &&
record->reset_source > PGC_S_UNPRIVILEGED &&
newval < conf->reset_val &&
!superuser())
changeVal = changeVal_orig;
} }
else else
{ {
...@@ -3009,34 +3022,38 @@ set_config_option(const char *name, const char *value, ...@@ -3009,34 +3022,38 @@ set_config_option(const char *name, const char *value,
} }
if (record->context == PGC_USERLIMIT && if (record->context == PGC_USERLIMIT &&
*conf->variable) IsUnderPostmaster && !superuser())
{ {
int old_int_value, int old_int_value,
new_int_value; new_int_value;
/* all USERLIMIT strings are message levels */ /* all USERLIMIT strings are message levels */
assign_msglvl(&old_int_value, conf->reset_val,
true, source);
assign_msglvl(&new_int_value, newval, assign_msglvl(&new_int_value, newval,
true, source); true, source);
/* Limit non-superuser changes */ assign_msglvl(&old_int_value, conf->reset_val,
if (source > PGC_S_UNPRIVILEGED && true, source);
new_int_value > old_int_value && if (new_int_value > old_int_value)
!superuser())
{ {
ereport(elevel, /* Limit non-superuser changes */
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), if (source > PGC_S_UNPRIVILEGED)
{
ereport(elevel,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied to set parameter \"%s\"", errmsg("permission denied to set parameter \"%s\"",
name), name),
errhint("Must be superuser to increase this value."))); errhint("Must be superuser to increase this value.")));
return false; return false;
}
}
/* Allow change if admin should override */
assign_msglvl(&old_int_value, *conf->variable,
true, source);
if (new_int_value < old_int_value)
{
if (source < PGC_S_UNPRIVILEGED &&
record->source > PGC_S_UNPRIVILEGED)
changeVal = changeValOrig;
} }
/* Honor change to config file with SIGHUP */
if (source < PGC_S_UNPRIVILEGED &&
record->reset_source > PGC_S_UNPRIVILEGED &&
newval < conf->reset_val &&
!superuser())
changeVal = changeVal_orig;
} }
} }
else if (conf->reset_val) else if (conf->reset_val)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment