X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=support%2Fgssapi%2Fg_mit_krb5_mech.c;fp=support%2Fgssapi%2Fg_mit_krb5_mech.c;h=1caa8d2905180147f2bf75d151f0a5c146967257;hp=0000000000000000000000000000000000000000;hb=f1bfe0916c04d93de7a4fae5315fff6e4ccac23f;hpb=981d25a37fe4a71eddd162672a658da223453985 diff --git a/support/gssapi/g_mit_krb5_mech.c b/support/gssapi/g_mit_krb5_mech.c new file mode 100644 index 0000000..1caa8d2 --- /dev/null +++ b/support/gssapi/g_mit_krb5_mech.c @@ -0,0 +1,297 @@ +/* + * g_mit_krb5_mech.c + * + * Copyright (c) 2004 The Regents of the University of Michigan. + * All rights reserved. + * + * Kevin Coffman + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "config.h" +#include +#include +#include "mglueP.h" + +/* + * Table of function names that we need to locate within a mechanism's + * shared library if it does not support the xxx_gss_initialize function. + */ +static char *glue_func_names[] = { + "gss_acquire_cred", + "gss_release_cred", + "gss_init_sec_context", + "gss_accept_sec_context", + "gss_process_context_token", + "gss_delete_sec_context", + "gss_context_time", + "gss_sign", + "gss_verify", + "gss_seal", + "gss_unseal", + "gss_display_status", + "gss_indicate_mechs", + "gss_compare_name", + "gss_display_name", + "gss_import_name", + "gss_release_name", + "gss_inquire_cred", + "gss_add_cred", + "gss_export_sec_context", + "gss_import_sec_context", + "gss_inquire_cred_by_mech", + "gss_inquire_names_for_mech", + "gss_inquire_context", + "gss_internal_release_oid", + "gss_wrap_size_limit", + "pname_to_uid", + "gss_duplicate_name", + "gss_set_allowable_enctypes", + "gss_verify_mic", + NULL +}; + +#ifdef HAVE_KRB5 +/* + * The MIT code does not support the krb5_gss_initialize function, so + * we need to locate the functions within the gssapi_krb5.so library + * and fill in this structure. + */ +static struct gss_config mit_krb5_mechanism = { + {9, "\052\206\110\206\367\022\001\002\002"}, + NULL, /* mechanism context -- we don't currently use this */ + NULL, /* gss_acquire_cred */ + NULL, /* gss_release_cred */ + NULL, /* gss_init_sec_context */ + NULL, /* gss_accept_sec_context */ + NULL, /* gss_process_context_token */ + NULL, /* gss_delete_sec_context */ + NULL, /* gss_context_time */ + NULL, /* gss_sign */ + NULL, /* gss_verify */ + NULL, /* gss_seal */ + NULL, /* gss_unseal */ + NULL, /* gss_display_status */ + NULL, /* gss_indicate_mechs */ + NULL, /* gss_compare_name */ + NULL, /* gss_display_name */ + NULL, /* gss_import_name */ + NULL, /* gss_release_name */ + NULL, /* gss_inquire_cred */ + NULL, /* gss_add_cred */ + NULL, /* gss_export_sec_context */ + NULL, /* gss_import_sec_context */ + NULL, /* gss_inquire_cred_by_mech */ + NULL, /* gss_inquire_names_for_mech */ + NULL, /* gss_inquire_context */ + NULL, /* gss_internal_release_oid */ + NULL, /* gss_wrap_size_limit */ + NULL, /* pname_to_uid */ + NULL, /* gss_duplicate_name */ + NULL, /* gss_set_allowable_enctypes */ + NULL, /* gss_verify_mic */ +}; +#endif + +#ifdef HAVE_HEIMDAL +/* + * The heimdal code does not support the krb5_gss_initialize function, so + * we need to locate the functions within the libgssapi.so library + * and fill in this structure. + */ +static struct gss_config heimdal_krb5_mechanism = { + {9, "\052\206\110\206\367\022\001\002\002"}, + NULL, /* mechanism context -- we don't currently use this */ + NULL, /* gss_acquire_cred */ + NULL, /* gss_release_cred */ + NULL, /* gss_init_sec_context */ + NULL, /* gss_accept_sec_context */ + NULL, /* gss_process_context_token */ + NULL, /* gss_delete_sec_context */ + NULL, /* gss_context_time */ + NULL, /* gss_sign */ + NULL, /* gss_verify */ + NULL, /* gss_seal */ + NULL, /* gss_unseal */ + NULL, /* gss_display_status */ + NULL, /* gss_indicate_mechs */ + NULL, /* gss_compare_name */ + NULL, /* gss_display_name */ + NULL, /* gss_import_name */ + NULL, /* gss_release_name */ + NULL, /* gss_inquire_cred */ + NULL, /* gss_add_cred */ + NULL, /* gss_export_sec_context */ + NULL, /* gss_import_sec_context */ + NULL, /* gss_inquire_cred_by_mech */ + NULL, /* gss_inquire_names_for_mech */ + NULL, /* gss_inquire_context */ + NULL, /* gss_internal_release_oid */ + NULL, /* gss_wrap_size_limit */ + NULL, /* pname_to_uid */ + NULL, /* gss_duplicate_name */ + NULL, /* gss_set_allowable_enctypes */ + NULL, /* gss_verify_mic */ +}; +#endif + + +/* + * Given a handle to a dynamic library (dl) and a symbol + * name (symname), return its address. Returns -1 if the + * symbol cannot be located. (Note that the value of the + * symbol could be NULL, which is valid.) + */ +void * +locate_symbol(void *dl, char *symname, char *prefix) +{ + void *sym; + const char *err_string; + char fullname[256]; + + snprintf(fullname, sizeof(fullname), "%s%s", prefix, symname); + + if ((sym = dlsym(dl, fullname)) == NULL) { + if ((sym = dlsym(dl, symname)) == NULL) { + if ((err_string = dlerror()) != NULL) { + return (void *)-1; + } + else { + return NULL; + } + } + } + return sym; +} + +#ifdef HAVE_KRB5 +/* + * Locate all the symbols in the MIT gssapi library and + * fill in the gss_config (gss_mechanism) structure. + */ +gss_mechanism +internal_krb5_gss_initialize(void *dl) +{ + char *fname; + void *p; + void **fptr; + int i; + static int mit_krb5_initialized = 0; + + if (mit_krb5_initialized) + return (&mit_krb5_mechanism); + + fptr = (void *) &mit_krb5_mechanism.gss_acquire_cred; + + + for (i = 0, fname = glue_func_names[i]; + fname; + i++, fname = glue_func_names[i]) { + if ((p = locate_symbol(dl, fname, "krb5_")) != (void *)-1) { + *fptr++ = p; + } + else { + *fptr++ = NULL; + } + } + if (mit_krb5_mechanism.gss_internal_release_oid == NULL || + mit_krb5_mechanism.gss_internal_release_oid == (void *) -1) { + fprintf(stderr, "WARNING: unable to locate function " + "krb5_gss_internal_release_oid in krb5 mechanism library: " + "there will be problems if multiple mechanisms are used!\n"); + p = locate_symbol(dl, "krb5_gss_release_oid", ""); + if (p == NULL || p == (void *) -1) { + fprintf(stderr, "ERROR: Unable to locate function " + "krb5_gss_internal_release_oid or " + "krb5_gss_release_oid in krb5 mechanism library\n"); + return NULL; + } + } +#ifdef HAVE_SET_ALLOWABLE_ENCTYPES + /* + * Special case for set_allowable_enctypes which has a different + * name format than the rest of the gss routines :-/ + */ + if ((p = locate_symbol(dl, "gss_krb5_set_allowable_enctypes", "")) + != (void *)-1) { + mit_krb5_mechanism.gss_set_allowable_enctypes = p; + } +#endif + mit_krb5_initialized = 1; + return (&mit_krb5_mechanism); +} +#endif + +#ifdef HAVE_HEIMDAL +/* + * Locate all the symbols in the MIT gssapi library and + * fill in the gss_config (gss_mechanism) structure. + */ +gss_mechanism +internal_heimdal_gss_initialize(void *dl) +{ + char *fname; + void *p; + void **fptr; + int i; + static int heimdal_krb5_initialized = 0; + + if (heimdal_krb5_initialized) + return (&heimdal_krb5_mechanism); + + fptr = (void *) &heimdal_krb5_mechanism.gss_acquire_cred; + + + for (i = 0, fname = glue_func_names[i]; + fname; + i++, fname = glue_func_names[i]) { + if ((p = locate_symbol(dl, fname, "")) != (void *)-1) { + *fptr++ = p; + } + else { +printf("Failed to locate function '%s' !!!\n", fname); + *fptr++ = NULL; + } + } + if (heimdal_krb5_mechanism.gss_internal_release_oid == NULL || + heimdal_krb5_mechanism.gss_internal_release_oid == (void *) -1) { + fprintf(stderr, "WARNING: unable to locate function " + "gss_internal_release_oid in krb5 mechanism library: " + "there will be problems if multiple mechanisms are used!\n"); + p = locate_symbol(dl, "krb5_gss_release_oid", ""); + if (p == NULL || p == (void *) -1) { + fprintf(stderr, "ERROR: Unable to locate function " + "gss_internal_release_oid or " + "gss_release_oid in krb5 mechanism library\n"); + return NULL; + } + } + heimdal_krb5_initialized = 1; + return (&heimdal_krb5_mechanism); +} +#endif