10
10
* Written by Peter Eisentraut <peter_e@gmx.net>.
11
11
*
12
12
* IDENTIFICATION
13
- * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.236 2004/08/31 04:53:44 tgl Exp $
13
+ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.237 2004/08/31 19:28:51 tgl Exp $
14
14
*
15
15
*--------------------------------------------------------------------
16
16
*/
@@ -1848,6 +1848,10 @@ static int guc_name_compare(const char *namea, const char *nameb);
1848
1848
static void push_old_value (struct config_generic * gconf );
1849
1849
static void ReportGUCOption (struct config_generic * record );
1850
1850
static char * _ShowOption (struct config_generic * record );
1851
+ static bool check_userlimit_privilege (struct config_generic * record ,
1852
+ GucSource source , int elevel );
1853
+ static bool check_userlimit_override (struct config_generic * record ,
1854
+ GucSource source );
1851
1855
1852
1856
1853
1857
/*
@@ -2034,7 +2038,7 @@ static bool
2034
2038
is_custom_class (const char * name , int dotPos )
2035
2039
{
2036
2040
/*
2037
- * The assign_custom_variable_classes has made sure no empty
2041
+ * assign_custom_variable_classes() has made sure no empty
2038
2042
* identifiers or whitespace exists in the variable
2039
2043
*/
2040
2044
bool result = false;
@@ -3233,22 +3237,14 @@ set_config_option(const char *name, const char *value,
3233
3237
if (newval < conf -> reset_val )
3234
3238
{
3235
3239
/* Limit non-superuser changes */
3236
- if (source > PGC_S_UNPRIVILEGED && !superuser ())
3237
- {
3238
- ereport (elevel ,
3239
- (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
3240
- errmsg ("permission denied to set parameter \"%s\"" ,
3241
- name ),
3242
- errhint ("must be superuser to change this value to false" )));
3240
+ if (!check_userlimit_privilege (record , source ,
3241
+ elevel ))
3243
3242
return false;
3244
- }
3245
3243
}
3246
3244
if (newval > * conf -> variable )
3247
3245
{
3248
3246
/* Allow change if admin should override */
3249
- if (source < PGC_S_UNPRIVILEGED &&
3250
- record -> source > PGC_S_UNPRIVILEGED &&
3251
- !superuser ())
3247
+ if (check_userlimit_override (record , source ))
3252
3248
changeVal = changeValOrig ;
3253
3249
}
3254
3250
}
@@ -3338,30 +3334,25 @@ set_config_option(const char *name, const char *value,
3338
3334
}
3339
3335
if (record -> context == PGC_USERLIMIT )
3340
3336
{
3341
- /* handle log_min_duration_statement, -1=disable */
3342
- if ((newval != -1 && conf -> reset_val != -1 &&
3343
- newval > conf -> reset_val ) || /* increase duration */
3344
- (newval == -1 && conf -> reset_val != -1 )) /* turn off */
3337
+ /*
3338
+ * handle log_min_duration_statement: if it's enabled
3339
+ * then either turning it off or increasing it
3340
+ * requires privileges.
3341
+ */
3342
+ if (conf -> reset_val != -1 &&
3343
+ (newval == -1 || newval > conf -> reset_val ))
3345
3344
{
3346
3345
/* Limit non-superuser changes */
3347
- if (source > PGC_S_UNPRIVILEGED && !superuser ())
3348
- {
3349
- ereport (elevel ,
3350
- (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
3351
- errmsg ("permission denied to set parameter \"%s\"" ,
3352
- name ),
3353
- errhint ("Must be superuser to increase this value or turn it off." )));
3346
+ if (!check_userlimit_privilege (record , source ,
3347
+ elevel ))
3354
3348
return false;
3355
- }
3356
3349
}
3357
- /* Allow change if admin should override */
3358
- if ((newval != -1 && * conf -> variable != -1 &&
3359
- newval < * conf -> variable ) || /* decrease duration */
3360
- (newval != -1 && * conf -> variable == -1 )) /* turn on */
3350
+ /* Admin override includes turning on or decreasing */
3351
+ if (newval != -1 &&
3352
+ (* conf -> variable == -1 || newval < * conf -> variable ))
3361
3353
{
3362
- if (source < PGC_S_UNPRIVILEGED &&
3363
- record -> source > PGC_S_UNPRIVILEGED &&
3364
- !superuser ())
3354
+ /* Allow change if admin should override */
3355
+ if (check_userlimit_override (record , source ))
3365
3356
changeVal = changeValOrig ;
3366
3357
}
3367
3358
}
@@ -3450,23 +3441,21 @@ set_config_option(const char *name, const char *value,
3450
3441
return false;
3451
3442
}
3452
3443
if (record -> context == PGC_USERLIMIT )
3453
- /* No REAL PGC_USERLIMIT */
3454
3444
{
3455
- /* Limit non-superuser changes */
3456
- if (source > PGC_S_UNPRIVILEGED && ! superuser () )
3445
+ /* No REAL PGC_USERLIMIT at present */
3446
+ if (newval < conf -> reset_val )
3457
3447
{
3458
- ereport (elevel ,
3459
- (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
3460
- errmsg ("permission denied to set parameter \"%s\"" ,
3461
- name ),
3462
- errhint ("Must be superuser to increase this value or turn it off." )));
3463
- return false;
3448
+ /* Limit non-superuser changes */
3449
+ if (!check_userlimit_privilege (record , source ,
3450
+ elevel ))
3451
+ return false;
3452
+ }
3453
+ if (newval > * conf -> variable )
3454
+ {
3455
+ /* Allow change if admin should override */
3456
+ if (check_userlimit_override (record , source ))
3457
+ changeVal = changeValOrig ;
3464
3458
}
3465
- /* Allow change if admin should override */
3466
- if (source < PGC_S_UNPRIVILEGED &&
3467
- record -> source > PGC_S_UNPRIVILEGED &&
3468
- !superuser ())
3469
- changeVal = false;
3470
3459
}
3471
3460
}
3472
3461
else
@@ -3559,27 +3548,17 @@ set_config_option(const char *name, const char *value,
3559
3548
(* var_hook ) (& var_value , * conf -> variable , true,
3560
3549
source );
3561
3550
3562
- /* Limit non-superuser changes */
3563
3551
if (new_value > reset_value )
3564
3552
{
3565
3553
/* Limit non-superuser changes */
3566
- if (source > PGC_S_UNPRIVILEGED && !superuser ())
3567
- {
3568
- ereport (elevel ,
3569
- (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
3570
- errmsg ("permission denied to set parameter \"%s\"" ,
3571
- name ),
3572
- errhint ("Must be superuser to increase this value." )));
3554
+ if (!check_userlimit_privilege (record , source ,
3555
+ elevel ))
3573
3556
return false;
3574
- }
3575
3557
}
3576
-
3577
- /* Allow change if admin should override */
3578
3558
if (new_value < var_value )
3579
3559
{
3580
- if (source < PGC_S_UNPRIVILEGED &&
3581
- record -> source > PGC_S_UNPRIVILEGED &&
3582
- !superuser ())
3560
+ /* Allow change if admin should override */
3561
+ if (check_userlimit_override (record , source ))
3583
3562
changeVal = changeValOrig ;
3584
3563
}
3585
3564
}
@@ -3702,6 +3681,71 @@ set_config_option(const char *name, const char *value,
3702
3681
return true;
3703
3682
}
3704
3683
3684
+ /*
3685
+ * Check whether we should allow a USERLIMIT parameter to be set
3686
+ *
3687
+ * This is invoked only when the desired new setting is "less" than the
3688
+ * old and so appropriate privileges are needed. If the setting should
3689
+ * be disallowed, either throw an error (in interactive case) or return false.
3690
+ */
3691
+ static bool
3692
+ check_userlimit_privilege (struct config_generic * record , GucSource source ,
3693
+ int elevel )
3694
+ {
3695
+ /* Allow if trusted source (e.g., config file) */
3696
+ if (source < PGC_S_UNPRIVILEGED )
3697
+ return true;
3698
+ /*
3699
+ * Allow if superuser. We can only check this inside a transaction,
3700
+ * though, so assume not-superuser otherwise. (In practice this means
3701
+ * that settings coming from PGOPTIONS will be treated as non-superuser)
3702
+ */
3703
+ if (IsTransactionState () && superuser ())
3704
+ return true;
3705
+
3706
+ ereport (elevel ,
3707
+ (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
3708
+ errmsg ("permission denied to set parameter \"%s\"" ,
3709
+ record -> name ),
3710
+ (record -> vartype == PGC_BOOL ) ?
3711
+ errhint ("Must be superuser to change this value to false." )
3712
+ : ((record -> vartype == PGC_INT ) ?
3713
+ errhint ("Must be superuser to increase this value or turn it off." )
3714
+ : errhint ("Must be superuser to increase this value." ))));
3715
+ return false;
3716
+ }
3717
+
3718
+ /*
3719
+ * Check whether we should allow a USERLIMIT parameter to be overridden
3720
+ *
3721
+ * This is invoked when the desired new setting is "greater" than the
3722
+ * old; if the old setting was unprivileged and the new one is privileged,
3723
+ * we should apply it, even though the normal rule would be not to.
3724
+ */
3725
+ static bool
3726
+ check_userlimit_override (struct config_generic * record , GucSource source )
3727
+ {
3728
+ /* Unprivileged source never gets to override this way */
3729
+ if (source > PGC_S_UNPRIVILEGED )
3730
+ return false;
3731
+ /* If existing setting is from privileged source, keep it */
3732
+ if (record -> source < PGC_S_UNPRIVILEGED )
3733
+ return false;
3734
+ /*
3735
+ * If user is a superuser, he gets to keep his setting. We can't check
3736
+ * this unless inside a transaction, though. XXX in practice that
3737
+ * restriction means this code is essentially worthless, because the
3738
+ * result will depend on whether we happen to be inside a transaction
3739
+ * block when SIGHUP arrives. Dike out until we can think of something
3740
+ * that actually works.
3741
+ */
3742
+ #ifdef NOT_USED
3743
+ if (IsTransactionState () && superuser ())
3744
+ return false;
3745
+ #endif
3746
+ /* Otherwise override */
3747
+ return true;
3748
+ }
3705
3749
3706
3750
3707
3751
/*
@@ -5450,22 +5494,19 @@ assign_custom_variable_classes(const char *newval, bool doit, GucSource source)
5450
5494
* Syntax error due to token following space after token or
5451
5495
* non alpha numeric character
5452
5496
*/
5453
- pfree (buf .data );
5454
- ereport (WARNING ,
5497
+ ereport (LOG ,
5455
5498
(errcode (ERRCODE_SYNTAX_ERROR ),
5456
- errmsg ("illegal syntax for custom_variable_classes \"%s\"" , newval )));
5499
+ errmsg ("invalid syntax for custom_variable_classes: \"%s\"" , newval )));
5500
+ pfree (buf .data );
5457
5501
return NULL ;
5458
5502
}
5459
5503
symLen ++ ;
5460
5504
appendStringInfoChar (& buf , (char ) c );
5461
5505
}
5462
5506
5507
+ /* Remove stray ',' at end */
5463
5508
if (symLen == 0 && buf .len > 0 )
5464
-
5465
- /*
5466
- * Remove stray ',' at end
5467
- */
5468
- buf .data [-- buf .len ] = 0 ;
5509
+ buf .data [-- buf .len ] = '\0' ;
5469
5510
5470
5511
if (buf .len == 0 )
5471
5512
newval = NULL ;
@@ -5479,39 +5520,32 @@ assign_custom_variable_classes(const char *newval, bool doit, GucSource source)
5479
5520
static bool
5480
5521
assign_stage_log_stats (bool newval , bool doit , GucSource source )
5481
5522
{
5482
- if (newval )
5523
+ if (newval && log_statement_stats )
5483
5524
{
5484
- if (log_statement_stats )
5485
- {
5486
- if (doit )
5487
- ereport (ERROR ,
5488
- (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
5489
- errmsg ("cannot enable parameter when \"log_statement_stats\" is true." )));
5490
- else
5491
- return false;
5492
- }
5493
- return true;
5525
+ if (source >= PGC_S_INTERACTIVE )
5526
+ ereport (ERROR ,
5527
+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
5528
+ errmsg ("cannot enable parameter when \"log_statement_stats\" is true" )));
5529
+ else
5530
+ return false;
5494
5531
}
5495
5532
return true;
5496
5533
}
5497
5534
5498
-
5499
5535
static bool
5500
5536
assign_log_stats (bool newval , bool doit , GucSource source )
5501
5537
{
5502
- if (newval )
5538
+ if (newval &&
5539
+ (log_parser_stats || log_planner_stats || log_executor_stats ))
5503
5540
{
5504
- if (log_parser_stats || log_planner_stats || log_executor_stats )
5505
- {
5506
- if (doit )
5507
- ereport (ERROR ,
5508
- (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
5509
- errmsg ("cannot enable \"log_statement_stats\" when \"log_parser_stats\",\n"
5510
- "\"log_planner_stats\", or \"log_executor_stats\" is true." )));
5511
- else
5512
- return false;
5513
- }
5514
- return true;
5541
+ if (source >= PGC_S_INTERACTIVE )
5542
+ ereport (ERROR ,
5543
+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
5544
+ errmsg ("cannot enable \"log_statement_stats\" when "
5545
+ "\"log_parser_stats\", \"log_planner_stats\", "
5546
+ "or \"log_executor_stats\" is true" )));
5547
+ else
5548
+ return false;
5515
5549
}
5516
5550
return true;
5517
5551
}
@@ -5534,7 +5568,6 @@ assign_transaction_read_only(bool newval, bool doit, GucSource source)
5534
5568
static const char *
5535
5569
assign_canonical_path (const char * newval , bool doit , GucSource source )
5536
5570
{
5537
-
5538
5571
if (doit )
5539
5572
{
5540
5573
/* We have to create a new pointer to force the change */
0 commit comments