Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 98e93a1

Browse files
committed
Clean up messy API for src/port/thread.c.
The point of this patch is to reduce inclusion spam by not needing to #include <netdb.h> or <pwd.h> in port.h (which is read by every compile in our tree). To do that, we must remove port.h's declarations of pqGetpwuid and pqGethostbyname. pqGethostbyname is only used, and is only ever likely to be used, in src/port/getaddrinfo.c --- which isn't even built on most platforms, making pqGethostbyname dead code for most people. Hence, deal with that by just moving it into getaddrinfo.c. To clean up pqGetpwuid, invent a couple of simple wrapper functions with less-messy APIs. This allows removing some duplicate error-handling code, too. In passing, remove thread.c from the MSVC build, since it contains nothing we use on Windows. Noted while working on 376ce3e. Discussion: https://postgr.es/m/1634252654444.90107@mit.edu
1 parent 7fa945b commit 98e93a1

File tree

11 files changed

+158
-110
lines changed

11 files changed

+158
-110
lines changed

src/backend/libpq/auth.c

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <sys/param.h>
1919
#include <sys/socket.h>
2020
#include <netinet/in.h>
21+
#include <pwd.h>
2122
#include <unistd.h>
2223
#ifdef HAVE_SYS_SELECT_H
2324
#include <sys/select.h>

src/bin/psql/common.c

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <ctype.h>
1111
#include <limits.h>
1212
#include <math.h>
13+
#include <pwd.h>
1314
#include <signal.h>
1415
#ifndef WIN32
1516
#include <unistd.h> /* for write() */

src/include/port.h

+3-11
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
#define PG_PORT_H
1515

1616
#include <ctype.h>
17-
#include <netdb.h>
18-
#include <pwd.h>
1917

2018
/*
2119
* Windows has enough specialized port stuff that we push most of it off
@@ -484,18 +482,12 @@ extern char *dlerror(void);
484482
#define RTLD_GLOBAL 0
485483
#endif
486484

487-
/* thread.h */
485+
/* thread.c */
488486
#ifndef WIN32
489-
extern int pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer,
490-
size_t buflen, struct passwd **result);
487+
extern bool pg_get_user_name(uid_t user_id, char *buffer, size_t buflen);
488+
extern bool pg_get_user_home_dir(uid_t user_id, char *buffer, size_t buflen);
491489
#endif
492490

493-
extern int pqGethostbyname(const char *name,
494-
struct hostent *resultbuf,
495-
char *buffer, size_t buflen,
496-
struct hostent **result,
497-
int *herrno);
498-
499491
extern void pg_qsort(void *base, size_t nel, size_t elsize,
500492
int (*cmp) (const void *, const void *));
501493
extern int pg_qsort_strcmp(const void *a, const void *b);

src/interfaces/libpq/fe-auth.c

+29-25
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
#ifndef MAXHOSTNAMELEN
3636
#include <netdb.h> /* for MAXHOSTNAMELEN on some */
3737
#endif
38-
#include <pwd.h>
3938
#endif
4039

4140
#include "common/md5.h"
@@ -1099,14 +1098,17 @@ pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn)
10991098

11001099

