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
5ba7b222eSGlenn Barry  * Common Development and Distribution License (the "License").
6ba7b222eSGlenn Barry  * 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 /*
22ba7b222eSGlenn Barry  * 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 /*
277c478bd9Sstevel@tonic-gate  *  GSSAPI library stub module for gssd.
287c478bd9Sstevel@tonic-gate  */
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include <stdio.h>
317c478bd9Sstevel@tonic-gate #include <stdlib.h>
327c478bd9Sstevel@tonic-gate #include <mechglueP.h>
337c478bd9Sstevel@tonic-gate #include "gssd.h"
347c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate #ifdef	_KERNEL
377c478bd9Sstevel@tonic-gate #define	MALLOC(n) kmem_alloc((n), KM_SLEEP)
387c478bd9Sstevel@tonic-gate #define	FREE(x, n) kmem_free((x), (n))
397c478bd9Sstevel@tonic-gate #define	memcpy(dst, src, n) bcopy((src), (dst), (n))
407c478bd9Sstevel@tonic-gate #define	clnt_pcreateerror(srv) printf("Cannot connect to server on %s\n", srv)
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate #ifdef	DEBUG
437c478bd9Sstevel@tonic-gate #ifndef	_SYS_CMN_ERR_H
447c478bd9Sstevel@tonic-gate #define	_SYS_CMN_ERR_H
457c478bd9Sstevel@tonic-gate #define	CE_NOTE 1
467c478bd9Sstevel@tonic-gate #endif
477c478bd9Sstevel@tonic-gate #include <sys/types.h>
487c478bd9Sstevel@tonic-gate #include <sys/devops.h>
497c478bd9Sstevel@tonic-gate #include <sys/open.h>
507c478bd9Sstevel@tonic-gate #include <sys/stat.h>
517c478bd9Sstevel@tonic-gate #include <sys/conf.h>
527c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
537c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
547c478bd9Sstevel@tonic-gate #include <sys/uio.h>
557c478bd9Sstevel@tonic-gate #endif /* DEBUG */
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate #else /* !_KERNEL */
587c478bd9Sstevel@tonic-gate #define	MALLOC(n) malloc(n)
597c478bd9Sstevel@tonic-gate #define	FREE(x, n) free(x)
607c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
617c478bd9Sstevel@tonic-gate #define	DEFAULT_MINOR_STAT	((OM_uint32) ~0)
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate CLIENT  *clnt, *getgssd_handle();
647c478bd9Sstevel@tonic-gate char *server = "localhost";
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate OM_uint32
kgss_acquire_cred_wrapped(minor_status,desired_name,time_req,desired_mechs,cred_usage,output_cred_handle,actual_mechs,time_rec,uid,gssd_cred_verifier)677c478bd9Sstevel@tonic-gate kgss_acquire_cred_wrapped(minor_status,
687c478bd9Sstevel@tonic-gate 			desired_name,
697c478bd9Sstevel@tonic-gate 			time_req,
707c478bd9Sstevel@tonic-gate 			desired_mechs,
717c478bd9Sstevel@tonic-gate 			cred_usage,
727c478bd9Sstevel@tonic-gate 			output_cred_handle,
737c478bd9Sstevel@tonic-gate 			actual_mechs,
747c478bd9Sstevel@tonic-gate 			time_rec,
757c478bd9Sstevel@tonic-gate 			uid,
767c478bd9Sstevel@tonic-gate 			gssd_cred_verifier)
777c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
787c478bd9Sstevel@tonic-gate 	gss_name_t desired_name;
797c478bd9Sstevel@tonic-gate 	OM_uint32 time_req;
807c478bd9Sstevel@tonic-gate 	gss_OID_set desired_mechs;
817c478bd9Sstevel@tonic-gate 	int cred_usage;
827c478bd9Sstevel@tonic-gate 	gssd_cred_id_t *output_cred_handle;
837c478bd9Sstevel@tonic-gate 	gss_OID_set *actual_mechs;
847c478bd9Sstevel@tonic-gate 	OM_uint32 *time_rec;
857c478bd9Sstevel@tonic-gate 	uid_t uid;
867c478bd9Sstevel@tonic-gate 	OM_uint32 *gssd_cred_verifier;
877c478bd9Sstevel@tonic-gate {
887c478bd9Sstevel@tonic-gate 	OM_uint32 minor_status_temp;
897c478bd9Sstevel@tonic-gate 	gss_buffer_desc	external_name;
907c478bd9Sstevel@tonic-gate 	gss_OID name_type;
917c478bd9Sstevel@tonic-gate 	int i;
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate 	gss_acquire_cred_arg arg;
947c478bd9Sstevel@tonic-gate 	gss_acquire_cred_res res;
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate 	/* get the client handle to GSSD */
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
997c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
1007c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
1017c478bd9Sstevel@tonic-gate 	}
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate 	/* convert the desired name from internal to external format */
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate 	if (gss_display_name(&minor_status_temp, desired_name, &external_name,
1067c478bd9Sstevel@tonic-gate 				&name_type) != GSS_S_COMPLETE) {
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate 			*minor_status = (OM_uint32) minor_status_temp;
1097c478bd9Sstevel@tonic-gate 			gss_release_buffer(&minor_status_temp, &external_name);
1107c478bd9Sstevel@tonic-gate 		return ((OM_uint32) GSS_S_FAILURE);
1117c478bd9Sstevel@tonic-gate 	}
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate 	/* copy the procedure arguments into the rpc arg parameter */
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate 	arg.uid = (OM_uint32)uid;
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 	arg.desired_name.GSS_BUFFER_T_len = (uint_t)external_name.length;
1197c478bd9Sstevel@tonic-gate 	arg.desired_name.GSS_BUFFER_T_val = (char *)external_name.value;
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate 	arg.name_type.GSS_OID_len =
1227c478bd9Sstevel@tonic-gate 		name_type == GSS_C_NULL_OID ?
1237c478bd9Sstevel@tonic-gate 			0 : (uint_t)name_type->length;
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate 	arg.name_type.GSS_OID_val =
1267c478bd9Sstevel@tonic-gate 		name_type == GSS_C_NULL_OID ?
1277c478bd9Sstevel@tonic-gate 			(char *)NULL : (char *)name_type->elements;
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 	arg.time_req = time_req;
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 	if (desired_mechs != GSS_C_NULL_OID_SET) {
1327c478bd9Sstevel@tonic-gate 		arg.desired_mechs.GSS_OID_SET_len =
1337c478bd9Sstevel@tonic-gate 			(uint_t)desired_mechs->count;
1347c478bd9Sstevel@tonic-gate 		arg.desired_mechs.GSS_OID_SET_val = (GSS_OID *)
1357c478bd9Sstevel@tonic-gate 			MALLOC(sizeof (GSS_OID) * desired_mechs->count);
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 		for (i = 0; i < desired_mechs->count; i++) {
1387c478bd9Sstevel@tonic-gate 			arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_len =
1397c478bd9Sstevel@tonic-gate 				(uint_t)desired_mechs->elements[i].length;
1407c478bd9Sstevel@tonic-gate 			arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val =
1417c478bd9Sstevel@tonic-gate 				(char *)
1427c478bd9Sstevel@tonic-gate 				MALLOC(desired_mechs->elements[i].length);
1437c478bd9Sstevel@tonic-gate 			memcpy(arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val,
1447c478bd9Sstevel@tonic-gate 				desired_mechs->elements[i].elements,
1457c478bd9Sstevel@tonic-gate 				desired_mechs->elements[i].length);
1467c478bd9Sstevel@tonic-gate 		}
1477c478bd9Sstevel@tonic-gate 	} else
1487c478bd9Sstevel@tonic-gate 		arg.desired_mechs.GSS_OID_SET_len = 0;
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 	arg.cred_usage = cred_usage;
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 	/* call the remote procedure */
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
1557c478bd9Sstevel@tonic-gate 	if (gss_acquire_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate 	/*
1587c478bd9Sstevel@tonic-gate 	 * if the RPC call times out, null out all return arguments,
1597c478bd9Sstevel@tonic-gate 	 * set minor_status to its maximum value, and return GSS_S_FAILURE
1607c478bd9Sstevel@tonic-gate 	 */
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 		if (minor_status != NULL)
163ba7b222eSGlenn Barry 			*minor_status = DEFAULT_MINOR_STAT;
1647c478bd9Sstevel@tonic-gate 		if (output_cred_handle != NULL)
165*0ab8aa70SToomas Soome 			*output_cred_handle = 0;
1667c478bd9Sstevel@tonic-gate 		if (actual_mechs != NULL)
1677c478bd9Sstevel@tonic-gate 			*actual_mechs = NULL;
1687c478bd9Sstevel@tonic-gate 		if (time_rec != NULL)
1697c478bd9Sstevel@tonic-gate 			*time_rec = 0;
1707c478bd9Sstevel@tonic-gate 
1717c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
1727c478bd9Sstevel@tonic-gate 	}
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate 	/* free the allocated memory for the flattened name and desire_mechs */
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate 	gss_release_buffer(&minor_status_temp, &external_name);
1777c478bd9Sstevel@tonic-gate 	for (i = 0; i < desired_mechs->count; i++)
1787c478bd9Sstevel@tonic-gate 		FREE(arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val,
1797c478bd9Sstevel@tonic-gate 			arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_len);
1807c478bd9Sstevel@tonic-gate 	FREE(arg.desired_mechs.GSS_OID_SET_val,
1817c478bd9Sstevel@tonic-gate 		arg.desired_mechs.GSS_OID_SET_len * sizeof (GSS_OID));
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 	/* copy the rpc results into the return arguments */
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate 	if (minor_status != NULL)
1867c478bd9Sstevel@tonic-gate 		*minor_status = res.minor_status;
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate 	if (output_cred_handle != NULL) {
1897c478bd9Sstevel@tonic-gate 		 *output_cred_handle =
1907c478bd9Sstevel@tonic-gate 		/*LINTED*/
1917c478bd9Sstevel@tonic-gate 		*((gssd_cred_id_t *)res.output_cred_handle.GSS_CRED_ID_T_val);
1927c478bd9Sstevel@tonic-gate 		 *gssd_cred_verifier = res.gssd_cred_verifier;
1937c478bd9Sstevel@tonic-gate 	}
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate 	if (res.status == GSS_S_COMPLETE &&
1967c478bd9Sstevel@tonic-gate 		res.actual_mechs.GSS_OID_SET_len != 0 &&
1977c478bd9Sstevel@tonic-gate 		actual_mechs != NULL) {
1987c478bd9Sstevel@tonic-gate 		*actual_mechs = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
1997c478bd9Sstevel@tonic-gate 		(*actual_mechs)->count =
2007c478bd9Sstevel@tonic-gate 			(int)res.actual_mechs.GSS_OID_SET_len;
2017c478bd9Sstevel@tonic-gate 		(*actual_mechs)->elements = (gss_OID)
2027c478bd9Sstevel@tonic-gate 			MALLOC(sizeof (gss_OID_desc) * (*actual_mechs)->count);
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate 		for (i = 0; i < (*actual_mechs)->count; i++) {
2057c478bd9Sstevel@tonic-gate 			(*actual_mechs)->elements[i].length = (OM_uint32)
2067c478bd9Sstevel@tonic-gate 			res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_len;
2077c478bd9Sstevel@tonic-gate 			(*actual_mechs)->elements[i].elements =
2087c478bd9Sstevel@tonic-gate 			(void *) MALLOC((*actual_mechs)->elements[i].length);
2097c478bd9Sstevel@tonic-gate 			memcpy((*actual_mechs)->elements[i].elements,
2107c478bd9Sstevel@tonic-gate 			res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_val,
2117c478bd9Sstevel@tonic-gate 			(*actual_mechs)->elements[i].length);
2127c478bd9Sstevel@tonic-gate 		}
2137c478bd9Sstevel@tonic-gate 	} else {
2147c478bd9Sstevel@tonic-gate 		if (res.status == GSS_S_COMPLETE && actual_mechs != NULL)
2157c478bd9Sstevel@tonic-gate 			(*actual_mechs)->count = 0;
2167c478bd9Sstevel@tonic-gate 	}
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 	if (time_rec != NULL)
2197c478bd9Sstevel@tonic-gate 		*time_rec = res.time_rec;
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate 	/*
2227c478bd9Sstevel@tonic-gate 	 * free the memory allocated for the results and return with the status
2237c478bd9Sstevel@tonic-gate 	 * received in the rpc call
2247c478bd9Sstevel@tonic-gate 	 */
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate 	clnt_freeres(clnt, xdr_gss_acquire_cred_res, (caddr_t)&res);
2277c478bd9Sstevel@tonic-gate 	return (res.status);
2287c478bd9Sstevel@tonic-gate }
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate OM_uint32
kgss_acquire_cred(minor_status,desired_name,time_req,desired_mechs,cred_usage,output_cred_handle,actual_mechs,time_rec,uid)2317c478bd9Sstevel@tonic-gate kgss_acquire_cred(minor_status,
2327c478bd9Sstevel@tonic-gate 		desired_name,
2337c478bd9Sstevel@tonic-gate 		time_req,
2347c478bd9Sstevel@tonic-gate 		desired_mechs,
2357c478bd9Sstevel@tonic-gate 		cred_usage,
2367c478bd9Sstevel@tonic-gate 		output_cred_handle,
2377c478bd9Sstevel@tonic-gate 		actual_mechs,
2387c478bd9Sstevel@tonic-gate 		time_rec,
2397c478bd9Sstevel@tonic-gate 		uid)
2407c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
2417c478bd9Sstevel@tonic-gate 	gss_name_t desired_name;
2427c478bd9Sstevel@tonic-gate 	OM_uint32 time_req;
2437c478bd9Sstevel@tonic-gate 	gss_OID_set desired_mechs;
2447c478bd9Sstevel@tonic-gate 	int cred_usage;
2457c478bd9Sstevel@tonic-gate 	gss_cred_id_t *output_cred_handle;
2467c478bd9Sstevel@tonic-gate 	gss_OID_set *actual_mechs;
2477c478bd9Sstevel@tonic-gate 	OM_uint32 *time_rec;
2487c478bd9Sstevel@tonic-gate 	uid_t uid;
2497c478bd9Sstevel@tonic-gate {
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 		OM_uint32	err;
2527c478bd9Sstevel@tonic-gate 		struct kgss_cred *kcred;
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 		kcred = KGSS_CRED_ALLOC();
2557c478bd9Sstevel@tonic-gate 		*output_cred_handle = (gss_cred_id_t)kcred;
2567c478bd9Sstevel@tonic-gate 		err = kgss_acquire_cred_wrapped(minor_status,
2577c478bd9Sstevel@tonic-gate 					desired_name, time_req,
2587c478bd9Sstevel@tonic-gate 					desired_mechs, cred_usage,
2597c478bd9Sstevel@tonic-gate 					&kcred->gssd_cred, actual_mechs,
2607c478bd9Sstevel@tonic-gate 					time_rec, uid,
2617c478bd9Sstevel@tonic-gate 					&kcred->gssd_cred_verifier);
2627c478bd9Sstevel@tonic-gate 		if (GSS_ERROR(err)) {
2637c478bd9Sstevel@tonic-gate 			KGSS_CRED_FREE(kcred);
2647c478bd9Sstevel@tonic-gate 			*output_cred_handle = GSS_C_NO_CREDENTIAL;
2657c478bd9Sstevel@tonic-gate 		}
2667c478bd9Sstevel@tonic-gate 		return (err);
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate OM_uint32
kgss_add_cred_wrapped(minor_status,input_cred_handle,gssd_cred_verifier,desired_name,desired_mech_type,cred_usage,initiator_time_req,acceptor_time_req,actual_mechs,initiator_time_rec,acceptor_time_rec,uid)2707c478bd9Sstevel@tonic-gate kgss_add_cred_wrapped(minor_status,
2717c478bd9Sstevel@tonic-gate 			input_cred_handle,
2727c478bd9Sstevel@tonic-gate 			gssd_cred_verifier,
2737c478bd9Sstevel@tonic-gate 			desired_name,
2747c478bd9Sstevel@tonic-gate 			desired_mech_type,
2757c478bd9Sstevel@tonic-gate 			cred_usage,
2767c478bd9Sstevel@tonic-gate 			initiator_time_req,
2777c478bd9Sstevel@tonic-gate 			acceptor_time_req,
2787c478bd9Sstevel@tonic-gate 			actual_mechs,
2797c478bd9Sstevel@tonic-gate 			initiator_time_rec,
2807c478bd9Sstevel@tonic-gate 			acceptor_time_rec,
2817c478bd9Sstevel@tonic-gate 			uid)
2827c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
2837c478bd9Sstevel@tonic-gate 	gssd_cred_id_t input_cred_handle;
2847c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_cred_verifier;
2857c478bd9Sstevel@tonic-gate 	gss_name_t desired_name;
2867c478bd9Sstevel@tonic-gate 	gss_OID desired_mech_type;
2877c478bd9Sstevel@tonic-gate 	int cred_usage;
2887c478bd9Sstevel@tonic-gate 	int initiator_time_req;
2897c478bd9Sstevel@tonic-gate 	int acceptor_time_req;
2907c478bd9Sstevel@tonic-gate 	gss_OID_set *actual_mechs;
2917c478bd9Sstevel@tonic-gate 	OM_uint32 *initiator_time_rec;
2927c478bd9Sstevel@tonic-gate 	OM_uint32 *acceptor_time_rec;
2937c478bd9Sstevel@tonic-gate 	uid_t uid;
2947c478bd9Sstevel@tonic-gate {
2957c478bd9Sstevel@tonic-gate 	CLIENT *clnt;
2967c478bd9Sstevel@tonic-gate 
297*0ab8aa70SToomas Soome 	OM_uint32	minor_status_temp;
2987c478bd9Sstevel@tonic-gate 	gss_buffer_desc	external_name;
2997c478bd9Sstevel@tonic-gate 	gss_OID		name_type;
3007c478bd9Sstevel@tonic-gate 	int		i;
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 	gss_add_cred_arg arg;
3037c478bd9Sstevel@tonic-gate 	gss_add_cred_res res;
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate 	/* get the client handle to GSSD */
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
3087c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
3097c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
3107c478bd9Sstevel@tonic-gate 	}
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate 	/* convert the desired name from internal to external format */
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	if (gss_display_name(&minor_status_temp, desired_name, &external_name,
3167c478bd9Sstevel@tonic-gate 				&name_type) != GSS_S_COMPLETE) {
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 		*minor_status = (OM_uint32) minor_status_temp;
3197c478bd9Sstevel@tonic-gate 		(void) gss_release_buffer(&minor_status_temp, &external_name);
3207c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
3217c478bd9Sstevel@tonic-gate 		return ((OM_uint32) GSS_S_FAILURE);
3227c478bd9Sstevel@tonic-gate 	}
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 	/* copy the procedure arguments into the rpc arg parameter */
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate 	arg.uid = (OM_uint32) uid;
3287c478bd9Sstevel@tonic-gate 	arg.input_cred_handle.GSS_CRED_ID_T_len =
329d4f95bf4SRichard Lowe 			input_cred_handle == GSSD_NO_CREDENTIAL ?
3307c478bd9Sstevel@tonic-gate 			0 : (uint_t)sizeof (gssd_cred_id_t);
3317c478bd9Sstevel@tonic-gate 	arg.input_cred_handle.GSS_CRED_ID_T_val =
3327c478bd9Sstevel@tonic-gate 						(char *)&input_cred_handle;
3337c478bd9Sstevel@tonic-gate 	arg.gssd_cred_verifier = gssd_cred_verifier;
3347c478bd9Sstevel@tonic-gate 	arg.desired_name.GSS_BUFFER_T_len = (uint_t)external_name.length;
3357c478bd9Sstevel@tonic-gate 	arg.desired_name.GSS_BUFFER_T_val = (char *)external_name.value;
3367c478bd9Sstevel@tonic-gate 	arg.name_type.GSS_OID_len =
3377c478bd9Sstevel@tonic-gate 		name_type == GSS_C_NULL_OID ?
3387c478bd9Sstevel@tonic-gate 			0 : (uint_t)name_type->length;
3397c478bd9Sstevel@tonic-gate 	arg.name_type.GSS_OID_val =
3407c478bd9Sstevel@tonic-gate 		name_type == GSS_C_NULL_OID ?
3417c478bd9Sstevel@tonic-gate 			(char *)NULL : (char *)name_type->elements;
3427c478bd9Sstevel@tonic-gate 
3437c478bd9Sstevel@tonic-gate 	arg.desired_mech_type.GSS_OID_len =
3447c478bd9Sstevel@tonic-gate 		(uint_t)(desired_mech_type != GSS_C_NULL_OID ?
3457c478bd9Sstevel@tonic-gate 		desired_mech_type->length : 0);
3467c478bd9Sstevel@tonic-gate 	arg.desired_mech_type.GSS_OID_val =
3477c478bd9Sstevel@tonic-gate 		(char *)(desired_mech_type != GSS_C_NULL_OID ?
3487c478bd9Sstevel@tonic-gate 		desired_mech_type->elements : 0);
3497c478bd9Sstevel@tonic-gate 	arg.cred_usage = cred_usage;
3507c478bd9Sstevel@tonic-gate 	arg.initiator_time_req = initiator_time_req;
3517c478bd9Sstevel@tonic-gate 	arg.acceptor_time_req = acceptor_time_req;
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate 	/* call the remote procedure */
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate 	bzero((caddr_t)&res, sizeof (res));
3567c478bd9Sstevel@tonic-gate 	if (gss_add_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 		/*
3597c478bd9Sstevel@tonic-gate 		 * if the RPC call times out, null out all return arguments,
3607c478bd9Sstevel@tonic-gate 		 * set minor_status to its maximum value, and return
3617c478bd9Sstevel@tonic-gate 		 * GSS_S_FAILURE
3627c478bd9Sstevel@tonic-gate 		 */
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 		if (minor_status != NULL)
3657c478bd9Sstevel@tonic-gate 			*minor_status = DEFAULT_MINOR_STAT;
3667c478bd9Sstevel@tonic-gate 		if (actual_mechs != NULL)
3677c478bd9Sstevel@tonic-gate 			*actual_mechs = NULL;
3687c478bd9Sstevel@tonic-gate 		if (initiator_time_rec != NULL)
3697c478bd9Sstevel@tonic-gate 			*initiator_time_rec = 0;
3707c478bd9Sstevel@tonic-gate 		if (acceptor_time_rec != NULL)
3717c478bd9Sstevel@tonic-gate 			*acceptor_time_rec = 0;
3727c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
3737c478bd9Sstevel@tonic-gate 	}
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate 	/* free the allocated memory for the flattened name */
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate 	(void) gss_release_buffer(&minor_status_temp, &external_name);
3787c478bd9Sstevel@tonic-gate 
3797c478bd9Sstevel@tonic-gate 	/* copy the rpc results into the return arguments */
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate 	if (minor_status != NULL)
3827c478bd9Sstevel@tonic-gate 		*minor_status = res.minor_status;
3837c478bd9Sstevel@tonic-gate 
3847c478bd9Sstevel@tonic-gate 	if (res.status == GSS_S_COMPLETE &&
3857c478bd9Sstevel@tonic-gate 		res.actual_mechs.GSS_OID_SET_len != 0 &&
3867c478bd9Sstevel@tonic-gate 		actual_mechs != NULL) {
3877c478bd9Sstevel@tonic-gate 		*actual_mechs = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
3887c478bd9Sstevel@tonic-gate 		(*actual_mechs)->count =
3897c478bd9Sstevel@tonic-gate 					(int)res.actual_mechs.GSS_OID_SET_len;
3907c478bd9Sstevel@tonic-gate 		(*actual_mechs)->elements = (gss_OID)
3917c478bd9Sstevel@tonic-gate 			MALLOC(sizeof (gss_OID_desc) * (*actual_mechs)->count);
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 		for (i = 0; i < (*actual_mechs)->count; i++) {
3947c478bd9Sstevel@tonic-gate 		    (*actual_mechs)->elements[i].length = (OM_uint32)
3957c478bd9Sstevel@tonic-gate 			res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_len;
3967c478bd9Sstevel@tonic-gate 		    (*actual_mechs)->elements[i].elements =
3977c478bd9Sstevel@tonic-gate 			(void *) MALLOC((*actual_mechs)->elements[i].length);
3987c478bd9Sstevel@tonic-gate 		    memcpy((*actual_mechs)->elements[i].elements,
3997c478bd9Sstevel@tonic-gate 			res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_val,
4007c478bd9Sstevel@tonic-gate 			(*actual_mechs)->elements[i].length);
4017c478bd9Sstevel@tonic-gate 		}
4027c478bd9Sstevel@tonic-gate 	} else {
4037c478bd9Sstevel@tonic-gate 		if (res.status == GSS_S_COMPLETE &&
4047c478bd9Sstevel@tonic-gate 			actual_mechs != NULL)
4057c478bd9Sstevel@tonic-gate 			(*actual_mechs)->count = 0;
4067c478bd9Sstevel@tonic-gate 	}
4077c478bd9Sstevel@tonic-gate 	if (initiator_time_rec != NULL)
4087c478bd9Sstevel@tonic-gate 		*initiator_time_rec = res.initiator_time_rec;
4097c478bd9Sstevel@tonic-gate 	if (acceptor_time_rec != NULL)
4107c478bd9Sstevel@tonic-gate 		*acceptor_time_rec = res.acceptor_time_rec;
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 	/*
4137c478bd9Sstevel@tonic-gate 	 * free the memory allocated for the results and return with the status
4147c478bd9Sstevel@tonic-gate 	 * received in the rpc call
4157c478bd9Sstevel@tonic-gate 	 */
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate 	clnt_freeres(clnt, xdr_gss_add_cred_res, (caddr_t)&res);
4187c478bd9Sstevel@tonic-gate 	return (res.status);
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate }
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate OM_uint32
kgss_add_cred(minor_status,input_cred_handle,desired_name,desired_mech_type,cred_usage,initiator_time_req,acceptor_time_req,actual_mechs,initiator_time_rec,acceptor_time_rec,uid)4237c478bd9Sstevel@tonic-gate kgss_add_cred(minor_status,
4247c478bd9Sstevel@tonic-gate 			input_cred_handle,
4257c478bd9Sstevel@tonic-gate 			desired_name,
4267c478bd9Sstevel@tonic-gate 			desired_mech_type,
4277c478bd9Sstevel@tonic-gate 			cred_usage,
4287c478bd9Sstevel@tonic-gate 			initiator_time_req,
4297c478bd9Sstevel@tonic-gate 			acceptor_time_req,
4307c478bd9Sstevel@tonic-gate 			actual_mechs,
4317c478bd9Sstevel@tonic-gate 			initiator_time_rec,
4327c478bd9Sstevel@tonic-gate 			acceptor_time_rec,
4337c478bd9Sstevel@tonic-gate 			uid)
4347c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
4357c478bd9Sstevel@tonic-gate 	gss_cred_id_t input_cred_handle;
4367c478bd9Sstevel@tonic-gate 	gss_name_t desired_name;
4377c478bd9Sstevel@tonic-gate 	gss_OID desired_mech_type;
4387c478bd9Sstevel@tonic-gate 	int cred_usage;
4397c478bd9Sstevel@tonic-gate 	int initiator_time_req;
4407c478bd9Sstevel@tonic-gate 	int acceptor_time_req;
4417c478bd9Sstevel@tonic-gate 	gss_OID_set *actual_mechs;
4427c478bd9Sstevel@tonic-gate 	OM_uint32 *initiator_time_rec;
4437c478bd9Sstevel@tonic-gate 	OM_uint32 *acceptor_time_rec;
4447c478bd9Sstevel@tonic-gate 	uid_t uid;
4457c478bd9Sstevel@tonic-gate {
4467c478bd9Sstevel@tonic-gate 
4477c478bd9Sstevel@tonic-gate 	OM_uint32	err;
4487c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_cred_verifier;
4497c478bd9Sstevel@tonic-gate 	gssd_cred_id_t gssd_input_cred_handle;
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate 
4527c478bd9Sstevel@tonic-gate 	if (input_cred_handle != GSS_C_NO_CREDENTIAL) {
4537c478bd9Sstevel@tonic-gate 		gssd_cred_verifier = KCRED_TO_CREDV(input_cred_handle);
4547c478bd9Sstevel@tonic-gate 		gssd_input_cred_handle = KCRED_TO_CRED(input_cred_handle);
4557c478bd9Sstevel@tonic-gate 	} else
456d4f95bf4SRichard Lowe 		gssd_input_cred_handle = GSSD_NO_CREDENTIAL;
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate 	err = kgss_add_cred_wrapped(minor_status, gssd_input_cred_handle,
4597c478bd9Sstevel@tonic-gate 			gssd_cred_verifier, desired_name, desired_mech_type,
4607c478bd9Sstevel@tonic-gate 			cred_usage, initiator_time_req, acceptor_time_req,
4617c478bd9Sstevel@tonic-gate 			actual_mechs, initiator_time_rec,
4627c478bd9Sstevel@tonic-gate 			acceptor_time_rec, uid);
4637c478bd9Sstevel@tonic-gate 	return (err);
4647c478bd9Sstevel@tonic-gate }
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate OM_uint32
kgss_release_cred_wrapped(minor_status,cred_handle,uid,gssd_cred_verifier)4677c478bd9Sstevel@tonic-gate kgss_release_cred_wrapped(minor_status,
4687c478bd9Sstevel@tonic-gate 		cred_handle,
4697c478bd9Sstevel@tonic-gate 		uid,
4707c478bd9Sstevel@tonic-gate 		gssd_cred_verifier)
4717c478bd9Sstevel@tonic-gate OM_uint32 *minor_status;
4727c478bd9Sstevel@tonic-gate gssd_cred_id_t *cred_handle;
4737c478bd9Sstevel@tonic-gate uid_t uid;
4747c478bd9Sstevel@tonic-gate OM_uint32 gssd_cred_verifier;
4757c478bd9Sstevel@tonic-gate {
4767c478bd9Sstevel@tonic-gate 
4777c478bd9Sstevel@tonic-gate 	gss_release_cred_arg arg;
4787c478bd9Sstevel@tonic-gate 	gss_release_cred_res res;
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate 	/* get the client handle to GSSD */
4827c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
4837c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
4847c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
4857c478bd9Sstevel@tonic-gate 	}
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate 	/* copy the procedure arguments into the rpc arg parameter */
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate 	arg.uid = (OM_uint32) uid;
4907c478bd9Sstevel@tonic-gate 	arg.gssd_cred_verifier = gssd_cred_verifier;
4917c478bd9Sstevel@tonic-gate 
4927c478bd9Sstevel@tonic-gate 	if (cred_handle != NULL) {
4937c478bd9Sstevel@tonic-gate 		arg.cred_handle.GSS_CRED_ID_T_len =
4947c478bd9Sstevel@tonic-gate 			(uint_t)sizeof (gssd_cred_id_t);
4957c478bd9Sstevel@tonic-gate 		arg.cred_handle.GSS_CRED_ID_T_val = (char *)cred_handle;
4967c478bd9Sstevel@tonic-gate 	} else
4977c478bd9Sstevel@tonic-gate 		arg.cred_handle.GSS_CRED_ID_T_len = 0;
4987c478bd9Sstevel@tonic-gate 
4997c478bd9Sstevel@tonic-gate 	/* call the remote procedure */
5007c478bd9Sstevel@tonic-gate 
5017c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
5027c478bd9Sstevel@tonic-gate 	if (gss_release_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
5037c478bd9Sstevel@tonic-gate 
5047c478bd9Sstevel@tonic-gate 		/*
5057c478bd9Sstevel@tonic-gate 		 * if the RPC call times out, null out all return arguments,
5067c478bd9Sstevel@tonic-gate 		 * set minor_status to its max value, and return GSS_S_FAILURE
5077c478bd9Sstevel@tonic-gate 		 */
5087c478bd9Sstevel@tonic-gate 
5097c478bd9Sstevel@tonic-gate 		if (minor_status != NULL)
510ba7b222eSGlenn Barry 			*minor_status = DEFAULT_MINOR_STAT;
5117c478bd9Sstevel@tonic-gate 		if (cred_handle != NULL)
512*0ab8aa70SToomas Soome 			*cred_handle = 0;
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
5157c478bd9Sstevel@tonic-gate 	}
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate 	/* if the release succeeded, null out the cred_handle */
5187c478bd9Sstevel@tonic-gate 	if (res.status == GSS_S_COMPLETE && cred_handle != NULL)
519*0ab8aa70SToomas Soome 		*cred_handle = 0;
5207c478bd9Sstevel@tonic-gate 
5217c478bd9Sstevel@tonic-gate 	/* copy the rpc results into the return arguments */
5227c478bd9Sstevel@tonic-gate 	if (minor_status != NULL)
5237c478bd9Sstevel@tonic-gate 		*minor_status = res.minor_status;
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate 	/* return with status returned in rpc call */
5267c478bd9Sstevel@tonic-gate 	return (res.status);
5277c478bd9Sstevel@tonic-gate }
5287c478bd9Sstevel@tonic-gate 
5297c478bd9Sstevel@tonic-gate OM_uint32
kgss_release_cred(minor_status,cred_handle,uid)5307c478bd9Sstevel@tonic-gate kgss_release_cred(minor_status,
5317c478bd9Sstevel@tonic-gate 			cred_handle,
5327c478bd9Sstevel@tonic-gate 			uid)
5337c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
5347c478bd9Sstevel@tonic-gate 	gss_cred_id_t *cred_handle;
5357c478bd9Sstevel@tonic-gate 	uid_t uid;
5367c478bd9Sstevel@tonic-gate 
5377c478bd9Sstevel@tonic-gate {
5387c478bd9Sstevel@tonic-gate 
5397c478bd9Sstevel@tonic-gate 		OM_uint32	err;
5407c478bd9Sstevel@tonic-gate 		struct kgss_cred *kcred;
5417c478bd9Sstevel@tonic-gate 
5427c478bd9Sstevel@tonic-gate 		if (*cred_handle == GSS_C_NO_CREDENTIAL)
5437c478bd9Sstevel@tonic-gate 			return (GSS_S_COMPLETE);
5447c478bd9Sstevel@tonic-gate 		else
5457c478bd9Sstevel@tonic-gate 			kcred = KCRED_TO_KGSS_CRED(*cred_handle);
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate 		err = kgss_release_cred_wrapped(minor_status, &kcred->gssd_cred,
5487c478bd9Sstevel@tonic-gate 			uid, kcred->gssd_cred_verifier);
5497c478bd9Sstevel@tonic-gate 		KGSS_CRED_FREE(kcred);
5507c478bd9Sstevel@tonic-gate 		*cred_handle = GSS_C_NO_CREDENTIAL;
5517c478bd9Sstevel@tonic-gate 		return (err);
5527c478bd9Sstevel@tonic-gate }
5537c478bd9Sstevel@tonic-gate 
5547c478bd9Sstevel@tonic-gate OM_uint32
kgss_init_sec_context_wrapped(minor_status,claimant_cred_handle,gssd_cred_verifier,context_handle,gssd_context_verifier,target_name,mech_type,req_flags,time_req,input_chan_bindings,input_token,actual_mech_type,output_token,ret_flags,time_rec,uid)5557c478bd9Sstevel@tonic-gate kgss_init_sec_context_wrapped(minor_status,
5567c478bd9Sstevel@tonic-gate 			claimant_cred_handle,
5577c478bd9Sstevel@tonic-gate 			gssd_cred_verifier,
5587c478bd9Sstevel@tonic-gate 			context_handle,
5597c478bd9Sstevel@tonic-gate 			gssd_context_verifier,
5607c478bd9Sstevel@tonic-gate 		target_name,
5617c478bd9Sstevel@tonic-gate 		mech_type,
5627c478bd9Sstevel@tonic-gate 		req_flags,
5637c478bd9Sstevel@tonic-gate 		time_req,
5647c478bd9Sstevel@tonic-gate 		input_chan_bindings,
5657c478bd9Sstevel@tonic-gate 		input_token,
5667c478bd9Sstevel@tonic-gate 		actual_mech_type,
5677c478bd9Sstevel@tonic-gate 		output_token,
5687c478bd9Sstevel@tonic-gate 		ret_flags,
5697c478bd9Sstevel@tonic-gate 		time_rec,
5707c478bd9Sstevel@tonic-gate 		uid)
5717c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
5727c478bd9Sstevel@tonic-gate 	gssd_cred_id_t claimant_cred_handle;
5737c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_cred_verifier;
5747c478bd9Sstevel@tonic-gate 	OM_uint32 *context_handle;
5757c478bd9Sstevel@tonic-gate 	OM_uint32 *gssd_context_verifier;
5767c478bd9Sstevel@tonic-gate 	gss_name_t target_name;
5777c478bd9Sstevel@tonic-gate 	gss_OID mech_type;
5787c478bd9Sstevel@tonic-gate 	int req_flags;
5797c478bd9Sstevel@tonic-gate 	OM_uint32 time_req;
5807c478bd9Sstevel@tonic-gate 	gss_channel_bindings_t input_chan_bindings;
5817c478bd9Sstevel@tonic-gate 	gss_buffer_t input_token;
5827c478bd9Sstevel@tonic-gate 	gss_OID *actual_mech_type;
5837c478bd9Sstevel@tonic-gate 	gss_buffer_t output_token;
5847c478bd9Sstevel@tonic-gate 	int *ret_flags;
5857c478bd9Sstevel@tonic-gate 	OM_uint32 *time_rec;
5867c478bd9Sstevel@tonic-gate 	uid_t uid;
5877c478bd9Sstevel@tonic-gate {
5887c478bd9Sstevel@tonic-gate 	OM_uint32 minor_status_temp;
5897c478bd9Sstevel@tonic-gate 	gss_buffer_desc external_name;
5907c478bd9Sstevel@tonic-gate 	gss_OID name_type;
5917c478bd9Sstevel@tonic-gate 	gss_init_sec_context_arg arg;
5927c478bd9Sstevel@tonic-gate 	gss_init_sec_context_res res;
5937c478bd9Sstevel@tonic-gate 
5947c478bd9Sstevel@tonic-gate 	/* get the client handle to GSSD */
5957c478bd9Sstevel@tonic-gate 
5967c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
5977c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
5987c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
5997c478bd9Sstevel@tonic-gate 	}
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 	/* convert the target name from internal to external format */
6027c478bd9Sstevel@tonic-gate 
6037c478bd9Sstevel@tonic-gate 	if (gss_display_name(&minor_status_temp, target_name,
6047c478bd9Sstevel@tonic-gate 			&external_name, &name_type) != GSS_S_COMPLETE) {
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate 		*minor_status = (OM_uint32) minor_status_temp;
6077c478bd9Sstevel@tonic-gate 		return ((OM_uint32) GSS_S_FAILURE);
6087c478bd9Sstevel@tonic-gate 	}
6097c478bd9Sstevel@tonic-gate 
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
6127c478bd9Sstevel@tonic-gate 
6137c478bd9Sstevel@tonic-gate 	arg.uid = (OM_uint32) uid;
6147c478bd9Sstevel@tonic-gate 
6157c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_len =
6167c478bd9Sstevel@tonic-gate 		*context_handle == (OM_uint32) GSS_C_NO_CONTEXT ? 0 :
6177c478bd9Sstevel@tonic-gate 		(uint_t)sizeof (OM_uint32);
6187c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_val =  (char *)context_handle;
6197c478bd9Sstevel@tonic-gate 	arg.gssd_context_verifier = *gssd_context_verifier;
6207c478bd9Sstevel@tonic-gate 
6217c478bd9Sstevel@tonic-gate 	arg.claimant_cred_handle.GSS_CRED_ID_T_len =
622d4f95bf4SRichard Lowe 		claimant_cred_handle == GSSD_NO_CREDENTIAL ?
6237c478bd9Sstevel@tonic-gate 		0 : (uint_t)sizeof (gssd_cred_id_t);
6247c478bd9Sstevel@tonic-gate 	arg.claimant_cred_handle.GSS_CRED_ID_T_val =
6257c478bd9Sstevel@tonic-gate 		(char *)&claimant_cred_handle;
6267c478bd9Sstevel@tonic-gate 	arg.gssd_cred_verifier =  gssd_cred_verifier;
6277c478bd9Sstevel@tonic-gate 
6287c478bd9Sstevel@tonic-gate 	arg.target_name.GSS_BUFFER_T_len = (uint_t)external_name.length;
6297c478bd9Sstevel@tonic-gate 	arg.target_name.GSS_BUFFER_T_val = (char *)external_name.value;
6307c478bd9Sstevel@tonic-gate 
6317c478bd9Sstevel@tonic-gate 	arg.name_type.GSS_OID_len =
6327c478bd9Sstevel@tonic-gate 		name_type == GSS_C_NULL_OID ?
6337c478bd9Sstevel@tonic-gate 		0 : (uint_t)name_type->length;
6347c478bd9Sstevel@tonic-gate 
6357c478bd9Sstevel@tonic-gate 	arg.name_type.GSS_OID_val =
6367c478bd9Sstevel@tonic-gate 		name_type == GSS_C_NULL_OID ?
6377c478bd9Sstevel@tonic-gate 		(char *)NULL : (char *)name_type->elements;
6387c478bd9Sstevel@tonic-gate 
6397c478bd9Sstevel@tonic-gate 	arg.mech_type.GSS_OID_len = (uint_t)(mech_type != GSS_C_NULL_OID ?
6407c478bd9Sstevel@tonic-gate 				mech_type->length : 0);
6417c478bd9Sstevel@tonic-gate 	arg.mech_type.GSS_OID_val = (char *)(mech_type != GSS_C_NULL_OID ?
6427c478bd9Sstevel@tonic-gate 				mech_type->elements : 0);
6437c478bd9Sstevel@tonic-gate 
6447c478bd9Sstevel@tonic-gate 	arg.req_flags = req_flags;
6457c478bd9Sstevel@tonic-gate 
6467c478bd9Sstevel@tonic-gate 	arg.time_req = time_req;
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate 	if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) {
6497c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.present = YES;
6507c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.initiator_addrtype =
6517c478bd9Sstevel@tonic-gate 			input_chan_bindings->initiator_addrtype;
6527c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len =
6537c478bd9Sstevel@tonic-gate 			(uint_t)input_chan_bindings->initiator_address.length;
6547c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val =
6557c478bd9Sstevel@tonic-gate 			(void *) input_chan_bindings->initiator_address.value;
6567c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.acceptor_addrtype =
6577c478bd9Sstevel@tonic-gate 			input_chan_bindings->acceptor_addrtype;
6587c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len =
6597c478bd9Sstevel@tonic-gate 			(uint_t)input_chan_bindings->acceptor_address.length;
6607c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val =
6617c478bd9Sstevel@tonic-gate 			(void *) input_chan_bindings->acceptor_address.value;
6627c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.application_data.GSS_BUFFER_T_len =
6637c478bd9Sstevel@tonic-gate 			(uint_t)input_chan_bindings->application_data.length;
6647c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.application_data.GSS_BUFFER_T_val =
6657c478bd9Sstevel@tonic-gate 			(void *) input_chan_bindings->application_data.value;
6667c478bd9Sstevel@tonic-gate 	} else {
6677c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.present = NO;
6687c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.initiator_addrtype = 0;
6697c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len = 0;
6707c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val = 0;
6717c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.acceptor_addrtype = 0;
6727c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len = 0;
6737c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val = 0;
6747c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.application_data.GSS_BUFFER_T_len = 0;
6757c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.application_data.GSS_BUFFER_T_val = 0;
6767c478bd9Sstevel@tonic-gate 	}
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate 	arg.input_token.GSS_BUFFER_T_len = (uint_t)
6797c478bd9Sstevel@tonic-gate 		(input_token != GSS_C_NO_BUFFER ? input_token->length : 0);
6807c478bd9Sstevel@tonic-gate 	arg.input_token.GSS_BUFFER_T_val = (char *)
6817c478bd9Sstevel@tonic-gate 		(input_token != GSS_C_NO_BUFFER ? input_token->value : 0);
6827c478bd9Sstevel@tonic-gate 
6837c478bd9Sstevel@tonic-gate 	/* initialize the output parameters to empty values */
6847c478bd9Sstevel@tonic-gate 	if (minor_status != NULL)
685ba7b222eSGlenn Barry 		*minor_status = DEFAULT_MINOR_STAT;
6867c478bd9Sstevel@tonic-gate 	if (actual_mech_type != NULL)
6877c478bd9Sstevel@tonic-gate 		*actual_mech_type = NULL;
6887c478bd9Sstevel@tonic-gate 	if (output_token != NULL)
6897c478bd9Sstevel@tonic-gate 		output_token->length = 0;
6907c478bd9Sstevel@tonic-gate 	if (ret_flags != NULL)
6917c478bd9Sstevel@tonic-gate 		*ret_flags = 0;
6927c478bd9Sstevel@tonic-gate 	if (time_rec != NULL)
6937c478bd9Sstevel@tonic-gate 		*time_rec = 0;
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate 	/* call the remote procedure */
6967c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
6977c478bd9Sstevel@tonic-gate 	if (gss_init_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate 		/* free the allocated memory for the flattened name */
7007c478bd9Sstevel@tonic-gate 		gss_release_buffer(&minor_status_temp, &external_name);
7017c478bd9Sstevel@tonic-gate 
7027c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
7037c478bd9Sstevel@tonic-gate 	}
7047c478bd9Sstevel@tonic-gate 
705ba7b222eSGlenn Barry 	/*
706ba7b222eSGlenn Barry 	 * We could return from a GSS error here and need to return both the
707ba7b222eSGlenn Barry 	 * minor_status and output_token, back to the caller if applicable.
708ba7b222eSGlenn Barry 	 */
709ba7b222eSGlenn Barry 	if (minor_status != NULL)
710ba7b222eSGlenn Barry 		*minor_status = res.minor_status;
711ba7b222eSGlenn Barry 
712ba7b222eSGlenn Barry 	if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) {
713ba7b222eSGlenn Barry 		output_token->length =
714ba7b222eSGlenn Barry 			(size_t)res.output_token.GSS_BUFFER_T_len;
715ba7b222eSGlenn Barry 		output_token->value =
716ba7b222eSGlenn Barry 			(void *)res.output_token.GSS_BUFFER_T_val;
717ba7b222eSGlenn Barry 		res.output_token.GSS_BUFFER_T_val = NULL;
718ba7b222eSGlenn Barry 		res.output_token.GSS_BUFFER_T_len = 0;
719ba7b222eSGlenn Barry 	}
7207c478bd9Sstevel@tonic-gate 
7217c478bd9Sstevel@tonic-gate 	/* free the allocated memory for the flattened name */
7227c478bd9Sstevel@tonic-gate 	gss_release_buffer(&minor_status_temp, &external_name);
7237c478bd9Sstevel@tonic-gate 
7247c478bd9Sstevel@tonic-gate 	/* if the call was successful, copy out the results */
7257c478bd9Sstevel@tonic-gate 	if (res.status == (OM_uint32) GSS_S_COMPLETE ||
7267c478bd9Sstevel@tonic-gate 		res.status == (OM_uint32) GSS_S_CONTINUE_NEEDED) {
7277c478bd9Sstevel@tonic-gate 		/*
728ba7b222eSGlenn Barry 		 * copy the rpc results into the return argument
729ba7b222eSGlenn Barry 		 * on CONTINUE_NEEDED only ctx handle is ready.
7307c478bd9Sstevel@tonic-gate 		 */
7317c478bd9Sstevel@tonic-gate 		/*LINTED*/
7327c478bd9Sstevel@tonic-gate 		*context_handle = *((OM_uint32 *)
7337c478bd9Sstevel@tonic-gate 			res.context_handle.GSS_CTX_ID_T_val);
7347c478bd9Sstevel@tonic-gate 
7357c478bd9Sstevel@tonic-gate 		*gssd_context_verifier = res.gssd_context_verifier;
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate 		/* the rest of the parameters is only ready on COMPLETE */
7387c478bd9Sstevel@tonic-gate 		if (res.status == GSS_S_COMPLETE) {
7397c478bd9Sstevel@tonic-gate 			if (actual_mech_type != NULL) {
7407c478bd9Sstevel@tonic-gate 				*actual_mech_type = (gss_OID)
7417c478bd9Sstevel@tonic-gate 					MALLOC(sizeof (gss_OID_desc));
7427c478bd9Sstevel@tonic-gate 				(*actual_mech_type)->length = (OM_UINT32)
7437c478bd9Sstevel@tonic-gate 					res.actual_mech_type.GSS_OID_len;
7447c478bd9Sstevel@tonic-gate 				(*actual_mech_type)->elements = (void *)
7457c478bd9Sstevel@tonic-gate 					MALLOC((*actual_mech_type)->length);
7467c478bd9Sstevel@tonic-gate 				memcpy((*actual_mech_type)->elements, (void *)
7477c478bd9Sstevel@tonic-gate 					res.actual_mech_type.GSS_OID_val,
7487c478bd9Sstevel@tonic-gate 					(*actual_mech_type)->length);
7497c478bd9Sstevel@tonic-gate 			}
7507c478bd9Sstevel@tonic-gate 
7517c478bd9Sstevel@tonic-gate 
7527c478bd9Sstevel@tonic-gate 			if (ret_flags != NULL)
7537c478bd9Sstevel@tonic-gate 				*ret_flags = res.ret_flags;
7547c478bd9Sstevel@tonic-gate 
7557c478bd9Sstevel@tonic-gate 			if (time_rec != NULL)
7567c478bd9Sstevel@tonic-gate 				*time_rec = res.time_rec;
7577c478bd9Sstevel@tonic-gate 		}
7587c478bd9Sstevel@tonic-gate 	}
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate 
7617c478bd9Sstevel@tonic-gate 	/*
7627c478bd9Sstevel@tonic-gate 	 * free the memory allocated for the results and return with the
7637c478bd9Sstevel@tonic-gate 	 * status received in the rpc call.
7647c478bd9Sstevel@tonic-gate 	 */
7657c478bd9Sstevel@tonic-gate 
7667c478bd9Sstevel@tonic-gate 	clnt_freeres(clnt, xdr_gss_init_sec_context_res, (caddr_t)&res);
7677c478bd9Sstevel@tonic-gate 	return (res.status);
7687c478bd9Sstevel@tonic-gate }
7697c478bd9Sstevel@tonic-gate OM_uint32
kgss_init_sec_context(OM_uint32 * minor_status,gss_cred_id_t claimant_cred_handle,gss_ctx_id_t * context_handle,gss_name_t target_name,gss_OID mech_type,int req_flags,OM_uint32 time_req,gss_channel_bindings_t input_chan_bindings,gss_buffer_t input_token,gss_OID * actual_mech_type,gss_buffer_t output_token,int * ret_flags,OM_uint32 * time_rec,uid_t uid)7707c478bd9Sstevel@tonic-gate kgss_init_sec_context(
7717c478bd9Sstevel@tonic-gate 		OM_uint32 *minor_status,
7727c478bd9Sstevel@tonic-gate 		gss_cred_id_t claimant_cred_handle,
7737c478bd9Sstevel@tonic-gate 		gss_ctx_id_t *context_handle,
7747c478bd9Sstevel@tonic-gate 		gss_name_t target_name,
7757c478bd9Sstevel@tonic-gate 		gss_OID mech_type,
7767c478bd9Sstevel@tonic-gate 		int req_flags,
7777c478bd9Sstevel@tonic-gate 		OM_uint32 time_req,
7787c478bd9Sstevel@tonic-gate 		gss_channel_bindings_t input_chan_bindings,
7797c478bd9Sstevel@tonic-gate 		gss_buffer_t input_token,
7807c478bd9Sstevel@tonic-gate 		gss_OID *actual_mech_type,
7817c478bd9Sstevel@tonic-gate 		gss_buffer_t output_token,
7827c478bd9Sstevel@tonic-gate 		int *ret_flags,
7837c478bd9Sstevel@tonic-gate 		OM_uint32 *time_rec,
7847c478bd9Sstevel@tonic-gate 		uid_t uid)
7857c478bd9Sstevel@tonic-gate {
7867c478bd9Sstevel@tonic-gate 		OM_uint32	err;
7877c478bd9Sstevel@tonic-gate 		struct kgss_ctx	*kctx;
7887c478bd9Sstevel@tonic-gate 		OM_uint32 gssd_cred_verifier;
7897c478bd9Sstevel@tonic-gate 		gssd_cred_id_t gssd_cl_cred_handle;
7907c478bd9Sstevel@tonic-gate 
7917c478bd9Sstevel@tonic-gate 		/*
7927c478bd9Sstevel@tonic-gate 		 * If this is an initial call, we'll need to create the
7937c478bd9Sstevel@tonic-gate 		 * wrapper struct that contains kernel state information, and
7947c478bd9Sstevel@tonic-gate 		 * a reference to the handle from gssd.
7957c478bd9Sstevel@tonic-gate 		 */
7967c478bd9Sstevel@tonic-gate 		if (*context_handle == GSS_C_NO_CONTEXT) {
7977c478bd9Sstevel@tonic-gate 			kctx = KGSS_ALLOC();
7987c478bd9Sstevel@tonic-gate 			*context_handle = (gss_ctx_id_t)kctx;
7997c478bd9Sstevel@tonic-gate 			kctx->gssd_ctx = (OM_uint32) GSS_C_NO_CONTEXT;
8007c478bd9Sstevel@tonic-gate 		} else
8017c478bd9Sstevel@tonic-gate 			kctx = (struct kgss_ctx *)*context_handle;
8027c478bd9Sstevel@tonic-gate 
8037c478bd9Sstevel@tonic-gate 		if (claimant_cred_handle != GSS_C_NO_CREDENTIAL) {
8047c478bd9Sstevel@tonic-gate 			gssd_cred_verifier =
805d4f95bf4SRichard Lowe 			    KCRED_TO_CREDV(claimant_cred_handle);
8067c478bd9Sstevel@tonic-gate 			gssd_cl_cred_handle =
807d4f95bf4SRichard Lowe 			    KCRED_TO_CRED(claimant_cred_handle);
808d4f95bf4SRichard Lowe 		} else {
809d4f95bf4SRichard Lowe 			gssd_cl_cred_handle = GSSD_NO_CREDENTIAL;
810d4f95bf4SRichard Lowe 		}
8117c478bd9Sstevel@tonic-gate 
8127c478bd9Sstevel@tonic-gate 		err = kgss_init_sec_context_wrapped(minor_status,
813d4f95bf4SRichard Lowe 		    gssd_cl_cred_handle,
814d4f95bf4SRichard Lowe 		    gssd_cred_verifier, &kctx->gssd_ctx,
815d4f95bf4SRichard Lowe 		    &kctx->gssd_ctx_verifier,
816d4f95bf4SRichard Lowe 		    target_name, mech_type, req_flags, time_req,
817d4f95bf4SRichard Lowe 		    input_chan_bindings, input_token, actual_mech_type,
818d4f95bf4SRichard Lowe 		    output_token, ret_flags, time_rec, uid);
8197c478bd9Sstevel@tonic-gate 
8207c478bd9Sstevel@tonic-gate 		if (GSS_ERROR(err)) {
8217c478bd9Sstevel@tonic-gate 			KGSS_FREE(kctx);
8227c478bd9Sstevel@tonic-gate 			*context_handle = GSS_C_NO_CONTEXT;
8237c478bd9Sstevel@tonic-gate 		}
8247c478bd9Sstevel@tonic-gate 		return (err);
8257c478bd9Sstevel@tonic-gate }
8267c478bd9Sstevel@tonic-gate OM_uint32
kgss_accept_sec_context_wrapped(minor_status,context_handle,gssd_context_verifier,verifier_cred_handle,gssd_cred_verifier,input_token,input_chan_bindings,src_name,mech_type,output_token,ret_flags,time_rec,delegated_cred_handle,uid)8277c478bd9Sstevel@tonic-gate kgss_accept_sec_context_wrapped(minor_status,
8287c478bd9Sstevel@tonic-gate 				context_handle,
8297c478bd9Sstevel@tonic-gate 				gssd_context_verifier,
8307c478bd9Sstevel@tonic-gate 				verifier_cred_handle,
8317c478bd9Sstevel@tonic-gate 				gssd_cred_verifier,
8327c478bd9Sstevel@tonic-gate 		input_token,
8337c478bd9Sstevel@tonic-gate 		input_chan_bindings,
8347c478bd9Sstevel@tonic-gate 		src_name,
8357c478bd9Sstevel@tonic-gate 		mech_type,
8367c478bd9Sstevel@tonic-gate 		output_token,
8377c478bd9Sstevel@tonic-gate 		ret_flags,
8387c478bd9Sstevel@tonic-gate 		time_rec,
8397c478bd9Sstevel@tonic-gate 		delegated_cred_handle,
8407c478bd9Sstevel@tonic-gate 		uid)
8417c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
8427c478bd9Sstevel@tonic-gate 	gssd_ctx_id_t *context_handle;
8437c478bd9Sstevel@tonic-gate 	OM_uint32 *gssd_context_verifier;
8447c478bd9Sstevel@tonic-gate 	gssd_cred_id_t verifier_cred_handle;
8457c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_cred_verifier;
8467c478bd9Sstevel@tonic-gate 	gss_buffer_t input_token;
8477c478bd9Sstevel@tonic-gate 	gss_channel_bindings_t input_chan_bindings;
8487c478bd9Sstevel@tonic-gate 	gss_buffer_t src_name;
8497c478bd9Sstevel@tonic-gate 	gss_OID *mech_type;
8507c478bd9Sstevel@tonic-gate 	gss_buffer_t output_token;
8517c478bd9Sstevel@tonic-gate 	int *ret_flags;
8527c478bd9Sstevel@tonic-gate 	OM_uint32 *time_rec;
8537c478bd9Sstevel@tonic-gate 	gss_cred_id_t *delegated_cred_handle;
8547c478bd9Sstevel@tonic-gate 	uid_t uid;
8557c478bd9Sstevel@tonic-gate {
8567c478bd9Sstevel@tonic-gate 	gss_accept_sec_context_arg arg;
8577c478bd9Sstevel@tonic-gate 	gss_accept_sec_context_res res;
8587c478bd9Sstevel@tonic-gate 	struct kgss_cred *kcred;
8597c478bd9Sstevel@tonic-gate 
8607c478bd9Sstevel@tonic-gate 	/* get the client handle to GSSD */
8617c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
8627c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
8637c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
8647c478bd9Sstevel@tonic-gate 	}
8657c478bd9Sstevel@tonic-gate 
8667c478bd9Sstevel@tonic-gate 	/* copy the procedure arguments into the rpc arg parameter */
8677c478bd9Sstevel@tonic-gate 	arg.uid = (OM_uint32) uid;
8687c478bd9Sstevel@tonic-gate 
8697c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_len =
870d4f95bf4SRichard Lowe 		*context_handle == GSSD_NO_CONTEXT ?
8717c478bd9Sstevel@tonic-gate 			0 : (uint_t)sizeof (gssd_ctx_id_t);
8727c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_val =  (char *)context_handle;
8737c478bd9Sstevel@tonic-gate 	arg.gssd_context_verifier =
8747c478bd9Sstevel@tonic-gate 		*context_handle == (OM_uint32) GSS_C_NO_CONTEXT ?
8757c478bd9Sstevel@tonic-gate 			0 : *gssd_context_verifier;
8767c478bd9Sstevel@tonic-gate 
8777c478bd9Sstevel@tonic-gate 	arg.verifier_cred_handle.GSS_CRED_ID_T_len =
878d4f95bf4SRichard Lowe 			verifier_cred_handle == GSSD_NO_CREDENTIAL ?
8797c478bd9Sstevel@tonic-gate 			0 : (uint_t)sizeof (gssd_cred_id_t);
8807c478bd9Sstevel@tonic-gate 	arg.verifier_cred_handle.GSS_CRED_ID_T_val =
8817c478bd9Sstevel@tonic-gate 						(char *)&verifier_cred_handle;
8827c478bd9Sstevel@tonic-gate 	arg.gssd_cred_verifier = gssd_cred_verifier;
8837c478bd9Sstevel@tonic-gate 
8847c478bd9Sstevel@tonic-gate 	arg.input_token_buffer.GSS_BUFFER_T_len =
8857c478bd9Sstevel@tonic-gate 			(uint_t)(input_token != GSS_C_NO_BUFFER ?
8867c478bd9Sstevel@tonic-gate 					input_token->length : 0);
8877c478bd9Sstevel@tonic-gate 	arg.input_token_buffer.GSS_BUFFER_T_val =
8887c478bd9Sstevel@tonic-gate 			(char *)(input_token != GSS_C_NO_BUFFER ?
8897c478bd9Sstevel@tonic-gate 					input_token->value : 0);
8907c478bd9Sstevel@tonic-gate 
8917c478bd9Sstevel@tonic-gate 	if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) {
8927c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.present = YES;
8937c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.initiator_addrtype =
8947c478bd9Sstevel@tonic-gate 			input_chan_bindings->initiator_addrtype;
8957c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len =
8967c478bd9Sstevel@tonic-gate 			(uint_t)input_chan_bindings->initiator_address.length;
8977c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val =
8987c478bd9Sstevel@tonic-gate 			(void *) input_chan_bindings->initiator_address.value;
8997c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.acceptor_addrtype =
9007c478bd9Sstevel@tonic-gate 			input_chan_bindings->acceptor_addrtype;
9017c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len =
9027c478bd9Sstevel@tonic-gate 			(uint_t)input_chan_bindings->acceptor_address.length;
9037c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val =
9047c478bd9Sstevel@tonic-gate 			(void *) input_chan_bindings->acceptor_address.value;
9057c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.application_data.GSS_BUFFER_T_len =
9067c478bd9Sstevel@tonic-gate 			(uint_t)input_chan_bindings->application_data.length;
9077c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.application_data.GSS_BUFFER_T_val =
9087c478bd9Sstevel@tonic-gate 			(void *) input_chan_bindings->application_data.value;
9097c478bd9Sstevel@tonic-gate 	} else {
9107c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.present = NO;
9117c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.initiator_addrtype = 0;
9127c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len = 0;
9137c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val = 0;
9147c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.acceptor_addrtype = 0;
9157c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len = 0;
9167c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val = 0;
9177c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.application_data.GSS_BUFFER_T_len = 0;
9187c478bd9Sstevel@tonic-gate 		arg.input_chan_bindings.application_data.GSS_BUFFER_T_val = 0;
9197c478bd9Sstevel@tonic-gate 	}
9207c478bd9Sstevel@tonic-gate 
9217c478bd9Sstevel@tonic-gate 	/* set the output parameters to empty values.... */
9227c478bd9Sstevel@tonic-gate 	if (minor_status != NULL)
923ba7b222eSGlenn Barry 		*minor_status = DEFAULT_MINOR_STAT;
9247c478bd9Sstevel@tonic-gate 	if (src_name != NULL) {
9257c478bd9Sstevel@tonic-gate 		src_name->length = 0;
9267c478bd9Sstevel@tonic-gate 		src_name->value = NULL;
9277c478bd9Sstevel@tonic-gate 	}
9287c478bd9Sstevel@tonic-gate 	if (mech_type != NULL)
9297c478bd9Sstevel@tonic-gate 		*mech_type = NULL;
9307c478bd9Sstevel@tonic-gate 	if (output_token != NULL)
9317c478bd9Sstevel@tonic-gate 		output_token->length = 0;
9327c478bd9Sstevel@tonic-gate 	if (ret_flags != NULL)
9337c478bd9Sstevel@tonic-gate 		*ret_flags = 0;
9347c478bd9Sstevel@tonic-gate 	if (time_rec != NULL)
9357c478bd9Sstevel@tonic-gate 		*time_rec = 0;
9367c478bd9Sstevel@tonic-gate 	if (delegated_cred_handle != NULL)
9377c478bd9Sstevel@tonic-gate 		*delegated_cred_handle = NULL;
9387c478bd9Sstevel@tonic-gate 
9397c478bd9Sstevel@tonic-gate 	/* call the remote procedure */
9407c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
9417c478bd9Sstevel@tonic-gate 	if (gss_accept_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
9427c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
9437c478bd9Sstevel@tonic-gate 	}
9447c478bd9Sstevel@tonic-gate 
945ba7b222eSGlenn Barry 	/*
946ba7b222eSGlenn Barry 	 * We could return from a GSS error here and need to return both the
947ba7b222eSGlenn Barry 	 * minor_status and output_token, back to the caller if applicable.
948ba7b222eSGlenn Barry 	 */
949ba7b222eSGlenn Barry 	if (minor_status != NULL)
950ba7b222eSGlenn Barry 		*minor_status = res.minor_status;
951ba7b222eSGlenn Barry 
952ba7b222eSGlenn Barry 	if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) {
953ba7b222eSGlenn Barry 		output_token->length =
954ba7b222eSGlenn Barry 			res.output_token.GSS_BUFFER_T_len;
955ba7b222eSGlenn Barry 		output_token->value =
956ba7b222eSGlenn Barry 			(void *) res.output_token.GSS_BUFFER_T_val;
957ba7b222eSGlenn Barry 		res.output_token.GSS_BUFFER_T_val = 0;
958ba7b222eSGlenn Barry 		res.output_token.GSS_BUFFER_T_len = 0;
959ba7b222eSGlenn Barry 	}
9607c478bd9Sstevel@tonic-gate 
9617c478bd9Sstevel@tonic-gate 	if (res.status == (OM_uint32) GSS_S_COMPLETE ||
9627c478bd9Sstevel@tonic-gate 		res.status == (OM_uint32) GSS_S_CONTINUE_NEEDED) {
9637c478bd9Sstevel@tonic-gate 		/*
9647c478bd9Sstevel@tonic-gate 		 * when gss returns CONTINUE_NEEDED we can only
965ba7b222eSGlenn Barry 		 * use the context parameter.
9667c478bd9Sstevel@tonic-gate 		 */
9677c478bd9Sstevel@tonic-gate 		/*LINTED*/
9687c478bd9Sstevel@tonic-gate 		*context_handle = *((gssd_ctx_id_t *)
9697c478bd9Sstevel@tonic-gate 			res.context_handle.GSS_CTX_ID_T_val);
9707c478bd9Sstevel@tonic-gate 		*gssd_context_verifier = res.gssd_context_verifier;
9717c478bd9Sstevel@tonic-gate 
9727c478bd9Sstevel@tonic-gate 		/* the other parameters are ready on for COMPLETE */
9737c478bd9Sstevel@tonic-gate 		if (res.status == GSS_S_COMPLETE)
9747c478bd9Sstevel@tonic-gate 		{
9757c478bd9Sstevel@tonic-gate 
9767c478bd9Sstevel@tonic-gate 			/*
9777c478bd9Sstevel@tonic-gate 			 *  The src_name is in external format.
9787c478bd9Sstevel@tonic-gate 			 */
9797c478bd9Sstevel@tonic-gate 			if (src_name != NULL) {
9807c478bd9Sstevel@tonic-gate 			    src_name->length = res.src_name.GSS_BUFFER_T_len;
9817c478bd9Sstevel@tonic-gate 			    src_name->value = res.src_name.GSS_BUFFER_T_val;
9827c478bd9Sstevel@tonic-gate 			    res.src_name.GSS_BUFFER_T_val = NULL;
9837c478bd9Sstevel@tonic-gate 			    res.src_name.GSS_BUFFER_T_len = 0;
9847c478bd9Sstevel@tonic-gate 			}
9857c478bd9Sstevel@tonic-gate 			/*
9867c478bd9Sstevel@tonic-gate 			 * move mech type returned to mech_type
9877c478bd9Sstevel@tonic-gate 			 * for gss_import_name_for_mech()
9887c478bd9Sstevel@tonic-gate 			 */
9897c478bd9Sstevel@tonic-gate 			if (mech_type != NULL) {
9907c478bd9Sstevel@tonic-gate 				*mech_type =
9917c478bd9Sstevel@tonic-gate 					(gss_OID) MALLOC(sizeof (gss_OID_desc));
9927c478bd9Sstevel@tonic-gate 				(*mech_type)->length =
9937c478bd9Sstevel@tonic-gate 					(OM_UINT32) res.mech_type.GSS_OID_len;
9947c478bd9Sstevel@tonic-gate 				(*mech_type)->elements =
9957c478bd9Sstevel@tonic-gate 					(void *) MALLOC((*mech_type)->length);
9967c478bd9Sstevel@tonic-gate 				memcpy((*mech_type)->elements,
9977c478bd9Sstevel@tonic-gate 					res.mech_type.GSS_OID_val,
9987c478bd9Sstevel@tonic-gate 					(*mech_type)->length);
9997c478bd9Sstevel@tonic-gate 			}
10007c478bd9Sstevel@tonic-gate 
10017c478bd9Sstevel@tonic-gate 			if (ret_flags != NULL)
10027c478bd9Sstevel@tonic-gate 				*ret_flags = res.ret_flags;
10037c478bd9Sstevel@tonic-gate 
10047c478bd9Sstevel@tonic-gate 			if (time_rec != NULL)
10057c478bd9Sstevel@tonic-gate 				*time_rec = res.time_rec;
10067c478bd9Sstevel@tonic-gate 
10077c478bd9Sstevel@tonic-gate 			if ((delegated_cred_handle != NULL) &&
10087c478bd9Sstevel@tonic-gate 				(res.delegated_cred_handle.GSS_CRED_ID_T_len
10097c478bd9Sstevel@tonic-gate 					!= 0)) {
10107c478bd9Sstevel@tonic-gate 				kcred = KGSS_CRED_ALLOC();
10117c478bd9Sstevel@tonic-gate 				/*LINTED*/
10127c478bd9Sstevel@tonic-gate 				kcred->gssd_cred = *((gssd_cred_id_t *)
10137c478bd9Sstevel@tonic-gate 				res.delegated_cred_handle.GSS_CRED_ID_T_val);
10147c478bd9Sstevel@tonic-gate 				kcred->gssd_cred_verifier =
10157c478bd9Sstevel@tonic-gate 					res.gssd_context_verifier;
10167c478bd9Sstevel@tonic-gate 				*delegated_cred_handle = (gss_cred_id_t)kcred;
10177c478bd9Sstevel@tonic-gate 			}
10187c478bd9Sstevel@tonic-gate 		} /* res.status == GSS_S_COMPLETE */
10197c478bd9Sstevel@tonic-gate 	} /* res.status == GSS_S_COMPLETE or GSS_CONTINUE_NEEDED */
10207c478bd9Sstevel@tonic-gate 
10217c478bd9Sstevel@tonic-gate 
10227c478bd9Sstevel@tonic-gate 	/*
10237c478bd9Sstevel@tonic-gate 	 * free the memory allocated for the results and return with the status
10247c478bd9Sstevel@tonic-gate 	 * received in the rpc call
10257c478bd9Sstevel@tonic-gate 	 */
10267c478bd9Sstevel@tonic-gate 
10277c478bd9Sstevel@tonic-gate 	clnt_freeres(clnt, xdr_gss_accept_sec_context_res, (caddr_t)&res);
10287c478bd9Sstevel@tonic-gate 	return (res.status);
10297c478bd9Sstevel@tonic-gate }
10307c478bd9Sstevel@tonic-gate 
10317c478bd9Sstevel@tonic-gate OM_uint32
kgss_accept_sec_context(OM_uint32 * minor_status,gss_ctx_id_t * context_handle,gss_cred_id_t verifier_cred_handle,gss_buffer_t input_token,gss_channel_bindings_t input_chan_bindings,gss_buffer_t src_name,gss_OID * mech_type,gss_buffer_t output_token,int * ret_flags,OM_uint32 * time_rec,gss_cred_id_t * delegated_cred_handle,uid_t uid)10327c478bd9Sstevel@tonic-gate kgss_accept_sec_context(
10337c478bd9Sstevel@tonic-gate 		OM_uint32 *minor_status,
10347c478bd9Sstevel@tonic-gate 		gss_ctx_id_t *context_handle,
10357c478bd9Sstevel@tonic-gate 		gss_cred_id_t verifier_cred_handle,
10367c478bd9Sstevel@tonic-gate 		gss_buffer_t input_token,
10377c478bd9Sstevel@tonic-gate 		gss_channel_bindings_t input_chan_bindings,
10387c478bd9Sstevel@tonic-gate 		gss_buffer_t src_name,
10397c478bd9Sstevel@tonic-gate 		gss_OID *mech_type,
10407c478bd9Sstevel@tonic-gate 		gss_buffer_t output_token,
10417c478bd9Sstevel@tonic-gate 		int *ret_flags,
10427c478bd9Sstevel@tonic-gate 		OM_uint32 *time_rec,
10437c478bd9Sstevel@tonic-gate 		gss_cred_id_t *delegated_cred_handle,
10447c478bd9Sstevel@tonic-gate 		uid_t uid)
10457c478bd9Sstevel@tonic-gate {
10467c478bd9Sstevel@tonic-gate 		OM_uint32 err;
10477c478bd9Sstevel@tonic-gate 		struct kgss_ctx *kctx;
10487c478bd9Sstevel@tonic-gate 		OM_uint32 gssd_cred_verifier;
10497c478bd9Sstevel@tonic-gate 		gssd_cred_id_t gssd_ver_cred_handle;
10507c478bd9Sstevel@tonic-gate 
10517c478bd9Sstevel@tonic-gate 
10527c478bd9Sstevel@tonic-gate 		if (*context_handle == GSS_C_NO_CONTEXT) {
10537c478bd9Sstevel@tonic-gate 			kctx = KGSS_ALLOC();
10547c478bd9Sstevel@tonic-gate 			*context_handle = (gss_ctx_id_t)kctx;
1055d4f95bf4SRichard Lowe 		kctx->gssd_ctx = GSSD_NO_CONTEXT;
10567c478bd9Sstevel@tonic-gate 		} else
10577c478bd9Sstevel@tonic-gate 			kctx = (struct kgss_ctx *)*context_handle;
10587c478bd9Sstevel@tonic-gate 
10597c478bd9Sstevel@tonic-gate 	if (verifier_cred_handle != GSS_C_NO_CREDENTIAL) {
10607c478bd9Sstevel@tonic-gate 			gssd_cred_verifier =
1061d4f95bf4SRichard Lowe 			    KCRED_TO_CREDV(verifier_cred_handle);
10627c478bd9Sstevel@tonic-gate 			gssd_ver_cred_handle =
1063d4f95bf4SRichard Lowe 			    KCRED_TO_CRED(verifier_cred_handle);
10647c478bd9Sstevel@tonic-gate 	} else
1065d4f95bf4SRichard Lowe 		gssd_ver_cred_handle = GSSD_NO_CREDENTIAL;
10667c478bd9Sstevel@tonic-gate 
1067cb4d790dSToomas Soome 	err = kgss_accept_sec_context_wrapped(minor_status, &kctx->gssd_ctx,
1068cb4d790dSToomas Soome 	    &kctx->gssd_ctx_verifier, gssd_ver_cred_handle,
1069cb4d790dSToomas Soome 	    gssd_cred_verifier, input_token, input_chan_bindings,
1070cb4d790dSToomas Soome 	    src_name, mech_type, output_token, ret_flags,
1071cb4d790dSToomas Soome 	    time_rec, delegated_cred_handle, uid);
10727c478bd9Sstevel@tonic-gate 
10737c478bd9Sstevel@tonic-gate 	if (GSS_ERROR(err)) {
10747c478bd9Sstevel@tonic-gate 		KGSS_FREE(kctx);
10757c478bd9Sstevel@tonic-gate 		*context_handle = GSS_C_NO_CONTEXT;
10767c478bd9Sstevel@tonic-gate 
10777c478bd9Sstevel@tonic-gate 	}
10787c478bd9Sstevel@tonic-gate 
10797c478bd9Sstevel@tonic-gate 	return (err);
10807c478bd9Sstevel@tonic-gate }
10817c478bd9Sstevel@tonic-gate 
10827c478bd9Sstevel@tonic-gate OM_uint32
kgss_process_context_token(minor_status,context_handle,token_buffer,uid)10837c478bd9Sstevel@tonic-gate kgss_process_context_token(minor_status,
10847c478bd9Sstevel@tonic-gate 			context_handle,
10857c478bd9Sstevel@tonic-gate 			token_buffer,
10867c478bd9Sstevel@tonic-gate 			uid)
10877c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
10887c478bd9Sstevel@tonic-gate 	gss_ctx_id_t context_handle;
10897c478bd9Sstevel@tonic-gate 	gss_buffer_t token_buffer;
10907c478bd9Sstevel@tonic-gate 	uid_t uid;
10917c478bd9Sstevel@tonic-gate {
10927c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_context_verifier;
10937c478bd9Sstevel@tonic-gate 
10947c478bd9Sstevel@tonic-gate 	gss_process_context_token_arg arg;
10957c478bd9Sstevel@tonic-gate 	gss_process_context_token_res res;
10967c478bd9Sstevel@tonic-gate 
10977c478bd9Sstevel@tonic-gate 	gssd_context_verifier = KGSS_CTX_TO_GSSD_CTXV(context_handle);
10987c478bd9Sstevel@tonic-gate 
10997c478bd9Sstevel@tonic-gate 	/* get the client handle to GSSD */
11007c478bd9Sstevel@tonic-gate 
11017c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
11027c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
11037c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
11047c478bd9Sstevel@tonic-gate 	}
11057c478bd9Sstevel@tonic-gate 
11067c478bd9Sstevel@tonic-gate 	/* copy the procedure arguments into the rpc arg parameter */
11077c478bd9Sstevel@tonic-gate 	arg.uid = (OM_uint32) uid;
11087c478bd9Sstevel@tonic-gate 
11097c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gss_ctx_id_t);
11107c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
11117c478bd9Sstevel@tonic-gate 	arg.gssd_context_verifier = gssd_context_verifier;
11127c478bd9Sstevel@tonic-gate 	arg.token_buffer.GSS_BUFFER_T_len = (uint_t)token_buffer;
11137c478bd9Sstevel@tonic-gate 	arg.token_buffer.GSS_BUFFER_T_val = (char *)token_buffer->value;
11147c478bd9Sstevel@tonic-gate 
11157c478bd9Sstevel@tonic-gate 	/* call the remote procedure */
11167c478bd9Sstevel@tonic-gate 
11177c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
11187c478bd9Sstevel@tonic-gate 	if (gss_process_context_token_1(&arg, &res, clnt) != RPC_SUCCESS) {
11197c478bd9Sstevel@tonic-gate 
11207c478bd9Sstevel@tonic-gate 	/*
11217c478bd9Sstevel@tonic-gate 	 * if the RPC call times out, null out all return arguments,
11227c478bd9Sstevel@tonic-gate 	 * set minor_status to its maximum value, and return GSS_S_FAILURE
11237c478bd9Sstevel@tonic-gate 	 */
11247c478bd9Sstevel@tonic-gate 
11257c478bd9Sstevel@tonic-gate 		if (minor_status != NULL)
1126ba7b222eSGlenn Barry 			*minor_status = DEFAULT_MINOR_STAT;
11277c478bd9Sstevel@tonic-gate 
11287c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
11297c478bd9Sstevel@tonic-gate 	}
11307c478bd9Sstevel@tonic-gate 
11317c478bd9Sstevel@tonic-gate 	/* copy the rpc results into the return arguments */
11327c478bd9Sstevel@tonic-gate 
11337c478bd9Sstevel@tonic-gate 	if (minor_status != NULL)
11347c478bd9Sstevel@tonic-gate 		*minor_status = res.minor_status;
11357c478bd9Sstevel@tonic-gate 
11367c478bd9Sstevel@tonic-gate 	/* return with status returned in rpc call */
11377c478bd9Sstevel@tonic-gate 
11387c478bd9Sstevel@tonic-gate 	return (res.status);
11397c478bd9Sstevel@tonic-gate }
11407c478bd9Sstevel@tonic-gate 
11417c478bd9Sstevel@tonic-gate OM_uint32
kgss_delete_sec_context_wrapped(minor_status,context_handle,gssd_context_verifier,output_token)11427c478bd9Sstevel@tonic-gate kgss_delete_sec_context_wrapped(minor_status,
11437c478bd9Sstevel@tonic-gate 			context_handle,
11447c478bd9Sstevel@tonic-gate 			gssd_context_verifier,
11457c478bd9Sstevel@tonic-gate 			output_token)
11467c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
11477c478bd9Sstevel@tonic-gate 	gssd_ctx_id_t *context_handle;
11487c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_context_verifier;
11497c478bd9Sstevel@tonic-gate 	gss_buffer_t output_token;
11507c478bd9Sstevel@tonic-gate {
11517c478bd9Sstevel@tonic-gate 	gss_delete_sec_context_arg arg;
11527c478bd9Sstevel@tonic-gate 	gss_delete_sec_context_res res;
11537c478bd9Sstevel@tonic-gate 
11547c478bd9Sstevel@tonic-gate 
11557c478bd9Sstevel@tonic-gate 	/* get the client handle to GSSD */
11567c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
11577c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
11587c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
11597c478bd9Sstevel@tonic-gate 	}
11607c478bd9Sstevel@tonic-gate 
11617c478bd9Sstevel@tonic-gate 	/* copy the procedure arguments into the rpc arg parameter */
11627c478bd9Sstevel@tonic-gate 
11637c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_len =
11647c478bd9Sstevel@tonic-gate 		*context_handle == (OM_uint32) GSS_C_NO_CONTEXT ? 0 :
11657c478bd9Sstevel@tonic-gate 		(uint_t)sizeof (OM_uint32);
11667c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_val =  (char *)context_handle;
11677c478bd9Sstevel@tonic-gate 
11687c478bd9Sstevel@tonic-gate 	arg.gssd_context_verifier = gssd_context_verifier;
11697c478bd9Sstevel@tonic-gate 
11707c478bd9Sstevel@tonic-gate 	/* call the remote procedure */
11717c478bd9Sstevel@tonic-gate 
11727c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
11737c478bd9Sstevel@tonic-gate 	if (gss_delete_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
11747c478bd9Sstevel@tonic-gate 
11757c478bd9Sstevel@tonic-gate 		/*
11767c478bd9Sstevel@tonic-gate 		 * if the RPC call times out, null out all return arguments,
11777c478bd9Sstevel@tonic-gate 		 * set minor_status to its max value, and return GSS_S_FAILURE
11787c478bd9Sstevel@tonic-gate 		 */
11797c478bd9Sstevel@tonic-gate 
11807c478bd9Sstevel@tonic-gate 		if (minor_status != NULL)
1181ba7b222eSGlenn Barry 			*minor_status = DEFAULT_MINOR_STAT;
11827c478bd9Sstevel@tonic-gate 		if (context_handle != NULL)
1183*0ab8aa70SToomas Soome 			*context_handle = 0;
11847c478bd9Sstevel@tonic-gate 		if (output_token != NULL)
11857c478bd9Sstevel@tonic-gate 			output_token->length = 0;
11867c478bd9Sstevel@tonic-gate 
11877c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
11887c478bd9Sstevel@tonic-gate 	}
11897c478bd9Sstevel@tonic-gate 
11907c478bd9Sstevel@tonic-gate 	/* copy the rpc results into the return arguments */
11917c478bd9Sstevel@tonic-gate 
11927c478bd9Sstevel@tonic-gate 	if (minor_status != NULL)
11937c478bd9Sstevel@tonic-gate 		*minor_status = res.minor_status;
11947c478bd9Sstevel@tonic-gate 
11957c478bd9Sstevel@tonic-gate 	if (res.context_handle.GSS_CTX_ID_T_len == 0)
1196*0ab8aa70SToomas Soome 		*context_handle = 0;
11977c478bd9Sstevel@tonic-gate 	else
11987c478bd9Sstevel@tonic-gate 		/*LINTED*/
11997c478bd9Sstevel@tonic-gate 		*context_handle = *((gssd_ctx_id_t *)
12007c478bd9Sstevel@tonic-gate 			res.context_handle.GSS_CTX_ID_T_val);
12017c478bd9Sstevel@tonic-gate 
1202ba7b222eSGlenn Barry 	if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) {
12037c478bd9Sstevel@tonic-gate 		output_token->length = res.output_token.GSS_BUFFER_T_len;
12047c478bd9Sstevel@tonic-gate 		output_token->value = res.output_token.GSS_BUFFER_T_val;
12057c478bd9Sstevel@tonic-gate 		res.output_token.GSS_BUFFER_T_len = 0;
12067c478bd9Sstevel@tonic-gate 		res.output_token.GSS_BUFFER_T_val = NULL;
12077c478bd9Sstevel@tonic-gate 	}
12087c478bd9Sstevel@tonic-gate 
12097c478bd9Sstevel@tonic-gate 	/*
12107c478bd9Sstevel@tonic-gate 	 * free the memory allocated for the results and return with the status
12117c478bd9Sstevel@tonic-gate 	 * received in the rpc call
12127c478bd9Sstevel@tonic-gate 	 */
12137c478bd9Sstevel@tonic-gate 
12147c478bd9Sstevel@tonic-gate 	clnt_freeres(clnt, xdr_gss_delete_sec_context_res, (caddr_t)&res);
12157c478bd9Sstevel@tonic-gate 	return (res.status);
12167c478bd9Sstevel@tonic-gate }
12177c478bd9Sstevel@tonic-gate 
12187c478bd9Sstevel@tonic-gate /*ARGSUSED*/
12197c478bd9Sstevel@tonic-gate OM_uint32
kgss_delete_sec_context(OM_uint32 * minor_status,gss_ctx_id_t * context_handle,gss_buffer_t output_token)12207c478bd9Sstevel@tonic-gate kgss_delete_sec_context(
12217c478bd9Sstevel@tonic-gate 		OM_uint32 *minor_status,
12227c478bd9Sstevel@tonic-gate 		gss_ctx_id_t *context_handle,
12237c478bd9Sstevel@tonic-gate 		gss_buffer_t output_token)
12247c478bd9Sstevel@tonic-gate {
12257c478bd9Sstevel@tonic-gate 		OM_uint32 err;
12267c478bd9Sstevel@tonic-gate 		struct kgss_ctx *kctx;
12277c478bd9Sstevel@tonic-gate 
12287c478bd9Sstevel@tonic-gate 		if (*context_handle == GSS_C_NO_CONTEXT) {
12297c478bd9Sstevel@tonic-gate 			return (GSS_S_NO_CONTEXT);
12307c478bd9Sstevel@tonic-gate 		} else
12317c478bd9Sstevel@tonic-gate 			kctx = KCTX_TO_KGSS_CTX(*context_handle);
12327c478bd9Sstevel@tonic-gate 
12337c478bd9Sstevel@tonic-gate 		err = kgss_delete_sec_context_wrapped(minor_status,
1234d4f95bf4SRichard Lowe 		    &kctx->gssd_ctx, kctx->gssd_ctx_verifier,
1235d4f95bf4SRichard Lowe 		    output_token);
12367c478bd9Sstevel@tonic-gate 
1237d4f95bf4SRichard Lowe 		if (kctx->gssd_ctx != GSSD_NO_CONTEXT)
12387c478bd9Sstevel@tonic-gate 			err = GSS_S_FAILURE;
12397c478bd9Sstevel@tonic-gate 		else
12407c478bd9Sstevel@tonic-gate 			err = GSS_S_COMPLETE;
12417c478bd9Sstevel@tonic-gate 
12427c478bd9Sstevel@tonic-gate 		KGSS_FREE(kctx);
12437c478bd9Sstevel@tonic-gate 		*context_handle = GSS_C_NO_CONTEXT;
12447c478bd9Sstevel@tonic-gate 		return (err);
12457c478bd9Sstevel@tonic-gate }
12467c478bd9Sstevel@tonic-gate 
12477c478bd9Sstevel@tonic-gate /*ARGSUSED*/
12487c478bd9Sstevel@tonic-gate OM_uint32
kgss_context_time(minor_status,context_handle,time_rec,uid)12497c478bd9Sstevel@tonic-gate kgss_context_time(minor_status,
12507c478bd9Sstevel@tonic-gate 		context_handle,
12517c478bd9Sstevel@tonic-gate 		time_rec,
12527c478bd9Sstevel@tonic-gate 		uid)
12537c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
12547c478bd9Sstevel@tonic-gate 	gss_ctx_id_t context_handle;
12557c478bd9Sstevel@tonic-gate 	OM_uint32 *time_rec;
12567c478bd9Sstevel@tonic-gate 	uid_t uid;
12577c478bd9Sstevel@tonic-gate {
12587c478bd9Sstevel@tonic-gate 	return (GSS_S_FAILURE);
12597c478bd9Sstevel@tonic-gate }
12607c478bd9Sstevel@tonic-gate 
12617c478bd9Sstevel@tonic-gate OM_uint32
kgss_sign_wrapped(minor_status,context_handle,qop_req,message_buffer,msg_token,gssd_context_verifier)12627c478bd9Sstevel@tonic-gate kgss_sign_wrapped(minor_status,
12637c478bd9Sstevel@tonic-gate 		context_handle,
12647c478bd9Sstevel@tonic-gate 		qop_req,
12657c478bd9Sstevel@tonic-gate 		message_buffer,
12667c478bd9Sstevel@tonic-gate 		msg_token,
12677c478bd9Sstevel@tonic-gate 		gssd_context_verifier)
12687c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
12697c478bd9Sstevel@tonic-gate 	gssd_ctx_id_t context_handle;
12707c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_context_verifier;
12717c478bd9Sstevel@tonic-gate 	int qop_req;
12727c478bd9Sstevel@tonic-gate 	gss_buffer_t message_buffer;
12737c478bd9Sstevel@tonic-gate 	gss_buffer_t msg_token;
12747c478bd9Sstevel@tonic-gate {
12757c478bd9Sstevel@tonic-gate 
12767c478bd9Sstevel@tonic-gate 	gss_sign_arg arg;
12777c478bd9Sstevel@tonic-gate 	gss_sign_res res;
12787c478bd9Sstevel@tonic-gate 
12797c478bd9Sstevel@tonic-gate 	/* get the client handle to GSSD */
12807c478bd9Sstevel@tonic-gate 
12817c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
12827c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
12837c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
12847c478bd9Sstevel@tonic-gate 	}
12857c478bd9Sstevel@tonic-gate 
12867c478bd9Sstevel@tonic-gate 	/* copy the procedure arguments into the rpc arg parameter */
12877c478bd9Sstevel@tonic-gate 
12887c478bd9Sstevel@tonic-gate 
12897c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
12907c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
12917c478bd9Sstevel@tonic-gate 	arg.gssd_context_verifier = gssd_context_verifier;
12927c478bd9Sstevel@tonic-gate 
12937c478bd9Sstevel@tonic-gate 	arg.qop_req = qop_req;
12947c478bd9Sstevel@tonic-gate 	arg.message_buffer.GSS_BUFFER_T_len = (uint_t)message_buffer->length;
12957c478bd9Sstevel@tonic-gate 	arg.message_buffer.GSS_BUFFER_T_val = (char *)message_buffer->value;
12967c478bd9Sstevel@tonic-gate 
12977c478bd9Sstevel@tonic-gate 	/* call the remote procedure */
12987c478bd9Sstevel@tonic-gate 
12997c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
13007c478bd9Sstevel@tonic-gate 	if (gss_sign_1(&arg, &res, clnt) != RPC_SUCCESS) {
13017c478bd9Sstevel@tonic-gate 
13027c478bd9Sstevel@tonic-gate 	/*
13037c478bd9Sstevel@tonic-gate 	 * if the RPC call times out, null out all return arguments,
13047c478bd9Sstevel@tonic-gate 	 * set minor_status to its maximum value, and return GSS_S_FAILURE
13057c478bd9Sstevel@tonic-gate 	 */
13067c478bd9Sstevel@tonic-gate 
13077c478bd9Sstevel@tonic-gate 		if (minor_status != NULL)
1308ba7b222eSGlenn Barry 			*minor_status = DEFAULT_MINOR_STAT;
13097c478bd9Sstevel@tonic-gate 		if (msg_token != NULL)
13107c478bd9Sstevel@tonic-gate 			msg_token->length = 0;
13117c478bd9Sstevel@tonic-gate 
13127c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
13137c478bd9Sstevel@tonic-gate 	}
13147c478bd9Sstevel@tonic-gate 
13157c478bd9Sstevel@tonic-gate 	/* copy the rpc results into the return arguments */
13167c478bd9Sstevel@tonic-gate 
13177c478bd9Sstevel@tonic-gate 	if (minor_status != NULL)
13187c478bd9Sstevel@tonic-gate 		*minor_status = res.minor_status;
13197c478bd9Sstevel@tonic-gate 
13207c478bd9Sstevel@tonic-gate 	if (msg_token != NULL) {
13217c478bd9Sstevel@tonic-gate 		msg_token->length = res.msg_token.GSS_BUFFER_T_len;
13227c478bd9Sstevel@tonic-gate 		msg_token->value = (void *) MALLOC(msg_token->length);
13237c478bd9Sstevel@tonic-gate 		memcpy(msg_token->value, res.msg_token.GSS_BUFFER_T_val,
13247c478bd9Sstevel@tonic-gate 			msg_token->length);
13257c478bd9Sstevel@tonic-gate 	}
13267c478bd9Sstevel@tonic-gate 
13277c478bd9Sstevel@tonic-gate 	/*
13287c478bd9Sstevel@tonic-gate 	 * free the memory allocated for the results and return with the status
13297c478bd9Sstevel@tonic-gate 	 * received in the rpc call
13307c478bd9Sstevel@tonic-gate 	 */
13317c478bd9Sstevel@tonic-gate 
13327c478bd9Sstevel@tonic-gate 	clnt_freeres(clnt, xdr_gss_sign_res, (caddr_t)&res);
13337c478bd9Sstevel@tonic-gate 	return (res.status);
13347c478bd9Sstevel@tonic-gate }
13357c478bd9Sstevel@tonic-gate 
13367c478bd9Sstevel@tonic-gate OM_uint32
kgss_sign(OM_uint32 * minor_status,gss_ctx_id_t context_handle,int qop_req,gss_buffer_t message_buffer,gss_buffer_t msg_token)13377c478bd9Sstevel@tonic-gate kgss_sign(
13387c478bd9Sstevel@tonic-gate 		OM_uint32 *minor_status,
13397c478bd9Sstevel@tonic-gate 		gss_ctx_id_t context_handle,
13407c478bd9Sstevel@tonic-gate 		int qop_req,
13417c478bd9Sstevel@tonic-gate 		gss_buffer_t message_buffer,
13427c478bd9Sstevel@tonic-gate 		gss_buffer_t msg_token)
13437c478bd9Sstevel@tonic-gate {
13447c478bd9Sstevel@tonic-gate 		if (context_handle == GSS_C_NO_CONTEXT)
13457c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
13467c478bd9Sstevel@tonic-gate 
13477c478bd9Sstevel@tonic-gate 		return (KGSS_SIGN(minor_status,
1348d4f95bf4SRichard Lowe 		    context_handle, qop_req, message_buffer,
1349d4f95bf4SRichard Lowe 		    msg_token));
13507c478bd9Sstevel@tonic-gate }
13517c478bd9Sstevel@tonic-gate 
13527c478bd9Sstevel@tonic-gate OM_uint32
kgss_verify_wrapped(minor_status,context_handle,message_buffer,token_buffer,qop_state,gssd_context_verifier)13537c478bd9Sstevel@tonic-gate kgss_verify_wrapped(
13547c478bd9Sstevel@tonic-gate 		minor_status,
13557c478bd9Sstevel@tonic-gate 		context_handle,
13567c478bd9Sstevel@tonic-gate 		message_buffer,
13577c478bd9Sstevel@tonic-gate 		token_buffer,
13587c478bd9Sstevel@tonic-gate 		qop_state,
13597c478bd9Sstevel@tonic-gate 		gssd_context_verifier)
13607c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
13617c478bd9Sstevel@tonic-gate 	gssd_ctx_id_t context_handle;
13627c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_context_verifier;
13637c478bd9Sstevel@tonic-gate 	gss_buffer_t message_buffer;
13647c478bd9Sstevel@tonic-gate 	gss_buffer_t token_buffer;
13657c478bd9Sstevel@tonic-gate 	int *qop_state;
13667c478bd9Sstevel@tonic-gate {
13677c478bd9Sstevel@tonic-gate 	gss_verify_arg arg;
13687c478bd9Sstevel@tonic-gate 	gss_verify_res res;
13697c478bd9Sstevel@tonic-gate 
13707c478bd9Sstevel@tonic-gate /* get the client handle to GSSD */
13717c478bd9Sstevel@tonic-gate 
13727c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
13737c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
13747c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
13757c478bd9Sstevel@tonic-gate 	}
13767c478bd9Sstevel@tonic-gate 
13777c478bd9Sstevel@tonic-gate 	/* copy the procedure arguments into the rpc arg parameter */
13787c478bd9Sstevel@tonic-gate 
13797c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
13807c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
13817c478bd9Sstevel@tonic-gate 
13827c478bd9Sstevel@tonic-gate 	arg.gssd_context_verifier = gssd_context_verifier;
13837c478bd9Sstevel@tonic-gate 
13847c478bd9Sstevel@tonic-gate 	arg.message_buffer.GSS_BUFFER_T_len = (uint_t)message_buffer->length;
13857c478bd9Sstevel@tonic-gate 	arg.message_buffer.GSS_BUFFER_T_val = (char *)message_buffer->value;
13867c478bd9Sstevel@tonic-gate 
13877c478bd9Sstevel@tonic-gate 	arg.token_buffer.GSS_BUFFER_T_len = (uint_t)token_buffer->length;
13887c478bd9Sstevel@tonic-gate 	arg.token_buffer.GSS_BUFFER_T_val = (char *)token_buffer->value;
13897c478bd9Sstevel@tonic-gate 
13907c478bd9Sstevel@tonic-gate 	/* call the remote procedure */
13917c478bd9Sstevel@tonic-gate 
13927c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
13937c478bd9Sstevel@tonic-gate 	if (gss_verify_1(&arg, &res, clnt) != RPC_SUCCESS) {
13947c478bd9Sstevel@tonic-gate 
13957c478bd9Sstevel@tonic-gate 	/*
13967c478bd9Sstevel@tonic-gate 	 * if the RPC call times out, null out all return arguments,
13977c478bd9Sstevel@tonic-gate 	 * set minor_status to its maximum value, and return GSS_S_FAILURE
13987c478bd9Sstevel@tonic-gate 	 */
13997c478bd9Sstevel@tonic-gate 
14007c478bd9Sstevel@tonic-gate 		if (minor_status != NULL)
1401ba7b222eSGlenn Barry 			*minor_status = DEFAULT_MINOR_STAT;
14027c478bd9Sstevel@tonic-gate 		if (qop_state != NULL)
14037c478bd9Sstevel@tonic-gate 			*qop_state = 0;
14047c478bd9Sstevel@tonic-gate 
14057c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
14067c478bd9Sstevel@tonic-gate 	}
14077c478bd9Sstevel@tonic-gate 
14087c478bd9Sstevel@tonic-gate 	/* copy the rpc results into the return arguments */
14097c478bd9Sstevel@tonic-gate 
14107c478bd9Sstevel@tonic-gate 	if (minor_status != NULL)
14117c478bd9Sstevel@tonic-gate 		*minor_status = res.minor_status;
14127c478bd9Sstevel@tonic-gate 
14137c478bd9Sstevel@tonic-gate 	if (qop_state != NULL)
14147c478bd9Sstevel@tonic-gate 		*qop_state = res.qop_state;
14157c478bd9Sstevel@tonic-gate 
14167c478bd9Sstevel@tonic-gate 	/* return with status returned in rpc call */
14177c478bd9Sstevel@tonic-gate 
14187c478bd9Sstevel@tonic-gate 	return (res.status);
14197c478bd9Sstevel@tonic-gate }
14207c478bd9Sstevel@tonic-gate 
14217c478bd9Sstevel@tonic-gate OM_uint32
kgss_verify(OM_uint32 * minor_status,gss_ctx_id_t context_handle,gss_buffer_t message_buffer,gss_buffer_t token_buffer,int * qop_state)14227c478bd9Sstevel@tonic-gate kgss_verify(OM_uint32 *minor_status,
14237c478bd9Sstevel@tonic-gate 	gss_ctx_id_t context_handle,
14247c478bd9Sstevel@tonic-gate 	gss_buffer_t message_buffer,
14257c478bd9Sstevel@tonic-gate 	gss_buffer_t token_buffer,
14267c478bd9Sstevel@tonic-gate 	int *qop_state)
14277c478bd9Sstevel@tonic-gate {
14287c478bd9Sstevel@tonic-gate 		if (context_handle == GSS_C_NO_CONTEXT)
14297c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
14307c478bd9Sstevel@tonic-gate 
14317c478bd9Sstevel@tonic-gate 		return (KGSS_VERIFY(minor_status, context_handle,
1432d4f95bf4SRichard Lowe 		    message_buffer, token_buffer, qop_state));
14337c478bd9Sstevel@tonic-gate }
14347c478bd9Sstevel@tonic-gate 
14357c478bd9Sstevel@tonic-gate 
14367c478bd9Sstevel@tonic-gate OM_uint32
kgss_seal_wrapped(minor_status,context_handle,conf_req_flag,qop_req,input_message_buffer,conf_state,output_message_buffer,gssd_context_verifier)14377c478bd9Sstevel@tonic-gate kgss_seal_wrapped(
14387c478bd9Sstevel@tonic-gate 	minor_status,
14397c478bd9Sstevel@tonic-gate 	context_handle,
14407c478bd9Sstevel@tonic-gate 	conf_req_flag,
14417c478bd9Sstevel@tonic-gate 	qop_req,
14427c478bd9Sstevel@tonic-gate 	input_message_buffer,
14437c478bd9Sstevel@tonic-gate 	conf_state,
14447c478bd9Sstevel@tonic-gate 	output_message_buffer,
14457c478bd9Sstevel@tonic-gate 	gssd_context_verifier)
14467c478bd9Sstevel@tonic-gate 
14477c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
14487c478bd9Sstevel@tonic-gate 	gssd_ctx_id_t context_handle;
14497c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_context_verifier;
14507c478bd9Sstevel@tonic-gate 	int conf_req_flag;
14517c478bd9Sstevel@tonic-gate 	int qop_req;
14527c478bd9Sstevel@tonic-gate 	gss_buffer_t input_message_buffer;
14537c478bd9Sstevel@tonic-gate 	int *conf_state;
14547c478bd9Sstevel@tonic-gate 	gss_buffer_t output_message_buffer;
14557c478bd9Sstevel@tonic-gate {
14567c478bd9Sstevel@tonic-gate 	gss_seal_arg arg;
14577c478bd9Sstevel@tonic-gate 	gss_seal_res res;
14587c478bd9Sstevel@tonic-gate 
14597c478bd9Sstevel@tonic-gate 	/* get the client handle to GSSD */
14607c478bd9Sstevel@tonic-gate 
14617c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
14627c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
14637c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
14647c478bd9Sstevel@tonic-gate 	}
14657c478bd9Sstevel@tonic-gate 
14667c478bd9Sstevel@tonic-gate 	/* copy the procedure arguments into the rpc arg parameter */
14677c478bd9Sstevel@tonic-gate 
14687c478bd9Sstevel@tonic-gate 
14697c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
14707c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
14717c478bd9Sstevel@tonic-gate 	arg.gssd_context_verifier = gssd_context_verifier;
14727c478bd9Sstevel@tonic-gate 
14737c478bd9Sstevel@tonic-gate 	arg.conf_req_flag = conf_req_flag;
14747c478bd9Sstevel@tonic-gate 
14757c478bd9Sstevel@tonic-gate 	arg.qop_req = qop_req;
14767c478bd9Sstevel@tonic-gate 
14777c478bd9Sstevel@tonic-gate 	arg.input_message_buffer.GSS_BUFFER_T_len =
14787c478bd9Sstevel@tonic-gate 				(uint_t)input_message_buffer->length;
14797c478bd9Sstevel@tonic-gate 
14807c478bd9Sstevel@tonic-gate 	arg.input_message_buffer.GSS_BUFFER_T_val =
14817c478bd9Sstevel@tonic-gate 				(char *)input_message_buffer->value;
14827c478bd9Sstevel@tonic-gate 
14837c478bd9Sstevel@tonic-gate 	/* call the remote procedure */
14847c478bd9Sstevel@tonic-gate 
14857c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
14867c478bd9Sstevel@tonic-gate 	if (gss_seal_1(&arg, &res, clnt) != RPC_SUCCESS) {
14877c478bd9Sstevel@tonic-gate 
14887c478bd9Sstevel@tonic-gate 	/*
14897c478bd9Sstevel@tonic-gate 	 * if the RPC call times out, null out all return arguments,
14907c478bd9Sstevel@tonic-gate 	 * set minor_status to its maximum value, and return GSS_S_FAILURE
14917c478bd9Sstevel@tonic-gate 	 */
14927c478bd9Sstevel@tonic-gate 
14937c478bd9Sstevel@tonic-gate 		if (minor_status != NULL)
1494ba7b222eSGlenn Barry 			*minor_status = DEFAULT_MINOR_STAT;
14957c478bd9Sstevel@tonic-gate 		if (conf_state != NULL)
14967c478bd9Sstevel@tonic-gate 			*conf_state = 0;
14977c478bd9Sstevel@tonic-gate 		if (output_message_buffer != NULL)
14987c478bd9Sstevel@tonic-gate 			output_message_buffer->length = 0;
14997c478bd9Sstevel@tonic-gate 
15007c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
15017c478bd9Sstevel@tonic-gate 	}
15027c478bd9Sstevel@tonic-gate 
15037c478bd9Sstevel@tonic-gate 	/* copy the rpc results into the return arguments */
15047c478bd9Sstevel@tonic-gate 
15057c478bd9Sstevel@tonic-gate 	if (minor_status != NULL)
15067c478bd9Sstevel@tonic-gate 		*minor_status = res.minor_status;
15077c478bd9Sstevel@tonic-gate 
15087c478bd9Sstevel@tonic-gate 	if (conf_state != NULL)
15097c478bd9Sstevel@tonic-gate 		*conf_state = res.conf_state;
15107c478bd9Sstevel@tonic-gate 
15117c478bd9Sstevel@tonic-gate 	if (output_message_buffer != NULL) {
15127c478bd9Sstevel@tonic-gate 		output_message_buffer->length =
15137c478bd9Sstevel@tonic-gate 				res.output_message_buffer.GSS_BUFFER_T_len;
15147c478bd9Sstevel@tonic-gate 
15157c478bd9Sstevel@tonic-gate 		output_message_buffer->value =
15167c478bd9Sstevel@tonic-gate 				(void *) MALLOC(output_message_buffer->length);
15177c478bd9Sstevel@tonic-gate 		memcpy(output_message_buffer->value,
15187c478bd9Sstevel@tonic-gate 			res.output_message_buffer.GSS_BUFFER_T_val,
15197c478bd9Sstevel@tonic-gate 			output_message_buffer->length);
15207c478bd9Sstevel@tonic-gate 	}
15217c478bd9Sstevel@tonic-gate 
15227c478bd9Sstevel@tonic-gate 	/*
15237c478bd9Sstevel@tonic-gate 	 * free the memory allocated for the results and return with the status
15247c478bd9Sstevel@tonic-gate 	 * received in the rpc call
15257c478bd9Sstevel@tonic-gate 	 */
15267c478bd9Sstevel@tonic-gate 
15277c478bd9Sstevel@tonic-gate 	clnt_freeres(clnt, xdr_gss_seal_res, (caddr_t)&res);
15287c478bd9Sstevel@tonic-gate 	return (res.status);
15297c478bd9Sstevel@tonic-gate }
15307c478bd9Sstevel@tonic-gate 
15317c478bd9Sstevel@tonic-gate OM_uint32
kgss_seal(OM_uint32 * minor_status,gss_ctx_id_t context_handle,int conf_req_flag,int qop_req,gss_buffer_t input_message_buffer,int * conf_state,gss_buffer_t output_message_buffer)15327c478bd9Sstevel@tonic-gate kgss_seal(OM_uint32 *minor_status,
15337c478bd9Sstevel@tonic-gate 		gss_ctx_id_t context_handle,
15347c478bd9Sstevel@tonic-gate 		int conf_req_flag,
15357c478bd9Sstevel@tonic-gate 		int qop_req,
15367c478bd9Sstevel@tonic-gate 		gss_buffer_t input_message_buffer,
15377c478bd9Sstevel@tonic-gate 		int *conf_state,
15387c478bd9Sstevel@tonic-gate 		gss_buffer_t output_message_buffer)
15397c478bd9Sstevel@tonic-gate 
15407c478bd9Sstevel@tonic-gate {
15417c478bd9Sstevel@tonic-gate 		if (context_handle == GSS_C_NO_CONTEXT)
15427c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
15437c478bd9Sstevel@tonic-gate 
15447c478bd9Sstevel@tonic-gate 		return (KGSS_SEAL(minor_status, context_handle,
15457c478bd9Sstevel@tonic-gate 			conf_req_flag, qop_req,
15467c478bd9Sstevel@tonic-gate 			input_message_buffer,
15477c478bd9Sstevel@tonic-gate 			conf_state, output_message_buffer));
15487c478bd9Sstevel@tonic-gate }
15497c478bd9Sstevel@tonic-gate 
15507c478bd9Sstevel@tonic-gate OM_uint32
kgss_unseal_wrapped(minor_status,context_handle,input_message_buffer,output_message_buffer,conf_state,qop_state,gssd_context_verifier)15517c478bd9Sstevel@tonic-gate kgss_unseal_wrapped(minor_status,
15527c478bd9Sstevel@tonic-gate 		context_handle,
15537c478bd9Sstevel@tonic-gate 		input_message_buffer,
15547c478bd9Sstevel@tonic-gate 		output_message_buffer,
15557c478bd9Sstevel@tonic-gate 		conf_state,
15567c478bd9Sstevel@tonic-gate 		qop_state,
15577c478bd9Sstevel@tonic-gate 		gssd_context_verifier)
15587c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
15597c478bd9Sstevel@tonic-gate 	gssd_ctx_id_t context_handle;
15607c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_context_verifier;
15617c478bd9Sstevel@tonic-gate 	gss_buffer_t input_message_buffer;
15627c478bd9Sstevel@tonic-gate 	gss_buffer_t output_message_buffer;
15637c478bd9Sstevel@tonic-gate 	int *conf_state;
15647c478bd9Sstevel@tonic-gate 	int *qop_state;
15657c478bd9Sstevel@tonic-gate {
15667c478bd9Sstevel@tonic-gate 	gss_unseal_arg arg;
15677c478bd9Sstevel@tonic-gate 	gss_unseal_res res;
15687c478bd9Sstevel@tonic-gate 
15697c478bd9Sstevel@tonic-gate 	/* get the client handle to GSSD */
15707c478bd9Sstevel@tonic-gate 
15717c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
15727c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
15737c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
15747c478bd9Sstevel@tonic-gate 	}
15757c478bd9Sstevel@tonic-gate 
15767c478bd9Sstevel@tonic-gate 	/* copy the procedure arguments into the rpc arg parameter */
15777c478bd9Sstevel@tonic-gate 
15787c478bd9Sstevel@tonic-gate 
15797c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
15807c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
15817c478bd9Sstevel@tonic-gate 	arg.gssd_context_verifier = gssd_context_verifier;
15827c478bd9Sstevel@tonic-gate 
15837c478bd9Sstevel@tonic-gate 	arg.input_message_buffer.GSS_BUFFER_T_len =
15847c478bd9Sstevel@tonic-gate 				(uint_t)input_message_buffer->length;
15857c478bd9Sstevel@tonic-gate 
15867c478bd9Sstevel@tonic-gate 	arg.input_message_buffer.GSS_BUFFER_T_val =
15877c478bd9Sstevel@tonic-gate 				(char *)input_message_buffer->value;
15887c478bd9Sstevel@tonic-gate 
15897c478bd9Sstevel@tonic-gate /* call the remote procedure */
15907c478bd9Sstevel@tonic-gate 
15917c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
15927c478bd9Sstevel@tonic-gate 	if (gss_unseal_1(&arg, &res, clnt) != RPC_SUCCESS) {
15937c478bd9Sstevel@tonic-gate 
15947c478bd9Sstevel@tonic-gate 	/*
15957c478bd9Sstevel@tonic-gate 	 * if the RPC call times out, null out all return arguments,
15967c478bd9Sstevel@tonic-gate 	 * set minor_status to its maximum value, and return GSS_S_FAILURE
15977c478bd9Sstevel@tonic-gate 	 */
15987c478bd9Sstevel@tonic-gate 
15997c478bd9Sstevel@tonic-gate 		if (minor_status != NULL)
1600ba7b222eSGlenn Barry 			*minor_status = DEFAULT_MINOR_STAT;
16017c478bd9Sstevel@tonic-gate 		if (output_message_buffer != NULL)
16027c478bd9Sstevel@tonic-gate 			output_message_buffer->length = 0;
16037c478bd9Sstevel@tonic-gate 		if (conf_state != NULL)
16047c478bd9Sstevel@tonic-gate 			*conf_state = 0;
16057c478bd9Sstevel@tonic-gate 		if (qop_state != NULL)
16067c478bd9Sstevel@tonic-gate 			*qop_state = 0;
16077c478bd9Sstevel@tonic-gate 
16087c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
16097c478bd9Sstevel@tonic-gate 	}
16107c478bd9Sstevel@tonic-gate 
16117c478bd9Sstevel@tonic-gate 	/* copy the rpc results into the return arguments */
16127c478bd9Sstevel@tonic-gate 
16137c478bd9Sstevel@tonic-gate 	if (minor_status != NULL)
16147c478bd9Sstevel@tonic-gate 		*minor_status = res.minor_status;
16157c478bd9Sstevel@tonic-gate 
16167c478bd9Sstevel@tonic-gate 	if (output_message_buffer != NULL) {
16177c478bd9Sstevel@tonic-gate 		output_message_buffer->length =
16187c478bd9Sstevel@tonic-gate 				res.output_message_buffer.GSS_BUFFER_T_len;
16197c478bd9Sstevel@tonic-gate 
16207c478bd9Sstevel@tonic-gate 		output_message_buffer->value =
16217c478bd9Sstevel@tonic-gate 			(void *) MALLOC(output_message_buffer->length);
16227c478bd9Sstevel@tonic-gate 		memcpy(output_message_buffer->value,
16237c478bd9Sstevel@tonic-gate 			res.output_message_buffer.GSS_BUFFER_T_val,
16247c478bd9Sstevel@tonic-gate 			output_message_buffer->length);
16257c478bd9Sstevel@tonic-gate 	}
16267c478bd9Sstevel@tonic-gate 
16277c478bd9Sstevel@tonic-gate 	if (conf_state != NULL)
16287c478bd9Sstevel@tonic-gate 		*conf_state = res.conf_state;
16297c478bd9Sstevel@tonic-gate 
16307c478bd9Sstevel@tonic-gate 	if (qop_state != NULL)
16317c478bd9Sstevel@tonic-gate 		*qop_state = res.qop_state;
16327c478bd9Sstevel@tonic-gate 
16337c478bd9Sstevel@tonic-gate 	/*
16347c478bd9Sstevel@tonic-gate 	 * free the memory allocated for the results and return with the status
16357c478bd9Sstevel@tonic-gate 	 * received in the rpc call
16367c478bd9Sstevel@tonic-gate 	 */
16377c478bd9Sstevel@tonic-gate 
16387c478bd9Sstevel@tonic-gate 	clnt_freeres(clnt, xdr_gss_unseal_res, (caddr_t)&res);
16397c478bd9Sstevel@tonic-gate 	return (res.status);
16407c478bd9Sstevel@tonic-gate }
16417c478bd9Sstevel@tonic-gate 
16427c478bd9Sstevel@tonic-gate OM_uint32
kgss_unseal(OM_uint32 * minor_status,gss_ctx_id_t context_handle,gss_buffer_t input_message_buffer,gss_buffer_t output_message_buffer,int * conf_state,int * qop_state)16437c478bd9Sstevel@tonic-gate kgss_unseal(OM_uint32 *minor_status,
16447c478bd9Sstevel@tonic-gate 	gss_ctx_id_t context_handle,
16457c478bd9Sstevel@tonic-gate 	gss_buffer_t input_message_buffer,
16467c478bd9Sstevel@tonic-gate 	gss_buffer_t output_message_buffer,
16477c478bd9Sstevel@tonic-gate 	int *conf_state,
16487c478bd9Sstevel@tonic-gate 	int *qop_state)
16497c478bd9Sstevel@tonic-gate {
16507c478bd9Sstevel@tonic-gate 		if (context_handle == GSS_C_NO_CONTEXT)
16517c478bd9Sstevel@tonic-gate 			return (GSS_S_FAILURE);
16527c478bd9Sstevel@tonic-gate 
16537c478bd9Sstevel@tonic-gate 		return (KGSS_UNSEAL(minor_status, context_handle,
1654d4f95bf4SRichard Lowe 		    input_message_buffer, output_message_buffer,
1655d4f95bf4SRichard Lowe 		    conf_state, qop_state));
16567c478bd9Sstevel@tonic-gate }
16577c478bd9Sstevel@tonic-gate 
16587c478bd9Sstevel@tonic-gate OM_uint32
kgss_display_status(minor_status,status_value,status_type,mech_type,message_context,status_string,uid)16597c478bd9Sstevel@tonic-gate kgss_display_status(minor_status,
16607c478bd9Sstevel@tonic-gate 		status_value,
16617c478bd9Sstevel@tonic-gate 		status_type,
16627c478bd9Sstevel@tonic-gate 		mech_type,
16637c478bd9Sstevel@tonic-gate 		message_context,
16647c478bd9Sstevel@tonic-gate 		status_string,
16657c478bd9Sstevel@tonic-gate 		uid)
16667c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
16677c478bd9Sstevel@tonic-gate 	OM_uint32 status_value;
16687c478bd9Sstevel@tonic-gate 	int status_type;
16697c478bd9Sstevel@tonic-gate 	gss_OID mech_type;
16707c478bd9Sstevel@tonic-gate 	int *message_context;
16717c478bd9Sstevel@tonic-gate 	gss_buffer_t status_string;
16727c478bd9Sstevel@tonic-gate 	uid_t uid;
16737c478bd9Sstevel@tonic-gate {
16747c478bd9Sstevel@tonic-gate 	gss_display_status_arg arg;
16757c478bd9Sstevel@tonic-gate 	gss_display_status_res res;
16767c478bd9Sstevel@tonic-gate 
16777c478bd9Sstevel@tonic-gate 	/* get the client handle to GSSD */
16787c478bd9Sstevel@tonic-gate 
16797c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
16807c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
16817c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
16827c478bd9Sstevel@tonic-gate 	}
16837c478bd9Sstevel@tonic-gate 
16847c478bd9Sstevel@tonic-gate 	/* copy the procedure arguments into the rpc arg parameter */
16857c478bd9Sstevel@tonic-gate 
16867c478bd9Sstevel@tonic-gate 	arg.uid = (OM_uint32) uid;
16877c478bd9Sstevel@tonic-gate 
16887c478bd9Sstevel@tonic-gate 	arg.status_value = status_value;
16897c478bd9Sstevel@tonic-gate 	arg.status_type = status_type;
16907c478bd9Sstevel@tonic-gate 
16917c478bd9Sstevel@tonic-gate 	arg.mech_type.GSS_OID_len = (uint_t)(mech_type != GSS_C_NULL_OID ?
16927c478bd9Sstevel@tonic-gate 					mech_type->length : 0);
16937c478bd9Sstevel@tonic-gate 	arg.mech_type.GSS_OID_val = (char *)(mech_type != GSS_C_NULL_OID ?
16947c478bd9Sstevel@tonic-gate 					mech_type->elements : 0);
16957c478bd9Sstevel@tonic-gate 
16967c478bd9Sstevel@tonic-gate 	arg.message_context = *message_context;
16977c478bd9Sstevel@tonic-gate 
16987c478bd9Sstevel@tonic-gate 	/* call the remote procedure */
16997c478bd9Sstevel@tonic-gate 
17007c478bd9Sstevel@tonic-gate 	if (message_context != NULL)
17017c478bd9Sstevel@tonic-gate 		*message_context = 0;
17027c478bd9Sstevel@tonic-gate 	if (status_string != NULL) {
17037c478bd9Sstevel@tonic-gate 		status_string->length = 0;
17047c478bd9Sstevel@tonic-gate 		status_string->value = NULL;
17057c478bd9Sstevel@tonic-gate 	}
17067c478bd9Sstevel@tonic-gate 
17077c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
17087c478bd9Sstevel@tonic-gate 	if (gss_display_status_1(&arg, &res, clnt) != RPC_SUCCESS) {
17097c478bd9Sstevel@tonic-gate 
17107c478bd9Sstevel@tonic-gate 	/*
17117c478bd9Sstevel@tonic-gate 	 * if the RPC call times out, null out all return arguments,
17127c478bd9Sstevel@tonic-gate 	 * set minor_status to its maximum value, and return GSS_S_FAILURE
17137c478bd9Sstevel@tonic-gate 	 */
17147c478bd9Sstevel@tonic-gate 
17157c478bd9Sstevel@tonic-gate 		if (minor_status != NULL)
1716ba7b222eSGlenn Barry 			*minor_status = DEFAULT_MINOR_STAT;
17177c478bd9Sstevel@tonic-gate 
17187c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
17197c478bd9Sstevel@tonic-gate 	}
17207c478bd9Sstevel@tonic-gate 
1721ba7b222eSGlenn Barry 	if (minor_status != NULL)
1722ba7b222eSGlenn Barry 		*minor_status = res.minor_status;
17237c478bd9Sstevel@tonic-gate 
17247c478bd9Sstevel@tonic-gate 	/* now process the results and pass them back to the caller */
17257c478bd9Sstevel@tonic-gate 
17267c478bd9Sstevel@tonic-gate 	if (res.status == GSS_S_COMPLETE) {
17277c478bd9Sstevel@tonic-gate 		if (message_context != NULL)
17287c478bd9Sstevel@tonic-gate 			*message_context = res.message_context;
17297c478bd9Sstevel@tonic-gate 		if (status_string != NULL) {
17307c478bd9Sstevel@tonic-gate 			status_string->length =
17317c478bd9Sstevel@tonic-gate 				(size_t)res.status_string.GSS_BUFFER_T_len;
17327c478bd9Sstevel@tonic-gate 			status_string->value =
17337c478bd9Sstevel@tonic-gate 				(void *)MALLOC(status_string->length);
17347c478bd9Sstevel@tonic-gate 			memcpy(status_string->value,
17357c478bd9Sstevel@tonic-gate 				res.status_string.GSS_BUFFER_T_val,
17367c478bd9Sstevel@tonic-gate 				status_string->length);
17377c478bd9Sstevel@tonic-gate 		}
17387c478bd9Sstevel@tonic-gate 	}
17397c478bd9Sstevel@tonic-gate 
17407c478bd9Sstevel@tonic-gate 	clnt_freeres(clnt, xdr_gss_display_status_res, (caddr_t)&res);
17417c478bd9Sstevel@tonic-gate 	return (res.status);
17427c478bd9Sstevel@tonic-gate }
17437c478bd9Sstevel@tonic-gate 
17447c478bd9Sstevel@tonic-gate /*ARGSUSED*/
17457c478bd9Sstevel@tonic-gate OM_uint32
kgss_indicate_mechs(minor_status,mech_set,uid)17467c478bd9Sstevel@tonic-gate kgss_indicate_mechs(minor_status,
17477c478bd9Sstevel@tonic-gate 		mech_set,
17487c478bd9Sstevel@tonic-gate 		uid)
17497c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
17507c478bd9Sstevel@tonic-gate 	gss_OID_set *mech_set;
17517c478bd9Sstevel@tonic-gate 	uid_t uid;
17527c478bd9Sstevel@tonic-gate {
17537c478bd9Sstevel@tonic-gate 	void *arg;
17547c478bd9Sstevel@tonic-gate 	gss_indicate_mechs_res res;
17557c478bd9Sstevel@tonic-gate 	int i;
17567c478bd9Sstevel@tonic-gate 
17577c478bd9Sstevel@tonic-gate 	/* get the client handle to GSSD */
17587c478bd9Sstevel@tonic-gate 
17597c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
17607c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
17617c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
17627c478bd9Sstevel@tonic-gate 	}
17637c478bd9Sstevel@tonic-gate 
17647c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
17657c478bd9Sstevel@tonic-gate 	if (gss_indicate_mechs_1(&arg, &res, clnt) != RPC_SUCCESS) {
17667c478bd9Sstevel@tonic-gate 
17677c478bd9Sstevel@tonic-gate 	/*
17687c478bd9Sstevel@tonic-gate 	 * if the RPC call times out, null out all return arguments,
17697c478bd9Sstevel@tonic-gate 	 * set minor_status to its maximum value, and return GSS_S_FAILURE
17707c478bd9Sstevel@tonic-gate 	 */
17717c478bd9Sstevel@tonic-gate 
17727c478bd9Sstevel@tonic-gate 		if (minor_status != NULL)
1773ba7b222eSGlenn Barry 			*minor_status = DEFAULT_MINOR_STAT;
17747c478bd9Sstevel@tonic-gate 		if (mech_set != NULL)
17757c478bd9Sstevel@tonic-gate 			*mech_set = NULL;
17767c478bd9Sstevel@tonic-gate 
17777c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
17787c478bd9Sstevel@tonic-gate 	}
17797c478bd9Sstevel@tonic-gate 
17807c478bd9Sstevel@tonic-gate 	/* copy the rpc results into the return arguments */
17817c478bd9Sstevel@tonic-gate 
17827c478bd9Sstevel@tonic-gate 	if (minor_status != NULL)
17837c478bd9Sstevel@tonic-gate 		*minor_status = res.minor_status;
17847c478bd9Sstevel@tonic-gate 
17857c478bd9Sstevel@tonic-gate 	if (mech_set != NULL) {
17867c478bd9Sstevel@tonic-gate 		*mech_set = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
17877c478bd9Sstevel@tonic-gate 		(*mech_set)->count = res.mech_set.GSS_OID_SET_len;
17887c478bd9Sstevel@tonic-gate 		(*mech_set)->elements = (void *)
17897c478bd9Sstevel@tonic-gate 			MALLOC ((*mech_set)->count * sizeof (gss_OID_desc));
17907c478bd9Sstevel@tonic-gate 		for (i = 0; i < (*mech_set)->count; i++) {
17917c478bd9Sstevel@tonic-gate 			(*mech_set)->elements[i].length =
17927c478bd9Sstevel@tonic-gate 				res.mech_set.GSS_OID_SET_val[i].GSS_OID_len;
17937c478bd9Sstevel@tonic-gate 			(*mech_set)->elements[i].elements = (void *)
17947c478bd9Sstevel@tonic-gate 				MALLOC ((*mech_set)->elements[i].length);
17957c478bd9Sstevel@tonic-gate 			memcpy ((*mech_set)->elements[i].elements,
17967c478bd9Sstevel@tonic-gate 				res.mech_set.GSS_OID_SET_val[i].GSS_OID_val,
17977c478bd9Sstevel@tonic-gate 				(*mech_set)->elements[i].length);
17987c478bd9Sstevel@tonic-gate 		}
17997c478bd9Sstevel@tonic-gate 	}
18007c478bd9Sstevel@tonic-gate 
18017c478bd9Sstevel@tonic-gate 	/*
18027c478bd9Sstevel@tonic-gate 	 * free the memory allocated for the results and return with the status
18037c478bd9Sstevel@tonic-gate 	 * received in the rpc call
18047c478bd9Sstevel@tonic-gate 	 */
18057c478bd9Sstevel@tonic-gate 
18067c478bd9Sstevel@tonic-gate 	clnt_freeres(clnt, xdr_gss_indicate_mechs_res, (caddr_t)&res);
18077c478bd9Sstevel@tonic-gate 	return (res.status);
18087c478bd9Sstevel@tonic-gate }
18097c478bd9Sstevel@tonic-gate 
18107c478bd9Sstevel@tonic-gate 
18117c478bd9Sstevel@tonic-gate OM_uint32
kgss_inquire_cred_wrapped(minor_status,cred_handle,gssd_cred_verifier,name,lifetime,cred_usage,mechanisms,uid)18127c478bd9Sstevel@tonic-gate kgss_inquire_cred_wrapped(minor_status,
18137c478bd9Sstevel@tonic-gate 			cred_handle,
18147c478bd9Sstevel@tonic-gate 			gssd_cred_verifier,
18157c478bd9Sstevel@tonic-gate 			name,
18167c478bd9Sstevel@tonic-gate 			lifetime,
18177c478bd9Sstevel@tonic-gate 			cred_usage,
18187c478bd9Sstevel@tonic-gate 			mechanisms,
18197c478bd9Sstevel@tonic-gate 			uid)
18207c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
18217c478bd9Sstevel@tonic-gate 	gssd_cred_id_t cred_handle;
18227c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_cred_verifier;
18237c478bd9Sstevel@tonic-gate 	gss_name_t *name;
18247c478bd9Sstevel@tonic-gate 	OM_uint32 *lifetime;
18257c478bd9Sstevel@tonic-gate 	int *cred_usage;
18267c478bd9Sstevel@tonic-gate 	gss_OID_set *mechanisms;
18277c478bd9Sstevel@tonic-gate 	uid_t uid;
18287c478bd9Sstevel@tonic-gate {
18297c478bd9Sstevel@tonic-gate 	OM_uint32 minor_status_temp;
18307c478bd9Sstevel@tonic-gate 	gss_buffer_desc external_name;
18317c478bd9Sstevel@tonic-gate 	gss_OID name_type;
18327c478bd9Sstevel@tonic-gate 	int i;
18337c478bd9Sstevel@tonic-gate 
18347c478bd9Sstevel@tonic-gate 	gss_inquire_cred_arg arg;
18357c478bd9Sstevel@tonic-gate 	gss_inquire_cred_res res;
18367c478bd9Sstevel@tonic-gate 
18377c478bd9Sstevel@tonic-gate 	/* get the client handle to GSSD */
18387c478bd9Sstevel@tonic-gate 
18397c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
18407c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
18417c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
18427c478bd9Sstevel@tonic-gate 	}
18437c478bd9Sstevel@tonic-gate 
18447c478bd9Sstevel@tonic-gate 
18457c478bd9Sstevel@tonic-gate 	/* copy the procedure arguments into the rpc arg parameter */
18467c478bd9Sstevel@tonic-gate 
18477c478bd9Sstevel@tonic-gate 	arg.uid = (OM_uint32) uid;
18487c478bd9Sstevel@tonic-gate 
18497c478bd9Sstevel@tonic-gate 	arg.cred_handle.GSS_CRED_ID_T_len =
1850d4f95bf4SRichard Lowe 			cred_handle == GSSD_NO_CREDENTIAL ?
18517c478bd9Sstevel@tonic-gate 			0 : (uint_t)sizeof (gssd_cred_id_t);
18527c478bd9Sstevel@tonic-gate 	arg.cred_handle.GSS_CRED_ID_T_val = (char *)&cred_handle;
18537c478bd9Sstevel@tonic-gate 	arg.gssd_cred_verifier = gssd_cred_verifier;
18547c478bd9Sstevel@tonic-gate 
18557c478bd9Sstevel@tonic-gate 	/* call the remote procedure */
18567c478bd9Sstevel@tonic-gate 
18577c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
18587c478bd9Sstevel@tonic-gate 	if (gss_inquire_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
18597c478bd9Sstevel@tonic-gate 
18607c478bd9Sstevel@tonic-gate 	/*
18617c478bd9Sstevel@tonic-gate 	 * if the RPC call times out, null out all return arguments,
18627c478bd9Sstevel@tonic-gate 	 * set minor_status to its maximum value, and return GSS_S_FAILURE
18637c478bd9Sstevel@tonic-gate 	 */
18647c478bd9Sstevel@tonic-gate 
18657c478bd9Sstevel@tonic-gate 		if (minor_status != NULL)
1866ba7b222eSGlenn Barry 			*minor_status = DEFAULT_MINOR_STAT;
18677c478bd9Sstevel@tonic-gate 		if (name != NULL)
18687c478bd9Sstevel@tonic-gate 			*name = NULL;
18697c478bd9Sstevel@tonic-gate 		if (lifetime != NULL)
18707c478bd9Sstevel@tonic-gate 			*lifetime = 0;
18717c478bd9Sstevel@tonic-gate 		if (cred_usage != NULL)
18727c478bd9Sstevel@tonic-gate 			*cred_usage = 0;
18737c478bd9Sstevel@tonic-gate 		if (mechanisms != NULL)
18747c478bd9Sstevel@tonic-gate 			*mechanisms = NULL;
18757c478bd9Sstevel@tonic-gate 
18767c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
18777c478bd9Sstevel@tonic-gate 	}
18787c478bd9Sstevel@tonic-gate 
18797c478bd9Sstevel@tonic-gate 	/* copy the rpc results into the return arguments */
18807c478bd9Sstevel@tonic-gate 
18817c478bd9Sstevel@tonic-gate 	if (minor_status != NULL)
18827c478bd9Sstevel@tonic-gate 		*minor_status = res.minor_status;
18837c478bd9Sstevel@tonic-gate 
18847c478bd9Sstevel@tonic-gate 	/* convert name from external to internal format */
18857c478bd9Sstevel@tonic-gate 
18867c478bd9Sstevel@tonic-gate 	if (name != NULL) {
18877c478bd9Sstevel@tonic-gate 		external_name.length = res.name.GSS_BUFFER_T_len;
18887c478bd9Sstevel@tonic-gate 		external_name.value = res.name.GSS_BUFFER_T_val;
18897c478bd9Sstevel@tonic-gate 
18907c478bd9Sstevel@tonic-gate 		/*
18917c478bd9Sstevel@tonic-gate 		 * we have to allocate a name_type descriptor and
18927c478bd9Sstevel@tonic-gate 		 * elements storage, since gss_import_name() only
18937c478bd9Sstevel@tonic-gate 		 * stores a pointer to the name_type info in the
18947c478bd9Sstevel@tonic-gate 		 * union_name struct
18957c478bd9Sstevel@tonic-gate 		 */
18967c478bd9Sstevel@tonic-gate 
18977c478bd9Sstevel@tonic-gate 		name_type = (gss_OID) MALLOC(sizeof (gss_OID_desc));
18987c478bd9Sstevel@tonic-gate 
18997c478bd9Sstevel@tonic-gate 		name_type->length = res.name_type.GSS_OID_len;
19007c478bd9Sstevel@tonic-gate 		name_type->elements = (void *) MALLOC(name_type->length);
19017c478bd9Sstevel@tonic-gate 		memcpy(name_type->elements, res.name_type.GSS_OID_val,
19027c478bd9Sstevel@tonic-gate 			name_type->length);
19037c478bd9Sstevel@tonic-gate 
19047c478bd9Sstevel@tonic-gate 		if (gss_import_name(&minor_status_temp, &external_name,
19057c478bd9Sstevel@tonic-gate 			name_type, name) != GSS_S_COMPLETE) {
19067c478bd9Sstevel@tonic-gate 
19077c478bd9Sstevel@tonic-gate 			*minor_status = (OM_uint32) minor_status_temp;
19087c478bd9Sstevel@tonic-gate 			gss_release_buffer(&minor_status_temp, &external_name);
19097c478bd9Sstevel@tonic-gate 
19107c478bd9Sstevel@tonic-gate 			clnt_freeres(clnt, xdr_gss_inquire_cred_res,
19117c478bd9Sstevel@tonic-gate 							(caddr_t)&res);
19127c478bd9Sstevel@tonic-gate 			return ((OM_uint32) GSS_S_FAILURE);
19137c478bd9Sstevel@tonic-gate 		}
19147c478bd9Sstevel@tonic-gate 	}
19157c478bd9Sstevel@tonic-gate 
19167c478bd9Sstevel@tonic-gate 	if (lifetime != NULL)
19177c478bd9Sstevel@tonic-gate 		*lifetime = res.lifetime;
19187c478bd9Sstevel@tonic-gate 
19197c478bd9Sstevel@tonic-gate 	if (cred_usage != NULL)
19207c478bd9Sstevel@tonic-gate 		*cred_usage = res.cred_usage;
19217c478bd9Sstevel@tonic-gate 
19227c478bd9Sstevel@tonic-gate 	if (mechanisms != NULL) {
19237c478bd9Sstevel@tonic-gate 		*mechanisms =
19247c478bd9Sstevel@tonic-gate 			(gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
19257c478bd9Sstevel@tonic-gate 		if (res.mechanisms.GSS_OID_SET_len != 0) {
19267c478bd9Sstevel@tonic-gate 			(*mechanisms)->count =
19277c478bd9Sstevel@tonic-gate 					(int)res.mechanisms.GSS_OID_SET_len;
19287c478bd9Sstevel@tonic-gate 			(*mechanisms)->elements = (gss_OID)
19297c478bd9Sstevel@tonic-gate 				MALLOC(sizeof (gss_OID) * (*mechanisms)->count);
19307c478bd9Sstevel@tonic-gate 
19317c478bd9Sstevel@tonic-gate 			for (i = 0; i < (*mechanisms)->count; i++) {
19327c478bd9Sstevel@tonic-gate 				(*mechanisms)->elements[i].length = (OM_uint32)
19337c478bd9Sstevel@tonic-gate 				res.mechanisms.GSS_OID_SET_val[i].GSS_OID_len;
19347c478bd9Sstevel@tonic-gate 				(*mechanisms)->elements[i].elements = (void *)
19357c478bd9Sstevel@tonic-gate 				MALLOC((*mechanisms)->elements[i].length);
19367c478bd9Sstevel@tonic-gate 				memcpy((*mechanisms)->elements[i].elements,
19377c478bd9Sstevel@tonic-gate 				res.mechanisms.GSS_OID_SET_val[i].GSS_OID_val,
19387c478bd9Sstevel@tonic-gate 				(*mechanisms)->elements[i].length);
19397c478bd9Sstevel@tonic-gate 			}
19407c478bd9Sstevel@tonic-gate 		} else
19417c478bd9Sstevel@tonic-gate 			(*mechanisms)->count = 0;
19427c478bd9Sstevel@tonic-gate 	}
19437c478bd9Sstevel@tonic-gate 
19447c478bd9Sstevel@tonic-gate 	/*
19457c478bd9Sstevel@tonic-gate 	 * free the memory allocated for the results and return with the status
19467c478bd9Sstevel@tonic-gate 	 * received in the rpc call
19477c478bd9Sstevel@tonic-gate 	 */
19487c478bd9Sstevel@tonic-gate 
19497c478bd9Sstevel@tonic-gate 	clnt_freeres(clnt, xdr_gss_inquire_cred_res, (caddr_t)&res);
19507c478bd9Sstevel@tonic-gate 	return (res.status);
19517c478bd9Sstevel@tonic-gate }
19527c478bd9Sstevel@tonic-gate 
19537c478bd9Sstevel@tonic-gate 
19547c478bd9Sstevel@tonic-gate OM_uint32
kgss_inquire_cred(minor_status,cred_handle,name,lifetime,cred_usage,mechanisms,uid)19557c478bd9Sstevel@tonic-gate kgss_inquire_cred(minor_status,
19567c478bd9Sstevel@tonic-gate 			cred_handle,
19577c478bd9Sstevel@tonic-gate 			name,
19587c478bd9Sstevel@tonic-gate 			lifetime,
19597c478bd9Sstevel@tonic-gate 			cred_usage,
19607c478bd9Sstevel@tonic-gate 			mechanisms,
19617c478bd9Sstevel@tonic-gate 			uid)
19627c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
19637c478bd9Sstevel@tonic-gate 	gss_cred_id_t cred_handle;
19647c478bd9Sstevel@tonic-gate 	gss_name_t *name;
19657c478bd9Sstevel@tonic-gate 	OM_uint32 *lifetime;
19667c478bd9Sstevel@tonic-gate 	int *cred_usage;
19677c478bd9Sstevel@tonic-gate 	gss_OID_set * mechanisms;
19687c478bd9Sstevel@tonic-gate 	uid_t uid;
19697c478bd9Sstevel@tonic-gate {
19707c478bd9Sstevel@tonic-gate 
19717c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_cred_verifier;
19727c478bd9Sstevel@tonic-gate 	gssd_cred_id_t gssd_cred_handle;
19737c478bd9Sstevel@tonic-gate 
19747c478bd9Sstevel@tonic-gate 		gssd_cred_verifier = KCRED_TO_CREDV(cred_handle);
19757c478bd9Sstevel@tonic-gate 		gssd_cred_handle = KCRED_TO_CRED(cred_handle);
19767c478bd9Sstevel@tonic-gate 
19777c478bd9Sstevel@tonic-gate 		return (kgss_inquire_cred_wrapped(minor_status,
19787c478bd9Sstevel@tonic-gate 				gssd_cred_handle, gssd_cred_verifier,
19797c478bd9Sstevel@tonic-gate 				name, lifetime, cred_usage, mechanisms, uid));
19807c478bd9Sstevel@tonic-gate }
19817c478bd9Sstevel@tonic-gate 
19827c478bd9Sstevel@tonic-gate 
19837c478bd9Sstevel@tonic-gate OM_uint32
kgss_inquire_cred_by_mech_wrapped(minor_status,cred_handle,gssd_cred_verifier,mech_type,uid)19847c478bd9Sstevel@tonic-gate kgss_inquire_cred_by_mech_wrapped(minor_status,
19857c478bd9Sstevel@tonic-gate 			cred_handle,
19867c478bd9Sstevel@tonic-gate 			gssd_cred_verifier,
19877c478bd9Sstevel@tonic-gate 			mech_type,
19887c478bd9Sstevel@tonic-gate 			uid)
19897c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
19907c478bd9Sstevel@tonic-gate 	gssd_cred_id_t cred_handle;
19917c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_cred_verifier;
19927c478bd9Sstevel@tonic-gate 	gss_OID mech_type;
19937c478bd9Sstevel@tonic-gate 	uid_t uid;
19947c478bd9Sstevel@tonic-gate {
19957c478bd9Sstevel@tonic-gate 	OM_uint32 minor_status_temp;
19967c478bd9Sstevel@tonic-gate 
19977c478bd9Sstevel@tonic-gate 	gss_inquire_cred_by_mech_arg arg;
19987c478bd9Sstevel@tonic-gate 	gss_inquire_cred_by_mech_res res;
19997c478bd9Sstevel@tonic-gate 
20007c478bd9Sstevel@tonic-gate 	/* get the client handle to GSSD */
20017c478bd9Sstevel@tonic-gate 
20027c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
20037c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
20047c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
20057c478bd9Sstevel@tonic-gate 	}
20067c478bd9Sstevel@tonic-gate 
20077c478bd9Sstevel@tonic-gate 
20087c478bd9Sstevel@tonic-gate 	/* copy the procedure arguments into the rpc arg parameter */
20097c478bd9Sstevel@tonic-gate 
20107c478bd9Sstevel@tonic-gate 	arg.uid = (OM_uint32) uid;
20117c478bd9Sstevel@tonic-gate 
20127c478bd9Sstevel@tonic-gate 	arg.cred_handle.GSS_CRED_ID_T_len =
2013d4f95bf4SRichard Lowe 			cred_handle == GSSD_NO_CREDENTIAL ?
20147c478bd9Sstevel@tonic-gate 			0 : (uint_t)sizeof (gssd_cred_id_t);
20157c478bd9Sstevel@tonic-gate 	arg.cred_handle.GSS_CRED_ID_T_val = (char *)&cred_handle;
20167c478bd9Sstevel@tonic-gate 	arg.gssd_cred_verifier = gssd_cred_verifier;
20177c478bd9Sstevel@tonic-gate 
20187c478bd9Sstevel@tonic-gate 	arg.mech_type.GSS_OID_len =
20197c478bd9Sstevel@tonic-gate 		(uint_t)(mech_type != GSS_C_NULL_OID ?
20207c478bd9Sstevel@tonic-gate 		mech_type->length : 0);
20217c478bd9Sstevel@tonic-gate 	arg.mech_type.GSS_OID_val =
20227c478bd9Sstevel@tonic-gate 		(char *)(mech_type != GSS_C_NULL_OID ?
20237c478bd9Sstevel@tonic-gate 		mech_type->elements : 0);
20247c478bd9Sstevel@tonic-gate 	/* call the remote procedure */
20257c478bd9Sstevel@tonic-gate 
20267c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
20277c478bd9Sstevel@tonic-gate 	if (gss_inquire_cred_by_mech_1(&arg, &res, clnt) != RPC_SUCCESS) {
20287c478bd9Sstevel@tonic-gate 
20297c478bd9Sstevel@tonic-gate 	/*
20307c478bd9Sstevel@tonic-gate 	 * if the RPC call times out, null out all return arguments,
20317c478bd9Sstevel@tonic-gate 	 * set minor_status to its maximum value, and return GSS_S_FAILURE
20327c478bd9Sstevel@tonic-gate 	 */
20337c478bd9Sstevel@tonic-gate 
20347c478bd9Sstevel@tonic-gate 		if (minor_status != NULL)
2035ba7b222eSGlenn Barry 			*minor_status = DEFAULT_MINOR_STAT;
20367c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
20377c478bd9Sstevel@tonic-gate 	}
20387c478bd9Sstevel@tonic-gate 
20397c478bd9Sstevel@tonic-gate 	/* copy the rpc results into the return arguments */
20407c478bd9Sstevel@tonic-gate 
20417c478bd9Sstevel@tonic-gate 	if (minor_status != NULL)
20427c478bd9Sstevel@tonic-gate 		*minor_status = res.minor_status;
20437c478bd9Sstevel@tonic-gate 
20447c478bd9Sstevel@tonic-gate 	/* convert name from external to internal format */
20457c478bd9Sstevel@tonic-gate 
20467c478bd9Sstevel@tonic-gate 	/*
20477c478bd9Sstevel@tonic-gate 	 * free the memory allocated for the results and return with the status
20487c478bd9Sstevel@tonic-gate 	 * received in the rpc call
20497c478bd9Sstevel@tonic-gate 	 */
20507c478bd9Sstevel@tonic-gate 
20517c478bd9Sstevel@tonic-gate 	clnt_freeres(clnt, xdr_gss_inquire_cred_by_mech_res, (caddr_t)&res);
20527c478bd9Sstevel@tonic-gate 	return (res.status);
20537c478bd9Sstevel@tonic-gate }
20547c478bd9Sstevel@tonic-gate 
20557c478bd9Sstevel@tonic-gate 
20567c478bd9Sstevel@tonic-gate OM_uint32
kgss_inquire_cred_by_mech(minor_status,cred_handle,mech_type,uid)20577c478bd9Sstevel@tonic-gate kgss_inquire_cred_by_mech(minor_status,
20587c478bd9Sstevel@tonic-gate 			cred_handle,
20597c478bd9Sstevel@tonic-gate 			mech_type,
20607c478bd9Sstevel@tonic-gate 			uid)
20617c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
20627c478bd9Sstevel@tonic-gate 	gss_cred_id_t cred_handle;
20637c478bd9Sstevel@tonic-gate 	gss_OID mech_type;
20647c478bd9Sstevel@tonic-gate 	uid_t uid;
20657c478bd9Sstevel@tonic-gate {
20667c478bd9Sstevel@tonic-gate 
20677c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_cred_verifier;
20687c478bd9Sstevel@tonic-gate 	gssd_cred_id_t gssd_cred_handle;
20697c478bd9Sstevel@tonic-gate 
20707c478bd9Sstevel@tonic-gate 	gssd_cred_verifier = KCRED_TO_CREDV(cred_handle);
20717c478bd9Sstevel@tonic-gate 	gssd_cred_handle = KCRED_TO_CRED(cred_handle);
20727c478bd9Sstevel@tonic-gate 
20737c478bd9Sstevel@tonic-gate 	return (kgss_inquire_cred_by_mech_wrapped(minor_status,
20747c478bd9Sstevel@tonic-gate 			gssd_cred_handle, gssd_cred_verifier,
20757c478bd9Sstevel@tonic-gate 			mech_type, uid));
20767c478bd9Sstevel@tonic-gate }
20777c478bd9Sstevel@tonic-gate 
20787c478bd9Sstevel@tonic-gate OM_uint32
kgsscred_expname_to_unix_cred(expName,uidOut,gidOut,gids,gidsLen,uid)20797c478bd9Sstevel@tonic-gate kgsscred_expname_to_unix_cred(expName, uidOut, gidOut, gids, gidsLen, uid)
20807c478bd9Sstevel@tonic-gate 	const gss_buffer_t expName;
20817c478bd9Sstevel@tonic-gate 	uid_t *uidOut;
20827c478bd9Sstevel@tonic-gate 	gid_t *gidOut;
20837c478bd9Sstevel@tonic-gate 	gid_t *gids[];
20847c478bd9Sstevel@tonic-gate 	int *gidsLen;
20857c478bd9Sstevel@tonic-gate 	uid_t uid;
20867c478bd9Sstevel@tonic-gate {
20877c478bd9Sstevel@tonic-gate 	gsscred_expname_to_unix_cred_arg args;
20887c478bd9Sstevel@tonic-gate 	gsscred_expname_to_unix_cred_res res;
20897c478bd9Sstevel@tonic-gate 
20907c478bd9Sstevel@tonic-gate 	/* check input/output parameters */
20917c478bd9Sstevel@tonic-gate 	if (expName == NULL || expName->value == NULL)
20927c478bd9Sstevel@tonic-gate 		return (GSS_S_CALL_INACCESSIBLE_READ);
20937c478bd9Sstevel@tonic-gate 
20947c478bd9Sstevel@tonic-gate 	if (uidOut == NULL)
20957c478bd9Sstevel@tonic-gate 		return (GSS_S_CALL_INACCESSIBLE_WRITE);
20967c478bd9Sstevel@tonic-gate 
20977c478bd9Sstevel@tonic-gate 	/* NULL out output parameters */
20987c478bd9Sstevel@tonic-gate 	*uidOut = 0;
20997c478bd9Sstevel@tonic-gate 	if (gidsLen)
21007c478bd9Sstevel@tonic-gate 		*gidsLen = 0;
21017c478bd9Sstevel@tonic-gate 
21027c478bd9Sstevel@tonic-gate 	if (gids)
21037c478bd9Sstevel@tonic-gate 		*gids = NULL;
21047c478bd9Sstevel@tonic-gate 
21057c478bd9Sstevel@tonic-gate 	/* get the client handle to gssd */
21067c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL)
21077c478bd9Sstevel@tonic-gate 	{
21087c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
21097c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
21107c478bd9Sstevel@tonic-gate 	}
21117c478bd9Sstevel@tonic-gate 
21127c478bd9Sstevel@tonic-gate 	/* copy the procedure arguments */
21137c478bd9Sstevel@tonic-gate 	args.uid = uid;
21147c478bd9Sstevel@tonic-gate 	args.expname.GSS_BUFFER_T_val = expName->value;
21157c478bd9Sstevel@tonic-gate 	args.expname.GSS_BUFFER_T_len = expName->length;
21167c478bd9Sstevel@tonic-gate 
21177c478bd9Sstevel@tonic-gate 	/* null out the return buffer and call the remote proc */
21187c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
21197c478bd9Sstevel@tonic-gate 
21207c478bd9Sstevel@tonic-gate 	if (gsscred_expname_to_unix_cred_1(&args, &res, clnt) != RPC_SUCCESS)
21217c478bd9Sstevel@tonic-gate 	{
21227c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
21237c478bd9Sstevel@tonic-gate 	}
21247c478bd9Sstevel@tonic-gate 
21257c478bd9Sstevel@tonic-gate 	/* copy the results into the result parameters */
21267c478bd9Sstevel@tonic-gate 	if (res.major == GSS_S_COMPLETE)
21277c478bd9Sstevel@tonic-gate 	{
21287c478bd9Sstevel@tonic-gate 		*uidOut = res.uid;
21297c478bd9Sstevel@tonic-gate 		if (gidOut)
21307c478bd9Sstevel@tonic-gate 			*gidOut = res.gid;
21317c478bd9Sstevel@tonic-gate 		if (gids && gidsLen)
21327c478bd9Sstevel@tonic-gate 		{
21337c478bd9Sstevel@tonic-gate 			*gids = res.gids.GSSCRED_GIDS_val;
21347c478bd9Sstevel@tonic-gate 			*gidsLen = res.gids.GSSCRED_GIDS_len;
21357c478bd9Sstevel@tonic-gate 			res.gids.GSSCRED_GIDS_val = NULL;
21367c478bd9Sstevel@tonic-gate 			res.gids.GSSCRED_GIDS_len = 0;
21377c478bd9Sstevel@tonic-gate 		}
21387c478bd9Sstevel@tonic-gate 	}
21397c478bd9Sstevel@tonic-gate 
21407c478bd9Sstevel@tonic-gate 	/* free RPC results */
21417c478bd9Sstevel@tonic-gate 	clnt_freeres(clnt, xdr_gsscred_expname_to_unix_cred_res, (caddr_t)&res);
21427c478bd9Sstevel@tonic-gate 
21437c478bd9Sstevel@tonic-gate 	return (res.major);
21447c478bd9Sstevel@tonic-gate } /* kgsscred_expname_to_unix_cred */
21457c478bd9Sstevel@tonic-gate 
21467c478bd9Sstevel@tonic-gate OM_uint32
kgsscred_name_to_unix_cred(intName,mechType,uidOut,gidOut,gids,gidsLen,uid)21477c478bd9Sstevel@tonic-gate kgsscred_name_to_unix_cred(intName, mechType, uidOut, gidOut, gids,
21487c478bd9Sstevel@tonic-gate 				gidsLen, uid)
21497c478bd9Sstevel@tonic-gate 	const gss_name_t intName;
21507c478bd9Sstevel@tonic-gate 	const gss_OID mechType;
21517c478bd9Sstevel@tonic-gate 	uid_t *uidOut;
21527c478bd9Sstevel@tonic-gate 	gid_t *gidOut;
21537c478bd9Sstevel@tonic-gate 	gid_t *gids[];
21547c478bd9Sstevel@tonic-gate 	int *gidsLen;
21557c478bd9Sstevel@tonic-gate 	uid_t uid;
21567c478bd9Sstevel@tonic-gate {
21577c478bd9Sstevel@tonic-gate 	gsscred_name_to_unix_cred_arg args;
21587c478bd9Sstevel@tonic-gate 	gsscred_name_to_unix_cred_res res;
21597c478bd9Sstevel@tonic-gate 	OM_uint32 major, minor;
21607c478bd9Sstevel@tonic-gate 	gss_OID nameOid;
21617c478bd9Sstevel@tonic-gate 	gss_buffer_desc flatName = GSS_C_EMPTY_BUFFER;
21627c478bd9Sstevel@tonic-gate 
21637c478bd9Sstevel@tonic-gate 
21647c478bd9Sstevel@tonic-gate 	/* check the input/output parameters */
21657c478bd9Sstevel@tonic-gate 	if (intName == NULL || mechType == NULL)
21667c478bd9Sstevel@tonic-gate 		return (GSS_S_CALL_INACCESSIBLE_READ);
21677c478bd9Sstevel@tonic-gate 
21687c478bd9Sstevel@tonic-gate 	if (uidOut == NULL)
21697c478bd9Sstevel@tonic-gate 		return (GSS_S_CALL_INACCESSIBLE_WRITE);
21707c478bd9Sstevel@tonic-gate 
21717c478bd9Sstevel@tonic-gate 	/* NULL out the output parameters */
21727c478bd9Sstevel@tonic-gate 	*uidOut = 0;
21737c478bd9Sstevel@tonic-gate 	if (gids)
21747c478bd9Sstevel@tonic-gate 		*gids = NULL;
21757c478bd9Sstevel@tonic-gate 
21767c478bd9Sstevel@tonic-gate 	if (gidsLen)
21777c478bd9Sstevel@tonic-gate 		*gidsLen = 0;
21787c478bd9Sstevel@tonic-gate 
21797c478bd9Sstevel@tonic-gate 	/* get the client handle to gssd */
21807c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL)
21817c478bd9Sstevel@tonic-gate 	{
21827c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
21837c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
21847c478bd9Sstevel@tonic-gate 	}
21857c478bd9Sstevel@tonic-gate 
21867c478bd9Sstevel@tonic-gate 	/* convert the name to flat representation */
21877c478bd9Sstevel@tonic-gate 	if ((major = gss_display_name(&minor, intName, &flatName, &nameOid))
21887c478bd9Sstevel@tonic-gate 			!= GSS_S_COMPLETE)
21897c478bd9Sstevel@tonic-gate 	{
21907c478bd9Sstevel@tonic-gate 		return (major);
21917c478bd9Sstevel@tonic-gate 	}
21927c478bd9Sstevel@tonic-gate 
21937c478bd9Sstevel@tonic-gate 	/* set the rpc parameters */
21947c478bd9Sstevel@tonic-gate 	args.uid = uid;
21957c478bd9Sstevel@tonic-gate 	args.pname.GSS_BUFFER_T_len = flatName.length;
21967c478bd9Sstevel@tonic-gate 	args.pname.GSS_BUFFER_T_val = flatName.value;
21977c478bd9Sstevel@tonic-gate 	args.name_type.GSS_OID_len = nameOid->length;
21987c478bd9Sstevel@tonic-gate 	args.name_type.GSS_OID_val = nameOid->elements;
21997c478bd9Sstevel@tonic-gate 	args.mech_type.GSS_OID_len = mechType->length;
22007c478bd9Sstevel@tonic-gate 	args.mech_type.GSS_OID_val = mechType->elements;
22017c478bd9Sstevel@tonic-gate 
22027c478bd9Sstevel@tonic-gate 	/* call the remote procedure */
22037c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
22047c478bd9Sstevel@tonic-gate 	if (gsscred_name_to_unix_cred_1(&args, &res, clnt) != RPC_SUCCESS)
22057c478bd9Sstevel@tonic-gate 	{
22067c478bd9Sstevel@tonic-gate 		gss_release_buffer(&minor, &flatName);
22077c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
22087c478bd9Sstevel@tonic-gate 	}
22097c478bd9Sstevel@tonic-gate 
22107c478bd9Sstevel@tonic-gate 	gss_release_buffer(&minor, &flatName);
22117c478bd9Sstevel@tonic-gate 	/* copy the output parameters on output */
22127c478bd9Sstevel@tonic-gate 	if (res.major == GSS_S_COMPLETE)
22137c478bd9Sstevel@tonic-gate 	{
22147c478bd9Sstevel@tonic-gate 		*uidOut = res.uid;
22157c478bd9Sstevel@tonic-gate 		if (gidOut)
22167c478bd9Sstevel@tonic-gate 			*gidOut = res.gid;
22177c478bd9Sstevel@tonic-gate 		if (gids && gidsLen)
22187c478bd9Sstevel@tonic-gate 		{
22197c478bd9Sstevel@tonic-gate 			*gids = res.gids.GSSCRED_GIDS_val;
22207c478bd9Sstevel@tonic-gate 			*gidsLen = res.gids.GSSCRED_GIDS_len;
22217c478bd9Sstevel@tonic-gate 			res.gids.GSSCRED_GIDS_val = NULL;
22227c478bd9Sstevel@tonic-gate 			res.gids.GSSCRED_GIDS_len = 0;
22237c478bd9Sstevel@tonic-gate 		}
22247c478bd9Sstevel@tonic-gate 	}
22257c478bd9Sstevel@tonic-gate 
22267c478bd9Sstevel@tonic-gate 	/* delete RPC allocated memory */
22277c478bd9Sstevel@tonic-gate 	clnt_freeres(clnt, xdr_gsscred_name_to_unix_cred_res, (caddr_t)&res);
22287c478bd9Sstevel@tonic-gate 
22297c478bd9Sstevel@tonic-gate 	return (res.major);
22307c478bd9Sstevel@tonic-gate } /* kgsscred_name_to_unix_cred */
22317c478bd9Sstevel@tonic-gate 
22327c478bd9Sstevel@tonic-gate OM_uint32
kgss_get_group_info(puid,gidOut,gids,gidsLen,uid)22337c478bd9Sstevel@tonic-gate kgss_get_group_info(puid, gidOut, gids, gidsLen, uid)
22347c478bd9Sstevel@tonic-gate 	const uid_t puid;
22357c478bd9Sstevel@tonic-gate 	gid_t *gidOut;
22367c478bd9Sstevel@tonic-gate 	gid_t *gids[];
22377c478bd9Sstevel@tonic-gate 	int *gidsLen;
22387c478bd9Sstevel@tonic-gate 	uid_t uid;
22397c478bd9Sstevel@tonic-gate {
22407c478bd9Sstevel@tonic-gate 	gss_get_group_info_arg args;
22417c478bd9Sstevel@tonic-gate 	gss_get_group_info_res res;
22427c478bd9Sstevel@tonic-gate 
22437c478bd9Sstevel@tonic-gate 
22447c478bd9Sstevel@tonic-gate 	/* check the output parameters */
22457c478bd9Sstevel@tonic-gate 	if (gidOut == NULL || gids == NULL || gidsLen == NULL)
22467c478bd9Sstevel@tonic-gate 		return (GSS_S_CALL_INACCESSIBLE_WRITE);
22477c478bd9Sstevel@tonic-gate 
22487c478bd9Sstevel@tonic-gate 	/* get the client GSSD handle */
22497c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL)
22507c478bd9Sstevel@tonic-gate 	{
22517c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
22527c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
22537c478bd9Sstevel@tonic-gate 	}
22547c478bd9Sstevel@tonic-gate 
22557c478bd9Sstevel@tonic-gate 	/* set the input parameters */
22567c478bd9Sstevel@tonic-gate 	args.uid = uid;
22577c478bd9Sstevel@tonic-gate 	args.puid = puid;
22587c478bd9Sstevel@tonic-gate 
22597c478bd9Sstevel@tonic-gate 
22607c478bd9Sstevel@tonic-gate 	/* call the remote procedure */
22617c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
22627c478bd9Sstevel@tonic-gate 	if (gss_get_group_info_1(&args, &res, clnt) != RPC_SUCCESS)
22637c478bd9Sstevel@tonic-gate 	{
22647c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
22657c478bd9Sstevel@tonic-gate 	}
22667c478bd9Sstevel@tonic-gate 
22677c478bd9Sstevel@tonic-gate 	/* copy the results */
22687c478bd9Sstevel@tonic-gate 	if (res.major == GSS_S_COMPLETE)
22697c478bd9Sstevel@tonic-gate 	{
22707c478bd9Sstevel@tonic-gate 		*gidOut = res.gid;
22717c478bd9Sstevel@tonic-gate 		*gids = res.gids.GSSCRED_GIDS_val;
22727c478bd9Sstevel@tonic-gate 		*gidsLen = res.gids.GSSCRED_GIDS_len;
22737c478bd9Sstevel@tonic-gate 		res.gids.GSSCRED_GIDS_val = NULL;
22747c478bd9Sstevel@tonic-gate 		res.gids.GSSCRED_GIDS_len = 0;
22757c478bd9Sstevel@tonic-gate 	}
22767c478bd9Sstevel@tonic-gate 
22777c478bd9Sstevel@tonic-gate 	/* nothing to free */
22787c478bd9Sstevel@tonic-gate 
22797c478bd9Sstevel@tonic-gate 	return (res.major);
22807c478bd9Sstevel@tonic-gate } /* kgss_get_group_info */
22817c478bd9Sstevel@tonic-gate 
22827c478bd9Sstevel@tonic-gate OM_uint32
kgss_export_sec_context_wrapped(minor_status,context_handle,output_token,gssd_context_verifier)22837c478bd9Sstevel@tonic-gate kgss_export_sec_context_wrapped(minor_status,
22847c478bd9Sstevel@tonic-gate 				context_handle,
22857c478bd9Sstevel@tonic-gate 				output_token,
22867c478bd9Sstevel@tonic-gate 				gssd_context_verifier)
22877c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
22887c478bd9Sstevel@tonic-gate 	gssd_ctx_id_t *context_handle;
22897c478bd9Sstevel@tonic-gate 	gss_buffer_t output_token;
22907c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_context_verifier;
22917c478bd9Sstevel@tonic-gate {
22927c478bd9Sstevel@tonic-gate 	CLIENT *clnt;
22937c478bd9Sstevel@tonic-gate 	gss_export_sec_context_arg arg;
22947c478bd9Sstevel@tonic-gate 	gss_export_sec_context_res res;
22957c478bd9Sstevel@tonic-gate 
22967c478bd9Sstevel@tonic-gate 
22977c478bd9Sstevel@tonic-gate /* get the client handle to GSSD */
22987c478bd9Sstevel@tonic-gate 
22997c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
23007c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
23017c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
23027c478bd9Sstevel@tonic-gate 	}
23037c478bd9Sstevel@tonic-gate 
23047c478bd9Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
23057c478bd9Sstevel@tonic-gate 
23067c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
23077c478bd9Sstevel@tonic-gate 	arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle;
23087c478bd9Sstevel@tonic-gate 	arg.gssd_context_verifier = gssd_context_verifier;
23097c478bd9Sstevel@tonic-gate 
23107c478bd9Sstevel@tonic-gate /* call the remote procedure */
23117c478bd9Sstevel@tonic-gate 
23127c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
23137c478bd9Sstevel@tonic-gate 	if (gss_export_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
23147c478bd9Sstevel@tonic-gate 
23157c478bd9Sstevel@tonic-gate /*
23167c478bd9Sstevel@tonic-gate  * if the RPC call times out, null out all return arguments, set minor_status
23177c478bd9Sstevel@tonic-gate  * to its maximum value, and return GSS_S_FAILURE
23187c478bd9Sstevel@tonic-gate  */
23197c478bd9Sstevel@tonic-gate 
23207c478bd9Sstevel@tonic-gate 		if (minor_status != NULL)
23217c478bd9Sstevel@tonic-gate 			*minor_status = DEFAULT_MINOR_STAT;
23227c478bd9Sstevel@tonic-gate 		if (context_handle != NULL)
2323*0ab8aa70SToomas Soome 			*context_handle = 0;
23247c478bd9Sstevel@tonic-gate 		if (output_token != NULL)
23257c478bd9Sstevel@tonic-gate 			output_token->length = 0;
23267c478bd9Sstevel@tonic-gate 
23277c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
23287c478bd9Sstevel@tonic-gate 	}
23297c478bd9Sstevel@tonic-gate 
23307c478bd9Sstevel@tonic-gate /* copy the rpc results into the return arguments */
23317c478bd9Sstevel@tonic-gate 
23327c478bd9Sstevel@tonic-gate 	if (minor_status != NULL)
23337c478bd9Sstevel@tonic-gate 		*minor_status = res.minor_status;
23347c478bd9Sstevel@tonic-gate 
23357c478bd9Sstevel@tonic-gate 	if (res.context_handle.GSS_CTX_ID_T_len == 0)
2336*0ab8aa70SToomas Soome 		*context_handle = 0;
23377c478bd9Sstevel@tonic-gate 	else
23387c478bd9Sstevel@tonic-gate 		*context_handle =
23397c478bd9Sstevel@tonic-gate 		    *((gssd_ctx_id_t *)res.context_handle.GSS_CTX_ID_T_val);
23407c478bd9Sstevel@tonic-gate 
2341ba7b222eSGlenn Barry 	if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) {
23427c478bd9Sstevel@tonic-gate 		output_token->length = res.output_token.GSS_BUFFER_T_len;
23437c478bd9Sstevel@tonic-gate 		output_token->value =
23447c478bd9Sstevel@tonic-gate 			(void *) MALLOC(output_token->length);
23457c478bd9Sstevel@tonic-gate 		memcpy(output_token->value,
23467c478bd9Sstevel@tonic-gate 			res.output_token.GSS_BUFFER_T_val,
23477c478bd9Sstevel@tonic-gate 			output_token->length);
23487c478bd9Sstevel@tonic-gate 	}
23497c478bd9Sstevel@tonic-gate 
23507c478bd9Sstevel@tonic-gate /*
23517c478bd9Sstevel@tonic-gate  * free the memory allocated for the results and return with the status
23527c478bd9Sstevel@tonic-gate  * received in the rpc call
23537c478bd9Sstevel@tonic-gate  */
23547c478bd9Sstevel@tonic-gate 
23557c478bd9Sstevel@tonic-gate 	clnt_freeres(clnt, xdr_gss_export_sec_context_res, (caddr_t)&res);
23567c478bd9Sstevel@tonic-gate 	return (res.status);
23577c478bd9Sstevel@tonic-gate 
23587c478bd9Sstevel@tonic-gate }
23597c478bd9Sstevel@tonic-gate 
23607c478bd9Sstevel@tonic-gate OM_uint32
kgss_export_sec_context(minor_status,context_handle,output_token)23617c478bd9Sstevel@tonic-gate kgss_export_sec_context(minor_status,
23627c478bd9Sstevel@tonic-gate 			context_handle,
23637c478bd9Sstevel@tonic-gate 			output_token)
23647c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
23657c478bd9Sstevel@tonic-gate 	gss_ctx_id_t *context_handle;
23667c478bd9Sstevel@tonic-gate 	gss_buffer_t output_token;
23677c478bd9Sstevel@tonic-gate {
23687c478bd9Sstevel@tonic-gate 	OM_uint32 err;
23697c478bd9Sstevel@tonic-gate 	struct kgss_ctx *kctx;
23707c478bd9Sstevel@tonic-gate 
23717c478bd9Sstevel@tonic-gate 	if (*context_handle == GSS_C_NO_CONTEXT) {
23727c478bd9Sstevel@tonic-gate 		return (GSS_S_NO_CONTEXT);
23737c478bd9Sstevel@tonic-gate 	} else
23747c478bd9Sstevel@tonic-gate 		kctx = KCTX_TO_KGSS_CTX(*context_handle);
23757c478bd9Sstevel@tonic-gate 
23767c478bd9Sstevel@tonic-gate 	err = kgss_export_sec_context_wrapped(minor_status,
23777c478bd9Sstevel@tonic-gate 		&kctx->gssd_ctx, output_token,
23787c478bd9Sstevel@tonic-gate 		kctx->gssd_ctx_verifier);
23797c478bd9Sstevel@tonic-gate 
23807c478bd9Sstevel@tonic-gate 	if (GSS_ERROR(err))
23817c478bd9Sstevel@tonic-gate 		return (err);
23827c478bd9Sstevel@tonic-gate 	else {
23837c478bd9Sstevel@tonic-gate 		KGSS_FREE(kctx);
23847c478bd9Sstevel@tonic-gate 		*context_handle = GSS_C_NO_CONTEXT;
23857c478bd9Sstevel@tonic-gate 		return (err);
23867c478bd9Sstevel@tonic-gate 	}
23877c478bd9Sstevel@tonic-gate 
23887c478bd9Sstevel@tonic-gate }
23897c478bd9Sstevel@tonic-gate 
23907c478bd9Sstevel@tonic-gate OM_uint32
kgss_import_sec_context_wrapped(minor_status,input_token,context_handle,gssd_context_verifier)23917c478bd9Sstevel@tonic-gate kgss_import_sec_context_wrapped(minor_status,
23927c478bd9Sstevel@tonic-gate 			input_token,
23937c478bd9Sstevel@tonic-gate 			context_handle,
23947c478bd9Sstevel@tonic-gate 			gssd_context_verifier)
23957c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
23967c478bd9Sstevel@tonic-gate 	gss_buffer_t input_token;
23977c478bd9Sstevel@tonic-gate 	gss_ctx_id_t *context_handle;
23987c478bd9Sstevel@tonic-gate 	OM_uint32 gssd_context_verifier;
23997c478bd9Sstevel@tonic-gate {
24007c478bd9Sstevel@tonic-gate 	CLIENT *clnt;
24017c478bd9Sstevel@tonic-gate 	gss_import_sec_context_arg arg;
24027c478bd9Sstevel@tonic-gate 	gss_import_sec_context_res res;
24037c478bd9Sstevel@tonic-gate 
24047c478bd9Sstevel@tonic-gate 
24057c478bd9Sstevel@tonic-gate /* get the client handle to GSSD */
24067c478bd9Sstevel@tonic-gate 
24077c478bd9Sstevel@tonic-gate 	if ((clnt = getgssd_handle()) == NULL) {
24087c478bd9Sstevel@tonic-gate 		clnt_pcreateerror(server);
24097c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
24107c478bd9Sstevel@tonic-gate 	}
24117c478bd9Sstevel@tonic-gate 
24127c478bd9Sstevel@tonic-gate /* copy the procedure arguments into the rpc arg parameter */
24137c478bd9Sstevel@tonic-gate 	arg.input_token.GSS_BUFFER_T_len = (uint_t)
24147c478bd9Sstevel@tonic-gate 		(input_token != GSS_C_NO_BUFFER ? input_token->length : 0);
24157c478bd9Sstevel@tonic-gate 	arg.input_token.GSS_BUFFER_T_val = (char *)
24167c478bd9Sstevel@tonic-gate 		(input_token != GSS_C_NO_BUFFER ? input_token->value : 0);
24177c478bd9Sstevel@tonic-gate 	arg.gssd_context_verifier = gssd_context_verifier;
24187c478bd9Sstevel@tonic-gate 
24197c478bd9Sstevel@tonic-gate 
24207c478bd9Sstevel@tonic-gate /* call the remote procedure */
24217c478bd9Sstevel@tonic-gate 
24227c478bd9Sstevel@tonic-gate 	memset(&res, 0, sizeof (res));
24237c478bd9Sstevel@tonic-gate 	if (gss_import_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
24247c478bd9Sstevel@tonic-gate 
24257c478bd9Sstevel@tonic-gate /*
24267c478bd9Sstevel@tonic-gate  * if the RPC call times out, null out all return arguments, set minor_status
24277c478bd9Sstevel@tonic-gate  * to its maximum value, and return GSS_S_FAILURE
24287c478bd9Sstevel@tonic-gate  */
24297c478bd9Sstevel@tonic-gate 
24307c478bd9Sstevel@tonic-gate 		if (minor_status != NULL)
24317c478bd9Sstevel@tonic-gate 			*minor_status = DEFAULT_MINOR_STAT;
24327c478bd9Sstevel@tonic-gate 		if (context_handle != NULL)
24337c478bd9Sstevel@tonic-gate 			*context_handle = NULL;
24347c478bd9Sstevel@tonic-gate 
24357c478bd9Sstevel@tonic-gate 		return (GSS_S_FAILURE);
24367c478bd9Sstevel@tonic-gate 	}
24377c478bd9Sstevel@tonic-gate 
24387c478bd9Sstevel@tonic-gate /* copy the rpc results into the return arguments */
24397c478bd9Sstevel@tonic-gate 
24407c478bd9Sstevel@tonic-gate 	if (minor_status != NULL)
24417c478bd9Sstevel@tonic-gate 		*minor_status = res.minor_status;
24427c478bd9Sstevel@tonic-gate 
24437c478bd9Sstevel@tonic-gate 	if (res.context_handle.GSS_CTX_ID_T_len == 0)
24447c478bd9Sstevel@tonic-gate 		*context_handle = NULL;
24457c478bd9Sstevel@tonic-gate 	else
24467c478bd9Sstevel@tonic-gate 		*context_handle =
24477c478bd9Sstevel@tonic-gate 		    *((gss_ctx_id_t *)res.context_handle.GSS_CTX_ID_T_val);
24487c478bd9Sstevel@tonic-gate 
24497c478bd9Sstevel@tonic-gate 
24507c478bd9Sstevel@tonic-gate /*
24517c478bd9Sstevel@tonic-gate  * free the memory allocated for the results and return with the status
24527c478bd9Sstevel@tonic-gate  * received in the rpc call
24537c478bd9Sstevel@tonic-gate  */
24547c478bd9Sstevel@tonic-gate 
24557c478bd9Sstevel@tonic-gate 	clnt_freeres(clnt, xdr_gss_import_sec_context_res, (caddr_t)&res);
24567c478bd9Sstevel@tonic-gate 	return (res.status);
24577c478bd9Sstevel@tonic-gate }
24587c478bd9Sstevel@tonic-gate 
24597c478bd9Sstevel@tonic-gate OM_uint32
kgss_import_sec_context(minor_status,input_token,context_handle)24607c478bd9Sstevel@tonic-gate kgss_import_sec_context(minor_status,
24617c478bd9Sstevel@tonic-gate 			input_token,
24627c478bd9Sstevel@tonic-gate 			context_handle)
24637c478bd9Sstevel@tonic-gate 	OM_uint32 *minor_status;
24647c478bd9Sstevel@tonic-gate 	gss_buffer_t input_token;
24657c478bd9Sstevel@tonic-gate 	gss_ctx_id_t *context_handle;
24667c478bd9Sstevel@tonic-gate {
24677c478bd9Sstevel@tonic-gate 	struct kgss_ctx *kctx;
24687c478bd9Sstevel@tonic-gate 
24697c478bd9Sstevel@tonic-gate 	if (*context_handle == GSS_C_NO_CONTEXT) {
24707c478bd9Sstevel@tonic-gate 		kctx = KGSS_ALLOC();
24717c478bd9Sstevel@tonic-gate 		*context_handle = (gss_ctx_id_t)kctx;
24727c478bd9Sstevel@tonic-gate 		kctx->gssd_ctx = (OM_uint32) GSS_C_NO_CONTEXT;
24737c478bd9Sstevel@tonic-gate 	} else
24747c478bd9Sstevel@tonic-gate 		kctx = (struct kgss_ctx *)*context_handle;
24757c478bd9Sstevel@tonic-gate 	return (kgss_import_sec_context_wrapped(minor_status,
24767c478bd9Sstevel@tonic-gate 		input_token, &kctx->gssd_ctx,
24777c478bd9Sstevel@tonic-gate 		KCTX_TO_CTXV(context_handle)));
24787c478bd9Sstevel@tonic-gate }
24797c478bd9Sstevel@tonic-gate 
24807c478bd9Sstevel@tonic-gate #ifdef _KERNEL
24817c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
24827c478bd9Sstevel@tonic-gate 
24837c478bd9Sstevel@tonic-gate static void *gss_clnt = NULL;
24847c478bd9Sstevel@tonic-gate 
24857c478bd9Sstevel@tonic-gate #ifdef DEBUG
24867c478bd9Sstevel@tonic-gate typedef struct {
24877c478bd9Sstevel@tonic-gate 	char		*name;		/* just put something here */
24887c478bd9Sstevel@tonic-gate } gssd_devstate_t;
24897c478bd9Sstevel@tonic-gate 
24907c478bd9Sstevel@tonic-gate 
24917c478bd9Sstevel@tonic-gate static void *gssd_state;
24927c478bd9Sstevel@tonic-gate 
gssd_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)24937c478bd9Sstevel@tonic-gate static int gssd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
24947c478bd9Sstevel@tonic-gate {
24957c478bd9Sstevel@tonic-gate 	/*	 cmn_err(CE_NOTE, "In gssd_attach"); */
24967c478bd9Sstevel@tonic-gate 	switch (cmd) {
24977c478bd9Sstevel@tonic-gate 	case DDI_ATTACH:
24987c478bd9Sstevel@tonic-gate 		if (ddi_create_minor_node(dip, "gssd", S_IFCHR, 0, "gssd", 0)
2499d4f95bf4SRichard Lowe 		    == DDI_FAILURE) {
25007c478bd9Sstevel@tonic-gate 			ddi_remove_minor_node(dip, NULL);
25017c478bd9Sstevel@tonic-gate 			return (DDI_FAILURE);
25027c478bd9Sstevel@tonic-gate 		}
25037c478bd9Sstevel@tonic-gate 		return (DDI_SUCCESS);
25047c478bd9Sstevel@tonic-gate 
25057c478bd9Sstevel@tonic-gate 	default:
25067c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
25077c478bd9Sstevel@tonic-gate 	}
25087c478bd9Sstevel@tonic-gate }
25097c478bd9Sstevel@tonic-gate 
gssd_getinfo(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)25107c478bd9Sstevel@tonic-gate static int gssd_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd,
25117c478bd9Sstevel@tonic-gate 		void *arg, void **result)
25127c478bd9Sstevel@tonic-gate {
25137c478bd9Sstevel@tonic-gate 	dev_t dev;
25147c478bd9Sstevel@tonic-gate 	int error;
25157c478bd9Sstevel@tonic-gate 
25167c478bd9Sstevel@tonic-gate /*	 cmn_err(CE_NOTE, "In gssd_getinfo"); */
25177c478bd9Sstevel@tonic-gate 
25187c478bd9Sstevel@tonic-gate 	switch (infocmd) {
25197c478bd9Sstevel@tonic-gate 	case DDI_INFO_DEVT2INSTANCE:
25207c478bd9Sstevel@tonic-gate 		dev = (dev_t)arg;
25217c478bd9Sstevel@tonic-gate 		*result = (void *) getminor(dev);
25227c478bd9Sstevel@tonic-gate 		error = DDI_SUCCESS;
25237c478bd9Sstevel@tonic-gate 		break;
25247c478bd9Sstevel@tonic-gate 
25257c478bd9Sstevel@tonic-gate 	case DDI_INFO_DEVT2DEVINFO:
25267c478bd9Sstevel@tonic-gate 	/*	cmn_err(CE_NOTE, "getinfo wants devinfo"); */
25277c478bd9Sstevel@tonic-gate 	default:
25287c478bd9Sstevel@tonic-gate 		error = DDI_FAILURE;
25297c478bd9Sstevel@tonic-gate 		break;
25307c478bd9Sstevel@tonic-gate 	}
25317c478bd9Sstevel@tonic-gate 	return (error);
25327c478bd9Sstevel@tonic-gate }
25337c478bd9Sstevel@tonic-gate 
gssd_identify(dev_info_t * dip)25347c478bd9Sstevel@tonic-gate static int gssd_identify(dev_info_t *dip)
25357c478bd9Sstevel@tonic-gate {
25367c478bd9Sstevel@tonic-gate 	/*	 cmn_err(CE_NOTE, "in gssd_identify"); */
25377c478bd9Sstevel@tonic-gate 	if (strcmp(ddi_get_name(dip), "gssd") == 0)
25387c478bd9Sstevel@tonic-gate 		return (DDI_IDENTIFIED);
25397c478bd9Sstevel@tonic-gate 	else
25407c478bd9Sstevel@tonic-gate 		return (DDI_NOT_IDENTIFIED);
25417c478bd9Sstevel@tonic-gate }
25427c478bd9Sstevel@tonic-gate 
gssd_probe(dev_info_t * dip)25437c478bd9Sstevel@tonic-gate static int gssd_probe(dev_info_t *dip)
25447c478bd9Sstevel@tonic-gate {
25457c478bd9Sstevel@tonic-gate 	/*	 cmn_err(CE_NOTE, "In gssd_probe"); */
25467c478bd9Sstevel@tonic-gate 
25477c478bd9Sstevel@tonic-gate 	return (DDI_PROBE_SUCCESS);
25487c478bd9Sstevel@tonic-gate }
25497c478bd9Sstevel@tonic-gate 
gssd_open(dev_t * devp,int flag,int otyp,cred_t * credp)25507c478bd9Sstevel@tonic-gate static int gssd_open(dev_t *devp, int flag, int otyp, cred_t *credp)
25517c478bd9Sstevel@tonic-gate {
25527c478bd9Sstevel@tonic-gate 	/*	 cmn_err (CE_NOTE, "In gssd_open"); */
25537c478bd9Sstevel@tonic-gate 	if (otyp != OTYP_CHR)
25547c478bd9Sstevel@tonic-gate 		return (EINVAL);
25557c478bd9Sstevel@tonic-gate 
25567c478bd9Sstevel@tonic-gate 	gss_clnt = getgssd_handle();
25577c478bd9Sstevel@tonic-gate 	return (0);
25587c478bd9Sstevel@tonic-gate }
25597c478bd9Sstevel@tonic-gate 
gssd_close(dev_t dev,int flag,int otyp,cred_t * credp)25607c478bd9Sstevel@tonic-gate static int gssd_close(dev_t dev, int flag, int otyp, cred_t *credp)
25617c478bd9Sstevel@tonic-gate {
25627c478bd9Sstevel@tonic-gate 	/*	 cmn_err(CE_NOTE, "In gssd_close"); */
25637c478bd9Sstevel@tonic-gate 	killgssd_handle(gss_clnt);
25647c478bd9Sstevel@tonic-gate 	return (0);
25657c478bd9Sstevel@tonic-gate }
25667c478bd9Sstevel@tonic-gate 
gssd_write(dev_t dev,struct uio * uiop,cred_t * credp)25677c478bd9Sstevel@tonic-gate static int gssd_write(dev_t dev, struct uio *uiop, cred_t *credp)
25687c478bd9Sstevel@tonic-gate {
25697c478bd9Sstevel@tonic-gate 	char buffer[1024];
25707c478bd9Sstevel@tonic-gate 	int len;
25717c478bd9Sstevel@tonic-gate 
25727c478bd9Sstevel@tonic-gate 	/*	 cmn_err(CE_NOTE, "In gssd_write"); */
25737c478bd9Sstevel@tonic-gate 	bzero(buffer, 1024);
25747c478bd9Sstevel@tonic-gate 
25757c478bd9Sstevel@tonic-gate 	uiomove(buffer, 1024, UIO_WRITE, uiop);
25767c478bd9Sstevel@tonic-gate 	len = strlen(buffer);
25777c478bd9Sstevel@tonic-gate 
25787c478bd9Sstevel@tonic-gate 	if (buffer[len-1] == '\n')
25797c478bd9Sstevel@tonic-gate 		buffer[--len] = '\0';
25807c478bd9Sstevel@tonic-gate 
25817c478bd9Sstevel@tonic-gate 	cmn_err(CE_NOTE, "Got command: (%d) \"%s\"", len, buffer);
25827c478bd9Sstevel@tonic-gate 	do_gssdtest(buffer);
25837c478bd9Sstevel@tonic-gate 	return (0);
25847c478bd9Sstevel@tonic-gate }
25857c478bd9Sstevel@tonic-gate 
25867c478bd9Sstevel@tonic-gate static struct cb_ops gssd_cb_ops = {
25877c478bd9Sstevel@tonic-gate 	gssd_open,		/* cb_open */
25887c478bd9Sstevel@tonic-gate 	gssd_close,		/* cb_close */
25897c478bd9Sstevel@tonic-gate 	nodev,			/* cb_strategy */
25907c478bd9Sstevel@tonic-gate 	nodev,			/* cb_print */
25917c478bd9Sstevel@tonic-gate 	nodev,			/* cb_dump */
25927c478bd9Sstevel@tonic-gate 	nulldev,		/* cb_read */
25937c478bd9Sstevel@tonic-gate 	gssd_write,		/* cb_write */
25947c478bd9Sstevel@tonic-gate 	nodev,			/* cb_ioctl */
25957c478bd9Sstevel@tonic-gate 	nodev,			/* cb_devmap */
25967c478bd9Sstevel@tonic-gate 	nodev,			/* cb_mmap */
25977c478bd9Sstevel@tonic-gate 	nodev,			/* cb_segmap */
25987c478bd9Sstevel@tonic-gate 	nochpoll,		/* cb_chpoll */
25997c478bd9Sstevel@tonic-gate 	ddi_prop_op,		/* cb_prop_op */
26007c478bd9Sstevel@tonic-gate 	NULL,			/* cb_stream */
26017c478bd9Sstevel@tonic-gate 	(int)(D_NEW|D_MP)	/* cb_flag */
26027c478bd9Sstevel@tonic-gate };
26037c478bd9Sstevel@tonic-gate 
26047c478bd9Sstevel@tonic-gate static struct dev_ops gssd_ops = {
26057c478bd9Sstevel@tonic-gate 	DEVO_REV,		/* devo_rev */
26067c478bd9Sstevel@tonic-gate 	0,			/* devo_refcnt */
26077c478bd9Sstevel@tonic-gate 	gssd_getinfo,		/* devo_getinfo */
26087c478bd9Sstevel@tonic-gate 	gssd_identify,		/* devo_identify */
26097c478bd9Sstevel@tonic-gate 	nulldev,		/* devo_probe */
26107c478bd9Sstevel@tonic-gate 	gssd_attach,		/* devo_attach */
26117c478bd9Sstevel@tonic-gate 	nulldev,		/* devo_detach */
26127c478bd9Sstevel@tonic-gate 	nodev,			/* devo_reset */
26137c478bd9Sstevel@tonic-gate 	&gssd_cb_ops,		/* devo_cb_ops */
26147c478bd9Sstevel@tonic-gate 	(struct bus_ops *)NULL	/* devo_bus_ops */
26157c478bd9Sstevel@tonic-gate };
26167c478bd9Sstevel@tonic-gate 
26177c478bd9Sstevel@tonic-gate extern struct mod_ops mod_driverops;
26187c478bd9Sstevel@tonic-gate 
26197c478bd9Sstevel@tonic-gate static struct modldrv modlmisc = {
26207c478bd9Sstevel@tonic-gate 	&mod_driverops,
26217c478bd9Sstevel@tonic-gate 	"GSSD DRV Client Module",
26227c478bd9Sstevel@tonic-gate 	&gssd_ops
26237c478bd9Sstevel@tonic-gate 
26247c478bd9Sstevel@tonic-gate #else /* !DEBUG */
26257c478bd9Sstevel@tonic-gate 
26267c478bd9Sstevel@tonic-gate static struct modlmisc modlmisc = {
26277c478bd9Sstevel@tonic-gate 	&mod_miscops,
26287c478bd9Sstevel@tonic-gate 	"GSSD Client Module"
26297c478bd9Sstevel@tonic-gate #endif /* DEBUG */
26307c478bd9Sstevel@tonic-gate };
26317c478bd9Sstevel@tonic-gate 
26327c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = {
26337c478bd9Sstevel@tonic-gate 	MODREV_1,
26347c478bd9Sstevel@tonic-gate 	(void *)&modlmisc,
26357c478bd9Sstevel@tonic-gate 	NULL
26367c478bd9Sstevel@tonic-gate };
26377c478bd9Sstevel@tonic-gate 
26387c478bd9Sstevel@tonic-gate char _depends_on[] = "strmod/rpcmod misc/tlimod";
26397c478bd9Sstevel@tonic-gate 
_init(void)26407c478bd9Sstevel@tonic-gate _init(void)
26417c478bd9Sstevel@tonic-gate {
26427c478bd9Sstevel@tonic-gate 	int status;
26437c478bd9Sstevel@tonic-gate 
26447c478bd9Sstevel@tonic-gate 	if ((status = ddi_soft_state_init(&gssd_state,
2645d4f95bf4SRichard Lowe 	    sizeof (gssd_devstate_t), 1)) != 0)
26467c478bd9Sstevel@tonic-gate 		return (status);
26477c478bd9Sstevel@tonic-gate 
26487c478bd9Sstevel@tonic-gate 	if ((status = mod_install((struct modlinkage *)&modlinkage)) != 0)
26497c478bd9Sstevel@tonic-gate 		ddi_soft_state_fini(&gssd_state);
26507c478bd9Sstevel@tonic-gate 
26517c478bd9Sstevel@tonic-gate 	cmn_err(CE_NOTE, "gssd: I'm in the kernel: %d.", status);
26527c478bd9Sstevel@tonic-gate 	return (status);
26537c478bd9Sstevel@tonic-gate }
26547c478bd9Sstevel@tonic-gate 
_fini()26557c478bd9Sstevel@tonic-gate _fini()
26567c478bd9Sstevel@tonic-gate {
26577c478bd9Sstevel@tonic-gate 	int status;
26587c478bd9Sstevel@tonic-gate 
26597c478bd9Sstevel@tonic-gate 	killgssd_handle(gss_clnt);
26607c478bd9Sstevel@tonic-gate 	cmn_err(CE_NOTE, "gssd: Handle destroyed.. leaving module.");
26617c478bd9Sstevel@tonic-gate 
26627c478bd9Sstevel@tonic-gate 	if ((status = mod_remove(&modlinkage)) != 0)
26637c478bd9Sstevel@tonic-gate 		return (status);
26647c478bd9Sstevel@tonic-gate 
26657c478bd9Sstevel@tonic-gate 	ddi_soft_state_fini(&gssd_state);
26667c478bd9Sstevel@tonic-gate 	return (status);
26677c478bd9Sstevel@tonic-gate }
26687c478bd9Sstevel@tonic-gate 
26697c478bd9Sstevel@tonic-gate _info(modinfop)
26707c478bd9Sstevel@tonic-gate struct modinfo *modinfop;
26717c478bd9Sstevel@tonic-gate {
26727c478bd9Sstevel@tonic-gate 	return (mod_info(&modlinkage, modinfop));
26737c478bd9Sstevel@tonic-gate }
26747c478bd9Sstevel@tonic-gate 
26757c478bd9Sstevel@tonic-gate #endif
2676