diff options
Diffstat (limited to 'fallback.cpp')
-rw-r--r-- | fallback.cpp | 80 |
1 files changed, 79 insertions, 1 deletions
diff --git a/fallback.cpp b/fallback.cpp index 405c499f..e81b8702 100644 --- a/fallback.cpp +++ b/fallback.cpp @@ -15,8 +15,9 @@ #include <stdio.h> #include <unistd.h> #include <sys/types.h> +#include <sys/socket.h> #include <sys/stat.h> -#include <unistd.h> +#include <sys/param.h> #include <errno.h> #include <fcntl.h> #include <wchar.h> @@ -1520,3 +1521,80 @@ static int mk_wcswidth(const wchar_t *pwcs, size_t n) } #endif // HAVE_BROKEN_WCWIDTH + +#ifndef HAVE_GETPEEREID + +/*------------------------------------------------------------------------- + * + * getpeereid.c + * get peer userid for UNIX-domain socket connection + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * + * + * IDENTIFICATION + * src/port/getpeereid.c + * + *------------------------------------------------------------------------- + */ + +#ifdef HAVE_SYS_UN_H +#include <sys/un.h> +#endif +#ifdef HAVE_UCRED_H +#include <ucred.h> +#endif +#ifdef HAVE_SYS_UCRED_H +#include <sys/ucred.h> +#endif + +/* + * BSD-style getpeereid() for platforms that lack it. + */ +int getpeereid(int sock, uid_t *uid, gid_t *gid) +{ +#if defined(SO_PEERCRED) + /* Linux: use getsockopt(SO_PEERCRED) */ + struct ucred peercred; + socklen_t so_len = sizeof(peercred); + + if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) != 0 || + so_len != sizeof(peercred)) + return -1; + *uid = peercred.uid; + *gid = peercred.gid; + return 0; +#elif defined(LOCAL_PEERCRED) + /* Debian with FreeBSD kernel: use getsockopt(LOCAL_PEERCRED) */ + struct xucred peercred; + socklen_t * so_len = sizeof(peercred); + + if (getsockopt(sock, 0, LOCAL_PEERCRED, &peercred, &so_len) != 0 || + so_len != sizeof(peercred) || + peercred.cr_version != XUCRED_VERSION) + return -1; + *uid = peercred.cr_uid; + *gid = peercred.cr_gid; + return 0; +#elif defined(HAVE_GETPEERUCRED) + /* Solaris: use getpeerucred() */ + ucred_t *ucred; + + ucred = NULL; /* must be initialized to NULL */ + if (getpeerucred(sock, &ucred) == -1) + return -1; + + *uid = ucred_geteuid(ucred); + *gid = ucred_getegid(ucred); + ucred_free(ucred); + + if (*uid == (uid_t) (-1) || *gid == (gid_t) (-1)) + return -1; + return 0; +#else + /* No implementation available on this platform */ + errno = ENOSYS; + return -1; +#endif +} +#endif // HAVE_GETPEEREID |