diff options
author | Dug Song <dugsong@cvs.openbsd.org> | 2001-06-26 19:56:53 +0000 |
---|---|---|
committer | Dug Song <dugsong@cvs.openbsd.org> | 2001-06-26 19:56:53 +0000 |
commit | f9a6c0ac3d4f139e51e54e808391cb56d776e7fb (patch) | |
tree | a048983afd7a1bc2677a45462f62160abb2c4a47 /sys | |
parent | 365a4d00173693652d309133c96a976401713859 (diff) |
implement djb's getpeereid(2), to allow local-domain servers to determine client credentials. mostly from superscript.com. deraadt@ ok
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/init_sysent.c | 4 | ||||
-rw-r--r-- | sys/kern/syscalls.c | 3 | ||||
-rw-r--r-- | sys/kern/syscalls.master | 3 | ||||
-rw-r--r-- | sys/kern/uipc_syscalls.c | 48 | ||||
-rw-r--r-- | sys/kern/uipc_usrreq.c | 16 | ||||
-rw-r--r-- | sys/sys/protosw.h | 7 | ||||
-rw-r--r-- | sys/sys/socket.h | 3 | ||||
-rw-r--r-- | sys/sys/syscall.h | 7 | ||||
-rw-r--r-- | sys/sys/syscallargs.h | 9 | ||||
-rw-r--r-- | sys/sys/unpcb.h | 14 |
10 files changed, 100 insertions, 14 deletions
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index d20711ef928..b6fce20328f 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init_sysent.c,v 1.51 2001/06/16 22:17:13 deraadt Exp $ */ +/* $OpenBSD: init_sysent.c,v 1.52 2001/06/26 19:56:52 dugsong Exp $ */ /* * System call switch table. @@ -707,5 +707,7 @@ struct sysent sysent[] = { sys_mlockall }, /* 271 = mlockall */ { 0, 0, sys_munlockall }, /* 272 = munlockall */ + { 3, s(struct sys_getpeereid_args), + sys_getpeereid }, /* 273 = getpeereid */ }; diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index f70d244033c..b6cd2e245c0 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syscalls.c,v 1.51 2001/06/16 22:17:13 deraadt Exp $ */ +/* $OpenBSD: syscalls.c,v 1.52 2001/06/26 19:56:52 dugsong Exp $ */ /* * System call names. @@ -359,4 +359,5 @@ char *syscallnames[] = { "kevent", /* 270 = kevent */ "mlockall", /* 271 = mlockall */ "munlockall", /* 272 = munlockall */ + "getpeereid", /* 273 = getpeereid */ }; diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 2bc8c9691d8..1a6ead6a9ec 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ -; $OpenBSD: syscalls.master,v 1.46 2001/06/16 22:16:23 deraadt Exp $ +; $OpenBSD: syscalls.master,v 1.47 2001/06/26 19:56:52 dugsong Exp $ ; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -533,4 +533,5 @@ const struct timespec *timeout); } 271 STD { int sys_mlockall(int flags); } 272 STD { int sys_munlockall(void); } +273 STD { int sys_getpeereid(int fdes, uid_t *euid, gid_t *egid); } diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 32a283b5633..b5969ac428d 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_syscalls.c,v 1.39 2001/06/22 14:14:10 deraadt Exp $ */ +/* $OpenBSD: uipc_syscalls.c,v 1.40 2001/06/26 19:56:52 dugsong Exp $ */ /* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */ /* @@ -49,6 +49,7 @@ #include <sys/socket.h> #include <sys/socketvar.h> #include <sys/signalvar.h> +#include <sys/unpcb.h> #include <sys/un.h> #ifdef KTRACE #include <sys/ktrace.h> @@ -971,6 +972,51 @@ bad: return (error); } +/* + * Get eid of peer for connected socket. + */ +/* ARGSUSED */ +int +sys_getpeereid(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct sys_getpeereid_args /* { + syscallarg(int) fdes; + syscallarg(uid_t *) euid; + syscallarg(gid_t *) egid; + } */ *uap = v; + struct file *fp; + register struct socket *so; + struct mbuf *m; + struct unpcbid *id; + int error; + + if ((error = getsock(p->p_fd, SCARG(uap, fdes), &fp)) != 0) + return (error); + so = (struct socket *)fp->f_data; + if (so->so_proto != pffindtype(AF_LOCAL, SOCK_STREAM)) + return (EOPNOTSUPP); + m = m_getclr(M_WAIT, MT_SONAME); + if (m == NULL) + return (ENOBUFS); + error = (*so->so_proto->pr_usrreq)(so, PRU_PEEREID, 0, m, 0); + if (!error && m->m_len != sizeof(struct unpcbid)) + error = EOPNOTSUPP; + if (error) + goto bad; + id = mtod(m, struct unpcbid *); + error = copyout((caddr_t)&(id->unp_euid), + (caddr_t)SCARG(uap, euid), sizeof(uid_t)); + if (error == 0) + error = copyout((caddr_t)&(id->unp_egid), + (caddr_t)SCARG(uap, egid), sizeof(gid_t)); +bad: + m_freem(m); + return (error); +} + int sockargs(mp, buf, buflen, type) struct mbuf **mp; diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 184eaaedb45..6d8c193fddb 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_usrreq.c,v 1.12 2001/04/06 04:42:07 csapuntz Exp $ */ +/* $OpenBSD: uipc_usrreq.c,v 1.13 2001/06/26 19:56:52 dugsong Exp $ */ /* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */ /* @@ -290,6 +290,15 @@ uipc_usrreq(so, req, m, nam, control) nam->m_len = 0; break; + case PRU_PEEREID: + if (unp->unp_flags & UNP_FEIDS) { + nam->m_len = sizeof(struct unpcbid); + bcopy((caddr_t)(&(unp->unp_connid)), + mtod(nam, caddr_t), (unsigned)nam->m_len); + } else + nam->m_len = 0; + break; + case PRU_SLOWTIMO: break; @@ -484,7 +493,10 @@ unp_connect(so, nam, p) unp3 = sotounpcb(so3); if (unp2->unp_addr) unp3->unp_addr = - m_copy(unp2->unp_addr, 0, (int)M_COPYALL); + 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_flags |= UNP_FEIDS; so2 = so3; } error = unp_connect2(so, so2); diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h index d0615fe6b2d..62be41d3460 100644 --- a/sys/sys/protosw.h +++ b/sys/sys/protosw.h @@ -1,4 +1,4 @@ -/* $OpenBSD: protosw.h,v 1.5 2001/05/25 22:08:22 itojun Exp $ */ +/* $OpenBSD: protosw.h,v 1.6 2001/06/26 19:56:51 dugsong Exp $ */ /* $NetBSD: protosw.h,v 1.10 1996/04/09 20:55:32 cgd Exp $ */ /*- @@ -150,8 +150,9 @@ struct protosw { #define PRU_SLOWTIMO 19 /* 500ms timeout */ #define PRU_PROTORCV 20 /* receive from below */ #define PRU_PROTOSEND 21 /* send to below */ +#define PRU_PEEREID 22 /* get local peer eid */ -#define PRU_NREQ 21 +#define PRU_NREQ 22 #ifdef PRUREQUESTS char *prurequests[] = { @@ -160,7 +161,7 @@ char *prurequests[] = { "RCVD", "SEND", "ABORT", "CONTROL", "SENSE", "RCVOOB", "SENDOOB", "SOCKADDR", "PEERADDR", "CONNECT2", "FASTTIMO", "SLOWTIMO", - "PROTORCV", "PROTOSEND", + "PROTORCV", "PROTOSEND", "PEEREID", }; #endif diff --git a/sys/sys/socket.h b/sys/sys/socket.h index 661d52abe63..b09c37f47e7 100644 --- a/sys/sys/socket.h +++ b/sys/sys/socket.h @@ -1,4 +1,4 @@ -/* $OpenBSD: socket.h,v 1.37 2001/06/22 14:11:00 deraadt Exp $ */ +/* $OpenBSD: socket.h,v 1.38 2001/06/26 19:56:51 dugsong Exp $ */ /* $NetBSD: socket.h,v 1.14 1996/02/09 18:25:36 christos Exp $ */ /* @@ -408,6 +408,7 @@ __BEGIN_DECLS int accept __P((int, struct sockaddr *, socklen_t *)); int bind __P((int, const struct sockaddr *, socklen_t)); int connect __P((int, const struct sockaddr *, socklen_t)); +int getpeereid __P((int, uid_t *, gid_t *)); int getpeername __P((int, struct sockaddr *, socklen_t *)); int getsockname __P((int, struct sockaddr *, socklen_t *)); int getsockopt __P((int, int, int, void *, socklen_t *)); diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index a73800e59f8..cbe2297ff6f 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.50 2001/06/16 22:17:12 deraadt Exp $ */ +/* $OpenBSD: syscall.h,v 1.51 2001/06/26 19:56:51 dugsong Exp $ */ /* * System call numbers. @@ -636,4 +636,7 @@ /* syscall: "munlockall" ret: "int" args: */ #define SYS_munlockall 272 -#define SYS_MAXSYSCALL 273 +/* syscall: "getpeereid" ret: "int" args: "int" "uid_t *" "gid_t *" */ +#define SYS_getpeereid 273 + +#define SYS_MAXSYSCALL 274 diff --git a/sys/sys/syscallargs.h b/sys/sys/syscallargs.h index 767e0fa799e..676153b553e 100644 --- a/sys/sys/syscallargs.h +++ b/sys/sys/syscallargs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscallargs.h,v 1.51 2001/06/16 22:17:12 deraadt Exp $ */ +/* $OpenBSD: syscallargs.h,v 1.52 2001/06/26 19:56:51 dugsong Exp $ */ /* * System call argument lists. @@ -1115,6 +1115,12 @@ struct sys_mlockall_args { syscallarg(int) flags; }; +struct sys_getpeereid_args { + syscallarg(int) fdes; + syscallarg(uid_t *) euid; + syscallarg(gid_t *) egid; +}; + /* * System call prototypes. */ @@ -1391,3 +1397,4 @@ int sys_kqueue __P((struct proc *, void *, register_t *)); int sys_kevent __P((struct proc *, void *, register_t *)); int sys_mlockall __P((struct proc *, void *, register_t *)); int sys_munlockall __P((struct proc *, void *, register_t *)); +int sys_getpeereid __P((struct proc *, void *, register_t *)); diff --git a/sys/sys/unpcb.h b/sys/sys/unpcb.h index bbeb1255c78..361cdde9dec 100644 --- a/sys/sys/unpcb.h +++ b/sys/sys/unpcb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: unpcb.h,v 1.4 1997/11/17 19:21:48 deraadt Exp $ */ +/* $OpenBSD: unpcb.h,v 1.5 2001/06/26 19:56:52 dugsong Exp $ */ /* $NetBSD: unpcb.h,v 1.6 1994/06/29 06:46:08 cgd Exp $ */ /* @@ -61,6 +61,11 @@ * 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 */ struct vnode *unp_vnode; /* if associated with file */ @@ -69,9 +74,16 @@ struct unpcb { struct unpcb *unp_refs; /* referencing socket linked list */ 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 */ int unp_cc; /* copy of rcv.sb_cc */ int unp_mbcnt; /* copy of rcv.sb_mbcnt */ struct timespec unp_ctime; /* holds creation time */ }; +/* + * flag bits in unp_flags + */ +#define UNP_FEIDS 1 /* unp_connid contains information */ + #define sotounpcb(so) ((struct unpcb *)((so)->so_pcb)) |