int
main(int argc, char *argv[])
{
+ bool do_check_root = true;
+
progname = get_progname(argv[0]);
/*
unsetenv("LC_ALL");
/*
- * Catch standard options before doing much else
+ * Catch standard options before doing much else, in particular before we
+ * insist on not being root.
*/
if (argc > 1)
{
puts("postgres (PostgreSQL) " PG_VERSION);
exit(0);
}
+
+ /*
+ * In addition to the above, we allow "--describe-config" and "-C var"
+ * to be called by root. This is reasonably safe since these are
+ * read-only activities. The -C case is important because pg_ctl may
+ * try to invoke it while still holding administrator privileges on
+ * Windows. Note that while -C can normally be in any argv position,
+ * if you wanna bypass the root check you gotta put it first. This
+ * reduces the risk that we might misinterpret some other mode's -C
+ * switch as being the postmaster/postgres one.
+ */
+ if (strcmp(argv[1], "--describe-config") == 0)
+ do_check_root = false;
+ else if (argc > 2 && strcmp(argv[1], "-C") == 0)
+ do_check_root = false;
}
/*
- * Make sure we are not running as root.
+ * Make sure we are not running as root, unless it's safe for the selected
+ * option.
*/
- check_root(progname);
+ if (do_check_root)
+ check_root(progname);
/*
* Dispatch to one of various subprograms depending on first argument.
else
my_exec_path = pg_strdup(exec_path);
- snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" %s%s -C data_directory" SYSTEMQUOTE,
- my_exec_path, pgdata_opt ? pgdata_opt : "", post_opts ?
- post_opts : "");
+ /* it's important for -C to be the first option, see main.c */
+ snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" -C data_directory %s%s" SYSTEMQUOTE,
+ my_exec_path,
+ pgdata_opt ? pgdata_opt : "",
+ post_opts ? post_opts : "");
fd = popen(cmd, "r");
if (fd == NULL || fgets(filename, sizeof(filename), fd) == NULL)