]> git.decadent.org.uk Git - nfs-utils.git/blob - support/gssapi/g_mit_krb5_mech.c
2005-08-26 Kevin Coffman <kwc@citi.umich.edu>
[nfs-utils.git] / support / gssapi / g_mit_krb5_mech.c
1 /*
2  *  g_mit_krb5_mech.c
3  *
4  *  Copyright (c) 2004 The Regents of the University of Michigan.
5  *  All rights reserved.
6  *
7  *  Kevin Coffman <kwc@umich.edu>
8  *
9  *  Redistribution and use in source and binary forms, with or without
10  *  modification, are permitted provided that the following conditions
11  *  are met:
12  *
13  *  1. Redistributions of source code must retain the above copyright
14  *     notice, this list of conditions and the following disclaimer.
15  *  2. Redistributions in binary form must reproduce the above copyright
16  *     notice, this list of conditions and the following disclaimer in the
17  *     documentation and/or other materials provided with the distribution.
18  *  3. Neither the name of the University nor the names of its
19  *     contributors may be used to endorse or promote products derived
20  *     from this software without specific prior written permission.
21  *
22  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
23  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  */
35
36 #include "config.h"
37 #include <stdio.h>
38 #include <dlfcn.h>
39 #include "mglueP.h"
40
41 /*
42  * Table of function names that we need to locate within a mechanism's
43  * shared library if it does not support the xxx_gss_initialize function.
44  */
45 static char *glue_func_names[] = {
46         "gss_acquire_cred",
47         "gss_release_cred",
48         "gss_init_sec_context",
49         "gss_accept_sec_context",
50         "gss_process_context_token",
51         "gss_delete_sec_context",
52         "gss_context_time",
53         "gss_sign",
54         "gss_verify",
55         "gss_seal",
56         "gss_unseal",
57         "gss_display_status",
58         "gss_indicate_mechs",
59         "gss_compare_name",
60         "gss_display_name",
61         "gss_import_name",
62         "gss_release_name",
63         "gss_inquire_cred",
64         "gss_add_cred",
65         "gss_export_sec_context",
66         "gss_import_sec_context",
67         "gss_inquire_cred_by_mech",
68         "gss_inquire_names_for_mech",
69         "gss_inquire_context",
70         "gss_internal_release_oid",
71         "gss_wrap_size_limit",
72         "pname_to_uid",
73         "gss_duplicate_name",
74         "gss_set_allowable_enctypes",
75         "gss_verify_mic",
76         NULL
77 };
78
79 #ifdef HAVE_KRB5
80 /*
81  * The MIT code does not support the krb5_gss_initialize function, so
82  * we need to locate the functions within the gssapi_krb5.so library
83  * and fill in this structure.
84  */
85 static struct gss_config mit_krb5_mechanism = {
86         {9, "\052\206\110\206\367\022\001\002\002"},
87         NULL,           /* mechanism context -- we don't currently use this */
88         NULL,           /* gss_acquire_cred */
89         NULL,           /* gss_release_cred */
90         NULL,           /* gss_init_sec_context */
91         NULL,           /* gss_accept_sec_context */
92         NULL,           /* gss_process_context_token */
93         NULL,           /* gss_delete_sec_context */
94         NULL,           /* gss_context_time */
95         NULL,           /* gss_sign */
96         NULL,           /* gss_verify */
97         NULL,           /* gss_seal */
98         NULL,           /* gss_unseal */
99         NULL,           /* gss_display_status */
100         NULL,           /* gss_indicate_mechs */
101         NULL,           /* gss_compare_name */
102         NULL,           /* gss_display_name */
103         NULL,           /* gss_import_name */
104         NULL,           /* gss_release_name */
105         NULL,           /* gss_inquire_cred */
106         NULL,           /* gss_add_cred */
107         NULL,           /* gss_export_sec_context */
108         NULL,           /* gss_import_sec_context */
109         NULL,           /* gss_inquire_cred_by_mech */
110         NULL,           /* gss_inquire_names_for_mech */
111         NULL,           /* gss_inquire_context */
112         NULL,           /* gss_internal_release_oid */
113         NULL,           /* gss_wrap_size_limit */
114         NULL,           /* pname_to_uid */
115         NULL,           /* gss_duplicate_name */
116         NULL,           /* gss_set_allowable_enctypes */
117         NULL,           /* gss_verify_mic */
118 };
119 #endif
120
121 #ifdef HAVE_HEIMDAL
122 /*
123  * The heimdal code does not support the krb5_gss_initialize function, so
124  * we need to locate the functions within the libgssapi.so library
125  * and fill in this structure.
126  */
127 static struct gss_config heimdal_krb5_mechanism = {
128         {9, "\052\206\110\206\367\022\001\002\002"},
129         NULL,           /* mechanism context -- we don't currently use this */
130         NULL,           /* gss_acquire_cred */
131         NULL,           /* gss_release_cred */
132         NULL,           /* gss_init_sec_context */
133         NULL,           /* gss_accept_sec_context */
134         NULL,           /* gss_process_context_token */
135         NULL,           /* gss_delete_sec_context */
136         NULL,           /* gss_context_time */
137         NULL,           /* gss_sign */
138         NULL,           /* gss_verify */
139         NULL,           /* gss_seal */
140         NULL,           /* gss_unseal */
141         NULL,           /* gss_display_status */
142         NULL,           /* gss_indicate_mechs */
143         NULL,           /* gss_compare_name */
144         NULL,           /* gss_display_name */
145         NULL,           /* gss_import_name */
146         NULL,           /* gss_release_name */
147         NULL,           /* gss_inquire_cred */
148         NULL,           /* gss_add_cred */
149         NULL,           /* gss_export_sec_context */
150         NULL,           /* gss_import_sec_context */
151         NULL,           /* gss_inquire_cred_by_mech */
152         NULL,           /* gss_inquire_names_for_mech */
153         NULL,           /* gss_inquire_context */
154         NULL,           /* gss_internal_release_oid */
155         NULL,           /* gss_wrap_size_limit */
156         NULL,           /* pname_to_uid */
157         NULL,           /* gss_duplicate_name */
158         NULL,           /* gss_set_allowable_enctypes */
159         NULL,           /* gss_verify_mic */
160 };
161 #endif
162
163
164 /*
165  * Given a handle to a dynamic library (dl) and a symbol
166  * name (symname), return its address.  Returns -1 if the
167  * symbol cannot be located.  (Note that the value of the
168  * symbol could be NULL, which is valid.)
169  */
170 void *
171 locate_symbol(void *dl, char *symname, char *prefix)
172 {
173         void *sym;
174         const char *err_string;
175         char fullname[256];
176
177         snprintf(fullname, sizeof(fullname), "%s%s", prefix, symname);
178
179         if ((sym = dlsym(dl, fullname)) == NULL) {
180                 if ((sym = dlsym(dl, symname)) == NULL) {
181                         if ((err_string = dlerror()) != NULL) {
182                                 return (void *)-1;
183                         }
184                         else {
185                                 return NULL;
186                         }
187                 }
188         }
189         return sym;
190 }
191
192 #ifdef HAVE_KRB5
193 /*
194  * Locate all the symbols in the MIT gssapi library and
195  * fill in the gss_config (gss_mechanism) structure.
196  */
197 gss_mechanism
198 internal_krb5_gss_initialize(void *dl)
199 {
200         char *fname;
201         void *p;
202         void **fptr;
203         int i;
204         static int mit_krb5_initialized = 0;
205
206         if (mit_krb5_initialized)
207                 return (&mit_krb5_mechanism);
208
209         fptr = (void *) &mit_krb5_mechanism.gss_acquire_cred;
210
211
212         for (i = 0, fname = glue_func_names[i];
213              fname;
214              i++, fname = glue_func_names[i]) {
215                 if ((p = locate_symbol(dl, fname, "krb5_")) != (void *)-1) {
216                         *fptr++ = p;
217                 }
218                 else {
219                         *fptr++ = NULL;
220                 }
221         }
222         if (mit_krb5_mechanism.gss_internal_release_oid == NULL ||
223             mit_krb5_mechanism.gss_internal_release_oid == (void *) -1) {
224             fprintf(stderr, "WARNING: unable to locate function "
225                 "krb5_gss_internal_release_oid in krb5 mechanism library: "
226                 "there will be problems if multiple mechanisms are used!\n");
227             p = locate_symbol(dl, "krb5_gss_release_oid", "");
228             if (p == NULL || p == (void *) -1) {
229                 fprintf(stderr, "ERROR: Unable to locate function "
230                         "krb5_gss_internal_release_oid or "
231                         "krb5_gss_release_oid in krb5 mechanism library\n");
232                 return NULL;
233             }
234         }
235 #ifdef HAVE_SET_ALLOWABLE_ENCTYPES
236         /*
237          * Special case for set_allowable_enctypes which has a different
238          * name format than the rest of the gss routines :-/
239          */
240         if ((p = locate_symbol(dl, "gss_krb5_set_allowable_enctypes", ""))
241                                                         != (void *)-1) {
242                 mit_krb5_mechanism.gss_set_allowable_enctypes = p;
243         }
244 #endif
245         mit_krb5_initialized = 1;
246         return (&mit_krb5_mechanism);
247 }
248 #endif
249
250 #ifdef HAVE_HEIMDAL
251 /*
252  * Locate all the symbols in the MIT gssapi library and
253  * fill in the gss_config (gss_mechanism) structure.
254  */
255 gss_mechanism
256 internal_heimdal_gss_initialize(void *dl)
257 {
258         char *fname;
259         void *p;
260         void **fptr;
261         int i;
262         static int heimdal_krb5_initialized = 0;
263
264         if (heimdal_krb5_initialized)
265                 return (&heimdal_krb5_mechanism);
266
267         fptr = (void *) &heimdal_krb5_mechanism.gss_acquire_cred;
268
269
270         for (i = 0, fname = glue_func_names[i];
271              fname;
272              i++, fname = glue_func_names[i]) {
273                 if ((p = locate_symbol(dl, fname, "")) != (void *)-1) {
274                         *fptr++ = p;
275                 }
276                 else {
277 printf("Failed to locate function '%s' !!!\n", fname);
278                         *fptr++ = NULL;
279                 }
280         }
281         if (heimdal_krb5_mechanism.gss_internal_release_oid == NULL ||
282             heimdal_krb5_mechanism.gss_internal_release_oid == (void *) -1) {
283             fprintf(stderr, "WARNING: unable to locate function "
284                 "gss_internal_release_oid in krb5 mechanism library: "
285                 "there will be problems if multiple mechanisms are used!\n");
286             p = locate_symbol(dl, "krb5_gss_release_oid", "");
287             if (p == NULL || p == (void *) -1) {
288                 fprintf(stderr, "ERROR: Unable to locate function "
289                         "gss_internal_release_oid or "
290                         "gss_release_oid in krb5 mechanism library\n");
291                 return NULL;
292             }
293         }
294         heimdal_krb5_initialized = 1;
295         return (&heimdal_krb5_mechanism);
296 }
297 #endif