--- a/sysdeps/mach/hurd/sendmsg.c +++ b/sysdeps/mach/hurd/sendmsg.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001,2002,2004,2010 Free Software Foundation, Inc. +/* Copyright (C) 2001,2002,2004,2010,2013 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -38,6 +39,9 @@ int *fds, nfds; struct sockaddr_un *addr = message->msg_name; socklen_t addr_len = message->msg_namelen; + struct cmsgcred *ucredp = NULL; + void *control = message->msg_control; + socklen_t controllen = message->msg_controllen; addr_port_t aport = MACH_PORT_NULL; union { @@ -106,6 +110,33 @@ } } + /* SCM_CREDS support: Create and send the ancillary data */ + cmsg = CMSG_FIRSTHDR (message); + if (cmsg != NULL && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDS) + { + for (; cmsg; cmsg = CMSG_NXTHDR (message, cmsg)) + { + ucredp = (struct cmsgcred *) CMSG_DATA(cmsg); + process_t proc = getproc (); + auth_t auth = getauth (); + nports = 2; + ports = __alloca (nports * sizeof (mach_port_t)); + ports[0] = proc; + ports[1] = auth; + + /* Fill in credentials data */ + ucredp->cmcred_pid = __getpid(); + ucredp->cmcred_uid = __getuid(); + ucredp->cmcred_euid = __geteuid(); + ucredp->cmcred_gid = __getgid(); + /* egid not in struct csmgcred */ + ucredp->cmcred_ngroups = + __getgroups (sizeof (ucredp->cmcred_groups) / sizeof (gid_t), + ucredp->cmcred_groups); + } + goto label; + } + /* SCM_RIGHTS support: get the number of fds to send. */ cmsg = CMSG_FIRSTHDR (message); for (; cmsg; cmsg = CMSG_NXTHDR (message, cmsg)) @@ -147,6 +178,7 @@ } } + label: if (addr) { if (addr->sun_family == AF_LOCAL) @@ -188,8 +220,8 @@ ports, MACH_MSG_TYPE_COPY_SEND, nports, - message->msg_control, - message->msg_controllen, + control, + controllen, &amount); __mach_port_deallocate (__mach_task_self (), aport);