1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * glue routine for gss_compare_name 31 * 32 */ 33 34 #include <mechglueP.h> 35 #ifdef HAVE_STDLIB_H 36 #include <stdlib.h> 37 #endif 38 #include <string.h> 39 40 OM_uint32 41 gss_compare_name(minor_status, 42 name1, 43 name2, 44 name_equal) 45 46 OM_uint32 *minor_status; 47 const gss_name_t name1; 48 const gss_name_t name2; 49 int *name_equal; 50 51 { 52 OM_uint32 major_status, temp_minor; 53 gss_union_name_t union_name1, union_name2; 54 gss_mechanism mech; 55 gss_name_t internal_name; 56 57 if (minor_status == NULL) 58 return (GSS_S_CALL_INACCESSIBLE_WRITE); 59 *minor_status = 0; 60 61 if (name1 == 0 || name2 == 0) 62 return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME); 63 64 if (name_equal == NULL) 65 return (GSS_S_CALL_INACCESSIBLE_WRITE); 66 67 union_name1 = (gss_union_name_t)name1; 68 union_name2 = (gss_union_name_t)name2; 69 /* 70 * Try our hardest to make union_name1 be the mechanism-specific 71 * name. (Of course we can't if both names aren't 72 * mechanism-specific.) 73 */ 74 if (union_name1->mech_type == 0) { 75 union_name1 = (gss_union_name_t)name2; 76 union_name2 = (gss_union_name_t)name1; 77 } 78 /* 79 * If union_name1 is mechanism specific, then fetch its mechanism 80 * information. 81 */ 82 if (union_name1->mech_type) { 83 mech = __gss_get_mechanism(union_name1->mech_type); 84 if (!mech) 85 return (GSS_S_BAD_MECH); 86 if (!mech->gss_compare_name) 87 return (GSS_S_UNAVAILABLE); 88 } 89 90 *name_equal = 0; /* Default to *not* equal.... */ 91 92 /* 93 * First case... both names are mechanism-specific 94 */ 95 if (union_name1->mech_type && union_name2->mech_type) { 96 if (!g_OID_equal(union_name1->mech_type, 97 union_name2->mech_type)) 98 return (GSS_S_COMPLETE); 99 if ((union_name1->mech_name == 0) || 100 (union_name2->mech_name == 0)) 101 /* should never happen */ 102 return (GSS_S_BAD_NAME); 103 return (mech->gss_compare_name(mech->context, minor_status, 104 union_name1->mech_name, 105 union_name2->mech_name, 106 name_equal)); 107 } 108 109 /* 110 * Second case... both names are NOT mechanism specific. 111 * 112 * All we do here is make sure the two name_types are equal and then 113 * that the external_names are equal. Note the we do not take care 114 * of the case where two different external names map to the same 115 * internal name. We cannot determine this, since we as yet do not 116 * know what mechanism to use for calling the underlying 117 * gss_import_name(). 118 */ 119 if (!union_name1->mech_type && !union_name2->mech_type) { 120 /* 121 * Second case, first sub-case... one name has null 122 * name_type, the other doesn't. 123 * 124 * Not knowing a mech_type we can't import the name with 125 * null name_type so we can't compare. 126 */ 127 if ((union_name1->name_type == GSS_C_NULL_OID && 128 union_name2->name_type != GSS_C_NULL_OID) || 129 (union_name1->name_type != GSS_C_NULL_OID && 130 union_name2->name_type == GSS_C_NULL_OID)) 131 return (GSS_S_COMPLETE); 132 /* 133 * Second case, second sub-case... both names have 134 * name_types, but they are different. 135 */ 136 if ((union_name1->name_type != GSS_C_NULL_OID && 137 union_name2->name_type != GSS_C_NULL_OID) && 138 !g_OID_equal(union_name1->name_type, 139 union_name2->name_type)) 140 return (GSS_S_COMPLETE); 141 /* 142 * Second case, third sub-case... both names have equal 143 * name_types (and both have no mech_types) so we just 144 * compare the external_names. 145 */ 146 if ((union_name1->external_name->length != 147 union_name2->external_name->length) || 148 (memcmp(union_name1->external_name->value, 149 union_name2->external_name->value, 150 union_name1->external_name->length) != 0)) 151 return (GSS_S_COMPLETE); 152 *name_equal = 1; 153 return (GSS_S_COMPLETE); 154 } 155 156 /* 157 * Final case... one name is mechanism specific, the other isn't. 158 * 159 * We attempt to convert the general name to the mechanism type of 160 * the mechanism-specific name, and then do the compare. If we 161 * can't import the general name, then we return that the name is 162 * _NOT_ equal. 163 */ 164 if (union_name2->mech_type) { 165 /* We make union_name1 the mechanism specific name. */ 166 union_name1 = (gss_union_name_t)name2; 167 union_name2 = (gss_union_name_t)name1; 168 } 169 major_status = __gss_import_internal_name(minor_status, 170 union_name1->mech_type, 171 union_name2, 172 &internal_name); 173 if (major_status != GSS_S_COMPLETE) 174 return (GSS_S_COMPLETE); /* return complete, but not equal */ 175 176 major_status = mech->gss_compare_name(mech->context, minor_status, 177 union_name1->mech_name, 178 internal_name, 179 name_equal); 180 (void) __gss_release_internal_name(&temp_minor, union_name1->mech_type, 181 &internal_name); 182 return (major_status); 183 } 184