0002-simplify-pqGetpwuid-API.patch
text/x-diff
Filename: 0002-simplify-pqGetpwuid-API.patch
Type: text/x-diff
Part: 1
Patch
Format: unified
Series: patch 0002
| File | + | − |
|---|---|---|
| src/backend/libpq/auth.c | 1 | 0 |
| src/bin/psql/common.c | 1 | 0 |
| src/include/port.h | 3 | 4 |
| src/interfaces/libpq/fe-auth.c | 29 | 25 |
| src/interfaces/libpq/fe-auth.h | 1 | 0 |
| src/interfaces/libpq/fe-connect.c | 10 | 30 |
| src/port/path.c | 1 | 10 |
| src/port/thread.c | 73 | 3 |
| src/tools/msvc/Mkvcbuild.pm | 1 | 1 |
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index b0d6988aff..4d72a6a8c1 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -18,6 +18,7 @@
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <pwd.h>
#include <unistd.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
index f210ccbde8..3503605a7d 100644
--- a/src/bin/psql/common.c
+++ b/src/bin/psql/common.c
@@ -10,6 +10,7 @@
#include <ctype.h>
#include <limits.h>
#include <math.h>
+#include <pwd.h>
#include <signal.h>
#ifndef WIN32
#include <unistd.h> /* for write() */
diff --git a/src/include/port.h b/src/include/port.h
index df81fa97c6..3f1716188b 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -14,7 +14,6 @@
#define PG_PORT_H
#include <ctype.h>
-#include <pwd.h>
/*
* Windows has enough specialized port stuff that we push most of it off
@@ -478,10 +477,10 @@ extern char *dlerror(void);
#define RTLD_GLOBAL 0
#endif
-/* thread.h */
+/* thread.c */
#ifndef WIN32
-extern int pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer,
- size_t buflen, struct passwd **result);
+extern bool pg_get_user_name(uid_t user_id, char *buffer, size_t buflen);
+extern bool pg_get_user_home_dir(uid_t user_id, char *buffer, size_t buflen);
#endif
extern void pg_qsort(void *base, size_t nel, size_t elsize,
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index 8d2e4e5db4..aa4534578a 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -35,7 +35,6 @@
#ifndef MAXHOSTNAMELEN
#include <netdb.h> /* for MAXHOSTNAMELEN on some */
#endif
-#include <pwd.h>
#endif
#include "common/md5.h"
@@ -1091,14 +1090,17 @@ pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn)
/*
- * pg_fe_getauthname
+ * pg_fe_getusername
*
- * Returns a pointer to malloc'd space containing whatever name the user
- * has authenticated to the system. If there is an error, return NULL,
- * and append a suitable error message to *errorMessage if that's not NULL.
+ * Returns a pointer to malloc'd space containing the name of the
+ * specified user_id. If there is an error, return NULL, and append
+ * a suitable error message to *errorMessage if that's not NULL.
+ *
+ * Caution: on Windows, the user_id argument is ignored, and we always
+ * fetch the current user's name.
*/
char *
-pg_fe_getauthname(PQExpBuffer errorMessage)
+pg_fe_getusername(uid_t user_id, PQExpBuffer errorMessage)
{
char *result = NULL;
const char *name = NULL;
@@ -1108,17 +1110,13 @@ pg_fe_getauthname(PQExpBuffer errorMessage)
char username[256 + 1];
DWORD namesize = sizeof(username);
#else
- uid_t user_id = geteuid();
char pwdbuf[BUFSIZ];
- struct passwd pwdstr;
- struct passwd *pw = NULL;
- int pwerr;
#endif
/*
* Some users are using configure --enable-thread-safety-force, so we
* might as well do the locking within our library to protect
- * pqGetpwuid(). In fact, application developers can use getpwuid() in
+ * getpwuid(). In fact, application developers can use getpwuid() in
* their application if they use the locking call we provide, or install
* their own locking function using PQregisterThreadLock().
*/
@@ -1132,21 +1130,10 @@ pg_fe_getauthname(PQExpBuffer errorMessage)
libpq_gettext("user name lookup failure: error code %lu\n"),
GetLastError());
#else
- pwerr = pqGetpwuid(user_id, &pwdstr, pwdbuf, sizeof(pwdbuf), &pw);
- if (pw != NULL)
- name = pw->pw_name;
+ if (pg_get_user_name(user_id, pwdbuf, sizeof(pwdbuf)))
+ name = pwdbuf;
else if (errorMessage)
- {
- if (pwerr != 0)
- appendPQExpBuffer(errorMessage,
- libpq_gettext("could not look up local user ID %d: %s\n"),
- (int) user_id,
- strerror_r(pwerr, pwdbuf, sizeof(pwdbuf)));
- else
- appendPQExpBuffer(errorMessage,
- libpq_gettext("local user with ID %d does not exist\n"),
- (int) user_id);
- }
+ appendPQExpBuffer(errorMessage, "%s\n", pwdbuf);
#endif
if (name)
@@ -1162,6 +1149,23 @@ pg_fe_getauthname(PQExpBuffer errorMessage)
return result;
}
+/*
+ * pg_fe_getauthname
+ *
+ * Returns a pointer to malloc'd space containing whatever name the user
+ * has authenticated to the system. If there is an error, return NULL,
+ * and append a suitable error message to *errorMessage if that's not NULL.
+ */
+char *
+pg_fe_getauthname(PQExpBuffer errorMessage)
+{
+#ifdef WIN32
+ return pg_fe_getusername(0, errorMessage);
+#else
+ return pg_fe_getusername(geteuid(), errorMessage);
+#endif
+}
+
/*
* PQencryptPassword -- exported routine to encrypt a password with MD5
diff --git a/src/interfaces/libpq/fe-auth.h b/src/interfaces/libpq/fe-auth.h
index 16d5e1da0f..f22b3fe648 100644
--- a/src/interfaces/libpq/fe-auth.h
+++ b/src/interfaces/libpq/fe-auth.h
@@ -20,6 +20,7 @@
/* Prototypes for functions in fe-auth.c */
extern int pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn);
+extern char *pg_fe_getusername(uid_t user_id, PQExpBuffer errorMessage);
extern char *pg_fe_getauthname(PQExpBuffer errorMessage);
/* Mechanisms in fe-auth-scram.c */
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index a12e0180fd..5fc16be849 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -2813,10 +2813,7 @@ keep_going: /* We will come back to here until there is
IS_AF_UNIX(conn->raddr.addr.ss_family))
{
#ifndef WIN32
- char pwdbuf[BUFSIZ];
- struct passwd pass_buf;
- struct passwd *pass;
- int passerr;
+ char *remote_username;
#endif
uid_t uid;
gid_t gid;
@@ -2839,28 +2836,20 @@ keep_going: /* We will come back to here until there is
}
#ifndef WIN32
- passerr = pqGetpwuid(uid, &pass_buf, pwdbuf, sizeof(pwdbuf), &pass);
- if (pass == NULL)
- {
- if (passerr != 0)
- appendPQExpBuffer(&conn->errorMessage,
- libpq_gettext("could not look up local user ID %d: %s\n"),
- (int) uid,
- strerror_r(passerr, sebuf, sizeof(sebuf)));
- else
- appendPQExpBuffer(&conn->errorMessage,
- libpq_gettext("local user with ID %d does not exist\n"),
- (int) uid);
- goto error_return;
- }
+ remote_username = pg_fe_getusername(uid,
+ &conn->errorMessage);
+ if (remote_username == NULL)
+ goto error_return; /* message already logged */
- if (strcmp(pass->pw_name, conn->requirepeer) != 0)
+ if (strcmp(remote_username, conn->requirepeer) != 0)
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n"),
- conn->requirepeer, pass->pw_name);
+ conn->requirepeer, remote_username);
+ free(remote_username);
goto error_return;
}
+ free(remote_username);
#else /* WIN32 */
/* should have failed with ENOSYS above */
Assert(false);
@@ -7271,16 +7260,7 @@ pqGetHomeDirectory(char *buf, int bufsize)
home = getenv("HOME");
if (home == NULL || home[0] == '\0')
- {
- char pwdbuf[BUFSIZ];
- struct passwd pwdstr;
- struct passwd *pwd = NULL;
-
- (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd);
- if (pwd == NULL)
- return false;
- home = pwd->pw_dir;
- }
+ return pg_get_user_home_dir(geteuid(), buf, bufsize);
strlcpy(buf, home, bufsize);
return true;
#else
diff --git a/src/port/path.c b/src/port/path.c
index 5ac26f4bcf..69bb8fe40b 100644
--- a/src/port/path.c
+++ b/src/port/path.c
@@ -815,16 +815,7 @@ get_home_path(char *ret_path)
home = getenv("HOME");
if (home == NULL || home[0] == '\0')
- {
- char pwdbuf[BUFSIZ];
- struct passwd pwdstr;
- struct passwd *pwd = NULL;
-
- (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd);
- if (pwd == NULL)
- return false;
- home = pwd->pw_dir;
- }
+ return pg_get_user_home_dir(geteuid(), ret_path, MAXPGPATH);
strlcpy(ret_path, home, MAXPGPATH);
return true;
#else
diff --git a/src/port/thread.c b/src/port/thread.c
index a4c1672c89..e2a570ec40 100644
--- a/src/port/thread.c
+++ b/src/port/thread.c
@@ -49,6 +49,7 @@
* One thread-safe solution for gethostbyname() might be to use getaddrinfo().
*/
+#ifndef WIN32
/*
* Wrapper around getpwuid() or getpwuid_r() to mimic POSIX getpwuid_r()
@@ -60,8 +61,7 @@
* error during lookup: returns an errno code, *result is NULL
* (caller should *not* assume that the errno variable is set)
*/
-#ifndef WIN32
-int
+static int
pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer,
size_t buflen, struct passwd **result)
{
@@ -75,4 +75,74 @@ pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer,
return (*result == NULL) ? errno : 0;
#endif
}
-#endif
+
+/*
+ * 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 = pqGetpwuid(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 = pqGetpwuid(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 */
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index deb62c1c7b..ec3546d0c0 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -106,7 +106,7 @@ sub mkvcbuild
pread.c preadv.c pwrite.c pwritev.c pg_bitutils.c
pg_strong_random.c pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c
pqsignal.c mkdtemp.c qsort.c qsort_arg.c bsearch_arg.c quotes.c system.c
- strerror.c tar.c thread.c
+ strerror.c tar.c
win32env.c win32error.c win32ntdll.c
win32security.c win32setlocale.c win32stat.c);