krb5 commit: Use interposer mechanisms in mechglue functions

Greg Hudson ghudson at MIT.EDU
Tue Oct 2 00:57:18 EDT 2012


https://github.com/krb5/krb5/commit/e40dc3cedbcee397526f797c4465927bc5f91aea
commit e40dc3cedbcee397526f797c4465927bc5f91aea
Author: Simo Sorce <simo at redhat.com>
Date:   Tue Jun 5 08:09:15 2012 -0400

    Use interposer mechanisms in mechglue functions
    
    Wherever a GSSAPI mechglue function accepts a mech OID from the
    caller, use gssint_select_mech_type() to choose the mechanism to use.
    Wherever a mechglue function outputs a mech OID to the caller, use
    gssint_get_public_oid() or gssint_make_public_oid_set() to expose the
    public mech OID.
    
    [ghudson at mit.edu: Stylistic changes, commit squashing, commit message]

 src/lib/gssapi/mechglue/g_accept_sec_context.c   |   56 +++++++++++++++++-----
 src/lib/gssapi/mechglue/g_acquire_cred.c         |   48 +++++++++----------
 src/lib/gssapi/mechglue/g_acquire_cred_with_pw.c |   46 +++++++++---------
 src/lib/gssapi/mechglue/g_canon_name.c           |   12 ++++-
 src/lib/gssapi/mechglue/g_export_cred.c          |    6 ++-
 src/lib/gssapi/mechglue/g_imp_cred.c             |   13 ++++--
 src/lib/gssapi/mechglue/g_imp_sec_context.c      |    8 +++-
 src/lib/gssapi/mechglue/g_init_sec_context.c     |   25 +++++-----
 src/lib/gssapi/mechglue/g_inq_context.c          |    7 ++-
 src/lib/gssapi/mechglue/g_inq_cred.c             |   31 +++++++-----
 src/lib/gssapi/mechglue/g_inq_names.c            |   10 +++-
 src/lib/gssapi/mechglue/g_mech_invoke.c          |   10 +++-
 src/lib/gssapi/mechglue/g_store_cred.c           |   13 ++++-
 src/lib/gssapi/mechglue/gssd_pname_to_uid.c      |   10 +++-
 14 files changed, 183 insertions(+), 112 deletions(-)

diff --git a/src/lib/gssapi/mechglue/g_accept_sec_context.c b/src/lib/gssapi/mechglue/g_accept_sec_context.c
index 85e41d3..dae83cc 100644
--- a/src/lib/gssapi/mechglue/g_accept_sec_context.c
+++ b/src/lib/gssapi/mechglue/g_accept_sec_context.c
@@ -114,7 +114,7 @@ gss_cred_id_t *		d_cred;
 {
     OM_uint32		status, temp_status, temp_minor_status;
     OM_uint32		temp_ret_flags = 0;
-    gss_union_ctx_id_t	union_ctx_id;
+    gss_union_ctx_id_t	union_ctx_id = NULL;
     gss_cred_id_t	input_cred_handle = GSS_C_NO_CREDENTIAL;
     gss_cred_id_t	tmp_d_cred = GSS_C_NO_CREDENTIAL;
     gss_name_t		internal_name = GSS_C_NO_NAME;
@@ -122,7 +122,11 @@ gss_cred_id_t *		d_cred;
     gss_OID_desc	token_mech_type_desc;
     gss_OID		token_mech_type = &token_mech_type_desc;
     gss_OID		actual_mech = GSS_C_NO_OID;
+    gss_OID		selected_mech = GSS_C_NO_OID;
+    gss_OID		public_mech;
     gss_mechanism	mech = NULL;
+    gss_union_cred_t	uc;
+    int			i;
 
     status = val_acc_sec_ctx_args(minor_status,
 				  context_handle,
@@ -155,6 +159,36 @@ gss_cred_id_t *		d_cred;
 	if (status)
 	    return status;
 
+	/*
+	 * An interposer calling back into the mechglue can't pass in a special
+	 * mech, so we have to recognize it using verifier_cred_handle.  Use
+	 * the mechanism for which we have matching creds, if available.
+	 */
+	if (verifier_cred_handle != GSS_C_NO_CREDENTIAL) {
+	    uc = (gss_union_cred_t)verifier_cred_handle;
+	    for (i = 0; i < uc->count; i++) {
+		public_mech = gssint_get_public_oid(&uc->mechs_array[i]);
+		if (public_mech && g_OID_equal(token_mech_type, public_mech)) {
+		    selected_mech = &uc->mechs_array[i];
+		    break;
+		}
+	    }
+	}
+
+	if (selected_mech == GSS_C_NO_OID) {
+	    status = gssint_select_mech_type(minor_status, token_mech_type,
+					     &selected_mech);
+	    if (status)
+		return status;
+	}
+
+    } else {
+	union_ctx_id = (gss_union_ctx_id_t)*context_handle;
+	selected_mech = union_ctx_id->mech_type;
+    }
+
+    /* Now create a new context if we didn't get one. */
+    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));
@@ -163,8 +197,7 @@ gss_cred_id_t *		d_cred;
 
 	union_ctx_id->loopback = union_ctx_id;
 	union_ctx_id->internal_ctx_id = GSS_C_NO_CONTEXT;
