Mercurial > dovecot > core-2.2
changeset 12887:352999078d83
Added net_getunixcred() to get UNIX socket peer process's UID and GID.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 05 Apr 2011 12:24:59 +0300 |
parents | 1ff458ba2e4b |
children | 03b8a8fe1959 |
files | configure.in src/lib/network.c src/lib/network.h |
diffstat | 3 files changed, 58 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Mon Apr 04 16:08:50 2011 +0300 +++ b/configure.in Tue Apr 05 12:24:59 2011 +0300 @@ -283,7 +283,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) + sys/utsname.h glob.h linux/falloc.h ucred.h) dnl * gcc specific options if test "x$ac_cv_c_compiler_gnu" = "xyes"; then @@ -380,7 +380,7 @@ strtoull strtoll strtouq strtoq \ setpriority quotactl getmntent kqueue kevent backtrace_symbols \ walkcontext dirfd clearenv malloc_usable_size glob fallocate \ - posix_fadvise) + posix_fadvise getpeereid getpeerucred) AC_CHECK_LIB(rt, clock_gettime, [ AC_DEFINE(HAVE_CLOCK_GETTIME,, Define if you have the clock_gettime function)
--- a/src/lib/network.c Mon Apr 04 16:08:50 2011 +0300 +++ b/src/lib/network.c Tue Apr 05 12:24:59 2011 +0300 @@ -1,5 +1,6 @@ /* Copyright (c) 1999-2011 Dovecot authors, see the included COPYING file */ +#define _GNU_SOURCE /* For Linux's struct ucred */ #include "lib.h" #include "close-keep-errno.h" #include "fd-set-nonblock.h" @@ -12,6 +13,9 @@ #include <ctype.h> #include <sys/un.h> #include <netinet/tcp.h> +#ifdef HAVE_UCRED_H +# include <ucred.h> /* for getpeerucred() */ +#endif union sockaddr_union { struct sockaddr sa; @@ -686,6 +690,51 @@ return 0; } +int net_getunixcred(int fd, struct net_unix_cred *cred_r) +{ +#if defined(SO_PEERCRED) + /* Linux */ + struct ucred ucred; + socklen_t len = sizeof(ucred); + + if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) < 0) { + i_error("getsockopt(SO_PEERCRED) failed: %m"); + return -1; + } + cred_r->uid = ucred.uid; + cred_r->gid = ucred.gid; + 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; + } + return 0; +#elif defined(HAVE_GETPEERUCRED) + /* Solaris */ + ucred_t *ucred; + + if (getpeerucred(fd, &ucred) < 0) { + i_error("getpeerucred() failed: %m"); + return -1; + } + cred_r->uid = ucred_geteuid(ucred); + cred_r->gid = ucred_getrgid(ucred); + ucred_free(ucred); + + if (cred_r->uid == (uid_t)-1 || + cred_r->gid == (gid_t)-1) { + errno = EINVAL; + return -1; + } + return 0; +#else + errno = EINVAL; + return -1; +#endif +} + const char *net_ip2addr(const struct ip_addr *ip) { #ifdef HAVE_IPV6
--- a/src/lib/network.h Mon Apr 04 16:08:50 2011 +0300 +++ b/src/lib/network.h Tue Apr 05 12:24:59 2011 +0300 @@ -31,6 +31,11 @@ }; ARRAY_DEFINE_TYPE(ip_addr, struct ip_addr); +struct net_unix_cred { + uid_t uid; + gid_t gid; +}; + /* maxmimum string length of IP address */ #ifdef HAVE_IPV6 # define MAX_IP_LEN INET6_ADDRSTRLEN @@ -109,6 +114,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. */ +int net_getunixcred(int fd, struct net_unix_cred *cred_r); /* Returns ip_addr as string, or NULL if ip is invalid. */ const char *net_ip2addr(const struct ip_addr *ip);