summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/uipc_usrreq.c28
-rw-r--r--sys/sys/socket.h26
2 files changed, 50 insertions, 4 deletions
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 3b668a2..3c68f05 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* From: @(#)uipc_usrreq.c 8.3 (Berkeley) 1/4/94
- * $Id: uipc_usrreq.c,v 1.19 1997/02/22 09:39:29 peter Exp $
+ * $Id: uipc_usrreq.c,v 1.20 1997/02/24 20:30:58 wollman Exp $
*/
#include <sys/param.h>
@@ -697,6 +697,10 @@ unp_externalize(rights)
return (0);
}
+#ifndef MIN
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+
static int
unp_internalize(control, p)
struct mbuf *control;
@@ -707,11 +711,29 @@ unp_internalize(control, p)
register struct file **rp;
register struct file *fp;
register int i, fd;
+ register struct cmsgcred *cmcred;
int oldfds;
- if (cm->cmsg_type != SCM_RIGHTS || cm->cmsg_level != SOL_SOCKET ||
- cm->cmsg_len != control->m_len)
+ if ((cm->cmsg_type != SCM_RIGHTS && cm->cmsg_type != SCM_CREDS) ||
+ cm->cmsg_level != SOL_SOCKET || cm->cmsg_len != control->m_len)
return (EINVAL);
+
+ /*
+ * Fill in credential information.
+ */
+ if (cm->cmsg_type == SCM_CREDS) {
+ cmcred = (struct cmsgcred *)(cm + 1);
+ cmcred->cmcred_pid = p->p_pid;
+ cmcred->cmcred_uid = p->p_cred->p_ruid;
+ cmcred->cmcred_gid = p->p_cred->p_rgid;
+ cmcred->cmcred_euid = p->p_ucred->cr_uid;
+ cmcred->cmcred_ngroups = MIN(p->p_ucred->cr_ngroups,
+ CMGROUP_MAX);
+ for (i = 0; i < cmcred->cmcred_ngroups; i++)
+ cmcred->cmcred_groups[i] = p->p_ucred->cr_groups[i];
+ return(0);
+ }
+
oldfds = (cm->cmsg_len - sizeof (*cm)) / sizeof (int);
/*
* check that all the FDs passed in refer to legal OPEN files
diff --git a/sys/sys/socket.h b/sys/sys/socket.h
index 7e0f6c7..c770a67 100644
--- a/sys/sys/socket.h
+++ b/sys/sys/socket.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)socket.h 8.4 (Berkeley) 2/21/94
- * $Id$
+ * $Id: socket.h,v 1.17 1997/02/22 09:45:55 peter Exp $
*/
#ifndef _SYS_SOCKET_H_
@@ -289,6 +289,29 @@ struct cmsghdr {
/* followed by u_char cmsg_data[]; */
};
+/*
+ * While we may have more groups than this, the cmsgcred struct must
+ * be able to fit in an mbuf, and NGROUPS_MAX is too large to allow
+ * this.
+*/
+#define CMGROUP_MAX 16
+
+/*
+ * Credentials structure, used to verify the identity of a peer
+ * process that has sent us a message. This is allocated by the
+ * peer process but filled in by the kernel. This prevents the
+ * peer from lying about its identity. (Note that cmcred_groups[0]
+ * is the effective GID.)
+ */
+struct cmsgcred {
+ pid_t cmcred_pid; /* PID of sending process */
+ uid_t cmcred_uid; /* real UID of sending process */
+ uid_t cmcred_euid; /* effective UID of sending process */
+ gid_t cmcred_gid; /* real GID of sending process */
+ short cmcred_ngroups; /* number or groups */
+ gid_t cmcred_groups[CMGROUP_MAX]; /* groups */
+};
+
/* given pointer to struct cmsghdr, return pointer to data */
#define CMSG_DATA(cmsg) ((u_char *)((cmsg) + 1))
@@ -304,6 +327,7 @@ struct cmsghdr {
/* "Socket"-level control message types: */
#define SCM_RIGHTS 0x01 /* access rights (array of int) */
#define SCM_TIMESTAMP 0x02 /* timestamp (struct timeval) */
+#define SCM_CREDS 0x03 /* process creds (struct cmsgcred) */
/*
* 4.3 compat sockaddr, move to compat file later
OpenPOWER on IntegriCloud