aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/libpq/fe-connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/libpq/fe-connect.c')
-rw-r--r--src/interfaces/libpq/fe-connect.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index f89ceb96642..5a6502fff4d 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -24,6 +24,9 @@
#ifdef HAVE_UCRED_H
#include <ucred.h>
#endif
+#ifdef HAVE_SYS_UCRED_H
+#include <sys/ucred.h>
+#endif
#include "libpq-fe.h"
#include "libpq-int.h"
@@ -1856,15 +1859,21 @@ keep_going: /* We will come back to here until there is
char *startpacket;
int packetlen;
- if (conn->requirepeer && conn->requirepeer[0])
+ /*
+ * Implement requirepeer check, if requested and it's a
+ * Unix-domain socket.
+ */
+ if (conn->requirepeer && conn->requirepeer[0] &&
+ IS_AF_UNIX(conn->raddr.addr.ss_family))
{
-#if defined(HAVE_GETPEEREID) || defined(SO_PEERCRED) || defined(HAVE_GETPEERUCRED)
+#if defined(HAVE_GETPEEREID) || defined(SO_PEERCRED) || defined(LOCAL_PEERCRED) || defined(HAVE_GETPEERUCRED)
char pwdbuf[BUFSIZ];
struct passwd pass_buf;
struct passwd *pass;
uid_t uid;
#if defined(HAVE_GETPEEREID)
+ /* Most BSDen, including OS X: use getpeereid() */
gid_t gid;
errno = 0;
@@ -1876,6 +1885,7 @@ keep_going: /* We will come back to here until there is
goto error_return;
}
#elif defined(SO_PEERCRED)
+ /* Linux: use getsockopt(SO_PEERCRED) */
struct ucred peercred;
ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
@@ -1890,7 +1900,25 @@ keep_going: /* We will come back to here until there is
goto error_return;
}
uid = peercred.uid;
+#elif defined(LOCAL_PEERCRED)
+ /* Debian with FreeBSD kernel: use LOCAL_PEERCRED */
+ struct xucred peercred;
+ ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
+
+ errno = 0;
+ if (getsockopt(conn->sock, 0, LOCAL_PEERCRED,
+ &peercred, &so_len) != 0 ||
+ so_len != sizeof(peercred) ||
+ peercred.cr_version != XUCRED_VERSION)
+ {
+ appendPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("could not get peer credentials: %s\n"),
+ pqStrerror(errno, sebuf, sizeof(sebuf)));
+ goto error_return;
+ }
+ uid = peercred.cr_uid;
#elif defined(HAVE_GETPEERUCRED)
+ /* Solaris: use getpeerucred() */
ucred_t *ucred;
ucred = NULL; /* must be initialized to NULL */