summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2010-06-30 19:57:06 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2010-06-30 19:57:06 +0000
commitc020dda5e1cf3952476edda2e2d4cb6a6add8b46 (patch)
tree4d6e52cc186e7e9c7415ba670bc3e70e24d353b1 /sys
parent396f70ce0db276ab8287db4c67d36ba435c2b247 (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.c3
-rw-r--r--sys/kern/uipc_socket.c19
-rw-r--r--sys/kern/uipc_syscalls.c12
-rw-r--r--sys/kern/uipc_usrreq.c19
-rw-r--r--sys/sys/socket.h12
-rw-r--r--sys/sys/unpcb.h8
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 */