6069 libdisasm: instrlen arch op should have a sane default
[illumos-gate.git] / usr / src / lib / libgss / g_compare_name.c
blobf4789fc50fd0629a113369148a3b4319a94ea14e
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
26 * glue routine for gss_compare_name
30 #include <mechglueP.h>
31 #include "gssapiP_generic.h"
32 #ifdef HAVE_STDLIB_H
33 #include <stdlib.h>
34 #endif
35 #include <string.h>
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)
45 /* Initialize outputs. */
47 if (minor_status != NULL)
48 *minor_status = 0;
50 /* Validate arguments. */
52 if (name1 == GSS_C_NO_NAME || name2 == GSS_C_NO_NAME)
53 return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
55 if (name_equal == NULL)
56 return (GSS_S_CALL_INACCESSIBLE_WRITE);
58 return (GSS_S_COMPLETE);
61 OM_uint32
62 gss_compare_name(minor_status,
63 name1,
64 name2,
65 name_equal)
67 OM_uint32 *minor_status;
68 const gss_name_t name1;
69 const gss_name_t name2;
70 int *name_equal;
73 OM_uint32 major_status, temp_minor;
74 gss_union_name_t union_name1, union_name2;
75 gss_mechanism mech = NULL;
76 gss_name_t internal_name;
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);
83 union_name1 = (gss_union_name_t)name1;
84 union_name2 = (gss_union_name_t)name2;
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.)
90 if (union_name1->mech_type == 0) {
91 union_name1 = (gss_union_name_t)name2;
92 union_name2 = (gss_union_name_t)name1;
95 * If union_name1 is mechanism specific, then fetch its mechanism
96 * information.
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);
106 *name_equal = 0; /* Default to *not* equal.... */
109 * First case... both names are mechanism-specific
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 if (!mech)
120 return (GSS_S_BAD_MECH);
121 if (!mech->gss_compare_name)
122 return (GSS_S_UNAVAILABLE);
123 major_status = mech->gss_compare_name(mech->context,
124 minor_status,
125 union_name1->mech_name,
126 union_name2->mech_name,
127 name_equal);
128 if (major_status != GSS_S_COMPLETE)
129 map_error(minor_status, mech);
130 return major_status;
134 * Second case... both names are NOT mechanism specific.
136 * All we do here is make sure the two name_types are equal and then
137 * that the external_names are equal. Note the we do not take care
138 * of the case where two different external names map to the same
139 * internal name. We cannot determine this, since we as yet do not
140 * know what mechanism to use for calling the underlying
141 * gss_import_name().
143 if (!union_name1->mech_type && !union_name2->mech_type) {
145 * Second case, first sub-case... one name has null
146 * name_type, the other doesn't.
148 * Not knowing a mech_type we can't import the name with
149 * null name_type so we can't compare.
151 if ((union_name1->name_type == GSS_C_NULL_OID &&
152 union_name2->name_type != GSS_C_NULL_OID) ||
153 (union_name1->name_type != GSS_C_NULL_OID &&
154 union_name2->name_type == GSS_C_NULL_OID))
155 return (GSS_S_COMPLETE);
157 * Second case, second sub-case... both names have
158 * name_types, but they are different.
160 if ((union_name1->name_type != GSS_C_NULL_OID &&
161 union_name2->name_type != GSS_C_NULL_OID) &&
162 !g_OID_equal(union_name1->name_type,
163 union_name2->name_type))
164 return (GSS_S_COMPLETE);
166 * Second case, third sub-case... both names have equal
167 * name_types (and both have no mech_types) so we just
168 * compare the external_names.
170 if ((union_name1->external_name->length !=
171 union_name2->external_name->length) ||
172 (memcmp(union_name1->external_name->value,
173 union_name2->external_name->value,
174 union_name1->external_name->length) != 0))
175 return (GSS_S_COMPLETE);
176 *name_equal = 1;
177 return (GSS_S_COMPLETE);
181 * Final case... one name is mechanism specific, the other isn't.
183 * We attempt to convert the general name to the mechanism type of
184 * the mechanism-specific name, and then do the compare. If we
185 * can't import the general name, then we return that the name is
186 * _NOT_ equal.
188 if (union_name2->mech_type) {
189 /* We make union_name1 the mechanism specific name. */
190 union_name1 = (gss_union_name_t)name2;
191 union_name2 = (gss_union_name_t)name1;
193 major_status = __gss_import_internal_name(minor_status,
194 union_name1->mech_type,
195 union_name2,
196 &internal_name);
197 if (major_status != GSS_S_COMPLETE)
198 return (GSS_S_COMPLETE); /* return complete, but not equal */
200 if (!mech)
201 return (GSS_S_BAD_MECH);
202 if (!mech->gss_compare_name)
203 return (GSS_S_UNAVAILABLE);
204 major_status = mech->gss_compare_name(mech->context, minor_status,
205 union_name1->mech_name,
206 internal_name,
207 name_equal);
208 if (major_status != GSS_S_COMPLETE)
209 map_error(minor_status, mech);
210 (void) __gss_release_internal_name(&temp_minor, union_name1->mech_type,
211 &internal_name);
212 return (major_status);