You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

109 lines
3.3 KiB

Index: postgresql-9.5.4/src/bin/pg_ctl/pg_ctl.c
===================================================================
--- postgresql-9.5.4.orig/src/bin/pg_ctl/pg_ctl.c
+++ postgresql-9.5.4/src/bin/pg_ctl/pg_ctl.c
@@ -95,6 +95,7 @@ static char *event_source = NULL;
static char *register_servicename = "PostgreSQL"; /* FIXME: + version ID? */
static char *register_username = NULL;
static char *register_password = NULL;
+static char *username = "";
static char *argv0 = NULL;
static bool allow_core_files = false;
static time_t start_time;
@@ -2114,6 +2115,9 @@ do_help(void)
#endif
printf(_(" -s, --silent only print errors, no informational messages\n"));
printf(_(" -t, --timeout=SECS seconds to wait when using -w option\n"));
+#if !defined(WIN32) && !defined(__CYGWIN__)
+ printf(_(" -U USERNAME user name of account PostgreSQL server is running as\n"));
+#endif
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -w wait until operation completes\n"));
printf(_(" -W do not wait until operation completes\n"));
@@ -2310,6 +2314,7 @@ main(int argc, char **argv)
{"pgdata", required_argument, NULL, 'D'},
{"silent", no_argument, NULL, 's'},
{"timeout", required_argument, NULL, 't'},
+ {"username", required_argument, NULL, 'U'},
{"core-files", no_argument, NULL, 'c'},
{NULL, 0, NULL, 0}
};
@@ -2350,20 +2355,6 @@ main(int argc, char **argv)
}
}
- /*
- * Disallow running as root, to forestall any possible security holes.
- */
-#ifndef WIN32
- if (geteuid() == 0)
- {
- write_stderr(_("%s: cannot be run as root\n"
- "Please log in (using, e.g., \"su\") as the "
- "(unprivileged) user that will\n"
- "own the server process.\n"),
- progname);
- exit(1);
- }
-#endif
env_wait = getenv("PGCTLTIMEOUT");
if (env_wait != NULL)
@@ -2449,11 +2440,15 @@ main(int argc, char **argv)
wait_seconds_arg = true;
break;
case 'U':
+#if defined(WIN32) || defined(__CYGWIN__)
if (strchr(optarg, '\\'))
register_username = pg_strdup(optarg);
else
/* Prepend .\ for local accounts */
register_username = psprintf(".\\%s", optarg);
+#else
+ username = pg_strdup(optarg);
+#endif
break;
case 'w':
do_wait = true;
@@ -2535,6 +2530,41 @@ main(int argc, char **argv)
exit(1);
}
+ /*
+ * Disallow running as root, to forestall any possible security holes.
+ */
+#if !defined(WIN32) && !defined(__CYGWIN__)
+ if (geteuid() == 0)
+ {
+ struct passwd *p;
+ if (!username || !strlen(username)) {
+ fprintf(stderr,
+ _("%s: when run as root, username needs to be provided\n"),
+ progname);
+ exit(1);
+ }
+ p = getpwnam(username);
+ if (!p) {
+ fprintf(stderr,
+ _("%s: invalid username: %s\n"),
+ progname, username);
+ exit(1);
+ }
+ if (!p->pw_uid) {
+ fprintf(stderr,
+ _("%s: user needs to be non-root\n"),
+ progname);
+ exit(1);
+ }
+ if (setgid(p->pw_gid) || setuid(p->pw_uid)) {
+ fprintf(stderr,
+ _("%s: failed to set user id %d: %d (%s)\n"),
+ progname, p->pw_uid, errno, strerror(errno));
+ exit(1);
+ }
+ }
+#endif
+
/* Note we put any -D switch into the env var above */
pg_config = getenv("PGDATA");
if (pg_config)