Merge pull request #11353 from kvuorine/fwknop-fixes
[feed/packages.git] / libs / postgresql / patches / 900-pg_ctl-setuid.patch
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 *event_source = 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 @@ -2055,6 +2056,9 @@ do_help(void)
12 #endif
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"));
17 +#endif
18 printf(_(" -V, --version output version information, then exit\n"));
19 printf(_(" -w, --wait wait until operation completes (default)\n"));
20 printf(_(" -W, --no-wait do not wait until operation completes\n"));
21 @@ -2267,6 +2271,7 @@ main(int argc, char **argv)
22 {"options", required_argument, NULL, 'o'},
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'},
27 {"wait", no_argument, NULL, 'w'},
28 {"no-wait", no_argument, NULL, 'W'},
29 @@ -2307,20 +2312,6 @@ main(int argc, char **argv)
30 }
31 }
32
33 - /*
34 - * Disallow running as root, to forestall any possible security holes.
35 - */
36 -#ifndef WIN32
37 - if (geteuid() == 0)
38 - {
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"),
43 - progname);
44 - exit(1);
45 - }
46 -#endif
47
48 env_wait = getenv("PGCTLTIMEOUT");
49 if (env_wait != NULL)
50 @@ -2407,11 +2398,15 @@ main(int argc, char **argv)
51 wait_seconds_arg = true;
52 break;
53 case 'U':
54 +#if defined(WIN32) || defined(__CYGWIN__)
55 if (strchr(optarg, '\\'))
56 register_username = pg_strdup(optarg);
57 else
58 /* Prepend .\ for local accounts */
59 register_username = psprintf(".\\%s", optarg);
60 +#else
61 + username = pg_strdup(optarg);
62 +#endif
63 break;
64 case 'w':
65 do_wait = true;
66 @@ -2493,6 +2488,41 @@ main(int argc, char **argv)
67 exit(1);
68 }
69
70 + /*
71 + * Disallow running as root, to forestall any possible security holes.
72 + */
73 +#if !defined(WIN32) && !defined(__CYGWIN__)
74 + if (geteuid() == 0)
75 + {
76 + struct passwd *p;
77 + if (!username || !strlen(username)) {
78 + fprintf(stderr,
79 + _("%s: when run as root, username needs to be provided\n"),
80 + progname);
81 + exit(1);
82 + }
83 + p = getpwnam(username);
84 + if (!p) {
85 + fprintf(stderr,
86 + _("%s: invalid username: %s\n"),
87 + progname, username);
88 + exit(1);
89 + }
90 + if (!p->pw_uid) {
91 + fprintf(stderr,
92 + _("%s: user needs to be non-root\n"),
93 + progname);
94 + exit(1);
95 + }
96 + if (setgid(p->pw_gid) || setuid(p->pw_uid)) {
97 + fprintf(stderr,
98 + _("%s: failed to set user id %d: %d (%s)\n"),
99 + progname, p->pw_uid, errno, strerror(errno));
100 + exit(1);
101 + }
102 + }
103 +#endif
104 +
105 /* Note we put any -D switch into the env var above */
106 pg_config = getenv("PGDATA");
107 if (pg_config)