Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit e4e89eb

Browse files
committed
Minor GUC code refactoring.
Split out "ConfigOptionIsVisible" to perform the privilege check for GUC_SUPERUSER_ONLY GUCs (which these days can also be read by pg_read_all_settings role members), and move the should-we-show-it checks from GetConfigOptionValues to its sole caller. This commit also removes get_explain_guc_options's check of GUC_NO_SHOW_ALL, which seems to have got cargo-culted in there. While there's no obvious use-case for marking a GUC both GUC_EXPLAIN and GUC_NO_SHOW_ALL, if it were set up that way one would expect EXPLAIN to show it --- if that's not what you want, then don't set GUC_EXPLAIN. In passing, simplify the loop logic in show_all_settings. Nitin Jadhav, Bharath Rupireddy, Tom Lane Discussion: https://postgr.es/m/CAMm1aWYgfekpRK-Jz5=pM_bV+Om=ktGq1vxTZ_dr1Z6MV-qokA@mail.gmail.com
1 parent a1c4cd6 commit e4e89eb

File tree

3 files changed

+40
-46
lines changed

3 files changed

+40
-46
lines changed

src/backend/utils/misc/guc.c

+4-9
Original file line numberDiff line numberDiff line change
@@ -4187,8 +4187,7 @@ GetConfigOption(const char *name, bool missing_ok, bool restrict_privileged)
41874187
if (record == NULL)
41884188
return NULL;
41894189
if (restrict_privileged &&
4190-
(record->flags & GUC_SUPERUSER_ONLY) &&
4191-
!has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS))
4190+
!ConfigOptionIsVisible(record))
41924191
ereport(ERROR,
41934192
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
41944193
errmsg("must be superuser or have privileges of pg_read_all_settings to examine \"%s\"",
@@ -4234,8 +4233,7 @@ GetConfigOptionResetString(const char *name)
42344233

42354234
record = find_option(name, false, false, ERROR);
42364235
Assert(record != NULL);
4237-
if ((record->flags & GUC_SUPERUSER_ONLY) &&
4238-
!has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS))
4236+
if (!ConfigOptionIsVisible(record))
42394237
ereport(ERROR,
42404238
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
42414239
errmsg("must be superuser or have privileges of pg_read_all_settings to examine \"%s\"",
@@ -5160,9 +5158,7 @@ get_explain_guc_options(int *num)
51605158
continue;
51615159

51625160
/* return only options visible to the current user */
5163-
if ((conf->flags & GUC_NO_SHOW_ALL) ||
5164-
((conf->flags & GUC_SUPERUSER_ONLY) &&
5165-
!has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS)))
5161+
if (!ConfigOptionIsVisible(conf))
51665162
continue;
51675163

51685164
/* return only options that are different from their boot values */
@@ -5243,8 +5239,7 @@ GetConfigOptionByName(const char *name, const char **varname, bool missing_ok)
52435239
return NULL;
52445240
}
52455241

5246-
if ((record->flags & GUC_SUPERUSER_ONLY) &&
5247-
!has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS))
5242+
if (!ConfigOptionIsVisible(record))
52485243
ereport(ERROR,
52495244
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
52505245
errmsg("must be superuser or have privileges of pg_read_all_settings to examine \"%s\"",

src/backend/utils/misc/guc_funcs.c

+33-37
Original file line numberDiff line numberDiff line change
@@ -492,9 +492,12 @@ ShowAllGUCConfig(DestReceiver *dest)
492492
struct config_generic *conf = guc_vars[i];
493493
char *setting;
494494

495-
if ((conf->flags & GUC_NO_SHOW_ALL) ||
496-
((conf->flags & GUC_SUPERUSER_ONLY) &&
497-
!has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS)))
495+
/* skip if marked NO_SHOW_ALL */
496+
if (conf->flags & GUC_NO_SHOW_ALL)
497+
continue;
498+
499+
/* return only options visible to the current user */
500+
if (!ConfigOptionIsVisible(conf))
498501
continue;
499502

500503
/* assign to the values array */
@@ -581,25 +584,27 @@ pg_settings_get_flags(PG_FUNCTION_ARGS)
581584
PG_RETURN_ARRAYTYPE_P(a);
582585
}
583586