-	status = generic_gss_copy_oid(&temp_minor_status,
-				      token_mech_type,
+	status = generic_gss_copy_oid(&temp_minor_status, selected_mech,
 				      &union_ctx_id->mech_type);
 	if (status != GSS_S_COMPLETE) {
 	    free(union_ctx_id);
@@ -173,9 +206,6 @@ gss_cred_id_t *		d_cred;
 
 	/* set the new context handle to caller's data */
 	*context_handle = (gss_ctx_id_t)union_ctx_id;
-    } else {
-	union_ctx_id = (gss_union_ctx_id_t)*context_handle;
-	token_mech_type = union_ctx_id->mech_type;
     }
 
     /*
@@ -184,7 +214,7 @@ gss_cred_id_t *		d_cred;
     if (verifier_cred_handle != GSS_C_NO_CREDENTIAL) {
 	input_cred_handle =
 	    gssint_get_mechanism_cred((gss_union_cred_t)verifier_cred_handle,
-				      token_mech_type);
+				      selected_mech);
 	if (input_cred_handle == GSS_C_NO_CREDENTIAL) {
 	    /* verifier credential specified but no acceptor credential found */
 	    status = GSS_S_NO_CRED;
@@ -197,7 +227,7 @@ gss_cred_id_t *		d_cred;
      * call it.
      */
 
-    mech = gssint_get_mechanism (token_mech_type);
+    mech = gssint_get_mechanism(selected_mech);
     if (mech && mech->gss_accept_sec_context) {
 
 	    status = mech->gss_accept_sec_context(minor_status,
@@ -253,8 +283,10 @@ gss_cred_id_t *		d_cred;
 	    /* Ensure we're returning correct creds format */
 	    if ((temp_ret_flags & GSS_C_DELEG_FLAG) &&
 		tmp_d_cred != GSS_C_NO_CREDENTIAL) {
+		public_mech = gssint_get_public_oid(selected_mech);
 		if (actual_mech != GSS_C_NO_OID &&
-		    !g_OID_prefix_equal(actual_mech, token_mech_type)) {
+		    public_mech != GSS_C_NO_OID &&
+		    !g_OID_prefix_equal(actual_mech, public_mech)) {
 		    *d_cred = tmp_d_cred; /* unwrapped pseudo-mech */
 		} else {
 		    gss_union_cred_t d_u_cred = NULL;
@@ -269,7 +301,7 @@ gss_cred_id_t *		d_cred;
 		    d_u_cred->count = 1;
 
 		    status = generic_gss_copy_oid(&temp_minor_status,
-						  token_mech_type,
+						  selected_mech,
 						  &d_u_cred->mechs_array);
 
 		    if (status != GSS_S_COMPLETE) {
@@ -292,9 +324,7 @@ gss_cred_id_t *		d_cred;
 	    }
 
 	    if (mech_type != NULL)
-		*mech_type = actual_mech;
-	    else
-		(void) gss_release_oid(&temp_minor_status, &actual_mech);
+		*mech_type = gssint_get_public_oid(actual_mech);
 	    if (ret_flags != NULL)
 		*ret_flags = temp_ret_flags;
 	    return	(status);
diff --git a/src/lib/gssapi/mechglue/g_acquire_cred.c b/src/lib/gssapi/mechglue/g_acquire_cred.c
index bdfd464..03b67e3 100644
--- a/src/lib/gssapi/mechglue/g_acquire_cred.c
+++ b/src/lib/gssapi/mechglue/g_acquire_cred.c
@@ -230,12 +230,8 @@ OM_uint32 *			time_rec;
      * setup the actual mechs output parameter
      */
     if (actual_mechs != NULL) {
-	gss_OID_set_desc oids;
-
-	oids.count = creds->count;
-	oids.elements = creds->mechs_array;
-
-	major = generic_gss_copy_oid_set(minor_status, &oids, actual_mechs);
+	major = gssint_make_public_oid_set(minor_status, creds->mechs_array,
+					   creds->count, actual_mechs);
 	if (GSS_ERROR(major))
 	    goto cleanup;
     }
@@ -374,6 +370,7 @@ gss_add_cred_from(minor_status, input_cred_handle,
     gss_OID		new_mechs_array = NULL;
     gss_cred_id_t *	new_cred_array = NULL;
     gss_OID_set		target_mechs = GSS_C_NO_OID_SET;
+    gss_OID		selected_mech = GSS_C_NO_OID;
 
     status = val_add_cred_args(minor_status,
 			       input_cred_handle,
@@ -390,7 +387,12 @@ gss_add_cred_from(minor_status, input_cred_handle,
     if (status != GSS_S_COMPLETE)
 	return (status);
 
-    mech = gssint_get_mechanism(desired_mech);
+    status = gssint_select_mech_type(minor_status, desired_mech,
+				     &selected_mech);
+    if (status != GSS_S_COMPLETE)
+	return (status);
+
+    mech = gssint_get_mechanism(selected_mech);
     if (!mech)
 	return GSS_S_BAD_MECH;
     else if (!mech->gss_acquire_cred)
@@ -404,7 +406,7 @@ gss_add_cred_from(minor_status, input_cred_handle,
 	(void) memset(union_cred, 0, sizeof (gss_union_cred_desc));
     } else {
 	union_cred = (gss_union_cred_t)input_cred_handle;
-	if (gssint_get_mechanism_cred(union_cred, desired_mech) !=
+	if (gssint_get_mechanism_cred(union_cred, selected_mech) !=
 	    GSS_C_NO_CREDENTIAL)
 	    return (GSS_S_DUPLICATE_ELEMENT);
     }
@@ -416,13 +418,12 @@ gss_add_cred_from(minor_status, input_cred_handle,
 	if (desired_name) {
 	    union_name = (gss_union_name_t)desired_name;
 	    if (union_name->mech_type &&
-		g_OID_equal(union_name->mech_type,
-			    &mech->mech_type))
+		g_OID_equal(union_name->mech_type, selected_mech))
 		internal_name = union_name->mech_name;
 	    else {
-		if (gssint_import_internal_name(minor_status,
-					        &mech->mech_type, union_name,
-					        &allocated_name) != GSS_S_COMPLETE)
+		if (gssint_import_internal_name(minor_status, selected_mech,
+						union_name, &allocated_name) !=
+		    GSS_S_COMPLETE)
 		    return (GSS_S_BAD_NAME);
 		internal_name = allocated_name;
 	    }
@@ -445,7 +446,8 @@ gss_add_cred_from(minor_status, input_cred_handle,
 	goto errout;
 
     status = gss_add_oid_set_member(minor_status,
-				    &mech->mech_type, &target_mechs);
+				    gssint_get_public_oid(selected_mech),
+				    &target_mechs);
     if (status != GSS_S_COMPLETE)
 	goto errout;
 
@@ -496,19 +498,15 @@ gss_add_cred_from(minor_status, input_cred_handle,
 
     new_cred_array[union_cred->count] = cred;
     if ((new_mechs_array[union_cred->count].elements =
-	 malloc(mech->mech_type.length)) == NULL)
+	 malloc(selected_mech->length)) == NULL)
 	goto errout;
 
-    g_OID_copy(&new_mechs_array[union_cred->count],
-	       &mech->mech_type);
+    g_OID_copy(&new_mechs_array[union_cred->count], selected_mech);
 
     if (actual_mechs != NULL) {
-	gss_OID_set_desc oids;
-
-	oids.count = union_cred->count + 1;
-	oids.elements = new_mechs_array;
-
-	status = generic_gss_copy_oid_set(minor_status, &oids, actual_mechs);
+	status = gssint_make_public_oid_set(minor_status, new_mechs_array,
+					    union_cred->count + 1,
+					    actual_mechs);
 	if (GSS_ERROR(status)) {
 	    free(new_mechs_array[union_cred->count].elements);
 	    goto errout;
@@ -538,7 +536,7 @@ gss_add_cred_from(minor_status, input_cred_handle,
 
     if (allocated_name)
 	(void) gssint_release_internal_name(&temp_minor_status,
-					   &mech->mech_type,
+					   selected_mech,
 					   &allocated_name);
     (void) generic_gss_release_oid_set(&temp_minor_status, &target_mechs);
 
@@ -555,7 +553,7 @@ errout:
 
     if (allocated_name)
 	(void) gssint_release_internal_name(&temp_minor_status,
-					   &mech->mech_type,
+					   selected_mech,
 					   &allocated_name);
 
     if (input_cred_handle == GSS_C_NO_CREDENTIAL && union_cred)
diff --git a/src/lib/gssapi/mechglue/g_acquire_cred_with_pw.c b/src/lib/gssapi/mechglue/g_acquire_cred_with_pw.c
index 4d0dbb9..f290f8a 100644
--- a/src/lib/gssapi/mechglue/g_acquire_cred_with_pw.c
+++ b/src/lib/gssapi/mechglue/g_acquire_cred_with_pw.c
@@ -216,12 +216,8 @@ OM_uint32 *		time_rec;
      * setup the actual mechs output parameter
      */
     if (actual_mechs != NULL) {
-	gss_OID_set_desc oids;
-
-	oids.count = creds->count;
-	oids.elements = creds->mechs_array;
-
-	major = generic_gss_copy_oid_set(minor_status, &oids, actual_mechs);
+	major = gssint_make_public_oid_set(minor_status, creds->mechs_array,
+					   creds->count, actual_mechs);
 	if (GSS_ERROR(major)) {
 	    (void) gss_release_cred(minor_status,
 				    (gss_cred_id_t *)&creds);
@@ -339,6 +335,7 @@ gss_add_cred_with_password(minor_status, input_cred_handle,
     gss_OID		new_mechs_array = NULL;
     gss_cred_id_t *	new_cred_array = NULL;
     gss_OID_set		target_mechs = GSS_C_NO_OID_SET;
+    gss_OID		selected_mech = GSS_C_NO_OID;
 
     status = val_add_cred_pw_args(minor_status,
 			          input_cred_handle,
@@ -355,7 +352,12 @@ gss_add_cred_with_password(minor_status, input_cred_handle,
     if (status != GSS_S_COMPLETE)
 	return (status);
 
-    mech = gssint_get_mechanism(desired_mech);
+    status = gssint_select_mech_type(minor_status, desired_mech,
+				     &selected_mech);
+    if (status != GSS_S_COMPLETE)
+	return (status);
+
+    mech = gssint_get_mechanism(selected_mech);
     if (!mech)
 	return GSS_S_BAD_MECH;
     if (!mech->gssspi_acquire_cred_with_password)
@@ -372,19 +374,19 @@ gss_add_cred_with_password(minor_status, input_cred_handle,
 	internal_name = GSS_C_NO_NAME;
     } else {
 	union_cred = (gss_union_cred_t)input_cred_handle;
-	if (gssint_get_mechanism_cred(union_cred, desired_mech) !=
+	if (gssint_get_mechanism_cred(union_cred, selected_mech) !=
 	    GSS_C_NO_CREDENTIAL)
 	    return (GSS_S_DUPLICATE_ELEMENT);
     }
 
     /* may need to create a mechanism specific name */
     union_name = (gss_union_name_t)desired_name;
-    if (union_name->mech_type && g_OID_equal(union_name->mech_type,
-					     &mech->mech_type))
+    if (union_name->mech_type &&
+	g_OID_equal(union_name->mech_type, selected_mech))
 	internal_name = union_name->mech_name;
     else {
 	if (gssint_import_internal_name(minor_status,
-					&mech->mech_type, union_name,
+					selected_mech, union_name,
 					&allocated_name) != GSS_S_COMPLETE)
 	    return (GSS_S_BAD_NAME);
 	internal_name = allocated_name;
@@ -405,7 +407,8 @@ gss_add_cred_with_password(minor_status, input_cred_handle,
 	goto errout;
 
     status = gss_add_oid_set_member(minor_status,
-				    &mech->mech_type, &target_mechs);
+				    gssint_get_public_oid(selected_mech),
+				    &target_mechs);
     if (status != GSS_S_COMPLETE)
 	goto errout;
 
@@ -452,19 +455,15 @@ gss_add_cred_with_password(minor_status, input_cred_handle,
 
     new_cred_array[union_cred->count] = cred;
     if ((new_mechs_array[union_cred->count].elements =
-	 malloc(mech->mech_type.length)) == NULL)
+	 malloc(selected_mech->length)) == NULL)
 	goto errout;
 
-    g_OID_copy(&new_mechs_array[union_cred->count],
-	       &mech->mech_type);
+    g_OID_copy(&new_mechs_array[union_cred->count], selected_mech);
 
     if (actual_mechs != NULL) {
-	gss_OID_set_desc oids;
-
-	oids.count = union_cred->count + 1;
-	oids.elements = new_mechs_array;
-
-	status = generic_gss_copy_oid_set(minor_status, &oids, actual_mechs);
+	status = gssint_make_public_oid_set(minor_status, new_mechs_array,
+					    union_cred->count + 1,
+					    actual_mechs);
 	if (GSS_ERROR(status)) {
 	    free(new_mechs_array[union_cred->count].elements);
 	    goto errout;
@@ -494,7 +493,7 @@ gss_add_cred_with_password(minor_status, input_cred_handle,
 
     if (allocated_name)
 	(void) gssint_release_internal_name(&temp_minor_status,
-					   &mech->mech_type,
+					    selected_mech,
 					   &allocated_name);
 
     return (GSS_S_COMPLETE);
@@ -510,8 +509,7 @@ errout:
 
     if (allocated_name)
 	(void) gssint_release_internal_name(&temp_minor_status,
-					   &mech->mech_type,
-					   &allocated_name);
+					    selected_mech, &allocated_name);
 
     if (target_mechs)
 	(void)gss_release_oid_set(&temp_minor_status, &target_mechs);
diff --git a/src/lib/gssapi/mechglue/g_canon_name.c b/src/lib/gssapi/mechglue/g_canon_name.c
index d178808..61f657f 100644
--- a/src/lib/gssapi/mechglue/g_canon_name.c
+++ b/src/lib/gssapi/mechglue/g_canon_name.c
@@ -65,6 +65,7 @@ gss_name_t *output_name;
 {
 	gss_union_name_t in_union, out_union = NULL, dest_union = NULL;
 	OM_uint32 major_status = GSS_S_FAILURE, tmpmin;
+	gss_OID selected_mech;
 
 	major_status = val_canon_name_args(minor_status,
 					   input_name,
@@ -73,6 +74,11 @@ gss_name_t *output_name;
 	if (major_status != GSS_S_COMPLETE)
 		return (major_status);
 
+	major_status = gssint_select_mech_type(minor_status, mech_type,
+					       &selected_mech);
+	if (major_status != GSS_S_COMPLETE)
+		return (major_status);
+
 	/* Initial value needed below. */
 	major_status = GSS_S_FAILURE;
 
@@ -82,7 +88,7 @@ gss_name_t *output_name;
 	 * been converted, then there is nothing for us to do.
 	 */
 	if (!output_name && in_union->mech_type &&
-		g_OID_equal(in_union->mech_type, mech_type))
+	    g_OID_equal(in_union->mech_type, selected_mech))
 		return (GSS_S_COMPLETE);
 
 	/* ok, then we need to do something - start by creating data struct */
@@ -133,14 +139,14 @@ gss_name_t *output_name;
 		dest_union = out_union;
 
 	/* now let's create the new mech name */
-	if ((major_status = generic_gss_copy_oid(minor_status, mech_type,
+	if ((major_status = generic_gss_copy_oid(minor_status, selected_mech,
 						 &dest_union->mech_type))) {
 	    map_errcode(minor_status);
 	    goto allocation_failure;
 	}
 
 	if ((major_status =
-		gssint_import_internal_name(minor_status, mech_type,
+		gssint_import_internal_name(minor_status, selected_mech,
 						in_union,
 						&dest_union->mech_name)))
 		goto allocation_failure;
diff --git a/src/lib/gssapi/mechglue/g_export_cred.c b/src/lib/gssapi/mechglue/g_export_cred.c
index 4994c9b..de2e98d 100644
--- a/src/lib/gssapi/mechglue/g_export_cred.c
+++ b/src/lib/gssapi/mechglue/g_export_cred.c
@@ -62,6 +62,7 @@ gss_export_cred(OM_uint32 * minor_status, gss_cred_id_t cred_handle,
     OM_uint32 status, tmpmin;
     gss_union_cred_t cred;
     gss_OID mech_oid;
+    gss_OID public_oid;
     gss_mechanism mech;
     gss_buffer_desc mech_token;
     struct k5buf buf;
@@ -78,6 +79,7 @@ gss_export_cred(OM_uint32 * minor_status, gss_cred_id_t cred_handle,
     for (i = 0; i < cred->count; i++) {
         /* Get an export token for this mechanism. */
         mech_oid = &cred->mechs_array[i];
+        public_oid = gssint_get_public_oid(mech_oid);
         mech = gssint_get_mechanism(mech_oid);
         if (mech == NULL) {
             status = GSS_S_DEFECTIVE_CREDENTIAL;
@@ -95,9 +97,9 @@ gss_export_cred(OM_uint32 * minor_status, gss_cred_id_t cred_handle,
         }
 
         /* Append the mech OID and token to buf. */
-        store_32_be(mech_oid->length, lenbuf);
+        store_32_be(public_oid->length, lenbuf);
         krb5int_buf_add_len(&buf, lenbuf, 4);
-        krb5int_buf_add_len(&buf, mech_oid->elements, mech_oid->length);
+        krb5int_buf_add_len(&buf, public_oid->elements, public_oid->length);
         store_32_be(mech_token.length, lenbuf);
         krb5int_buf_add_len(&buf, lenbuf, 4);
         krb5int_buf_add_len(&buf, mech_token.value, mech_token.length);
diff --git a/src/lib/gssapi/mechglue/g_imp_cred.c b/src/lib/gssapi/mechglue/g_imp_cred.c
index 20083cb..1611daf 100644
--- a/src/lib/gssapi/mechglue/g_imp_cred.c
+++ b/src/lib/gssapi/mechglue/g_imp_cred.c
@@ -96,6 +96,7 @@ gss_import_cred(OM_uint32 *minor_status, gss_buffer_t token,
     gss_mechanism mech;
     gss_buffer_desc tok, mech_token;
     gss_OID_desc mech_oid;
+    gss_OID selected_mech;
     gss_cred_id_t mech_cred;
     void *elemcopy;
 
@@ -128,7 +129,11 @@ gss_import_cred(OM_uint32 *minor_status, gss_buffer_t token,
         (void)get_entry(minor_status, &tok, &mech_oid, &mech_token);
 
         /* Import this entry's mechanism token. */
-        mech = gssint_get_mechanism(&mech_oid);
+        status = gssint_select_mech_type(minor_status, &mech_oid,
+                                         &selected_mech);
+        if (status != GSS_S_COMPLETE)
+            goto error;
+        mech = gssint_get_mechanism(selected_mech);
         if (mech == NULL || mech->gss_import_cred == NULL) {
             status = GSS_S_DEFECTIVE_TOKEN;
             goto error;
@@ -140,14 +145,14 @@ gss_import_cred(OM_uint32 *minor_status, gss_buffer_t token,
         }
 
         /* Add the resulting mechanism cred to the union cred. */
-        elemcopy = malloc(mech_oid.length);
+        elemcopy = malloc(selected_mech->length);
         if (elemcopy == NULL) {
             if (mech->gss_release_cred != NULL)
                 mech->gss_release_cred(&tmpmin, &mech_cred);
             goto oom;
         }
-        memcpy(elemcopy, mech_oid.elements, mech_oid.length);
-        cred->mechs_array[cred->count].length = mech_oid.length;
+        memcpy(elemcopy, selected_mech->elements, selected_mech->length);
+        cred->mechs_array[cred->count].length = selected_mech->length;
         cred->mechs_array[cred->count].elements = elemcopy;
         cred->cred_array[cred->count++] = mech_cred;
     }
diff --git a/src/lib/gssapi/mechglue/g_imp_sec_context.c b/src/lib/gssapi/mechglue/g_imp_sec_context.c
index 45ba9d6..8207488 100644
--- a/src/lib/gssapi/mechglue/g_imp_sec_context.c
+++ b/src/lib/gssapi/mechglue/g_imp_sec_context.c
@@ -83,6 +83,7 @@ gss_ctx_id_t *		context_handle;
     char		*p;
     gss_union_ctx_id_t	ctx;
     gss_buffer_desc	token;
+    gss_OID		selected_mech = GSS_C_NO_OID;
     gss_mechanism	mech;
 
     status = val_imp_sec_ctx_args(minor_status,
@@ -133,7 +134,12 @@ gss_ctx_id_t *		context_handle;
      * call it.
      */
 
-    mech = gssint_get_mechanism (ctx->mech_type);
+    status = gssint_select_mech_type(minor_status, ctx->mech_type,
+				     &selected_mech);
+    if (status != GSS_S_COMPLETE)
+	goto error_out;
+
+    mech = gssint_get_mechanism(selected_mech);
     if (!mech) {
 	status = GSS_S_BAD_MECH;
 	goto error_out;
diff --git a/src/lib/gssapi/mechglue/g_init_sec_context.c b/src/lib/gssapi/mechglue/g_init_sec_context.c
index 5afea2d..aaae767 100644
--- a/src/lib/gssapi/mechglue/g_init_sec_context.c
+++ b/src/lib/gssapi/mechglue/g_init_sec_context.c
@@ -116,7 +116,7 @@ OM_uint32 *		time_rec;
     gss_union_cred_t	union_cred;
     gss_name_t		internal_name;
     gss_union_ctx_id_t	union_ctx_id;
-    gss_OID		mech_type = (gss_OID) req_mech_type;
+    gss_OID		selected_mech;
     gss_mechanism	mech;
     gss_cred_id_t	input_cred_handle;
 
@@ -136,8 +136,10 @@ OM_uint32 *		time_rec;
     if (status != GSS_S_COMPLETE)
 	return (status);
 
-    if (req_mech_type)
-	mech_type = (gss_OID)req_mech_type;
+    status = gssint_select_mech_type(minor_status, req_mech_type,
+				     &selected_mech);
+    if (status != GSS_S_COMPLETE)
+	return (status);
 
     union_name = (gss_union_name_t)target_name;
 
@@ -146,26 +148,23 @@ OM_uint32 *		time_rec;
      * mechanism.  If mech_type is NULL, set it to the resultant
      * mechanism
      */
-    mech = gssint_get_mechanism (mech_type);
+    mech = gssint_get_mechanism(selected_mech);
     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 &&
-	g_OID_equal(union_name->mech_type, mech_type)) {
+	g_OID_equal(union_name->mech_type, selected_mech)) {
 	internal_name = union_name->mech_name;
     } else {
-	if ((status = gssint_import_internal_name(minor_status, mech_type,
+	if ((status = gssint_import_internal_name(minor_status, selected_mech,
 						 union_name,
 						 &internal_name)) != GSS_S_COMPLETE)
 	    return (status);
@@ -185,7 +184,7 @@ OM_uint32 *		time_rec;
 	if (union_ctx_id == NULL)
 	    goto end;
 
-	if (generic_gss_copy_oid(&temp_minor_status, mech_type,
+	if (generic_gss_copy_oid(&temp_minor_status, selected_mech,
 				 &union_ctx_id->mech_type) != GSS_S_COMPLETE) {
 	    free(union_ctx_id);
 	    goto end;
@@ -202,7 +201,7 @@ OM_uint32 *		time_rec;
      * use the default credential.
      */
     union_cred = (gss_union_cred_t) claimant_cred_handle;
-    input_cred_handle = gssint_get_mechanism_cred(union_cred, mech_type);
+    input_cred_handle = gssint_get_mechanism_cred(union_cred, selected_mech);
 
     /*
      * now call the approprate underlying mechanism routine
@@ -213,7 +212,7 @@ OM_uint32 *		time_rec;
 	input_cred_handle,
 	&union_ctx_id->internal_ctx_id,
 	internal_name,
-	mech_type,
+	gssint_get_public_oid(selected_mech),
 	req_flags,
 	time_req,
 	input_chan_bindings,
@@ -245,7 +244,7 @@ end:
     if (union_name->mech_name == NULL ||
 	union_name->mech_name != internal_name) {
 	(void) gssint_release_internal_name(&temp_minor_status,
-					   mech_type, &internal_name);
+					    selected_mech, &internal_name);
     }
 
     return(status);
diff --git a/src/lib/gssapi/mechglue/g_inq_context.c b/src/lib/gssapi/mechglue/g_inq_context.c
index bb6d569..d3fb343 100644
--- a/src/lib/gssapi/mechglue/g_inq_context.c
+++ b/src/lib/gssapi/mechglue/g_inq_context.c
@@ -86,6 +86,7 @@ gss_inquire_context(
     gss_union_ctx_id_t	ctx;
     gss_mechanism	mech;
     OM_uint32		status, temp_minor;
+    gss_OID		actual_mech;
     gss_name_t localTargName = NULL, localSourceName = NULL;
 
     status = val_inq_ctx_args(minor_status,
@@ -116,7 +117,7 @@ gss_inquire_context(
 			(src_name ? &localSourceName : NULL),
 			(targ_name ? &localTargName : NULL),
 			lifetime_rec,
-			NULL,
+			&actual_mech,
 			ctx_flags,
 			locally_initiated,
 			opened);
@@ -157,8 +158,8 @@ gss_inquire_context(
         }
     }
 
-    /* spec says mech type must point to static storage */
     if (mech_type)
-	*mech_type = &mech->mech_type;
+	*mech_type = gssint_get_public_oid(actual_mech);
+
     return(GSS_S_COMPLETE);
 }
diff --git a/src/lib/gssapi/mechglue/g_inq_cred.c b/src/lib/gssapi/mechglue/g_inq_cred.c
index 7dab781..dc69c50 100644
--- a/src/lib/gssapi/mechglue/g_inq_cred.c
+++ b/src/lib/gssapi/mechglue/g_inq_cred.c
@@ -123,19 +123,17 @@ gss_OID_set *		mechanisms;
      */
 
     if(mechanisms != NULL) {
-	status = gss_create_empty_oid_set(minor_status, &mechs);
-	if (GSS_ERROR(status))
-	    goto error;
-
 	if (union_cred) {
-	    for (i = 0; i < union_cred->count; i++) {
-		status = gss_add_oid_set_member(minor_status,
-						&union_cred->mechs_array[i],
-						&mechs);
-		if (GSS_ERROR(status))
-		    goto error;
-	    }
+	    status = gssint_make_public_oid_set(minor_status,
+						union_cred->mechs_array,
+						union_cred->count, &mechs);
+	    if (GSS_ERROR(status))
+		goto error;
 	} else {
+	    status = gss_create_empty_oid_set(minor_status, &mechs);
+	    if (GSS_ERROR(status))
+		goto error;
+
 	    status = gss_add_oid_set_member(minor_status,
 					    &mech->mech_type, &mechs);
 	    if (GSS_ERROR(status))
@@ -172,6 +170,7 @@ gss_inquire_cred_by_mech(minor_status, cred_handle, mech_type, name,
     gss_mechanism	mech;
     OM_uint32		status, temp_minor_status;
     gss_name_t		internal_name;
+    gss_OID		selected_mech;
 
     if (minor_status != NULL)
 	*minor_status = 0;
@@ -182,14 +181,18 @@ gss_inquire_cred_by_mech(minor_status, cred_handle, mech_type, name,
     if (minor_status == NULL)
 	return (GSS_S_CALL_INACCESSIBLE_WRITE);
 
-    mech = gssint_get_mechanism (mech_type);
+    status = gssint_select_mech_type(minor_status, mech_type, &selected_mech);
+    if (status != GSS_S_COMPLETE)
+	return (status);
+
+    mech = gssint_get_mechanism(selected_mech);
     if (!mech)
 	return (GSS_S_BAD_MECH);
     if (!mech->gss_inquire_cred_by_mech)
 	return (GSS_S_BAD_BINDINGS);
 
     union_cred = (gss_union_cred_t) cred_handle;
-    mech_cred = gssint_get_mechanism_cred(union_cred, mech_type);
+    mech_cred = gssint_get_mechanism_cred(union_cred, selected_mech);
 
 #if 0
     if (mech_cred == NULL)
@@ -197,7 +200,7 @@ gss_inquire_cred_by_mech(minor_status, cred_handle, mech_type, name,
 #endif
 
     status = mech->gss_inquire_cred_by_mech(minor_status,
-					    mech_cred, mech_type,
+					    mech_cred, selected_mech,
 					    name ? &internal_name : NULL,
 					    initiator_lifetime,
 					    acceptor_lifetime, cred_usage);
diff --git a/src/lib/gssapi/mechglue/g_inq_names.c b/src/lib/gssapi/mechglue/g_inq_names.c
index 1a45701..b44fd6c 100644
--- a/src/lib/gssapi/mechglue/g_inq_names.c
+++ b/src/lib/gssapi/mechglue/g_inq_names.c
@@ -40,6 +40,7 @@ gss_OID_set *	name_types;
 
 {
     OM_uint32		status;
+    gss_OID		selected_mech = GSS_C_NO_OID;
     gss_mechanism	mech;
 
     /* Initialize outputs. */
@@ -63,14 +64,19 @@ gss_OID_set *	name_types;
      * call it.
      */
 
-    mech = gssint_get_mechanism (mechanism);
+    status = gssint_select_mech_type(minor_status, mechanism,
+				     &selected_mech);
+    if (status != GSS_S_COMPLETE)
+	return (status);
+
+    mech = gssint_get_mechanism(selected_mech);
 
     if (mech) {
 
 	if (mech->gss_inquire_names_for_mech) {
 	    status = mech->gss_inquire_names_for_mech(
 				minor_status,
-				mechanism,
+				selected_mech,
 				name_types);
 	    if (status != GSS_S_COMPLETE)
 		map_error(minor_status, mech);
diff --git a/src/lib/gssapi/mechglue/g_mech_invoke.c b/src/lib/gssapi/mechglue/g_mech_invoke.c
index cb9412e..0647cda 100644
--- a/src/lib/gssapi/mechglue/g_mech_invoke.c
+++ b/src/lib/gssapi/mechglue/g_mech_invoke.c
@@ -38,6 +38,7 @@ gssspi_mech_invoke (OM_uint32 *minor_status,
 		    gss_buffer_t value)
 {
     OM_uint32		status;
+    gss_OID		selected_mech = GSS_C_NO_OID;
     gss_mechanism	mech;
 
     if (minor_status == NULL)
@@ -50,13 +51,18 @@ gssspi_mech_invoke (OM_uint32 *minor_status,
      * call it.
      */
 
-    mech = gssint_get_mechanism (desired_mech);
+    status = gssint_select_mech_type(minor_status, desired_mech,
+				     &selected_mech);
+    if (status != GSS_S_COMPLETE)
+	return status;
+
+    mech = gssint_get_mechanism(selected_mech);
     if (mech == NULL || mech->gssspi_mech_invoke == NULL) {
 	return GSS_S_BAD_MECH;
     }
 
     status = mech->gssspi_mech_invoke(minor_status,
-				      desired_mech,
+				      gssint_get_public_oid(selected_mech),
 				      desired_object,
 				      value);
     if (status != GSS_S_COMPLETE)
diff --git a/src/lib/gssapi/mechglue/g_store_cred.c b/src/lib/gssapi/mechglue/g_store_cred.c
index a68a587..030c73f 100644
--- a/src/lib/gssapi/mechglue/g_store_cred.c
+++ b/src/lib/gssapi/mechglue/g_store_cred.c
@@ -143,6 +143,7 @@ gss_cred_usage_t		 *cred_usage_stored;
 	gss_cred_id_t		mech_cred;
 	gss_mechanism		mech;
 	gss_OID			dmech;
+	gss_OID			selected_mech;
 	int			i;
 
 	major_status = val_store_cred_args(minor_status,
@@ -167,7 +168,13 @@ gss_cred_usage_t		 *cred_usage_stored;
 
 	/* desired_mech != GSS_C_NULL_OID -> store one element */
 	if (desired_mech != GSS_C_NULL_OID) {
-		mech = gssint_get_mechanism(desired_mech);
+		major_status = gssint_select_mech_type(minor_status,
+						       desired_mech,
+						       &selected_mech);
+		if (major_status != GSS_S_COMPLETE)
+			return (major_status);
+
+		mech = gssint_get_mechanism(selected_mech);
 		if (mech == NULL)
 			return (GSS_S_BAD_MECH);
 
@@ -179,13 +186,13 @@ gss_cred_usage_t		 *cred_usage_stored;
 		    mech->gss_store_cred_into == NULL)
 			return (major_status);
 
-		mech_cred = gssint_get_mechanism_cred(union_cred, desired_mech);
+		mech_cred = gssint_get_mechanism_cred(union_cred, selected_mech);
 		if (mech_cred == GSS_C_NO_CREDENTIAL)
 			return (GSS_S_NO_CRED);
 
 		major_status = store_cred_fallback(minor_status, mech,
 						   mech_cred, cred_usage,
-						   desired_mech,
+						   selected_mech,
 						   overwrite_cred,
 						   default_cred, cred_store,
 						   elements_stored,
diff --git a/src/lib/gssapi/mechglue/gssd_pname_to_uid.c b/src/lib/gssapi/mechglue/gssd_pname_to_uid.c
index 7254c3a..4e7b644 100644
--- a/src/lib/gssapi/mechglue/gssd_pname_to_uid.c
+++ b/src/lib/gssapi/mechglue/gssd_pname_to_uid.c
@@ -123,6 +123,7 @@ gss_localname(OM_uint32 *minor,
     gss_mechanism mech;
     gss_union_name_t unionName;
     gss_name_t mechName = GSS_C_NO_NAME, mechNameP;
+    gss_OID selected_mech = GSS_C_NO_OID;
 
     if (localname != GSS_C_NO_BUFFER) {
 	localname->length = 0;
@@ -142,9 +143,12 @@ gss_localname(OM_uint32 *minor,
 
     unionName = (gss_union_name_t)pname;
 
-    if (mech_type != GSS_C_NO_OID)
-        mech = gssint_get_mechanism(mech_type);
-    else
+    if (mech_type != GSS_C_NO_OID) {
+        major = gssint_select_mech_type(minor, mech_type, &selected_mech);
+        if (major != GSS_S_COMPLETE)
+	    return major;
+        mech = gssint_get_mechanism(selected_mech);
+    } else
         mech = gssint_get_mechanism(unionName->mech_type);
 
     if (mech == NULL)


More information about the cvs-krb5 mailing list