11011100
/*
1102-
* pg_fe_getauthname
1101+
* pg_fe_getusername
11031102
*
1104-
* Returns a pointer to malloc'd space containing whatever name the user
1105-
* has authenticated to the system. If there is an error, return NULL,
1106-
* and append a suitable error message to *errorMessage if that's not NULL.
1103+
* Returns a pointer to malloc'd space containing the name of the
1104+
* specified user_id. If there is an error, return NULL, and append
1105+
* a suitable error message to *errorMessage if that's not NULL.
1106+
*
1107+
* Caution: on Windows, the user_id argument is ignored, and we always
1108+
* fetch the current user's name.
11071109
*/
11081110
char *
1109-
pg_fe_getauthname(PQExpBuffer errorMessage)
1111+
pg_fe_getusername(uid_t user_id, PQExpBuffer errorMessage)
11101112
{
11111113
char *result = NULL;
11121114
const char *name = NULL;
@@ -1116,17 +1118,13 @@ pg_fe_getauthname(PQExpBuffer errorMessage)
11161118
char username[256 + 1];
11171119
DWORD namesize = sizeof(username);
11181120
#else
1119-
uid_t user_id = geteuid();
11201121
char pwdbuf[BUFSIZ];
1121-
struct passwd pwdstr;
1122-
struct passwd *pw = NULL;
1123-
int pwerr;
11241122
#endif
11251123

11261124
/*
11271125
* Some users are using configure --enable-thread-safety-force, so we
11281126
* might as well do the locking within our library to protect
1129-
* pqGetpwuid(). In fact, application developers can use getpwuid() in
1127+
* getpwuid(). In fact, application developers can use getpwuid() in
11301128
* their application if they use the locking call we provide, or install
11311129
* their own locking function using PQregisterThreadLock().
11321130
*/
@@ -1140,21 +1138,10 @@ pg_fe_getauthname(PQExpBuffer errorMessage)
11401138
libpq_gettext("user name lookup failure: error code %lu\n"),
11411139
GetLastError());
11421140
#else
1143-
pwerr = pqGetpwuid(user_id, &pwdstr, pwdbuf, sizeof(pwdbuf), &pw);
1144-
if (pw != NULL)
1145-
name = pw->pw_name;
1141+
if (pg_get_user_name(user_id, pwdbuf, sizeof(pwdbuf)))
1142+
name = pwdbuf;
11461143
else if (errorMessage)
1147-
{
1148-
if (pwerr != 0)
1149-
appendPQExpBuffer(errorMessage,
1150-
libpq_gettext("could not look up local user ID %d: %s\n"),
1151-
(int) user_id,
1152-
strerror_r(pwerr, pwdbuf, sizeof(pwdbuf)));
1153-
else
1154-
appendPQExpBuffer(errorMessage,
1155-
libpq_gettext("local user with ID %d does not exist\n"),
1156-
(int) user_id);
1157-
}
1144+
appendPQExpBuffer(errorMessage, "%s\n", pwdbuf);
11581145
#endif
11591146

11601147
if (name)
@@ -1170,6 +1157,23 @@ pg_fe_getauthname(PQExpBuffer errorMessage)
11701157
return result;
11711158
}
11721159

1160+
/*
1161+
* pg_fe_getauthname
1162+
*
1163+
* Returns a pointer to malloc'd space containing whatever name the user
1164+
* has authenticated to the system. If there is an error, return NULL,
1165+
* and append a suitable error message to *errorMessage if that's not NULL.
1166+
*/
1167+
char *
1168+
pg_fe_getauthname(PQExpBuffer errorMessage)
1169+
{
1170+
#ifdef WIN32
1171+
return pg_fe_getusername(0, errorMessage);
1172+
#else
1173+
return pg_fe_getusername(geteuid(), errorMessage);
1174+
#endif
1175+
}
1176+
11731177

11741178
/*
11751179
* PQencryptPassword -- exported routine to encrypt a password with MD5

src/interfaces/libpq/fe-auth.h

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
/* Prototypes for functions in fe-auth.c */
2222
extern int pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn);
23+
extern char *pg_fe_getusername(uid_t user_id, PQExpBuffer errorMessage);
2324
extern char *pg_fe_getauthname(PQExpBuffer errorMessage);
2425

2526
/* Mechanisms in fe-auth-scram.c */

src/interfaces/libpq/fe-connect.c

+10-30
Original file line numberDiff line numberDiff line change
@@ -2813,10 +2813,7 @@ PQconnectPoll(PGconn *conn)
28132813
IS_AF_UNIX(conn->raddr.addr.ss_family))
28142814
{
28152815
#ifndef WIN32
2816-
char pwdbuf[BUFSIZ];
2817-
struct passwd pass_buf;
2818-
struct passwd *pass;
2819-
int passerr;
2816+
char *remote_username;
28202817
#endif
28212818
uid_t uid;
28222819
gid_t gid;
@@ -2839,28 +2836,20 @@ PQconnectPoll(PGconn *conn)
28392836
}
28402837

28412838
#ifndef WIN32
2842-
passerr = pqGetpwuid(uid, &pass_buf, pwdbuf, sizeof(pwdbuf), &pass);
2843-
if (pass == NULL)
2844-
{
2845-
if (passerr != 0)
2846-
appendPQExpBuffer(&conn->errorMessage,
2847-
libpq_gettext("could not look up local user ID %d: %s\n"),
2848-
(int) uid,
2849-
strerror_r(passerr, sebuf, sizeof(sebuf)));
2850-
else
2851-
appendPQExpBuffer(&conn->errorMessage,
2852-
libpq_gettext("local user with ID %d does not exist\n"),
2853-
(int) uid);
2854-
goto error_return;
2855-
}
2839+
remote_username = pg_fe_getusername(uid,
2840+
&conn->errorMessage);
2841+
if (remote_username == NULL)
2842+
goto error_return; /* message already logged */
28562843

