29 #if defined(HAVE_SYS_PERSONALITY_H)
30 #include <sys/personality.h>
31 #elif defined(HAVE_SYS_PROCCTL_H)
32 #include <sys/procctl.h>
37 #if defined(WIN32) && !defined(_MSC_VER)
38 extern int _CRT_glob = 0;
54 #define log_error(errcodefn, ...) \
55 ereport(LOG, (errcodefn, errmsg_internal(__VA_ARGS__)))
57 #define log_error(errcodefn, ...) \
58 (fprintf(stderr, __VA_ARGS__), fputc('\n', stderr))
62 #define getcwd(cwd,len) GetCurrentDirectory(len, cwd)
68 static BOOL GetTokenUser(HANDLE hToken, PTOKEN_USER *ppTokenUser);
87 char path_exe[
MAXPGPATH +
sizeof(
".exe") - 1];
90 if (strlen(path) >= strlen(
".exe") &&
91 pg_strcasecmp(path + strlen(path) - strlen(
".exe"),
".exe") != 0)
93 strlcpy(path_exe, path,
sizeof(path_exe) - 4);
94 strcat(path_exe,
".exe");
116 errno =
S_ISDIR(
buf.st_mode) ? EISDIR : EPERM;
125 is_r = (
access(path, R_OK) == 0);
126 is_x = (
access(path, X_OK) == 0);
133 return is_x ? (is_r ? 0 : -2) : -1;
161 _(
"could not identify current directory: %m"));
180 _(
"invalid binary \"%s\": %m"), retpath);
195 if ((path = getenv(
"PATH")) && *path)
209 endp = startp + strlen(startp);
230 _(
"could not read binary \"%s\": %m"),
238 _(
"could not find a \"%s\" to execute"),
argv0);
282 _(
"could not identify current directory: %m"));
295 if (chdir(path) == -1)
298 _(
"could not change directory to \"%s\": %m"), path);
311 rllen =
readlink(fname, link_buf,
sizeof(link_buf));
312 if (rllen < 0 || rllen >=
sizeof(link_buf))
315 _(
"could not read symbolic link \"%s\": %m"), fname);
318 link_buf[rllen] =
'\0';
319 strcpy(path, link_buf);
323 strlcpy(link_buf, fname,
sizeof(link_buf));
328 _(
"could not identify current directory: %m"));
334 if (chdir(orig_wd) == -1)
337 _(
"could not change directory to \"%s\": %m"), orig_wd);
352 const char *versionstr,
char *retpath)
366 "/%s%s", target,
EXE);
371 snprintf(cmd,
sizeof(cmd),
"\"%s\" -V", retpath);
376 if (strcmp(line, versionstr) != 0)
394 if ((pgver = popen(cmd,
"r")) == NULL)
396 perror(
"popen failure");
401 if (fgets(line, maxsize, pgver) == NULL)
404 fprintf(stderr,
"no data was returned by command \"%s\"\n", cmd);
406 perror(
"fgets failure");
427 exitstatus = pclose(stream);
432 if (exitstatus == -1)
436 _(
"%s() failed: %m"),
"pclose");
486 bindtextdomain(app, path);
489 setenv(
"PGLOCALEDIR", path, 0);
492 if (getenv(
"PGSYSCONFDIR") == NULL)
496 setenv(
"PGSYSCONFDIR", path, 0);
510 pg_disable_aslr(
void)
512 #if defined(HAVE_SYS_PERSONALITY_H)
513 return personality(ADDR_NO_RANDOMIZE);
514 #elif defined(HAVE_SYS_PROCCTL_H) && defined(PROC_ASLR_FORCE_DISABLE)
515 int data = PROC_ASLR_FORCE_DISABLE;
517 return procctl(P_PID, 0, PROC_ASLR_CTL, &
data);
553 ACL_SIZE_INFORMATION asi;
554 ACCESS_ALLOWED_ACE *pace;
557 DWORD dwTokenInfoLength = 0;
559 PTOKEN_USER pTokenUser = NULL;
560 TOKEN_DEFAULT_DACL tddNew;
561 TOKEN_DEFAULT_DACL *ptdd = NULL;
562 TOKEN_INFORMATION_CLASS tic = TokenDefaultDacl;
566 if (!GetTokenInformation(hToken, tic, (LPVOID) NULL, dwTokenInfoLength, &dwSize))
568 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
570 ptdd = (TOKEN_DEFAULT_DACL *) LocalAlloc(LPTR, dwSize);
578 if (!GetTokenInformation(hToken, tic, (LPVOID) ptdd, dwSize, &dwSize))
581 "could not get token information: error code %lu",
589 "could not get token information buffer size: error code %lu",
596 if (!GetAclInformation(ptdd->DefaultDacl, (LPVOID) &asi,
597 (DWORD)
sizeof(ACL_SIZE_INFORMATION),
601 "could not get ACL information: error code %lu",
607 if (!GetTokenUser(hToken, &pTokenUser))
611 dwNewAclSize = asi.AclBytesInUse +
sizeof(ACCESS_ALLOWED_ACE) +
612 GetLengthSid(pTokenUser->User.Sid) -
sizeof(DWORD);
615 pacl = (PACL) LocalAlloc(LPTR, dwNewAclSize);
623 if (!InitializeAcl(pacl, dwNewAclSize, ACL_REVISION))
626 "could not initialize ACL: error code %lu", GetLastError());
631 for (
i = 0;
i < (int) asi.AceCount;
i++)
633 if (!GetAce(ptdd->DefaultDacl,
i, (LPVOID *) &pace))
636 "could not get ACE: error code %lu", GetLastError());
640 if (!AddAce(pacl, ACL_REVISION, MAXDWORD, pace, ((PACE_HEADER) pace)->AceSize))
643 "could not add ACE: error code %lu", GetLastError());
649 if (!AddAccessAllowedAceEx(pacl, ACL_REVISION, OBJECT_INHERIT_ACE, GENERIC_ALL, pTokenUser->User.Sid))
652 "could not add access allowed ACE: error code %lu",
658 tddNew.DefaultDacl = pacl;
660 if (!SetTokenInformation(hToken, tic, (LPVOID) &tddNew, dwNewAclSize))
663 "could not set token information: error code %lu",
672 LocalFree((HLOCAL) pTokenUser);
675 LocalFree((HLOCAL) pacl);
678 LocalFree((HLOCAL) ptdd);
692 GetTokenUser(HANDLE hToken, PTOKEN_USER *ppTokenUser)
698 if (!GetTokenInformation(hToken,
704 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
706 *ppTokenUser = (PTOKEN_USER) LocalAlloc(LPTR, dwLength);
708 if (*ppTokenUser == NULL)
718 "could not get token information buffer size: error code %lu",
724 if (!GetTokenInformation(hToken,
730 LocalFree(*ppTokenUser);
734 "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)
int find_other_exec(const char *argv0, const char *target, const char *versionstr, char *retpath)
static int resolve_symlinks(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)
#define is_absolute_path(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)
#define readlink(path, buf, size)