Mercurial > dovecot > core-2.2
changeset 14233:80688ab1ea3d
Extends struct net_unix_cred with pid field and modifies net_getunixcred() to fill it in if possible.
Depends: none
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 19 May 2012 22:40:08 +0300 |
parents | 875eeb3052a9 |
children | fbb1ecb9b888 |
files | configure.in src/lib/network.c src/lib/network.h |
diffstat | 3 files changed, 58 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Sat May 19 22:28:19 2012 +0300 +++ b/configure.in Sat May 19 22:40:08 2012 +0300 @@ -292,7 +292,7 @@ sys/quota.h sys/fs/ufs_quota.h ufs/ufs/quota.h jfs/quota.h sys/fs/quota_common.h \ mntent.h sys/mnttab.h sys/event.h sys/time.h sys/mkdev.h linux/dqblk_xfs.h \ xfs/xqm.h execinfo.h ucontext.h malloc_np.h sys/utsname.h sys/vmount.h \ - sys/utsname.h glob.h linux/falloc.h ucred.h) + sys/utsname.h glob.h linux/falloc.h ucred.h sys/ucred.h) dnl * clang check have_clang=no @@ -408,6 +408,8 @@ walkcontext dirfd clearenv malloc_usable_size glob fallocate \ posix_fadvise getpeereid getpeerucred) +AC_CHECK_TYPES([struct sockpeercred]) + AC_CHECK_LIB(rt, clock_gettime, [ AC_DEFINE(HAVE_CLOCK_GETTIME,, Define if you have the clock_gettime function) LIBS="$LIBS -lrt"
--- a/src/lib/network.c Sat May 19 22:28:19 2012 +0300 +++ b/src/lib/network.c Sat May 19 22:40:08 2012 +0300 @@ -13,8 +13,10 @@ #include <ctype.h> #include <sys/un.h> #include <netinet/tcp.h> -#ifdef HAVE_UCRED_H +#if defined(HAVE_UCRED_H) # include <ucred.h> /* for getpeerucred() */ +#elif defined(HAVE_SYS_UCRED_H) +# include <sys/ucred.h> /* for FreeBSD struct xucred */ #endif union sockaddr_union { @@ -694,16 +696,14 @@ int net_getunixcred(int fd, struct net_unix_cred *cred_r) { -#if defined(HAVE_GETPEEREID) - /* OSX 10.4+, FreeBSD 4.6+, OpenBSD 3.0+, NetBSD 5.0+ */ - if (getpeereid(fd, &cred_r->uid, &cred_r->gid) < 0) { - i_error("getpeereid() failed: %m"); - return -1; - } - return 0; -#elif defined(SO_PEERCRED) +#if defined(SO_PEERCRED) +# if defined(HAVE_STRUCT_SOCKPEERCRED) + /* OpenBSD (may also provide getpeereid, but we also want pid) */ + struct sockpeercred ucred; +# else /* Linux */ struct ucred ucred; +# endif socklen_t len = sizeof(ucred); if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) < 0) { @@ -712,6 +712,48 @@ } cred_r->uid = ucred.uid; cred_r->gid = ucred.gid; + cred_r->pid = ucred.pid; + return 0; +#elif defined(LOCAL_PEEREID) + /* NetBSD (may also provide getpeereid, but we also want pid) */ + struct unpcbid ucred; + socklen_t len = sizeof(ucred); + + if (getsockopt(s, 0, LOCAL_PEEREID, &ucred, &len) < 0) { + i_error("getsockopt(LOCAL_PEEREID) failed: %m"); + return -1; + } + + cred_r->uid = ucred.unp_euid; + cred_r->gid = ucred.unp_egid; + cred_r->pid = ucred.unp_pid; + return 0; +#elif defined(HAVE_GETPEEREID) + /* OSX 10.4+, FreeBSD 4.6+, OpenBSD 3.0+, NetBSD 5.0+ */ + if (getpeereid(fd, &cred_r->uid, &cred_r->gid) < 0) { + i_error("getpeereid() failed: %m"); + return -1; + } + cred_r->pid = (pid_t)-1; + return 0; +#elif defined(LOCAL_PEERCRED) + /* Older FreeBSD */ + struct xucred ucred; + socklen_t len = sizeof(ucred); + + if (getsockopt(fd, 0, LOCAL_PEERCRED, &ucred, &len) < 0) { + i_error("getsockopt(LOCAL_PEERCRED) failed: %m"); + return -1; + } + + if (ucred.cr_version != XUCRED_VERSION) { + errno = EINVAL; + return -1; + } + + cred_r->uid = ucred.cr_uid; + cred_r->gid = ucred.cr_gid; + cred_r->pid = (pid_t)-1; return 0; #elif defined(HAVE_GETPEERUCRED) /* Solaris */ @@ -723,6 +765,7 @@ } cred_r->uid = ucred_geteuid(ucred); cred_r->gid = ucred_getrgid(ucred); + cred_r->pid = ucred_getpid(ucred); ucred_free(ucred); if (cred_r->uid == (uid_t)-1 ||
--- a/src/lib/network.h Sat May 19 22:28:19 2012 +0300 +++ b/src/lib/network.h Sat May 19 22:40:08 2012 +0300 @@ -34,6 +34,7 @@ struct net_unix_cred { uid_t uid; gid_t gid; + pid_t pid; }; /* maxmimum string length of IP address */ @@ -115,7 +116,8 @@ int net_getpeername(int fd, struct ip_addr *addr, unsigned int *port); /* Get UNIX socket name. */ int net_getunixname(int fd, const char **name_r); -/* Get UNIX socket peer process's credentials. */ +/* Get UNIX socket peer process's credentials. The pid may be (pid_t)-1 if + unavailable. */ int net_getunixcred(int fd, struct net_unix_cred *cred_r); /* Returns ip_addr as string, or NULL if ip is invalid. */