2857-
if (strcmp(pass->pw_name, conn->requirepeer) != 0)
2844+
if (strcmp(remote_username, conn->requirepeer) != 0)
28582845
{
28592846
appendPQExpBuffer(&conn->errorMessage,
28602847
libpq_gettext("requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n"),
2861-
conn->requirepeer, pass->pw_name);
2848+
conn->requirepeer, remote_username);
2849+
free(remote_username);
28622850
goto error_return;
28632851
}
2852+
free(remote_username);
28642853
#else /* WIN32 */
28652854
/* should have failed with ENOSYS above */
28662855
Assert(false);
@@ -7271,16 +7260,7 @@ pqGetHomeDirectory(char *buf, int bufsize)
72717260

72727261
home = getenv("HOME");
72737262
if (home == NULL || home[0] == '\0')
7274-
{
7275-
char pwdbuf[BUFSIZ];
7276-
struct passwd pwdstr;
7277-
struct passwd *pwd = NULL;
7278-
7279-
(void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd);
7280-
if (pwd == NULL)
7281-
return false;
7282-
home = pwd->pw_dir;
7283-
}
7263+
return pg_get_user_home_dir(geteuid(), buf, bufsize);
72847264
strlcpy(buf, home, bufsize);
72857265
return true;
72867266
#else

src/port/Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ libpgport.a: $(OBJS)
8484
rm -f $@
8585
$(AR) $(AROPT) $@ $^
8686

87+
# getaddrinfo.o and getaddrinfo_shlib.o need PTHREAD_CFLAGS (but getaddrinfo_srv.o does not)
88+
getaddrinfo.o: CFLAGS+=$(PTHREAD_CFLAGS)
89+
getaddrinfo_shlib.o: CFLAGS+=$(PTHREAD_CFLAGS)
90+
8791
# thread.o and thread_shlib.o need PTHREAD_CFLAGS (but thread_srv.o does not)
8892
thread.o: CFLAGS+=$(PTHREAD_CFLAGS)
8993
thread_shlib.o: CFLAGS+=$(PTHREAD_CFLAGS)

src/port/getaddrinfo.c

+44
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@
3434
#include "port/pg_bswap.h"
3535

3636

37+
#ifdef FRONTEND
38+
static int pqGethostbyname(const char *name,
39+
struct hostent *resultbuf,
40+
char *buffer, size_t buflen,
41+
struct hostent **result,
42+
int *herrno);
43+
#endif
44+
3745
#ifdef WIN32
3846
/*
3947
* The native routines may or may not exist on the Windows platform we are on,
@@ -394,3 +402,39 @@ getnameinfo(const struct sockaddr *sa, int salen,
394402

395403
return 0;
396404
}
405+
406+
/*
407+
* Wrapper around gethostbyname() or gethostbyname_r() to mimic
408+
* POSIX gethostbyname_r() behaviour, if it is not available or required.
409+
*/
410+
#ifdef FRONTEND
411+
static int
412+
pqGethostbyname(const char *name,
413+
struct hostent *resultbuf,
414+
char *buffer, size_t buflen,
415+
struct hostent **result,
416+
int *herrno)
417+
{
418+
#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_GETHOSTBYNAME_R)
419+
420+
/*
421+
* broken (well early POSIX draft) gethostbyname_r() which returns 'struct
422+
* hostent *'
423+
*/
424+
*result = gethostbyname_r(name, resultbuf, buffer, buflen, herrno);
425+
return (*result == NULL) ? -1 : 0;
426+
#else
427+
428+
/* no gethostbyname_r(), just use gethostbyname() */
429+
*result = gethostbyname(name);
430+
431+
if (*result != NULL)
432+
*herrno = h_errno;
433+
434+
if (*result != NULL)
435+
return 0;
436+
else
437+
return -1;
438+
#endif
439+
}
440+
#endif /* FRONTEND */

src/port/path.c

+1-10
Original file line numberDiff line numberDiff line change
@@ -815,16 +815,7 @@ get_home_path(char *ret_path)
815815

816816
home = getenv("HOME");
817817
if (home == NULL || home[0] == '\0')
818-
{
819-
char pwdbuf[BUFSIZ];
820-
struct passwd pwdstr;
821-
struct passwd *pwd = NULL;
822-
823-
(void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd);
824-
if (pwd == NULL)
825-
return false;
826-
home = pwd->pw_dir;
827-
}
818+
return pg_get_user_home_dir(geteuid(), ret_path, MAXPGPATH);
828819
strlcpy(ret_path, home, MAXPGPATH);
829820
return true;
830821
#else

0 commit comments

Comments
 (0)