diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2010-06-30 19:57:06 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2010-06-30 19:57:06 +0000 |
commit | c020dda5e1cf3952476edda2e2d4cb6a6add8b46 (patch) | |
tree | 4d6e52cc186e7e9c7415ba670bc3e70e24d353b1 /sys | |
parent | 396f70ce0db276ab8287db4c67d36ba435c2b247 (diff) |
Add getsockopt SOL_SOCKET SO_PEERCRED support. This behaves similar to
getpeereid(2), but also supplies the remote pid. This is supplied in
a 'struct sockpeercred' (unlike Linux -- they showed how little they
know about real unix by calling theirs 'struct ucred').
ok guenther ajacoutot
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_sysctl.c | 3 | ||||
-rw-r--r-- | sys/kern/uipc_socket.c | 19 | ||||
-rw-r--r-- | sys/kern/uipc_syscalls.c | 12 | ||||
-rw-r--r-- | sys/kern/uipc_usrreq.c | 19 | ||||
-rw-r--r-- | sys/sys/socket.h | 12 | ||||
-rw-r--r-- | sys/sys/unpcb.h | 8 |
6 files changed, 50 insertions, 23 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 401280e5101..52161fbe068 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sysctl.c,v 1.186 2010/06/29 16:39:22 guenther Exp $ */ +/* $OpenBSD: kern_sysctl.c,v 1.187 2010/06/30 19:57:05 deraadt Exp $ */ /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ /*- @@ -66,6 +66,7 @@ #include <sys/pipe.h> #include <sys/eventvar.h> #include <sys/socketvar.h> +#include <sys/socket.h> #include <sys/domain.h> #include <sys/protosw.h> #ifdef __HAVE_TIMECOUNTER diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 375e633a060..c4d573bbfc2 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.79 2009/10/31 12:00:08 fgsch Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.80 2010/06/30 19:57:05 deraadt Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -43,6 +43,7 @@ #include <sys/event.h> #include <sys/protosw.h> #include <sys/socket.h> +#include <sys/unpcb.h> #include <sys/socketvar.h> #include <sys/signalvar.h> #include <sys/resourcevar.h> @@ -1193,6 +1194,22 @@ sogetopt(struct socket *so, int level, int optname, struct mbuf **mp) break; } + case SO_PEERCRED: + if (so->so_proto->pr_protocol == AF_UNIX) { + struct unpcb *unp = sotounpcb(so); + + if (unp->unp_flags & UNP_FEIDS) { + *mp = m = m_get(M_WAIT, MT_SOOPTS); + m->m_len = sizeof(unp->unp_connid); + bcopy((caddr_t)(&(unp->unp_connid)), + mtod(m, caddr_t), + (unsigned)m->m_len); + } else + return (EINVAL); + } else + return (EOPNOTSUPP); + break; + default: (void)m_free(m); return (ENOPROTOOPT); diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 912b3be61f6..4a3c9c2166c 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_syscalls.c,v 1.74 2009/12/23 07:40:31 guenther Exp $ */ +/* $OpenBSD: uipc_syscalls.c,v 1.75 2010/06/30 19:57:05 deraadt Exp $ */ /* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */ /* @@ -1007,7 +1007,7 @@ sys_getpeereid(struct proc *p, void *v, register_t *retval) struct file *fp; struct socket *so; struct mbuf *m = NULL; - struct unpcbid *id; + struct sockpeercred *id; int error; if ((error = getsock(p->p_fd, SCARG(uap, fdes), &fp)) != 0) @@ -1023,14 +1023,14 @@ sys_getpeereid(struct proc *p, void *v, register_t *retval) goto bad; } error = (*so->so_proto->pr_usrreq)(so, PRU_PEEREID, 0, m, 0, p); - if (!error && m->m_len != sizeof(struct unpcbid)) + if (!error && m->m_len != sizeof(struct sockpeercred)) error = EOPNOTSUPP; if (error) goto bad; - id = mtod(m, struct unpcbid *); - error = copyout(&(id->unp_euid), SCARG(uap, euid), sizeof(uid_t)); + id = mtod(m, struct sockpeercred *); + error = copyout(&(id->uid), SCARG(uap, euid), sizeof(uid_t)); if (error == 0) - error = copyout(&(id->unp_egid), SCARG(uap, egid), sizeof(gid_t)); + error = copyout(&(id->gid), SCARG(uap, egid), sizeof(gid_t)); bad: FRELE(fp); m_freem(m); diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 79b819bf483..d9c8da248c8 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_usrreq.c,v 1.45 2009/02/22 07:47:22 otto Exp $ */ +/* $OpenBSD: uipc_usrreq.c,v 1.46 2010/06/30 19:57:05 deraadt Exp $ */ /* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */ /* @@ -290,7 +290,7 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, case PRU_PEEREID: if (unp->unp_flags & UNP_FEIDS) { - nam->m_len = sizeof(struct unpcbid); + nam->m_len = sizeof(struct sockpeercred); bcopy((caddr_t)(&(unp->unp_connid)), mtod(nam, caddr_t), (unsigned)nam->m_len); } else @@ -431,8 +431,9 @@ unp_bind(struct unpcb *unp, struct mbuf *nam, struct proc *p) vp->v_socket = unp->unp_socket; unp->unp_vnode = vp; unp->unp_addr = m_copy(nam, 0, (int)M_COPYALL); - unp->unp_connid.unp_euid = p->p_ucred->cr_uid; - unp->unp_connid.unp_egid = p->p_ucred->cr_gid; + unp->unp_connid.uid = p->p_ucred->cr_uid; + unp->unp_connid.gid = p->p_ucred->cr_gid; + unp->unp_connid.pid = p->p_pid; unp->unp_flags |= UNP_FEIDSBIND; VOP_UNLOCK(vp, 0, p); return (0); @@ -484,13 +485,15 @@ unp_connect(struct socket *so, struct mbuf *nam, struct proc *p) if (unp2->unp_addr) unp3->unp_addr = m_copy(unp2->unp_addr, 0, (int)M_COPYALL); - unp3->unp_connid.unp_euid = p->p_ucred->cr_uid; - unp3->unp_connid.unp_egid = p->p_ucred->cr_gid; + unp3->unp_connid.uid = p->p_ucred->cr_uid; + unp3->unp_connid.gid = p->p_ucred->cr_gid; + unp3->unp_connid.pid = p->p_pid; unp3->unp_flags |= UNP_FEIDS; so2 = so3; if (unp2->unp_flags & UNP_FEIDSBIND) { - unp->unp_connid.unp_euid = unp2->unp_connid.unp_euid; - unp->unp_connid.unp_egid = unp2->unp_connid.unp_egid; + unp->unp_connid.uid = unp2->unp_connid.uid; + unp->unp_connid.gid = unp2->unp_connid.gid; + unp->unp_connid.pid = unp2->unp_connid.pid; unp->unp_flags |= UNP_FEIDS; } } diff --git a/sys/sys/socket.h b/sys/sys/socket.h index fccb66b235e..46ddac9834d 100644 --- a/sys/sys/socket.h +++ b/sys/sys/socket.h @@ -1,4 +1,4 @@ -/* $OpenBSD: socket.h,v 1.64 2010/06/29 20:30:33 guenther Exp $ */ +/* $OpenBSD: socket.h,v 1.65 2010/06/30 19:57:05 deraadt Exp $ */ /* $NetBSD: socket.h,v 1.14 1996/02/09 18:25:36 christos Exp $ */ /* @@ -72,6 +72,7 @@ #define SO_JUMBO 0x0400 /* try to use jumbograms */ #define SO_TIMESTAMP 0x0800 /* timestamp received dgram traffic */ #define SO_BINDANY 0x1000 /* allow bind to any address */ +#define SO_PEERCRED 0x2000 /* get connect-time credentials */ /* * Additional options, not kept in so_options. @@ -244,6 +245,15 @@ struct sockcred { gid_t sc_groups[1]; /* variable length */ }; +#if __BSD_VISIBLE +/* Read using getsockopt() with SOL_SOCKET, SO_PEERCRED */ +struct sockpeercred { + uid_t uid; /* effective user id */ + gid_t gid; /* effective group id */ + pid_t pid; +}; +#endif /* __BSD_VISIBLE */ + /* * Compute size of a sockcred structure with groups. */ diff --git a/sys/sys/unpcb.h b/sys/sys/unpcb.h index 9dc004a1c66..a667044fb75 100644 --- a/sys/sys/unpcb.h +++ b/sys/sys/unpcb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: unpcb.h,v 1.7 2006/11/17 08:33:20 claudio Exp $ */ +/* $OpenBSD: unpcb.h,v 1.8 2010/06/30 19:57:05 deraadt Exp $ */ /* $NetBSD: unpcb.h,v 1.6 1994/06/29 06:46:08 cgd Exp $ */ /* @@ -57,10 +57,6 @@ * so that changes in the sockbuf may be computed to modify * back pressure on the sender accordingly. */ -struct unpcbid { - uid_t unp_euid; - gid_t unp_egid; -}; struct unpcb { struct socket *unp_socket; /* pointer back to socket */ @@ -71,7 +67,7 @@ struct unpcb { struct unpcb *unp_nextref; /* link in unp_refs list */ struct mbuf *unp_addr; /* bound address of socket */ int unp_flags; /* this unpcb contains peer eids */ - struct unpcbid unp_connid; /* id of peer process */ + struct sockpeercred unp_connid;/* id of peer process */ int unp_cc; /* copy of rcv.sb_cc */ int unp_mbcnt; /* copy of rcv.sb_mbcnt */ struct timespec unp_ctime; /* holds creation time */ |