g_mechname.c (gss_add_mech_name_type): Only mark a name-type as being
authorTheodore Tso <tytso@mit.edu>
Sat, 24 Feb 1996 23:45:13 +0000 (23:45 +0000)
committerTheodore Tso <tytso@mit.edu>
Sat, 24 Feb 1996 23:45:13 +0000 (23:45 +0000)
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

13 files changed:
src/lib/gssapi/mechglue/ChangeLog
src/lib/gssapi/mechglue/g_accept_sec_context.c
src/lib/gssapi/mechglue/g_acquire_cred.c
src/lib/gssapi/mechglue/g_compare_name.c
src/lib/gssapi/mechglue/g_glue.c
src/lib/gssapi/mechglue/g_imp_name.c
src/lib/gssapi/mechglue/g_init_sec_context.c
src/lib/gssapi/mechglue/g_initialize.c
src/lib/gssapi/mechglue/g_inquire_context.c
src/lib/gssapi/mechglue/g_mechname.c [new file with mode: 0644]
src/lib/gssapi/mechglue/g_rel_name.c
src/lib/gssapi/mechglue/g_rel_oid_set.c
src/lib/gssapi/mechglue/mglueP.h

index 8a70b6986280f24d45fd51d7554876b98dfe034b..c2a45cd0ad14ecfbbc552edfb2b9c80d4184c5ae 100644 (file)
@@ -1,3 +1,45 @@
+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
index c9cad6053f3d9d88c2d7fde35c3b9e4e395cef63..7fdc6f2212d51d2ce222e5b70a0b92a2095b5fe5 100644 (file)
@@ -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);
 }
+
index 0b601e8f376eb8ce9fc907a1f7ea14f4968db7af..dcc9329e8f8d32b2b8acdaf3679e4767db444eaf 100644 (file)
 #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,
@@ -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; i<desired_mechs->count; i++) {
+    for (i=0; i<desired_mechs->count; 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) {
index 23e8dc7c65f6553c45aedf63d52884c5c3ae4628..11d2cd66d0b37d464fb5058489ca3fb745f3bddd 100644 (file)
 #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,
@@ -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);
 }
index 3a751a4496548ce45d53b3d5a43068d85cb188bc..556d108e515bf4c62c4f79b004480a664944a793 100644 (file)
@@ -27,6 +27,8 @@
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
+#include <errno.h>
+
 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);
+}
index 637acfa573135b2c788408ba1ff9b31d2617ee4c..27cd09256d314ff4a7f7a44fe1ef8deb79c46b94 100644 (file)
@@ -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,
index b9520cb736dba5916ef2db9964507a343548a5be..2d54436bfea35168fb758692f08d54f71b491750 100644 (file)
 #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,
@@ -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);
 }
index 33e6a446c66c099db60e974d26abc21dc4e810ab..c92d73154e73d9a053ce49713a3b0cb17bcb1b27 100644 (file)
 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;
 }
 
index a0e52f017f25cd25382ddd6f22bff99e83e05d0b..26d9a9a95955e268767ec96d46aa603c20faccec 100644 (file)
 #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,
@@ -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 (file)
index 0000000..c013bdc
--- /dev/null
@@ -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 <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;
+}
+
index 493266e7c50826b4fefbcc0eab72f76867492b0c..1010304ad1855e1dbb55ddb4ccdb796f6fcfdd95 100644 (file)
@@ -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);
index 0f6fb43f8d4b6559b91b38334320f7b14d6320eb..caa1e13ac25be2d12a7aa2428cc1e987935925e6 100644 (file)
@@ -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);
index 12cf51112b40517384cff83df5336e53745026af..553064419ff8d01d99541064fe84f9026bc1184e 100644 (file)
@@ -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 */