summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/bsnmp/snmpd/main.c74
-rw-r--r--contrib/bsnmp/snmpd/trans_lsock.c9
2 files changed, 40 insertions, 43 deletions
diff --git a/contrib/bsnmp/snmpd/main.c b/contrib/bsnmp/snmpd/main.c
index 8331a83..01a5818 100644
--- a/contrib/bsnmp/snmpd/main.c
+++ b/contrib/bsnmp/snmpd/main.c
@@ -1026,34 +1026,31 @@ snmp_input_consume(struct port_input *pi)
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 @@ recv_stream(struct port_input *pi)
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 @@ recv_stream(struct port_input *pi)
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 @@ recv_stream(struct port_input *pi)
pi->length += len;
if (pi->cred)
- check_priv(pi, &msg);
+ check_priv_stream(pi);
return (0);
}
@@ -1122,10 +1109,12 @@ static int
recv_dgram(struct port_input *pi)
{
u_char embuf[1000];
+ char cbuf[CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX))];
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 +1134,9 @@ recv_dgram(struct port_input *pi)
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 +1157,15 @@ recv_dgram(struct port_input *pi)
pi->length = (size_t)len;
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ 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);
}
diff --git a/contrib/bsnmp/snmpd/trans_lsock.c b/contrib/bsnmp/snmpd/trans_lsock.c
index 2cddd48..30b66f7 100644
--- a/contrib/bsnmp/snmpd/trans_lsock.c
+++ b/contrib/bsnmp/snmpd/trans_lsock.c
@@ -343,6 +343,7 @@ lsock_init_port(struct tport *tp)
}
} else {
struct lsock_peer *peer;
+ const int on = 1;
peer = LIST_FIRST(&p->peers);
@@ -351,6 +352,14 @@ lsock_init_port(struct tport *tp)
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) +
OpenPOWER on IntegriCloud