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