[Midnightbsd-cvs] src [8260] trunk/contrib/bsnmp/snmpd: fix a bunch of small issues
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sat Sep 17 17:40:33 EDT 2016
Revision: 8260
http://svnweb.midnightbsd.org/src/?rev=8260
Author: laffer1
Date: 2016-09-17 17:40:32 -0400 (Sat, 17 Sep 2016)
Log Message:
-----------
fix a bunch of small issues
Modified Paths:
--------------
trunk/contrib/bsnmp/snmpd/main.c
trunk/contrib/bsnmp/snmpd/trans_lsock.c
trunk/contrib/bsnmp/snmpd/trans_udp.c
Modified: trunk/contrib/bsnmp/snmpd/main.c
===================================================================
--- trunk/contrib/bsnmp/snmpd/main.c 2016-09-17 21:39:35 UTC (rev 8259)
+++ trunk/contrib/bsnmp/snmpd/main.c 2016-09-17 21:40:32 UTC (rev 8260)
@@ -1026,34 +1026,31 @@
pi->length -= pi->consumed;
}
-struct credmsg {
- struct cmsghdr hdr;
- struct cmsgcred cred;
-};
+static void
+check_priv_dgram(struct port_input *pi, struct sockcred *cred)
+{
+ /* process explicitly sends credentials */
+ if (cred)
+ pi->priv = (cred->sc_euid == 0);
+ else
+ pi->priv = 0;
+}
+
static void
-check_priv(struct port_input *pi, struct msghdr *msg)
+check_priv_stream(struct port_input *pi)
{
- struct credmsg *cmsg;
struct xucred ucred;
socklen_t ucredlen;
- pi->priv = 0;
-
- if (msg->msg_controllen == sizeof(*cmsg)) {
- /* process explicitly sends credentials */
-
- cmsg = (struct credmsg *)msg->msg_control;
- pi->priv = (cmsg->cred.cmcred_euid == 0);
- return;
- }
-
- /* ok, obtain the accept time credentials */
+ /* obtain the accept time credentials */
ucredlen = sizeof(ucred);
if (getsockopt(pi->fd, 0, LOCAL_PEERCRED, &ucred, &ucredlen) == 0 &&
ucredlen >= sizeof(ucred) && ucred.cr_version == XUCRED_VERSION)
pi->priv = (ucred.cr_uid == 0);
+ else
+ pi->priv = 0;
}
/*
@@ -1065,7 +1062,6 @@
struct msghdr msg;
struct iovec iov[1];
ssize_t len;
- struct credmsg cmsg;
if (pi->buf == NULL) {
/* no buffer yet - allocate one */
@@ -1084,17 +1080,8 @@
msg.msg_namelen = pi->peerlen;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
- if (pi->cred) {
- msg.msg_control = &cmsg;
- msg.msg_controllen = sizeof(cmsg);
-
- cmsg.hdr.cmsg_len = sizeof(cmsg);
- cmsg.hdr.cmsg_level = SOL_SOCKET;
- cmsg.hdr.cmsg_type = SCM_CREDS;
- } else {
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- }
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
msg.msg_flags = 0;
iov[0].iov_base = pi->buf + pi->length;
@@ -1109,7 +1096,7 @@
pi->length += len;
if (pi->cred)
- check_priv(pi, &msg);
+ check_priv_stream(pi);
return (0);
}
@@ -1119,13 +1106,16 @@
* Each receive should return one datagram.
*/
static int
-recv_dgram(struct port_input *pi)
+recv_dgram(struct port_input *pi, struct in_addr *laddr)
{
u_char embuf[1000];
+ char cbuf[CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX)) +
+ CMSG_SPACE(sizeof(struct in_addr))];
struct msghdr msg;
struct iovec iov[1];
ssize_t len;
- struct credmsg cmsg;
+ struct cmsghdr *cmsg;
+ struct sockcred *cred = NULL;
if (pi->buf == NULL) {
/* no buffer yet - allocate one */
@@ -1145,17 +1135,9 @@
msg.msg_namelen = pi->peerlen;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
- if (pi->cred) {
- msg.msg_control = &cmsg;
- msg.msg_controllen = sizeof(cmsg);
-
- cmsg.hdr.cmsg_len = sizeof(cmsg);
- cmsg.hdr.cmsg_level = SOL_SOCKET;
- cmsg.hdr.cmsg_type = SCM_CREDS;
- } else {
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- }
+ memset(cbuf, 0, sizeof(cbuf));
+ msg.msg_control = cbuf;
+ msg.msg_controllen = sizeof(cbuf);
msg.msg_flags = 0;
iov[0].iov_base = pi->buf;
@@ -1176,8 +1158,18 @@
pi->length = (size_t)len;
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level == IPPROTO_IP &&
+ cmsg->cmsg_type == IP_RECVDSTADDR)
+ memcpy(laddr, CMSG_DATA(cmsg), sizeof(struct in_addr));
+ if (cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SCM_CREDS)
+ cred = (struct sockcred *)CMSG_DATA(cmsg);
+ }
+
if (pi->cred)
- check_priv(pi, &msg);
+ check_priv_dgram(pi, cred);
return (0);
}
@@ -1199,12 +1191,35 @@
#ifdef USE_TCPWRAPPERS
char client[16];
#endif
+ struct msghdr msg;
+ struct iovec iov[1];
+ char cbuf[CMSG_SPACE(sizeof(struct in_addr))];
+ struct cmsghdr *cmsgp;
/* get input depending on the transport */
if (pi->stream) {
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+
ret = recv_stream(pi);
} else {
- ret = recv_dgram(pi);
+ struct in_addr *laddr;
+
+ memset(cbuf, 0, CMSG_SPACE(sizeof(struct in_addr)));
+ msg.msg_control = cbuf;
+ msg.msg_controllen = CMSG_SPACE(sizeof(struct in_addr));
+ cmsgp = CMSG_FIRSTHDR(&msg);
+ cmsgp->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
+ cmsgp->cmsg_level = IPPROTO_IP;
+ cmsgp->cmsg_type = IP_SENDSRCADDR;
+ laddr = (struct in_addr *)CMSG_DATA(cmsgp);
+
+ ret = recv_dgram(pi, laddr);
+
+ if (laddr->s_addr == 0) {
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ }
}
if (ret == -1)
@@ -1349,11 +1364,19 @@
sndbuf, &sndlen, "SNMP", ierr, vi, NULL);
if (ferr == SNMPD_INPUT_OK) {
- slen = sendto(pi->fd, sndbuf, sndlen, 0, pi->peer, pi->peerlen);
+ msg.msg_name = pi->peer;
+ msg.msg_namelen = pi->peerlen;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_flags = 0;
+ iov[0].iov_base = sndbuf;
+ iov[0].iov_len = sndlen;
+
+ slen = sendmsg(pi->fd, &msg, 0);
if (slen == -1)
- syslog(LOG_ERR, "sendto: %m");
+ syslog(LOG_ERR, "sendmsg: %m");
else if ((size_t)slen != sndlen)
- syslog(LOG_ERR, "sendto: short write %zu/%zu",
+ syslog(LOG_ERR, "sendmsg: short write %zu/%zu",
sndlen, (size_t)slen);
}
snmp_pdu_free(&pdu);
Modified: trunk/contrib/bsnmp/snmpd/trans_lsock.c
===================================================================
--- trunk/contrib/bsnmp/snmpd/trans_lsock.c 2016-09-17 21:39:35 UTC (rev 8259)
+++ trunk/contrib/bsnmp/snmpd/trans_lsock.c 2016-09-17 21:40:32 UTC (rev 8260)
@@ -343,6 +343,7 @@
}
} else {
struct lsock_peer *peer;
+ const int on = 1;
peer = LIST_FIRST(&p->peers);
@@ -351,6 +352,14 @@
return (SNMP_ERR_RES_UNAVAIL);
}
+ if (setsockopt(peer->input.fd, 0, LOCAL_CREDS, &on,
+ sizeof(on)) == -1) {
+ syslog(LOG_ERR, "setsockopt(LOCAL_CREDS): %m");
+ close(peer->input.fd);
+ peer->input.fd = -1;
+ return (SNMP_ERR_GENERR);
+ }
+
strcpy(sa.sun_path, p->name);
sa.sun_family = AF_LOCAL;
sa.sun_len = strlen(p->name) +
Modified: trunk/contrib/bsnmp/snmpd/trans_udp.c
===================================================================
--- trunk/contrib/bsnmp/snmpd/trans_udp.c 2016-09-17 21:39:35 UTC (rev 8259)
+++ trunk/contrib/bsnmp/snmpd/trans_udp.c 2016-09-17 21:40:32 UTC (rev 8260)
@@ -103,6 +103,7 @@
struct udp_port *p = (struct udp_port *)tp;
struct sockaddr_in addr;
u_int32_t ip;
+ const int on = 1;
if ((p->input.fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
syslog(LOG_ERR, "creating UDP socket: %m");
@@ -115,6 +116,14 @@
addr.sin_port = htons(p->port);
addr.sin_family = AF_INET;
addr.sin_len = sizeof(addr);
+ if (addr.sin_addr.s_addr == INADDR_ANY &&
+ setsockopt(p->input.fd, IPPROTO_IP, IP_RECVDSTADDR, &on,
+ sizeof(on)) == -1) {
+ syslog(LOG_ERR, "setsockopt(IP_RECVDSTADDR): %m");
+ close(p->input.fd);
+ p->input.fd = -1;
+ return (SNMP_ERR_GENERR);
+ }
if (bind(p->input.fd, (struct sockaddr *)&addr, sizeof(addr))) {
if (errno == EADDRNOTAVAIL) {
close(p->input.fd);
More information about the Midnightbsd-cvs
mailing list