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>
46 #if defined(WIN32) && !defined(_MSC_VER)
47 extern int _CRT_glob = 0;
63 #define log_error(errcodefn, ...) \
64 ereport(LOG, (errcodefn, errmsg_internal(__VA_ARGS__)))
66 #define log_error(errcodefn, ...) \
67 (fprintf(stderr, __VA_ARGS__), fputc('\n', stderr))
74 static BOOL GetTokenUser(HANDLE hToken, PTOKEN_USER *ppTokenUser);
93 char path_exe[
MAXPGPATH +
sizeof(
".exe") - 1];
96 if (strlen(path) < strlen(
".exe") ||
97 pg_strcasecmp(path + strlen(path) - strlen(
".exe"),
".exe") != 0)
99 strlcpy(path_exe, path,
sizeof(path_exe) - 4);
100 strcat(path_exe,
".exe");
122 errno =
S_ISDIR(
buf.st_mode) ? EISDIR : EPERM;
131 is_r = (
access(path, R_OK) == 0);
132 is_x = (
access(path, X_OK) == 0);
139 return is_x ? (is_r ? 0 : -2) : -1;
172 _(
"invalid binary \"%s\": %m"), retpath);
186 if ((path = getenv(
"PATH")) && *path)
200 endp = startp + strlen(startp);
215 _(
"could not read binary \"%s\": %m"),
223 _(
"could not find a \"%s\" to execute"),
argv0);
250 _(
"could not resolve path \"%s\" to absolute form: %m"),
285 path = realpath(fname, NULL);
286 if (path == NULL && errno == EINVAL)
296 path = realpath(fname,
buf);
299 int save_errno = errno;
315 path = _fullpath(NULL, fname, 0);
328 const char *versionstr,
char *retpath)
342 "/%s%s", target,
EXE);
347 snprintf(cmd,
sizeof(cmd),
"\"%s\" -V", retpath);
352 if (strcmp(line, versionstr) != 0)
370 if ((pgver = popen(cmd,
"r")) == NULL)
372 perror(
"popen failure");
377 if (fgets(line, maxsize, pgver) == NULL)
380 fprintf(stderr,
"no data was returned by command \"%s\"\n", cmd);
382 perror(
"fgets failure");
403 exitstatus = pclose(stream);
408 if (exitstatus == -1)
412 _(
"%s() failed: %m"),
"pclose");
462 bindtextdomain(app, path);
465 setenv(
"PGLOCALEDIR", path, 0);
468 if (getenv(
"PGSYSCONFDIR") == NULL)
472 setenv(
"PGSYSCONFDIR", path, 0);
486 pg_disable_aslr(
void)
488 #if defined(HAVE_SYS_PERSONALITY_H)
489 return personality(ADDR_NO_RANDOMIZE);
490 #elif defined(HAVE_SYS_PROCCTL_H) && defined(PROC_ASLR_FORCE_DISABLE)
491 int data = PROC_ASLR_FORCE_DISABLE;
493 return procctl(P_PID, 0, PROC_ASLR_CTL, &
data);
529 ACL_SIZE_INFORMATION asi;
530 ACCESS_ALLOWED_ACE *pace;
533 DWORD dwTokenInfoLength = 0;
535 PTOKEN_USER pTokenUser = NULL;
536 TOKEN_DEFAULT_DACL tddNew;
537 TOKEN_DEFAULT_DACL *ptdd = NULL;
538 TOKEN_INFORMATION_CLASS tic = TokenDefaultDacl;
542 if (!GetTokenInformation(hToken, tic, (LPVOID) NULL, dwTokenInfoLength, &dwSize))
544 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
546 ptdd = (TOKEN_DEFAULT_DACL *) LocalAlloc(LPTR, dwSize);
554 if (!GetTokenInformation(hToken, tic, (LPVOID) ptdd, dwSize, &dwSize))
557 "could not get token information: error code %lu",
565 "could not get token information buffer size: error code %lu",
572 if (!GetAclInformation(ptdd->DefaultDacl, (LPVOID) &asi,
573 (DWORD)
sizeof(ACL_SIZE_INFORMATION),
577 "could not get ACL information: error code %lu",
583 if (!GetTokenUser(hToken, &pTokenUser))
587 dwNewAclSize = asi.AclBytesInUse +
sizeof(ACCESS_ALLOWED_ACE) +
588 GetLengthSid(pTokenUser->User.Sid) -
sizeof(DWORD);
591 pacl = (PACL) LocalAlloc(LPTR, dwNewAclSize);
599 if (!InitializeAcl(pacl, dwNewAclSize, ACL_REVISION))
602 "could not initialize ACL: error code %lu", GetLastError());
607 for (
i = 0;
i < (int) asi.AceCount;
i++)
609 if (!GetAce(ptdd->DefaultDacl,
i, (LPVOID *) &pace))
612 "could not get ACE: error code %lu", GetLastError());
616 if (!AddAce(pacl, ACL_REVISION, MAXDWORD, pace, ((PACE_HEADER) pace)->AceSize))
619 "could not add ACE: error code %lu", GetLastError());
625 if (!AddAccessAllowedAceEx(pacl, ACL_REVISION, OBJECT_INHERIT_ACE, GENERIC_ALL, pTokenUser->User.Sid))
628 "could not add access allowed ACE: error code %lu",
634 tddNew.DefaultDacl = pacl;
636 if (!SetTokenInformation(hToken, tic, (LPVOID) &tddNew, dwNewAclSize))
639 "could not set token information: error code %lu",
648 LocalFree((HLOCAL) pTokenUser);
651 LocalFree((HLOCAL) pacl);
654 LocalFree((HLOCAL) ptdd);
668 GetTokenUser(HANDLE hToken, PTOKEN_USER *ppTokenUser)
674 if (!GetTokenInformation(hToken,
680 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
682 *ppTokenUser = (PTOKEN_USER) LocalAlloc(LPTR, dwLength);
684 if (*ppTokenUser == NULL)
694 "could not get token information buffer size: error code %lu",
700 if (!GetTokenInformation(hToken,
706 LocalFree(*ppTokenUser);
710 "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, char *line, int maxsize)
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)
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)
char * first_dir_separator(const char *filename)
int pg_strcasecmp(const char *s1, const char *s2)
void canonicalize_path(char *path)
void get_etc_path(const char *my_exec_path, char *ret_path)
char * first_path_var_separator(const char *pathlist)
size_t strlcpy(char *dst, const char *src, size_t siz)
char * wait_result_to_str(int exitstatus)
BOOL AddUserToTokenDacl(HANDLE hToken)