+Sat Feb 24 16:19:30 1996 Theodore Y. Ts'o <tytso@dcl>
+
+ * 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 <epeisach@kangaroo.mit.edu>
* mglueP.h (gss_config): Change int fields to OM_uint32 to match
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;
* 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)
return(GSS_S_BAD_MECH);
}
+
#endif
#include <string.h>
+#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,
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;
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;
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
* 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);
}
}
* 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));
j = 0;
- for(i=0; i<desired_mechs->count; i++) {
+ for (i=0; i<desired_mechs->count; i++) {
if(creds_returned[i].available) {
creds->mechs_array[j].length =
/* 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) {
#endif
#include <string.h>
+#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,
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();
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
* 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);
}
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
+#include <errno.h>
+
extern gss_mechanism *__gss_mechs_array;
/*
}
+/*
+ * 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);
+}
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,
#endif
#include <string.h>
+#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,
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
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
} 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);
}
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;
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;
* 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 */
__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;
}
#include <stdlib.h>
#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,
{
gss_union_ctx_id_t ctx;
gss_mechanism mech;
- OM_uint32 status, temp_minor, temp_major;
+ OM_uint32 status, temp_minor;
gss_initialize();
/* 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,
}
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);
}
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);
-
-}
--- /dev/null
+/*
+ * 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 <stdlib.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#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;
+}
+
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);
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);
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);
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 */