Udiff g_init_sec_context.c
--- /net/etna.eng/build7/semery/mit2/webrev/usr/src/lib/libgss/g_init_sec_context.c- Wed Sep 8 17:00:27 2004
+++ g_init_sec_context.c Wed Sep 8 13:42:03 2004
@@ -1,11 +1,11 @@
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "@(#)g_init_sec_context.c 1.21 04/09/08 SMI"
+#pragma ident "@(#)g_init_sec_context.c 1.20 03/10/24 SMI"
/*
* glue routine for gss_init_sec_context
*/
#include <mechglueP.h>
@@ -41,81 +41,95 @@
gss_buffer_t output_token;
OM_uint32 * ret_flags;
OM_uint32 * time_rec;
{
- OM_uint32 status, temp_status, temp_minor_status;
+ OM_uint32 status, temp_minor_status;
gss_union_name_t union_name;
gss_union_cred_t union_cred;
gss_name_t internal_name;
gss_union_ctx_id_t union_ctx_id;
gss_OID mech_type = GSS_C_NULL_OID;
gss_mechanism mech;
gss_cred_id_t input_cred_handle;
- gss_initialize();
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+ *minor_status = 0;
+ /* clear output values */
+ if (actual_mech_type)
+ *actual_mech_type = NULL;
+
if (context_handle == NULL)
- return (GSS_S_NO_CONTEXT);
+ return (GSS_S_CALL_INACCESSIBLE_WRITE | GSS_S_NO_CONTEXT);
- /*
- * If mech_type is NULL, and the target_name is
- * mechanism-specific, then set it to the mech_type of
- * target_name.
- */
- if ((mech_type == GSS_C_NULL_OID) && union_name->mech_type)
- mech_type = union_name->mech_type;
+ if (target_name == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
+ if (output_token == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ output_token->value = NULL;
+ output_token->length = 0;
+
+
+ if (req_mech_type)
+ mech_type = (gss_OID)req_mech_type;
+
+ union_name = (gss_union_name_t)target_name;
+
/*
* obtain the gss mechanism information for the requested
* mechanism. If mech_type is NULL, set it to the resultant
* mechanism
*/
mech = __gss_get_mechanism(mech_type);
if (mech == NULL)
return (GSS_S_BAD_MECH);
+ if (mech->gss_init_sec_context == NULL)
+ return (GSS_S_UNAVAILABLE);
+
if (mech_type == GSS_C_NULL_OID)
mech_type = &mech->mech_type;
/*
* If target_name is mechanism_specific, then it must match the
* mech_type that we're about to use. Otherwise, do an import on
* the external_name form of the target name.
*/
- if (union_name->mech_type) {
- if (!g_OID_equal(union_name->mech_type, mech_type))
- return (GSS_S_BAD_MECH);
+ if (union_name->mech_type &&
+ g_OID_equal(union_name->mech_type, mech_type)) {
internal_name = union_name->mech_name;
} else {
- if ((temp_status = __gss_import_internal_name(minor_status,
+ if ((status = __gss_import_internal_name(minor_status,
mech_type, union_name,
- &internal_name)))
- return (GSS_S_BAD_NAME);
+ &internal_name)) != GSS_S_COMPLETE)
+ return (status);
}
/*
* if context_handle is GSS_C_NO_CONTEXT, allocate a union context
* descriptor to hold the mech type information as well as the
* underlying mechanism context handle. Otherwise, cast the
* value of *context_handle to the union context variable.
*/
if (*context_handle == GSS_C_NO_CONTEXT) {
+ status = GSS_S_FAILURE;
union_ctx_id = (gss_union_ctx_id_t)
malloc(sizeof (gss_union_ctx_id_desc));
+ if (union_ctx_id == NULL)
+ goto end;
- /* copy the mech type information */
+ if (generic_gss_copy_oid(&temp_minor_status, mech_type,
+ &union_ctx_id->mech_type) != GSS_S_COMPLETE) {
+ free(union_ctx_id);
+ goto end;
+ }
- union_ctx_id->mech_type->elements = (void *)
- malloc(mech_type->length);
-
- union_ctx_id->mech_type->length = mech_type->length;
- memcpy(union_ctx_id->mech_type->elements, mech_type->elements,
- mech_type->length);
-
/* copy the supplied context handle */
-
union_ctx_id->internal_ctx_id = *context_handle;
} else
union_ctx_id = (gss_union_ctx_id_t)*context_handle;
/*
@@ -128,11 +142,10 @@
/*
* now call the approprate underlying mechanism routine
*/
- if (mech->gss_init_sec_context) {
status = mech->gss_init_sec_context(
mech->context,
minor_status,
input_cred_handle,
&union_ctx_id->internal_ctx_id,
@@ -145,16 +158,28 @@
actual_mech_type,
output_token,
ret_flags,
time_rec);
- if (*context_handle == GSS_C_NO_CONTEXT)
+ if (status != GSS_S_COMPLETE && status != GSS_S_CONTINUE_NEEDED) {
+ /*
+ * the spec says (the preferred) method is to delete all
+ * context info on the first call to init, and on all
+ * subsequent calls make the caller responsible for
+ * calling gss_delete_sec_context
+ */
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ free(union_ctx_id->mech_type->elements);
+ free(union_ctx_id->mech_type);
+ free(union_ctx_id);
+ }
+ } else if (*context_handle == GSS_C_NO_CONTEXT)
*context_handle = (gss_ctx_id_t) union_ctx_id;
- } else
- status = GSS_S_BAD_BINDINGS;
- if (!union_name->mech_type) {
+end:
+ if (union_name->mech_name == NULL ||
+ union_name->mech_name != internal_name) {
(void) __gss_release_internal_name(&temp_minor_status,
mech_type, &internal_name);
}
return (status);