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

Lines changed: 4 additions & 9 deletions
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

Lines changed: 33 additions & 37 deletions
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

Lines changed: 3 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy