24#define _DARWIN_BETTER_REALPATH
38#if defined(HAVE_SYS_PERSONALITY_H)
39#include <sys/personality.h>
40#elif defined(HAVE_SYS_PROCCTL_H)
41#include <sys/procctl.h>
48#if defined(WIN32) && !defined(_MSC_VER)
49extern int _CRT_glob = 0;
65#define log_error(errcodefn, ...) \
66 ereport(LOG, (errcodefn, errmsg_internal(__VA_ARGS__)))
68#define log_error(errcodefn, ...) \
69 (fprintf(stderr, __VA_ARGS__), fputc('\n', stderr))
76static BOOL GetTokenUser(HANDLE hToken, PTOKEN_USER *ppTokenUser);
95 char path_exe[
MAXPGPATH +
sizeof(
".exe") - 1];
98 if (strlen(path) < strlen(
".exe") ||
99 pg_strcasecmp(path + strlen(path) - strlen(
".exe"),
".exe") != 0)
101 strlcpy(path_exe, path,
sizeof(path_exe) - 4);
102 strcat(path_exe,
".exe");
124 errno =
S_ISDIR(
buf.st_mode) ? EISDIR : EPERM;
133 is_r = (
access(path, R_OK) == 0);
134 is_x = (
access(path, X_OK) == 0);
141 return is_x ? (is_r ? 0 : -2) : -1;
174 _(
"invalid binary \"%s\": %m"), retpath);
188 if ((path = getenv(
"PATH")) && *path)
202 endp = startp + strlen(startp);
217 _(
"could not read binary \"%s\": %m"),
225 _(
"could not find a \"%s\" to execute"),
argv0);
252 _(
"could not resolve path \"%s\" to absolute form: %m"),
287 path = realpath(fname, NULL);
298 path = _fullpath(NULL, fname, 0);
311 const char *versionstr,
char *retpath)
325 "/%s%s", target,
EXE);
330 snprintf(cmd,
sizeof(cmd),
"\"%s\" -V", retpath);
335 if (strcmp(line, versionstr) != 0)
360 if ((pipe_cmd = popen(cmd,
"r")) == NULL)
363 _(
"could not execute command \"%s\": %m"), cmd);
373 if (ferror(pipe_cmd))
375 _(
"could not read from command \"%s\": %m"), cmd);
378 _(
"no data was returned by command \"%s\""), cmd);
396 exitstatus = pclose(stream);
401 if (exitstatus == -1)
405 _(
"%s() failed: %m"),
"pclose");
455 bindtextdomain(app, path);
458 setenv(
"PGLOCALEDIR", path, 0);
461 if (getenv(
"PGSYSCONFDIR") == NULL)
465 setenv(
"PGSYSCONFDIR", path, 0);
481#if defined(HAVE_SYS_PERSONALITY_H)
482 return personality(ADDR_NO_RANDOMIZE);
483#elif defined(HAVE_SYS_PROCCTL_H) && defined(PROC_ASLR_FORCE_DISABLE)
484 int data = PROC_ASLR_FORCE_DISABLE;
486 return procctl(P_PID, 0, PROC_ASLR_CTL, &
data);
522 ACL_SIZE_INFORMATION asi;
523 ACCESS_ALLOWED_ACE *pace;
526 DWORD dwTokenInfoLength = 0;
528 PTOKEN_USER pTokenUser = NULL;
529 TOKEN_DEFAULT_DACL tddNew;
530 TOKEN_DEFAULT_DACL *ptdd = NULL;
531 TOKEN_INFORMATION_CLASS tic = TokenDefaultDacl;
535 if (!GetTokenInformation(hToken, tic, (LPVOID) NULL, dwTokenInfoLength, &dwSize))
537 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
539 ptdd = (TOKEN_DEFAULT_DACL *) LocalAlloc(LPTR, dwSize);
547 if (!GetTokenInformation(hToken, tic, (LPVOID) ptdd, dwSize, &dwSize))
550 "could not get token information: error code %lu",
558 "could not get token information buffer size: error code %lu",
565 if (!GetAclInformation(ptdd->DefaultDacl, (LPVOID) &asi,
566 (DWORD)
sizeof(ACL_SIZE_INFORMATION),
570 "could not get ACL information: error code %lu",
576 if (!GetTokenUser(hToken, &pTokenUser))
580 dwNewAclSize = asi.AclBytesInUse +
sizeof(ACCESS_ALLOWED_ACE) +
581 GetLengthSid(pTokenUser->User.Sid) -
sizeof(DWORD);
584 pacl = (PACL) LocalAlloc(LPTR, dwNewAclSize);
592 if (!InitializeAcl(pacl, dwNewAclSize, ACL_REVISION))
595 "could not initialize ACL: error code %lu", GetLastError());
600 for (
i = 0;
i < (int) asi.AceCount;
i++)
602 if (!GetAce(ptdd->DefaultDacl,
i, (LPVOID *) &pace))
605 "could not get ACE: error code %lu", GetLastError());
609 if (!AddAce(pacl, ACL_REVISION, MAXDWORD, pace, ((PACE_HEADER) pace)->AceSize))
612 "could not add ACE: error code %lu", GetLastError());
618 if (!AddAccessAllowedAceEx(pacl, ACL_REVISION, OBJECT_INHERIT_ACE, GENERIC_ALL, pTokenUser->User.Sid))
621 "could not add access allowed ACE: error code %lu",
627 tddNew.DefaultDacl = pacl;
629 if (!SetTokenInformation(hToken, tic, (LPVOID) &tddNew, dwNewAclSize))
632 "could not set token information: error code %lu",
641 LocalFree((HLOCAL) pTokenUser);
644 LocalFree((HLOCAL) pacl);
647 LocalFree((HLOCAL) ptdd);
661GetTokenUser(HANDLE hToken, PTOKEN_USER *ppTokenUser)
667 if (!GetTokenInformation(hToken,
673 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
675 *ppTokenUser = (PTOKEN_USER) LocalAlloc(LPTR, dwLength);
677 if (*ppTokenUser == NULL)
687 "could not get token information buffer size: error code %lu",
693 if (!GetTokenInformation(hToken,
699 LocalFree(*ppTokenUser);
703 "could not get token information: error code %lu",
static void cleanup(void)
#define PG_TEXTDOMAIN(domain)
int find_my_exec(const char *argv0, char *retpath)
#define log_error(errcodefn,...)
int validate_exec(const char *path)
char * pipe_read_line(char *cmd)
int pclose_check(FILE *stream)
void set_pglocale_pgservice(const char *argv0, const char *app)
static char * pg_realpath(const char *fname)
int find_other_exec(const char *argv0, const char *target, const char *versionstr, char *retpath)
static int normalize_exec_path(char *path)
int errcode_for_file_access(void)
int errcode(int sqlerrcode)
char my_exec_path[MAXPGPATH]
static void const char fflush(stdout)
void pfree(void *pointer)
char * pg_get_line(FILE *stream, PromptInterruptContext *prompt_ctx)
void get_locale_path(const char *my_exec_path, char *ret_path)
void join_path_components(char *ret_path, const char *head, const char *tail)
char * last_dir_separator(const char *filename)
int pg_strcasecmp(const char *s1, const char *s2)
char * first_path_var_separator(const char *pathlist)
void canonicalize_path(char *path)
void get_etc_path(const char *my_exec_path, char *ret_path)
char * first_dir_separator(const char *filename)
size_t strlcpy(char *dst, const char *src, size_t siz)
char * wait_result_to_str(int exitstatus)
BOOL AddUserToTokenDacl(HANDLE hToken)