Index: sys/sys/protosw.h =================================================================== RCS file: /home/ncvs/src/sys/sys/protosw.h,v retrieving revision 1.28 diff -u -r1.28 protosw.h --- sys/sys/protosw.h 1999/12/29 04:24:45 1.28 +++ sys/sys/protosw.h 2000/07/29 23:57:05 @@ -151,7 +151,8 @@ #define PRU_PROTOSEND 21 /* send to below */ /* end for protocol's internal use */ #define PRU_SEND_EOF 22 /* send and close */ -#define PRU_NREQ 22 +#define PRU_PEEREID 23 /* get local peer eid */ +#define PRU_NREQ 23 #ifdef PRUREQUESTS char *prurequests[] = { @@ -161,7 +162,7 @@ "SENSE", "RCVOOB", "SENDOOB", "SOCKADDR", "PEERADDR", "CONNECT2", "FASTTIMO", "SLOWTIMO", "PROTORCV", "PROTOSEND", - "SEND_EOF", + "SEND_EOF", "PEEREID", }; #endif @@ -227,6 +228,7 @@ struct mbuf **controlp, int *flagsp)); int (*pru_sopoll) __P((struct socket *so, int events, struct ucred *cred, struct proc *p)); + int (*pru_getpeereid) __P((struct socket *so, uid_t *uid, gid_t *gid)); }; int pru_accept_notsupp __P((struct socket *so, struct sockaddr **nam)); Index: sys/sys/socket.h =================================================================== RCS file: /home/ncvs/src/sys/sys/socket.h,v retrieving revision 1.39 diff -u -r1.39 socket.h --- sys/sys/socket.h 2000/03/11 19:51:04 1.39 +++ sys/sys/socket.h 2000/07/29 23:57:05 @@ -417,6 +417,7 @@ 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 *)); Index: sys/sys/unpcb.h =================================================================== RCS file: /home/ncvs/src/sys/sys/unpcb.h,v retrieving revision 1.9 diff -u -r1.9 unpcb.h --- sys/sys/unpcb.h 1999/08/28 00:52:09 1.9 +++ sys/sys/unpcb.h 2000/07/29 23:57:07 @@ -67,6 +67,11 @@ typedef u_quad_t unp_gen_t; LIST_HEAD(unp_head, unpcb); +struct unpcbid { + uid_t unp_euid; + gid_t unp_egid; +}; + struct unpcb { LIST_ENTRY(unpcb) unp_link; /* glue on list of all PCBs */ struct socket *unp_socket; /* pointer back to socket */ @@ -74,6 +79,8 @@ struct vnode *unp_rvnode; /* root vp for creating process */ ino_t unp_ino; /* fake inode number */ struct unpcb *unp_conn; /* control block of connected socket */ + int unp_eids; /* this upcb contains peer eids */ + struct unpcbid unp_connid; /* id of peer process */ struct unp_head unp_refs; /* referencing socket linked list */ LIST_ENTRY(unpcb) unp_reflink; /* link in unp_refs list */ struct sockaddr_un *unp_addr; /* bound address of socket */ Index: sys/kern/syscalls.master =================================================================== RCS file: /home/ncvs/src/sys/kern/syscalls.master,v retrieving revision 1.72 diff -u -r1.72 syscalls.master --- sys/kern/syscalls.master 2000/01/19 06:01:07 1.72 +++ sys/kern/syscalls.master 2000/07/29 23:57:10 @@ -513,3 +513,5 @@ 359 STD BSD { int aio_waitcomplete(struct aiocb **aiocbp, struct timespec *timeout); } 360 STD BSD { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); } 361 STD BSD { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); } +362 STD BSD { int getpeereid(int fdes, uid_t *euid, gid_t *egid); } + Index: sys/kern/uipc_syscalls.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_syscalls.c,v retrieving revision 1.65 diff -u -r1.65 uipc_syscalls.c --- sys/kern/uipc_syscalls.c 1999/12/12 05:52:49 1.65 +++ sys/kern/uipc_syscalls.c 2000/07/29 23:57:17 @@ -1222,6 +1222,41 @@ } #endif /* COMPAT_OLDSOCK */ +/* + * Get eid of peer for connected socket. + */ +/* ARGSUSED */ +int +getpeereid(p, uap) + struct proc *p; + register struct getpeereid_args /* { + int fdes; + uid_t *euid; + gid_t *egid; + } */ *uap; +{ + struct file *fp; + register struct socket *so; + int error; + uid_t u; + gid_t g; + + error = getsock(p->p_fd, uap->fdes, &fp); + if (error) + return (error); + so = (struct socket *)fp->f_data; + if (so->so_proto != pffindtype(AF_LOCAL,SOCK_STREAM)) + return (EOPNOTSUPP); + error = (*so->so_proto->pr_usrreqs->pru_getpeereid)(so, &u, &g); + if (error) + return(error); + error = copyout((caddr_t) &u, (caddr_t)(uap->euid), sizeof(uid_t)); + if (error) + return(error); + error = copyout((caddr_t) &g, (caddr_t)(uap->egid), sizeof(gid_t)); + return (error); +} + int sockargs(mp, buf, buflen, type) struct mbuf **mp; Index: sys/kern/uipc_usrreq.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_usrreq.c,v retrieving revision 1.54 diff -u -r1.54 uipc_usrreq.c --- sys/kern/uipc_usrreq.c 2000/03/09 15:15:27 1.54 +++ sys/kern/uipc_usrreq.c 2000/07/29 23:57:27 @@ -212,6 +212,21 @@ } static int +uipc_peereid(struct socket *so, uid_t *uid, gid_t *gid) +{ + struct unpcb *unp = sotounpcb(so); + + if (unp == 0) + return EINVAL; + if (!unp->unp_eids) + return EOPNOTSUPP; + *uid = unp->unp_connid.unp_euid; + *gid = unp->unp_connid.unp_egid; + return 0; +} + + +static int uipc_rcvd(struct socket *so, int flags) { struct unpcb *unp = sotounpcb(so); @@ -423,7 +438,7 @@ uipc_connect2, pru_control_notsupp, uipc_detach, uipc_disconnect, uipc_listen, uipc_peeraddr, uipc_rcvd, pru_rcvoob_notsupp, uipc_send, uipc_sense, uipc_shutdown, uipc_sockaddr, - sosend, soreceive, sopoll + sosend, soreceive, sopoll, uipc_peereid, }; /* @@ -638,6 +653,9 @@ unp3->unp_addr = (struct sockaddr_un *) dup_sockaddr((struct sockaddr *) unp2->unp_addr, 1); + unp3->unp_connid.unp_euid = p->p_ucred->cr_uid; + unp3->unp_connid.unp_egid = p->p_ucred->cr_gid; + unp3->unp_eids = 1; so2 = so3; } error = unp_connect2(so, so2);