From df9c435c759fffe77c9c92f70e7c095ffb6556ae Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Thu, 14 Oct 2021 15:20:13 -0700 Subject: [PATCH v1] Prefer getenv("HOME") to find the UNIX home directory According to getpwnam(3): An application that wants to determine its user's home directory should inspect the value of HOME (rather than the value getpwuid(getuid())->pw_dir) since this allows the user to modify their notion of "the home directory" during a login session. Signed-off-by: Anders Kaseorg --- src/bin/psql/command.c | 20 ++++++++++++-------- src/interfaces/libpq/fe-connect.c | 14 ++++++++++---- src/port/path.c | 14 ++++++++++---- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 49d4c0e3ce..cc2fe6ba0e 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -15,6 +15,7 @@ #include /* for stat() */ #include /* for setitimer() */ #include /* open() flags */ +#include /* for getenv() */ #include /* for geteuid(), getpid(), stat() */ #else #include @@ -558,15 +559,18 @@ exec_command_cd(PsqlScanState scan_state, bool active_branch, const char *cmd) uid_t user_id = geteuid(); errno = 0; /* clear errno before call */ - pw = getpwuid(user_id); - if (!pw) - { - pg_log_error("could not get home directory for user ID %ld: %s", - (long) user_id, - errno ? strerror(errno) : _("user does not exist")); - exit(EXIT_FAILURE); + dir = getenv("HOME"); + if (dir == NULL || dir[0] == '\0') { + pw = getpwuid(user_id); + if (!pw) + { + pg_log_error("could not get home directory for user ID %ld: %s", + (long) user_id, + errno ? strerror(errno) : _("user does not exist")); + exit(EXIT_FAILURE); + } + dir = pw->pw_dir; } - dir = pw->pw_dir; #else /* WIN32 */ /* diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index b288d346f9..ebdd815c73 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "common/ip.h" @@ -7242,14 +7243,19 @@ bool pqGetHomeDirectory(char *buf, int bufsize) { #ifndef WIN32 + const char *home; char pwdbuf[BUFSIZ]; struct passwd pwdstr; struct passwd *pwd = NULL; - (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd); - if (pwd == NULL) - return false; - strlcpy(buf, pwd->pw_dir, bufsize); + home = getenv("HOME"); + if (home == NULL || home[0] == '\0') { + (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd); + if (pwd == NULL) + return false; + home = pwd->pw_dir; + } + strlcpy(buf, home, bufsize); return true; #else char tmppath[MAX_PATH]; diff --git a/src/port/path.c b/src/port/path.c index c39d4688cd..607bd16c23 100644 --- a/src/port/path.c +++ b/src/port/path.c @@ -32,6 +32,7 @@ #define near #include #else +#include #include #endif @@ -807,14 +808,19 @@ bool get_home_path(char *ret_path) { #ifndef WIN32 + const char *home; char pwdbuf[BUFSIZ]; struct passwd pwdstr; struct passwd *pwd = NULL; - (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd); - if (pwd == NULL) - return false; - strlcpy(ret_path, pwd->pw_dir, MAXPGPATH); + home = getenv("HOME"); + if (home == NULL || home[0] == '\0') { + (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd); + if (pwd == NULL) + return false; + home = pwd->pw_dir; + } + strlcpy(ret_path, home, MAXPGPATH); return true; #else char *tmppath; -- 2.33.0