diff options
| author | Peter Eisentraut | 2024-09-02 06:16:25 +0000 |
|---|---|---|
| committer | Peter Eisentraut | 2024-09-02 07:04:30 +0000 |
| commit | 4d5111b3f1a151faf8129e38f8424898588e606d (patch) | |
| tree | 6c2e3c4291f4249b25954690b69d6b8c644d6ee6 /src/port | |
| parent | 23138284cde438f65f093156e76683d63b826fff (diff) | |
More use of getpwuid_r() directly
Remove src/port/user.c, call getpwuid_r() directly. This reduces some
complexity and allows better control of the error behavior. For
example, the old code would in some circumstances silently truncate
the result string, or produce error message strings that the caller
wouldn't use.
src/port/user.c used to be called src/port/thread.c and contained
various portability complications to support thread-safety. These are
all obsolete, and all but the user-lookup functions have already been
removed. This patch completes this by also removing the user-lookup
functions.
Also convert src/backend/libpq/auth.c to use getpwuid_r() for
thread-safety.
Originally, I tried to be overly correct by using
sysconf(_SC_GETPW_R_SIZE_MAX) to get the buffer size for getpwuid_r(),
but that doesn't work on FreeBSD. All the OS where I could find the
source code internally use 1024 as the suggested buffer size, so I
just ended up hardcoding that. The previous code used BUFSIZ, which
is an unrelated constant from stdio.h, so its use seemed
inappropriate.
Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
Discussion: https://www.postgresql.org/message-id/flat/5f293da9-ceb4-4937-8e52-82c25db8e4d3%40eisentraut.org
Diffstat (limited to 'src/port')
| -rw-r--r-- | src/port/Makefile | 3 | ||||
| -rw-r--r-- | src/port/meson.build | 1 | ||||
| -rw-r--r-- | src/port/path.c | 23 | ||||
| -rw-r--r-- | src/port/user.c | 89 |
4 files changed, 20 insertions, 96 deletions
diff --git a/src/port/Makefile b/src/port/Makefile index db7c02117b0..9324ec2d9fc 100644 --- a/src/port/Makefile +++ b/src/port/Makefile @@ -57,8 +57,7 @@ OBJS = \ quotes.o \ snprintf.o \ strerror.o \ - tar.o \ - user.o + tar.o # libpgport.a, libpgport_shlib.a, and libpgport_srv.a contain the same files # foo.o, foo_shlib.o, and foo_srv.o are all built from foo.c diff --git a/src/port/meson.build b/src/port/meson.build index ff54b7b53e9..1150966ab71 100644 --- a/src/port/meson.build +++ b/src/port/meson.build @@ -20,7 +20,6 @@ pgport_sources = [ 'snprintf.c', 'strerror.c', 'tar.c', - 'user.c', ] if host_system == 'windows' diff --git a/src/port/path.c b/src/port/path.c index 330b3f90332..de4df6cd78b 100644 --- a/src/port/path.c +++ b/src/port/path.c @@ -32,6 +32,7 @@ #define near #include <shlobj.h> #else +#include <pwd.h> #include <unistd.h> #endif @@ -934,10 +935,24 @@ get_home_path(char *ret_path) const char *home; home = getenv("HOME"); - if (home == NULL || home[0] == '\0') - return pg_get_user_home_dir(geteuid(), ret_path, MAXPGPATH); - strlcpy(ret_path, home, MAXPGPATH); - return true; + if (home && home[0]) + { + strlcpy(ret_path, home, MAXPGPATH); + return true; + } + else + { + struct passwd pwbuf; + struct passwd *pw; + char buf[1024]; + int rc; + + rc = getpwuid_r(geteuid(), &pwbuf, buf, sizeof buf, &pw); + if (rc != 0 || !pw) + return false; + strlcpy(ret_path, pw->pw_dir, MAXPGPATH); + return true; + } #else char *tmppath; diff --git a/src/port/user.c b/src/port/user.c deleted file mode 100644 index 7444aeb64b2..00000000000 --- a/src/port/user.c +++ /dev/null @@ -1,89 +0,0 @@ -/*------------------------------------------------------------------------- - * - * user.c - * - * Wrapper functions for user and home directory lookup. - * - * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group - * - * src/port/user.c - * - *------------------------------------------------------------------------- - */ - -#include "c.h" - -#include <pwd.h> - -#ifndef WIN32 - -/* - * pg_get_user_name - get the name of the user with the given ID - * - * On success, the user name is returned into the buffer (of size buflen), - * and "true" is returned. On failure, a localized error message is - * returned into the buffer, and "false" is returned. - */ -bool -pg_get_user_name(uid_t user_id, char *buffer, size_t buflen) -{ - char pwdbuf[BUFSIZ]; - struct passwd pwdstr; - struct passwd *pw = NULL; - int pwerr; - - pwerr = getpwuid_r(user_id, &pwdstr, pwdbuf, sizeof(pwdbuf), &pw); - if (pw != NULL) - { - strlcpy(buffer, pw->pw_name, buflen); - return true; - } - if (pwerr != 0) - snprintf(buffer, buflen, - _("could not look up local user ID %d: %s"), - (int) user_id, - strerror_r(pwerr, pwdbuf, sizeof(pwdbuf))); - else - snprintf(buffer, buflen, - _("local user with ID %d does not exist"), - (int) user_id); - return false; -} - -/* - * pg_get_user_home_dir - get the home directory of the user with the given ID - * - * On success, the directory path is returned into the buffer (of size buflen), - * and "true" is returned. On failure, a localized error message is - * returned into the buffer, and "false" is returned. - * - * Note that this does not incorporate the common behavior of checking - * $HOME first, since it's independent of which user_id is queried. - */ -bool -pg_get_user_home_dir(uid_t user_id, char *buffer, size_t buflen) -{ - char pwdbuf[BUFSIZ]; - struct passwd pwdstr; - struct passwd *pw = NULL; - int pwerr; - - pwerr = getpwuid_r(user_id, &pwdstr, pwdbuf, sizeof(pwdbuf), &pw); - if (pw != NULL) - { - strlcpy(buffer, pw->pw_dir, buflen); - return true; - } - if (pwerr != 0) - snprintf(buffer, buflen, - _("could not look up local user ID %d: %s"), - (int) user_id, - strerror_r(pwerr, pwdbuf, sizeof(pwdbuf))); - else - snprintf(buffer, buflen, - _("local user with ID %d does not exist"), - (int) user_id); - return false; -} - -#endif /* !WIN32 */ |
