17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5ba7b222eSGlenn Barry * Common Development and Distribution License (the "License").
6ba7b222eSGlenn Barry * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
225e01956fSGlenn Barry * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate */
247c478bd9Sstevel@tonic-gate
257c478bd9Sstevel@tonic-gate /*
267c478bd9Sstevel@tonic-gate * glue routine for gss_accept_sec_context
277c478bd9Sstevel@tonic-gate */
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate #include <mechglueP.h>
305e01956fSGlenn Barry #include "gssapiP_generic.h"
317c478bd9Sstevel@tonic-gate #ifdef HAVE_STDLIB_H
327c478bd9Sstevel@tonic-gate #include <stdlib.h>
337c478bd9Sstevel@tonic-gate #endif
347c478bd9Sstevel@tonic-gate #include <string.h>
357c478bd9Sstevel@tonic-gate #include <errno.h>
365e01956fSGlenn Barry #include <syslog.h>
377c478bd9Sstevel@tonic-gate
385e01956fSGlenn Barry #ifndef LEAN_CLIENT
39503a2b89SPeter Shoults static OM_uint32
val_acc_sec_ctx_args(OM_uint32 * minor_status,gss_ctx_id_t * context_handle,gss_buffer_t input_token_buffer,gss_name_t * src_name,gss_OID * mech_type,gss_buffer_t output_token,gss_cred_id_t * d_cred)40503a2b89SPeter Shoults val_acc_sec_ctx_args(
41503a2b89SPeter Shoults OM_uint32 *minor_status,
42503a2b89SPeter Shoults gss_ctx_id_t *context_handle,
43503a2b89SPeter Shoults gss_buffer_t input_token_buffer,
44503a2b89SPeter Shoults gss_name_t *src_name,
45503a2b89SPeter Shoults gss_OID *mech_type,
46503a2b89SPeter Shoults gss_buffer_t output_token,
47503a2b89SPeter Shoults gss_cred_id_t *d_cred)
48503a2b89SPeter Shoults {
49503a2b89SPeter Shoults
50503a2b89SPeter Shoults /* Initialize outputs. */
51503a2b89SPeter Shoults
52503a2b89SPeter Shoults if (minor_status != NULL)
53503a2b89SPeter Shoults *minor_status = 0;
54503a2b89SPeter Shoults
55503a2b89SPeter Shoults if (src_name != NULL)
56503a2b89SPeter Shoults *src_name = GSS_C_NO_NAME;
57503a2b89SPeter Shoults
58503a2b89SPeter Shoults if (mech_type != NULL)
59503a2b89SPeter Shoults *mech_type = GSS_C_NO_OID;
60503a2b89SPeter Shoults
61503a2b89SPeter Shoults if (output_token != GSS_C_NO_BUFFER) {
62503a2b89SPeter Shoults output_token->length = 0;
63503a2b89SPeter Shoults output_token->value = NULL;
64503a2b89SPeter Shoults }
65503a2b89SPeter Shoults
66503a2b89SPeter Shoults if (d_cred != NULL)
67503a2b89SPeter Shoults *d_cred = GSS_C_NO_CREDENTIAL;
68503a2b89SPeter Shoults
69503a2b89SPeter Shoults /* Validate arguments. */
70503a2b89SPeter Shoults
71503a2b89SPeter Shoults if (minor_status == NULL)
72503a2b89SPeter Shoults return (GSS_S_CALL_INACCESSIBLE_WRITE);
73503a2b89SPeter Shoults
74503a2b89SPeter Shoults if (context_handle == NULL)
75503a2b89SPeter Shoults return (GSS_S_CALL_INACCESSIBLE_WRITE);
76503a2b89SPeter Shoults
77503a2b89SPeter Shoults if (input_token_buffer == GSS_C_NO_BUFFER)
78503a2b89SPeter Shoults return (GSS_S_CALL_INACCESSIBLE_READ);
79503a2b89SPeter Shoults
80503a2b89SPeter Shoults if (output_token == GSS_C_NO_BUFFER)
81503a2b89SPeter Shoults return (GSS_S_CALL_INACCESSIBLE_WRITE);
82503a2b89SPeter Shoults
83503a2b89SPeter Shoults return (GSS_S_COMPLETE);
84503a2b89SPeter Shoults }
85503a2b89SPeter Shoults
867c478bd9Sstevel@tonic-gate OM_uint32
gss_accept_sec_context(minor_status,context_handle,verifier_cred_handle,input_token_buffer,input_chan_bindings,src_name,mech_type,output_token,ret_flags,time_rec,d_cred)877c478bd9Sstevel@tonic-gate gss_accept_sec_context(minor_status,
887c478bd9Sstevel@tonic-gate context_handle,
897c478bd9Sstevel@tonic-gate verifier_cred_handle,
907c478bd9Sstevel@tonic-gate input_token_buffer,
917c478bd9Sstevel@tonic-gate input_chan_bindings,
927c478bd9Sstevel@tonic-gate src_name,
937c478bd9Sstevel@tonic-gate mech_type,
947c478bd9Sstevel@tonic-gate output_token,
957c478bd9Sstevel@tonic-gate ret_flags,
967c478bd9Sstevel@tonic-gate time_rec,
977c478bd9Sstevel@tonic-gate d_cred)
987c478bd9Sstevel@tonic-gate
997c478bd9Sstevel@tonic-gate OM_uint32 *minor_status;
1007c478bd9Sstevel@tonic-gate gss_ctx_id_t *context_handle;
1017c478bd9Sstevel@tonic-gate const gss_cred_id_t verifier_cred_handle;
1027c478bd9Sstevel@tonic-gate const gss_buffer_t input_token_buffer;
1037c478bd9Sstevel@tonic-gate const gss_channel_bindings_t input_chan_bindings;
1047c478bd9Sstevel@tonic-gate gss_name_t *src_name;
1057c478bd9Sstevel@tonic-gate gss_OID *mech_type;
1067c478bd9Sstevel@tonic-gate gss_buffer_t output_token;
1077c478bd9Sstevel@tonic-gate OM_uint32 *ret_flags;
1087c478bd9Sstevel@tonic-gate OM_uint32 *time_rec;
1097c478bd9Sstevel@tonic-gate gss_cred_id_t *d_cred; /* delegated cred handle */
1107c478bd9Sstevel@tonic-gate
1117c478bd9Sstevel@tonic-gate {
112354d1447Swyllys OM_uint32 status, temp_status, t_minstat;
1137c478bd9Sstevel@tonic-gate gss_union_ctx_id_t union_ctx_id;
1147c478bd9Sstevel@tonic-gate gss_union_cred_t union_cred;
1157c478bd9Sstevel@tonic-gate gss_cred_id_t input_cred_handle = GSS_C_NO_CREDENTIAL;
1167c478bd9Sstevel@tonic-gate gss_cred_id_t tmp_d_cred = GSS_C_NO_CREDENTIAL;
1177c478bd9Sstevel@tonic-gate gss_name_t internal_name = GSS_C_NO_NAME;
1187c478bd9Sstevel@tonic-gate gss_name_t tmp_src_name = GSS_C_NO_NAME;
1197c478bd9Sstevel@tonic-gate gss_OID_desc token_mech_type_desc;
1207c478bd9Sstevel@tonic-gate gss_OID token_mech_type = &token_mech_type_desc;
121354d1447Swyllys OM_uint32 flags;
1227c478bd9Sstevel@tonic-gate gss_mechanism mech;
1237c478bd9Sstevel@tonic-gate
124503a2b89SPeter Shoults status = val_acc_sec_ctx_args(minor_status,
125503a2b89SPeter Shoults context_handle,
126503a2b89SPeter Shoults input_token_buffer,
127503a2b89SPeter Shoults src_name,
128503a2b89SPeter Shoults mech_type,
129503a2b89SPeter Shoults output_token,
130503a2b89SPeter Shoults d_cred);
131503a2b89SPeter Shoults if (status != GSS_S_COMPLETE)
132503a2b89SPeter Shoults return (status);
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate /*
1357c478bd9Sstevel@tonic-gate * if context_handle is GSS_C_NO_CONTEXT, allocate a union context
1367c478bd9Sstevel@tonic-gate * descriptor to hold the mech type information as well as the
1377c478bd9Sstevel@tonic-gate * underlying mechanism context handle. Otherwise, cast the
1387c478bd9Sstevel@tonic-gate * value of *context_handle to the union context variable.
1397c478bd9Sstevel@tonic-gate */
1407c478bd9Sstevel@tonic-gate
1417c478bd9Sstevel@tonic-gate if (*context_handle == GSS_C_NO_CONTEXT) {
1427c478bd9Sstevel@tonic-gate
143ba7b222eSGlenn Barry if (input_token_buffer == GSS_C_NO_BUFFER)
1447c478bd9Sstevel@tonic-gate return (GSS_S_CALL_INACCESSIBLE_READ);
1457c478bd9Sstevel@tonic-gate
1467c478bd9Sstevel@tonic-gate /* Get the token mech type */
1477c478bd9Sstevel@tonic-gate status = __gss_get_mech_type(token_mech_type,
1487c478bd9Sstevel@tonic-gate input_token_buffer);
1497c478bd9Sstevel@tonic-gate
1507c478bd9Sstevel@tonic-gate if (status)
1517c478bd9Sstevel@tonic-gate return (status);
1527c478bd9Sstevel@tonic-gate
1537c478bd9Sstevel@tonic-gate status = GSS_S_FAILURE;
1547c478bd9Sstevel@tonic-gate union_ctx_id = (gss_union_ctx_id_t)
1557c478bd9Sstevel@tonic-gate malloc(sizeof (gss_union_ctx_id_desc));
1567c478bd9Sstevel@tonic-gate if (!union_ctx_id)
1577c478bd9Sstevel@tonic-gate return (GSS_S_FAILURE);
1587c478bd9Sstevel@tonic-gate
1597c478bd9Sstevel@tonic-gate union_ctx_id->internal_ctx_id = GSS_C_NO_CONTEXT;
160354d1447Swyllys status = generic_gss_copy_oid(&t_minstat,
1617c478bd9Sstevel@tonic-gate token_mech_type,
1627c478bd9Sstevel@tonic-gate &union_ctx_id->mech_type);
1637c478bd9Sstevel@tonic-gate if (status != GSS_S_COMPLETE) {
1647c478bd9Sstevel@tonic-gate free(union_ctx_id);
1657c478bd9Sstevel@tonic-gate return (status);
1667c478bd9Sstevel@tonic-gate }
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate /* set the new context handle to caller's data */
1697c478bd9Sstevel@tonic-gate *context_handle = (gss_ctx_id_t)union_ctx_id;
1707c478bd9Sstevel@tonic-gate } else {
1717c478bd9Sstevel@tonic-gate union_ctx_id = (gss_union_ctx_id_t)*context_handle;
1727c478bd9Sstevel@tonic-gate token_mech_type = union_ctx_id->mech_type;
1737c478bd9Sstevel@tonic-gate }
1747c478bd9Sstevel@tonic-gate
1757c478bd9Sstevel@tonic-gate /*
1767c478bd9Sstevel@tonic-gate * get the appropriate cred handle from the union cred struct.
1777c478bd9Sstevel@tonic-gate * defaults to GSS_C_NO_CREDENTIAL if there is no cred, which will
1787c478bd9Sstevel@tonic-gate * use the default credential.
1797c478bd9Sstevel@tonic-gate */
1807c478bd9Sstevel@tonic-gate union_cred = (gss_union_cred_t)verifier_cred_handle;
1817c478bd9Sstevel@tonic-gate input_cred_handle = __gss_get_mechanism_cred(union_cred,
1827c478bd9Sstevel@tonic-gate token_mech_type);
1837c478bd9Sstevel@tonic-gate
1847c478bd9Sstevel@tonic-gate /*
1857c478bd9Sstevel@tonic-gate * now select the approprate underlying mechanism routine and
1867c478bd9Sstevel@tonic-gate * call it.
1877c478bd9Sstevel@tonic-gate */
1887c478bd9Sstevel@tonic-gate
1897c478bd9Sstevel@tonic-gate mech = __gss_get_mechanism(token_mech_type);
1907c478bd9Sstevel@tonic-gate if (mech && mech->gss_accept_sec_context) {
1917c478bd9Sstevel@tonic-gate status = mech->gss_accept_sec_context(
1927c478bd9Sstevel@tonic-gate mech->context,
1937c478bd9Sstevel@tonic-gate minor_status,
1947c478bd9Sstevel@tonic-gate &union_ctx_id->internal_ctx_id,
1957c478bd9Sstevel@tonic-gate input_cred_handle,
1967c478bd9Sstevel@tonic-gate input_token_buffer,
1977c478bd9Sstevel@tonic-gate input_chan_bindings,
1987c478bd9Sstevel@tonic-gate &internal_name,
1995e01956fSGlenn Barry mech_type,
2007c478bd9Sstevel@tonic-gate output_token,
201354d1447Swyllys &flags,
2027c478bd9Sstevel@tonic-gate time_rec,
2037c478bd9Sstevel@tonic-gate d_cred ? &tmp_d_cred : NULL);
2047c478bd9Sstevel@tonic-gate
2057c478bd9Sstevel@tonic-gate /* If there's more work to do, keep going... */
2067c478bd9Sstevel@tonic-gate if (status == GSS_S_CONTINUE_NEEDED)
2077c478bd9Sstevel@tonic-gate return (GSS_S_CONTINUE_NEEDED);
2087c478bd9Sstevel@tonic-gate
2097c478bd9Sstevel@tonic-gate /* if the call failed, return with failure */
2105e01956fSGlenn Barry if (status != GSS_S_COMPLETE) {
2115e01956fSGlenn Barry if (mech_type && (*mech_type != GSS_C_NULL_OID))
2125e01956fSGlenn Barry map_error_oid(minor_status, *mech_type);
2135e01956fSGlenn Barry else {
2145e01956fSGlenn Barry map_error(minor_status, mech);
2155e01956fSGlenn Barry }
2167c478bd9Sstevel@tonic-gate goto error_out;
2175e01956fSGlenn Barry }
2187c478bd9Sstevel@tonic-gate
219354d1447Swyllys
2207c478bd9Sstevel@tonic-gate /*
2217c478bd9Sstevel@tonic-gate * if src_name is non-NULL,
2227c478bd9Sstevel@tonic-gate * convert internal_name into a union name equivalent
2237c478bd9Sstevel@tonic-gate * First call the mechanism specific display_name()
2247c478bd9Sstevel@tonic-gate * then call gss_import_name() to create
2257c478bd9Sstevel@tonic-gate * the union name struct cast to src_name
226*4aed303fSChris Love * NB: __gss_convert_name_to_union_name will
227*4aed303fSChris Love * "consume" (free) the name.
2287c478bd9Sstevel@tonic-gate */
2297c478bd9Sstevel@tonic-gate if (internal_name != NULL) {
2307c478bd9Sstevel@tonic-gate temp_status = __gss_convert_name_to_union_name(
231354d1447Swyllys &t_minstat, mech,
2327c478bd9Sstevel@tonic-gate internal_name, &tmp_src_name);
2337c478bd9Sstevel@tonic-gate if (temp_status != GSS_S_COMPLETE) {
234354d1447Swyllys *minor_status = t_minstat;
2355e01956fSGlenn Barry map_error(minor_status, mech);
2367c478bd9Sstevel@tonic-gate if (output_token->length)
2377c478bd9Sstevel@tonic-gate (void) gss_release_buffer(
238354d1447Swyllys &t_minstat,
2397c478bd9Sstevel@tonic-gate output_token);
2407c478bd9Sstevel@tonic-gate return (temp_status);
2417c478bd9Sstevel@tonic-gate }
2427c478bd9Sstevel@tonic-gate if (src_name != NULL) {
2437c478bd9Sstevel@tonic-gate *src_name = tmp_src_name;
2447c478bd9Sstevel@tonic-gate }
2457c478bd9Sstevel@tonic-gate } else if (src_name != NULL) {
2467c478bd9Sstevel@tonic-gate *src_name = GSS_C_NO_NAME;
2477c478bd9Sstevel@tonic-gate }
2487c478bd9Sstevel@tonic-gate
2497c478bd9Sstevel@tonic-gate /* Ensure we're returning correct creds format */
250354d1447Swyllys if ((flags & GSS_C_DELEG_FLAG) &&
2517c478bd9Sstevel@tonic-gate tmp_d_cred != GSS_C_NO_CREDENTIAL) {
252354d1447Swyllys /*
253354d1447Swyllys * If we got back an OID different from the original
254354d1447Swyllys * token OID, assume the delegated_cred is already
255354d1447Swyllys * a proper union_cred and just return it. Don't
256354d1447Swyllys * try to re-wrap it. This is for SPNEGO or other
257354d1447Swyllys * pseudo-mechanisms.
258354d1447Swyllys */
2595e01956fSGlenn Barry if (*mech_type != GSS_C_NO_OID &&
260354d1447Swyllys token_mech_type != GSS_C_NO_OID &&
2615e01956fSGlenn Barry !g_OID_equal(*mech_type, token_mech_type)) {
262354d1447Swyllys *d_cred = tmp_d_cred;
263354d1447Swyllys } else {
2647c478bd9Sstevel@tonic-gate gss_union_cred_t d_u_cred = NULL;
2657c478bd9Sstevel@tonic-gate
2667c478bd9Sstevel@tonic-gate d_u_cred = malloc(sizeof (gss_union_cred_desc));
2677c478bd9Sstevel@tonic-gate if (d_u_cred == NULL) {
2687c478bd9Sstevel@tonic-gate status = GSS_S_FAILURE;
2697c478bd9Sstevel@tonic-gate goto error_out;
2707c478bd9Sstevel@tonic-gate }
2717c478bd9Sstevel@tonic-gate (void) memset(d_u_cred, 0,
2727c478bd9Sstevel@tonic-gate sizeof (gss_union_cred_desc));
2737c478bd9Sstevel@tonic-gate
2747c478bd9Sstevel@tonic-gate d_u_cred->count = 1;
2757c478bd9Sstevel@tonic-gate
276354d1447Swyllys status = generic_gss_copy_oid(
277354d1447Swyllys &t_minstat,
2785e01956fSGlenn Barry *mech_type,
2797c478bd9Sstevel@tonic-gate &d_u_cred->mechs_array);
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate if (status != GSS_S_COMPLETE) {
2827c478bd9Sstevel@tonic-gate free(d_u_cred);
2837c478bd9Sstevel@tonic-gate goto error_out;
2847c478bd9Sstevel@tonic-gate }
2857c478bd9Sstevel@tonic-gate
286354d1447Swyllys d_u_cred->cred_array = malloc(
287354d1447Swyllys sizeof (gss_cred_id_t));
2887c478bd9Sstevel@tonic-gate if (d_u_cred->cred_array != NULL) {
2897c478bd9Sstevel@tonic-gate d_u_cred->cred_array[0] = tmp_d_cred;
2907c478bd9Sstevel@tonic-gate } else {
2917c478bd9Sstevel@tonic-gate free(d_u_cred);
2927c478bd9Sstevel@tonic-gate status = GSS_S_FAILURE;
2937c478bd9Sstevel@tonic-gate goto error_out;
2947c478bd9Sstevel@tonic-gate }
2957c478bd9Sstevel@tonic-gate
2967c478bd9Sstevel@tonic-gate if (status != GSS_S_COMPLETE) {
2977c478bd9Sstevel@tonic-gate free(d_u_cred->cred_array);
2987c478bd9Sstevel@tonic-gate free(d_u_cred);
2997c478bd9Sstevel@tonic-gate goto error_out;
3007c478bd9Sstevel@tonic-gate }
3017c478bd9Sstevel@tonic-gate
3027c478bd9Sstevel@tonic-gate internal_name = GSS_C_NO_NAME;
3037c478bd9Sstevel@tonic-gate
3047c478bd9Sstevel@tonic-gate d_u_cred->auxinfo.creation_time = time(0);
3057c478bd9Sstevel@tonic-gate d_u_cred->auxinfo.time_rec = 0;
3067c478bd9Sstevel@tonic-gate
3077c478bd9Sstevel@tonic-gate if (mech->gss_inquire_cred) {
308354d1447Swyllys status = mech->gss_inquire_cred(
309354d1447Swyllys mech->context,
3107c478bd9Sstevel@tonic-gate minor_status,
3117c478bd9Sstevel@tonic-gate tmp_d_cred,
3127c478bd9Sstevel@tonic-gate &internal_name,
3137c478bd9Sstevel@tonic-gate &d_u_cred->auxinfo.time_rec,
3147c478bd9Sstevel@tonic-gate &d_u_cred->auxinfo.cred_usage,
3157c478bd9Sstevel@tonic-gate NULL);
3167c478bd9Sstevel@tonic-gate }
3177c478bd9Sstevel@tonic-gate
3185e01956fSGlenn Barry if (status != GSS_S_COMPLETE)
3195e01956fSGlenn Barry map_error(minor_status, mech);
3205e01956fSGlenn Barry
3217c478bd9Sstevel@tonic-gate if (internal_name != NULL) {
322354d1447Swyllys temp_status =
323354d1447Swyllys __gss_convert_name_to_union_name(
324354d1447Swyllys &t_minstat, mech,
3257c478bd9Sstevel@tonic-gate internal_name, &tmp_src_name);
3267c478bd9Sstevel@tonic-gate if (temp_status != GSS_S_COMPLETE) {
327354d1447Swyllys *minor_status = t_minstat;
3285e01956fSGlenn Barry map_error(minor_status, mech);
3297c478bd9Sstevel@tonic-gate if (output_token->length)
3307c478bd9Sstevel@tonic-gate (void) gss_release_buffer(
331354d1447Swyllys &t_minstat,
3327c478bd9Sstevel@tonic-gate output_token);
3337c478bd9Sstevel@tonic-gate free(d_u_cred->cred_array);
3347c478bd9Sstevel@tonic-gate free(d_u_cred);
3357c478bd9Sstevel@tonic-gate return (temp_status);
3367c478bd9Sstevel@tonic-gate }
3377c478bd9Sstevel@tonic-gate }
3387c478bd9Sstevel@tonic-gate
3397c478bd9Sstevel@tonic-gate if (tmp_src_name != NULL) {
3407c478bd9Sstevel@tonic-gate status = gss_display_name(
341354d1447Swyllys &t_minstat,
3427c478bd9Sstevel@tonic-gate tmp_src_name,
3437c478bd9Sstevel@tonic-gate &d_u_cred->auxinfo.name,
3447c478bd9Sstevel@tonic-gate &d_u_cred->auxinfo.name_type);
3457c478bd9Sstevel@tonic-gate }
3467c478bd9Sstevel@tonic-gate
3477c478bd9Sstevel@tonic-gate *d_cred = (gss_cred_id_t)d_u_cred;
3487c478bd9Sstevel@tonic-gate }
349a6d402a0Swyllys }
350a6d402a0Swyllys if (ret_flags != NULL) {
351354d1447Swyllys *ret_flags = flags;
352354d1447Swyllys }
3537c478bd9Sstevel@tonic-gate
3547c478bd9Sstevel@tonic-gate if (src_name == NULL && tmp_src_name != NULL)
355354d1447Swyllys (void) gss_release_name(&t_minstat,
3567c478bd9Sstevel@tonic-gate &tmp_src_name);
3577c478bd9Sstevel@tonic-gate return (status);
3587c478bd9Sstevel@tonic-gate } else {
3597c478bd9Sstevel@tonic-gate
3607c478bd9Sstevel@tonic-gate status = GSS_S_BAD_MECH;
3617c478bd9Sstevel@tonic-gate }
3627c478bd9Sstevel@tonic-gate
3637c478bd9Sstevel@tonic-gate error_out:
3647c478bd9Sstevel@tonic-gate if (union_ctx_id) {
3657c478bd9Sstevel@tonic-gate if (union_ctx_id->mech_type) {
3667c478bd9Sstevel@tonic-gate if (union_ctx_id->mech_type->elements)
3677c478bd9Sstevel@tonic-gate free(union_ctx_id->mech_type->elements);
3687c478bd9Sstevel@tonic-gate free(union_ctx_id->mech_type);
3697c478bd9Sstevel@tonic-gate }
3707c478bd9Sstevel@tonic-gate free(union_ctx_id);
3717c478bd9Sstevel@tonic-gate *context_handle = GSS_C_NO_CONTEXT;
3727c478bd9Sstevel@tonic-gate }
3737c478bd9Sstevel@tonic-gate
374ba7b222eSGlenn Barry #if 0
375ba7b222eSGlenn Barry /*
376ba7b222eSGlenn Barry * Solaris Kerberos
377ba7b222eSGlenn Barry * Don't release, it causes a problem with error token.
378ba7b222eSGlenn Barry */
3797c478bd9Sstevel@tonic-gate if (output_token->length)
380354d1447Swyllys (void) gss_release_buffer(&t_minstat, output_token);
381ba7b222eSGlenn Barry #endif
3827c478bd9Sstevel@tonic-gate
3837c478bd9Sstevel@tonic-gate if (src_name)
3847c478bd9Sstevel@tonic-gate *src_name = GSS_C_NO_NAME;
3857c478bd9Sstevel@tonic-gate
3867c478bd9Sstevel@tonic-gate if (tmp_src_name != GSS_C_NO_NAME)
387354d1447Swyllys (void) gss_release_buffer(&t_minstat,
3887c478bd9Sstevel@tonic-gate (gss_buffer_t)tmp_src_name);
3897c478bd9Sstevel@tonic-gate
3907c478bd9Sstevel@tonic-gate return (status);
3917c478bd9Sstevel@tonic-gate }
3925e01956fSGlenn Barry #endif /* LEAN_CLIENT */
393