xref: /titanic_51/usr/src/uts/common/rpc/sec/auth_kern.c (revision 0e91b739ccc30f8aa65da0a0f6607401aa9d31fc)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
567dbe2beSCasper H.S. Dik  * Common Development and Distribution License (the "License").
667dbe2beSCasper H.S. Dik  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
2267dbe2beSCasper H.S. Dik  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
277c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley 4.3 BSD
317c478bd9Sstevel@tonic-gate  * under license from the Regents of the University of California.
327c478bd9Sstevel@tonic-gate  */
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate  * auth_kern.c, implements UNIX style authentication parameters in the kernel.
367c478bd9Sstevel@tonic-gate  * Interfaces with svc_auth_unix on the server.  See auth_unix.c for the user
377c478bd9Sstevel@tonic-gate  * level implementation of unix auth.
387c478bd9Sstevel@tonic-gate  *
397c478bd9Sstevel@tonic-gate  */
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #include <sys/param.h>
427c478bd9Sstevel@tonic-gate #include <sys/time.h>
437c478bd9Sstevel@tonic-gate #include <sys/types.h>
447c478bd9Sstevel@tonic-gate #include <sys/systm.h>
457c478bd9Sstevel@tonic-gate #include <sys/user.h>
467c478bd9Sstevel@tonic-gate #include <sys/proc.h>
477c478bd9Sstevel@tonic-gate #include <sys/cred.h>
487c478bd9Sstevel@tonic-gate #include <sys/kmem.h>
497c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
507c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
517c478bd9Sstevel@tonic-gate #include <sys/utsname.h>
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate #include <rpc/types.h>
547c478bd9Sstevel@tonic-gate #include <rpc/xdr.h>
557c478bd9Sstevel@tonic-gate #include <rpc/auth.h>
567c478bd9Sstevel@tonic-gate #include <rpc/auth_unix.h>
577c478bd9Sstevel@tonic-gate #include <rpc/clnt.h>
587c478bd9Sstevel@tonic-gate #include <rpc/rpc_msg.h>
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate /*
617c478bd9Sstevel@tonic-gate  * Unix authenticator operations vector
627c478bd9Sstevel@tonic-gate  */
637c478bd9Sstevel@tonic-gate static void	authkern_nextverf(AUTH *);
647c478bd9Sstevel@tonic-gate static bool_t	authkern_marshal(AUTH *, XDR *, struct cred *);
657c478bd9Sstevel@tonic-gate static bool_t	authkern_validate(AUTH *, struct opaque_auth *);
667c478bd9Sstevel@tonic-gate static bool_t	authkern_refresh(AUTH *, struct rpc_msg *, cred_t *);
677c478bd9Sstevel@tonic-gate static void	authkern_destroy(AUTH *);
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate static struct auth_ops auth_kern_ops = {
707c478bd9Sstevel@tonic-gate 	authkern_nextverf,
717c478bd9Sstevel@tonic-gate 	authkern_marshal,
727c478bd9Sstevel@tonic-gate 	authkern_validate,
737c478bd9Sstevel@tonic-gate 	authkern_refresh,
747c478bd9Sstevel@tonic-gate 	authkern_destroy,
757c478bd9Sstevel@tonic-gate 	authany_wrap,
767c478bd9Sstevel@tonic-gate 	authany_unwrap
777c478bd9Sstevel@tonic-gate };
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate /*
807c478bd9Sstevel@tonic-gate  * Create a kernel unix style authenticator.
817c478bd9Sstevel@tonic-gate  * Returns an auth handle.
827c478bd9Sstevel@tonic-gate  */
837c478bd9Sstevel@tonic-gate AUTH *
847c478bd9Sstevel@tonic-gate authkern_create(void)
857c478bd9Sstevel@tonic-gate {
867c478bd9Sstevel@tonic-gate 	/*
877c478bd9Sstevel@tonic-gate 	 * Allocate and set up auth handle
887c478bd9Sstevel@tonic-gate 	 */
897c478bd9Sstevel@tonic-gate 	return (kmem_cache_alloc(authkern_cache, KM_SLEEP));
907c478bd9Sstevel@tonic-gate }
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate /*
937c478bd9Sstevel@tonic-gate  *  The constructor of the authkern_cache.
947c478bd9Sstevel@tonic-gate  */
957c478bd9Sstevel@tonic-gate /* ARGSUSED */
967c478bd9Sstevel@tonic-gate int
977c478bd9Sstevel@tonic-gate authkern_init(void *buf, void *cdrarg, int kmflags)
987c478bd9Sstevel@tonic-gate {
997c478bd9Sstevel@tonic-gate 	AUTH *auth = (AUTH *)buf;
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	auth->ah_ops = &auth_kern_ops;
1027c478bd9Sstevel@tonic-gate 	auth->ah_cred.oa_flavor = AUTH_UNIX;
1037c478bd9Sstevel@tonic-gate 	auth->ah_verf = _null_auth;
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate 	return (0);
1067c478bd9Sstevel@tonic-gate }
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate /*
1097c478bd9Sstevel@tonic-gate  * authkern operations
1107c478bd9Sstevel@tonic-gate  */
1117c478bd9Sstevel@tonic-gate /* ARGSUSED */
1127c478bd9Sstevel@tonic-gate static void
1137c478bd9Sstevel@tonic-gate authkern_nextverf(AUTH *auth)
1147c478bd9Sstevel@tonic-gate {
1157c478bd9Sstevel@tonic-gate 	/* no action necessary */
1167c478bd9Sstevel@tonic-gate }
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate static bool_t
1197c478bd9Sstevel@tonic-gate authkern_marshal(AUTH *auth, XDR *xdrs, struct cred *cr)
1207c478bd9Sstevel@tonic-gate {
1217c478bd9Sstevel@tonic-gate 	char *sercred;
1227c478bd9Sstevel@tonic-gate 	XDR xdrm;
123*0e91b739SMarcel Telka 	bool_t ret;
124*0e91b739SMarcel Telka 	uint32_t gidlen, credsize, namelen, rounded_namelen;
1257c478bd9Sstevel@tonic-gate 	int32_t *ptr;
1267c478bd9Sstevel@tonic-gate 	char *nodename = uts_nodename();
127*0e91b739SMarcel Telka 	uint_t startpos;
128*0e91b739SMarcel Telka 
129*0e91b739SMarcel Telka 	ASSERT(xdrs->x_op == XDR_ENCODE);
130*0e91b739SMarcel Telka 	ASSERT(auth->ah_cred.oa_flavor == AUTH_SYS);
131*0e91b739SMarcel Telka 	ASSERT(auth->ah_verf.oa_flavor == AUTH_NONE);
132*0e91b739SMarcel Telka 	ASSERT(auth->ah_verf.oa_length == 0);
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 	/*
1357c478bd9Sstevel@tonic-gate 	 * First we try a fast path to get through
1367c478bd9Sstevel@tonic-gate 	 * this very common operation.
1377c478bd9Sstevel@tonic-gate 	 */
138*0e91b739SMarcel Telka 	namelen = (uint32_t)strlen(nodename);
139*0e91b739SMarcel Telka 	if (namelen > MAX_MACHINE_NAME)
140*0e91b739SMarcel Telka 		return (FALSE);
141*0e91b739SMarcel Telka 	rounded_namelen = RNDUP(namelen);
142*0e91b739SMarcel Telka 
143*0e91b739SMarcel Telka 	/*
144*0e91b739SMarcel Telka 	 * NFIELDS is a number of the following fields we are going to encode:
145*0e91b739SMarcel Telka 	 *   - stamp
146*0e91b739SMarcel Telka 	 *   - strlen(machinename)
147*0e91b739SMarcel Telka 	 *   - uid
148*0e91b739SMarcel Telka 	 *   - gid
149*0e91b739SMarcel Telka 	 *   - the number of gids
150*0e91b739SMarcel Telka 	 */
151*0e91b739SMarcel Telka #define	NFIELDS	5
152*0e91b739SMarcel Telka 	CTASSERT((NFIELDS + NGRPS) * BYTES_PER_XDR_UNIT +
153*0e91b739SMarcel Telka 	    RNDUP(MAX_MACHINE_NAME) <= MAX_AUTH_BYTES);
154*0e91b739SMarcel Telka 
1557c478bd9Sstevel@tonic-gate 	gidlen = crgetngroups(cr);
1567c478bd9Sstevel@tonic-gate 	if (gidlen > NGRPS)
15767dbe2beSCasper H.S. Dik 		gidlen = NGRPS;
1587c478bd9Sstevel@tonic-gate 
159*0e91b739SMarcel Telka 	credsize = NFIELDS * BYTES_PER_XDR_UNIT + rounded_namelen +
160*0e91b739SMarcel Telka 	    gidlen * BYTES_PER_XDR_UNIT;
161*0e91b739SMarcel Telka 	ASSERT(credsize <= MAX_AUTH_BYTES);
162*0e91b739SMarcel Telka #undef	NFIELDS
163*0e91b739SMarcel Telka 
164*0e91b739SMarcel Telka 	/*
165*0e91b739SMarcel Telka 	 * We need to marshal both cred and verf parts of the rpc_msg body
166*0e91b739SMarcel Telka 	 * (call_body).  For the cred part we need to inline the auth_flavor
167*0e91b739SMarcel Telka 	 * and the opaque auth body size.  Then we inline the credsize bytes of
168*0e91b739SMarcel Telka 	 * the opaque auth body for the cred part.  Finally we add the
169*0e91b739SMarcel Telka 	 * AUTH_NONE verifier (its auth_flavor and the opaque auth body size).
170*0e91b739SMarcel Telka 	 */
171*0e91b739SMarcel Telka 	ptr = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT + credsize +
172*0e91b739SMarcel Telka 	    2 * BYTES_PER_XDR_UNIT);
173*0e91b739SMarcel Telka 	if (ptr != NULL) {
1747c478bd9Sstevel@tonic-gate 		/*
1757c478bd9Sstevel@tonic-gate 		 * We can do the fast path.
1767c478bd9Sstevel@tonic-gate 		 */
177*0e91b739SMarcel Telka 		const gid_t *gp = crgetgroups(cr);
178*0e91b739SMarcel Telka 
179*0e91b739SMarcel Telka 		IXDR_PUT_U_INT32(ptr, AUTH_SYS);	/* cred flavor */
180*0e91b739SMarcel Telka 		IXDR_PUT_U_INT32(ptr, credsize);	/* cred len */
181*0e91b739SMarcel Telka 
1827c478bd9Sstevel@tonic-gate 		IXDR_PUT_INT32(ptr, gethrestime_sec());
183*0e91b739SMarcel Telka 		IXDR_PUT_U_INT32(ptr, namelen);
184*0e91b739SMarcel Telka 		bcopy(nodename, ptr, namelen);
185*0e91b739SMarcel Telka 		if ((rounded_namelen - namelen) > 0)
186*0e91b739SMarcel Telka 			bzero((char *)ptr + namelen, rounded_namelen - namelen);
1877c478bd9Sstevel@tonic-gate 		ptr += rounded_namelen / BYTES_PER_XDR_UNIT;
188*0e91b739SMarcel Telka 		IXDR_PUT_U_INT32(ptr, crgetuid(cr));
189*0e91b739SMarcel Telka 		IXDR_PUT_U_INT32(ptr, crgetgid(cr));
190*0e91b739SMarcel Telka 		IXDR_PUT_U_INT32(ptr, gidlen);
191*0e91b739SMarcel Telka 		while (gidlen-- > 0)
192*0e91b739SMarcel Telka 			IXDR_PUT_U_INT32(ptr, *gp++);
193*0e91b739SMarcel Telka 
194*0e91b739SMarcel Telka 		IXDR_PUT_U_INT32(ptr, AUTH_NULL);	/* verf flavor */
195*0e91b739SMarcel Telka 		IXDR_PUT_U_INT32(ptr, 0);		/* verf len */
196*0e91b739SMarcel Telka 
1977c478bd9Sstevel@tonic-gate 		return (TRUE);
1987c478bd9Sstevel@tonic-gate 	}
199*0e91b739SMarcel Telka 
2007c478bd9Sstevel@tonic-gate 	sercred = kmem_alloc(MAX_AUTH_BYTES, KM_SLEEP);
201*0e91b739SMarcel Telka 
2027c478bd9Sstevel@tonic-gate 	/*
203*0e91b739SMarcel Telka 	 * Serialize the auth body data into sercred.
2047c478bd9Sstevel@tonic-gate 	 */
2057c478bd9Sstevel@tonic-gate 	xdrmem_create(&xdrm, sercred, MAX_AUTH_BYTES, XDR_ENCODE);
206*0e91b739SMarcel Telka 	startpos = XDR_GETPOS(&xdrm);
207*0e91b739SMarcel Telka 	if (!xdr_authkern(&xdrm, cr)) {
2087c478bd9Sstevel@tonic-gate 		printf("authkern_marshal: xdr_authkern failed\n");
2097c478bd9Sstevel@tonic-gate 		ret = FALSE;
2107c478bd9Sstevel@tonic-gate 		goto done;
2117c478bd9Sstevel@tonic-gate 	}
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate 	/*
214*0e91b739SMarcel Telka 	 * Make opaque auth credentials to point at the serialized auth body
215*0e91b739SMarcel Telka 	 * data.
2167c478bd9Sstevel@tonic-gate 	 */
217*0e91b739SMarcel Telka 	auth->ah_cred.oa_base = sercred;
218*0e91b739SMarcel Telka 	auth->ah_cred.oa_length = XDR_GETPOS(&xdrm) - startpos;
219*0e91b739SMarcel Telka 	ASSERT(auth->ah_cred.oa_length <= MAX_AUTH_BYTES);
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate 	/*
222*0e91b739SMarcel Telka 	 * serialize credentials and verifier (null)
2237c478bd9Sstevel@tonic-gate 	 */
2247c478bd9Sstevel@tonic-gate 	if ((xdr_opaque_auth(xdrs, &(auth->ah_cred))) &&
2257c478bd9Sstevel@tonic-gate 	    (xdr_opaque_auth(xdrs, &(auth->ah_verf))))
2267c478bd9Sstevel@tonic-gate 		ret = TRUE;
2277c478bd9Sstevel@tonic-gate 	else
2287c478bd9Sstevel@tonic-gate 		ret = FALSE;
229*0e91b739SMarcel Telka 
2307c478bd9Sstevel@tonic-gate done:
231*0e91b739SMarcel Telka 	XDR_DESTROY(&xdrm);
2327c478bd9Sstevel@tonic-gate 	kmem_free(sercred, MAX_AUTH_BYTES);
233*0e91b739SMarcel Telka 
2347c478bd9Sstevel@tonic-gate 	return (ret);
2357c478bd9Sstevel@tonic-gate }
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate /* ARGSUSED */
2387c478bd9Sstevel@tonic-gate static bool_t
2397c478bd9Sstevel@tonic-gate authkern_validate(AUTH *auth, struct opaque_auth *verf)
2407c478bd9Sstevel@tonic-gate {
2417c478bd9Sstevel@tonic-gate 	return (TRUE);
2427c478bd9Sstevel@tonic-gate }
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate /* ARGSUSED */
2457c478bd9Sstevel@tonic-gate static bool_t
2467c478bd9Sstevel@tonic-gate authkern_refresh(AUTH *auth, struct rpc_msg *msg, cred_t *cr)
2477c478bd9Sstevel@tonic-gate {
2487c478bd9Sstevel@tonic-gate 	return (FALSE);
2497c478bd9Sstevel@tonic-gate }
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate static void
2527c478bd9Sstevel@tonic-gate authkern_destroy(AUTH *auth)
2537c478bd9Sstevel@tonic-gate {
2547c478bd9Sstevel@tonic-gate 	kmem_cache_free(authkern_cache, auth);
2557c478bd9Sstevel@tonic-gate }
256