Re: LOCAL_PEERCRED and getpeereid
Re: LOCAL_PEERCRED and getpeereid
- Subject: Re: LOCAL_PEERCRED and getpeereid
- From: Etsushi Kato <email@hidden>
- Date: Sat, 6 Mar 2004 00:02:32 +0900
On Fri, Mar 05, 2004 at 07:24:50PM +0900,
Etsushi Kato <email@hidden> 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
email@hidden
--- 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 | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/darwin-kernel
Do not post admin requests to the list. They will be ignored.