Mercurial > dovecot > core-2.2
comparison src/lib/net.c @ 16276:d594ce839da3
net_getunixcred() support for NetBSD <v5.0. Fixed also building with other NetBSDs.
Patch by Emmanuel Dreyfus
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 11 Apr 2013 13:15:39 +0300 |
parents | 790bb5dfadc6 |
children | c802c0b960e2 |
comparison
equal
deleted
inserted
replaced
16275:e33ec9eb166e | 16276:d594ce839da3 |
---|---|
36 sizeof(so.sin6) : sizeof(so.sin)) | 36 sizeof(so.sin6) : sizeof(so.sin)) |
37 #else | 37 #else |
38 # define SIZEOF_SOCKADDR(so) (sizeof(so.sin)) | 38 # define SIZEOF_SOCKADDR(so) (sizeof(so.sin)) |
39 #endif | 39 #endif |
40 | 40 |
41 #if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && !defined(HAVE_GETPEERUCRED) && defined(MSG_WAITALL) && defined(LOCAL_CREDS) | |
42 # define NEEDS_LOCAL_CREDS 1 | |
43 #endif | |
44 | |
41 bool net_ip_compare(const struct ip_addr *ip1, const struct ip_addr *ip2) | 45 bool net_ip_compare(const struct ip_addr *ip1, const struct ip_addr *ip2) |
42 { | 46 { |
43 return net_ip_cmp(ip1, ip2) == 0; | 47 return net_ip_cmp(ip1, ip2) == 0; |
44 } | 48 } |
45 | 49 |
300 ret = connect(fd, &sa.sa, sizeof(sa)); | 304 ret = connect(fd, &sa.sa, sizeof(sa)); |
301 if (ret < 0 && errno != EINPROGRESS) { | 305 if (ret < 0 && errno != EINPROGRESS) { |
302 i_close_fd(&fd); | 306 i_close_fd(&fd); |
303 return -1; | 307 return -1; |
304 } | 308 } |
309 | |
310 #ifdef NEEDS_LOCAL_CREDS | |
311 { | |
312 int on = 1; | |
313 if (setsockopt(fd, 0, LOCAL_CREDS, &on, sizeof on)) { | |
314 i_error("setsockopt(LOCAL_CREDS) failed: %m"); | |
315 return -1; | |
316 } | |
317 } | |
318 #endif | |
305 | 319 |
306 return fd; | 320 return fd; |
307 } | 321 } |
308 | 322 |
309 int net_connect_unix_with_retries(const char *path, unsigned int msecs) | 323 int net_connect_unix_with_retries(const char *path, unsigned int msecs) |
456 if (fd == -1) { | 470 if (fd == -1) { |
457 i_error("socket() failed: %m"); | 471 i_error("socket() failed: %m"); |
458 return -1; | 472 return -1; |
459 } | 473 } |
460 | 474 |
475 #ifdef NEEDS_LOCAL_CREDS | |
476 { | |
477 int on = 1; | |
478 if (setsockopt(fd, 0, LOCAL_CREDS, &on, sizeof on)) { | |
479 i_error("setsockopt(LOCAL_CREDS) failed: %m"); | |
480 return -1; | |
481 } | |
482 } | |
483 #endif | |
484 | |
461 /* bind */ | 485 /* bind */ |
462 if (bind(fd, &sa.sa, sizeof(sa)) < 0) { | 486 if (bind(fd, &sa.sa, sizeof(sa)) < 0) { |
463 if (errno != EADDRINUSE) | 487 if (errno != EADDRINUSE) |
464 i_error("bind(%s) failed: %m", path); | 488 i_error("bind(%s) failed: %m", path); |
465 } else { | 489 } else { |
719 #elif defined(LOCAL_PEEREID) | 743 #elif defined(LOCAL_PEEREID) |
720 /* NetBSD (may also provide getpeereid, but we also want pid) */ | 744 /* NetBSD (may also provide getpeereid, but we also want pid) */ |
721 struct unpcbid ucred; | 745 struct unpcbid ucred; |
722 socklen_t len = sizeof(ucred); | 746 socklen_t len = sizeof(ucred); |
723 | 747 |
724 if (getsockopt(s, 0, LOCAL_PEEREID, &ucred, &len) < 0) { | 748 if (getsockopt(fd, 0, LOCAL_PEEREID, &ucred, &len) < 0) { |
725 i_error("getsockopt(LOCAL_PEEREID) failed: %m"); | 749 i_error("getsockopt(LOCAL_PEEREID) failed: %m"); |
726 return -1; | 750 return -1; |
727 } | 751 } |
728 | 752 |
729 cred_r->uid = ucred.unp_euid; | 753 cred_r->uid = ucred.unp_euid; |
773 if (cred_r->uid == (uid_t)-1 || | 797 if (cred_r->uid == (uid_t)-1 || |
774 cred_r->gid == (gid_t)-1) { | 798 cred_r->gid == (gid_t)-1) { |
775 errno = EINVAL; | 799 errno = EINVAL; |
776 return -1; | 800 return -1; |
777 } | 801 } |
802 return 0; | |
803 #elif NEEDS_LOCAL_CREDS | |
804 /* NetBSD < 5 */ | |
805 int i, n, on; | |
806 struct iovec iov; | |
807 struct msghdr msg; | |
808 struct { | |
809 struct cmsghdr ch; | |
810 char buf[110]; | |
811 } cdata; | |
812 struct sockcred *sc; | |
813 | |
814 iov.iov_base = (char *)&on; | |
815 iov.iov_len = 1; | |
816 | |
817 sc = (struct sockcred *)cdata.buf; | |
818 sc->sc_uid = sc->sc_euid = sc->sc_gid = sc->sc_egid = -1; | |
819 memset(&cdata.ch, 0, sizeof cdata.ch); | |
820 | |
821 memset(&msg, 0, sizeof msg); | |
822 | |
823 msg.msg_iov = &iov; | |
824 msg.msg_iovlen = 1; | |
825 msg.msg_control = &cdata; | |
826 msg.msg_controllen = sizeof(cdata.ch) + sizeof(cdata.buf); | |
827 | |
828 for (i = 0; i < 10; i++) { | |
829 n = recvmsg(fd, &msg, MSG_WAITALL | MSG_PEEK); | |
830 if (n >= 0 || errno != EAGAIN) | |
831 break; | |
832 usleep(100); | |
833 } | |
834 if (n < 0) { | |
835 i_error("recvmsg() failed: %m"); | |
836 return -1; | |
837 } | |
838 cred_r->uid = sc->sc_euid; | |
839 cred_r->gid = sc->sc_egid; | |
778 return 0; | 840 return 0; |
779 #else | 841 #else |
780 errno = EINVAL; | 842 errno = EINVAL; |
781 return -1; | 843 return -1; |
782 #endif | 844 #endif |