summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDug Song <dugsong@cvs.openbsd.org>2001-06-26 19:56:53 +0000
committerDug Song <dugsong@cvs.openbsd.org>2001-06-26 19:56:53 +0000
commitf9a6c0ac3d4f139e51e54e808391cb56d776e7fb (patch)
treea048983afd7a1bc2677a45462f62160abb2c4a47 /sys
parent365a4d00173693652d309133c96a976401713859 (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.c4
-rw-r--r--sys/kern/syscalls.c3
-rw-r--r--sys/kern/syscalls.master3
-rw-r--r--sys/kern/uipc_syscalls.c48
-rw-r--r--sys/kern/uipc_usrreq.c16
-rw-r--r--sys/sys/protosw.h7
-rw-r--r--sys/sys/socket.h3
-rw-r--r--sys/sys/syscall.h7
-rw-r--r--sys/sys/syscallargs.h9
-rw-r--r--sys/sys/unpcb.h14
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))