dovecot-2.2: net_getunixcred() support for NetBSD <v5.0. Fixed a...

dovecot at dovecot.org dovecot at dovecot.org
Thu Apr 11 13:15:46 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/d594ce839da3
changeset: 16276:d594ce839da3
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Apr 11 13:15:39 2013 +0300
description:
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Patch by Emmanuel Dreyfus

diffstat:

 src/lib/net.c |  64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 63 insertions(+), 1 deletions(-)

diffs (102 lines):

diff -r e33ec9eb166e -r d594ce839da3 src/lib/net.c
--- a/src/lib/net.c	Thu Apr 11 13:13:14 2013 +0300
+++ b/src/lib/net.c	Thu Apr 11 13:15:39 2013 +0300
@@ -38,6 +38,10 @@
 #  define SIZEOF_SOCKADDR(so) (sizeof(so.sin))
 #endif
 
+#if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && !defined(HAVE_GETPEERUCRED) && defined(MSG_WAITALL) && defined(LOCAL_CREDS)
+#  define NEEDS_LOCAL_CREDS 1
+#endif
+
 bool net_ip_compare(const struct ip_addr *ip1, const struct ip_addr *ip2)
 {
 	return net_ip_cmp(ip1, ip2) == 0;
@@ -303,6 +307,16 @@
 		return -1;
 	}
 
+#ifdef NEEDS_LOCAL_CREDS
+	{
+		int on = 1;
+		if (setsockopt(fd, 0, LOCAL_CREDS, &on, sizeof on)) {
+			i_error("setsockopt(LOCAL_CREDS) failed: %m");
+			return -1;
+		}
+	}
+#endif
+
 	return fd;
 }
 
@@ -458,6 +472,16 @@
 		return -1;
 	}
 
+#ifdef NEEDS_LOCAL_CREDS
+	{
+		int on = 1;
+		if (setsockopt(fd, 0, LOCAL_CREDS, &on, sizeof on)) {
+			i_error("setsockopt(LOCAL_CREDS) failed: %m");
+			return -1;
+		}
+	}
+#endif
+
 	/* bind */
 	if (bind(fd, &sa.sa, sizeof(sa)) < 0) {
 		if (errno != EADDRINUSE)
@@ -721,7 +745,7 @@
 	struct unpcbid ucred;
 	socklen_t len = sizeof(ucred);
 
-	if (getsockopt(s, 0, LOCAL_PEEREID, &ucred, &len) < 0) {
+	if (getsockopt(fd, 0, LOCAL_PEEREID, &ucred, &len) < 0) {
 		i_error("getsockopt(LOCAL_PEEREID) failed: %m");
 		return -1;
 	}
@@ -776,6 +800,44 @@
 		return -1;
 	}
 	return 0;
+#elif NEEDS_LOCAL_CREDS
+	/* NetBSD < 5 */
+	int i, n, on;
+	struct iovec iov;
+	struct msghdr msg;
+	struct {
+		struct cmsghdr ch;
+		char buf[110];
+	} cdata;
+	struct sockcred *sc;
+
+	iov.iov_base = (char *)&on;
+	iov.iov_len = 1;
+
+	sc = (struct sockcred *)cdata.buf;
+	sc->sc_uid = sc->sc_euid = sc->sc_gid = sc->sc_egid = -1;
+	memset(&cdata.ch, 0, sizeof cdata.ch);
+
+	memset(&msg, 0, sizeof msg);
+
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+	msg.msg_control = &cdata;
+	msg.msg_controllen = sizeof(cdata.ch) + sizeof(cdata.buf);
+
+	for (i = 0; i < 10; i++) {
+		n = recvmsg(fd, &msg, MSG_WAITALL | MSG_PEEK);
+		if (n >= 0 || errno != EAGAIN)
+			break;
+		usleep(100);
+	}
+	if (n < 0) {
+		i_error("recvmsg() failed: %m");
+		return -1;
+	}
+	cred_r->uid = sc->sc_euid;
+	cred_r->gid = sc->sc_egid;
+	return 0;
 #else
 	errno = EINVAL;
 	return -1;


More information about the dovecot-cvs mailing list