]> git.decadent.org.uk Git - nfs-utils.git/blob - support/gssapi/g_compare_name.c
2005-08-26 Kevin Coffman <kwc@citi.umich.edu>
[nfs-utils.git] / support / gssapi / g_compare_name.c
1 /* #ident  "@(#)gss_compare_name.c 1.13     95/08/02 SMI" */
2
3 /*
4  * Copyright 1996 by Sun Microsystems, Inc.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software
7  * and its documentation for any purpose is hereby granted without fee,
8  * provided that the above copyright notice appears in all copies and
9  * that both that copyright notice and this permission notice appear in
10  * supporting documentation, and that the name of Sun Microsystems not be used
11  * in advertising or publicity pertaining to distribution of the software
12  * without specific, written prior permission. Sun Microsystems makes no
13  * representations about the suitability of this software for any
14  * purpose.  It is provided "as is" without express or implied warranty.
15  *
16  * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18  * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
20  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22  * PERFORMANCE OF THIS SOFTWARE.
23  */
24
25 /*
26  *  glue routine for gss_compare_name
27  *
28  */
29
30 #include "mglueP.h"
31 #ifdef HAVE_STDLIB_H
32 #include <stdlib.h>
33 #endif
34 #include <string.h>
35
36 #define g_OID_equal(o1,o2) \
37    (((o1)->length == (o2)->length) && \
38     (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0))
39
40 OM_uint32 KRB5_CALLCONV
41 gss_compare_name (minor_status,
42                   name1,
43                   name2,
44                   name_equal)
45
46 OM_uint32 *             minor_status;
47 gss_name_t              name1;
48 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     gss_initialize();
58
59     if (name1 == 0 || name2 == 0) {
60         if (name_equal)
61             *name_equal = 0;
62         return GSS_S_BAD_NAME;
63     }
64
65     union_name1 = (gss_union_name_t) name1;
66     union_name2 = (gss_union_name_t) name2;
67     /*
68      * Try our hardest to make union_name1 be the mechanism-specific
69      * name.  (Of course we can't if both names aren't
70      * mechanism-specific.)
71      */
72     if (union_name1->mech_type == 0) {
73         union_name1 = (gss_union_name_t) name2;
74         union_name2 = (gss_union_name_t) name1;
75     }
76     /*
77      * If union_name1 is mechanism specific, then fetch its mechanism
78      * information.
79      */
80     if (union_name1->mech_type) {
81         mech = __gss_get_mechanism (union_name1->mech_type);
82         if (!mech)
83             return (GSS_S_BAD_MECH);
84         if (!mech->gss_compare_name)
85             return (GSS_S_BAD_BINDINGS);
86     }
87
88     if (name_equal == NULL)
89         return GSS_S_COMPLETE;
90
91     *name_equal = 0;            /* Default to *not* equal.... */
92
93     /*
94      * First case... both names are mechanism-specific
95      */
96     if (union_name1->mech_type && union_name2->mech_type) {
97         if (!g_OID_equal(union_name1->mech_type, union_name2->mech_type))
98             return (GSS_S_COMPLETE);
99         if ((union_name1->mech_name == 0) || (union_name2->mech_name == 0))
100             /* should never happen */
101             return (GSS_S_BAD_NAME);
102 #ifdef USE_MECH_CONTEXT
103         return (mech->gss_compare_name(mech->context, minor_status,
104 #else
105         return (mech->gss_compare_name(minor_status,
106 #endif
107                                        union_name1->mech_name,
108                                        union_name2->mech_name, name_equal));
109
110     }
111
112     /*
113      * Second case... both names are NOT mechanism specific.
114      *
115      * All we do here is make sure the two name_types are equal and then
116      * that the external_names are equal. Note the we do not take care
117      * of the case where two different external names map to the same
118      * internal name. We cannot determine this, since we as yet do not
119      * know what mechanism to use for calling the underlying
120      * gss_import_name().
121      */
122     if (!union_name1->mech_type && !union_name2->mech_type) {
123         if (!g_OID_equal(union_name1->name_type, union_name2->name_type))
124             return (GSS_S_COMPLETE);
125         if ((union_name1->external_name->length !=
126              union_name2->external_name->length) ||
127             (memcmp(union_name1->external_name->value,
128                     union_name2->external_name->value,
129                     union_name1->external_name->length) != 0))
130             return (GSS_S_COMPLETE);
131         *name_equal = 1;
132         return (GSS_S_COMPLETE);
133     }
134
135     /*
136      * Final case... one name is mechanism specific, the other isn't.
137      *
138      * We attempt to convert the general name to the mechanism type of
139      * the mechanism-specific name, and then do the compare.  If we
140      * can't import the general name, then we return that the name is
141      * _NOT_ equal.
142      */
143     if (union_name2->mech_type) {
144         /* We make union_name1 the mechanism specific name. */
145         union_name1 = (gss_union_name_t) name2;
146         union_name2 = (gss_union_name_t) name1;
147     }
148     major_status = __gss_import_internal_name(minor_status,
149                                               union_name1->mech_type,
150                                               union_name2,
151                                               &internal_name);
152     if (major_status != GSS_S_COMPLETE)
153         return (GSS_S_COMPLETE);
154 #ifdef USE_MECH_CONTEXT
155     major_status = mech->gss_compare_name(mech->context, minor_status,
156 #else
157     major_status = mech->gss_compare_name(minor_status,
158 #endif
159                                           union_name1->mech_name,
160                                           internal_name, name_equal);
161     __gss_release_internal_name(&temp_minor, union_name1->mech_type,
162                                 &internal_name);
163     return (major_status);
164
165 }