xref: /onnv-gate/usr/src/uts/common/rpc/sec/sec_svc.c (revision 6786:8978aafca942)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*6786Srmesta  * Common Development and Distribution License (the "License").
6*6786Srmesta  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*6786Srmesta  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  *  sec_svc.c, Server-side rpc security interface.
300Sstevel@tonic-gate  */
310Sstevel@tonic-gate #ifdef _KERNEL
320Sstevel@tonic-gate #include <sys/param.h>
330Sstevel@tonic-gate #include <sys/types.h>
340Sstevel@tonic-gate #include <sys/debug.h>
350Sstevel@tonic-gate #include <sys/systm.h>
360Sstevel@tonic-gate #include <rpc/types.h>
370Sstevel@tonic-gate #include <netinet/in.h>
380Sstevel@tonic-gate #include <rpc/xdr.h>
390Sstevel@tonic-gate #include <rpc/auth.h>
400Sstevel@tonic-gate #include <rpc/clnt.h>
410Sstevel@tonic-gate #include <rpc/rpc_msg.h>
420Sstevel@tonic-gate #include <sys/tiuser.h>
430Sstevel@tonic-gate #include <sys/tihdr.h>
440Sstevel@tonic-gate #include <sys/t_kuser.h>
450Sstevel@tonic-gate #include <sys/cmn_err.h>
460Sstevel@tonic-gate #include <rpc/auth_des.h>
470Sstevel@tonic-gate #include <rpc/auth_sys.h>
480Sstevel@tonic-gate #include <rpc/rpcsec_gss.h>
490Sstevel@tonic-gate #include <rpc/svc_auth.h>
500Sstevel@tonic-gate #include <rpc/svc.h>
510Sstevel@tonic-gate #else
520Sstevel@tonic-gate #include <rpc/rpc.h>
530Sstevel@tonic-gate #endif
540Sstevel@tonic-gate 
550Sstevel@tonic-gate 
560Sstevel@tonic-gate enum auth_stat _svcauth_null(struct svc_req *, struct rpc_msg *);
570Sstevel@tonic-gate 
580Sstevel@tonic-gate /*
590Sstevel@tonic-gate  *  NO-OP server wrap/unwrap svc_authany_ops using no-op svc_authany_wrap().
600Sstevel@tonic-gate  */
610Sstevel@tonic-gate /* ARGSUSED */
620Sstevel@tonic-gate static int
svc_authany_wrap(SVCAUTH * auth,XDR * xdrs,xdrproc_t xfunc,caddr_t xwhere)630Sstevel@tonic-gate svc_authany_wrap(SVCAUTH *auth, XDR *xdrs, xdrproc_t xfunc, caddr_t xwhere)
640Sstevel@tonic-gate {
650Sstevel@tonic-gate 	return (*xfunc)(xdrs, xwhere);
660Sstevel@tonic-gate }
670Sstevel@tonic-gate 
680Sstevel@tonic-gate struct svc_auth_ops svc_authany_ops = {
690Sstevel@tonic-gate 	svc_authany_wrap,
700Sstevel@tonic-gate 	svc_authany_wrap
710Sstevel@tonic-gate };
720Sstevel@tonic-gate 
730Sstevel@tonic-gate 
740Sstevel@tonic-gate /*
750Sstevel@tonic-gate  * The call rpc message, msg has been obtained from the wire.  The msg contains
760Sstevel@tonic-gate  * the raw form of credentials and verifiers.  authenticate returns AUTH_OK
770Sstevel@tonic-gate  * if the msg is successfully authenticated.  If AUTH_OK then the routine also
780Sstevel@tonic-gate  * does the following things:
790Sstevel@tonic-gate  * set rqst->rq_xprt->verf to the appropriate response verifier;
800Sstevel@tonic-gate  * sets rqst->rq_client_cred to the "cooked" form of the credentials.
810Sstevel@tonic-gate  *
820Sstevel@tonic-gate  * NB: rqst->rq_cxprt->verf must be pre-alloctaed;
830Sstevel@tonic-gate  * its length is set appropriately.
840Sstevel@tonic-gate  *
850Sstevel@tonic-gate  * The caller still owns and is responsible for msg->u.cmb.cred and
860Sstevel@tonic-gate  * msg->u.cmb.verf.  The authentication system retains ownership of
870Sstevel@tonic-gate  * rqst->rq_client_cred, the cooked credentials.
880Sstevel@tonic-gate  *
890Sstevel@tonic-gate  * There is an assumption that any flavor less than AUTH_NULL is
900Sstevel@tonic-gate  * invalid.
910Sstevel@tonic-gate  */
920Sstevel@tonic-gate enum auth_stat
sec_svc_msg(struct svc_req * rqst,struct rpc_msg * msg,bool_t * no_dispatch)930Sstevel@tonic-gate sec_svc_msg(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch)
940Sstevel@tonic-gate {
950Sstevel@tonic-gate 	int cred_flavor;
960Sstevel@tonic-gate 
970Sstevel@tonic-gate 	rqst->rq_cred = msg->rm_call.cb_cred;
980Sstevel@tonic-gate 	rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
990Sstevel@tonic-gate 	rqst->rq_xprt->xp_verf.oa_length = 0;
1000Sstevel@tonic-gate 	/*
1010Sstevel@tonic-gate 	 * Init the xp_auth to be no-op for all the flavors.
1020Sstevel@tonic-gate 	 * Flavor specific routines will revise this when appropriate.
1030Sstevel@tonic-gate 	 */
1040Sstevel@tonic-gate 	rqst->rq_xprt->xp_auth.svc_ah_ops = svc_authany_ops;
1050Sstevel@tonic-gate 	rqst->rq_xprt->xp_auth.svc_ah_private = NULL;
1060Sstevel@tonic-gate 	*no_dispatch = FALSE;
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate 	cred_flavor = rqst->rq_cred.oa_flavor;
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate 	switch (cred_flavor) {
1110Sstevel@tonic-gate 	case AUTH_NULL:
1120Sstevel@tonic-gate 		rqst->rq_xprt->xp_cookie = (void *) AUTH_NULL;
1130Sstevel@tonic-gate 		return (_svcauth_null(rqst, msg));
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate 	case AUTH_UNIX:
1160Sstevel@tonic-gate 		rqst->rq_xprt->xp_cookie = (void *) AUTH_UNIX;
1170Sstevel@tonic-gate 		return (_svcauth_unix(rqst, msg));
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate 	case AUTH_SHORT:
1200Sstevel@tonic-gate 		rqst->rq_xprt->xp_cookie = (void *) AUTH_SHORT;
1210Sstevel@tonic-gate 		return (_svcauth_short(rqst, msg));
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 	case AUTH_DES:
1240Sstevel@tonic-gate 		rqst->rq_xprt->xp_cookie = (void *) AUTH_DES;
1250Sstevel@tonic-gate 		return (_svcauth_des(rqst, msg));
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate 	case RPCSEC_GSS:
1280Sstevel@tonic-gate 		/*
1290Sstevel@tonic-gate 		 * RPCSEC_GSS flavor routine takes an additional
1300Sstevel@tonic-gate 		 * boolean parameter that gets set to TRUE when
1310Sstevel@tonic-gate 		 * the call is not to be dispatched to the server.
1320Sstevel@tonic-gate 		 */
1330Sstevel@tonic-gate 		return (__svcrpcsec_gss(rqst, msg, no_dispatch));
1340Sstevel@tonic-gate 	}
1350Sstevel@tonic-gate 	return (AUTH_REJECTEDCRED);
1360Sstevel@tonic-gate }
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate /*
1390Sstevel@tonic-gate  *  sec_svc_getcred() gets unix cred of incoming security rpc requests.
1400Sstevel@tonic-gate  *  It also returns the prinicipal name and a cookie which is application
1410Sstevel@tonic-gate  *  dependent e.g. for nfs, it is the pseudo flavor.
1420Sstevel@tonic-gate  *
1430Sstevel@tonic-gate  *  return 0 on failure
1440Sstevel@tonic-gate  */
1450Sstevel@tonic-gate int
sec_svc_getcred(struct svc_req * req,cred_t * cr,caddr_t * principal,int * secmod)1460Sstevel@tonic-gate sec_svc_getcred(struct svc_req *req, cred_t *cr, caddr_t *principal,
1470Sstevel@tonic-gate 	int *secmod)
1480Sstevel@tonic-gate {
1490Sstevel@tonic-gate 	struct authunix_parms *aup;
1500Sstevel@tonic-gate 	struct authdes_cred *adc;
1510Sstevel@tonic-gate 	int flavor, stat;
1520Sstevel@tonic-gate 	rpc_gss_rawcred_t *rcred;
1530Sstevel@tonic-gate 	rpc_gss_ucred_t	*ucred;
1540Sstevel@tonic-gate 	void *cookie;
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 	stat = 1;
1570Sstevel@tonic-gate 	flavor = req->rq_cred.oa_flavor;
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate 	*principal = NULL;
1600Sstevel@tonic-gate 	switch (flavor) {
1610Sstevel@tonic-gate 	case AUTH_UNIX:
1620Sstevel@tonic-gate 		*secmod = AUTH_UNIX;
1630Sstevel@tonic-gate 		aup = (struct authunix_parms *)req->rq_clntcred;
164*6786Srmesta 		if (crsetugid(cr, aup->aup_uid, aup->aup_gid) != 0)
165*6786Srmesta 			(void) crsetugid(cr, UID_NOBODY, GID_NOBODY);
166*6786Srmesta 		if (crsetgroups(cr, aup->aup_len, aup->aup_gids) != 0)
167*6786Srmesta 			(void) crsetgroups(cr, 0, NULL);
1680Sstevel@tonic-gate 		break;
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate 	case AUTH_NONE:
1710Sstevel@tonic-gate 		*secmod = AUTH_NONE;
1720Sstevel@tonic-gate 		break;
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate 	case AUTH_DES:
1750Sstevel@tonic-gate 		*secmod = AUTH_DES;
1760Sstevel@tonic-gate 		adc = (struct authdes_cred *)req->rq_clntcred;
1770Sstevel@tonic-gate 		stat = kauthdes_getucred(adc, cr);
1780Sstevel@tonic-gate 		*principal = adc->adc_fullname.name;
1790Sstevel@tonic-gate 		break;
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate 	case RPCSEC_GSS:
1820Sstevel@tonic-gate 		stat = rpc_gss_getcred(req, &rcred, &ucred, &cookie);
1830Sstevel@tonic-gate 		*secmod = (int)(uintptr_t)cookie;	/* XX64 */
1840Sstevel@tonic-gate 		if (ucred != NULL) {
1850Sstevel@tonic-gate 			if (crsetugid(cr, ucred->uid, ucred->gid) != 0 ||
1860Sstevel@tonic-gate 			    crsetgroups(cr, ucred->gidlen, ucred->gidlist) != 0)
1870Sstevel@tonic-gate 				stat = 0;
1880Sstevel@tonic-gate 		} else {
1890Sstevel@tonic-gate 			(void) crsetugid(cr, UID_NOBODY, GID_NOBODY);
1900Sstevel@tonic-gate 			(void) crsetgroups(cr, 0, NULL);
1910Sstevel@tonic-gate 		}
1920Sstevel@tonic-gate 		*principal = (caddr_t)rcred->client_principal;
1930Sstevel@tonic-gate 		break;
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate 	default:
1960Sstevel@tonic-gate 		stat = 0;
1970Sstevel@tonic-gate 		break;
1980Sstevel@tonic-gate 	}
1990Sstevel@tonic-gate 
2000Sstevel@tonic-gate 	return (stat);
2010Sstevel@tonic-gate }
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate 
2040Sstevel@tonic-gate /* ARGSUSED */
2050Sstevel@tonic-gate enum auth_stat
_svcauth_null(struct svc_req * rqst,struct rpc_msg * msg)2060Sstevel@tonic-gate _svcauth_null(struct svc_req *rqst, struct rpc_msg *msg)
2070Sstevel@tonic-gate {
2080Sstevel@tonic-gate 	return (AUTH_OK);
2090Sstevel@tonic-gate }
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate /*
2130Sstevel@tonic-gate  *  Load root principal names from user space to kernel space.
2140Sstevel@tonic-gate  *
2150Sstevel@tonic-gate  *  flavor - security flavor
2160Sstevel@tonic-gate  *  count - number of principal names to be loaded
2170Sstevel@tonic-gate  *  proots - address of the array of root names.
2180Sstevel@tonic-gate  *		input is the array address in the user space,
2190Sstevel@tonic-gate  *		output is the kernel address.
2200Sstevel@tonic-gate  *
2210Sstevel@tonic-gate  *  return 0 on failure.
2220Sstevel@tonic-gate  */
2230Sstevel@tonic-gate int
sec_svc_loadrootnames(int flavor,int count,caddr_t ** proots,model_t model)2240Sstevel@tonic-gate sec_svc_loadrootnames(int flavor, int count, caddr_t **proots, model_t model)
2250Sstevel@tonic-gate {
2260Sstevel@tonic-gate 	caddr_t *roots, *oroots, root;
2270Sstevel@tonic-gate 	char netname[MAXNETNAMELEN+1];
2280Sstevel@tonic-gate 	struct rpc_gss_principal gsstmp, *gssname;
2290Sstevel@tonic-gate 	uint_t i, j;
2300Sstevel@tonic-gate 	size_t len, allocsz, oallocsz;
2310Sstevel@tonic-gate 
2320Sstevel@tonic-gate #ifdef lint
2330Sstevel@tonic-gate 	model = model;
2340Sstevel@tonic-gate #endif
2350Sstevel@tonic-gate 
2360Sstevel@tonic-gate 	/*
2370Sstevel@tonic-gate 	 * Get list of names from user space
2380Sstevel@tonic-gate 	 */
2390Sstevel@tonic-gate 	allocsz = count * sizeof (caddr_t);
2400Sstevel@tonic-gate 	oallocsz = count * SIZEOF_PTR(model);
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate 	/*
2430Sstevel@tonic-gate 	 * And now copy each individual principal name
2440Sstevel@tonic-gate 	 */
2450Sstevel@tonic-gate 	switch (flavor) {
2460Sstevel@tonic-gate 	case AUTH_DES:
2470Sstevel@tonic-gate 		roots = kmem_zalloc(allocsz, KM_SLEEP);
2480Sstevel@tonic-gate 		oroots = kmem_alloc(oallocsz, KM_SLEEP);
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate 		if (copyin(*proots, oroots, oallocsz))
2510Sstevel@tonic-gate 			goto done;
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
2540Sstevel@tonic-gate 			/*
2550Sstevel@tonic-gate 			 * copyinstr copies the complete string (including the
2560Sstevel@tonic-gate 			 * NULL) and returns the len with the NULL byte
2570Sstevel@tonic-gate 			 * included in the calculation as long as the max
2580Sstevel@tonic-gate 			 * length is not exceeded.
2590Sstevel@tonic-gate 			 */
2600Sstevel@tonic-gate #ifdef _SYSCALL32_IMPL
2610Sstevel@tonic-gate 			if (model != DATAMODEL_NATIVE) {
2620Sstevel@tonic-gate 				caddr32_t *tmp;
2630Sstevel@tonic-gate 
2640Sstevel@tonic-gate 				tmp = (caddr32_t *)oroots;
2650Sstevel@tonic-gate 				root = (caddr_t)(uintptr_t)tmp[i];
2660Sstevel@tonic-gate 			} else
2670Sstevel@tonic-gate #endif
2680Sstevel@tonic-gate 				root = oroots[i];
2690Sstevel@tonic-gate 			if (copyinstr(root, netname, sizeof (netname), &len)) {
2700Sstevel@tonic-gate 				for (j = 0; j < i; j++) {
2710Sstevel@tonic-gate 					if (roots[j] != NULL)
2720Sstevel@tonic-gate 						kmem_free(roots[j],
2730Sstevel@tonic-gate 						    strlen(roots[j]) + 1);
2740Sstevel@tonic-gate 				}
2750Sstevel@tonic-gate 				goto done;
2760Sstevel@tonic-gate 			}
2770Sstevel@tonic-gate 			roots[i] = kmem_alloc(len, KM_SLEEP);
2780Sstevel@tonic-gate 			bcopy(netname, roots[i], len);
2790Sstevel@tonic-gate 		}
2800Sstevel@tonic-gate 		kmem_free(oroots, oallocsz);
2810Sstevel@tonic-gate 		*proots = roots;
2820Sstevel@tonic-gate 		return (1);
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 	case RPCSEC_GSS:
2850Sstevel@tonic-gate 		roots = kmem_alloc(allocsz, KM_SLEEP);
2860Sstevel@tonic-gate 		oroots = kmem_alloc(oallocsz, KM_SLEEP);
2870Sstevel@tonic-gate 
2880Sstevel@tonic-gate 		if (copyin(*proots, oroots, oallocsz))
2890Sstevel@tonic-gate 			goto done;
2900Sstevel@tonic-gate 
2910Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
2920Sstevel@tonic-gate #ifdef _SYSCALL32_IMPL
2930Sstevel@tonic-gate 			if (model != DATAMODEL_NATIVE) {
2940Sstevel@tonic-gate 				caddr32_t *tmp;
2950Sstevel@tonic-gate 
2960Sstevel@tonic-gate 				tmp = (caddr32_t *)oroots;
2970Sstevel@tonic-gate 				root = (caddr_t)(uintptr_t)tmp[i];
2980Sstevel@tonic-gate 			} else
2990Sstevel@tonic-gate #endif
3000Sstevel@tonic-gate 				root = oroots[i];
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate 			if (copyin(root, &gsstmp, sizeof (gsstmp))) {
3030Sstevel@tonic-gate 				kmem_free(oroots, oallocsz);
3040Sstevel@tonic-gate 				goto gssfreeup;
3050Sstevel@tonic-gate 			}
3060Sstevel@tonic-gate 			len = sizeof (gsstmp.len) + gsstmp.len;
3070Sstevel@tonic-gate 			gssname = kmem_alloc(len, KM_SLEEP);
3080Sstevel@tonic-gate 			if (copyin(root, gssname, len)) {
3090Sstevel@tonic-gate 				kmem_free(gssname, len);
3100Sstevel@tonic-gate 				kmem_free(oroots, oallocsz);
3110Sstevel@tonic-gate 				goto gssfreeup;
3120Sstevel@tonic-gate 			}
3130Sstevel@tonic-gate 			roots[i] = (caddr_t)gssname;
3140Sstevel@tonic-gate 		}
3150Sstevel@tonic-gate 		kmem_free(oroots, oallocsz);
3160Sstevel@tonic-gate 		*proots = roots;
3170Sstevel@tonic-gate 		return (1);
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate 	default:
3200Sstevel@tonic-gate 		return (0);
3210Sstevel@tonic-gate 	}
3220Sstevel@tonic-gate 
3230Sstevel@tonic-gate gssfreeup:
3240Sstevel@tonic-gate 	for (j = 0; j < i; j++) {
3250Sstevel@tonic-gate 		if (roots[j] != NULL) {
3260Sstevel@tonic-gate 			gssname = (rpc_gss_principal_t)roots[j];
3270Sstevel@tonic-gate 			kmem_free(roots[j], gssname->len +
3280Sstevel@tonic-gate 			    sizeof (gssname->len));
3290Sstevel@tonic-gate 		}
3300Sstevel@tonic-gate 	}
3310Sstevel@tonic-gate done:
3320Sstevel@tonic-gate 	kmem_free(roots, allocsz);
3330Sstevel@tonic-gate 	return (0);
3340Sstevel@tonic-gate }
3350Sstevel@tonic-gate 
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate /*
3380Sstevel@tonic-gate  * Figure out everything we allocated in a root principal name list in
3390Sstevel@tonic-gate  * order to free it up.
3400Sstevel@tonic-gate  */
3410Sstevel@tonic-gate void
sec_svc_freerootnames(int flavor,int count,caddr_t * proots)3420Sstevel@tonic-gate sec_svc_freerootnames(int flavor, int count, caddr_t *proots)
3430Sstevel@tonic-gate {
3440Sstevel@tonic-gate 	int i;
3450Sstevel@tonic-gate 	rpc_gss_principal_t gssname;
3460Sstevel@tonic-gate 
3470Sstevel@tonic-gate 	switch (flavor) {
3480Sstevel@tonic-gate 	case AUTH_DES:
3490Sstevel@tonic-gate 		for (i = 0; i < count; i++)
3500Sstevel@tonic-gate 			if (proots[i] != NULL)
3510Sstevel@tonic-gate 				kmem_free(proots[i], strlen(proots[i]) + 1);
3520Sstevel@tonic-gate 		break;
3530Sstevel@tonic-gate 
3540Sstevel@tonic-gate 	case RPCSEC_GSS:
3550Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
3560Sstevel@tonic-gate 			if (proots[i] == NULL)
3570Sstevel@tonic-gate 				continue;
3580Sstevel@tonic-gate 			gssname = (rpc_gss_principal_t)proots[i];
3590Sstevel@tonic-gate 			kmem_free(proots[i], gssname->len + sizeof (int));
3600Sstevel@tonic-gate 		}
3610Sstevel@tonic-gate 		break;
3620Sstevel@tonic-gate 
3630Sstevel@tonic-gate 	}
3640Sstevel@tonic-gate 	kmem_free(proots, count * sizeof (caddr_t));
3650Sstevel@tonic-gate }
3660Sstevel@tonic-gate 
3670Sstevel@tonic-gate /*
3680Sstevel@tonic-gate  * Check if the  given principal name is in the root principal list
3690Sstevel@tonic-gate  */
3700Sstevel@tonic-gate bool_t
sec_svc_inrootlist(int flavor,caddr_t rootname,int count,caddr_t * roots)3710Sstevel@tonic-gate sec_svc_inrootlist(int flavor, caddr_t rootname, int count, caddr_t *roots)
3720Sstevel@tonic-gate {
3730Sstevel@tonic-gate 	int i, tmp_len;
3740Sstevel@tonic-gate 	rpc_gss_principal_t gssp, tmp_gssp;
3750Sstevel@tonic-gate 	size_t namelen;
3760Sstevel@tonic-gate 
3770Sstevel@tonic-gate 	switch (flavor) {
3780Sstevel@tonic-gate 	case AUTH_DES:
3790Sstevel@tonic-gate 		namelen = strlen(rootname) + 1;
3800Sstevel@tonic-gate 		for (i = 0; i < count; i++)
3810Sstevel@tonic-gate 			if (bcmp(rootname, roots[i], namelen) == 0)
3820Sstevel@tonic-gate 				return (TRUE);
3830Sstevel@tonic-gate 		break;
3840Sstevel@tonic-gate 
3850Sstevel@tonic-gate 	case RPCSEC_GSS:
3860Sstevel@tonic-gate 		gssp = (rpc_gss_principal_t)rootname;
3870Sstevel@tonic-gate 		namelen = gssp->len;
3880Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
3890Sstevel@tonic-gate 			tmp_gssp = (rpc_gss_principal_t)roots[i];
3900Sstevel@tonic-gate 			tmp_len = tmp_gssp->len;
3910Sstevel@tonic-gate 			if ((namelen == tmp_len) &&
3920Sstevel@tonic-gate 			    (bcmp(&gssp->name[0],
3930Sstevel@tonic-gate 			    &tmp_gssp->name[0], namelen) == 0))
3940Sstevel@tonic-gate 				return (TRUE);
3950Sstevel@tonic-gate 		}
3960Sstevel@tonic-gate 		break;
3970Sstevel@tonic-gate 	}
3980Sstevel@tonic-gate 	return (FALSE);
3990Sstevel@tonic-gate }
4000Sstevel@tonic-gate 
4010Sstevel@tonic-gate /*
4020Sstevel@tonic-gate  * Miscellaneout "control" functions manipulating global RPC security
4030Sstevel@tonic-gate  * attributes for server applications.
4040Sstevel@tonic-gate  */
4050Sstevel@tonic-gate bool_t
sec_svc_control(uint_t cmd,void * argp)4060Sstevel@tonic-gate sec_svc_control(uint_t cmd, void *argp)
4070Sstevel@tonic-gate {
4080Sstevel@tonic-gate 	bool_t result = FALSE;		/* be paranoid */
4090Sstevel@tonic-gate 
4100Sstevel@tonic-gate 	switch (cmd) {
4110Sstevel@tonic-gate 	case RPC_SVC_SET_GSS_CALLBACK:
4120Sstevel@tonic-gate 		result = rpc_gss_set_callback((rpc_gss_callback_t *)argp);
4130Sstevel@tonic-gate 		break;
4140Sstevel@tonic-gate 	default:
4150Sstevel@tonic-gate 		cmn_err(CE_WARN, "sec_svc_control: bad command (%d)", cmd);
4160Sstevel@tonic-gate 		result = FALSE;
4170Sstevel@tonic-gate 		break;
4180Sstevel@tonic-gate 	}
4190Sstevel@tonic-gate 
4200Sstevel@tonic-gate 	return (result);
4210Sstevel@tonic-gate }
422