summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>1997-03-21 16:12:32 +0000
committerwpaul <wpaul@FreeBSD.org>1997-03-21 16:12:32 +0000
commitcdd7ea42624c882c277e717173e0d9f2d4edfbd1 (patch)
tree4c9acd2b85ec891acf70c2c3de953ed480bd654e /sys/kern
parent61cded15d6400a98014df014cb90523b2a94edd4 (diff)
downloadFreeBSD-src-cdd7ea42624c882c277e717173e0d9f2d4edfbd1.zip
FreeBSD-src-cdd7ea42624c882c277e717173e0d9f2d4edfbd1.tar.gz
Add support to sendmsg()/recvmsg() for passing credentials between
processes using AF_LOCAL sockets. This hack is going to be used with Secure RPC to duplicate a feature of STREAMS which has no real counterpart in sockets (with STREAMS/TLI, you can apparently use t_getinfo() to learn UID of a local process on the other side of a transport endpoint). What happens is this: the client sets up a sendmsg() call with ancillary data using the SCM_CREDS socket-level control message type. It does not need to fill in the structure. When the kernel notices the data, unp_internalize() fills in the cmesgcred structure with the sending process' credentials (UID, EUID, GID, and ancillary groups). This data is later delivered to the receiving process. The receiver can then perform the follwing tests: - Did the client send ancillary data? o Yes, proceed. o No, refuse to authenticate the client. - The the client send data of type SCM_CREDS? o Yes, proceed. o No, refuse to authenticate the client. - Is the cmsgcred structure the right size? o Yes, proceed. o No, signal a possible error. The receiver can now inspect the credential information and use it to authenticate the client.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/uipc_usrreq.c28
1 files changed, 25 insertions, 3 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
OpenPOWER on IntegriCloud