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]
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"
39 OM_uint32
*minor_status
,
45 /* Initialize outputs. */
47 if (minor_status
!= NULL
)
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
);
62 gss_compare_name(minor_status
,
67 OM_uint32
*minor_status
;
68 const gss_name_t name1
;
69 const gss_name_t name2
;
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
98 if (union_name1
->mech_type
) {
99 mech
= __gss_get_mechanism(union_name1
->mech_type
);
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
);
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
,
125 union_name1
->mech_name
,
126 union_name2
->mech_name
,
128 if (major_status
!= GSS_S_COMPLETE
)
129 map_error(minor_status
, mech
);
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
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
);
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
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
,
197 if (major_status
!= GSS_S_COMPLETE
)
198 return (GSS_S_COMPLETE
); /* return complete, but not equal */
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
,
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
,
212 return (major_status
);