Home | History | Annotate | Download | only in gssapi
      1      0   stevel /*
      2      0   stevel  * CDDL HEADER START
      3      0   stevel  *
      4      0   stevel  * The contents of this file are subject to the terms of the
      5   6855  johnlev  * Common Development and Distribution License (the "License").
      6   6855  johnlev  * You may not use this file except in compliance with the License.
      7      0   stevel  *
      8      0   stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9      0   stevel  * or http://www.opensolaris.org/os/licensing.
     10      0   stevel  * See the License for the specific language governing permissions
     11      0   stevel  * and limitations under the License.
     12      0   stevel  *
     13      0   stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14      0   stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15      0   stevel  * If applicable, add the following below this CDDL HEADER, with the
     16      0   stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17      0   stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18      0   stevel  *
     19      0   stevel  * CDDL HEADER END
     20      0   stevel  */
     21      0   stevel /*
     22  10598    Glenn  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23      0   stevel  * Use is subject to license terms.
     24      0   stevel  */
     25      0   stevel 
     26      0   stevel /*
     27      0   stevel  *  GSSAPI library stub module for gssd.
     28      0   stevel  */
     29      0   stevel 
     30      0   stevel #include <mechglueP.h>
     31      0   stevel #include "gssd_prot.h"
     32      0   stevel #include <rpc/rpc.h>
     33      0   stevel 
     34      0   stevel #include <sys/systm.h>
     35      0   stevel #include <sys/types.h>
     36      0   stevel #include <sys/cmn_err.h>
     37      0   stevel #include <sys/kmem.h>
     38      0   stevel #include <gssapi/kgssapi_defs.h>
     39      0   stevel #include <sys/debug.h>
     40      0   stevel 
     41      0   stevel #ifdef GSSDEBUG
     42      0   stevel /*
     43      0   stevel  * Kernel kgssd module debugging aid. The global variable "gss_log"
     44      0   stevel  * is a bit mask which allows various types of debugging messages
     45      0   stevel  * to be printed out.
     46      0   stevel  *
     47      0   stevel  *	 gss_log & 1  will cause actual failures to be printed.
     48      0   stevel  *	 gss_log & 2  will cause informational messages to be
     49      0   stevel  *	                 printed on the client side of kgssd.
     50      0   stevel  *	 gss_log & 4  will cause informational messages to be
     51      0   stevel  *	                 printed on the server side of kgssd.
     52      0   stevel  *	 gss_log & 8  will cause informational messages to be
     53      0   stevel  *	                 printed on both client and server side of kgssd.
     54      0   stevel  */
     55      0   stevel 
     56      0   stevel uint_t gss_log = 1;
     57      0   stevel 
     58      0   stevel #endif /* GSSDEBUG */
     59      0   stevel 
     60      0   stevel #ifdef  DEBUG
     61      0   stevel extern void prom_printf();
     62      0   stevel #endif
     63      0   stevel 
     64      0   stevel char *server = "localhost";
     65      0   stevel 
     66      0   stevel static OM_uint32 kgss_sign_wrapped(void *, OM_uint32 *, gss_ctx_id_t, int,
     67      0   stevel 	gss_buffer_t, gss_buffer_t,  OM_uint32);
     68      0   stevel 
     69      0   stevel static OM_uint32 kgss_verify_wrapped(void *, OM_uint32 *, gss_ctx_id_t,
     70      0   stevel 	gss_buffer_t, gss_buffer_t, int *qop_state, OM_uint32);
     71      0   stevel 
     72      0   stevel /* EXPORT DELETE START */
     73      0   stevel static OM_uint32 kgss_seal_wrapped(void *, OM_uint32 *, gss_ctx_id_t,
     74      0   stevel 	int, int, gss_buffer_t, int *, gss_buffer_t,  OM_uint32);
     75      0   stevel 
     76      0   stevel static OM_uint32 kgss_unseal_wrapped(void *, OM_uint32 *, gss_ctx_id_t,
     77      0   stevel 	gss_buffer_t, gss_buffer_t, int *conf_state, int *qop_state,
     78      0   stevel 	OM_uint32);
     79      0   stevel /* EXPORT DELETE END */
     80      0   stevel 
     81      0   stevel static OM_uint32 kgss_delete_sec_context_wrapped(void *, OM_uint32 *,
     82      0   stevel 	gssd_ctx_id_t *, gss_buffer_t, OM_uint32);
     83      0   stevel 
     84      0   stevel static void __kgss_reset_mech(gss_mechanism *, gss_OID);
     85      0   stevel 
     86      0   stevel #define	DEFAULT_MINOR_STAT	((OM_uint32) ~0)
     87      0   stevel 
     88      0   stevel OM_uint32
     89      0   stevel kgss_acquire_cred_wrapped(minor_status,
     90      0   stevel 			desired_name,
     91      0   stevel 			time_req,
     92      0   stevel 			desired_mechs,
     93      0   stevel 			cred_usage,
     94      0   stevel 			output_cred_handle,
     95      0   stevel 			actual_mechs,
     96      0   stevel 			time_rec,
     97      0   stevel 			uid,
     98      0   stevel 			gssd_cred_verifier)
     99      0   stevel 	OM_uint32 *minor_status;
    100      0   stevel 	const gss_name_t desired_name;
    101      0   stevel 	OM_uint32 time_req;
    102      0   stevel 	const gss_OID_set desired_mechs;
    103      0   stevel 	int cred_usage;
    104      0   stevel 	gssd_cred_id_t *output_cred_handle;
    105      0   stevel 	gss_OID_set *actual_mechs;
    106      0   stevel 	OM_uint32 *time_rec;
    107      0   stevel 	uid_t uid;
    108      0   stevel 	OM_uint32 *gssd_cred_verifier;
    109      0   stevel {
    110      0   stevel 	CLIENT *clnt;
    111      0   stevel 
    112      0   stevel 	OM_uint32 	minor_status_temp;
    113      0   stevel 	gss_buffer_desc	external_name;
    114      0   stevel 	gss_OID		name_type;
    115      0   stevel 	enum clnt_stat	client_stat;
    116      0   stevel 	int		i;
    117      0   stevel 
    118      0   stevel 	gss_acquire_cred_arg arg;
    119      0   stevel 	gss_acquire_cred_res res;
    120      0   stevel 
    121      0   stevel 	/* get the client handle to GSSD */
    122      0   stevel 
    123      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
    124      0   stevel 		GSSLOG(1, "kgss_acquire_cred: can't connect to server on %s\n",
    125      0   stevel 			server);
    126      0   stevel 		return (GSS_S_FAILURE);
    127      0   stevel 	}
    128      0   stevel 
    129      0   stevel 	/* convert the desired name from internal to external format */
    130      0   stevel 
    131      0   stevel 	if (gss_display_name(&minor_status_temp, desired_name, &external_name,
    132      0   stevel 				&name_type) != GSS_S_COMPLETE) {
    133      0   stevel 
    134      0   stevel 		*minor_status = (OM_uint32) minor_status_temp;
    135      0   stevel 		killgssd_handle(clnt);
    136      0   stevel 		GSSLOG0(1, "kgss_acquire_cred: display name failed\n");
    137      0   stevel 		return ((OM_uint32) GSS_S_FAILURE);
    138      0   stevel 	}
    139      0   stevel 
    140      0   stevel 
    141      0   stevel 	/* copy the procedure arguments into the rpc arg parameter */
    142      0   stevel 
    143      0   stevel 	arg.uid = (OM_uint32) uid;
    144      0   stevel 
    145      0   stevel 	arg.desired_name.GSS_BUFFER_T_len = (uint_t)external_name.length;
    146      0   stevel 	arg.desired_name.GSS_BUFFER_T_val = (char *)external_name.value;
    147      0   stevel 
    148      0   stevel 	arg.name_type.GSS_OID_len =
    149      0   stevel 		name_type == GSS_C_NULL_OID ?
    150      0   stevel 			0 : (uint_t)name_type->length;
    151      0   stevel 
    152      0   stevel 	arg.name_type.GSS_OID_val =
    153      0   stevel 		name_type == GSS_C_NULL_OID ?
    154      0   stevel 			(char *)NULL : (char *)name_type->elements;
    155      0   stevel 
    156      0   stevel 	arg.time_req = time_req;
    157      0   stevel 
    158      0   stevel 	if (desired_mechs != GSS_C_NULL_OID_SET) {
    159      0   stevel 		arg.desired_mechs.GSS_OID_SET_len =
    160      0   stevel 			(uint_t)desired_mechs->count;
    161      0   stevel 		arg.desired_mechs.GSS_OID_SET_val = (GSS_OID *)
    162      0   stevel 			MALLOC(sizeof (GSS_OID) * desired_mechs->count);
    163      0   stevel 
    164      0   stevel 		for (i = 0; i < desired_mechs->count; i++) {
    165      0   stevel 		    arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_len =
    166      0   stevel 			(uint_t)desired_mechs->elements[i].length;
    167      0   stevel 		    arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val =
    168      0   stevel 			(char *)MALLOC(desired_mechs->elements[i].length);
    169      0   stevel 		    (void) memcpy(
    170      0   stevel 			arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val,
    171      0   stevel 			desired_mechs->elements[i].elements,
    172      0   stevel 			desired_mechs->elements[i].length);
    173      0   stevel 		}
    174      0   stevel 	} else
    175      0   stevel 		arg.desired_mechs.GSS_OID_SET_len = 0;
    176      0   stevel 
    177      0   stevel 	arg.cred_usage = cred_usage;
    178      0   stevel 
    179      0   stevel 	/* call the remote procedure */
    180      0   stevel 
    181      0   stevel 	bzero((caddr_t)&res, sizeof (res));
    182      0   stevel 	client_stat = gss_acquire_cred_1(&arg, &res, clnt);
    183      0   stevel 
    184      0   stevel 	(void) gss_release_buffer(&minor_status_temp, &external_name);
    185      0   stevel 	if (desired_mechs != GSS_C_NULL_OID_SET) {
    186      0   stevel 		for (i = 0; i < desired_mechs->count; i++)
    187      0   stevel 			FREE(arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val,
    188      0   stevel 			    arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_len);
    189      0   stevel 		FREE(arg.desired_mechs.GSS_OID_SET_val,
    190      0   stevel 		    arg.desired_mechs.GSS_OID_SET_len * sizeof (GSS_OID));
    191      0   stevel 	}
    192      0   stevel 
    193      0   stevel 	if (client_stat != RPC_SUCCESS) {
    194      0   stevel 
    195      0   stevel 		/*
    196      0   stevel 		 * if the RPC call times out, null out all return arguments,
    197      0   stevel 		 * set minor_status to its maximum value, and return
    198      0   stevel 		 * GSS_S_FAILURE
    199      0   stevel 		 */
    200      0   stevel 
    201      0   stevel 		if (minor_status != NULL)
    202      0   stevel 			*minor_status = DEFAULT_MINOR_STAT;
    203      0   stevel 		if (output_cred_handle != NULL)
    204      0   stevel 			*output_cred_handle = NULL;
    205      0   stevel 		if (actual_mechs != NULL)
    206      0   stevel 			*actual_mechs = NULL;
    207      0   stevel 		if (time_rec != NULL)
    208      0   stevel 			*time_rec = 0;
    209      0   stevel 
    210      0   stevel 		killgssd_handle(clnt);
    211      0   stevel 		GSSLOG0(1, "kgss_acquire_cred: RPC call times out\n");
    212      0   stevel 		return (GSS_S_FAILURE);
    213      0   stevel 	}
    214      0   stevel 
    215      0   stevel 	/* copy the rpc results into the return arguments */
    216      0   stevel 
    217      0   stevel 	if (minor_status != NULL)
    218      0   stevel 		*minor_status = res.minor_status;
    219      0   stevel 
    220      0   stevel 	if (output_cred_handle != NULL &&
    221      0   stevel 		(res.status == GSS_S_COMPLETE)) {
    222      0   stevel 	    *output_cred_handle =
    223      0   stevel 		*((gssd_cred_id_t *)res.output_cred_handle.GSS_CRED_ID_T_val);
    224      0   stevel 	    *gssd_cred_verifier = res.gssd_cred_verifier;
    225      0   stevel 	}
    226      0   stevel 
    227      0   stevel 	if (res.status == GSS_S_COMPLETE &&
    228      0   stevel 		res.actual_mechs.GSS_OID_SET_len != 0 &&
    229      0   stevel 		actual_mechs != NULL) {
    230      0   stevel 		*actual_mechs = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
    231      0   stevel 		(*actual_mechs)->count =
    232      0   stevel 					(int)res.actual_mechs.GSS_OID_SET_len;
    233      0   stevel 		(*actual_mechs)->elements = (gss_OID)
    234      0   stevel 			MALLOC(sizeof (gss_OID_desc) * (*actual_mechs)->count);
    235      0   stevel 
    236      0   stevel 		for (i = 0; i < (*actual_mechs)->count; i++) {
    237      0   stevel 		    (*actual_mechs)->elements[i].length = (OM_uint32)
    238      0   stevel 			res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_len;
    239      0   stevel 		    (*actual_mechs)->elements[i].elements =
    240      0   stevel 			(void *) MALLOC((*actual_mechs)->elements[i].length);
    241      0   stevel 		    (void) memcpy((*actual_mechs)->elements[i].elements,
    242      0   stevel 			res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_val,
    243      0   stevel 			(*actual_mechs)->elements[i].length);
    244      0   stevel 		}
    245      0   stevel 	} else {
    246      0   stevel 		if (res.status == GSS_S_COMPLETE &&
    247      0   stevel 			actual_mechs != NULL)
    248      0   stevel 			(*actual_mechs) = NULL;
    249      0   stevel 	}
    250      0   stevel 
    251      0   stevel 	if (time_rec != NULL)
    252      0   stevel 		*time_rec = res.time_rec;
    253      0   stevel 
    254      0   stevel 	/*
    255      0   stevel 	 * free the memory allocated for the results and return with the status
    256      0   stevel 	 * received in the rpc call
    257      0   stevel 	 */
    258      0   stevel 
    259      0   stevel 	clnt_freeres(clnt, xdr_gss_acquire_cred_res, (caddr_t)&res);
    260      0   stevel 	killgssd_handle(clnt);
    261      0   stevel 	return (res.status);
    262      0   stevel 
    263      0   stevel }
    264      0   stevel 
    265      0   stevel OM_uint32
    266      0   stevel kgss_acquire_cred(minor_status,
    267      0   stevel 		desired_name,
    268      0   stevel 		time_req,
    269      0   stevel 		desired_mechs,
    270      0   stevel 		cred_usage,
    271      0   stevel 		output_cred_handle,
    272      0   stevel 		actual_mechs,
    273      0   stevel 		time_rec,
    274      0   stevel 		uid)
    275      0   stevel 	OM_uint32 *minor_status;
    276      0   stevel 	const gss_name_t desired_name;
    277      0   stevel 	OM_uint32 time_req;
    278      0   stevel 	const gss_OID_set desired_mechs;
    279      0   stevel 	int cred_usage;
    280      0   stevel 	gss_cred_id_t *output_cred_handle;
    281      0   stevel 	gss_OID_set *actual_mechs;
    282      0   stevel 	OM_uint32 *time_rec;
    283      0   stevel 	uid_t uid;
    284      0   stevel {
    285      0   stevel 
    286      0   stevel 	OM_uint32	err;
    287      0   stevel 	struct kgss_cred *kcred;
    288      0   stevel 
    289      0   stevel 	kcred = KGSS_CRED_ALLOC();
    290      0   stevel 	*output_cred_handle = (gss_cred_id_t)kcred;
    291      0   stevel 	err = kgss_acquire_cred_wrapped(minor_status, desired_name, time_req,
    292      0   stevel 		desired_mechs, cred_usage, &kcred->gssd_cred, actual_mechs,
    293      0   stevel 		time_rec, uid, &kcred->gssd_cred_verifier);
    294      0   stevel 	if (GSS_ERROR(err)) {
    295      0   stevel 		KGSS_CRED_FREE(kcred);
    296      0   stevel 		*output_cred_handle = GSS_C_NO_CREDENTIAL;
    297      0   stevel 	}
    298      0   stevel 	return (err);
    299      0   stevel }
    300      0   stevel 
    301      0   stevel OM_uint32
    302      0   stevel kgss_add_cred_wrapped(minor_status,
    303      0   stevel 			input_cred_handle,
    304      0   stevel 			gssd_cred_verifier,
    305      0   stevel 			desired_name,
    306      0   stevel 			desired_mech_type,
    307      0   stevel 			cred_usage,
    308      0   stevel 			initiator_time_req,
    309      0   stevel 			acceptor_time_req,
    310      0   stevel 			actual_mechs,
    311      0   stevel 			initiator_time_rec,
    312      0   stevel 			acceptor_time_rec,
    313      0   stevel 			uid)
    314      0   stevel 	OM_uint32 *minor_status;
    315      0   stevel 	gssd_cred_id_t input_cred_handle;
    316      0   stevel 	OM_uint32 gssd_cred_verifier;
    317      0   stevel 	gss_name_t desired_name;
    318      0   stevel 	gss_OID desired_mech_type;
    319      0   stevel 	int cred_usage;
    320      0   stevel 	int initiator_time_req;
    321      0   stevel 	int acceptor_time_req;
    322      0   stevel 	gss_OID_set *actual_mechs;
    323      0   stevel 	OM_uint32 *initiator_time_rec;
    324      0   stevel 	OM_uint32 *acceptor_time_rec;
    325      0   stevel 	uid_t uid;
    326      0   stevel {
    327      0   stevel 	CLIENT *clnt;
    328      0   stevel 
    329      0   stevel 	OM_uint32 	minor_status_temp;
    330      0   stevel 	gss_buffer_desc	external_name;
    331      0   stevel 	gss_OID		name_type;
    332      0   stevel 	int		i;
    333      0   stevel 
    334      0   stevel 	gss_add_cred_arg arg;
    335      0   stevel 	gss_add_cred_res res;
    336      0   stevel 
    337      0   stevel 
    338      0   stevel 	/*
    339      0   stevel 	 * NULL the params here once
    340      0   stevel 	 * If there are errors then we won't
    341      0   stevel 	 * have to do it for every error
    342      0   stevel 	 * case
    343      0   stevel 	 */
    344      0   stevel 
    345      0   stevel 	if (minor_status != NULL)
    346      0   stevel 		*minor_status = DEFAULT_MINOR_STAT;
    347      0   stevel 	if (actual_mechs != NULL)
    348      0   stevel 		*actual_mechs = NULL;
    349      0   stevel 	if (initiator_time_rec != NULL)
    350      0   stevel 		*initiator_time_rec = 0;
    351      0   stevel 	if (acceptor_time_rec != NULL)
    352      0   stevel 			*acceptor_time_rec = 0;
    353      0   stevel 	/* get the client handle to GSSD */
    354      0   stevel 
    355      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
    356      0   stevel 		GSSLOG(1, "kgss_add_cred: can't connect to server on %s\n",
    357      0   stevel 			server);
    358      0   stevel 		return (GSS_S_FAILURE);
    359      0   stevel 	}
    360      0   stevel 
    361      0   stevel 
    362      0   stevel 	/* convert the desired name from internal to external format */
    363      0   stevel 
    364      0   stevel 	if (gss_display_name(&minor_status_temp, desired_name, &external_name,
    365      0   stevel 				&name_type) != GSS_S_COMPLETE) {
    366      0   stevel 
    367      0   stevel 		*minor_status = (OM_uint32) minor_status_temp;
    368      0   stevel 		killgssd_handle(clnt);
    369      0   stevel 		GSSLOG0(1, "kgss_acquire_cred: display name failed\n");
    370      0   stevel 		return ((OM_uint32) GSS_S_FAILURE);
    371      0   stevel 	}
    372      0   stevel 
    373      0   stevel 
    374      0   stevel 	/* copy the procedure arguments into the rpc arg parameter */
    375      0   stevel 
    376      0   stevel 	arg.uid = (OM_uint32)uid;
    377      0   stevel 	arg.input_cred_handle.GSS_CRED_ID_T_len =
    378      0   stevel 			input_cred_handle ==
    379      0   stevel 			(gssd_cred_id_t)GSS_C_NO_CREDENTIAL ?
    380      0   stevel 			0 : (uint_t)sizeof (gssd_cred_id_t);
    381      0   stevel 	arg.input_cred_handle.GSS_CRED_ID_T_val = (char *)&input_cred_handle;
    382      0   stevel 	arg.gssd_cred_verifier = gssd_cred_verifier;
    383      0   stevel 	arg.desired_name.GSS_BUFFER_T_len = (uint_t)external_name.length;
    384      0   stevel 	arg.desired_name.GSS_BUFFER_T_val = (char *)external_name.value;
    385      0   stevel 	arg.name_type.GSS_OID_len =
    386      0   stevel 		name_type == GSS_C_NULL_OID ?
    387      0   stevel 			0 : (uint_t)name_type->length;
    388      0   stevel 	arg.name_type.GSS_OID_val =
    389      0   stevel 		name_type == GSS_C_NULL_OID ?
    390      0   stevel 			(char *)NULL : (char *)name_type->elements;
    391      0   stevel 
    392      0   stevel 	arg.desired_mech_type.GSS_OID_len =
    393      0   stevel 		(uint_t)(desired_mech_type != GSS_C_NULL_OID ?
    394      0   stevel 		desired_mech_type->length : 0);
    395      0   stevel 	arg.desired_mech_type.GSS_OID_val =
    396      0   stevel 		(char *)(desired_mech_type != GSS_C_NULL_OID ?
    397      0   stevel 		desired_mech_type->elements : 0);
    398      0   stevel 	arg.cred_usage = cred_usage;
    399      0   stevel 	arg.initiator_time_req = initiator_time_req;
    400      0   stevel 	arg.acceptor_time_req = acceptor_time_req;
    401      0   stevel 
    402      0   stevel 	/* call the remote procedure */
    403      0   stevel 
    404      0   stevel 	bzero((caddr_t)&res, sizeof (res));
    405      0   stevel 	if (gss_add_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
    406      0   stevel 
    407      0   stevel 		/*
    408      0   stevel 		 * if the RPC call times out, null out all return arguments,
    409      0   stevel 		 * set minor_status to its maximum value, and return
    410      0   stevel 		 * GSS_S_FAILURE
    411      0   stevel 		 */
    412      0   stevel 
    413      0   stevel 		killgssd_handle(clnt);
    414      0   stevel 		(void) gss_release_buffer(&minor_status_temp, &external_name);
    415      0   stevel 		GSSLOG0(1, "kgss_add_cred: RPC call times out\n");
    416      0   stevel 		return (GSS_S_FAILURE);
    417      0   stevel 	}
    418      0   stevel 
    419      0   stevel 	/* free the allocated memory for the flattened name */
    420      0   stevel 
    421      0   stevel 	(void) gss_release_buffer(&minor_status_temp, &external_name);
    422      0   stevel 
    423      0   stevel 	/* copy the rpc results into the return arguments */
    424      0   stevel 
    425      0   stevel 	if (minor_status != NULL)
    426      0   stevel 		*minor_status = res.minor_status;
    427      0   stevel 
    428      0   stevel 	if (res.status == GSS_S_COMPLETE &&
    429      0   stevel 		res.actual_mechs.GSS_OID_SET_len != 0 &&
    430      0   stevel 		actual_mechs != NULL) {
    431      0   stevel 		*actual_mechs = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
    432      0   stevel 		(*actual_mechs)->count =
    433      0   stevel 					(int)res.actual_mechs.GSS_OID_SET_len;
    434      0   stevel 		(*actual_mechs)->elements = (gss_OID)
    435      0   stevel 			MALLOC(sizeof (gss_OID_desc) * (*actual_mechs)->count);
    436      0   stevel 
    437      0   stevel 		for (i = 0; i < (*actual_mechs)->count; i++) {
    438      0   stevel 		    (*actual_mechs)->elements[i].length = (OM_uint32)
    439      0   stevel 			res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_len;
    440      0   stevel 		    (*actual_mechs)->elements[i].elements =
    441      0   stevel 			(void *) MALLOC((*actual_mechs)->elements[i].length);
    442      0   stevel 		    (void) memcpy((*actual_mechs)->elements[i].elements,
    443      0   stevel 			res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_val,
    444      0   stevel 			(*actual_mechs)->elements[i].length);
    445      0   stevel 		}
    446      0   stevel 	} else {
    447      0   stevel 		if (res.status == GSS_S_COMPLETE && actual_mechs != NULL)
    448      0   stevel 			(*actual_mechs) = NULL;
    449      0   stevel 	}
    450      0   stevel 	if (initiator_time_rec != NULL)
    451      0   stevel 		*initiator_time_rec = res.acceptor_time_rec;
    452      0   stevel 	if (acceptor_time_rec != NULL)
    453      0   stevel 		*acceptor_time_rec = res.acceptor_time_rec;
    454      0   stevel 
    455      0   stevel 	/*
    456      0   stevel 	 * free the memory allocated for the results and return with the status
    457      0   stevel 	 * received in the rpc call
    458      0   stevel 	 */
    459      0   stevel 
    460      0   stevel 	clnt_freeres(clnt, xdr_gss_add_cred_res, (caddr_t)&res);
    461      0   stevel 	killgssd_handle(clnt);
    462      0   stevel 	return (res.status);
    463      0   stevel 
    464      0   stevel }
    465      0   stevel 
    466      0   stevel OM_uint32
    467      0   stevel kgss_add_cred(minor_status,
    468      0   stevel 			input_cred_handle,
    469      0   stevel 			desired_name,
    470      0   stevel 			desired_mech_type,
    471      0   stevel 			cred_usage,
    472      0   stevel 			initiator_time_req,
    473      0   stevel 			acceptor_time_req,
    474      0   stevel 			actual_mechs,
    475      0   stevel 			initiator_time_rec,
    476      0   stevel 			acceptor_time_rec,
    477      0   stevel 			uid)
    478      0   stevel 	OM_uint32 *minor_status;
    479      0   stevel 	gss_cred_id_t input_cred_handle;
    480      0   stevel 	gss_name_t desired_name;
    481      0   stevel 	gss_OID desired_mech_type;
    482      0   stevel 	int cred_usage;
    483      0   stevel 	int initiator_time_req;
    484      0   stevel 	int acceptor_time_req;
    485      0   stevel 	gss_OID_set *actual_mechs;
    486      0   stevel 	OM_uint32 *initiator_time_rec;
    487      0   stevel 	OM_uint32 *acceptor_time_rec;
    488      0   stevel 	uid_t uid;
    489      0   stevel {
    490      0   stevel 
    491      0   stevel 	OM_uint32	err;
    492      0   stevel 	OM_uint32 gssd_cred_verifier;
    493      0   stevel 	gssd_cred_id_t gssd_input_cred_handle;
    494      0   stevel 
    495      0   stevel 	if (input_cred_handle != GSS_C_NO_CREDENTIAL) {
    496      0   stevel 		gssd_cred_verifier = KCRED_TO_CREDV(input_cred_handle);
    497      0   stevel 		gssd_input_cred_handle = KCRED_TO_CRED(input_cred_handle);
    498      0   stevel 	} else
    499      0   stevel 		gssd_input_cred_handle = (gssd_cred_id_t)GSS_C_NO_CREDENTIAL;
    500      0   stevel 
    501      0   stevel 	err = kgss_add_cred_wrapped(minor_status, gssd_input_cred_handle,
    502      0   stevel 			gssd_cred_verifier, desired_name, desired_mech_type,
    503      0   stevel 			cred_usage, initiator_time_req, acceptor_time_req,
    504      0   stevel 			actual_mechs, initiator_time_rec,
    505      0   stevel 			acceptor_time_rec, uid);
    506      0   stevel 	return (err);
    507      0   stevel }
    508      0   stevel 
    509      0   stevel 
    510      0   stevel OM_uint32
    511      0   stevel kgss_release_cred_wrapped(minor_status,
    512      0   stevel 			cred_handle,
    513      0   stevel 			uid,
    514      0   stevel 			gssd_cred_verifier)
    515      0   stevel     OM_uint32 *minor_status;
    516      0   stevel     gssd_cred_id_t *cred_handle;
    517      0   stevel     uid_t uid;
    518      0   stevel     OM_uint32  gssd_cred_verifier;
    519      0   stevel {
    520      0   stevel 	CLIENT *clnt;
    521      0   stevel 
    522      0   stevel 	gss_release_cred_arg arg;
    523      0   stevel 	gss_release_cred_res res;
    524      0   stevel 
    525      0   stevel 
    526      0   stevel 	/* get the client handle to GSSD */
    527      0   stevel 
    528      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
    529      0   stevel 		GSSLOG(1, "kgss_release_cred: can't connect to server on %s\n",
    530      0   stevel 			server);
    531      0   stevel 		return (GSS_S_FAILURE);
    532      0   stevel 	}
    533      0   stevel 
    534      0   stevel 	/* copy the procedure arguments into the rpc arg parameter */
    535      0   stevel 
    536      0   stevel 	arg.uid = (OM_uint32)uid;
    537      0   stevel 	arg.gssd_cred_verifier = gssd_cred_verifier;
    538      0   stevel 
    539      0   stevel 	if (cred_handle != NULL) {
    540      0   stevel 		arg.cred_handle.GSS_CRED_ID_T_len =
    541      0   stevel 					(uint_t)sizeof (gssd_cred_id_t);
    542      0   stevel 		arg.cred_handle.GSS_CRED_ID_T_val = (char *)cred_handle;
    543      0   stevel 	} else
    544      0   stevel 		arg.cred_handle.GSS_CRED_ID_T_len = 0;
    545      0   stevel 
    546      0   stevel 	/* call the remote procedure */
    547      0   stevel 
    548      0   stevel 	bzero((caddr_t)&res, sizeof (res));
    549      0   stevel 	if (gss_release_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
    550      0   stevel 
    551      0   stevel 	/*
    552      0   stevel 	 * if the RPC call times out, null out all return arguments, set
    553      0   stevel 	 * minor_status to its maximum value, and return GSS_S_FAILURE
    554      0   stevel 	 */
    555      0   stevel 
    556      0   stevel 		if (minor_status != NULL)
    557      0   stevel 			*minor_status = DEFAULT_MINOR_STAT;
    558      0   stevel 		if (cred_handle != NULL)
    559      0   stevel 			*cred_handle = NULL;
    560      0   stevel 
    561      0   stevel 		killgssd_handle(clnt);
    562      0   stevel 		GSSLOG0(1, "kgss_release_cred: RPC call times out\n");
    563      0   stevel 		return (GSS_S_FAILURE);
    564      0   stevel 	}
    565      0   stevel 
    566      0   stevel 	/* if the release succeeded, null out the cred_handle */
    567      0   stevel 
    568      0   stevel 	if (res.status == GSS_S_COMPLETE && cred_handle != NULL)
    569      0   stevel 		*cred_handle = NULL;
    570      0   stevel 
    571      0   stevel 	/* copy the rpc results into the return arguments */
    572      0   stevel 
    573      0   stevel 	if (minor_status != NULL)
    574      0   stevel 		*minor_status = res.minor_status;
    575      0   stevel 
    576      0   stevel 	/* return with status returned in rpc call */
    577      0   stevel 
    578      0   stevel 	killgssd_handle(clnt);
    579      0   stevel 
    580      0   stevel 	return (res.status);
    581      0   stevel 
    582      0   stevel }
    583      0   stevel 
    584      0   stevel OM_uint32
    585      0   stevel kgss_release_cred(minor_status,
    586      0   stevel 			cred_handle,
    587      0   stevel 			uid)
    588      0   stevel     OM_uint32 *minor_status;
    589      0   stevel     gss_cred_id_t *cred_handle;
    590      0   stevel     uid_t uid;
    591      0   stevel 
    592      0   stevel {
    593      0   stevel 
    594      0   stevel 	OM_uint32	err;
    595      0   stevel 	struct kgss_cred *kcred;
    596      0   stevel 
    597      0   stevel 	if (*cred_handle == GSS_C_NO_CREDENTIAL)
    598      0   stevel 		return (GSS_S_COMPLETE);
    599      0   stevel 	else
    600      0   stevel 		kcred = KCRED_TO_KGSS_CRED(*cred_handle);
    601      0   stevel 
    602      0   stevel 	err = kgss_release_cred_wrapped(minor_status, &kcred->gssd_cred,
    603      0   stevel 		uid, kcred->gssd_cred_verifier);
    604      0   stevel 	KGSS_CRED_FREE(kcred);
    605      0   stevel 	*cred_handle = GSS_C_NO_CREDENTIAL;
    606      0   stevel 	return (err);
    607      0   stevel }
    608      0   stevel 
    609      0   stevel static OM_uint32
    610      0   stevel kgss_init_sec_context_wrapped(
    611      0   stevel 	OM_uint32 *minor_status,
    612      0   stevel 	const gssd_cred_id_t claimant_cred_handle,
    613      0   stevel 	OM_uint32 gssd_cred_verifier,
    614      0   stevel 	gssd_ctx_id_t *context_handle,
    615      0   stevel 	OM_uint32 *gssd_context_verifier,
    616      0   stevel 	const gss_name_t target_name,
    617      0   stevel 	const gss_OID mech_type,
    618      0   stevel 	int req_flags,
    619      0   stevel 	OM_uint32 time_req,
    620      0   stevel 	const gss_channel_bindings_t input_chan_bindings,
    621      0   stevel 	const gss_buffer_t input_token,
    622      0   stevel 	gss_OID *actual_mech_type,
    623      0   stevel 	gss_buffer_t output_token,
    624      0   stevel 	int *ret_flags,
    625      0   stevel 	OM_uint32 *time_rec,
    626      0   stevel 	uid_t uid)
    627      0   stevel {
    628      0   stevel 	CLIENT *clnt;
    629      0   stevel 
    630      0   stevel 	OM_uint32 	minor_status_temp;
    631      0   stevel 	gss_buffer_desc	external_name;
    632      0   stevel 	gss_OID		name_type;
    633      0   stevel 
    634      0   stevel 	gss_init_sec_context_arg arg;
    635      0   stevel 	gss_init_sec_context_res res;
    636      0   stevel 
    637      0   stevel 	/* get the client handle to GSSD */
    638      0   stevel 
    639      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
    640      0   stevel 		GSSLOG(1,
    641      0   stevel 		"kgss_init_sec_context: can't connect to server on %s\n",
    642      0   stevel 		server);
    643      0   stevel 		return (GSS_S_FAILURE);
    644      0   stevel 	}
    645      0   stevel 
    646      0   stevel 	/* convert the target name from internal to external format */
    647      0   stevel 
    648      0   stevel 	if (gss_display_name(&minor_status_temp, target_name,
    649      0   stevel 		&external_name, &name_type) != GSS_S_COMPLETE) {
    650      0   stevel 
    651      0   stevel 		*minor_status = (OM_uint32) minor_status_temp;
    652      0   stevel 		killgssd_handle(clnt);
    653      0   stevel 		GSSLOG0(1, "kgss_init_sec_context: can't display name\n");
    654      0   stevel 		return ((OM_uint32) GSS_S_FAILURE);
    655      0   stevel 	}
    656      0   stevel 
    657      0   stevel 
    658      0   stevel 	/* copy the procedure arguments into the rpc arg parameter */
    659      0   stevel 
    660      0   stevel 	arg.uid = (OM_uint32)uid;
    661      0   stevel 
    662      0   stevel 	arg.context_handle.GSS_CTX_ID_T_len =
    663      0   stevel 		*context_handle == (gssd_ctx_id_t)GSS_C_NO_CONTEXT ?
    664      0   stevel 			0 : (uint_t)sizeof (gssd_ctx_id_t);
    665      0   stevel 	arg.context_handle.GSS_CTX_ID_T_val =  (char *)context_handle;
    666      0   stevel 
    667      0   stevel 	arg.gssd_context_verifier =  *gssd_context_verifier;
    668      0   stevel 
    669      0   stevel 	arg.claimant_cred_handle.GSS_CRED_ID_T_len =
    670      0   stevel 		claimant_cred_handle == (gssd_cred_id_t)GSS_C_NO_CREDENTIAL ?
    671      0   stevel 			0 : (uint_t)sizeof (gssd_cred_id_t);
    672      0   stevel 	arg.claimant_cred_handle.GSS_CRED_ID_T_val =
    673      0   stevel 						(char *)&claimant_cred_handle;
    674      0   stevel 	arg.gssd_cred_verifier = gssd_cred_verifier;
    675      0   stevel 
    676      0   stevel 	arg.target_name.GSS_BUFFER_T_len = (uint_t)external_name.length;
    677      0   stevel 	arg.target_name.GSS_BUFFER_T_val = (char *)external_name.value;
    678      0   stevel 
    679      0   stevel 	arg.name_type.GSS_OID_len =
    680      0   stevel 		name_type == GSS_C_NULL_OID ?
    681      0   stevel 			0 : (uint_t)name_type->length;
    682      0   stevel 
    683      0   stevel 	arg.name_type.GSS_OID_val =
    684      0   stevel 		name_type == GSS_C_NULL_OID ?
    685      0   stevel 			(char *)NULL : (char *)name_type->elements;
    686      0   stevel 
    687      0   stevel 	arg.mech_type.GSS_OID_len = (uint_t)(mech_type != GSS_C_NULL_OID ?
    688      0   stevel 						mech_type->length : 0);
    689      0   stevel 	arg.mech_type.GSS_OID_val = (char *)(mech_type != GSS_C_NULL_OID ?
    690      0   stevel 						mech_type->elements : 0);
    691      0   stevel 
    692      0   stevel 	arg.req_flags = req_flags;
    693      0   stevel 
    694      0   stevel 	arg.time_req = time_req;
    695      0   stevel 
    696      0   stevel 	if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) {
    697      0   stevel 		arg.input_chan_bindings.present = YES;
    698      0   stevel 		arg.input_chan_bindings.initiator_addrtype =
    699      0   stevel 			input_chan_bindings->initiator_addrtype;
    700      0   stevel 		arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len =
    701      0   stevel 			(uint_t)input_chan_bindings->initiator_address.length;
    702      0   stevel 		arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val =
    703      0   stevel 			(void *)input_chan_bindings->initiator_address.value;
    704      0   stevel 		arg.input_chan_bindings.acceptor_addrtype =
    705      0   stevel 			input_chan_bindings->acceptor_addrtype;
    706      0   stevel 		arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len =
    707      0   stevel 			(uint_t)input_chan_bindings->acceptor_address.length;
    708      0   stevel 		arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val =
    709      0   stevel 			(void *)input_chan_bindings->acceptor_address.value;
    710      0   stevel 		arg.input_chan_bindings.application_data.GSS_BUFFER_T_len =
    711      0   stevel 			(uint_t)input_chan_bindings->application_data.length;
    712      0   stevel 		arg.input_chan_bindings.application_data.GSS_BUFFER_T_val =
    713      0   stevel 			(void *)input_chan_bindings->application_data.value;
    714      0   stevel 	} else {
    715      0   stevel 		arg.input_chan_bindings.present = NO;
    716      0   stevel 		arg.input_chan_bindings.initiator_addrtype = 0;
    717      0   stevel 		arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len = 0;
    718      0   stevel 		arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val = 0;
    719      0   stevel 		arg.input_chan_bindings.acceptor_addrtype = 0;
    720      0   stevel 		arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len = 0;
    721      0   stevel 		arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val = 0;
    722      0   stevel 		arg.input_chan_bindings.application_data.GSS_BUFFER_T_len = 0;
    723      0   stevel 		arg.input_chan_bindings.application_data.GSS_BUFFER_T_val = 0;
    724      0   stevel 	}
    725      0   stevel 
    726      0   stevel 	arg.input_token.GSS_BUFFER_T_len =
    727      0   stevel 		(uint_t)(input_token != GSS_C_NO_BUFFER ?
    728      0   stevel 		input_token->length : 0);
    729      0   stevel 	arg.input_token.GSS_BUFFER_T_val =
    730      0   stevel 		(char *)(input_token != GSS_C_NO_BUFFER ?
    731      0   stevel 		input_token->value : 0);
    732      0   stevel 
    733      0   stevel 	/* call the remote procedure */
    734      0   stevel 
    735      0   stevel 	bzero((caddr_t)&res, sizeof (res));
    736      0   stevel 	if (gss_init_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
    737      0   stevel 
    738      0   stevel 	/*
    739      0   stevel 	 * if the RPC call times out, null out all return arguments, set
    740      0   stevel 	 * minor_status to its maximum value, and return GSS_S_FAILURE
    741      0   stevel 	 */
    742      0   stevel 
    743      0   stevel 		if (minor_status != NULL)
    744      0   stevel 			*minor_status = DEFAULT_MINOR_STAT;
    745      0   stevel 		if (actual_mech_type != NULL)
    746      0   stevel 			*actual_mech_type = NULL;
    747      0   stevel 		if (output_token != NULL)
    748      0   stevel 			output_token->length = 0;
    749      0   stevel 		if (ret_flags != NULL)
    750      0   stevel 			*ret_flags = 0;
    751      0   stevel 		if (time_rec != NULL)
    752      0   stevel 			*time_rec = 0;
    753      0   stevel 
    754      0   stevel 		killgssd_handle(clnt);
    755      0   stevel 		(void) gss_release_buffer(&minor_status_temp, &external_name);
    756      0   stevel 		GSSLOG0(1, "kgss_init_sec_context: RPC call times out\n");
    757      0   stevel 		return (GSS_S_FAILURE);
    758      0   stevel 	}
    759      0   stevel 
    760      0   stevel 	/* free the allocated memory for the flattened name */
    761      0   stevel 
    762      0   stevel 	(void) gss_release_buffer(&minor_status_temp, &external_name);
    763      0   stevel 
    764      0   stevel 	if (minor_status != NULL)
    765      0   stevel 		*minor_status = res.minor_status;
    766      0   stevel 
    767  10598    Glenn 	if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) {
    768  10598    Glenn 		output_token->length =
    769  10598    Glenn 			(size_t)res.output_token.GSS_BUFFER_T_len;
    770  10598    Glenn 		output_token->value =
    771  10598    Glenn 			(void *)MALLOC(output_token->length);
    772  10598    Glenn 		(void) memcpy(output_token->value,
    773  10598    Glenn 			    res.output_token.GSS_BUFFER_T_val,
    774  10598    Glenn 			    output_token->length);
    775  10598    Glenn 	}
    776  10598    Glenn 
    777      0   stevel 	/* if the call was successful, copy out the results */
    778      0   stevel 	if (res.status == (OM_uint32) GSS_S_COMPLETE ||
    779      0   stevel 		res.status == (OM_uint32) GSS_S_CONTINUE_NEEDED) {
    780      0   stevel 		/*
    781      0   stevel 		 * if the return code is GSS_S_CONTINUE_NEEDED
    782      0   stevel 		 * ignore all return parameters except for
    783      0   stevel 		 * status codes, output token and context handle.
    784      0   stevel 		 */
    785      0   stevel 		*context_handle =
    786      0   stevel 			*((gssd_ctx_id_t *)
    787      0   stevel 			res.context_handle.GSS_CTX_ID_T_val);
    788      0   stevel 		*gssd_context_verifier = res.gssd_context_verifier;
    789      0   stevel 
    790      0   stevel 		if (res.status == GSS_S_COMPLETE) {
    791      0   stevel 			if (actual_mech_type != NULL) {
    792      0   stevel 				*actual_mech_type =
    793      0   stevel 					(gss_OID) MALLOC(sizeof (gss_OID_desc));
    794      0   stevel 				(*actual_mech_type)->length =
    795      0   stevel 					(OM_UINT32)
    796      0   stevel 					res.actual_mech_type.GSS_OID_len;
    797      0   stevel 				(*actual_mech_type)->elements =
    798      0   stevel 					(void *)
    799      0   stevel 					MALLOC((*actual_mech_type)->length);
    800      0   stevel 				(void) memcpy((*actual_mech_type)->elements,
    801      0   stevel 					(void *)
    802      0   stevel 					res.actual_mech_type.GSS_OID_val,
    803      0   stevel 					(*actual_mech_type)->length);
    804      0   stevel 			}
    805      0   stevel 
    806      0   stevel 
    807      0   stevel 			if (ret_flags != NULL)
    808      0   stevel 				*ret_flags = res.ret_flags;
    809      0   stevel 
    810      0   stevel 			if (time_rec != NULL)
    811      0   stevel 				*time_rec = res.time_rec;
    812      0   stevel 		}
    813      0   stevel 	}
    814      0   stevel 
    815      0   stevel 	/*
    816      0   stevel 	 * free the memory allocated for the results and return with the status
    817      0   stevel 	 * received in the rpc call
    818      0   stevel 	 */
    819      0   stevel 
    820      0   stevel 	clnt_freeres(clnt, xdr_gss_init_sec_context_res, (caddr_t)&res);
    821      0   stevel 	killgssd_handle(clnt);
    822      0   stevel 	return (res.status);
    823      0   stevel 
    824      0   stevel }
    825      0   stevel 
    826      0   stevel static struct gss_config default_gc = {
    827      0   stevel 	{ 0, NULL},
    828      0   stevel 	NULL,
    829      0   stevel 	NULL,
    830      0   stevel 	0,
    831      0   stevel /* EXPORT DELETE START */ /* CRYPT DELETE START */
    832      0   stevel 	kgss_unseal_wrapped,
    833      0   stevel /* EXPORT DELETE END */ /* CRYPT DELETE END */
    834      0   stevel 	NULL,		/* kgss_delete_sec_context_wrapped */
    835      0   stevel /* EXPORT DELETE START */ /* CRYPT DELETE START */
    836      0   stevel 	kgss_seal_wrapped,
    837      0   stevel /* EXPORT DELETE END */ /* CRYPT DELETE END */
    838      0   stevel 	NULL,		/* kgss_import_sec_context */
    839      0   stevel /* EXPORT DELETE START */
    840      0   stevel /* CRYPT DELETE START */
    841      0   stevel #if 0
    842      0   stevel /* CRYPT DELETE END */
    843      0   stevel 	kgss_seal_wrapped,
    844      0   stevel 	kgss_unseal_wrapped,
    845      0   stevel /* CRYPT DELETE START */
    846      0   stevel #endif
    847      0   stevel /* CRYPT DELETE END */
    848      0   stevel /* EXPORT DELETE END */
    849      0   stevel 	kgss_sign_wrapped,
    850      0   stevel 	kgss_verify_wrapped
    851      0   stevel };
    852      0   stevel 
    853      0   stevel void
    854      0   stevel kgss_free_oid(gss_OID oid)
    855      0   stevel {
    856      0   stevel 	FREE(oid->elements, oid->length);
    857      0   stevel 	FREE(oid, sizeof (gss_OID_desc));
    858      0   stevel }
    859      0   stevel 
    860      0   stevel OM_uint32
    861      0   stevel kgss_init_sec_context(
    862      0   stevel 	OM_uint32 *minor_status,
    863      0   stevel 	const gss_cred_id_t claimant_cred_handle,
    864      0   stevel 	gss_ctx_id_t *context_handle,
    865      0   stevel 	const gss_name_t target_name,
    866      0   stevel 	const gss_OID mech_type,
    867      0   stevel 	int req_flags,
    868      0   stevel 	OM_uint32 time_req,
    869      0   stevel 	const gss_channel_bindings_t input_chan_bindings,
    870      0   stevel 	const gss_buffer_t input_token,
    871      0   stevel 	gss_OID *actual_mech_type,
    872      0   stevel 	gss_buffer_t output_token,
    873      0   stevel 	int *ret_flags,
    874      0   stevel 	OM_uint32 *time_rec,
    875      0   stevel 	uid_t uid)
    876      0   stevel {
    877      0   stevel 	OM_uint32	err;
    878      0   stevel 	struct kgss_ctx	*kctx;
    879      0   stevel 	gss_OID	amt;
    880      0   stevel 	gssd_cred_id_t gssd_cl_cred_handle;
    881      0   stevel 	OM_uint32 gssd_cred_verifier;
    882      0   stevel 
    883      0   stevel 	/*
    884      0   stevel 	 * If this is an initial call, we'll need to create the
    885      0   stevel 	 * wrapper struct that contains kernel state information, and
    886      0   stevel 	 * a reference to the handle from gssd.
    887      0   stevel 	 */
    888      0   stevel 	if (*context_handle == GSS_C_NO_CONTEXT) {
    889      0   stevel 		kctx = KGSS_ALLOC();
    890      0   stevel 		/*
    891      0   stevel 		 * The default gss-mechanism struct as pointers to
    892      0   stevel 		 * the sign/seal/verify/unseal routines that make
    893      0   stevel 		 * upcalls to gssd.
    894      0   stevel 		 */
    895      0   stevel 		kctx->mech = &default_gc;
    896      0   stevel 		kctx->gssd_ctx = (gssd_ctx_id_t)GSS_C_NO_CONTEXT;
    897      0   stevel 		*context_handle = (gss_ctx_id_t)kctx;
    898      0   stevel 	} else
    899      0   stevel 		kctx = (struct kgss_ctx *)*context_handle;
    900      0   stevel 
    901      0   stevel 	if (claimant_cred_handle != GSS_C_NO_CREDENTIAL) {
    902      0   stevel 		gssd_cred_verifier = KCRED_TO_CREDV(claimant_cred_handle);
    903      0   stevel 		gssd_cl_cred_handle = KCRED_TO_CRED(claimant_cred_handle);
    904      0   stevel 	} else
    905      0   stevel 		gssd_cl_cred_handle = (gssd_cred_id_t)GSS_C_NO_CREDENTIAL;
    906      0   stevel 
    907      0   stevel 	/*
    908      0   stevel 	 * We need to know the resulting mechanism oid, so allocate
    909      0   stevel 	 * it if the caller won't.
    910      0   stevel 	 */
    911      0   stevel 	if (actual_mech_type == NULL)
    912      0   stevel 		actual_mech_type = &amt;
    913      0   stevel 
    914      0   stevel 	err = kgss_init_sec_context_wrapped(minor_status, gssd_cl_cred_handle,
    915      0   stevel 		gssd_cred_verifier, &kctx->gssd_ctx, &kctx->gssd_ctx_verifier,
    916      0   stevel 		target_name, mech_type, req_flags, time_req,
    917      0   stevel 		input_chan_bindings, input_token, actual_mech_type,
    918      0   stevel 		output_token, ret_flags, time_rec, uid);
    919      0   stevel 
    920      0   stevel 	if (GSS_ERROR(err)) {
    921      0   stevel 		KGSS_FREE(kctx);
    922      0   stevel 		*context_handle = GSS_C_NO_CONTEXT;
    923      0   stevel 	} else if (err == GSS_S_COMPLETE) {
    924      0   stevel 		/*
    925      0   stevel 		 * Now check if there is a kernel module for this
    926      0   stevel 		 * mechanism OID. If so, set the gss_mechanism structure
    927      0   stevel 		 * in the wrapper context to point to the kernel mech.
    928      0   stevel 		 */
    929      0   stevel 		__kgss_reset_mech(&kctx->mech, *actual_mech_type);
    930      0   stevel 
    931      0   stevel 		/*
    932      0   stevel 		 * If the mech oid was allocated for us, free it.
    933      0   stevel 		 */
    934      0   stevel 		if (&amt == actual_mech_type) {
    935      0   stevel 			kgss_free_oid(amt);
    936      0   stevel 		}
    937      0   stevel 	}
    938      0   stevel 	return (err);
    939      0   stevel }
    940      0   stevel 
    941      0   stevel static OM_uint32
    942      0   stevel kgss_accept_sec_context_wrapped(
    943      0   stevel 	OM_uint32 *minor_status,
    944      0   stevel 	gssd_ctx_id_t *context_handle,
    945      0   stevel 	OM_uint32 *gssd_context_verifier,
    946      0   stevel 	const gssd_cred_id_t verifier_cred_handle,
    947      0   stevel 	OM_uint32 gssd_cred_verifier,
    948      0   stevel 	const gss_buffer_t input_token,
    949      0   stevel 	const gss_channel_bindings_t input_chan_bindings,
    950      0   stevel 	gss_buffer_t src_name,
    951      0   stevel 	gss_OID *mech_type,
    952      0   stevel 	gss_buffer_t output_token,
    953      0   stevel 	int *ret_flags,
    954      0   stevel 	OM_uint32 *time_rec,
    955      0   stevel 	gss_cred_id_t *delegated_cred_handle,
    956      0   stevel 	uid_t uid)
    957      0   stevel {
    958      0   stevel 	CLIENT *clnt;
    959      0   stevel 
    960      0   stevel 	gss_accept_sec_context_arg arg;
    961      0   stevel 	gss_accept_sec_context_res res;
    962      0   stevel 	struct kgss_cred *kcred;
    963      0   stevel 
    964      0   stevel 	/* get the client handle to GSSD */
    965      0   stevel 
    966      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
    967      0   stevel 		GSSLOG(1,
    968      0   stevel 		"kgss_accept_sec_context: can't connect to server on %s\n",
    969      0   stevel 		server);
    970      0   stevel 		return (GSS_S_FAILURE);
    971      0   stevel 	}
    972      0   stevel 
    973      0   stevel 	/* copy the procedure arguments into the rpc arg parameter */
    974      0   stevel 
    975      0   stevel 	arg.uid = (OM_uint32)uid;
    976      0   stevel 
    977      0   stevel 	arg.context_handle.GSS_CTX_ID_T_len =
    978      0   stevel 		*context_handle == (gssd_ctx_id_t)GSS_C_NO_CONTEXT ?
    979      0   stevel 			0 : (uint_t)sizeof (gssd_ctx_id_t);
    980      0   stevel 	arg.context_handle.GSS_CTX_ID_T_val =  (char *)context_handle;
    981      0   stevel 	arg.gssd_context_verifier = *gssd_context_verifier;
    982      0   stevel 
    983      0   stevel 	arg.verifier_cred_handle.GSS_CRED_ID_T_len =
    984      0   stevel 			verifier_cred_handle ==
    985      0   stevel 			(gssd_cred_id_t)GSS_C_NO_CREDENTIAL ?
    986      0   stevel 			0 : (uint_t)sizeof (gssd_cred_id_t);
    987      0   stevel 	arg.verifier_cred_handle.GSS_CRED_ID_T_val =
    988      0   stevel 						(char *)&verifier_cred_handle;
    989      0   stevel 	arg.gssd_cred_verifier = gssd_cred_verifier;
    990      0   stevel 
    991      0   stevel 	arg.input_token_buffer.GSS_BUFFER_T_len =
    992      0   stevel 			(uint_t)(input_token != GSS_C_NO_BUFFER ?
    993      0   stevel 						input_token->length : 0);
    994      0   stevel 	arg.input_token_buffer.GSS_BUFFER_T_val =
    995      0   stevel 			(char *)(input_token != GSS_C_NO_BUFFER ?
    996      0   stevel 						input_token->value : 0);
    997      0   stevel 
    998      0   stevel 	if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) {
    999      0   stevel 		arg.input_chan_bindings.present = YES;
   1000      0   stevel 		arg.input_chan_bindings.initiator_addrtype =
   1001      0   stevel 			input_chan_bindings->initiator_addrtype;
   1002      0   stevel 		arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len =
   1003      0   stevel 			(uint_t)input_chan_bindings->initiator_address.length;
   1004      0   stevel 		arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val =
   1005      0   stevel 			(void *)input_chan_bindings->initiator_address.value;
   1006      0   stevel 		arg.input_chan_bindings.acceptor_addrtype =
   1007      0   stevel 			input_chan_bindings->acceptor_addrtype;
   1008      0   stevel 		arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len =
   1009      0   stevel 			(uint_t)input_chan_bindings->acceptor_address.length;
   1010      0   stevel 		arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val =
   1011      0   stevel 			(void *)input_chan_bindings->acceptor_address.value;
   1012      0   stevel 		arg.input_chan_bindings.application_data.GSS_BUFFER_T_len =
   1013      0   stevel 			(uint_t)input_chan_bindings->application_data.length;
   1014      0   stevel 		arg.input_chan_bindings.application_data.GSS_BUFFER_T_val =
   1015      0   stevel 			(void *)input_chan_bindings->application_data.value;
   1016      0   stevel 	} else {
   1017      0   stevel 
   1018      0   stevel 		arg.input_chan_bindings.present = NO;
   1019      0   stevel 		arg.input_chan_bindings.initiator_addrtype = 0;
   1020      0   stevel 		arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len = 0;
   1021      0   stevel 		arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val = 0;
   1022      0   stevel 		arg.input_chan_bindings.acceptor_addrtype = 0;
   1023      0   stevel 		arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len = 0;
   1024      0   stevel 		arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val = 0;
   1025      0   stevel 		arg.input_chan_bindings.application_data.GSS_BUFFER_T_len = 0;
   1026      0   stevel 		arg.input_chan_bindings.application_data.GSS_BUFFER_T_val = 0;
   1027      0   stevel 	}
   1028      0   stevel 
   1029      0   stevel 	/* set the return parameters in case of errors.... */
   1030      0   stevel 	if (minor_status != NULL)
   1031      0   stevel 		*minor_status = DEFAULT_MINOR_STAT;
   1032      0   stevel 	if (src_name != NULL) {
   1033      0   stevel 		src_name->length = 0;
   1034      0   stevel 		src_name->value = NULL;
   1035      0   stevel 	}
   1036      0   stevel 	if (mech_type != NULL)
   1037      0   stevel 		*mech_type = NULL;
   1038      0   stevel 	if (output_token != NULL)
   1039      0   stevel 		output_token->length = 0;
   1040      0   stevel 	if (ret_flags != NULL)
   1041      0   stevel 		*ret_flags = 0;
   1042      0   stevel 	if (time_rec != NULL)
   1043      0   stevel 		*time_rec = 0;
   1044      0   stevel 	if (delegated_cred_handle != NULL)
   1045      0   stevel 		*delegated_cred_handle = NULL;
   1046      0   stevel 
   1047      0   stevel 	/* call the remote procedure */
   1048      0   stevel 
   1049      0   stevel 	bzero((caddr_t)&res, sizeof (res));
   1050      0   stevel 	if (gss_accept_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
   1051      0   stevel 		killgssd_handle(clnt);
   1052      0   stevel 		GSSLOG0(1, "kgss_accept_sec_context: RPC call times out\n");
   1053      0   stevel 		return (GSS_S_FAILURE);
   1054      0   stevel 	}
   1055      0   stevel 
   1056  10598    Glenn 	if (minor_status != NULL)
   1057  10598    Glenn 		*minor_status = res.minor_status;
   1058  10598    Glenn 
   1059  10598    Glenn 	if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) {
   1060  10598    Glenn 		output_token->length =
   1061  10598    Glenn 			res.output_token.GSS_BUFFER_T_len;
   1062  10598    Glenn 		output_token->value =
   1063  10598    Glenn 			(void *)  MALLOC(output_token->length);
   1064  10598    Glenn 		(void) memcpy(output_token->value,
   1065  10598    Glenn 			    res.output_token.GSS_BUFFER_T_val,
   1066  10598    Glenn 			    output_token->length);
   1067  10598    Glenn 	}
   1068  10598    Glenn 
   1069      0   stevel 	/* if the call was successful, copy out the results */
   1070      0   stevel 
   1071      0   stevel 	if (res.status == (OM_uint32) GSS_S_COMPLETE ||
   1072      0   stevel 		res.status == (OM_uint32) GSS_S_CONTINUE_NEEDED) {
   1073      0   stevel 
   1074      0   stevel 		/*
   1075      0   stevel 		 * the only parameters that are ready when we
   1076      0   stevel 		 * get GSS_S_CONTINUE_NEEDED are: minor, ctxt_handle,
   1077      0   stevel 		 * and the output token to send to the peer.
   1078      0   stevel 		 */
   1079      0   stevel 
   1080      0   stevel 		*context_handle = *((gssd_ctx_id_t *)
   1081      0   stevel 			res.context_handle.GSS_CTX_ID_T_val);
   1082      0   stevel 			*gssd_context_verifier = res.gssd_context_verifier;
   1083      0   stevel 
   1084      0   stevel 		/* these other parameters are only ready upon GSS_S_COMPLETE */
   1085      0   stevel 		if (res.status == (OM_uint32) GSS_S_COMPLETE) {
   1086      0   stevel 
   1087      0   stevel 			if (src_name != NULL) {
   1088      0   stevel 			    src_name->length = res.src_name.GSS_BUFFER_T_len;
   1089      0   stevel 			    src_name->value = res.src_name.GSS_BUFFER_T_val;
   1090      0   stevel 			    res.src_name.GSS_BUFFER_T_val = NULL;
   1091      0   stevel 			    res.src_name.GSS_BUFFER_T_len = 0;
   1092      0   stevel 			}
   1093      0   stevel 
   1094      0   stevel 			/*
   1095      0   stevel 			 * move mech type returned to mech_type
   1096      0   stevel 			 * for gss_import_name_for_mech()
   1097      0   stevel 			 */
   1098      0   stevel 			if (mech_type != NULL) {
   1099      0   stevel 				*mech_type = (gss_OID)
   1100      0   stevel 					MALLOC(sizeof (gss_OID_desc));
   1101      0   stevel 				(*mech_type)->length =
   1102      0   stevel 					(OM_UINT32) res.mech_type.GSS_OID_len;
   1103      0   stevel 				(*mech_type)->elements =
   1104      0   stevel 					(void *) MALLOC((*mech_type)->length);
   1105      0   stevel 				(void) memcpy((*mech_type)->elements,
   1106      0   stevel 					res.mech_type.GSS_OID_val,
   1107      0   stevel 					(*mech_type)->length);
   1108      0   stevel 			}
   1109      0   stevel 
   1110      0   stevel 			if (ret_flags != NULL)
   1111      0   stevel 				*ret_flags = res.ret_flags;
   1112      0   stevel 
   1113      0   stevel 			if (time_rec != NULL)
   1114      0   stevel 				*time_rec = res.time_rec;
   1115      0   stevel 
   1116      0   stevel 			if ((delegated_cred_handle != NULL) &&
   1117      0   stevel 				(res.delegated_cred_handle.GSS_CRED_ID_T_len
   1118      0   stevel 				!= 0)) {
   1119      0   stevel 				kcred = KGSS_CRED_ALLOC();
   1120      0   stevel 				kcred->gssd_cred =
   1121      0   stevel 				*((gssd_cred_id_t *)
   1122      0   stevel 				res.delegated_cred_handle.GSS_CRED_ID_T_val);
   1123      0   stevel 				kcred->gssd_cred_verifier =
   1124      0   stevel 					res.gssd_context_verifier;
   1125      0   stevel 				*delegated_cred_handle = (gss_cred_id_t)kcred;
   1126      0   stevel 			}
   1127      0   stevel 
   1128      0   stevel 		}
   1129      0   stevel 	}
   1130      0   stevel 
   1131      0   stevel 
   1132      0   stevel 	/*
   1133      0   stevel 	 * free the memory allocated for the results and return with the status
   1134      0   stevel 	 * received in the rpc call
   1135      0   stevel 	 */
   1136      0   stevel 
   1137      0   stevel 	clnt_freeres(clnt, xdr_gss_accept_sec_context_res, (caddr_t)&res);
   1138      0   stevel 	killgssd_handle(clnt);
   1139      0   stevel 	return (res.status);
   1140      0   stevel 
   1141      0   stevel }
   1142      0   stevel 
   1143      0   stevel OM_uint32
   1144      0   stevel kgss_accept_sec_context(
   1145      0   stevel 	OM_uint32 *minor_status,
   1146      0   stevel 	gss_ctx_id_t *context_handle,
   1147      0   stevel 	const gss_cred_id_t verifier_cred_handle,
   1148      0   stevel 	const gss_buffer_t input_token,
   1149      0   stevel 	const gss_channel_bindings_t input_chan_bindings,
   1150      0   stevel 	gss_buffer_t src_name,
   1151      0   stevel 	gss_OID *mech_type,
   1152      0   stevel 	gss_buffer_t output_token,
   1153      0   stevel 	int *ret_flags,
   1154      0   stevel 	OM_uint32 *time_rec,
   1155      0   stevel 	gss_cred_id_t *delegated_cred_handle,
   1156      0   stevel 	uid_t uid)
   1157      0   stevel {
   1158      0   stevel 	OM_uint32 err;
   1159      0   stevel 	struct kgss_ctx	*kctx;
   1160      0   stevel 	gss_OID mt;
   1161      0   stevel 	OM_uint32 gssd_cred_verifier;
   1162      0   stevel 	gssd_cred_id_t gssd_ver_cred_handle;
   1163      0   stevel 
   1164      0   stevel 
   1165      0   stevel 	/*
   1166      0   stevel 	 * See kgss_init_sec_context() to get an idea of what is going
   1167      0   stevel 	 * on here.
   1168      0   stevel 	 */
   1169      0   stevel 	if (mech_type == NULL)
   1170      0   stevel 		mech_type = &mt;
   1171      0   stevel 
   1172      0   stevel 	if (*context_handle == GSS_C_NO_CONTEXT) {
   1173      0   stevel 		kctx = KGSS_ALLOC();
   1174      0   stevel 		kctx->mech = &default_gc;
   1175      0   stevel 		kctx->gssd_ctx = (gssd_ctx_id_t)GSS_C_NO_CONTEXT;
   1176      0   stevel 		*context_handle = (gss_ctx_id_t)kctx;
   1177      0   stevel 	} else
   1178      0   stevel 		kctx = (struct kgss_ctx *)*context_handle;
   1179      0   stevel 
   1180      0   stevel 	if (verifier_cred_handle != GSS_C_NO_CREDENTIAL) {
   1181      0   stevel 		gssd_cred_verifier = KCRED_TO_CREDV(verifier_cred_handle);
   1182      0   stevel 		gssd_ver_cred_handle = KCRED_TO_CRED(verifier_cred_handle);
   1183      0   stevel 	} else
   1184      0   stevel 		gssd_ver_cred_handle = (gssd_cred_id_t)GSS_C_NO_CREDENTIAL;
   1185      0   stevel 
   1186      0   stevel 	err = kgss_accept_sec_context_wrapped(minor_status,
   1187      0   stevel 		&kctx->gssd_ctx, &kctx->gssd_ctx_verifier,
   1188      0   stevel 		gssd_ver_cred_handle, gssd_cred_verifier,
   1189      0   stevel 		input_token, input_chan_bindings, src_name,
   1190      0   stevel 		mech_type, output_token, ret_flags,
   1191      0   stevel 		time_rec, delegated_cred_handle, uid);
   1192      0   stevel 
   1193      0   stevel 	if (GSS_ERROR(err)) {
   1194      0   stevel 		KGSS_FREE(kctx);
   1195      0   stevel 		*context_handle = GSS_C_NO_CONTEXT;
   1196      0   stevel 
   1197      0   stevel 	} else if (err == GSS_S_COMPLETE) {
   1198      0   stevel 		__kgss_reset_mech(&kctx->mech, *mech_type);
   1199      0   stevel 
   1200      0   stevel 		/*
   1201      0   stevel 		 * If the mech oid was allocated for us, free it.
   1202      0   stevel 		 */
   1203      0   stevel 		if (&mt == mech_type) {
   1204      0   stevel 			kgss_free_oid(mt);
   1205      0   stevel 		}
   1206      0   stevel 	}
   1207      0   stevel 
   1208      0   stevel 	return (err);
   1209      0   stevel }
   1210      0   stevel 
   1211      0   stevel OM_uint32
   1212      0   stevel kgss_process_context_token(minor_status,
   1213      0   stevel 				context_handle,
   1214      0   stevel 				token_buffer,
   1215      0   stevel 				uid)
   1216      0   stevel 	OM_uint32 *minor_status;
   1217      0   stevel 	const gss_ctx_id_t context_handle;
   1218      0   stevel 	gss_buffer_t token_buffer;
   1219      0   stevel 	uid_t uid;
   1220      0   stevel {
   1221      0   stevel 	CLIENT *clnt;
   1222      0   stevel 	OM_uint32 gssd_context_verifier;
   1223      0   stevel 	gssd_ctx_id_t gssd_ctx_handle;
   1224      0   stevel 	gss_process_context_token_arg arg;
   1225      0   stevel 	gss_process_context_token_res res;
   1226      0   stevel 
   1227      0   stevel 	gssd_context_verifier = KGSS_CTX_TO_GSSD_CTXV(context_handle);
   1228      0   stevel 	gssd_ctx_handle = (gssd_ctx_id_t)KGSS_CTX_TO_GSSD_CTX(context_handle);
   1229      0   stevel 
   1230      0   stevel 	/* get the client handle to GSSD */
   1231      0   stevel 
   1232      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
   1233      0   stevel 		GSSLOG(1,
   1234      0   stevel 		"kgss_process_context_token: can't connect to server on %s\n",
   1235      0   stevel 		server);
   1236      0   stevel 		return (GSS_S_FAILURE);
   1237      0   stevel 	}
   1238      0   stevel 
   1239      0   stevel 	/* copy the procedure arguments into the rpc arg parameter */
   1240      0   stevel 
   1241      0   stevel 	arg.uid = (OM_uint32) uid;
   1242      0   stevel 
   1243      0   stevel 	arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
   1244      0   stevel 	arg.context_handle.GSS_CTX_ID_T_val = (char *)&gssd_ctx_handle;
   1245      0   stevel 	arg.gssd_context_verifier = gssd_context_verifier;
   1246      0   stevel 	arg.token_buffer.GSS_BUFFER_T_len = (uint_t)token_buffer->length;
   1247      0   stevel 	arg.token_buffer.GSS_BUFFER_T_val = (char *)token_buffer->value;
   1248      0   stevel 
   1249      0   stevel 	/* call the remote procedure */
   1250      0   stevel 
   1251      0   stevel 	bzero(&res, sizeof (res));
   1252      0   stevel 
   1253      0   stevel 	if (gss_process_context_token_1(&arg, &res, clnt) != RPC_SUCCESS) {
   1254      0   stevel 
   1255      0   stevel 	/*
   1256      0   stevel 	 * if the RPC call times out, null out all return arguments, set
   1257      0   stevel 	 * minor_status to its maximum value, and return GSS_S_FAILURE
   1258      0   stevel 	 */
   1259      0   stevel 
   1260      0   stevel 		if (minor_status != NULL)
   1261      0   stevel 			*minor_status = DEFAULT_MINOR_STAT;
   1262      0   stevel 		GSSLOG0(1, "kgss_process_context_token: RPC call times out\n");
   1263      0   stevel 		killgssd_handle(clnt);
   1264      0   stevel 		return (GSS_S_FAILURE);
   1265      0   stevel 	}
   1266      0   stevel 
   1267      0   stevel 	/* copy the rpc results into the return arguments */
   1268      0   stevel 
   1269      0   stevel 	if (minor_status != NULL)
   1270      0   stevel 		*minor_status = res.minor_status;
   1271      0   stevel 
   1272      0   stevel 	/* return with status returned in rpc call */
   1273      0   stevel 
   1274      0   stevel 	killgssd_handle(clnt);
   1275      0   stevel 	return (res.status);
   1276      0   stevel 
   1277      0   stevel }
   1278      0   stevel 
   1279      0   stevel /*ARGSUSED*/
   1280      0   stevel static OM_uint32
   1281      0   stevel kgss_delete_sec_context_wrapped(void *private,
   1282      0   stevel 			OM_uint32 *minor_status,
   1283      0   stevel 			gssd_ctx_id_t *context_handle,
   1284      0   stevel 			gss_buffer_t output_token,
   1285      0   stevel 			OM_uint32 gssd_context_verifier)
   1286      0   stevel 
   1287      0   stevel 
   1288      0   stevel {
   1289      0   stevel 	CLIENT *clnt;
   1290      0   stevel 
   1291      0   stevel 	gss_delete_sec_context_arg arg;
   1292      0   stevel 	gss_delete_sec_context_res res;
   1293      0   stevel 
   1294      0   stevel 
   1295      0   stevel 	/* get the client handle to GSSD */
   1296      0   stevel 
   1297      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
   1298      0   stevel 		GSSLOG(1,
   1299      0   stevel 		"kgss_delete_sec_context: can't connect to server on %s\n",
   1300      0   stevel 		server);
   1301      0   stevel 		return (GSS_S_FAILURE);
   1302      0   stevel 	}
   1303      0   stevel 
   1304      0   stevel 	/* copy the procedure arguments into the rpc arg parameter */
   1305      0   stevel 
   1306      0   stevel 	arg.context_handle.GSS_CTX_ID_T_len =
   1307      0   stevel 		*context_handle == (gssd_ctx_id_t)GSS_C_NO_CONTEXT ?
   1308      0   stevel 			0 : (uint_t)sizeof (gssd_ctx_id_t);
   1309      0   stevel 	arg.context_handle.GSS_CTX_ID_T_val =  (char *)context_handle;
   1310      0   stevel 
   1311      0   stevel 	arg.gssd_context_verifier = gssd_context_verifier;
   1312      0   stevel 
   1313      0   stevel 	/* call the remote procedure */
   1314      0   stevel 
   1315      0   stevel 	bzero((caddr_t)&res, sizeof (res));
   1316      0   stevel 	if (gss_delete_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
   1317      0   stevel 
   1318      0   stevel 	/*
   1319      0   stevel 	 * if the RPC call times out, null out all return arguments, set
   1320      0   stevel 	 * minor_status to its maximum value, and return GSS_S_FAILURE
   1321      0   stevel 	 */
   1322      0   stevel 
   1323      0   stevel 		if (minor_status != NULL)
   1324      0   stevel 			*minor_status = DEFAULT_MINOR_STAT;
   1325      0   stevel 		if (context_handle != NULL)
   1326      0   stevel 			*context_handle = NULL;
   1327      0   stevel 		if (output_token != NULL)
   1328      0   stevel 			output_token->length = 0;
   1329      0   stevel 
   1330      0   stevel 		killgssd_handle(clnt);
   1331      0   stevel 		GSSLOG0(1, "kgssd_delete_sec_context: RPC call times out\n");
   1332      0   stevel 		return (GSS_S_FAILURE);
   1333      0   stevel 	}
   1334      0   stevel 
   1335      0   stevel 	/* copy the rpc results into the return arguments */
   1336      0   stevel 
   1337      0   stevel 	if (minor_status != NULL)
   1338      0   stevel 		*minor_status = res.minor_status;
   1339      0   stevel 
   1340      0   stevel 	if (res.context_handle.GSS_CTX_ID_T_len == 0)
   1341      0   stevel 		*context_handle = NULL;
   1342      0   stevel 	else
   1343      0   stevel 		*context_handle =
   1344      0   stevel 		    *((gssd_ctx_id_t *)res.context_handle.GSS_CTX_ID_T_val);
   1345      0   stevel 
   1346      0   stevel 	if (output_token != NULL) {
   1347      0   stevel 		output_token->length = res.output_token.GSS_BUFFER_T_len;
   1348      0   stevel 		output_token->value = res.output_token.GSS_BUFFER_T_val;
   1349      0   stevel 		res.output_token.GSS_BUFFER_T_len = 0;
   1350      0   stevel 		res.output_token.GSS_BUFFER_T_val = NULL;
   1351      0   stevel 	}
   1352      0   stevel 
   1353      0   stevel 	/*
   1354      0   stevel 	 * free the memory allocated for the results and return with the status
   1355      0   stevel 	 * received in the rpc call
   1356      0   stevel 	 */
   1357      0   stevel 
   1358      0   stevel 	clnt_freeres(clnt, xdr_gss_delete_sec_context_res, (caddr_t)&res);
   1359      0   stevel 	killgssd_handle(clnt);
   1360      0   stevel 	return (res.status);
   1361      0   stevel 
   1362      0   stevel }
   1363      0   stevel 
   1364      0   stevel OM_uint32
   1365      0   stevel kgss_delete_sec_context(
   1366      0   stevel 		OM_uint32 *minor_status,
   1367      0   stevel 		gss_ctx_id_t *context_handle,
   1368      0   stevel 		gss_buffer_t output_token)
   1369      0   stevel {
   1370      0   stevel 	OM_uint32 err;
   1371      0   stevel 	struct kgss_ctx	*kctx;
   1372      0   stevel 
   1373      0   stevel 	if (*context_handle == GSS_C_NO_CONTEXT) {
   1374      0   stevel 		GSSLOG0(8, "kgss_delete_sec_context: Null context handle \n");
   1375      0   stevel 		return (GSS_S_COMPLETE);
   1376      0   stevel 	} else
   1377      0   stevel 		kctx = (struct kgss_ctx *)*context_handle;
   1378      0   stevel 
   1379      0   stevel 	if (kctx->ctx_imported == FALSE) {
   1380      0   stevel 		if (kctx->gssd_ctx == (gssd_ctx_id_t)GSS_C_NO_CONTEXT) {
   1381      0   stevel 			KGSS_FREE(kctx);
   1382      0   stevel 			*context_handle = GSS_C_NO_CONTEXT;
   1383      0   stevel 			return (GSS_S_COMPLETE);
   1384      0   stevel 		}
   1385      0   stevel 		err = kgss_delete_sec_context_wrapped(
   1386      0   stevel 				KCTX_TO_PRIVATE(*context_handle),
   1387      0   stevel 				minor_status,
   1388      0   stevel 				&kctx->gssd_ctx,
   1389      0   stevel 				output_token,
   1390      0   stevel 				kctx->gssd_ctx_verifier);
   1391      0   stevel 	} else {
   1392      0   stevel 		if (kctx->gssd_i_ctx == (gss_ctx_id_t)GSS_C_NO_CONTEXT) {
   1393      0   stevel 			KGSS_FREE(kctx);
   1394      0   stevel 			*context_handle = GSS_C_NO_CONTEXT;
   1395      0   stevel 			return (GSS_S_COMPLETE);
   1396      0   stevel 		}
   1397      0   stevel 		err = KGSS_DELETE_SEC_CONTEXT(minor_status, kctx,
   1398      0   stevel 				&kctx->gssd_i_ctx,  output_token);
   1399      0   stevel 	}
   1400      0   stevel 	KGSS_FREE(kctx);
   1401      0   stevel 	*context_handle = GSS_C_NO_CONTEXT;
   1402      0   stevel 	return (err);
   1403      0   stevel 
   1404      0   stevel }
   1405      0   stevel 
   1406      0   stevel 
   1407      0   stevel OM_uint32
   1408      0   stevel kgss_export_sec_context_wrapped(minor_status,
   1409      0   stevel 				context_handle,
   1410      0   stevel 				output_token,
   1411      0   stevel 				gssd_context_verifier)
   1412      0   stevel 	OM_uint32 *minor_status;
   1413      0   stevel 	gssd_ctx_id_t *context_handle;
   1414      0   stevel 	gss_buffer_t output_token;
   1415      0   stevel 	OM_uint32 gssd_context_verifier;
   1416      0   stevel {
   1417      0   stevel 	CLIENT *clnt;
   1418      0   stevel 	gss_export_sec_context_arg arg;
   1419      0   stevel 	gss_export_sec_context_res res;
   1420      0   stevel 
   1421      0   stevel 
   1422      0   stevel 	/* get the client handle to GSSD */
   1423      0   stevel 
   1424      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
   1425      0   stevel 		GSSLOG(1, "kgss_export_sec_context_wrapped :"
   1426      0   stevel 			" can't connect to server on %s\n", server);
   1427      0   stevel 		return (GSS_S_FAILURE);
   1428      0   stevel 	}
   1429      0   stevel 
   1430      0   stevel 	/* copy the procedure arguments into the rpc arg parameter */
   1431      0   stevel 
   1432      0   stevel 	arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
   1433      0   stevel 	arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle;
   1434      0   stevel 	arg.gssd_context_verifier = gssd_context_verifier;
   1435      0   stevel 
   1436      0   stevel 	/* call the remote procedure */
   1437      0   stevel 
   1438      0   stevel 	(void) memset(&res, 0, sizeof (res));
   1439      0   stevel 	if (gss_export_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
   1440      0   stevel 
   1441      0   stevel 	/*
   1442      0   stevel 	 * if the RPC call times out, null out all return arguments,
   1443      0   stevel 	 * set minor_status to its maximum value, and return
   1444      0   stevel 	 * GSS_S_FAILURE
   1445      0   stevel 	 */
   1446      0   stevel 
   1447      0   stevel 		if (minor_status != NULL)
   1448      0   stevel 			*minor_status = DEFAULT_MINOR_STAT;
   1449      0   stevel 		if (context_handle != NULL)
   1450      0   stevel 			*context_handle = NULL;
   1451      0   stevel 		if (output_token != NULL)
   1452      0   stevel 			output_token->length = 0;
   1453      0   stevel 		killgssd_handle(clnt);
   1454      0   stevel 		GSSLOG0(1,
   1455      0   stevel 		"kgss_export_sec_context_wrapped: RPC call times out\n");
   1456      0   stevel 		return (GSS_S_FAILURE);
   1457      0   stevel 	}
   1458      0   stevel 
   1459      0   stevel 	/* copy the rpc results into the return arguments */
   1460      0   stevel 
   1461      0   stevel 	if (minor_status != NULL)
   1462      0   stevel 		*minor_status = res.minor_status;
   1463      0   stevel 
   1464      0   stevel 	if (res.context_handle.GSS_CTX_ID_T_len == 0)
   1465      0   stevel 		*context_handle = NULL;
   1466      0   stevel 	else
   1467      0   stevel 		*context_handle =
   1468      0   stevel 		    *((gssd_ctx_id_t *)res.context_handle.GSS_CTX_ID_T_val);
   1469      0   stevel 
   1470      0   stevel 	if (output_token != NULL) {
   1471      0   stevel 		output_token->length = res.output_token.GSS_BUFFER_T_len;
   1472      0   stevel 		output_token->value =
   1473      0   stevel 			(void *)  MALLOC(output_token->length);
   1474      0   stevel 		(void) memcpy(output_token->value,
   1475      0   stevel 			res.output_token.GSS_BUFFER_T_val,
   1476      0   stevel 			output_token->length);
   1477      0   stevel 	}
   1478      0   stevel 
   1479      0   stevel 	/*
   1480      0   stevel 	 * free the memory allocated for the results and return with the status
   1481      0   stevel 	 * received in the rpc call
   1482      0   stevel 	 */
   1483      0   stevel 
   1484      0   stevel 	clnt_freeres(clnt, xdr_gss_export_sec_context_res, (caddr_t)&res);
   1485      0   stevel 	killgssd_handle(clnt);
   1486      0   stevel 	return (res.status);
   1487      0   stevel 
   1488      0   stevel }
   1489      0   stevel 
   1490      0   stevel OM_uint32
   1491      0   stevel kgss_export_sec_context(minor_status,
   1492      0   stevel 			context_handle,
   1493      0   stevel 			output_token)
   1494      0   stevel 	OM_uint32 *minor_status;
   1495      0   stevel 	gss_ctx_id_t context_handle;
   1496      0   stevel 	gss_buffer_t output_token;
   1497      0   stevel {
   1498      0   stevel 	struct kgss_ctx	*kctx;
   1499      0   stevel 
   1500      0   stevel 	if (context_handle == GSS_C_NO_CONTEXT)
   1501      0   stevel 		return (GSS_S_FAILURE);
   1502      0   stevel 	else
   1503      0   stevel 		kctx = (struct kgss_ctx *)context_handle;
   1504      0   stevel 
   1505      0   stevel 
   1506      0   stevel 
   1507      0   stevel 	/*
   1508      0   stevel 	 *  If there is a kernel module then import_sec context must be
   1509      0   stevel 	 *  supported and we make an upcall to export_sec_context.
   1510      0   stevel 	 *  If there is no kernel module then we return an error
   1511      0   stevel 	 */
   1512      0   stevel 
   1513      0   stevel 	*minor_status = 0;
   1514      0   stevel 
   1515      0   stevel 	if (kctx->mech->gss_import_sec_context) {
   1516      0   stevel 		GSSLOG0(8, "kgss_export_sec_context: Kernel mod available \n");
   1517      0   stevel 		return (kgss_export_sec_context_wrapped(minor_status,
   1518      0   stevel 						&kctx->gssd_ctx,
   1519      0   stevel 						output_token,
   1520      0   stevel 						kctx->gssd_ctx_verifier));
   1521      0   stevel 
   1522      0   stevel 	} else {
   1523      0   stevel 
   1524      0   stevel 		/*
   1525      0   stevel 		 * This is not the right error value; instead of
   1526      0   stevel 		 * inventing  new error we return GSS_S_NAME_NOT_MN
   1527      0   stevel 		 * This error is not returned by the export routine
   1528      0   stevel 		 */
   1529      0   stevel 
   1530      0   stevel 		GSSLOG0(8, "kgss_export_sec_context: Kernel mod "
   1531      0   stevel 			"unavailable \n");
   1532      0   stevel 		return (GSS_S_NAME_NOT_MN);
   1533      0   stevel 	}
   1534      0   stevel 
   1535      0   stevel }
   1536      0   stevel 
   1537      0   stevel OM_uint32
   1538      0   stevel kgss_import_sec_context(minor_status,
   1539      0   stevel 			interprocess_token,
   1540      0   stevel 			context_handle)
   1541      0   stevel 
   1542      0   stevel OM_uint32 *		minor_status;
   1543      0   stevel const gss_buffer_t	interprocess_token;
   1544      0   stevel gss_ctx_id_t 		context_handle;
   1545      0   stevel 
   1546      0   stevel {
   1547      0   stevel OM_uint32 status;
   1548      0   stevel struct kgss_ctx	*kctx;
   1549      0   stevel 
   1550      0   stevel size_t		length;
   1551      0   stevel char		*p;
   1552      0   stevel gss_buffer_desc token;
   1553      0   stevel gss_ctx_id_t	internal_ctx_id;
   1554      0   stevel 	kctx = (struct kgss_ctx *)context_handle;
   1555      0   stevel 
   1556      0   stevel 	if (kctx->gssd_ctx != (gssd_ctx_id_t)GSS_C_NO_CONTEXT) {
   1557      0   stevel 		return (GSS_S_FAILURE);
   1558      0   stevel 	}
   1559      0   stevel 
   1560      0   stevel 	if (!(KCTX_TO_MECH(context_handle)->gss_import_sec_context)) {
   1561      0   stevel 
   1562      0   stevel 	/*
   1563      0   stevel 	 *  This should never happen
   1564      0   stevel 	 *  If Kernel import sec context does not exist the export
   1565      0   stevel 	 *  sec context should have caught this and returned an error
   1566      0   stevel 	 *  and the caller should not have called this routine
   1567      0   stevel 	 */
   1568      0   stevel 		GSSLOG0(1, "import_sec_context  called improperly\n");
   1569      0   stevel 		return (GSS_S_FAILURE);
   1570      0   stevel 	}
   1571      0   stevel 	*minor_status = 0;
   1572      0   stevel 
   1573      0   stevel 	if (interprocess_token->length == 0 || interprocess_token->value == 0)
   1574      0   stevel 		return (GSS_S_DEFECTIVE_TOKEN);
   1575      0   stevel 
   1576      0   stevel 	status = GSS_S_FAILURE;
   1577      0   stevel 
   1578      0   stevel 	p = interprocess_token->value;
   1579      0   stevel 	length = *p++;
   1580      0   stevel 	length = (length << 8) + *p++;
   1581      0   stevel 	length = (length << 8) + *p++;
   1582      0   stevel 	length = (length << 8) + *p++;
   1583      0   stevel 
   1584      0   stevel 	p += length;
   1585      0   stevel 
   1586      0   stevel 	token.length = interprocess_token->length - 4 - length;
   1587      0   stevel 	token.value = p;
   1588      0   stevel 
   1589      0   stevel 	/*
   1590      0   stevel 	 * select the approprate underlying mechanism routine and
   1591      0   stevel 	 * call it.
   1592      0   stevel 	 */
   1593      0   stevel 
   1594      0   stevel 	status = KGSS_IMPORT_SEC_CONTEXT(minor_status, &token, kctx,
   1595      0   stevel 				&internal_ctx_id);
   1596      0   stevel 
   1597      0   stevel 	if (status == GSS_S_COMPLETE) {
   1598      0   stevel 		KCTX_TO_I_CTX(kctx) = internal_ctx_id;
   1599      0   stevel 		kctx->ctx_imported = TRUE;
   1600      0   stevel 		return (GSS_S_COMPLETE);
   1601      0   stevel 	} else
   1602      0   stevel 		return (status);
   1603      0   stevel }
   1604      0   stevel 
   1605      0   stevel /*ARGSUSED*/
   1606      0   stevel OM_uint32
   1607      0   stevel kgss_context_time(minor_status,
   1608      0   stevel 		context_handle,
   1609      0   stevel 		time_rec,
   1610      0   stevel 		uid)
   1611      0   stevel 	OM_uint32 *minor_status;
   1612      0   stevel 	const gss_ctx_id_t context_handle;
   1613      0   stevel 	OM_uint32 *time_rec;
   1614      0   stevel 	uid_t uid;
   1615      0   stevel {
   1616      0   stevel 	return (GSS_S_FAILURE);
   1617      0   stevel }
   1618      0   stevel 
   1619      0   stevel /*ARGSUSED*/
   1620      0   stevel static OM_uint32
   1621      0   stevel kgss_sign_wrapped(void *private,
   1622      0   stevel 	OM_uint32 *minor_status,
   1623      0   stevel 	const gss_ctx_id_t ctx_handle,
   1624      0   stevel 	int qop_req,
   1625      0   stevel 	const gss_buffer_t message_buffer,
   1626      0   stevel 	gss_buffer_t msg_token,
   1627      0   stevel 	OM_uint32 gssd_context_verifier)
   1628      0   stevel {
   1629      0   stevel 	CLIENT *clnt;
   1630      0   stevel 	gssd_ctx_id_t context_handle;
   1631      0   stevel 
   1632      0   stevel 	gss_sign_arg arg;
   1633      0   stevel 	gss_sign_res res;
   1634      0   stevel 	context_handle = (gssd_ctx_id_t)KCTX_TO_GSSD_CTX(ctx_handle);
   1635      0   stevel 	/* get the client handle to GSSD */
   1636      0   stevel 
   1637      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
   1638      0   stevel 		GSSLOG(1, "kgss_sign: can't connect to server on %s\n", server);
   1639      0   stevel 		return (GSS_S_FAILURE);
   1640      0   stevel 	}
   1641      0   stevel 
   1642      0   stevel 	/* copy the procedure arguments into the rpc arg parameter */
   1643      0   stevel 
   1644      0   stevel 	arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
   1645      0   stevel 	arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
   1646      0   stevel 
   1647      0   stevel 	arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
   1648      0   stevel 	arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
   1649      0   stevel 	arg.gssd_context_verifier = gssd_context_verifier;
   1650      0   stevel 
   1651      0   stevel 	arg.qop_req = qop_req;
   1652      0   stevel 
   1653      0   stevel 	arg.message_buffer.GSS_BUFFER_T_len = (uint_t)message_buffer->length;
   1654      0   stevel 	arg.message_buffer.GSS_BUFFER_T_val = (char *)message_buffer->value;
   1655      0   stevel 
   1656      0   stevel 	/* call the remote procedure */
   1657      0   stevel 
   1658      0   stevel 	bzero((caddr_t)&res, sizeof (res));
   1659      0   stevel 	if (gss_sign_1(&arg, &res, clnt) != RPC_SUCCESS) {
   1660      0   stevel 
   1661      0   stevel 	/*
   1662      0   stevel 	 * if the RPC call times out, null out all return arguments, set
   1663      0   stevel 	 * minor_status to its maximum value, and return GSS_S_FAILURE
   1664      0   stevel 	 */
   1665      0   stevel 
   1666      0   stevel 		if (minor_status != NULL)
   1667      0   stevel 			*minor_status = DEFAULT_MINOR_STAT;
   1668      0   stevel 		if (msg_token != NULL)
   1669      0   stevel 			msg_token->length = 0;
   1670      0   stevel 
   1671      0   stevel 		killgssd_handle(clnt);
   1672      0   stevel 		GSSLOG0(1, "kgss_sign: RPC call times out\n");
   1673      0   stevel 		return (GSS_S_FAILURE);
   1674      0   stevel 	}
   1675      0   stevel 
   1676      0   stevel 	/* copy the rpc results into the return arguments */
   1677      0   stevel 
   1678      0   stevel 	if (minor_status != NULL)
   1679      0   stevel 		*minor_status = res.minor_status;
   1680      0   stevel 
   1681      0   stevel 	if (msg_token != NULL) {
   1682      0   stevel 		msg_token->length = res.msg_token.GSS_BUFFER_T_len;
   1683      0   stevel 		msg_token->value = (void *) MALLOC(msg_token->length);
   1684      0   stevel 		(void) memcpy(msg_token->value, res.msg_token.GSS_BUFFER_T_val,
   1685      0   stevel 			msg_token->length);
   1686      0   stevel 	}
   1687      0   stevel 
   1688      0   stevel 	/*
   1689      0   stevel 	 * free the memory allocated for the results and return with the status
   1690      0   stevel 	 * received in the rpc call
   1691      0   stevel 	 */
   1692      0   stevel 
   1693      0   stevel 	clnt_freeres(clnt, xdr_gss_sign_res, (caddr_t)&res);
   1694      0   stevel 	killgssd_handle(clnt);
   1695      0   stevel 	return (res.status);
   1696      0   stevel 
   1697      0   stevel }
   1698      0   stevel 
   1699      0   stevel OM_uint32
   1700      0   stevel kgss_sign(
   1701      0   stevel 	OM_uint32 *minor_status,
   1702      0   stevel 	const gss_ctx_id_t context_handle,
   1703      0   stevel 	int qop_req,
   1704      0   stevel 	const gss_buffer_t message_buffer,
   1705      0   stevel 	gss_buffer_t msg_token)
   1706      0   stevel {
   1707      0   stevel 	if (context_handle == GSS_C_NO_CONTEXT)
   1708      0   stevel 		return (GSS_S_FAILURE);
   1709      0   stevel 	return (KGSS_SIGN(minor_status, context_handle, qop_req,
   1710      0   stevel 			message_buffer, msg_token));
   1711      0   stevel }
   1712      0   stevel 
   1713      0   stevel /*ARGSUSED*/
   1714      0   stevel static OM_uint32
   1715      0   stevel kgss_verify_wrapped(void *private,
   1716      0   stevel 	OM_uint32 *minor_status,
   1717      0   stevel 	const gss_ctx_id_t ctx_handle,
   1718      0   stevel 	const gss_buffer_t message_buffer,
   1719      0   stevel 	const gss_buffer_t token_buffer,
   1720      0   stevel 	int *qop_state,
   1721      0   stevel 	OM_uint32 gssd_context_verifier)
   1722      0   stevel {
   1723      0   stevel 	CLIENT *clnt;
   1724      0   stevel 
   1725      0   stevel 	gssd_ctx_id_t context_handle;
   1726      0   stevel 	gss_verify_arg arg;
   1727      0   stevel 	gss_verify_res res;
   1728      0   stevel 
   1729      0   stevel 	context_handle = (gssd_ctx_id_t)KCTX_TO_GSSD_CTX(ctx_handle);
   1730      0   stevel 
   1731      0   stevel 	/* get the client handle to GSSD */
   1732      0   stevel 
   1733      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
   1734      0   stevel 		GSSLOG(1, "kgss_verify: can't connect to server on %s\n",
   1735      0   stevel 			server);
   1736      0   stevel 		return (GSS_S_FAILURE);
   1737      0   stevel 	}
   1738      0   stevel 
   1739      0   stevel 	/* copy the procedure arguments into the rpc arg parameter */
   1740      0   stevel 
   1741      0   stevel 	arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gss_ctx_id_t);
   1742      0   stevel 	arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
   1743      0   stevel 
   1744      0   stevel 	arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
   1745      0   stevel 	arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
   1746      0   stevel 	arg.gssd_context_verifier = gssd_context_verifier;
   1747      0   stevel 
   1748      0   stevel 	arg.message_buffer.GSS_BUFFER_T_len = (uint_t)message_buffer->length;
   1749      0   stevel 	arg.message_buffer.GSS_BUFFER_T_val = (char *)message_buffer->value;
   1750      0   stevel 
   1751      0   stevel 	arg.token_buffer.GSS_BUFFER_T_len = (uint_t)token_buffer->length;
   1752      0   stevel 	arg.token_buffer.GSS_BUFFER_T_val = (char *)token_buffer->value;
   1753      0   stevel 
   1754      0   stevel 	/* call the remote procedure */
   1755      0   stevel 
   1756      0   stevel 	bzero((caddr_t)&res, sizeof (res));
   1757      0   stevel 	if (gss_verify_1(&arg, &res, clnt) != RPC_SUCCESS) {
   1758      0   stevel 
   1759      0   stevel 	/*
   1760      0   stevel 	 * if the RPC call times out, null out all return arguments, set
   1761      0   stevel 	 * minor_status to its maximum value, and return GSS_S_FAILURE
   1762      0   stevel 	 */
   1763      0   stevel 
   1764      0   stevel 		if (minor_status != NULL)
   1765      0   stevel 			*minor_status = DEFAULT_MINOR_STAT;
   1766      0   stevel 		if (qop_state != NULL)
   1767      0   stevel 			*qop_state = 0;
   1768      0   stevel 
   1769      0   stevel 		killgssd_handle(clnt);
   1770      0   stevel 		GSSLOG0(1, "kgss_verify: RPC call times out\n");
   1771      0   stevel 		return (GSS_S_FAILURE);
   1772      0   stevel 	}
   1773      0   stevel 
   1774      0   stevel 	/* copy the rpc results into the return arguments */
   1775      0   stevel 
   1776      0   stevel 	if (minor_status != NULL)
   1777      0   stevel 		*minor_status = res.minor_status;
   1778      0   stevel 
   1779      0   stevel 	if (qop_state != NULL)
   1780      0   stevel 		*qop_state = res.qop_state;
   1781      0   stevel 
   1782      0   stevel 	/* return with status returned in rpc call */
   1783      0   stevel 
   1784      0   stevel 	killgssd_handle(clnt);
   1785      0   stevel 	return (res.status);
   1786      0   stevel 
   1787      0   stevel }
   1788      0   stevel 
   1789      0   stevel OM_uint32
   1790      0   stevel kgss_verify(OM_uint32 *minor_status,
   1791      0   stevel 		const gss_ctx_id_t context_handle,
   1792      0   stevel 		const gss_buffer_t message_buffer,
   1793      0   stevel 		const gss_buffer_t token_buffer,
   1794      0   stevel 		int *qop_state)
   1795      0   stevel {
   1796      0   stevel 	if (context_handle == GSS_C_NO_CONTEXT)
   1797      0   stevel 		return (GSS_S_FAILURE);
   1798      0   stevel 	return (KGSS_VERIFY(minor_status, context_handle,
   1799      0   stevel 			    message_buffer,
   1800      0   stevel 			    token_buffer,
   1801      0   stevel 			    qop_state));
   1802      0   stevel }
   1803      0   stevel 
   1804      0   stevel /* EXPORT DELETE START */
   1805      0   stevel 
   1806      0   stevel /*ARGSUSED*/
   1807      0   stevel static OM_uint32
   1808      0   stevel kgss_seal_wrapped(void *private,
   1809      0   stevel 	OM_uint32 *minor_status,
   1810      0   stevel 	const gss_ctx_id_t ctx_handle,
   1811      0   stevel 	int conf_req_flag,
   1812      0   stevel 	int qop_req,
   1813      0   stevel 	const gss_buffer_t input_message_buffer,
   1814      0   stevel 	int *conf_state,
   1815      0   stevel 	gss_buffer_t output_message_buffer,
   1816      0   stevel 	OM_uint32 gssd_context_verifier)
   1817      0   stevel {
   1818      0   stevel 	CLIENT *clnt;
   1819      0   stevel 	gssd_ctx_id_t	context_handle;
   1820      0   stevel 
   1821      0   stevel 	gss_seal_arg arg;
   1822      0   stevel 	gss_seal_res res;
   1823      0   stevel 
   1824      0   stevel 	context_handle = (gssd_ctx_id_t)KCTX_TO_GSSD_CTX(ctx_handle);
   1825      0   stevel 
   1826      0   stevel 	/* get the client handle to GSSD */
   1827      0   stevel 
   1828      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
   1829      0   stevel 		GSSLOG(1, "kgss_seal: can't connect to server on %s\n", server);
   1830      0   stevel 		return (GSS_S_FAILURE);
   1831      0   stevel 	}
   1832      0   stevel 
   1833      0   stevel 	/* copy the procedure arguments into the rpc arg parameter */
   1834      0   stevel 
   1835      0   stevel 	arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gss_ctx_id_t);
   1836      0   stevel 	arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
   1837      0   stevel 
   1838      0   stevel 	arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (OM_uint32);
   1839      0   stevel 	arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
   1840      0   stevel 	arg.gssd_context_verifier = gssd_context_verifier;
   1841      0   stevel 
   1842      0   stevel 	arg.conf_req_flag = conf_req_flag;
   1843      0   stevel 
   1844      0   stevel 	arg.qop_req = qop_req;
   1845      0   stevel 
   1846      0   stevel 	arg.input_message_buffer.GSS_BUFFER_T_len =
   1847      0   stevel 					(uint_t)input_message_buffer->length;
   1848      0   stevel 
   1849      0   stevel 	arg.input_message_buffer.GSS_BUFFER_T_val =
   1850      0   stevel 					(char *)input_message_buffer->value;
   1851      0   stevel 
   1852      0   stevel 	/* call the remote procedure */
   1853      0   stevel 
   1854      0   stevel 	bzero((caddr_t)&res, sizeof (res));
   1855      0   stevel 	if (gss_seal_1(&arg, &res, clnt) != RPC_SUCCESS) {
   1856      0   stevel 
   1857      0   stevel 	/*
   1858      0   stevel 	 * if the RPC call times out, null out all return arguments, set
   1859      0   stevel 	 * minor_status to its maximum value, and return GSS_S_FAILURE
   1860      0   stevel 	 */
   1861      0   stevel 
   1862      0   stevel 		if (minor_status != NULL)
   1863      0   stevel 			*minor_status = DEFAULT_MINOR_STAT;
   1864      0   stevel 		if (conf_state != NULL)
   1865      0   stevel 			*conf_state = 0;
   1866      0   stevel 		if (output_message_buffer != NULL)
   1867      0   stevel 			output_message_buffer->length = 0;
   1868      0   stevel 
   1869      0   stevel 		killgssd_handle(clnt);
   1870      0   stevel 		GSSLOG0(1, "kgss_seal: RPC call times out\n");
   1871      0   stevel 		return (GSS_S_FAILURE);
   1872      0   stevel 	}
   1873      0   stevel 
   1874      0   stevel 	/* copy the rpc results into the return arguments */
   1875      0   stevel 
   1876      0   stevel 	if (minor_status != NULL)
   1877      0   stevel 		*minor_status = res.minor_status;
   1878      0   stevel 
   1879      0   stevel 	if (conf_state != NULL)
   1880      0   stevel 		*conf_state = res.conf_state;
   1881      0   stevel 
   1882      0   stevel 	if (output_message_buffer != NULL) {
   1883      0   stevel 		output_message_buffer->length =
   1884      0   stevel 				res.output_message_buffer.GSS_BUFFER_T_len;
   1885      0   stevel 
   1886      0   stevel 		output_message_buffer->value =
   1887      0   stevel 				(void *) MALLOC(output_message_buffer->length);
   1888      0   stevel 		(void) memcpy(output_message_buffer->value,
   1889      0   stevel 			res.output_message_buffer.GSS_BUFFER_T_val,
   1890      0   stevel 			output_message_buffer->length);
   1891      0   stevel 	}
   1892      0   stevel 
   1893      0   stevel 	/*
   1894      0   stevel 	 * free the memory allocated for the results and return with the status
   1895      0   stevel 	 * received in the rpc call
   1896      0   stevel 	 */
   1897      0   stevel 
   1898      0   stevel 	clnt_freeres(clnt, xdr_gss_seal_res, (caddr_t)&res);
   1899      0   stevel 	killgssd_handle(clnt);
   1900      0   stevel 	return (res.status);
   1901      0   stevel }
   1902      0   stevel 
   1903      0   stevel /*ARGSUSED*/
   1904      0   stevel OM_uint32
   1905      0   stevel kgss_seal(OM_uint32 *minor_status,
   1906      0   stevel 	const gss_ctx_id_t context_handle,
   1907      0   stevel 	int conf_req_flag,
   1908      0   stevel 	int qop_req,
   1909      0   stevel 	const gss_buffer_t input_message_buffer,
   1910      0   stevel 	int *conf_state,
   1911      0   stevel 	gss_buffer_t output_message_buffer)
   1912      0   stevel 
   1913      0   stevel {
   1914      0   stevel 	if (context_handle == GSS_C_NO_CONTEXT)
   1915      0   stevel 		return (GSS_S_FAILURE);
   1916      0   stevel 	return (KGSS_SEAL(minor_status, context_handle,
   1917      0   stevel 		conf_req_flag, qop_req,
   1918      0   stevel 		input_message_buffer, conf_state,
   1919      0   stevel 		output_message_buffer));
   1920      0   stevel }
   1921      0   stevel 
   1922      0   stevel /*ARGSUSED*/
   1923      0   stevel static OM_uint32
   1924      0   stevel kgss_unseal_wrapped(void *private,
   1925      0   stevel 	OM_uint32 *minor_status,
   1926      0   stevel 	const gss_ctx_id_t ctx_handle,
   1927      0   stevel 	const gss_buffer_t input_message_buffer,
   1928      0   stevel 	gss_buffer_t output_message_buffer,
   1929      0   stevel 	int *conf_state,
   1930      0   stevel 	int *qop_state,
   1931      0   stevel 	OM_uint32 gssd_context_verifier)
   1932      0   stevel {
   1933      0   stevel 	CLIENT *clnt;
   1934      0   stevel 
   1935      0   stevel 	gss_unseal_arg arg;
   1936      0   stevel 	gss_unseal_res res;
   1937      0   stevel 	gssd_ctx_id_t context_handle;
   1938      0   stevel 
   1939      0   stevel 	context_handle = (gssd_ctx_id_t)KCTX_TO_GSSD_CTX(ctx_handle);
   1940      0   stevel 
   1941      0   stevel 	/* get the client handle to GSSD */
   1942      0   stevel 
   1943      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
   1944      0   stevel 		GSSLOG(1, "kgss_unseal: can't connect to server on %s\n",
   1945      0   stevel 			server);
   1946      0   stevel 		return (GSS_S_FAILURE);
   1947      0   stevel 	}
   1948      0   stevel 
   1949      0   stevel 	/* copy the procedure arguments into the rpc arg parameter */
   1950      0   stevel 
   1951      0   stevel 	arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gss_ctx_id_t);
   1952      0   stevel 	arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
   1953      0   stevel 
   1954      0   stevel 	arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
   1955      0   stevel 	arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
   1956      0   stevel 	arg.gssd_context_verifier = gssd_context_verifier;
   1957      0   stevel 
   1958      0   stevel 	arg.input_message_buffer.GSS_BUFFER_T_len =
   1959      0   stevel 					(uint_t)input_message_buffer->length;
   1960      0   stevel 
   1961      0   stevel 	arg.input_message_buffer.GSS_BUFFER_T_val =
   1962      0   stevel 					(char *)input_message_buffer->value;
   1963      0   stevel 
   1964      0   stevel 	/* call the remote procedure */
   1965      0   stevel 
   1966      0   stevel 	bzero((caddr_t)&res, sizeof (res));
   1967      0   stevel 	if (gss_unseal_1(&arg, &res, clnt) != RPC_SUCCESS) {
   1968      0   stevel 
   1969      0   stevel 	/*
   1970      0   stevel 	 * if the RPC call times out, null out all return arguments, set
   1971      0   stevel 	 * minor_status to its maximum value, and return GSS_S_FAILURE
   1972      0   stevel 	 */
   1973      0   stevel 
   1974      0   stevel 		if (minor_status != NULL)
   1975      0   stevel 			*minor_status = DEFAULT_MINOR_STAT;
   1976      0   stevel 		if (output_message_buffer != NULL)
   1977      0   stevel 			output_message_buffer->length = 0;
   1978      0   stevel 		if (conf_state != NULL)
   1979      0   stevel 			*conf_state = 0;
   1980      0   stevel 		if (qop_state != NULL)
   1981      0   stevel 			*qop_state = 0;
   1982      0   stevel 
   1983      0   stevel 		killgssd_handle(clnt);
   1984      0   stevel 		GSSLOG0(1, "kgss_unseal: RPC call times out\n");
   1985      0   stevel 		return (GSS_S_FAILURE);
   1986      0   stevel 	}
   1987      0   stevel 
   1988      0   stevel 	/* copy the rpc results into the return arguments */
   1989      0   stevel 
   1990      0   stevel 	if (minor_status != NULL)
   1991      0   stevel 		*minor_status = res.minor_status;
   1992      0   stevel 
   1993      0   stevel 	if (output_message_buffer != NULL) {
   1994      0   stevel 		output_message_buffer->length =
   1995      0   stevel 				res.output_message_buffer.GSS_BUFFER_T_len;
   1996      0   stevel 
   1997      0   stevel 		output_message_buffer->value =
   1998      0   stevel 			(void *) MALLOC(output_message_buffer->length);
   1999      0   stevel 		(void) memcpy(output_message_buffer->value,
   2000      0   stevel 			res.output_message_buffer.GSS_BUFFER_T_val,
   2001      0   stevel 			output_message_buffer->length);
   2002      0   stevel 	}
   2003      0   stevel 
   2004      0   stevel 	if (conf_state != NULL)
   2005      0   stevel 		*conf_state = res.conf_state;
   2006      0   stevel 
   2007      0   stevel 	if (qop_state != NULL)
   2008      0   stevel 		*qop_state = res.qop_state;
   2009      0   stevel 
   2010      0   stevel 	/*
   2011      0   stevel 	 * free the memory allocated for the results and return with the
   2012      0   stevel 	 * status received in the rpc call
   2013      0   stevel 	 */
   2014      0   stevel 
   2015      0   stevel 	clnt_freeres(clnt, xdr_gss_unseal_res, (caddr_t)&res);
   2016      0   stevel 	killgssd_handle(clnt);
   2017      0   stevel 	return (res.status);
   2018      0   stevel }
   2019      0   stevel 
   2020      0   stevel OM_uint32
   2021      0   stevel kgss_unseal(OM_uint32 *minor_status,
   2022      0   stevel 	const gss_ctx_id_t context_handle,
   2023      0   stevel 	const gss_buffer_t input_message_buffer,
   2024      0   stevel 	const gss_buffer_t output_message_buffer,
   2025      0   stevel 	int *conf_state,
   2026      0   stevel 	int *qop_state)
   2027      0   stevel {
   2028      0   stevel 
   2029      0   stevel 	if (context_handle == GSS_C_NO_CONTEXT)
   2030      0   stevel 		return (GSS_S_FAILURE);
   2031      0   stevel 
   2032      0   stevel 	return (KGSS_UNSEAL(minor_status, context_handle, input_message_buffer,
   2033      0   stevel 		output_message_buffer, conf_state, qop_state));
   2034      0   stevel }
   2035      0   stevel 
   2036      0   stevel /* EXPORT DELETE END */
   2037      0   stevel 
   2038      0   stevel OM_uint32
   2039      0   stevel kgss_display_status(minor_status,
   2040      0   stevel 		status_value,
   2041      0   stevel 		status_type,
   2042      0   stevel 		mech_type,
   2043      0   stevel 		message_context,
   2044      0   stevel 		status_string,
   2045      0   stevel 		uid)
   2046      0   stevel 	OM_uint32 *minor_status;
   2047      0   stevel 	OM_uint32 status_value;
   2048      0   stevel 	int status_type;
   2049      0   stevel 	const gss_OID mech_type;
   2050      0   stevel 	int *message_context;
   2051      0   stevel 	gss_buffer_t status_string;
   2052      0   stevel 	uid_t uid;
   2053      0   stevel {
   2054      0   stevel 	CLIENT *clnt;
   2055      0   stevel 
   2056      0   stevel 	gss_display_status_arg arg;
   2057      0   stevel 	gss_display_status_res res;
   2058      0   stevel 
   2059      0   stevel 	/* get the client handle to GSSD */
   2060      0   stevel 
   2061      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
   2062      0   stevel 	GSSLOG(1, "kgss_display_status: can't connect to server on %s\n",
   2063      0   stevel 			server);
   2064      0   stevel 		return (GSS_S_FAILURE);
   2065      0   stevel 	}
   2066      0   stevel 
   2067      0   stevel 	/* copy the procedure arguments into the rpc arg parameter */
   2068      0   stevel 
   2069      0   stevel 	arg.uid = (OM_uint32) uid;
   2070      0   stevel 
   2071      0   stevel 	arg.status_value = status_value;
   2072      0   stevel 	arg.status_type = status_type;
   2073      0   stevel 
   2074      0   stevel 	arg.mech_type.GSS_OID_len = (uint_t)(mech_type != GSS_C_NULL_OID ?
   2075      0   stevel 						mech_type->length : 0);
   2076      0   stevel 	arg.mech_type.GSS_OID_val = (char *)(mech_type != GSS_C_NULL_OID ?
   2077      0   stevel 						mech_type->elements : 0);
   2078      0   stevel 
   2079      0   stevel 	arg.message_context = *message_context;
   2080      0   stevel 
   2081      0   stevel 	/* call the remote procedure */
   2082      0   stevel 
   2083      0   stevel 	if (message_context != NULL)
   2084      0   stevel 		*message_context = 0;
   2085      0   stevel 	if (status_string != NULL) {
   2086      0   stevel 		status_string->length = 0;
   2087      0   stevel 		status_string->value = NULL;
   2088      0   stevel 	}
   2089      0   stevel 
   2090      0   stevel 	bzero((caddr_t)&res, sizeof (res));
   2091      0   stevel 	if (gss_display_status_1(&arg, &res, clnt) != RPC_SUCCESS) {
   2092      0   stevel 
   2093      0   stevel 	/*
   2094      0   stevel 	 * if the RPC call times out, null out all return arguments, set
   2095      0   stevel 	 * minor_status to its maximum value, and return GSS_S_FAILURE
   2096      0   stevel 	 */
   2097      0   stevel 
   2098      0   stevel 		if (minor_status != NULL)
   2099      0   stevel 			*minor_status = DEFAULT_MINOR_STAT;
   2100      0   stevel 
   2101      0   stevel 		killgssd_handle(clnt);
   2102      0   stevel 		GSSLOG0(1, "kgss_display_status: RPC call time out\n");
   2103      0   stevel 		return (GSS_S_FAILURE);
   2104      0   stevel 	}
   2105      0   stevel 
   2106      0   stevel 
   2107      0   stevel 	/* now process the results and pass them back to the caller */
   2108      0   stevel 
   2109      0   stevel 	if (res.status == GSS_S_COMPLETE) {
   2110      0   stevel 		if (minor_status != NULL)
   2111      0   stevel 			*minor_status = res.minor_status;
   2112      0   stevel 		if (message_context != NULL)
   2113      0   stevel 			*message_context = res.message_context;
   2114      0   stevel 		if (status_string != NULL) {
   2115      0   stevel 			status_string->length =
   2116      0   stevel 				(size_t)res.status_string.GSS_BUFFER_T_len;
   2117      0   stevel 			status_string->value =
   2118      0   stevel 				(void *) MALLOC(status_string->length);
   2119      0   stevel 			(void) memcpy(status_string->value,
   2120      0   stevel 				res.status_string.GSS_BUFFER_T_val,
   2121      0   stevel 				status_string->length);
   2122      0   stevel 		}
   2123      0   stevel 	}
   2124      0   stevel 
   2125      0   stevel 	clnt_freeres(clnt, xdr_gss_display_status_res, (caddr_t)&res);
   2126      0   stevel 	killgssd_handle(clnt);
   2127      0   stevel 	return (res.status);
   2128      0   stevel }
   2129      0   stevel 
   2130      0   stevel /*ARGSUSED*/
   2131      0   stevel OM_uint32
   2132      0   stevel kgss_indicate_mechs(minor_status,
   2133      0   stevel 			mech_set,
   2134      0   stevel 			uid)
   2135      0   stevel 	OM_uint32 *minor_status;
   2136      0   stevel 	gss_OID_set *mech_set;
   2137      0   stevel 	uid_t uid;
   2138      0   stevel {
   2139      0   stevel 	CLIENT *clnt;
   2140      0   stevel 	void *arg;
   2141      0   stevel 	gss_indicate_mechs_res res;
   2142      0   stevel 	int i;
   2143      0   stevel 
   2144      0   stevel 	/* get the client handle to GSSD */
   2145      0   stevel 
   2146      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
   2147      0   stevel 	GSSLOG(1, "kgss_indicate_mechs: can't connect to server on %s\n",
   2148      0   stevel 			server);
   2149      0   stevel 		return (GSS_S_FAILURE);
   2150      0   stevel 	}
   2151      0   stevel 
   2152      0   stevel 	bzero((caddr_t)&res, sizeof (res));
   2153      0   stevel 	if (gss_indicate_mechs_1(&arg, &res, clnt) != RPC_SUCCESS) {
   2154      0   stevel 
   2155      0   stevel 	/*
   2156      0   stevel 	 * if the RPC call times out, null out all return arguments, set
   2157      0   stevel 	 * minor_status to its maximum value, and return GSS_S_FAILURE
   2158      0   stevel 	 */
   2159      0   stevel 
   2160      0   stevel 		if (minor_status != NULL)
   2161      0   stevel 			*minor_status = DEFAULT_MINOR_STAT;
   2162      0   stevel 		if (mech_set != NULL)
   2163      0   stevel 			*mech_set = NULL;
   2164      0   stevel 
   2165      0   stevel 		killgssd_handle(clnt);
   2166      0   stevel 		GSSLOG0(1, "kgss_indicate_mechs: RPC call times out\n");
   2167      0   stevel 		return (GSS_S_FAILURE);
   2168      0   stevel 	}
   2169      0   stevel 
   2170      0   stevel 	/* copy the rpc results into the return arguments */
   2171      0   stevel 
   2172      0   stevel 	if (minor_status != NULL)
   2173      0   stevel 		*minor_status = res.minor_status;
   2174      0   stevel 
   2175      0   stevel 	if (mech_set != NULL) {
   2176      0   stevel 		*mech_set = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
   2177      0   stevel 		(*mech_set)->count = res.mech_set.GSS_OID_SET_len;
   2178      0   stevel 		(*mech_set)->elements = (void *)
   2179      0   stevel 			MALLOC ((*mech_set)->count * sizeof (gss_OID_desc));
   2180      0   stevel 		for (i = 0; i < (*mech_set)->count; i++) {
   2181      0   stevel 			(*mech_set)->elements[i].length =
   2182      0   stevel 				res.mech_set.GSS_OID_SET_val[i].GSS_OID_len;
   2183      0   stevel 			(*mech_set)->elements[i].elements = (void *)
   2184      0   stevel 				MALLOC ((*mech_set)->elements[i].length);
   2185      0   stevel 			(void) memcpy((*mech_set)->elements[i].elements,
   2186      0   stevel 				res.mech_set.GSS_OID_SET_val[i].GSS_OID_val,
   2187      0   stevel 				(*mech_set)->elements[i].length);
   2188      0   stevel 		}
   2189      0   stevel 	}
   2190      0   stevel 
   2191      0   stevel 	/*
   2192      0   stevel 	 * free the memory allocated for the results and return with the status
   2193      0   stevel 	 * received in the rpc call
   2194      0   stevel 	 */
   2195      0   stevel 
   2196      0   stevel 	clnt_freeres(clnt, xdr_gss_indicate_mechs_res, (caddr_t)&res);
   2197      0   stevel 	killgssd_handle(clnt);
   2198      0   stevel 	return (res.status);
   2199      0   stevel }
   2200      0   stevel 
   2201      0   stevel 
   2202      0   stevel OM_uint32
   2203      0   stevel kgss_inquire_cred_wrapped(minor_status,
   2204      0   stevel 		cred_handle,
   2205      0   stevel 		gssd_cred_verifier,
   2206      0   stevel 		name,
   2207      0   stevel 		lifetime,
   2208      0   stevel 		cred_usage,
   2209      0   stevel 		mechanisms,
   2210      0   stevel 		uid)
   2211      0   stevel 	OM_uint32 *minor_status;
   2212      0   stevel 	const gssd_cred_id_t cred_handle;
   2213      0   stevel 	OM_uint32 gssd_cred_verifier;
   2214      0   stevel 	gss_name_t *name;
   2215      0   stevel 	OM_uint32 *lifetime;
   2216      0   stevel 	int *cred_usage;
   2217      0   stevel 	gss_OID_set *mechanisms;
   2218      0   stevel 	uid_t uid;
   2219      0   stevel {
   2220      0   stevel 	CLIENT *clnt;
   2221      0   stevel 
   2222      0   stevel 	OM_uint32 	minor_status_temp;
   2223      0   stevel 	gss_buffer_desc	external_name;
   2224      0   stevel 	gss_OID_desc	name_type;
   2225      0   stevel 	int		i;
   2226      0   stevel 
   2227      0   stevel 	gss_inquire_cred_arg arg;
   2228      0   stevel 	gss_inquire_cred_res res;
   2229      0   stevel 
   2230      0   stevel 	/*
   2231      0   stevel 	 * NULL the params here once
   2232      0   stevel 	 * If there are errors then we won't
   2233      0   stevel 	 * have to do it for every error
   2234      0   stevel 	 * case
   2235      0   stevel 	 */
   2236      0   stevel 	if (minor_status != NULL)
   2237      0   stevel 		*minor_status = DEFAULT_MINOR_STAT;
   2238      0   stevel 	if (name != NULL)
   2239      0   stevel 		*name = NULL;
   2240      0   stevel 	if (lifetime != NULL)
   2241      0   stevel 		*lifetime = 0;
   2242      0   stevel 	if (cred_usage != NULL)
   2243      0   stevel 		*cred_usage = 0;
   2244      0   stevel 	if (mechanisms != NULL)
   2245      0   stevel 		*mechanisms = NULL;
   2246      0   stevel 
   2247      0   stevel 	/* get the client handle to GSSD */
   2248      0   stevel 
   2249      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
   2250      0   stevel 		GSSLOG(1, "kgss_inquire_cred: can't connect to server on %s\n",
   2251      0   stevel 			server);
   2252      0   stevel 		return (GSS_S_FAILURE);
   2253      0   stevel 	}
   2254      0   stevel 
   2255      0   stevel 
   2256      0   stevel 	/* copy the procedure arguments into the rpc arg parameter */
   2257      0   stevel 
   2258      0   stevel 	arg.uid = (OM_uint32) uid;
   2259      0   stevel 
   2260      0   stevel 	arg.cred_handle.GSS_CRED_ID_T_len =
   2261      0   stevel 			cred_handle == (gssd_cred_id_t)GSS_C_NO_CREDENTIAL ?
   2262      0   stevel 			0 : (uint_t)sizeof (gssd_cred_id_t);
   2263      0   stevel 	arg.cred_handle.GSS_CRED_ID_T_val = (char *)&cred_handle;
   2264      0   stevel 	arg.gssd_cred_verifier = gssd_cred_verifier;
   2265      0   stevel 
   2266      0   stevel 	/* call the remote procedure */
   2267      0   stevel 
   2268      0   stevel 	bzero((caddr_t)&res, sizeof (res));
   2269      0   stevel 	if (gss_inquire_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
   2270      0   stevel 
   2271      0   stevel 		/*
   2272      0   stevel 		 * if the RPC call times out
   2273      0   stevel 		 * kill the handle and return GSS_S_FAILURE
   2274      0   stevel 		 * the parameters have been set to NULL already
   2275      0   stevel 		 */
   2276      0   stevel 
   2277      0   stevel 		killgssd_handle(clnt);
   2278      0   stevel 		GSSLOG0(1, "kgss_inquire_cred: RPC call times out\n");
   2279      0   stevel 		return (GSS_S_FAILURE);
   2280      0   stevel 	}
   2281      0   stevel 
   2282      0   stevel 	/* copy the rpc results into the return arguments */
   2283      0   stevel 
   2284      0   stevel 	if (minor_status != NULL)
   2285      0   stevel 		*minor_status = res.minor_status;
   2286      0   stevel 
   2287      0   stevel 	/* convert name from external to internal format */
   2288      0   stevel 
   2289      0   stevel 	if (name != NULL) {
   2290      0   stevel 		external_name.length = res.name.GSS_BUFFER_T_len;
   2291      0   stevel 		external_name.value = res.name.GSS_BUFFER_T_val;
   2292      0   stevel 
   2293      0   stevel 		/*
   2294      0   stevel 		 * we can pass a pointer to res structure
   2295      0   stevel 		 * since gss_import_name treats the name_type
   2296      0   stevel 		 * parameter as read only and performs a copy
   2297      0   stevel 		 */
   2298      0   stevel 
   2299      0   stevel 		name_type.length = res.name_type.GSS_OID_len;
   2300      0   stevel 		name_type.elements = (void *)res.name_type.GSS_OID_val;
   2301      0   stevel 
   2302      0   stevel 		if (gss_import_name(&minor_status_temp, &external_name,
   2303      0   stevel 			&name_type, name) != GSS_S_COMPLETE) {
   2304      0   stevel 
   2305      0   stevel 			*minor_status = (OM_uint32) minor_status_temp;
   2306      0   stevel 			clnt_freeres(clnt, xdr_gss_inquire_cred_res,
   2307      0   stevel 							(caddr_t)&res);
   2308      0   stevel 			killgssd_handle(clnt);
   2309      0   stevel 			GSSLOG0(1, "kgss_inquire_cred: import name fails\n");
   2310      0   stevel 			return ((OM_uint32) GSS_S_FAILURE);
   2311      0   stevel 		}
   2312      0   stevel 	}
   2313      0   stevel 
   2314      0   stevel 	if (lifetime != NULL)
   2315      0   stevel 		*lifetime = res.lifetime;
   2316      0   stevel 
   2317      0   stevel 	if (cred_usage != NULL)
   2318      0   stevel 		*cred_usage = res.cred_usage;
   2319      0   stevel 
   2320      0   stevel 	if (res.status == GSS_S_COMPLETE &&
   2321      0   stevel 		res.mechanisms.GSS_OID_SET_len != 0 &&
   2322      0   stevel 		mechanisms != NULL) {
   2323      0   stevel 		*mechanisms = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
   2324      0   stevel 		(*mechanisms)->count =
   2325      0   stevel 			(int)res.mechanisms.GSS_OID_SET_len;
   2326      0   stevel 		(*mechanisms)->elements = (gss_OID)
   2327      0   stevel 			MALLOC(sizeof (gss_OID_desc) * (*mechanisms)->count);
   2328      0   stevel 
   2329      0   stevel 		for (i = 0; i < (*mechanisms)->count; i++) {
   2330      0   stevel 		    (*mechanisms)->elements[i].length = (OM_uint32)
   2331      0   stevel 			res.mechanisms.GSS_OID_SET_val[i].GSS_OID_len;
   2332      0   stevel 		    (*mechanisms)->elements[i].elements =
   2333      0   stevel 			(void *) MALLOC((*mechanisms)->elements[i].length);
   2334      0   stevel 		    (void) memcpy((*mechanisms)->elements[i].elements,
   2335      0   stevel 			res.mechanisms.GSS_OID_SET_val[i].GSS_OID_val,
   2336      0   stevel 			(*mechanisms)->elements[i].length);
   2337      0   stevel 		}
   2338      0   stevel 	} else {
   2339      0   stevel 		if (res.status == GSS_S_COMPLETE &&
   2340      0   stevel 			mechanisms != NULL)
   2341      0   stevel 			(*mechanisms) = NULL;
   2342      0   stevel 	}
   2343      0   stevel 	/*
   2344      0   stevel 	 * free the memory allocated for the results and return with the status
   2345      0   stevel 	 * received in the rpc call
   2346      0   stevel 	 */
   2347      0   stevel 
   2348      0   stevel 	clnt_freeres(clnt, xdr_gss_inquire_cred_res, (caddr_t)&res);
   2349      0   stevel 	killgssd_handle(clnt);
   2350      0   stevel 	return (res.status);
   2351      0   stevel 
   2352      0   stevel }
   2353      0   stevel 
   2354      0   stevel OM_uint32
   2355      0   stevel kgss_inquire_cred(minor_status,
   2356      0   stevel 			cred_handle,
   2357      0   stevel 			name,
   2358      0   stevel 			lifetime,
   2359      0   stevel 			cred_usage,
   2360      0   stevel 			mechanisms,
   2361      0   stevel 			uid)
   2362      0   stevel 	OM_uint32 *minor_status;
   2363      0   stevel 	const gss_cred_id_t cred_handle;
   2364      0   stevel 	gss_name_t *name;
   2365      0   stevel 	OM_uint32 *lifetime;
   2366      0   stevel 	int *cred_usage;
   2367      0   stevel 	gss_OID_set * mechanisms;
   2368      0   stevel 	uid_t uid;
   2369      0   stevel {
   2370      0   stevel 
   2371      0   stevel 	OM_uint32 gssd_cred_verifier;
   2372      0   stevel 	OM_uint32 gssd_cred_handle;
   2373      0   stevel 
   2374      0   stevel 	gssd_cred_verifier = KCRED_TO_CREDV(cred_handle);
   2375      0   stevel 	gssd_cred_handle = KCRED_TO_CRED(cred_handle);
   2376      0   stevel 
   2377      0   stevel 	return (kgss_inquire_cred_wrapped(minor_status,
   2378      0   stevel 			gssd_cred_handle, gssd_cred_verifier,
   2379      0   stevel 			name, lifetime, cred_usage, mechanisms, uid));
   2380      0   stevel }
   2381      0   stevel 
   2382      0   stevel OM_uint32
   2383      0   stevel kgss_inquire_cred_by_mech_wrapped(minor_status,
   2384      0   stevel 		cred_handle,
   2385      0   stevel 		gssd_cred_verifier,
   2386      0   stevel 		mech_type,
   2387      0   stevel 		uid)
   2388      0   stevel 	OM_uint32 *minor_status;
   2389      0   stevel 	gssd_cred_id_t cred_handle;
   2390      0   stevel 	OM_uint32 gssd_cred_verifier;
   2391      0   stevel 	gss_OID mech_type;
   2392      0   stevel 	uid_t uid;
   2393      0   stevel {
   2394      0   stevel 	CLIENT *clnt;
   2395      0   stevel 
   2396      0   stevel 	gss_inquire_cred_by_mech_arg arg;
   2397      0   stevel 	gss_inquire_cred_by_mech_res res;
   2398      0   stevel 
   2399      0   stevel 	/* get the client handle to GSSD */
   2400      0   stevel 
   2401      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
   2402      0   stevel 		GSSLOG(1, "kgss_inquire_cred: can't connect to server on %s\n",
   2403      0   stevel 			server);
   2404      0   stevel 		return (GSS_S_FAILURE);
   2405      0   stevel 	}
   2406      0   stevel 
   2407      0   stevel 
   2408      0   stevel 	/* copy the procedure arguments into the rpc arg parameter */
   2409      0   stevel 
   2410      0   stevel 	arg.uid = (OM_uint32) uid;
   2411      0   stevel 
   2412      0   stevel 	arg.cred_handle.GSS_CRED_ID_T_len =
   2413      0   stevel 			cred_handle == (gssd_cred_id_t)GSS_C_NO_CREDENTIAL ?
   2414      0   stevel 			0 : (uint_t)sizeof (gssd_cred_id_t);
   2415      0   stevel 	arg.cred_handle.GSS_CRED_ID_T_val = (char *)&cred_handle;
   2416      0   stevel 	arg.gssd_cred_verifier = gssd_cred_verifier;
   2417      0   stevel 
   2418      0   stevel 	arg.mech_type.GSS_OID_len =
   2419      0   stevel 		(uint_t)(mech_type != GSS_C_NULL_OID ?
   2420      0   stevel 		mech_type->length : 0);
   2421      0   stevel 	arg.mech_type.GSS_OID_val =
   2422      0   stevel 		(char *)(mech_type != GSS_C_NULL_OID ?
   2423      0   stevel 		mech_type->elements : 0);
   2424      0   stevel 	/* call the remote procedure */
   2425      0   stevel 
   2426      0   stevel 	bzero((caddr_t)&res, sizeof (res));
   2427      0   stevel 	if (gss_inquire_cred_by_mech_1(&arg, &res, clnt) != RPC_SUCCESS) {
   2428      0   stevel 
   2429      0   stevel 	/*
   2430      0   stevel 	 * if the RPC call times out, null out all return arguments, set
   2431      0   stevel 	 * minor_status to its maximum value, and return GSS_S_FAILURE
   2432      0   stevel 	 */
   2433      0   stevel 
   2434      0   stevel 		if (minor_status != NULL)
   2435      0   stevel 			*minor_status = DEFAULT_MINOR_STAT;
   2436      0   stevel 		killgssd_handle(clnt);
   2437      0   stevel 		GSSLOG0(1, "kgss_inquire_cred: RPC call times out\n");
   2438      0   stevel 		return (GSS_S_FAILURE);
   2439      0   stevel 	}
   2440      0   stevel 
   2441      0   stevel 	/* copy the rpc results into the return arguments */
   2442      0   stevel 
   2443      0   stevel 	if (minor_status != NULL)
   2444      0   stevel 		*minor_status = res.minor_status;
   2445      0   stevel 
   2446      0   stevel 	clnt_freeres(clnt, xdr_gss_inquire_cred_by_mech_res, (caddr_t)&res);
   2447      0   stevel 	killgssd_handle(clnt);
   2448      0   stevel 	return (res.status);
   2449      0   stevel 
   2450      0   stevel }
   2451      0   stevel 
   2452      0   stevel OM_uint32
   2453      0   stevel kgss_inquire_cred_by_mech(minor_status,
   2454      0   stevel 			cred_handle,
   2455      0   stevel 			mech_type,
   2456      0   stevel 			uid)
   2457      0   stevel 	OM_uint32 *minor_status;
   2458      0   stevel 	gss_cred_id_t cred_handle;
   2459      0   stevel 	gss_OID mech_type;
   2460      0   stevel 	uid_t uid;
   2461      0   stevel {
   2462      0   stevel 
   2463      0   stevel 	OM_uint32 gssd_cred_verifier;
   2464      0   stevel 	OM_uint32 gssd_cred_handle;
   2465      0   stevel 
   2466      0   stevel 	gssd_cred_verifier = KCRED_TO_CREDV(cred_handle);
   2467      0   stevel 	gssd_cred_handle = KCRED_TO_CRED(cred_handle);
   2468      0   stevel 
   2469      0   stevel 	return (kgss_inquire_cred_by_mech_wrapped(minor_status,
   2470      0   stevel 			gssd_cred_handle, gssd_cred_verifier,
   2471      0   stevel 			mech_type, uid));
   2472      0   stevel }
   2473      0   stevel 
   2474      0   stevel OM_uint32
   2475      0   stevel kgsscred_expname_to_unix_cred(expName, uidOut, gidOut, gids, gidsLen, uid)
   2476      0   stevel 	const gss_buffer_t expName;
   2477      0   stevel 	uid_t *uidOut;
   2478      0   stevel 	gid_t *gidOut;
   2479      0   stevel 	gid_t *gids[];
   2480      0   stevel 	int *gidsLen;
   2481      0   stevel 	uid_t uid;
   2482      0   stevel {
   2483      0   stevel 	CLIENT *clnt;
   2484      0   stevel 	gsscred_expname_to_unix_cred_arg args;
   2485      0   stevel 	gsscred_expname_to_unix_cred_res res;
   2486      0   stevel 
   2487      0   stevel 	/* check input/output parameters */
   2488      0   stevel 	if (expName == NULL || expName->value == NULL)
   2489      0   stevel 		return (GSS_S_CALL_INACCESSIBLE_READ);
   2490      0   stevel 
   2491      0   stevel 	if (uidOut == NULL)
   2492      0   stevel 		return (GSS_S_CALL_INACCESSIBLE_WRITE);
   2493      0   stevel 
   2494      0   stevel 	/* NULL out output parameters */
   2495      0   stevel 	*uidOut = UID_NOBODY;
   2496      0   stevel 	if (gidsLen)
   2497      0   stevel 		*gidsLen = 0;
   2498      0   stevel 
   2499      0   stevel 	if (gids)
   2500      0   stevel 		*gids = NULL;
   2501      0   stevel 
   2502      0   stevel 	/* get the client handle to gssd */
   2503      0   stevel 	if ((clnt = getgssd_handle()) == NULL)
   2504      0   stevel 	{
   2505      0   stevel 		GSSLOG(1, "kgsscred_expname_to_unix_cred:"
   2506      0   stevel 			" can't connect to server on %s\n", server);
   2507      0   stevel 		return (GSS_S_FAILURE);
   2508      0   stevel 	}
   2509      0   stevel 
   2510      0   stevel 	/* copy the procedure arguments */
   2511      0   stevel 	args.uid = uid;
   2512      0   stevel 	args.expname.GSS_BUFFER_T_val = expName->value;
   2513      0   stevel 	args.expname.GSS_BUFFER_T_len = expName->length;
   2514      0   stevel 
   2515      0   stevel 	/* null out the return buffer and call the remote proc */
   2516      0   stevel 	bzero(&res, sizeof (res));
   2517      0   stevel 
   2518      0   stevel 	if (gsscred_expname_to_unix_cred_1(&args, &res, clnt) != RPC_SUCCESS)
   2519      0   stevel 	{
   2520      0   stevel 		killgssd_handle(clnt);
   2521      0   stevel 		GSSLOG0(1,
   2522      0   stevel 			"kgsscred_expname_to_unix_cred: RPC call times out\n");
   2523      0   stevel 		return (GSS_S_FAILURE);
   2524      0   stevel 	}
   2525      0   stevel 
   2526      0   stevel 	/* copy the results into the result parameters */
   2527      0   stevel 	if (res.major == GSS_S_COMPLETE)
   2528      0   stevel 	{
   2529      0   stevel 		*uidOut = res.uid;
   2530      0   stevel 		if (gidOut)
   2531      0   stevel 			*gidOut = res.gid;
   2532      0   stevel 		if (gids && gidsLen)
   2533      0   stevel 		{
   2534      0   stevel 			*gids = res.gids.GSSCRED_GIDS_val;
   2535      0   stevel 			*gidsLen = res.gids.GSSCRED_GIDS_len;
   2536      0   stevel 			res.gids.GSSCRED_GIDS_val = NULL;
   2537      0   stevel 			res.gids.GSSCRED_GIDS_len = 0;
   2538      0   stevel 		}
   2539      0   stevel 	}
   2540      0   stevel 
   2541      0   stevel 	/* free RPC results */
   2542      0   stevel 	clnt_freeres(clnt, xdr_gsscred_expname_to_unix_cred_res, (caddr_t)&res);
   2543      0   stevel 	killgssd_handle(clnt);
   2544      0   stevel 
   2545      0   stevel 	return (res.major);
   2546      0   stevel } /* kgsscred_expname_to_unix_cred */
   2547      0   stevel 
   2548      0   stevel OM_uint32
   2549      0   stevel kgsscred_name_to_unix_cred(intName, mechType, uidOut, gidOut, gids,
   2550      0   stevel 				gidsLen, uid)
   2551      0   stevel 	const gss_name_t intName;
   2552      0   stevel 	const gss_OID mechType;
   2553      0   stevel 	uid_t *uidOut;
   2554      0   stevel 	gid_t *gidOut;
   2555      0   stevel 	gid_t *gids[];
   2556      0   stevel 	int *gidsLen;
   2557      0   stevel 	uid_t uid;
   2558      0   stevel {
   2559      0   stevel 	CLIENT *clnt;
   2560      0   stevel 	gsscred_name_to_unix_cred_arg args;
   2561      0   stevel 	gsscred_name_to_unix_cred_res res;
   2562      0   stevel 	OM_uint32 major, minor;
   2563      0   stevel 	gss_OID nameOid;
   2564      0   stevel 	gss_buffer_desc flatName = GSS_C_EMPTY_BUFFER;
   2565      0   stevel 
   2566      0   stevel 	/* check the input/output parameters */
   2567      0   stevel 	if (intName == NULL || mechType == NULL)
   2568      0   stevel 		return (GSS_S_CALL_INACCESSIBLE_READ);
   2569      0   stevel 
   2570      0   stevel 	if (uidOut == NULL)
   2571      0   stevel 		return (GSS_S_CALL_INACCESSIBLE_WRITE);
   2572      0   stevel 
   2573      0   stevel 	/* NULL out the output parameters */
   2574      0   stevel 	*uidOut = UID_NOBODY;
   2575      0   stevel 	if (gids)
   2576      0   stevel 		*gids = NULL;
   2577      0   stevel 
   2578      0   stevel 	if (gidsLen)
   2579      0   stevel 		*gidsLen = 0;
   2580      0   stevel 
   2581      0   stevel 	/* get the client handle to gssd */
   2582      0   stevel 	if ((clnt = getgssd_handle()) == NULL)
   2583      0   stevel 	{
   2584      0   stevel 		GSSLOG(1,
   2585      0   stevel 		"kgsscred_name_to_unix_cred: can't connect to server %s\n",
   2586      0   stevel 				server);
   2587      0   stevel 		return (GSS_S_FAILURE);
   2588      0   stevel 	}
   2589      0   stevel 
   2590      0   stevel 	/* convert the name to flat representation */
   2591      0   stevel 	if ((major = gss_display_name(&minor, intName, &flatName, &nameOid))
   2592      0   stevel 			!= GSS_S_COMPLETE)
   2593      0   stevel 	{
   2594      0   stevel 		killgssd_handle(clnt);
   2595      0   stevel 		GSSLOG0(1, "kgsscred_name_to_unix_cred: display name failed\n");
   2596      0   stevel 		return (major);
   2597      0   stevel 	}
   2598      0   stevel 
   2599      0   stevel 	/* set the rpc parameters */
   2600      0   stevel 	args.uid = uid;
   2601      0   stevel 	args.pname.GSS_BUFFER_T_len = flatName.length;
   2602      0   stevel 	args.pname.GSS_BUFFER_T_val = flatName.value;
   2603      0   stevel 	args.name_type.GSS_OID_len = nameOid->length;
   2604      0   stevel 	args.name_type.GSS_OID_val = nameOid->elements;
   2605      0   stevel 	args.mech_type.GSS_OID_len = mechType->length;
   2606      0   stevel 	args.mech_type.GSS_OID_val = mechType->elements;
   2607      0   stevel 
   2608      0   stevel 	/* call the remote procedure */
   2609      0   stevel 	bzero(&res, sizeof (res));
   2610      0   stevel 	if (gsscred_name_to_unix_cred_1(&args, &res, clnt) != RPC_SUCCESS) {
   2611      0   stevel 		killgssd_handle(clnt);
   2612      0   stevel 		(void) gss_release_buffer(&minor, &flatName);
   2613      0   stevel 		GSSLOG0(1, "kgsscred_name_to_unix_cred: RPC call times out\n");
   2614      0   stevel 		return (GSS_S_FAILURE);
   2615      0   stevel 	}
   2616      0   stevel 
   2617      0   stevel 	/* delete the flat name buffer */
   2618      0   stevel 	(void) gss_release_buffer(&minor, &flatName);
   2619      0   stevel 
   2620      0   stevel 	/* copy the output parameters on output */
   2621      0   stevel 	if (res.major == GSS_S_COMPLETE) {
   2622      0   stevel 		*uidOut = res.uid;
   2623      0   stevel 
   2624      0   stevel 		if (gidOut)
   2625      0   stevel 			*gidOut = res.gid;
   2626      0   stevel 		if (gids && gidsLen) {
   2627      0   stevel 			*gids = res.gids.GSSCRED_GIDS_val;
   2628      0   stevel 			*gidsLen = res.gids.GSSCRED_GIDS_len;
   2629      0   stevel 			res.gids.GSSCRED_GIDS_val = NULL;
   2630      0   stevel 			res.gids.GSSCRED_GIDS_len = 0;
   2631      0   stevel 		}
   2632      0   stevel 	}
   2633      0   stevel 
   2634      0   stevel 	/* delete RPC allocated memory */
   2635      0   stevel 	clnt_freeres(clnt, xdr_gsscred_name_to_unix_cred_res, (caddr_t)&res);
   2636      0   stevel 	killgssd_handle(clnt);
   2637      0   stevel 
   2638      0   stevel 	return (res.major);
   2639      0   stevel } /* kgsscred_name_to_unix_cred */
   2640      0   stevel 
   2641      0   stevel OM_uint32
   2642      0   stevel kgss_get_group_info(puid, gidOut, gids, gidsLen, uid)
   2643      0   stevel 	const uid_t puid;
   2644      0   stevel 	gid_t *gidOut;
   2645      0   stevel 	gid_t *gids[];
   2646      0   stevel 	int *gidsLen;
   2647      0   stevel 	uid_t uid;
   2648      0   stevel {
   2649      0   stevel 	CLIENT *clnt;
   2650      0   stevel 	gss_get_group_info_arg args;
   2651      0   stevel 	gss_get_group_info_res res;
   2652      0   stevel 
   2653      0   stevel 
   2654      0   stevel 	/* check the output parameters */
   2655      0   stevel 	if (gidOut == NULL || gids == NULL || gidsLen == NULL)
   2656      0   stevel 		return (GSS_S_CALL_INACCESSIBLE_WRITE);
   2657      0   stevel 
   2658      0   stevel 	/* get the client GSSD handle */
   2659      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
   2660      0   stevel 		GSSLOG(1,
   2661      0   stevel 			"kgss_get_group_info: can't connect to server on %s\n",
   2662      0   stevel 			server);
   2663      0   stevel 		return (GSS_S_FAILURE);
   2664      0   stevel 	}
   2665      0   stevel 
   2666      0   stevel 	/* set the input parameters */
   2667      0   stevel 	args.uid = uid;
   2668      0   stevel 	args.puid = puid;
   2669      0   stevel 
   2670      0   stevel 	/* call the remote procedure */
   2671      0   stevel 	bzero(&res, sizeof (res));
   2672      0   stevel 	if (gss_get_group_info_1(&args, &res, clnt) != RPC_SUCCESS) {
   2673      0   stevel 		killgssd_handle(clnt);
   2674      0   stevel 		GSSLOG0(1, "kgss_get_group_info: RPC call times out\n");
   2675      0   stevel 		return (GSS_S_FAILURE);
   2676      0   stevel 	}
   2677      0   stevel 
   2678      0   stevel 	/* copy the results */
   2679      0   stevel 	if (res.major == GSS_S_COMPLETE) {
   2680      0   stevel 		*gidOut = res.gid;
   2681      0   stevel 		*gids = res.gids.GSSCRED_GIDS_val;
   2682      0   stevel 		*gidsLen = res.gids.GSSCRED_GIDS_len;
   2683      0   stevel 		res.gids.GSSCRED_GIDS_val = NULL;
   2684      0   stevel 		res.gids.GSSCRED_GIDS_len = 0;
   2685      0   stevel 	}
   2686      0   stevel 
   2687      0   stevel 	/* no results to free */
   2688      0   stevel 	killgssd_handle(clnt);
   2689      0   stevel 
   2690      0   stevel 	return (res.major);
   2691      0   stevel } /* kgss_get_group_info */
   2692      0   stevel 
   2693      0   stevel static char *
   2694      0   stevel kgss_get_kmod(gss_OID mech_oid)
   2695      0   stevel {
   2696      0   stevel 	CLIENT *clnt;
   2697      0   stevel 	gss_get_kmod_arg args;
   2698      0   stevel 	gss_get_kmod_res res;
   2699      0   stevel 
   2700      0   stevel 
   2701      0   stevel 	/* get the client GSSD handle */
   2702      0   stevel 	if ((clnt = getgssd_handle()) == NULL) {
   2703      0   stevel 		GSSLOG(1, "kgss_get_kmod: can't connect to server on %s\n",
   2704      0   stevel 			server);
   2705      0   stevel 		return (NULL);
   2706      0   stevel 	}
   2707      0   stevel 
   2708      0   stevel 	/* set the input parameters */
   2709      0   stevel 	args.mech_oid.GSS_OID_len = mech_oid->length;
   2710      0   stevel 	args.mech_oid.GSS_OID_val = mech_oid->elements;
   2711      0   stevel 
   2712      0   stevel 	/* call the remote procedure */
   2713      0   stevel 	bzero(&res, sizeof (res));
   2714      0   stevel 	if (gss_get_kmod_1(&args, &res, clnt) != RPC_SUCCESS) {
   2715      0   stevel 		killgssd_handle(clnt);
   2716      0   stevel 		GSSLOG0(1, "gss_get_kmod_1: RPC call times out\n");
   2717      0   stevel 		return (NULL);
   2718      0   stevel 	}
   2719      0   stevel 	/* no results to free */
   2720      0   stevel 	killgssd_handle(clnt);
   2721      0   stevel 
   2722      0   stevel 	if (res.module_follow == TRUE) {
   2723      0   stevel 		return (res.gss_get_kmod_res_u.modname);
   2724      0   stevel 	} else
   2725      0   stevel 		return (NULL);
   2726      0   stevel } /* kgss_get_kmod */
   2727      0   stevel 
   2728      0   stevel static gss_mechanism	kgss_mech_head;
   2729      0   stevel static gss_mechanism	kgss_mech_tail;
   2730      0   stevel kmutex_t	__kgss_mech_lock;
   2731      0   stevel 
   2732      0   stevel /*
   2733      0   stevel  * See if there is kernel mechanism module, and if so, attempt to
   2734      0   stevel  * load it and reset the pointer (gss_mechanism) to the sign/seal/etc.
   2735      0   stevel  * entry points to that of the kernel module.
   2736      0   stevel  */
   2737      0   stevel static void
   2738      0   stevel __kgss_reset_mech(gss_mechanism *mechp, gss_OID mech_oid)
   2739      0   stevel {
   2740      0   stevel 	gss_mechanism mech;
   2741      0   stevel 	char *kmod;
   2742      0   stevel 
   2743      0   stevel 	/*
   2744      0   stevel 	 * We can search the list without a mutex, becuase the list never
   2745      0   stevel 	 * shrinks and we always add to the end.
   2746      0   stevel 	 */
   2747      0   stevel 	mech = __kgss_get_mechanism(mech_oid);
   2748      0   stevel 	if (mech) {
   2749      0   stevel 		*mechp = mech;
   2750      0   stevel 		return;
   2751      0   stevel 	}
   2752      0   stevel 
   2753      0   stevel 	/*
   2754      0   stevel 	 * Get the module name from the kernel.
   2755      0   stevel 	 */
   2756      0   stevel 	kmod = kgss_get_kmod(mech_oid);
   2757      0   stevel 
   2758      0   stevel 	if (kmod) {
   2759   6855  johnlev 		extern int modload(const char *, const char *);
   2760      0   stevel 		if (modload("misc/kgss", kmod) < 0) {
   2761      0   stevel 			/*
   2762      0   stevel 			 * Modload of 'kmod' failed, so log an
   2763      0   stevel 			 * appropriate comment
   2764      0   stevel 			 */
   2765      0   stevel 			cmn_err(CE_NOTE, "kgss_reset_mech: Algorithm modload "
   2766      0   stevel 				"(%s) failed. Userland gssd will now handle "
   2767      0   stevel 				"all GSSAPI calls, which may result in "
   2768      0   stevel 				"reduced performance.\n", kmod);
   2769      0   stevel 		};
   2770      0   stevel 
   2771      0   stevel 		/*
   2772      0   stevel 		 * Allocated in the XDR routine called by gss_get_kmod_1().
   2773      0   stevel 		 */
   2774      0   stevel 		FREE(kmod, strlen(kmod)+1);
   2775      0   stevel 
   2776      0   stevel 		mech = __kgss_get_mechanism(mech_oid);
   2777      0   stevel 		if (mech) {
   2778      0   stevel 			*mechp = mech;
   2779      0   stevel 		}
   2780      0   stevel 
   2781      0   stevel 		/*
   2782      0   stevel 		 * If for some reason the module load didn't take,
   2783      0   stevel 		 * we return anyway and hope that the next context
   2784      0   stevel 		 * creation succeeds.
   2785      0   stevel 		 */
   2786      0   stevel 		return;
   2787      0   stevel 	}
   2788      0   stevel 
   2789      0   stevel 
   2790      0   stevel 	/*
   2791      0   stevel 	 * No kernel module, so enter this mech oid into the list
   2792      0   stevel 	 * using the default sign/seal/etc. operations that upcall to
   2793      0   stevel 	 * gssd.
   2794      0   stevel 	 */
   2795      0   stevel 	mutex_enter(&__kgss_mech_lock);
   2796      0   stevel 	mech = __kgss_get_mechanism(mech_oid);
   2797      0   stevel 	if (mech) {
   2798      0   stevel 		mutex_exit(&__kgss_mech_lock);
   2799      0   stevel 		*mechp = mech;
   2800      0   stevel 		return;
   2801      0   stevel 	}
   2802      0   stevel 
   2803      0   stevel 	/*
   2804      0   stevel 	 * Allocate space for the mechanism entry.
   2805      0   stevel 	 */
   2806      0   stevel 	mech = kmem_zalloc(sizeof (struct gss_config), KM_SLEEP);
   2807      0   stevel 
   2808      0   stevel 	/*
   2809      0   stevel 	 * Copy basic information from default mechanism struct.
   2810      0   stevel 	 */
   2811      0   stevel 	*mech = default_gc;
   2812      0   stevel 
   2813      0   stevel 	/*
   2814      0   stevel 	 * Record the real mech OID.
   2815      0   stevel 	 */
   2816      0   stevel 	mech->mech_type.length = mech_oid->length;
   2817      0   stevel 	mech->mech_type.elements = MALLOC(mech_oid->length);
   2818      0   stevel 	bcopy(mech_oid->elements,  mech->mech_type.elements, mech_oid->length);
   2819      0   stevel 
   2820      0   stevel 	/*
   2821      0   stevel 	 * Add it to the table.
   2822      0   stevel 	 */
   2823      0   stevel 	__kgss_add_mechanism(mech);
   2824      0   stevel 	mutex_exit(&__kgss_mech_lock);
   2825      0   stevel 	*mechp = mech;
   2826      0   stevel }
   2827      0   stevel 
   2828      0   stevel /*
   2829      0   stevel  * Called with __kgss_mech_lock held.
   2830      0   stevel  */
   2831      0   stevel void
   2832      0   stevel __kgss_add_mechanism(gss_mechanism mech)
   2833      0   stevel {
   2834      0   stevel 	gss_mechanism tmp;
   2835      0   stevel 
   2836      0   stevel 	tmp = kgss_mech_tail;
   2837      0   stevel 	kgss_mech_tail = mech;
   2838      0   stevel 
   2839      0   stevel 	if (tmp != NULL)
   2840      0   stevel 		tmp->next = mech;
   2841      0   stevel 
   2842      0   stevel 	if (kgss_mech_head == NULL)
   2843      0   stevel 		kgss_mech_head = mech;
   2844      0   stevel }
   2845      0   stevel 
   2846      0   stevel /*
   2847      0   stevel  *  given the mechs_array and a mechanism OID, return the
   2848      0   stevel  *  pointer to the mechanism, or NULL if that mechanism is
   2849      0   stevel  *  not supported.
   2850      0   stevel  */
   2851      0   stevel gss_mechanism
   2852      0   stevel __kgss_get_mechanism(gss_OID type)
   2853      0   stevel {
   2854      0   stevel 	gss_mechanism mech;
   2855      0   stevel 
   2856      0   stevel 	mech = kgss_mech_head;
   2857      0   stevel 
   2858      0   stevel 	/*
   2859      0   stevel 	 * Note that a reader can scan this list without the mutex held.
   2860      0   stevel 	 * This is safe because we always append, and never shrink the list.
   2861      0   stevel 	 * Moreover, the entry is fully initialized before it is ever
   2862      0   stevel 	 * added to the list.
   2863      0   stevel 	 */
   2864      0   stevel 	while (mech != NULL) {
   2865      0   stevel 		if ((mech->mech_type.length == type->length) &&
   2866      0   stevel 		    (bcmp(mech->mech_type.elements, type->elements,
   2867      0   stevel 		    type->length) == 0))
   2868      0   stevel 			return (mech);
   2869      0   stevel 
   2870      0   stevel 		mech = mech->next;
   2871      0   stevel 	}
   2872      0   stevel 	return (NULL);
   2873      0   stevel }
   2874