From c981c53a4ce52a576c2e1d51a60a9fbccb60030f Mon Sep 17 00:00:00 2001 From: Theodore Tso Date: Sat, 24 Feb 1996 23:45:13 +0000 Subject: [PATCH] g_mechname.c (gss_add_mech_name_type): Only mark a name-type as being non-mechanism-specific if the mechanism doesn't match the type currently associated with the name-type. g_init_sec_context.c (gss_init_security_context): If we are using a mechanism-specific name, use the mechanism-specific name directly, instead of calling __gss_internal_import() on the external form of the name. If the mechanism_type is unspecified, use the type of the mechanism-specific name. If the mechanism_type is specified, it must match the type of the supplied name. g_acquire_cred.c (gss_acquire_cred): If we are acquiring credentials for a mechanism-specific name, use the name directly, instead of doing an __gss_internal_import() on the name. Also, if the desired_mechanisms oid is NULL, default to using the mechanism-type of the mechanism-specific name. g_compare_name.c (gss_compare_name): Add logic for comparing mechanism-specific names. g_accept_sec_context.c (gss_accept_sec_context): Use __gss_convert_name_to_union_name() to take the gss_name_t returned by the mechanism accept_sec_context(), and convert it into a mechanism-specific union name. g_inquire_context.c (gss_inquire_context): Removed local static function convert_name_to_union_name(), and changed references to it use the generalized __gss_convert_name_to_union_name() call. g_glue.c (__gss_convert_name_to_union_name): New function which takes gss_name_t returned by a particular mechanism, and converts it into a gss_union_name. g_rel_oid_set.c (gss_release_oid_set): Manually free the oids in an OID set, since the containing structure is allocated as an array. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7523 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/gssapi/mechglue/ChangeLog | 42 ++++++ .../gssapi/mechglue/g_accept_sec_context.c | 63 +-------- src/lib/gssapi/mechglue/g_acquire_cred.c | 133 +++++++++--------- src/lib/gssapi/mechglue/g_compare_name.c | 123 +++++++++++----- src/lib/gssapi/mechglue/g_glue.c | 67 +++++++++ src/lib/gssapi/mechglue/g_imp_name.c | 5 + src/lib/gssapi/mechglue/g_init_sec_context.c | 54 ++++--- src/lib/gssapi/mechglue/g_initialize.c | 47 +++++-- src/lib/gssapi/mechglue/g_inquire_context.c | 66 +-------- src/lib/gssapi/mechglue/g_mechname.c | 116 +++++++++++++++ src/lib/gssapi/mechglue/g_rel_name.c | 4 +- src/lib/gssapi/mechglue/g_rel_oid_set.c | 2 +- src/lib/gssapi/mechglue/mglueP.h | 7 + 13 files changed, 473 insertions(+), 256 deletions(-) create mode 100644 src/lib/gssapi/mechglue/g_mechname.c diff --git a/src/lib/gssapi/mechglue/ChangeLog b/src/lib/gssapi/mechglue/ChangeLog index 8a70b6986..c2a45cd0a 100644 --- a/src/lib/gssapi/mechglue/ChangeLog +++ b/src/lib/gssapi/mechglue/ChangeLog @@ -1,3 +1,45 @@ +Sat Feb 24 16:19:30 1996 Theodore Y. Ts'o + + * g_mechname.c (gss_add_mech_name_type): Only mark a name-type as + being non-mechanism-specific if the mechanism doesn't + match the type currently associated with the name-type. + + * g_init_sec_context.c (gss_init_security_context): If we are + using a mechanism-specific name, use the + mechanism-specific name directly, instead of calling + __gss_internal_import() on the external form of the name. + If the mechanism_type is unspecified, use the type of the + mechanism-specific name. If the mechanism_type is + specified, it must match the type of the supplied name. + + * g_acquire_cred.c (gss_acquire_cred): If we are acquiring + credentials for a mechanism-specific name, use the name + directly, instead of doing an __gss_internal_import() on + the name. Also, if the desired_mechanisms oid is NULL, + default to using the mechanism-type of the + mechanism-specific name. + + * g_compare_name.c (gss_compare_name): Add logic for comparing + mechanism-specific names. + + * g_accept_sec_context.c (gss_accept_sec_context): Use + __gss_convert_name_to_union_name() to take the gss_name_t + returned by the mechanism accept_sec_context(), and + convert it into a mechanism-specific union name. + + * g_inquire_context.c (gss_inquire_context): Removed local static + function convert_name_to_union_name(), and changed + references to it use the generalized + __gss_convert_name_to_union_name() call. + + * g_glue.c (__gss_convert_name_to_union_name): New function which + takes gss_name_t returned by a particular mechanism, and + converts it into a gss_union_name. + + * g_rel_oid_set.c (gss_release_oid_set): Manually free the oids in + an OID set, since the containing structure is allocated as + an array. + Sat Feb 24 12:21:03 1996 Ezra Peisach * mglueP.h (gss_config): Change int fields to OM_uint32 to match diff --git a/src/lib/gssapi/mechglue/g_accept_sec_context.c b/src/lib/gssapi/mechglue/g_accept_sec_context.c index c9cad6053..7fdc6f221 100644 --- a/src/lib/gssapi/mechglue/g_accept_sec_context.c +++ b/src/lib/gssapi/mechglue/g_accept_sec_context.c @@ -63,9 +63,6 @@ gss_cred_id_t * delegated_cred_handle; gss_union_cred_t union_cred; gss_cred_id_t input_cred_handle = GSS_C_NO_CREDENTIAL; gss_name_t internal_name; - gss_buffer_desc external_name_desc; - gss_buffer_t external_name = &external_name_desc; - gss_OID name_type; gss_OID_desc token_mech_type_desc; gss_OID token_mech_type = &token_mech_type_desc; gss_mechanism mech; @@ -169,64 +166,17 @@ gss_cred_id_t * delegated_cred_handle; * then call gss_import_name() to create * the union name struct cast to src_name */ - - if(src_name != NULL && status == GSS_S_COMPLETE) { - temp_status = __gss_display_internal_name ( - &temp_minor_status, - &mech->mech_type, - internal_name, - external_name, - &name_type); - + if (src_name != NULL && status == GSS_S_COMPLETE) { + temp_status = __gss_convert_name_to_union_name( + &temp_minor_status, mech, internal_name, src_name); if (temp_status != GSS_S_COMPLETE) { - - /* - * this should never happen, since we just got - * the name from the mechanism gss_accept_sec_context - * call. However, things that can't happen often do. - */ if (minor_status) *minor_status = temp_minor_status; - gss_release_buffer( - &temp_minor_status, - output_token); + gss_release_buffer(&temp_minor_status, output_token); __gss_release_internal_name(&temp_minor_status, - &mech->mech_type, - &internal_name); - return(GSS_S_FAILURE); - } - - /* now create the union name */ - - temp_status = gss_import_name( - &temp_minor_status, - external_name, - name_type, - src_name); - - if(temp_status != GSS_S_COMPLETE) { - if (minor_status) - *minor_status = temp_minor_status; - gss_release_buffer( - &temp_minor_status, - output_token); - __gss_release_internal_name( - &temp_minor_status, - &mech->mech_type, - &internal_name); - gss_release_buffer( - &temp_minor_status, - external_name); - return(GSS_S_FAILURE); + &mech->mech_type, &internal_name); + return (temp_status); } - - __gss_release_internal_name( - &temp_minor_status, - &mech->mech_type, - &internal_name); - gss_release_buffer( - &temp_minor_status, - external_name); } if(*context_handle == GSS_C_NO_CONTEXT) @@ -237,3 +187,4 @@ gss_cred_id_t * delegated_cred_handle; return(GSS_S_BAD_MECH); } + diff --git a/src/lib/gssapi/mechglue/g_acquire_cred.c b/src/lib/gssapi/mechglue/g_acquire_cred.c index 0b601e8f3..dcc9329e8 100644 --- a/src/lib/gssapi/mechglue/g_acquire_cred.c +++ b/src/lib/gssapi/mechglue/g_acquire_cred.c @@ -32,6 +32,10 @@ #endif #include +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + OM_uint32 gss_acquire_cred(minor_status, desired_name, @@ -52,9 +56,9 @@ gss_OID_set * actual_mechs; OM_uint32 * time_rec; { - OM_uint32 status, temp_status, - temp_minor_status, temp_time_rec = ~0; - int i, j, creds_acquired = 0; + OM_uint32 status, temp_minor_status, temp_time_rec = ~0; + unsigned int i, j, creds_acquired = 0; + int k; gss_union_name_t union_name; gss_name_t internal_name; gss_union_cred_t creds; @@ -98,12 +102,17 @@ OM_uint32 * time_rec; union_name = (gss_union_name_t) desired_name; /* - * if desired_mechs equals GSS_C_NULL_OID_SET, set it to the - * first entry in the mechs_array. + * if desired_mechs equals GSS_C_NULL_OID_SET, then pick an + * appropriate default. */ - if(desired_mechs == GSS_C_NULL_OID_SET) { - if ((mech = __gss_get_mechanism (NULL)) == NULL) + /* + * If union_name->mech_type is NULL then we get the default + * mechanism; otherwise, we get the mechanism for the + * mechanism-specific name. + */ + mech = __gss_get_mechanism(union_name->mech_type); + if (mech == NULL) return (GSS_S_BAD_MECH); desired_mechs = &default_OID_set; @@ -111,7 +120,7 @@ OM_uint32 * time_rec; default_OID_set.elements = &default_OID; default_OID.length = mech->mech_type.length; default_OID.elements = mech->mech_type.elements; - } + } /* * Now allocate the creds returned array. There is one element @@ -128,63 +137,59 @@ OM_uint32 * time_rec; * creds_returned->available as 1 and call the mechanism * specific gss_acquire_cred(), placing the returned cred in * creds_returned->cred. If not, mark creds_returned->available as - * 0. */ - - for(j=0; j < desired_mechs->count; j++) { - + * 0. + */ + status = GSS_S_BAD_MECH; + for (j=0; j < desired_mechs->count; j++) { creds_returned[j].available = 0; mech = __gss_get_mechanism (&desired_mechs->elements[j]); - if (mech && mech->gss_acquire_cred) { - - /* - * we first have to import the external name in - * union_name so it can be used in the - * gss_acquire_cred() call. - */ - - if ((status = __gss_import_internal_name( - minor_status, - &mech->mech_type, - union_name, - &internal_name))) { - status = GSS_S_BAD_NAME; + if (!mech || !mech->gss_acquire_cred) + continue; + /* + * If this is a mechanism-specific name, then only use the + * mechanism of the name. + */ + if (union_name->mech_type && !g_OID_equal(union_name->mech_type, + &mech->mech_type)) + continue; + /* + * If this is not a mechanism-specific name, then we need to + * do an import the external name in union_name first. + */ + if (!union_name->mech_type) { + if (__gss_import_internal_name(&temp_minor_status, + &mech->mech_type, + union_name, &internal_name)) { continue; } - - status = mech->gss_acquire_cred( - mech->context, - minor_status, - internal_name, - time_req, - desired_mechs, - cred_usage, - &creds_returned[j].cred, - NULL, - &temp_time_rec); + } else + internal_name = union_name->mech_name; - if ((temp_status = __gss_release_internal_name( - &temp_minor_status, - &mech->mech_type, - &internal_name))) { - /* Not much we can do here, really... Just keep on going */ - ; + status = mech->gss_acquire_cred(mech->context, minor_status, + internal_name, time_req, + desired_mechs, cred_usage, + &creds_returned[j].cred, + NULL, &temp_time_rec); + /* + * Add this into the creds_returned structure, if we got + * a good credential for this mechanism. + */ + if (status == GSS_S_COMPLETE) { + if (time_rec) { + *time_rec = *time_rec > temp_time_rec ? + temp_time_rec : *time_rec; + temp_time_rec = *time_rec; } - /* - * Add this into the creds_returned structure, if we got - * a good credential for this mechanism. - */ - if(status == GSS_S_COMPLETE) { - if (time_rec) { - *time_rec = *time_rec > temp_time_rec ? - temp_time_rec : *time_rec; - temp_time_rec = *time_rec; - } - - creds_returned[j].available = 1; - creds_acquired++; - } + creds_returned[j].available = 1; + creds_acquired++; + } + + if (!union_name->mech_type) { + (void) __gss_release_internal_name(&temp_minor_status, + &mech->mech_type, + &internal_name); } } @@ -194,10 +199,9 @@ OM_uint32 * time_rec; * no credentials found, return an error. Also, allocate the * actual_mechs data. */ - - if(creds_acquired == 0) { + if (creds_acquired == 0) { free (creds_returned); - return(GSS_S_BAD_MECH); + return (status); } creds = (gss_union_cred_t) malloc(sizeof(gss_union_cred_desc)); @@ -227,7 +231,7 @@ OM_uint32 * time_rec; j = 0; - for(i=0; icount; i++) { + for (i=0; icount; i++) { if(creds_returned[i].available) { creds->mechs_array[j].length = @@ -275,9 +279,10 @@ OM_uint32 * time_rec; /* This really shouldn't ever fail, but just in case.... */ - for(i=0; i < creds->count; i++) { - free(creds->mechs_array[i].elements); - if (actual_mechs) free((*actual_mechs)->elements[i].elements); + for (k=0; k < creds->count; k++) { + free(creds->mechs_array[k].elements); + if (actual_mechs) + free((*actual_mechs)->elements[k].elements); } if (actual_mechs) { diff --git a/src/lib/gssapi/mechglue/g_compare_name.c b/src/lib/gssapi/mechglue/g_compare_name.c index 23e8dc7c6..11d2cd66d 100644 --- a/src/lib/gssapi/mechglue/g_compare_name.c +++ b/src/lib/gssapi/mechglue/g_compare_name.c @@ -33,6 +33,10 @@ #endif #include +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + OM_uint32 gss_compare_name (minor_status, name1, @@ -45,8 +49,10 @@ gss_name_t name2; int * name_equal; { - OM_uint32 status; + OM_uint32 major_status, temp_minor; gss_union_name_t union_name1, union_name2; + gss_mechanism mech; + gss_name_t internal_name; gss_initialize(); @@ -56,7 +62,52 @@ int * name_equal; return GSS_S_BAD_NAME; } + union_name1 = (gss_union_name_t) name1; + union_name2 = (gss_union_name_t) name2; + /* + * Try our hardest to make union_name1 be the mechanism-specific + * name. (Of course we can't if both names aren't + * mechanism-specific.) + */ + if (union_name1->mech_type == 0) { + union_name1 = (gss_union_name_t) name2; + union_name2 = (gss_union_name_t) name1; + } + /* + * If union_name1 is mechanism specific, then fetch its mechanism + * information. + */ + if (union_name1->mech_type) { + mech = __gss_get_mechanism (union_name1->mech_type); + if (!mech) + return (GSS_S_BAD_MECH); + if (!mech->gss_compare_name) + return (GSS_S_BAD_BINDINGS); + } + + if (name_equal == NULL) + return GSS_S_COMPLETE; + + *name_equal = 0; /* Default to *not* equal.... */ + + /* + * First case... both names are mechanism-specific + */ + if (union_name1->mech_type && union_name2->mech_type) { + if (!g_OID_equal(union_name1->mech_type, union_name2->mech_type)) + return (GSS_S_COMPLETE); + if ((union_name1->mech_name == 0) || (union_name2->mech_name == 0)) + /* should never happen */ + return (GSS_S_BAD_NAME); + return (mech->gss_compare_name(mech->context, minor_status, + union_name1->mech_name, + union_name2->mech_name, name_equal)); + + } + /* + * Second case... both names are NOT mechanism specific. + * * All we do here is make sure the two name_types are equal and then * that the external_names are equal. Note the we do not take care * of the case where two different external names map to the same @@ -64,41 +115,43 @@ int * name_equal; * know what mechanism to use for calling the underlying * gss_import_name(). */ - - union_name1 = (gss_union_name_t) name1; - union_name2 = (gss_union_name_t) name2; - - if(name_equal != NULL) + if (!union_name1->mech_type && !union_name2->mech_type) { + if (!g_OID_equal(union_name1->name_type, union_name2->name_type)) + return (GSS_S_COMPLETE); + if ((union_name1->external_name->length != + union_name2->external_name->length) || + (memcmp(union_name1->external_name->value, + union_name2->external_name->value, + union_name1->external_name->length) != 0)) + return (GSS_S_COMPLETE); *name_equal = 1; - else - return(GSS_S_COMPLETE); - - status = GSS_S_COMPLETE; - - do { - if((union_name1->name_type->length != - union_name2->name_type->length) - || - (memcmp(union_name1->name_type->elements, - union_name2->name_type->elements, - union_name1->name_type->length) != 0)) { - - *name_equal = 0; - break; - } - - if((union_name1->external_name->length != - union_name2->external_name->length) - || - (memcmp(union_name1->external_name->value, - union_name2->external_name->value, - union_name1->external_name->length) != 0)) { - - *name_equal = 0; - break; - } + return (GSS_S_COMPLETE); + } - } while (0); + /* + * Final case... one name is mechanism specific, the other isn't. + * + * We attempt to convert the general name to the mechanism type of + * the mechanism-specific name, and then do the compare. If we + * can't import the general name, then we return that the name is + * _NOT_ equal. + */ + if (union_name2->mech_type) { + /* We make union_name1 the mechanism specific name. */ + union_name1 = (gss_union_name_t) name2; + union_name2 = (gss_union_name_t) name1; + } + major_status = __gss_import_internal_name(minor_status, + union_name1->mech_type, + union_name2, + &internal_name); + if (major_status != GSS_S_COMPLETE) + return (GSS_S_COMPLETE); + major_status = mech->gss_compare_name(mech->context, minor_status, + union_name1->mech_name, + internal_name, name_equal); + __gss_release_internal_name(&temp_minor, union_name1->mech_type, + &internal_name); + return (major_status); - return(status); } diff --git a/src/lib/gssapi/mechglue/g_glue.c b/src/lib/gssapi/mechglue/g_glue.c index 3a751a449..556d108e5 100644 --- a/src/lib/gssapi/mechglue/g_glue.c +++ b/src/lib/gssapi/mechglue/g_glue.c @@ -27,6 +27,8 @@ #ifdef HAVE_STDLIB_H #include #endif +#include + extern gss_mechanism *__gss_mechs_array; /* @@ -210,3 +212,68 @@ gss_name_t *internal_name; } +/* + * This function converts an internal gssapi name to a union gssapi + * name. Note that internal_name should be considered "consumed" by + * this call, whether or not we return an error. + */ +OM_uint32 __gss_convert_name_to_union_name(minor_status, mech, + internal_name, external_name) + OM_uint32 *minor_status; + gss_mechanism mech; + gss_name_t internal_name; + gss_name_t *external_name; +{ + OM_uint32 major_status,tmp; + gss_union_name_t union_name; + + union_name = (gss_union_name_t) malloc (sizeof(gss_union_name_desc)); + if (!union_name) { + *minor_status = ENOMEM; + goto allocation_failure; + } + union_name->mech_type = 0; + union_name->mech_name = internal_name; + union_name->name_type = 0; + union_name->external_name = 0; + + major_status = generic_gss_copy_oid(minor_status, &mech->mech_type, + &union_name->mech_type); + if (major_status != GSS_S_COMPLETE) + goto allocation_failure; + + union_name->external_name = + (gss_buffer_t) malloc(sizeof(gss_buffer_desc)); + if (!union_name->external_name) { + *minor_status = ENOMEM; + goto allocation_failure; + } + + major_status = mech->gss_display_name(mech->context, minor_status, + internal_name, + union_name->external_name, + &union_name->name_type); + if (major_status != GSS_S_COMPLETE) + goto allocation_failure; + + *external_name = union_name; + return (GSS_S_COMPLETE); + +allocation_failure: + if (union_name) { + if (union_name->external_name) { + if (union_name->external_name->value) + free(union_name->external_name->value); + free(union_name->external_name); + } + if (union_name->name_type) + gss_release_oid(&tmp, &union_name->name_type); + if (union_name->mech_name) + __gss_release_internal_name(minor_status, union_name->mech_type, + &union_name->mech_name); + if (union_name->mech_type) + gss_release_oid(&tmp, &union_name->mech_type); + free(union_name); + } + return (major_status); +} diff --git a/src/lib/gssapi/mechglue/g_imp_name.c b/src/lib/gssapi/mechglue/g_imp_name.c index 637acfa57..27cd09256 100644 --- a/src/lib/gssapi/mechglue/g_imp_name.c +++ b/src/lib/gssapi/mechglue/g_imp_name.c @@ -116,6 +116,11 @@ gss_name_t * output_name; if (major_status != GSS_S_COMPLETE) goto allocation_failure; + /* + * See if this is a mechanism-specific name. If so, let's import + * it now so we can get any error messages, and to avoid trouble + * later... + */ mech = gss_find_mechanism_from_name_type(input_name_type); if (mech) { major_status = generic_gss_copy_oid(minor_status, mech, diff --git a/src/lib/gssapi/mechglue/g_init_sec_context.c b/src/lib/gssapi/mechglue/g_init_sec_context.c index b9520cb73..2d54436bf 100644 --- a/src/lib/gssapi/mechglue/g_init_sec_context.c +++ b/src/lib/gssapi/mechglue/g_init_sec_context.c @@ -32,6 +32,10 @@ #endif #include +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + OM_uint32 gss_init_sec_context (minor_status, claimant_cred_handle, @@ -73,6 +77,16 @@ OM_uint32 FAR * time_rec; if (context_handle == NULL) return GSS_S_NO_CONTEXT; + + union_name = (gss_union_name_t) target_name; + + /* + * 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; /* * obtain the gss mechanism information for the requested @@ -86,19 +100,21 @@ OM_uint32 FAR * time_rec; if (mech_type == GSS_C_NULL_OID) mech_type = &mech->mech_type; - /* - * Get the internal name for the mechanism requested from - * the supplied target name. + /* + * 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. */ - - union_name = (gss_union_name_t) target_name; - - if ((temp_status = __gss_import_internal_name ( - minor_status, - mech_type, - union_name, - &internal_name))) - return (GSS_S_BAD_NAME); + if (union_name->mech_type) { + if (!g_OID_equal(union_name->mech_type, mech_type)) + return (GSS_S_BAD_MECH); + internal_name = union_name->mech_name; + } else { + if ((temp_status = __gss_import_internal_name(minor_status, mech_type, + union_name, + &internal_name))) + return (GSS_S_BAD_NAME); + } /* * if context_handle is GSS_C_NO_CONTEXT, allocate a union context @@ -156,16 +172,10 @@ OM_uint32 FAR * time_rec; } else status = GSS_S_BAD_BINDINGS; - temp_status = __gss_release_internal_name( - &temp_minor_status, - mech_type, - &internal_name); - - if (temp_status != GSS_S_COMPLETE) { - if (minor_status) - *minor_status = temp_minor_status; - return(GSS_S_BAD_NAME); + if (!union_name->mech_type) { + (void) __gss_release_internal_name(&temp_minor_status, + mech_type, &internal_name); } - + return(status); } diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c index 33e6a446c..c92d73154 100644 --- a/src/lib/gssapi/mechglue/g_initialize.c +++ b/src/lib/gssapi/mechglue/g_initialize.c @@ -44,6 +44,10 @@ static void solaris_initialize (void); #endif /* USE_SOLARIS_SHARED_LIBRARIES */ +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + extern gss_mechanism krb5_gss_initialize(); static int _gss_initialized = 0; @@ -60,8 +64,10 @@ gss_mechanism *__gss_mechs_array = NULL; static OM_uint32 add_mechanism (gss_mechanism mech, int replace) { - gss_mechanism *temp_array; - int i; + gss_mechanism * temp_array; + gss_OID_set mech_names; + OM_uint32 minor_status, major_status; + unsigned int i; if (mech == NULL) return GSS_S_COMPLETE; @@ -81,19 +87,16 @@ add_mechanism (gss_mechanism mech, int replace) * entry for this OID */ for (i=0; __gss_mechs_array[i]->mech_type.length != 0; i++) { - if ((__gss_mechs_array[i]->mech_type.length == - mech->mech_type.length) && - (memcmp (__gss_mechs_array[i]->mech_type.elements, - mech->mech_type.elements, - mech->mech_type.length) == 0)) { - - /* We found a match. Replace it? */ - if (!replace) - return GSS_S_FAILURE; - - __gss_mechs_array[i] = mech; - return GSS_S_COMPLETE; - } + if (!g_OID_equal(&__gss_mechs_array[i]->mech_type, + &mech->mech_type)) + continue; + + /* We found a match. Replace it? */ + if (!replace) + return GSS_S_FAILURE; + + __gss_mechs_array[i] = mech; + return GSS_S_COMPLETE; } /* we didn't find it -- add it to the end of the __gss_mechs_array */ @@ -108,6 +111,20 @@ add_mechanism (gss_mechanism mech, int replace) __gss_mechs_array = temp_array; + /* + * OK, now let's register all of the name types this mechanism + * knows how to deal with. + */ + major_status = gss_inquire_names_for_mech(&minor_status, &mech->mech_type, + &mech_names); + if (major_status != GSS_S_COMPLETE) + return (GSS_S_COMPLETE); + for (i=0; i < mech_names->count; i++) { + gss_add_mech_name_type(&minor_status, &mech_names->elements[i], + &mech->mech_type); + } + (void) gss_release_oid_set(&minor_status, &mech_names); + return GSS_S_COMPLETE; } diff --git a/src/lib/gssapi/mechglue/g_inquire_context.c b/src/lib/gssapi/mechglue/g_inquire_context.c index a0e52f017..26d9a9a95 100644 --- a/src/lib/gssapi/mechglue/g_inquire_context.c +++ b/src/lib/gssapi/mechglue/g_inquire_context.c @@ -32,13 +32,6 @@ #include #endif -static OM_uint32 -convert_name_to_union_name( - gss_mechanism mech, - OM_uint32 *minor_status, - gss_name_t * internal_name); - - /* Last argument new for V2 */ OM_uint32 gss_inquire_context( minor_status, @@ -65,7 +58,7 @@ int * open; { gss_union_ctx_id_t ctx; gss_mechanism mech; - OM_uint32 status, temp_minor, temp_major; + OM_uint32 status, temp_minor; gss_initialize(); @@ -106,7 +99,8 @@ int * open; /* need to convert names */ if (src_name) { - status = convert_name_to_union_name(mech, minor_status, src_name); + status = __gss_convert_name_to_union_name(minor_status, mech, + *src_name, src_name); if (status != GSS_S_COMPLETE) { (void) mech->gss_release_name(mech->context, @@ -122,11 +116,10 @@ int * open; } if (targ_name) { - status = convert_name_to_union_name(mech, minor_status, targ_name); + status = __gss_convert_name_to_union_name(minor_status, mech, + *targ_name, targ_name); if (status != GSS_S_COMPLETE) { - (void) mech->gss_release_name(mech->context, - &temp_minor, targ_name); if (mech_type) { gss_release_oid(&temp_minor, mech_type); } @@ -137,52 +130,3 @@ int * open; return(GSS_S_COMPLETE); } -static OM_uint32 -convert_name_to_union_name( - mech, - minor_status, - internal_name) -gss_mechanism mech; -OM_uint32 *minor_status; -gss_name_t * internal_name; - -{ - OM_uint32 status; - gss_OID name_type; - gss_union_name_t union_name; - - union_name = (gss_union_name_t) malloc (sizeof(gss_union_name_desc)); - if (!union_name) - return (GSS_S_FAILURE); - - union_name->external_name = - (gss_buffer_t) malloc(sizeof(gss_buffer_desc)); - - if (!union_name->external_name) { - free(union_name); - return (GSS_S_FAILURE); - } - - status = mech->gss_display_name( - mech->context, - minor_status, - *internal_name, - union_name->external_name, - &union_name->name_type); - - if (status != GSS_S_COMPLETE) { - free(union_name->external_name); - free(union_name); - return (GSS_S_FAILURE); - } - - status = mech->gss_release_name( - mech->context, - minor_status, - internal_name); - - *internal_name = union_name; - - return (GSS_S_COMPLETE); - -} diff --git a/src/lib/gssapi/mechglue/g_mechname.c b/src/lib/gssapi/mechglue/g_mechname.c new file mode 100644 index 000000000..c013bdc15 --- /dev/null +++ b/src/lib/gssapi/mechglue/g_mechname.c @@ -0,0 +1,116 @@ +/* + * g_mechname.c --- registry of mechanism-specific name types + * + * This file contains a registry of mechanism-specific name types. It + * is used to determine which name types not should be lazy evaluated, + * but rather evaluated on the spot. + */ + +#include "mglueP.h" +#ifdef HAVE_STDLIB_H +#include +#endif + +#include +#include +#include + +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + +static gss_mech_spec_name name_list = NULL; + +/* + * generic searching helper function. + */ +static gss_mech_spec_name search_mech_spec(name_type) + gss_OID name_type; +{ + gss_mech_spec_name p; + + for (p = name_list; p; p = p->next) { + if (g_OID_equal(name_type, p->name_type)) + return p; + } + return NULL; +} + +/* + * Given a name_type, if it is specific to a mechanism, return the + * mechanism OID. Otherwise, return NULL. + */ +gss_OID gss_find_mechanism_from_name_type(name_type) + gss_OID name_type; +{ + gss_mech_spec_name p; + + p = search_mech_spec(name_type); + if (!p) + return NULL; + return p->mech; +} + +/* + * This function adds a (name_type, mechanism) pair to the + * mechanism-specific name type registry. If an entry for the + * name_type already exists, then zero out the mechanism entry. + * Otherwise, enter the pair into the registry. + */ +OM_uint32 +gss_add_mech_name_type(minor_status, name_type, mech) + OM_uint32 *minor_status; + gss_OID name_type; + gss_OID mech; +{ + OM_uint32 major_status, tmp; + gss_mech_spec_name p; + + p = search_mech_spec(name_type); + if (p) { + /* + * We found an entry for this name type; mark it as not being + * a mechanism-specific name type. + */ + if (p->mech) { + if (!g_OID_equal(mech, p->mech)) { + generic_gss_release_oid(minor_status, &p->mech); + p->mech = 0; + } + } + return GSS_S_COMPLETE; + } + p = malloc(sizeof(gss_mech_spec_name_desc)); + if (!p) { + *minor_status = ENOMEM; + goto allocation_failure; + } + p->name_type = 0; + p->mech = 0; + + major_status = generic_gss_copy_oid(minor_status, name_type, + &p->name_type); + if (major_status) + goto allocation_failure; + major_status = generic_gss_copy_oid(minor_status, mech, + &p->mech); + if (major_status) + goto allocation_failure; + + p->next = name_list; + p->prev = 0; + name_list = p; + + return GSS_S_COMPLETE; + +allocation_failure: + if (p) { + if (p->mech) + generic_gss_release_oid(&tmp, &p->mech); + if (p->name_type) + generic_gss_release_oid(&tmp, &p->name_type); + free(p); + } + return GSS_S_FAILURE; +} + diff --git a/src/lib/gssapi/mechglue/g_rel_name.c b/src/lib/gssapi/mechglue/g_rel_name.c index 493266e7c..1010304ad 100644 --- a/src/lib/gssapi/mechglue/g_rel_name.c +++ b/src/lib/gssapi/mechglue/g_rel_name.c @@ -60,7 +60,7 @@ gss_name_t * input_name; return GSS_S_BAD_NAME; if (union_name->name_type) - generic_gss_release_oid(minor_status, &union_name->name_type); + gss_release_oid(minor_status, &union_name->name_type); free(union_name->external_name->value); free(union_name->external_name); @@ -68,7 +68,7 @@ gss_name_t * input_name; if (union_name->mech_type) { __gss_release_internal_name(minor_status, union_name->mech_type, &union_name->mech_name); - generic_gss_release_oid(minor_status, &union_name->mech_type); + gss_release_oid(minor_status, &union_name->mech_type); } free(union_name); diff --git a/src/lib/gssapi/mechglue/g_rel_oid_set.c b/src/lib/gssapi/mechglue/g_rel_oid_set.c index 0f6fb43f8..caa1e13ac 100644 --- a/src/lib/gssapi/mechglue/g_rel_oid_set.c +++ b/src/lib/gssapi/mechglue/g_rel_oid_set.c @@ -52,7 +52,7 @@ gss_OID_set * set; for (index=0; index<(*set)->count; index++) { oid = &(*set)->elements[index]; - gss_release_oid(&temp_minor, &oid); + free(oid->elements); } free((*set)->elements); free(*set); diff --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h index 12cf51112..553064419 100644 --- a/src/lib/gssapi/mechglue/mglueP.h +++ b/src/lib/gssapi/mechglue/mglueP.h @@ -343,6 +343,13 @@ PROTOTYPE((OM_uint32 *, gss_OID, gss_name_t, OM_uint32 __gss_release_internal_name PROTOTYPE((OM_uint32 *, gss_OID, gss_name_t *)); +OM_uint32 __gss_convert_name_to_union_name +PROTOTYPE((OM_uint32 *, /* minor_status */ + gss_mechanism, /* mech */ + gss_name_t, /* internal_name */ + gss_name_t * /* external_name */ + )); + OM_uint32 generic_gss_release_oid PROTOTYPE( (OM_uint32 *, /* minor_status */ gss_OID * /* oid */ -- 2.26.2