587+
/*
588+
* Return whether or not the GUC variable is visible to the current user.
589+
*/
590+
bool
591+
ConfigOptionIsVisible(struct config_generic *conf)
592+
{
593+
if ((conf->flags & GUC_SUPERUSER_ONLY) &&
594+
!has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS))
595+
return false;
596+
else
597+
return true;
598+
}
599+
584600
/*
585601
* Extract fields to show in pg_settings for given variable.
586602
*/
587603
static void
588-
GetConfigOptionValues(struct config_generic *conf, const char **values,
589-
bool *noshow)
604+
GetConfigOptionValues(struct config_generic *conf, const char **values)
590605
{
591606
char buffer[256];
592607

593-
if (noshow)
594-
{
595-
if ((conf->flags & GUC_NO_SHOW_ALL) ||
596-
((conf->flags & GUC_SUPERUSER_ONLY) &&
597-
!has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS)))
598-
*noshow = true;
599-
else
600-
*noshow = false;
601-
}
602-
603608
/* first get the generic attributes */
604609

605610
/* name */
@@ -940,30 +945,23 @@ show_all_settings(PG_FUNCTION_ARGS)
940945
max_calls = funcctx->max_calls;
941946
attinmeta = funcctx->attinmeta;
942947

943-
if (call_cntr < max_calls) /* do when there is more left to send */
948+
while (call_cntr < max_calls) /* do when there is more left to send */
944949
{
950+
struct config_generic *conf = guc_vars[call_cntr];
945951
char *values[NUM_PG_SETTINGS_ATTS];
946-
bool noshow;
947952
HeapTuple tuple;
948953
Datum result;
949954

950-
/*
951-
* Get the next visible GUC variable name and value
952-
*/
953-
do
955+
/* skip if marked NO_SHOW_ALL or if not visible to current user */
956+
if ((conf->flags & GUC_NO_SHOW_ALL) ||
957+
!ConfigOptionIsVisible(conf))
954958
{
955-
GetConfigOptionValues(guc_vars[call_cntr], (const char **) values,
956-
&noshow);
957-
if (noshow)
958-
{
959-
/* bump the counter and get the next config setting */
960-
call_cntr = ++funcctx->call_cntr;
959+
call_cntr = ++funcctx->call_cntr;
960+
continue;
961+
}
961962

962-
/* make sure we haven't gone too far now */
963-
if (call_cntr >= max_calls)
964-
SRF_RETURN_DONE(funcctx);
965-
}
966-
} while (noshow);
963+
/* extract values for the current variable */
964+
GetConfigOptionValues(conf, (const char **) values);
967965

968966
/* build a tuple */
969967
tuple = BuildTupleFromCStrings(attinmeta, values);
@@ -973,11 +971,9 @@ show_all_settings(PG_FUNCTION_ARGS)
973971

974972
SRF_RETURN_NEXT(funcctx, result);
975973
}
976-
else
977-
{
978-
/* do when there is no more left */
979-
SRF_RETURN_DONE(funcctx);
980-
}
974+
975+
/* do when there is no more left */
976+
SRF_RETURN_DONE(funcctx);
981977
}
982978

983979
/*

src/include/utils/guc_tables.h

+3
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,9 @@ extern struct config_generic **get_explain_guc_options(int *num);
292292
/* get string value of variable */
293293
extern char *ShowGUCOption(struct config_generic *record, bool use_units);
294294

295+
/* get whether or not the GUC variable is visible to current user */
296+
extern bool ConfigOptionIsVisible(struct config_generic *conf);
297+
295298
/* get the current set of variables */
296299
extern struct config_generic **get_guc_variables(int *num_vars);
297300

0 commit comments

Comments
 (0)