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

Commit 7d1a0f5

Browse files
committed
Allow "-C variable" and "--describe-config" even to root users.
There's no really compelling reason to refuse to do these read-only, non-server-starting options as root, and there's at least one good reason to allow -C: pg_ctl uses -C to find out the true data directory location when pointed at a config-only directory. On Windows, this is done before dropping administrator privileges, which means that pg_ctl fails for administrators if and only if a config-only layout is used. Since the root-privilege check is done so early in startup, it's a bit awkward to check for these switches. Make the somewhat arbitrary decision that we'll only skip the root check if -C is the first switch. This is not just to make the code a bit simpler: it also guarantees that we can't misinterpret a --boot mode switch. (While AuxiliaryProcessMain doesn't currently recognize any such switch, it might have one in the future.) This is no particular problem for pg_ctl, and since the whole behavior is undocumented anyhow, it's not a documentation issue either. (--describe-config only works as the first switch anyway, so this is no restriction for that case either.) Back-patch to 9.2 where pg_ctl first began to use -C. MauMau, heavily edited by me
1 parent 598f303 commit 7d1a0f5

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

src/backend/main/main.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ static char *get_current_username(const char *progname);
5959
int
6060
main(int argc, char *argv[])
6161
{
62+
bool do_check_root = true;
63+
6264
progname = get_progname(argv[0]);
6365

6466
/*
@@ -153,7 +155,8 @@ main(int argc, char *argv[])
153155
unsetenv("LC_ALL");
154156

155157
/*
156-
* Catch standard options before doing much else
158+
* Catch standard options before doing much else, in particular before we
159+
* insist on not being root.
157160
*/
158161
if (argc > 1)
159162
{
@@ -167,12 +170,29 @@ main(int argc, char *argv[])
167170
puts("postgres (PostgreSQL) " PG_VERSION);
168171
exit(0);
169172
}
173+
174+
/*
175+
* In addition to the above, we allow "--describe-config" and "-C var"
176+
* to be called by root. This is reasonably safe since these are
177+
* read-only activities. The -C case is important because pg_ctl may
178+
* try to invoke it while still holding administrator privileges on
179+
* Windows. Note that while -C can normally be in any argv position,
180+
* if you wanna bypass the root check you gotta put it first. This
181+
* reduces the risk that we might misinterpret some other mode's -C
182+
* switch as being the postmaster/postgres one.
183+
*/
184+
if (strcmp(argv[1], "--describe-config") == 0)
185+
do_check_root = false;
186+
else if (argc > 2 && strcmp(argv[1], "-C") == 0)
187+
do_check_root = false;
170188
}
171189

172190
/*
173-
* Make sure we are not running as root.
191+
* Make sure we are not running as root, unless it's safe for the selected
192+
* option.
174193
*/
175-
check_root(progname);
194+
if (do_check_root)
195+
check_root(progname);
176196

177197
/*
178198
* Dispatch to one of various subprograms depending on first argument.

src/bin/pg_ctl/pg_ctl.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,9 +1962,11 @@ adjust_data_dir(void)
19621962
else
19631963
my_exec_path = pg_strdup(exec_path);
19641964

1965-
snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" %s%s -C data_directory" SYSTEMQUOTE,
1966-
my_exec_path, pgdata_opt ? pgdata_opt : "", post_opts ?
1967-
post_opts : "");
1965+
/* it's important for -C to be the first option, see main.c */
1966+
snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" -C data_directory %s%s" SYSTEMQUOTE,
1967+
my_exec_path,
1968+
pgdata_opt ? pgdata_opt : "",
1969+
post_opts ? post_opts : "");
19681970

19691971
fd = popen(cmd, "r");
19701972
if (fd == NULL || fgets(filename, sizeof(filename), fd) == NULL)

0 commit comments

Comments
 (0)