1*7f2fe78bSCy Schubert /* #pragma ident "@(#)g_compare_name.c 1.16 04/02/23 SMI" */
2*7f2fe78bSCy Schubert
3*7f2fe78bSCy Schubert /*
4*7f2fe78bSCy Schubert * Copyright 1996 by Sun Microsystems, Inc.
5*7f2fe78bSCy Schubert *
6*7f2fe78bSCy Schubert * Permission to use, copy, modify, distribute, and sell this software
7*7f2fe78bSCy Schubert * and its documentation for any purpose is hereby granted without fee,
8*7f2fe78bSCy Schubert * provided that the above copyright notice appears in all copies and
9*7f2fe78bSCy Schubert * that both that copyright notice and this permission notice appear in
10*7f2fe78bSCy Schubert * supporting documentation, and that the name of Sun Microsystems not be used
11*7f2fe78bSCy Schubert * in advertising or publicity pertaining to distribution of the software
12*7f2fe78bSCy Schubert * without specific, written prior permission. Sun Microsystems makes no
13*7f2fe78bSCy Schubert * representations about the suitability of this software for any
14*7f2fe78bSCy Schubert * purpose. It is provided "as is" without express or implied warranty.
15*7f2fe78bSCy Schubert *
16*7f2fe78bSCy Schubert * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17*7f2fe78bSCy Schubert * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18*7f2fe78bSCy Schubert * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19*7f2fe78bSCy Schubert * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
20*7f2fe78bSCy Schubert * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21*7f2fe78bSCy Schubert * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22*7f2fe78bSCy Schubert * PERFORMANCE OF THIS SOFTWARE.
23*7f2fe78bSCy Schubert */
24*7f2fe78bSCy Schubert
25*7f2fe78bSCy Schubert /*
26*7f2fe78bSCy Schubert * glue routine for gss_compare_name
27*7f2fe78bSCy Schubert *
28*7f2fe78bSCy Schubert */
29*7f2fe78bSCy Schubert
30*7f2fe78bSCy Schubert #include "mglueP.h"
31*7f2fe78bSCy Schubert #ifdef HAVE_STDLIB_H
32*7f2fe78bSCy Schubert #include <stdlib.h>
33*7f2fe78bSCy Schubert #endif
34*7f2fe78bSCy Schubert #include <string.h>
35*7f2fe78bSCy Schubert
36*7f2fe78bSCy Schubert static OM_uint32
val_comp_name_args(OM_uint32 * minor_status,gss_name_t name1,gss_name_t name2,int * name_equal)37*7f2fe78bSCy Schubert val_comp_name_args(
38*7f2fe78bSCy Schubert OM_uint32 *minor_status,
39*7f2fe78bSCy Schubert gss_name_t name1,
40*7f2fe78bSCy Schubert gss_name_t name2,
41*7f2fe78bSCy Schubert int *name_equal)
42*7f2fe78bSCy Schubert {
43*7f2fe78bSCy Schubert
44*7f2fe78bSCy Schubert /* Initialize outputs. */
45*7f2fe78bSCy Schubert
46*7f2fe78bSCy Schubert if (minor_status != NULL)
47*7f2fe78bSCy Schubert *minor_status = 0;
48*7f2fe78bSCy Schubert
49*7f2fe78bSCy Schubert /* Validate arguments. */
50*7f2fe78bSCy Schubert
51*7f2fe78bSCy Schubert if (name1 == GSS_C_NO_NAME || name2 == GSS_C_NO_NAME)
52*7f2fe78bSCy Schubert return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
53*7f2fe78bSCy Schubert
54*7f2fe78bSCy Schubert if (name_equal == NULL)
55*7f2fe78bSCy Schubert return (GSS_S_CALL_INACCESSIBLE_WRITE);
56*7f2fe78bSCy Schubert
57*7f2fe78bSCy Schubert return (GSS_S_COMPLETE);
58*7f2fe78bSCy Schubert }
59*7f2fe78bSCy Schubert
60*7f2fe78bSCy Schubert
61*7f2fe78bSCy Schubert OM_uint32 KRB5_CALLCONV
gss_compare_name(minor_status,name1,name2,name_equal)62*7f2fe78bSCy Schubert gss_compare_name (minor_status,
63*7f2fe78bSCy Schubert name1,
64*7f2fe78bSCy Schubert name2,
65*7f2fe78bSCy Schubert name_equal)
66*7f2fe78bSCy Schubert
67*7f2fe78bSCy Schubert OM_uint32 * minor_status;
68*7f2fe78bSCy Schubert gss_name_t name1;
69*7f2fe78bSCy Schubert gss_name_t name2;
70*7f2fe78bSCy Schubert int * name_equal;
71*7f2fe78bSCy Schubert
72*7f2fe78bSCy Schubert {
73*7f2fe78bSCy Schubert OM_uint32 major_status, temp_minor;
74*7f2fe78bSCy Schubert gss_union_name_t union_name1, union_name2;
75*7f2fe78bSCy Schubert gss_mechanism mech = NULL;
76*7f2fe78bSCy Schubert gss_name_t internal_name;
77*7f2fe78bSCy Schubert
78*7f2fe78bSCy Schubert major_status = val_comp_name_args(minor_status,
79*7f2fe78bSCy Schubert name1, name2, name_equal);
80*7f2fe78bSCy Schubert if (major_status != GSS_S_COMPLETE)
81*7f2fe78bSCy Schubert return (major_status);
82*7f2fe78bSCy Schubert
83*7f2fe78bSCy Schubert union_name1 = (gss_union_name_t) name1;
84*7f2fe78bSCy Schubert union_name2 = (gss_union_name_t) name2;
85*7f2fe78bSCy Schubert /*
86*7f2fe78bSCy Schubert * Try our hardest to make union_name1 be the mechanism-specific
87*7f2fe78bSCy Schubert * name. (Of course we can't if both names aren't
88*7f2fe78bSCy Schubert * mechanism-specific.)
89*7f2fe78bSCy Schubert */
90*7f2fe78bSCy Schubert if (union_name1->mech_type == 0) {
91*7f2fe78bSCy Schubert union_name1 = (gss_union_name_t) name2;
92*7f2fe78bSCy Schubert union_name2 = (gss_union_name_t) name1;
93*7f2fe78bSCy Schubert }
94*7f2fe78bSCy Schubert /*
95*7f2fe78bSCy Schubert * If union_name1 is mechanism specific, then fetch its mechanism
96*7f2fe78bSCy Schubert * information.
97*7f2fe78bSCy Schubert */
98*7f2fe78bSCy Schubert if (union_name1->mech_type) {
99*7f2fe78bSCy Schubert mech = gssint_get_mechanism (union_name1->mech_type);
100*7f2fe78bSCy Schubert if (!mech)
101*7f2fe78bSCy Schubert return (GSS_S_BAD_MECH);
102*7f2fe78bSCy Schubert if (!mech->gss_compare_name)
103*7f2fe78bSCy Schubert return (GSS_S_UNAVAILABLE);
104*7f2fe78bSCy Schubert }
105*7f2fe78bSCy Schubert
106*7f2fe78bSCy Schubert *name_equal = 0; /* Default to *not* equal.... */
107*7f2fe78bSCy Schubert
108*7f2fe78bSCy Schubert /*
109*7f2fe78bSCy Schubert * First case... both names are mechanism-specific
110*7f2fe78bSCy Schubert */
111*7f2fe78bSCy Schubert if (union_name1->mech_type && union_name2->mech_type) {
112*7f2fe78bSCy Schubert if (!g_OID_equal(union_name1->mech_type, union_name2->mech_type))
113*7f2fe78bSCy Schubert return (GSS_S_COMPLETE);
114*7f2fe78bSCy Schubert if ((union_name1->mech_name == 0) || (union_name2->mech_name == 0))
115*7f2fe78bSCy Schubert /* should never happen */
116*7f2fe78bSCy Schubert return (GSS_S_BAD_NAME);
117*7f2fe78bSCy Schubert if (!mech)
118*7f2fe78bSCy Schubert return (GSS_S_BAD_MECH);
119*7f2fe78bSCy Schubert if (!mech->gss_compare_name)
120*7f2fe78bSCy Schubert return (GSS_S_UNAVAILABLE);
121*7f2fe78bSCy Schubert major_status = mech->gss_compare_name(minor_status,
122*7f2fe78bSCy Schubert union_name1->mech_name,
123*7f2fe78bSCy Schubert union_name2->mech_name,
124*7f2fe78bSCy Schubert name_equal);
125*7f2fe78bSCy Schubert if (major_status != GSS_S_COMPLETE)
126*7f2fe78bSCy Schubert map_error(minor_status, mech);
127*7f2fe78bSCy Schubert return major_status;
128*7f2fe78bSCy Schubert }
129*7f2fe78bSCy Schubert
130*7f2fe78bSCy Schubert /*
131*7f2fe78bSCy Schubert * Second case... both names are NOT mechanism specific.
132*7f2fe78bSCy Schubert *
133*7f2fe78bSCy Schubert * All we do here is make sure the two name_types are equal and then
134*7f2fe78bSCy Schubert * that the external_names are equal. Note the we do not take care
135*7f2fe78bSCy Schubert * of the case where two different external names map to the same
136*7f2fe78bSCy Schubert * internal name. We cannot determine this, since we as yet do not
137*7f2fe78bSCy Schubert * know what mechanism to use for calling the underlying
138*7f2fe78bSCy Schubert * gss_import_name().
139*7f2fe78bSCy Schubert */
140*7f2fe78bSCy Schubert if (!union_name1->mech_type && !union_name2->mech_type) {
141*7f2fe78bSCy Schubert /*
142*7f2fe78bSCy Schubert * Second case, first sub-case... one name has null
143*7f2fe78bSCy Schubert * name_type, the other doesn't.
144*7f2fe78bSCy Schubert *
145*7f2fe78bSCy Schubert * Not knowing a mech_type we can't import the name with
146*7f2fe78bSCy Schubert * null name_type so we can't compare.
147*7f2fe78bSCy Schubert */
148*7f2fe78bSCy Schubert if ((union_name1->name_type == GSS_C_NULL_OID &&
149*7f2fe78bSCy Schubert union_name2->name_type != GSS_C_NULL_OID) ||
150*7f2fe78bSCy Schubert (union_name1->name_type != GSS_C_NULL_OID &&
151*7f2fe78bSCy Schubert union_name2->name_type == GSS_C_NULL_OID))
152*7f2fe78bSCy Schubert return (GSS_S_COMPLETE);
153*7f2fe78bSCy Schubert /*
154*7f2fe78bSCy Schubert * Second case, second sub-case... both names have
155*7f2fe78bSCy Schubert * name_types, but they are different.
156*7f2fe78bSCy Schubert */
157*7f2fe78bSCy Schubert if ((union_name1->name_type != GSS_C_NULL_OID &&
158*7f2fe78bSCy Schubert union_name2->name_type != GSS_C_NULL_OID) &&
159*7f2fe78bSCy Schubert !g_OID_equal(union_name1->name_type,
160*7f2fe78bSCy Schubert union_name2->name_type))
161*7f2fe78bSCy Schubert return (GSS_S_COMPLETE);
162*7f2fe78bSCy Schubert /*
163*7f2fe78bSCy Schubert * Second case, third sub-case... both names have equal
164*7f2fe78bSCy Schubert * name_types (and both have no mech_types) so we just
165*7f2fe78bSCy Schubert * compare the external_names.
166*7f2fe78bSCy Schubert */
167*7f2fe78bSCy Schubert if ((union_name1->external_name->length !=
168*7f2fe78bSCy Schubert union_name2->external_name->length) ||
169*7f2fe78bSCy Schubert (memcmp(union_name1->external_name->value,
170*7f2fe78bSCy Schubert union_name2->external_name->value,
171*7f2fe78bSCy Schubert union_name1->external_name->length) != 0))
172*7f2fe78bSCy Schubert return (GSS_S_COMPLETE);
173*7f2fe78bSCy Schubert *name_equal = 1;
174*7f2fe78bSCy Schubert return (GSS_S_COMPLETE);
175*7f2fe78bSCy Schubert }
176*7f2fe78bSCy Schubert
177*7f2fe78bSCy Schubert /*
178*7f2fe78bSCy Schubert * Final case... one name is mechanism specific, the other isn't.
179*7f2fe78bSCy Schubert *
180*7f2fe78bSCy Schubert * We attempt to convert the general name to the mechanism type of
181*7f2fe78bSCy Schubert * the mechanism-specific name, and then do the compare. If we
182*7f2fe78bSCy Schubert * can't import the general name, then we return that the name is
183*7f2fe78bSCy Schubert * _NOT_ equal.
184*7f2fe78bSCy Schubert */
185*7f2fe78bSCy Schubert if (union_name2->mech_type) {
186*7f2fe78bSCy Schubert /* We make union_name1 the mechanism specific name. */
187*7f2fe78bSCy Schubert union_name1 = (gss_union_name_t) name2;
188*7f2fe78bSCy Schubert union_name2 = (gss_union_name_t) name1;
189*7f2fe78bSCy Schubert }
190*7f2fe78bSCy Schubert major_status = gssint_import_internal_name(minor_status,
191*7f2fe78bSCy Schubert union_name1->mech_type,
192*7f2fe78bSCy Schubert union_name2,
193*7f2fe78bSCy Schubert &internal_name);
194*7f2fe78bSCy Schubert if (major_status != GSS_S_COMPLETE)
195*7f2fe78bSCy Schubert return (GSS_S_COMPLETE); /* return complete, but not equal */
196*7f2fe78bSCy Schubert
197*7f2fe78bSCy Schubert if (!mech)
198*7f2fe78bSCy Schubert return (GSS_S_BAD_MECH);
199*7f2fe78bSCy Schubert if (!mech->gss_compare_name)
200*7f2fe78bSCy Schubert return (GSS_S_UNAVAILABLE);
201*7f2fe78bSCy Schubert major_status = mech->gss_compare_name(minor_status,
202*7f2fe78bSCy Schubert union_name1->mech_name,
203*7f2fe78bSCy Schubert internal_name, name_equal);
204*7f2fe78bSCy Schubert if (major_status != GSS_S_COMPLETE)
205*7f2fe78bSCy Schubert map_error(minor_status, mech);
206*7f2fe78bSCy Schubert gssint_release_internal_name(&temp_minor, union_name1->mech_type,
207*7f2fe78bSCy Schubert &internal_name);
208*7f2fe78bSCy Schubert return (major_status);
209*7f2fe78bSCy Schubert
210*7f2fe78bSCy Schubert }
211