diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c index 329cc24..4462749 100644 --- a/src/bin/pg_ctl/pg_ctl.c +++ b/src/bin/pg_ctl/pg_ctl.c @@ -1961,10 +1961,16 @@ main(int argc, char **argv) int c; pgpid_t killproc = 0; +#ifdef WIN32 + char *restrict_env; +#endif + #if defined(WIN32) || defined(__CYGWIN__) setvbuf(stderr, NULL, _IONBF, 0); #endif + + progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_ctl")); start_time = time(NULL); @@ -2182,6 +2188,49 @@ main(int argc, char **argv) canonicalize_path(pg_config); pg_data = xstrdup(pg_config); } +#ifdef WIN32 + + /* + * Before we execute another program, make sure that we are running with a + * restricted token. If not, re-execute ourselves with one. + */ + + if ((restrict_env = getenv("PG_RESTRICT_EXEC")) == NULL + || strcmp(restrict_env, "1") != 0) + { + PROCESS_INFORMATION pi; + char *cmdline; + + ZeroMemory(&pi, sizeof(pi)); + + cmdline = xstrdup(GetCommandLine()); + + putenv("PG_RESTRICT_EXEC=1"); + + if (!CreateRestrictedProcess(cmdline, &pi, false)) + { + write_stderr(_("%s: could not re-exec with restricted token: error code %lu\n"), progname, GetLastError()); + } + else + { + /* + * Successfully re-execed. Now wait for child process to capture + * exitcode. + */ + DWORD x; + + CloseHandle(pi.hThread); + WaitForSingleObject(pi.hProcess, INFINITE); + + if (!GetExitCodeProcess(pi.hProcess, &x)) + { + write_stderr(_("%s: could not get exit code from subprocess: error code %lu\n"), progname, GetLastError()); + exit(1); + } + exit(x); + } + } +#endif adjust_data_dir();