1   /*
   2    * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
   3    * Use is subject to license terms.
   4    */
   5   
   6 | #pragma ident        "@(#)g_compare_name.c        1.17        04/09/08 SMI"
   6 | #pragma ident        "@(#)g_compare_name.c        1.16        04/02/23 SMI"
   7   
   8   /*
   9    *  glue routine for gss_compare_name
  10    *
  11    */
  12   
  13   #include <mechglueP.h>
  14   #ifdef HAVE_STDLIB_H
  15   #include <stdlib.h>
  16   #endif
  17   #include <string.h>
  18   
  19   OM_uint32
  20   gss_compare_name(minor_status,
  21                           name1,
  22                           name2,
  23                           name_equal)
  24   
  25   OM_uint32 *minor_status;
  26   const gss_name_t name1;
  27   const gss_name_t name2;
  28   int *name_equal;
  29   
  30   {
  31           OM_uint32                major_status, temp_minor;
  32           gss_union_name_t        union_name1, union_name2;
  33           gss_mechanism                mech;
  34           gss_name_t                internal_name;
  35   
  36 |         gss_initialize();
  36 |         if (minor_status == NULL)
  37 +                 return (GSS_S_CALL_INACCESSIBLE_WRITE);
  38 +         *minor_status = 0;
  39   
  38 |         if (name1 == 0 || name2 == 0) {
  39 |                 if (name_equal)
  40 |         if (name1 == 0 || name2 == 0)
  41 |                 return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
  40 -                         *name_equal = 0;
  41 -                 return (GSS_S_BAD_NAME);
  42 -         }
  42   
  43 +         if (name_equal == NULL)
  44 +                 return (GSS_S_CALL_INACCESSIBLE_WRITE);
  45 + 
  46           union_name1 = (gss_union_name_t)name1;
  47           union_name2 = (gss_union_name_t)name2;
  48           /*
  49            * Try our hardest to make union_name1 be the mechanism-specific
  50            * name.  (Of course we can't if both names aren't
  51            * mechanism-specific.)
  52            */
  53           if (union_name1->mech_type == 0) {
  54                   union_name1 = (gss_union_name_t)name2;
  55                   union_name2 = (gss_union_name_t)name1;
  56           }
  57           /*
  58            * If union_name1 is mechanism specific, then fetch its mechanism
  59            * information.
  60            */
  61           if (union_name1->mech_type) {
  62                   mech = __gss_get_mechanism(union_name1->mech_type);
  63                   if (!mech)
  64                           return (GSS_S_BAD_MECH);
  65                   if (!mech->gss_compare_name)
  64 |                         return (GSS_S_BAD_BINDINGS);
  66 |                         return (GSS_S_UNAVAILABLE);
  67           }
  67 -         if (name_equal == NULL)
  68 -                 return GSS_S_COMPLETE;
  69 - 
  68   
  69           *name_equal = 0;        /* Default to *not* equal.... */
  70   
  71           /*
  72            * First case... both names are mechanism-specific
  73            */
  74           if (union_name1->mech_type && union_name2->mech_type) {
  75                   if (!g_OID_equal(union_name1->mech_type,
  76                                           union_name2->mech_type))
  77                           return (GSS_S_COMPLETE);
  78                   if ((union_name1->mech_name == 0) ||
  79                           (union_name2->mech_name == 0))
  80                           /* should never happen */
  81                           return (GSS_S_BAD_NAME);
  82                   return (mech->gss_compare_name(mech->context, minor_status,
  83                                                           union_name1->mech_name,
  84                                                           union_name2->mech_name,
  85                                                           name_equal));
  86           }
  87   
  88           /*
  89            * Second case... both names are NOT mechanism specific.
  90            *
  91            * All we do here is make sure the two name_types are equal and then
  92            * that the external_names are equal. Note the we do not take care
  93            * of the case where two different external names map to the same
  94            * internal name. We cannot determine this, since we as yet do not
  95            * know what mechanism to use for calling the underlying
  96            * gss_import_name().
  97            */
  98           if (!union_name1->mech_type && !union_name2->mech_type) {
 100 |                 if (!g_OID_equal(union_name1->name_type, union_name2->name_type))
  99 |                 /*
 100 +                  * Second case, first sub-case... one name has null
 101 +                  * name_type, the other doesn't.
 102 +                  *
 103 +                  * Not knowing a mech_type we can't import the name with
 104 +                  * null name_type so we can't compare.
 105 +                  */
 106 +                 if ((union_name1->name_type == GSS_C_NULL_OID &&
 107 +                     union_name2->name_type != GSS_C_NULL_OID) ||
 108 +                     (union_name1->name_type != GSS_C_NULL_OID &&
 109 +                     union_name2->name_type == GSS_C_NULL_OID))
 110                           return (GSS_S_COMPLETE);
 111 +                 /*
 112 +                  * Second case, second sub-case... both names have
 113 +                  * name_types, but they are different.
 114 +                  */
 115 +                 if ((union_name1->name_type != GSS_C_NULL_OID &&
 116 +                     union_name2->name_type != GSS_C_NULL_OID) &&
 117 +                     !g_OID_equal(union_name1->name_type,
 118 +                                         union_name2->name_type))
 119 +                         return (GSS_S_COMPLETE);
 120 +                 /*
 121 +                  * Second case, third sub-case... both names have equal
 122 +                  * name_types (and both have no mech_types) so we just
 123 +                  * compare the external_names.
 124 +                  */
 125                   if ((union_name1->external_name->length !=
 126                           union_name2->external_name->length) ||
 127                           (memcmp(union_name1->external_name->value,
 128                                   union_name2->external_name->value,
 129                                   union_name1->external_name->length) != 0))
 130                           return (GSS_S_COMPLETE);
 131                   *name_equal = 1;
 132                   return (GSS_S_COMPLETE);
 133           }
 134   
 135           /*
 136            * Final case... one name is mechanism specific, the other isn't.
 137            *
 138            * We attempt to convert the general name to the mechanism type of
 139            * the mechanism-specific name, and then do the compare.  If we
 140            * can't import the general name, then we return that the name is
 141            * _NOT_ equal.
 142            */
 143           if (union_name2->mech_type) {
 144                   /* We make union_name1 the mechanism specific name. */
 145                   union_name1 = (gss_union_name_t)name2;
 146                   union_name2 = (gss_union_name_t)name1;
 147           }
 148           major_status = __gss_import_internal_name(minor_status,
 149                                                           union_name1->mech_type,
 150                                                           union_name2,
 151                                                           &internal_name);
 152           if (major_status != GSS_S_COMPLETE)
 130 |                 return (GSS_S_COMPLETE);
 153 |                 return (GSS_S_COMPLETE); /* return complete, but not equal */
 154   
 155           major_status = mech->gss_compare_name(mech->context, minor_status,
 156                                                           union_name1->mech_name,
 157                                                           internal_name,
 158                                                           name_equal);
 159           (void) __gss_release_internal_name(&temp_minor, union_name1->mech_type,
 160                                           &internal_name);
 161           return (major_status);
 162   }

 ----Unchanged portion omitted----