1 --- a/src/bin/pg_ctl/pg_ctl.c
2 +++ b/src/bin/pg_ctl/pg_ctl.c
3 @@ -94,6 +94,7 @@ static char *exec_path = NULL;
4 static char *register_servicename = "PostgreSQL"; /* FIXME: + version ID? */
5 static char *register_username = NULL;
6 static char *register_password = NULL;
7 +static char *username = "";
8 static char *argv0 = NULL;
9 static bool allow_core_files = false;
10 static time_t start_time;
11 @@ -2093,6 +2094,9 @@ do_help(void)
12 printf(_(" -D, --pgdata=DATADIR location of the database storage area\n"));
13 printf(_(" -s, --silent only print errors, no informational messages\n"));
14 printf(_(" -t, --timeout=SECS seconds to wait when using -w option\n"));
15 +#if !defined(WIN32) && !defined(__CYGWIN__)
16 + printf(_(" -U, --username=NAME user name of account PostgreSQL server is running as\n"));
18 printf(_(" -V, --version output version information, then exit\n"));
19 printf(_(" -w wait until operation completes\n"));
20 printf(_(" -W do not wait until operation completes\n"));
21 @@ -2289,6 +2293,7 @@ main(int argc, char **argv)
22 {"pgdata", required_argument, NULL, 'D'},
23 {"silent", no_argument, NULL, 's'},
24 {"timeout", required_argument, NULL, 't'},
25 + {"username", required_argument, NULL, 'U'},
26 {"core-files", no_argument, NULL, 'c'},
29 @@ -2329,20 +2334,6 @@ main(int argc, char **argv)
34 - * Disallow running as root, to forestall any possible security holes.
39 - write_stderr(_("%s: cannot be run as root\n"
40 - "Please log in (using, e.g., \"su\") as the "
41 - "(unprivileged) user that will\n"
42 - "own the server process.\n"),
48 env_wait = getenv("PGCTLTIMEOUT");
50 @@ -2416,11 +2407,15 @@ main(int argc, char **argv)
51 wait_seconds_arg = true;
54 +#if defined(WIN32) || defined(__CYGWIN__)
55 if (strchr(optarg, '\\'))
56 register_username = pg_strdup(optarg);
58 /* Prepend .\ for local accounts */
59 register_username = psprintf(".\\%s", optarg);
61 + username = pg_strdup(optarg);
66 @@ -2502,6 +2497,41 @@ main(int argc, char **argv)
71 + * Disallow running as root, to forestall any possible security holes.
73 +#if !defined(WIN32) && !defined(__CYGWIN__)
77 + if (!username || !strlen(username)) {
79 + _("%s: when run as root, username needs to be provided\n"),
83 + p = getpwnam(username);
86 + _("%s: invalid username: %s\n"),
87 + progname, username);
92 + _("%s: user needs to be non-root\n"),
96 + if (setgid(p->pw_gid) || setuid(p->pw_uid)) {
98 + _("%s: failed to set user id %d: %d (%s)\n"),
99 + progname, p->pw_uid, errno, strerror(errno));
105 /* Note we put any -D switch into the env var above */
106 pg_config = getenv("PGDATA");