Re: LOCAL_PEERCRED and getpeereid
On Fri, Mar 05, 2004 at 07:24:50PM +0900, Etsushi Kato <ekato@ees.hokudai.ac.jp> wrote:
Can someone check this patch? and is it possible that getpeereid()
is supported in the next release of darwin?
Hmm, my patch seems to be deleted. So, I'll resend the patch as a text. P.S. Is it the proper list for sending patches? Cheers, -- Etsushi Kato ekato@ees.hokudai.ac.jp --- xnu-517.3.7/bsd/kern/uipc_proto.c.orig Sat Dec 20 07:36:53 2003 +++ xnu-517.3.7/bsd/kern/uipc_proto.c Fri Mar 5 02:02:05 2004 @@ -78,7 +78,7 @@ static struct protosw localsw[] = { { SOCK_STREAM, &localdomain, 0, PR_CONNREQUIRED|PR_WANTRCVD|PR_RIGHTS, - 0, 0, 0, 0, + 0, 0, 0, &uipc_ctloutput, 0, 0, 0, 0, 0, 0, &uipc_usrreqs --- xnu-517.3.7/bsd/kern/uipc_usrreq.c.orig Sat Dec 20 07:36:53 2003 +++ xnu-517.3.7/bsd/kern/uipc_usrreq.c Fri Mar 5 03:08:06 2004 @@ -219,6 +219,8 @@ if (unp == 0 || unp->unp_vnode == 0) return EINVAL; + cru2x(p->p_ucred, &unp->unp_peercred); + unp->unp_flags |= UNP_HAVEPCCACHED; return 0; } @@ -450,6 +452,40 @@ sosend, soreceive, sopoll }; +int +uipc_ctloutput(so, sopt) + struct socket *so; + struct sockopt *sopt; +{ + struct unpcb *unp = sotounpcb(so); + int error; + + switch (sopt->sopt_dir) { + case SOPT_GET: + switch (sopt->sopt_name) { + case LOCAL_PEERCRED: + if (unp->unp_flags & UNP_HAVEPC) + error = sooptcopyout(sopt, &unp->unp_peercred, + sizeof(unp->unp_peercred)); + else { + if (so->so_type == SOCK_STREAM) + error = ENOTCONN; + else + error = EINVAL; + } + break; + default: + error = EOPNOTSUPP; + break; + } + break; + case SOPT_SET: + error = EOPNOTSUPP; + break; + } + return (error); +} + /* * Both send and receive buffers are allocated PIPSIZ bytes of buffering * for stream sockets, although the total for sender and receiver is @@ -627,7 +663,7 @@ register struct sockaddr_un *soun = (struct sockaddr_un *)nam; register struct vnode *vp; register struct socket *so2, *so3; - struct unpcb *unp2, *unp3; + struct unpcb *unp, *unp2, *unp3; int error, len; struct nameidata nd; char buf[SOCK_MAXADDRLEN]; @@ -682,12 +718,33 @@ thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL); goto bad; } + unp = sotounpcb(so); unp2 = sotounpcb(so2); unp3 = sotounpcb(so3); if (unp2->unp_addr) unp3->unp_addr = (struct sockaddr_un *) dup_sockaddr((struct sockaddr *) unp2->unp_addr, 1); + /* + * unp_peercred management: + * + * The connecter's (client's) credentials are copied + * from its process structure at the time of connect() + * (which is now). + */ + cru2x(p->p_ucred, &unp3->unp_peercred); + unp3->unp_flags |= UNP_HAVEPC; + /* + * The receiver's (server's) credentials are copied + * from the unp_peercred member of socket on which the + * process's credentials at that time so we can use + * them now. + */ + KASSERT(unp2->unp_flags & UNP_HAVEPCCACHED, + ("unp_connect: listener without cached peercred")); + memcpy(&unp->unp_peercred, &unp2->unp_peercred, + sizeof(unp->unp_peercred)); + unp->unp_flags |= UNP_HAVEPC; so2 = so3; } error = unp_connect2(so, so2); --- xnu-517.3.7/bsd/sys/un.h.orig Sat Dec 20 07:37:23 2003 +++ xnu-517.3.7/bsd/sys/un.h Fri Mar 5 01:55:26 2004 @@ -71,11 +71,15 @@ char sun_path[104]; /* path name (gag) */ }; +/* Socket options. */ +#define LOCAL_PEERCRED 0x001 /* retrieve peer credentails */ + #ifdef KERNEL #ifdef __APPLE_API_PRIVATE struct mbuf; struct socket; +int uipc_ctloutput(struct socket *so, struct sockopt *sopt); int uipc_usrreq __P((struct socket *so, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *control)); int unp_connect2 __P((struct socket *so, struct socket *so2)); --- xnu-517.3.7/bsd/sys/unpcb.h.orig Sat Dec 20 07:37:23 2003 +++ xnu-517.3.7/bsd/sys/unpcb.h Fri Mar 5 02:45:28 2004 @@ -105,7 +105,25 @@ int unp_cc; /* copy of rcv.sb_cc */ int unp_mbcnt; /* copy of rcv.sb_mbcnt */ unp_gen_t unp_gencnt; /* generation count of this instance */ + int unp_flags; /* flags */ + struct xucred unp_peercred; /* peer credentials, if applicable */ }; + +/* + * Flags in unp_flags. + * + * UNP_HAVEPC - indicates that the unp_peercred member is filled in + * and is really the credentials of the connected peer. This is used + * to determine whether the contents should be sent to the user or + * not. + * + * UNP_HAVEPCCACHED - indicates that the unp_peercred member is filled + * in, but does *not* contain the credentials of the connected peer + * (there may not even be a peer). This is set in unp_listen() when + * it fills in unp_peercred for later consumption by unp_connect(). + */ +#define UNP_HAVEPC 0x001 +#define UNP_HAVEPCCACHED 0x002 #define sotounpcb(so) ((struct unpcb *)((so)->so_pcb)) #endif /* __APPLE_API_PRIVATE */ --- Libc-320/gen/Makefile.inc.orig Thu Aug 28 16:06:04 2003 +++ Libc-320/gen/Makefile.inc Fri Mar 5 03:32:32 2004 @@ -8,7 +8,7 @@ SRCS += NSSystemDirectories.c OSSystemInfo.c arc4random.c assert.c cache.c \ confstr.c crypt.c devname.c disklabel.c errlst.c fts.c \ - getloadavg.c getttyent.c getusershell.c getvfsbyname.c isnan.c \ + getloadavg.c getpeereid.c getttyent.c getusershell.c getvfsbyname.c isnan.c \ malloc.c nanosleep.c nlist.c scalable_malloc.c setlogin.c sigsetops.c \ stack_logging.c strtofflags.c sysconf.c syslog.c uname.c zone.c --- Libc-320/include/unistd.h.orig Sat Oct 25 07:36:25 2003 +++ Libc-320/include/unistd.h Fri Mar 5 03:53:07 2004 @@ -208,6 +208,7 @@ long gethostid(void); int gethostname(char *, int); mode_t getmode(const void *, mode_t); +int getpeereid(int, uid_t *, gid_t, *); int getpagesize(void) __pure2; char *getpass(const char *); int getpgid(pid_t _pid); --- /dev/null Fri Mar 5 04:07:53 2004 +++ Libc-320/gen/getpeereid.c Fri Mar 5 03:30:07 2004 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2001 Dima Dorfman. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD: src/lib/libc/gen/getpeereid.c,v 1.6 2002/12/16 13:42:13 maxim Exp $"); + +#include <sys/param.h> +#include <sys/socket.h> +#include <sys/ucred.h> +#include <sys/un.h> + +#include <errno.h> +#include <unistd.h> + +int +getpeereid(int s, uid_t *euid, gid_t *egid) +{ + struct xucred xuc; + socklen_t xuclen; + int error; + + xuclen = sizeof(xuc); + error = getsockopt(s, 0, LOCAL_PEERCRED, &xuc, &xuclen); + if (error != 0) + return (error); + if (xuc.cr_version != XUCRED_VERSION) + return (EINVAL); + *euid = xuc.cr_uid; + *egid = xuc.cr_gid; + return (0); +} _______________________________________________ darwin-kernel mailing list | darwin-kernel@lists.apple.com Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/darwin-kernel Do not post admin requests to the list. They will be ignored.
participants (1)
-
Etsushi Kato