diff options
Diffstat (limited to 'src/interfaces/libpq/fe-connect.c')
-rw-r--r-- | src/interfaces/libpq/fe-connect.c | 32 |
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 */ |