Initial checkin of Sun's (Derek's) multi-mechanism GSSAPI support
authorTheodore Tso <tytso@mit.edu>
Wed, 15 Nov 1995 16:21:13 +0000 (16:21 +0000)
committerTheodore Tso <tytso@mit.edu>
Wed, 15 Nov 1995 16:21:13 +0000 (16:21 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7107 dc483132-0cff-0310-8789-dd5450dbe970

31 files changed:
src/lib/gssapi/mechglue/.cvsignore [new file with mode: 0644]
src/lib/gssapi/mechglue/Makefile.in [new file with mode: 0644]
src/lib/gssapi/mechglue/add_mechanism.c [new file with mode: 0644]
src/lib/gssapi/mechglue/configure.in [new file with mode: 0644]
src/lib/gssapi/mechglue/get_mech_type.c [new file with mode: 0644]
src/lib/gssapi/mechglue/get_mechanism.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_accept_sec_context.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_acquire_cred.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_compare_name.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_context_time.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_delete_sec_context.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_display_name.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_display_status.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_import_name.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_indicate_mechs.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_init_sec_context.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_initialize.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_inquire_cred.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_process_context.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_release_buffer.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_release_cred.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_release_name.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_release_oid_set.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_seal.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_sign.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_unseal.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gss_verify.c [new file with mode: 0644]
src/lib/gssapi/mechglue/gssd_pname_to_uid.c [new file with mode: 0644]
src/lib/gssapi/mechglue/internal_name.c [new file with mode: 0644]
src/lib/gssapi/mechglue/mechglue.h [new file with mode: 0644]
src/lib/gssapi/mechglue/mechglueP.h [new file with mode: 0644]

diff --git a/src/lib/gssapi/mechglue/.cvsignore b/src/lib/gssapi/mechglue/.cvsignore
new file mode 100644 (file)
index 0000000..e8c05a6
--- /dev/null
@@ -0,0 +1 @@
+configure
diff --git a/src/lib/gssapi/mechglue/Makefile.in b/src/lib/gssapi/mechglue/Makefile.in
new file mode 100644 (file)
index 0000000..b32292f
--- /dev/null
@@ -0,0 +1,98 @@
+CFLAGS = $(CCOPTS) $(DEFS) -I. -I$(srcdir)
+
+##DOSBUILDTOP = ..\..\..
+##DOSLIBNAME=..\gssapi.$(LIBEXT)
+##DOSsrcdir = .
+##DOS!include $(BUILDTOP)\config\windows.in
+
+LIBDONE=DONE
+LIB_SUBDIRSS=.
+
+SRCS   = gss_acquire_cred.c \
+         gss_release_cred.c \
+         gss_init_sec_context.c \
+         gss_accept_sec_context.c \
+         gss_process_context.c \
+         gss_delete_sec_context.c \
+         gss_context_time.c \
+         gss_sign.c \
+         gss_verify.c \
+         gss_seal.c \
+         gss_unseal.c \
+         gss_display_status.c \
+         gss_indicate_mechs.c \
+         gss_compare_name.c \
+         gss_display_name.c \
+         gss_import_name.c \
+         gss_release_name.c \
+         gss_release_buffer.c \
+         gss_release_oid_set.c \
+         gss_inquire_cred.c \
+         gss_initialize.c \
+         get_mech_type.c \
+         get_mechanism.c \
+         internal_name.c \
+         gssd_pname_to_uid.c \
+         add_mechanism.c
+
+OBJS   = gss_acquire_cred.$(OBJEXT) \
+         gss_release_cred.$(OBJEXT) \
+         gss_init_sec_context.$(OBJEXT) \
+         gss_accept_sec_context.$(OBJEXT) \
+         gss_process_context.$(OBJEXT) \
+         gss_delete_sec_context.$(OBJEXT) \
+         gss_context_time.$(OBJEXT) \
+         gss_sign.$(OBJEXT) \
+         gss_verify.$(OBJEXT) \
+         gss_seal.$(OBJEXT) \
+         gss_unseal.$(OBJEXT) \
+         gss_display_status.$(OBJEXT) \
+         gss_indicate_mechs.$(OBJEXT) \
+         gss_compare_name.$(OBJEXT) \
+         gss_display_name.$(OBJEXT) \
+         gss_import_name.$(OBJEXT) \
+         gss_release_name.$(OBJEXT) \
+         gss_release_buffer.$(OBJEXT) \
+         gss_release_oid_set.$(OBJEXT) \
+         gss_inquire_cred.$(OBJEXT) \
+         gss_initialize.$(OBJEXT) \
+         get_mech_type.$(OBJEXT) \
+         get_mechanism.$(OBJEXT) \
+         internal_name.$(OBJEXT) \
+         gssd_pname_to_uid.$(OBJEXT) \
+         add_mechanism.$(OBJEXT)
+
+EXPORTED_HEADERS = mechglue.h
+
+all:: all-$(WHAT) $(OBJS)
+
+all-unix::
+
+all-mac::
+
+all-windows::
+       if not exist $(EHDRDIR)\nul mkdir $(EHDRDIR)
+       copy mechglue.h $(EHDRDIR)
+
+unixmac: 
+
+libgssapi.$(LIBEXT): $(OBJS)
+       $(ARCHIVE) $@ $(OBJS)
+       $(RANLIB) $@
+
+clean:: clean-$(WHAT)
+
+clean-unix::
+clean-mac::
+clean-windows::
+       $(RM) $(EHDRDIR)\gssapi.h $(EHDRDIR)\gssapi_generic.h
+       if exist $(EHDRDIR)\nul rmdir $(EHDRDIR)
+
+# Krb5InstallHeaders($(EXPORTED_HEADERS), $(KRB5_INCDIR)/krb5)
+install::
+       @set -x; for f in $(EXPORTED_HEADERS) ; \
+       do $(INSTALL_DATA) $(srcdir)$(S)$$f     \
+               $(DESTDIR)$(KRB5_INCDIR)$(S)gssapi$(S)$$f ; \
+       done
diff --git a/src/lib/gssapi/mechglue/add_mechanism.c b/src/lib/gssapi/mechglue/add_mechanism.c
new file mode 100644 (file)
index 0000000..fa5ea53
--- /dev/null
@@ -0,0 +1,67 @@
+#ident "@(#)add_mechanism.c    1.5     95/08/04 SMI"
+/*
+ * This function will add a new mechanism to the mechs_array
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+#include <errno.h>
+
+static struct gss_config null_mech = {
+  {0,NULL}};
+
+gss_mechanism *mechs_array = NULL;
+
+OM_uint32 add_mechanism (gss_mechanism mech, int replace)
+{
+    gss_mechanism *temp_array;
+    int i;
+
+    if (mech == NULL)
+       return GSS_S_COMPLETE;
+
+    /* initialize the mechs_array if it hasn't already been initialized */
+    if (mechs_array == NULL) {
+       mechs_array = (gss_mechanism *) malloc (sizeof(gss_mechanism));
+
+       if (mechs_array == NULL)
+           return ENOMEM;
+
+       mechs_array[0] = &null_mech;
+    }
+
+    /* 
+     * Find the length of mechs_array, and look for an existing
+     * entry for this OID
+     */
+    for (i=0; mechs_array[i]->mech_type.length != 0; i++) {
+       if ((mechs_array[i]->mech_type.length == mech->mech_type.length) &&
+           (memcmp (mechs_array[i]->mech_type.elements, 
+                    mech->mech_type.elements,
+                    mech->mech_type.length) == 0)) {
+
+           /* We found a match.  Replace it? */
+           if (!replace)
+               return GSS_S_FAILURE;
+
+           mechs_array[i] = mech;
+           return GSS_S_COMPLETE;
+       }
+    }
+
+    /* we didn't find it -- add it to the end of the mechs_array */
+    temp_array = (gss_mechanism *) realloc(mechs_array,
+                                          (i+2)*sizeof(gss_mechanism));
+
+    if (temp_array == NULL)
+       return ENOMEM;
+
+    temp_array[i++] = mech;
+    temp_array[i] = &null_mech;
+
+    mechs_array = temp_array;
+
+    return GSS_S_COMPLETE;
+}
diff --git a/src/lib/gssapi/mechglue/configure.in b/src/lib/gssapi/mechglue/configure.in
new file mode 100644 (file)
index 0000000..3cd9048
--- /dev/null
@@ -0,0 +1,11 @@
+AC_INIT(configure.in)
+CONFIG_RULES
+AC_PROG_ARCHIVE
+AC_PROG_RANLIB
+AC_PROG_INSTALL
+CopySrcHeader(mechglue.h,[$(EHDRDIR)])
+AppendRule([install:: libgssapi.[$](LIBEXT)
+       [$](INSTALL_DATA) libgssapi.[$](LIBEXT) [$](DESTDIR)[$](KRB5_LIBDIR)[$](S)libgssapi.[$](LIBEXT)])
+LinkFileDir([$](TOPLIBD)/libgssapi.[$](LIBEXT),libgssapi.[$](LIBEXT),./gssapi/mechglue)
+AppendRule([all:: [$](TOPLIBD)/libgssapi.[$](LIBEXT)])
+V5_AC_OUTPUT_MAKEFILE
diff --git a/src/lib/gssapi/mechglue/get_mech_type.c b/src/lib/gssapi/mechglue/get_mech_type.c
new file mode 100644 (file)
index 0000000..0dc0875
--- /dev/null
@@ -0,0 +1,66 @@
+#ident  "@(#)get_mech_type.c 1.4     95/06/08 SMI"
+/*
+ *  glue routine for get_mech_type
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32 get_mech_type(OID, token)
+
+gss_OID *      OID;
+gss_buffer_t   token;
+
+{
+    unsigned char * buffer_ptr;
+    
+    /*
+     * This routine reads the prefix of "token" in order to determine
+     * its mechanism type. It assumes the encoding suggested in
+     * Appendix B of RFC 1508. This format starts out as follows :
+     *
+     * tag for APPLICATION 0, Sequence[constructed, definite length]
+     * length of remainder of token
+     * tag of OBJECT IDENTIFIER
+     * length of mechanism OID
+     * encoding of mechanism OID
+     * <the rest of the token>
+     *
+     * Numerically, this looks like :
+     *
+     * 0x60
+     * <length> - could be multiple bytes
+     * 0x06
+     * <length> - assume only one byte, hence OID length < 127
+     * <mech OID bytes>
+     *
+     * The routine returns a pointer to the OID value. The return code is
+     * the length of the OID, if successful; otherwise it is 0.
+     */
+    
+    if (OID == NULL || *OID == GSS_C_NULL_OID)
+       return (0);
+
+    /* if the token is a null pointer, return a zero length OID */
+    
+    if(token == NULL) {
+       (*OID)->length = 0;
+       (*OID)->elements = NULL;
+       return (0);
+    }
+    
+    /* Skip past the APP/Sequnce byte and the token length */
+    
+    buffer_ptr = (unsigned char *) token->value;
+    
+    while(*(++buffer_ptr) & (1<<7))
+       continue;
+    
+    /* increment buffer_ptr to point to the OID and return its length */
+    
+    (*OID)->length = (OM_uint32) *(buffer_ptr+3);
+    (*OID)->elements = (void *) (buffer_ptr+4);
+    return ((*OID)->length);
+}
diff --git a/src/lib/gssapi/mechglue/get_mechanism.c b/src/lib/gssapi/mechglue/get_mechanism.c
new file mode 100644 (file)
index 0000000..b3f7b69
--- /dev/null
@@ -0,0 +1,32 @@
+#ident  "@(#)get_mechanism.c 1.10     95/08/04 SMI"
+/*
+ *  given the mechs_array and a mechanism OID, return the 
+ *  pointer to the mechanism, or NULL if that mechanism is
+ *  not supported.  If the requested OID is NULL, then return
+ *  the first mechanism.
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+extern gss_mechanism *mechs_array;
+
+gss_mechanism get_mechanism (const_gss_OID type)
+{
+    int        i;
+
+    if (type == GSS_C_NULL_OID)
+       return (mechs_array[0]);
+
+    for (i=0; mechs_array[i]->mech_type.length != 0; i++) {
+       if ((mechs_array[i]->mech_type.length == type->length) &&
+           (memcmp (mechs_array[i]->mech_type.elements, type->elements,
+                    type->length) == 0)) {
+
+           return (mechs_array[i]);
+       }
+    }
+    return NULL;
+}
diff --git a/src/lib/gssapi/mechglue/gss_accept_sec_context.c b/src/lib/gssapi/mechglue/gss_accept_sec_context.c
new file mode 100644 (file)
index 0000000..e9fd119
--- /dev/null
@@ -0,0 +1,215 @@
+#ident  "@(#)gss_accept_sec_context.c 1.19     95/08/07 SMI"
+/*
+ *  glue routine for gss_accept_sec_context
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_accept_sec_context (minor_status,
+                        context_handle,
+                        verifier_cred_handle,
+                        input_token_buffer,
+                        input_chan_bindings,
+                        src_name,
+                        mech_type,
+                        output_token,
+                        ret_flags,
+                        time_rec,
+                        delegated_cred_handle)
+
+OM_uint32 *            minor_status;
+gss_ctx_id_t *         context_handle;
+gss_cred_id_t          verifier_cred_handle;
+gss_buffer_t           input_token_buffer;
+gss_channel_bindings_t input_chan_bindings;
+gss_name_t *           src_name;
+gss_OID *              mech_type;
+gss_buffer_t           output_token;
+int *                  ret_flags;
+OM_uint32 *            time_rec;
+gss_cred_id_t *                delegated_cred_handle;
+
+{
+    OM_uint32          status, temp_status, temp_minor_status;
+    gss_union_ctx_id_t union_ctx_id;
+    gss_union_cred_t   union_cred;
+    gss_cred_id_t      input_cred_handle = GSS_C_NO_CREDENTIAL;
+    gss_name_t         internal_name;
+    gss_buffer_desc    external_name_desc;
+    gss_buffer_t       external_name = &external_name_desc;
+    gss_OID            name_type;
+    gss_OID_desc       token_mech_type_desc;
+    gss_OID            token_mech_type = &token_mech_type_desc;
+    gss_mechanism      mech;
+    int i;
+    
+    gss_initialize();
+
+    if (context_handle == NULL)
+       return GSS_S_NO_CONTEXT;
+
+    /*
+     * if context_handle is GSS_C_NO_CONTEXT, allocate a union context
+     * descriptor to hold the mech type information as well as the
+     * underlying mechanism context handle. Otherwise, cast the
+     * value of *context_handle to the union context variable.
+     */
+    
+    if(*context_handle == GSS_C_NO_CONTEXT) {
+
+       union_ctx_id = (gss_union_ctx_id_t)
+           malloc(sizeof(gss_union_ctx_id_desc));
+
+       union_ctx_id->mech_type = (gss_OID)
+           malloc(sizeof(gss_OID_desc));
+
+       /*
+        * get the token mech type, create the context id mech type space
+        * and copy in the OID
+        */
+
+       get_mech_type(&token_mech_type, input_token_buffer);
+
+       union_ctx_id->mech_type->elements = (void *)
+           malloc(token_mech_type->length);
+
+       union_ctx_id->mech_type->length = token_mech_type->length;
+       memcpy(union_ctx_id->mech_type->elements,
+              token_mech_type->elements,
+              token_mech_type->length);
+
+       /* copy the supplied context handle */
+
+       union_ctx_id->internal_ctx_id = *context_handle;
+    } else
+       union_ctx_id = *context_handle;
+    
+    /* 
+     * get the appropriate cred handle from the union cred struct.
+     * defaults to GSS_C_NO_CREDENTIAL if there is no cred, which will
+     * use the default credential.
+     */
+    
+    union_cred = (gss_union_cred_t) verifier_cred_handle;
+    
+    if (verifier_cred_handle != GSS_C_NO_CREDENTIAL) 
+       for (i=0; i < union_cred->count; i++) {
+           if((union_cred->mechs_array[i].length == token_mech_type->length)
+              &&
+              (memcmp(union_cred->mechs_array[i].elements,
+                      token_mech_type->elements, 
+                      token_mech_type->length) == 0)) {
+               
+               input_cred_handle = union_cred->cred_array[i];
+               break;
+           }
+       }
+    
+    /*
+     * now select the approprate underlying mechanism routine and
+     * call it.
+     */
+    
+    mech = get_mechanism (token_mech_type);
+    if (mech && mech->gss_accept_sec_context) {
+
+           status = mech->gss_accept_sec_context(
+                                                 mech->context,
+                                                 minor_status,
+                                                 &union_ctx_id->internal_ctx_id,
+                                                 input_cred_handle,
+                                                 input_token_buffer,
+                                                 input_chan_bindings,
+                                                 &internal_name,
+                                                 mech_type,
+                                                 output_token,
+                                                 ret_flags,
+                                                 time_rec,
+                                                 delegated_cred_handle);
+
+           /* if the call failed, return with failure */
+
+           if(status != GSS_S_COMPLETE
+              &&
+              status != GSS_S_CONTINUE_NEEDED)
+               return(status);
+
+           /*
+            * if src_name is non-NULL,
+            * convert internal_name into a union name equivalent
+            * First call the mechanism specific display_name()
+            * then call gss_import_name() to create
+            * the union name struct cast to src_name
+            */
+
+           if(src_name != NULL) {
+               temp_status = display_internal_name (
+                                                    &temp_minor_status,
+                                                    &mech->mech_type,
+                                                    internal_name,
+                                                    external_name,
+                                                    &name_type);
+
+               if (temp_status != GSS_S_COMPLETE) {
+                       
+                   /*
+                    * this should never happen, since we just got
+                    * the name from the mechanism gss_accept_sec_context
+                    * call. However, things that can't happen often do.
+                    */
+                   if (minor_status)
+                       *minor_status = temp_minor_status;
+                   gss_release_buffer(
+                                      &temp_minor_status,
+                                      output_token);
+                   release_internal_name(&temp_minor_status,
+                                         &mech->mech_type,
+                                         &internal_name);
+                   return(GSS_S_FAILURE);
+               }
+
+               /* now create the union name */
+
+               temp_status = gss_import_name(
+                                             &temp_minor_status,
+                                             external_name,
+                                             name_type,
+                                             src_name);
+
+               if(temp_status != GSS_S_COMPLETE) {
+                   if (minor_status)
+                       *minor_status = temp_minor_status;
+                   gss_release_buffer(
+                                      &temp_minor_status,
+                                      output_token);
+                   release_internal_name(
+                                         &temp_minor_status,
+                                         &mech->mech_type,
+                                         &internal_name);
+                   gss_release_buffer(
+                                      &temp_minor_status,
+                                      external_name);
+                   return(GSS_S_FAILURE);
+               }
+
+               release_internal_name(
+                                     &temp_minor_status,
+                                     &mech->mech_type,
+                                     &internal_name);
+               gss_release_buffer(
+                                  &temp_minor_status,
+                                  external_name);
+           }
+
+       if(*context_handle == GSS_C_NO_CONTEXT)
+           *context_handle = (gss_ctx_id_t *) union_ctx_id;
+
+       return(status);
+    }
+    
+    return(GSS_S_BAD_MECH);
+}
diff --git a/src/lib/gssapi/mechglue/gss_acquire_cred.c b/src/lib/gssapi/mechglue/gss_acquire_cred.c
new file mode 100644 (file)
index 0000000..3b1c568
--- /dev/null
@@ -0,0 +1,271 @@
+#ident  "@(#)gss_acquire_cred.c 1.19     95/08/07 SMI"
+/*
+ *  glue routine for gss_acquire_cred
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_acquire_cred(minor_status,
+                 desired_name,
+                 time_req,
+                 desired_mechs,
+                cred_usage,
+                 output_cred_handle,
+                 actual_mechs,
+                 time_rec)
+
+OM_uint32 *            minor_status;
+gss_name_t             desired_name;
+OM_uint32              time_req;
+gss_OID_set            desired_mechs;
+int                    cred_usage;
+gss_cred_id_t *                output_cred_handle;
+gss_OID_set *          actual_mechs;
+OM_uint32 *            time_rec;
+
+{
+    OM_uint32          status, temp_status,
+    temp_minor_status, temp_time_rec = ~0;
+    int                        i, j, creds_acquired = 0;
+    gss_union_name_t   union_name;
+    gss_name_t         internal_name;
+    gss_union_cred_t   creds;
+    gss_OID_set_desc   default_OID_set;
+    gss_OID_desc       default_OID;
+    gss_mechanism      mech;
+    
+    /*
+     * This struct is used to keep track of which mech_types are
+     * actually available and to store the credentials returned
+     * from them by each mechanism specific gss_acquire_cred() call.
+     * The results are used to construct the final union_cred
+     * structure returned by the glue layer gss_acquire_cred() call
+     * and the actual_mechs gss_OID_set returned.
+     */
+    
+    struct creds_returned {
+       unsigned char   available;
+       gss_cred_id_t   cred;
+    } *creds_returned;
+    
+    gss_initialize();
+
+    /* Set this to NULL for now */
+
+    if (actual_mechs)
+       *actual_mechs = GSS_C_NULL_OID_SET;
+
+    if (minor_status)
+       *minor_status = 0;
+    
+    if (desired_name == GSS_C_NO_NAME)
+       return GSS_S_BAD_NAME;
+
+    /* No need to continue if we don't have a place to store the creds */
+    if (output_cred_handle == NULL)
+       return GSS_S_COMPLETE;
+
+    /* get desired_name cast as a union_name type */
+    
+    union_name = (gss_union_name_t) desired_name;
+    
+    /*
+     * if desired_mechs equals GSS_C_NULL_OID_SET, set it to the
+     * first entry in the mechs_array.
+     */
+    
+    if(desired_mechs == GSS_C_NULL_OID_SET) {
+       if ((mech = get_mechanism (NULL)) == NULL)
+           return (GSS_S_BAD_MECH);
+
+       desired_mechs = &default_OID_set;
+       default_OID_set.count = 1 ;
+       default_OID_set.elements = &default_OID;
+       default_OID.length = mech->mech_type.length;
+       default_OID.elements = mech->mech_type.elements;
+    }  
+    
+    /*
+     * Now allocate the creds returned array. There is one element
+     * for each member of the desired_mechs argument. 
+     */
+    
+    creds_returned = (struct creds_returned *)
+       malloc(sizeof(struct creds_returned)
+              * desired_mechs->count);
+    
+    /*
+     * For each requested mechanism in desired_mechs, determine if it
+     * is supported. If so, mark the corresponding element in
+     * creds_returned->available as 1 and call the mechanism
+     * specific gss_acquire_cred(), placing the returned cred in
+     * creds_returned->cred. If not, mark creds_returned->available as
+     * 0.  */
+    
+    for(j=0; j < desired_mechs->count; j++) {
+
+       creds_returned[j].available = 0;
+
+       mech = get_mechanism (&desired_mechs->elements[j]);
+       if (mech && mech->gss_acquire_cred) {
+
+           /*
+            * we first have to import the external name in
+            * union_name so it can be used in the
+            * gss_acquire_cred() call.
+            */
+
+           if ((status = import_internal_name(
+                                              minor_status,
+                                              &mech->mech_type,
+                                              union_name,
+                                              &internal_name))) {
+               status = GSS_S_BAD_NAME;
+               continue;
+           }
+                               
+           status = mech->gss_acquire_cred(
+                                           mech->context,
+                                           minor_status,
+                                           internal_name,
+                                           time_req,
+                                           desired_mechs,
+                                           cred_usage,
+                                           &creds_returned[j].cred,
+                                           NULL,
+                                           &temp_time_rec);
+
+           if ((temp_status = release_internal_name(
+                                                    &temp_minor_status,
+                                                    &mech->mech_type,
+                                                    &internal_name))) {
+               /* Not much we can do here, really... Just keep on going */
+               ;
+           }
+
+           /* 
+            * Add this into the creds_returned structure, if we got
+            * a good credential for this mechanism.
+            */
+           if(status == GSS_S_COMPLETE) {
+               if (time_rec) {
+                   *time_rec = *time_rec > temp_time_rec ?
+                       temp_time_rec : *time_rec;
+                   temp_time_rec = *time_rec;
+               }
+
+               creds_returned[j].available = 1;
+               creds_acquired++;
+           }   
+       }
+    }
+    
+    /*
+     * Now allocate the creds struct, which will be cast as a gss_cred_id_t
+     * and returned in the output_cred_handle argument. If there were
+     * no credentials found, return an error. Also, allocate the
+     * actual_mechs data.
+     */
+    
+    if(creds_acquired == 0) {
+       free (creds_returned);
+       return(GSS_S_BAD_MECH);
+    }
+    
+    creds = (gss_union_cred_t) malloc(sizeof(gss_union_cred_desc));
+    
+    creds->count = creds_acquired;
+    
+    creds->mechs_array = (gss_OID)
+       malloc(sizeof(gss_OID_desc) * creds_acquired);
+    
+    creds->cred_array = (gss_cred_id_t *)
+       malloc(sizeof(gss_cred_id_t) * creds_acquired);
+    
+    if(actual_mechs != NULL) {
+       *actual_mechs = (gss_OID_set) malloc(sizeof(gss_OID_set_desc));
+
+       (*actual_mechs)->count = creds_acquired;
+
+       (*actual_mechs)->elements = (gss_OID)
+           malloc(sizeof(gss_OID_desc) * creds_acquired);
+    }
+    
+    /*
+     * copy the mechanisms found and their allocated credentials into the
+     * creds structure. At the same time, build up the actual_mechs
+     * data.
+     */
+    
+    j = 0;
+    
+    for(i=0; i<desired_mechs->count; i++) {
+       if(creds_returned[i].available) {
+
+           creds->mechs_array[j].length =
+               desired_mechs->elements[i].length;
+           creds->mechs_array[j].elements = (void *)
+               malloc(desired_mechs->elements[i].length);
+           memcpy(creds->mechs_array[j].elements,
+                  desired_mechs->elements[i].elements,
+                  desired_mechs->elements[i].length);
+           creds->cred_array[j] = creds_returned[i].cred;
+
+           (*actual_mechs)->elements[j].length =
+               desired_mechs->elements[i].length;
+           (*actual_mechs)->elements[j].elements = (void *)
+               malloc(desired_mechs->elements[i].length);
+           memcpy((*actual_mechs)->elements[j].elements,
+                  desired_mechs->elements[i].elements,
+                  desired_mechs->elements[i].length);
+
+           j++;
+       }
+    }
+    
+    /* free the creds_returned struct, since we are done with it. */
+    
+    free(creds_returned);
+    
+    /* record the information needed for gss_inquire_cred() */
+    
+    creds->auxinfo.creation_time = time(0);
+    creds->auxinfo.time_rec = temp_time_rec;
+    creds->auxinfo.cred_usage =  cred_usage;
+    
+    /*
+     * we can't just record the internal name, desired_name, since
+     * it may be destroyed between now and the time gss_inquire_cred()
+     * is called.  So we must record the printable name in a
+     * gss_buffer_t, calling gss_display_name() to fill it in. When
+     * gss_inquire_name() is called, we must then call gss_import_name()
+     * to get the internal name that is required at that point.
+     */
+    if (gss_display_name(&temp_minor_status, desired_name,
+                        &creds->auxinfo.name, &creds->auxinfo.name_type)
+       != GSS_S_COMPLETE) {
+       
+       /* This really shouldn't ever fail, but just in case.... */
+
+       for(i=0; i < creds->count; i++) {
+           free(creds->mechs_array[i].elements);
+           free((*actual_mechs)->elements[i].elements);
+       }
+       
+       free((*actual_mechs)->elements);
+       free(*actual_mechs);
+       *actual_mechs = GSS_C_NULL_OID_SET;
+       free(creds->cred_array);
+       free(creds->mechs_array);
+       free(creds);
+       
+       return(GSS_S_BAD_NAME);
+    }
+    
+    *output_cred_handle = (gss_cred_id_t) creds;
+    return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/mechglue/gss_compare_name.c b/src/lib/gssapi/mechglue/gss_compare_name.c
new file mode 100644 (file)
index 0000000..b07ace5
--- /dev/null
@@ -0,0 +1,79 @@
+#ident  "@(#)gss_compare_name.c 1.13     95/08/02 SMI"
+/*
+ *  glue routine for gss_compare_name
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_compare_name (minor_status,
+                  name1,
+                  name2,
+                  name_equal)
+
+OM_uint32 *            minor_status;
+gss_name_t             name1;
+gss_name_t             name2;
+int *                  name_equal;
+
+{
+    OM_uint32          status;
+    gss_union_name_t   union_name1, union_name2;
+    
+    gss_initialize();
+
+    if (name1 == GSS_C_NO_NAME || name2 == GSS_C_NO_NAME) {
+       if (name_equal)
+           *name_equal = 0;
+       return GSS_S_BAD_NAME;
+    }
+
+    /*
+     * All we do here is make sure the two name_types are equal and then
+     * that the external_names are equal. Note the we do not take care
+     * of the case where two different external names map to the same
+     * internal name. We cannot determine this, since we as yet do not
+     * know what mechanism to use for calling the underlying
+     * gss_import_name().
+     */
+    
+    union_name1 = (gss_union_name_t) name1;
+    union_name2 = (gss_union_name_t) name2;
+    
+    if(name_equal != NULL)
+       *name_equal = 1;
+    else
+       return(GSS_S_COMPLETE); 
+    
+    status = GSS_S_COMPLETE;
+
+    do {
+       if((union_name1->name_type->length !=
+           union_name2->name_type->length)
+          ||
+          (memcmp(union_name1->name_type->elements,
+                  union_name2->name_type->elements,
+                  union_name1->name_type->length) != 0)) {
+           
+           *name_equal = 0;
+           break;
+       }
+    
+       if((union_name1->external_name->length !=
+           union_name2->external_name->length)
+          ||
+          (memcmp(union_name1->external_name->value,
+                  union_name2->external_name->value,
+                  union_name1->external_name->length) != 0)) {
+           
+           *name_equal = 0;
+           break;
+       }
+
+    } while (0);
+    
+    return(status);
+}
diff --git a/src/lib/gssapi/mechglue/gss_context_time.c b/src/lib/gssapi/mechglue/gss_context_time.c
new file mode 100644 (file)
index 0000000..efcd5d6
--- /dev/null
@@ -0,0 +1,53 @@
+#ident  "@(#)gss_context_time.c 1.8     95/08/07 SMI"
+/*
+ *  glue routines for gss_context_time
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_context_time (minor_status,
+                  context_handle,
+                  time_rec)
+
+OM_uint32 *            minor_status;
+gss_ctx_id_t           context_handle;
+OM_uint32 *            time_rec;
+
+{
+    OM_uint32          status;
+    gss_union_ctx_id_t ctx;
+    gss_mechanism      mech;
+
+    gss_initialize();
+
+    if (context_handle == GSS_C_NO_CONTEXT)
+       return GSS_S_NO_CONTEXT;
+    
+    /*
+     * select the approprate underlying mechanism routine and
+     * call it.
+     */
+    
+    ctx = (gss_union_ctx_id_t) context_handle;
+    mech = get_mechanism (ctx->mech_type);
+    
+    if (mech) {
+
+       if (mech->gss_context_time)
+           status = mech->gss_context_time(
+                                           mech->context,
+                                           minor_status,
+                                           ctx->internal_ctx_id,
+                                           time_rec);
+       else
+           status = GSS_S_BAD_BINDINGS;
+
+       return(status);
+    }
+    
+    return(GSS_S_NO_CONTEXT);
+}
diff --git a/src/lib/gssapi/mechglue/gss_delete_sec_context.c b/src/lib/gssapi/mechglue/gss_delete_sec_context.c
new file mode 100644 (file)
index 0000000..69866bd
--- /dev/null
@@ -0,0 +1,62 @@
+#ident  "@(#)gss_delete_sec_context.c 1.10     95/08/07 SMI"
+/*
+ *  glue routine for gss_delete_sec_context
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_delete_sec_context (minor_status,
+                        context_handle,
+                        output_token)
+
+OM_uint32 *            minor_status;
+gss_ctx_id_t *         context_handle;
+gss_buffer_t           output_token;
+
+{
+    OM_uint32          status;
+    gss_union_ctx_id_t ctx;
+    gss_mechanism      mech;
+    
+    gss_initialize();
+
+    /* if the context_handle is Null, return NO_CONTEXT error */
+    
+    if(context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT)
+       return(GSS_S_NO_CONTEXT);
+    
+    /*
+     * select the approprate underlying mechanism routine and
+     * call it.
+     */
+    
+    ctx = (gss_union_ctx_id_t) *context_handle;
+    mech = get_mechanism (ctx->mech_type);
+    
+    if (mech) {
+
+       if (mech->gss_delete_sec_context)
+           status = mech->gss_delete_sec_context(
+                                                 mech->context,
+                                                 minor_status,
+                                                 &ctx->internal_ctx_id,
+                                                 output_token);
+       else
+           status = GSS_S_BAD_BINDINGS;
+
+       /* now free up the space for the union context structure */
+       
+       free(ctx->mech_type->elements);
+       free(ctx->mech_type);
+       free(*context_handle);
+       *context_handle = NULL;
+
+       return(status);
+    }
+    
+    return(GSS_S_NO_CONTEXT);
+}
diff --git a/src/lib/gssapi/mechglue/gss_display_name.c b/src/lib/gssapi/mechglue/gss_display_name.c
new file mode 100644 (file)
index 0000000..4f1a278
--- /dev/null
@@ -0,0 +1,54 @@
+#ident  "%Z%%M% %I%     %E% SMI"
+/*
+ *  glue routine for gss_display_name()
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_display_name (minor_status,
+                  input_name,
+                  output_name_buffer,
+                  output_name_type)
+
+OM_uint32 *            minor_status;
+gss_name_t             input_name;
+gss_buffer_t           output_name_buffer;
+gss_OID *              output_name_type;
+
+{
+    gss_union_name_t   union_name;
+    
+    /*
+     * copy the value of the external_name component of the union
+     * name into the output_name_buffer and point the output_name_type
+     * to the name_type component of union_name
+     */
+    
+    if (input_name == GSS_C_NO_NAME)
+       return GSS_S_BAD_NAME;
+
+    union_name = (gss_union_name_t) input_name;
+    
+    if(output_name_type != NULL)
+       *output_name_type = union_name->name_type;
+    
+    if(output_name_buffer != NULL) {
+       output_name_buffer->length = union_name->external_name->length;
+
+       output_name_buffer->value =
+           (void *) malloc(output_name_buffer->length);
+
+       memcpy(output_name_buffer->value,
+              union_name->external_name->value,
+              output_name_buffer->length);
+    }
+    
+    if (minor_status)
+       *minor_status = 0;
+
+    return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/mechglue/gss_display_status.c b/src/lib/gssapi/mechglue/gss_display_status.c
new file mode 100644 (file)
index 0000000..43decb6
--- /dev/null
@@ -0,0 +1,59 @@
+#ident  "@(#)gss_display_status.c 1.8     95/08/07 SMI"
+/*
+ *  glue routine gss_display_status
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_display_status (minor_status,
+                    status_value,
+                    status_type,
+                    req_mech_type,
+                    message_context,
+                    status_string)
+
+OM_uint32 *            minor_status;
+int                    status_value;
+int                    status_type;
+const_gss_OID          req_mech_type;
+int *                  message_context;
+gss_buffer_t           status_string;
+
+{
+    OM_uint32          status;
+    gss_OID            mech_type = (gss_OID) req_mech_type;
+    gss_mechanism      mech;
+
+    gss_initialize();
+
+    /*
+     * select the approprate underlying mechanism routine and
+     * call it.
+     */
+
+    mech = get_mechanism (mech_type);
+
+    if (mech == NULL) 
+       return (GSS_S_BAD_MECH);
+
+    if (mech_type == GSS_C_NULL_OID)
+       mech_type = &mech->mech_type;
+
+    if (mech->gss_display_status)
+       status = mech->gss_display_status(
+                                         mech->context,
+                                         minor_status,
+                                         status_value,
+                                         status_type,
+                                         mech_type,
+                                         message_context,
+                                         status_string);
+    else
+       status = GSS_S_BAD_BINDINGS;
+
+    return(status);
+}
diff --git a/src/lib/gssapi/mechglue/gss_import_name.c b/src/lib/gssapi/mechglue/gss_import_name.c
new file mode 100644 (file)
index 0000000..6ec428d
--- /dev/null
@@ -0,0 +1,64 @@
+#ident  "%Z%%M% %I%     %E% SMI"
+/*
+ *  glue routine gss_import_name
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_import_name(minor_status,
+                input_name_buffer,
+                input_name_type,
+                output_name)
+
+OM_uint32 *            minor_status;
+gss_buffer_t           input_name_buffer;
+const_gss_OID          input_name_type;
+gss_name_t *           output_name;
+
+{
+    gss_union_name_t   union_name;
+
+    if (minor_status)
+       *minor_status = 0;
+
+    /* if output_name is NULL, simply return */
+
+    if(output_name == NULL)
+       return (GSS_S_COMPLETE);
+
+    if (input_name_buffer == GSS_C_NO_BUFFER)
+       return (GSS_S_BAD_NAME);
+
+    /*
+     * First create the union name struct that will hold the internal
+     * name and the mech_type. Then fill in the mech_type.
+     */
+
+    union_name = (gss_union_name_t) malloc (sizeof(gss_union_name_desc));
+
+    /*
+     * All we do here is record the external name and name_type.
+     * When the name is actually used, the underlying gss_import_name()
+     * is called for the appropriate mechanism. Note that the name type
+     * is assumed to be constant, so only a pointer to it is stored in
+     * union_name
+     */
+
+    union_name->external_name =
+       (gss_buffer_t) malloc(sizeof(gss_buffer_desc));
+    union_name->external_name->length = input_name_buffer->length;
+    union_name->external_name->value =
+       (void  *) malloc(input_name_buffer->length);
+    memcpy(union_name->external_name->value, input_name_buffer->value,
+          input_name_buffer->length);
+
+    union_name->name_type = (gss_OID) input_name_type;
+
+    *output_name = (gss_name_t) union_name;
+
+    return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/mechglue/gss_indicate_mechs.c b/src/lib/gssapi/mechglue/gss_indicate_mechs.c
new file mode 100644 (file)
index 0000000..3b8183e
--- /dev/null
@@ -0,0 +1,65 @@
+#ident  "@(#)gss_indicate_mechs.c 1.13     95/08/04 SMI"
+/*
+ *  glue routine for gss_indicate_mechs
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+extern gss_mechanism *mechs_array;
+
+static gss_OID_set_desc        supported_mechs_desc; 
+static gss_OID_set supported_mechs = NULL;
+
+OM_uint32
+gss_indicate_mechs (minor_status,
+                    mech_set)
+
+OM_uint32 *            minor_status;
+gss_OID_set *          mech_set;
+
+{
+    int i;
+    
+    gss_initialize();
+
+    if (minor_status)
+       *minor_status = 0;
+
+    /*
+     * If we have already computed the mechanisms supported, return
+     * a pointer to it. Otherwise, compute them and return the pointer.
+     */
+    
+    if(supported_mechs == NULL) {
+
+       supported_mechs = &supported_mechs_desc;
+       supported_mechs->count = 0;
+
+       /* Build the mech_set from the OIDs in mechs_array. */
+
+       for(i=0; mechs_array[i]->mech_type.length != 0; i++) 
+           supported_mechs->count++;
+
+       supported_mechs->elements =
+           (void *) malloc(supported_mechs->count *
+                           sizeof(gss_OID_desc));
+
+       for(i=0; i < supported_mechs->count; i++) {
+           supported_mechs->elements[i].length =
+               mechs_array[i]->mech_type.length;
+           supported_mechs->elements[i].elements = (void *)
+               malloc(mechs_array[i]->mech_type.length);
+           memcpy(supported_mechs->elements[i].elements,
+                  mechs_array[i]->mech_type.elements,
+                  mechs_array[i]->mech_type.length);
+       }
+    }
+    
+    if(mech_set != NULL)
+       *mech_set = supported_mechs;
+    
+    return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/mechglue/gss_init_sec_context.c b/src/lib/gssapi/mechglue/gss_init_sec_context.c
new file mode 100644 (file)
index 0000000..ed6f81f
--- /dev/null
@@ -0,0 +1,147 @@
+#ident  "@(#)gss_init_sec_context.c 1.20     95/08/07 SMI"
+/*
+ *  glue routine for gss_init_sec_context
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_init_sec_context (minor_status,
+                      claimant_cred_handle,
+                      context_handle,
+                      target_name,
+                      req_mech_type,
+                      req_flags,
+                      time_req,
+                      input_chan_bindings,
+                      input_token,
+                      actual_mech_type,
+                      output_token,
+                      ret_flags,
+                      time_rec)
+
+OM_uint32 *            minor_status;
+gss_cred_id_t          claimant_cred_handle;
+gss_ctx_id_t *         context_handle;
+gss_name_t             target_name;
+const_gss_OID          req_mech_type;
+int                    req_flags;
+int                    time_req;
+gss_channel_bindings_t input_chan_bindings;
+gss_buffer_t           input_token;
+gss_OID *              actual_mech_type;
+gss_buffer_t           output_token;
+int *                  ret_flags;
+OM_uint32 *            time_rec;
+
+{
+    OM_uint32          status, temp_status, temp_minor_status;
+    gss_union_name_t   union_name;
+    gss_name_t         internal_name;
+    gss_union_ctx_id_t union_ctx_id;
+    gss_OID            mech_type = (gss_OID) req_mech_type;
+    gss_mechanism      mech;
+
+    gss_initialize();
+
+    if (context_handle == NULL)
+       return GSS_S_NO_CONTEXT;
+    
+    /*
+     * obtain the gss mechanism information for the requested
+     * mechanism.  If mech_type is NULL, set it to the resultant
+     * mechanism
+     */
+    mech = get_mechanism (mech_type);
+    if (mech == NULL)
+       return (GSS_S_BAD_MECH);
+
+    if (mech_type == GSS_C_NULL_OID)
+       mech_type = &mech->mech_type;
+
+    /* 
+     * Get the internal name for the mechanism requested from 
+     * the supplied target name.
+     */
+
+    union_name = (gss_union_name_t) target_name;
+    
+    if ((temp_status = import_internal_name (
+                                            minor_status,
+                                            mech_type,
+                                            union_name,
+                                            &internal_name)))
+       return (GSS_S_BAD_NAME);
+
+    /*
+     * if context_handle is GSS_C_NO_CONTEXT, allocate a union context
+     * descriptor to hold the mech type information as well as the
+     * underlying mechanism context handle. Otherwise, cast the
+     * value of *context_handle to the union context variable.
+     */
+    
+    if(*context_handle == GSS_C_NO_CONTEXT) {
+       union_ctx_id = (gss_union_ctx_id_t)
+           malloc(sizeof(gss_union_ctx_id_desc));
+
+       union_ctx_id->mech_type = (gss_OID)
+           malloc(sizeof(gss_OID_desc));
+
+       /* copy in the mech type information */
+
+       union_ctx_id->mech_type->elements = (void *)
+           malloc(mech_type->length);
+
+       union_ctx_id->mech_type->length = mech_type->length;
+       memcpy(union_ctx_id->mech_type->elements, mech_type->elements,
+              mech_type->length);
+
+       /* copy the supplied context handle */
+
+       union_ctx_id->internal_ctx_id = *context_handle;
+    } else
+       union_ctx_id = *context_handle;
+    
+    /*
+     * now call the approprate underlying mechanism routine 
+     */
+    
+    if (mech->gss_init_sec_context) {
+       status = mech->gss_init_sec_context(
+                                           mech->context,
+                                           minor_status,
+                                           claimant_cred_handle,
+                                           &union_ctx_id->internal_ctx_id,
+                                           internal_name,
+                                           mech_type,
+                                           req_flags,
+                                           time_req,
+                                           input_chan_bindings,
+                                           input_token,
+                                           actual_mech_type,
+                                           output_token,
+                                           ret_flags,
+                                           time_rec);
+
+       if (*context_handle == GSS_C_NO_CONTEXT)
+           *context_handle = (gss_ctx_id_t) union_ctx_id;
+
+    } else
+       status = GSS_S_BAD_BINDINGS;
+
+    temp_status = release_internal_name(
+                                       &temp_minor_status,
+                                       mech_type,
+                                       &internal_name);
+           
+    if (temp_status != GSS_S_COMPLETE) {
+       if (minor_status)
+           *minor_status = temp_minor_status;
+       return(GSS_S_BAD_NAME);
+    }
+    
+    return(status);
+}
diff --git a/src/lib/gssapi/mechglue/gss_initialize.c b/src/lib/gssapi/mechglue/gss_initialize.c
new file mode 100644 (file)
index 0000000..a6e7ed1
--- /dev/null
@@ -0,0 +1,34 @@
+#ident "@(#)gss_initialize.c   1.5     95/09/11 SMI"
+/*
+ * This function will initialize the gssapi mechglue library
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+static int _gss_initialized = 0;
+
+void gss_initialize (void)
+{
+    gss_mechanism mech;
+
+    /* Make sure we've not run already */
+    if (_gss_initialized)
+       return;
+    _gss_initialized = 1;
+
+    /* 
+     * Use hard-coded in mechanisms...  I need to know what mechanisms
+     * are supported...  As more mechanisms become supported, they
+     * should be added here, unless shared libraries are used.
+     */
+
+    /* Initialize the krb5 mechanism */
+    mech = (gss_mechanism)krb5_gss_initialize();
+    if (mech)
+       add_mechanism (mech, 1);
+
+    return;
+}
diff --git a/src/lib/gssapi/mechglue/gss_inquire_cred.c b/src/lib/gssapi/mechglue/gss_inquire_cred.c
new file mode 100644 (file)
index 0000000..460e8c3
--- /dev/null
@@ -0,0 +1,104 @@
+#ident  "@(#)gss_inquire_cred.c 1.9     95/08/02 SMI"
+/*
+ *  glue routine for gss_inquire_cred
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_inquire_cred(minor_status,
+                 cred_handle,
+                 name,
+                 lifetime,
+                cred_usage,
+                 mechanisms)
+
+OM_uint32 *            minor_status;
+gss_cred_id_t          cred_handle;
+gss_name_t *           name;
+OM_uint32 *            lifetime;
+int *                  cred_usage;
+gss_OID_set *          mechanisms;
+
+{
+    OM_uint32          status, elapsed_time, temp_minor_status;
+    gss_union_cred_t   union_cred;
+    int                        i;
+    
+    gss_initialize();
+
+    if(cred_handle == GSS_C_NO_CREDENTIAL)
+       
+       /* This action doesn't conform to the spec. We are supposed
+        * to return information about the default credential.
+        * However, we don't know what mechanism the default
+        * credential is associated with, so we can't call
+        * the mechanism specific version of gss_inquire_cred().
+        * Consequently, we just return NO_CRED.
+        */
+       
+       return(GSS_S_NO_CRED);
+    else
+       
+       /* get the cred_handle cast as a union_credentials structure */
+       
+       union_cred = (gss_union_cred_t) cred_handle;
+    
+    /*
+     * get the information out of the union_cred structure that was
+     * placed there during gss_acquire_cred.
+     */
+    
+    if(cred_usage != NULL)
+       *cred_usage = union_cred->auxinfo.cred_usage;
+    
+    if(lifetime != NULL) {
+       elapsed_time = time(0) - union_cred->auxinfo.creation_time;
+       *lifetime = union_cred->auxinfo.time_rec < elapsed_time ? 0 :
+       union_cred->auxinfo.time_rec - elapsed_time;
+    }
+    
+    /*
+     * if name is non_null,
+     * call gss_import_name(), giving it the printable name held within
+     * union_cred in order to get an internal name to pass back to the
+     * caller. If this call fails, return failure to our caller.
+     */
+    
+    if(name != NULL)
+       if(gss_import_name(&temp_minor_status,
+                          &union_cred->auxinfo.name,
+                          union_cred->auxinfo.name_type,
+                          name) != GSS_S_COMPLETE)
+           return(GSS_S_DEFECTIVE_CREDENTIAL);
+    
+    /*
+     * copy the mechanism set in union_cred into an OID set and return in
+     * the mechanisms parameter.
+     */
+    
+    if(mechanisms != NULL) {
+
+       *mechanisms = (gss_OID_set) malloc(sizeof(gss_OID_set_desc));
+
+       (*mechanisms)->count = union_cred->count;
+       (*mechanisms)->elements =
+           (gss_OID) malloc(sizeof(gss_OID_desc) *
+                            union_cred->count);
+
+       for(i=0; i < union_cred->count; i++) {
+           (*mechanisms)->elements[i].length =
+               union_cred->mechs_array[i].length;
+           (*mechanisms)->elements[i].elements = (void *)
+               malloc(union_cred->mechs_array[i].length);
+           memcpy((*mechanisms)->elements[i].elements,
+                  union_cred->mechs_array[i].elements,
+                  union_cred->mechs_array[i].length);
+       }
+    }
+    
+    return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/mechglue/gss_process_context.c b/src/lib/gssapi/mechglue/gss_process_context.c
new file mode 100644 (file)
index 0000000..e44e416
--- /dev/null
@@ -0,0 +1,53 @@
+#ident  "@(#)gss_process_context.c 1.9     95/08/07 SMI"
+/*
+ *  glue routine gss_process_context
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_process_context_token (minor_status,
+                           context_handle,
+                           token_buffer)
+
+OM_uint32 *            minor_status;
+gss_ctx_id_t           context_handle;
+gss_buffer_t           token_buffer;
+
+{
+    OM_uint32          status;
+    gss_union_ctx_id_t ctx;
+    gss_mechanism      mech;
+    
+    gss_initialize();
+
+    if (context_handle == GSS_C_NO_CONTEXT)
+       return GSS_S_NO_CONTEXT;
+
+    /*
+     * select the approprate underlying mechanism routine and
+     * call it.
+     */
+    
+    ctx = (gss_union_ctx_id_t) context_handle;
+    mech = get_mechanism (ctx->mech_type);
+
+    if (mech) {
+
+       if (mech->gss_process_context_token)
+           status = mech->gss_process_context_token(
+                                                   mech->context,
+                                                   minor_status,
+                                                   ctx->internal_ctx_id,
+                                                   token_buffer);
+       else
+           status = GSS_S_BAD_BINDINGS;
+
+       return(status);
+    }
+    
+    return(GSS_S_NO_CONTEXT);
+}
diff --git a/src/lib/gssapi/mechglue/gss_release_buffer.c b/src/lib/gssapi/mechglue/gss_release_buffer.c
new file mode 100644 (file)
index 0000000..99ed4d5
--- /dev/null
@@ -0,0 +1,34 @@
+#ident  "%Z%%M% %I%     %E% SMI"
+/*
+ *  glue routine for gss_release_buffer
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_release_buffer (minor_status,
+                   buffer)
+
+OM_uint32 *            minor_status;
+gss_buffer_t           buffer;
+{
+    if (minor_status)
+       *minor_status = 0;
+
+    /* if buffer is NULL, return */
+
+    if(buffer == GSS_C_NO_BUFFER)
+       return(GSS_S_COMPLETE);
+
+    if ((buffer->length) &&
+       (buffer->value)) {
+           free(buffer->value);
+           buffer->length = 0;
+           buffer->value = NULL;
+    }
+
+    return (GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/mechglue/gss_release_cred.c b/src/lib/gssapi/mechglue/gss_release_cred.c
new file mode 100644 (file)
index 0000000..2ef9427
--- /dev/null
@@ -0,0 +1,74 @@
+#ident  "@(#)gss_release_cred.c 1.15     95/08/07 SMI"
+/*
+ *  glue routine for gss_release_cred
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_release_cred(minor_status,
+                 cred_handle)
+
+OM_uint32 *            minor_status;
+gss_cred_id_t *                cred_handle;
+
+{
+    OM_uint32          status, temp_status;
+    int                        j;
+    gss_union_cred_t   union_cred;
+    gss_mechanism      mech;
+    
+    gss_initialize();
+
+    if (minor_status)
+       *minor_status = 0;
+
+    /* if the cred_handle is null, return a NO_CRED error */
+    
+    if (cred_handle == GSS_C_NO_CREDENTIAL)
+       return(GSS_S_NO_CRED);
+    
+    /*
+     * Loop through the union_cred struct, selecting the approprate 
+     * underlying mechanism routine and calling it. At the end,
+     * release all of the storage taken by the union_cred struct.
+     */
+    
+    union_cred = (gss_union_cred_t) *cred_handle;
+    *cred_handle = NULL;
+
+    if (union_cred == NULL)
+       return GSS_S_NO_CRED;
+
+    status = GSS_S_COMPLETE;
+    
+    for(j=0; j < union_cred->count; j++) {
+
+       mech = get_mechanism (&union_cred->mechs_array[j]);
+
+       if (mech) {
+
+           if (mech->gss_release_cred) {
+               temp_status = mech->gss_release_cred
+                   (mech->context,
+                    minor_status,
+                    &union_cred->cred_array[j]);
+
+           if (temp_status != GSS_S_COMPLETE)
+               status = GSS_S_NO_CRED;
+
+           } else
+               status = GSS_S_NO_CRED;
+       } else
+           status = GSS_S_NO_CRED;
+    }
+
+    free(union_cred->cred_array);
+    free(union_cred->mechs_array);
+    free(union_cred);
+    
+    return(status);
+}
diff --git a/src/lib/gssapi/mechglue/gss_release_name.c b/src/lib/gssapi/mechglue/gss_release_name.c
new file mode 100644 (file)
index 0000000..87b7d31
--- /dev/null
@@ -0,0 +1,43 @@
+#ident  "@(#)gss_release_name.c 1.2     95/05/09 SMI"
+/*
+ *  glue routine for gss_release_name
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_release_name (minor_status,
+                 input_name)
+
+OM_uint32 *            minor_status;
+gss_name_t *           input_name;
+
+{
+    gss_union_name_t   union_name;
+    
+    /* if input_name is NULL, return error */
+    
+    if(input_name == GSS_C_NO_NAME)
+       return(GSS_S_BAD_NAME);
+    
+    /*
+     * free up the space for the external_name and then
+     * free the union_name descriptor
+     */
+    
+    union_name = (gss_union_name_t) *input_name;
+    *input_name = GSS_C_NO_NAME;
+    *minor_status = 0;
+    
+    if (union_name == NULL)
+       return GSS_S_BAD_NAME;
+    
+    free(union_name->external_name->value);
+    free(union_name->external_name);
+    free(union_name);
+
+    return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/mechglue/gss_release_oid_set.c b/src/lib/gssapi/mechglue/gss_release_oid_set.c
new file mode 100644 (file)
index 0000000..3a98df2
--- /dev/null
@@ -0,0 +1,33 @@
+#ident  "@(#)gss_release_oid_set.c 1.12     95/08/23 SMI"
+/*
+ *  glue routine for gss_release_oid_set
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_release_oid_set (minor_status,
+                    set)
+
+OM_uint32 *            minor_status;
+gss_OID_set *          set;
+{
+    if (minor_status)
+       *minor_status = 0;
+
+    if (set ==NULL)
+       return GSS_S_COMPLETE;
+
+    if (*set == GSS_C_NULL_OID_SET)
+       return(GSS_S_COMPLETE);
+
+    free((*set)->elements);
+    free(*set);
+
+    *set = GSS_C_NULL_OID_SET;
+    
+    return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/mechglue/gss_seal.c b/src/lib/gssapi/mechglue/gss_seal.c
new file mode 100644 (file)
index 0000000..47cb5c5
--- /dev/null
@@ -0,0 +1,64 @@
+#ident  "@(#)gss_seal.c 1.10     95/08/07 SMI"
+/*
+ *  glue routine for gss_seal
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_seal (minor_status,
+          context_handle,
+          conf_req_flag,
+          qop_req,
+          input_message_buffer,
+          conf_state,
+          output_message_buffer)
+
+OM_uint32 *            minor_status;
+gss_ctx_id_t           context_handle;
+int                    conf_req_flag;
+int                    qop_req;
+gss_buffer_t           input_message_buffer;
+int *                  conf_state;
+gss_buffer_t           output_message_buffer;
+
+{
+    OM_uint32          status;
+    gss_union_ctx_id_t ctx;
+    gss_mechanism      mech;
+
+    gss_initialize();
+    
+    if (context_handle == GSS_C_NO_CONTEXT)
+       return GSS_S_NO_CONTEXT;
+
+    /*
+     * select the approprate underlying mechanism routine and
+     * call it.
+     */
+    
+    ctx = (gss_union_ctx_id_t) context_handle;
+    mech = get_mechanism (ctx->mech_type);
+    
+    if (mech) {
+       if (mech->gss_seal)
+           status = mech->gss_seal(
+                                   mech->context,
+                                   minor_status,
+                                   ctx->internal_ctx_id,
+                                   conf_req_flag,
+                                   qop_req,
+                                   input_message_buffer,
+                                   conf_state,
+                                   output_message_buffer);
+       else
+           status = GSS_S_BAD_BINDINGS;
+       
+       return(status);
+    }
+
+    return(GSS_S_NO_CONTEXT);
+}
diff --git a/src/lib/gssapi/mechglue/gss_sign.c b/src/lib/gssapi/mechglue/gss_sign.c
new file mode 100644 (file)
index 0000000..ba00f28
--- /dev/null
@@ -0,0 +1,58 @@
+#ident  "@(#)gss_sign.c 1.10     95/08/07 SMI"
+/*
+ *  glue routine gss_sign
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_sign (minor_status,
+          context_handle,
+          qop_req,
+          message_buffer,
+          msg_token)
+
+OM_uint32 *            minor_status;
+gss_ctx_id_t           context_handle;
+int                    qop_req;
+gss_buffer_t           message_buffer;
+gss_buffer_t           msg_token;
+
+{
+    OM_uint32          status;
+    gss_union_ctx_id_t ctx;
+    gss_mechanism      mech;
+
+    gss_initialize();
+
+    if (context_handle == GSS_C_NO_CONTEXT)
+       return GSS_S_NO_CONTEXT;
+
+    /*
+     * select the approprate underlying mechanism routine and
+     * call it.
+     */
+
+    ctx = (gss_union_ctx_id_t) context_handle;
+    mech = get_mechanism (ctx->mech_type);
+
+    if (mech) {
+       if (mech->gss_sign)
+           status = mech->gss_sign(
+                                   mech->context,
+                                   minor_status,
+                                   ctx->internal_ctx_id,
+                                   qop_req,
+                                   message_buffer,
+                                   msg_token);
+       else
+           status = GSS_S_BAD_BINDINGS;
+
+       return(status);
+    }
+
+    return(GSS_S_NO_CONTEXT);
+}
diff --git a/src/lib/gssapi/mechglue/gss_unseal.c b/src/lib/gssapi/mechglue/gss_unseal.c
new file mode 100644 (file)
index 0000000..97d19a5
--- /dev/null
@@ -0,0 +1,61 @@
+#ident  "@(#)gss_unseal.c 1.10     95/08/07 SMI"
+/*
+ *  glue routine gss_unseal
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_unseal (minor_status,
+            context_handle,
+            input_message_buffer,
+            output_message_buffer,
+            conf_state,
+            qop_state)
+
+OM_uint32 *            minor_status;
+gss_ctx_id_t           context_handle;
+gss_buffer_t           input_message_buffer;
+gss_buffer_t           output_message_buffer;
+int *                  conf_state;
+int *                  qop_state;
+
+{
+    OM_uint32          status;
+    gss_union_ctx_id_t ctx;
+    gss_mechanism      mech;
+
+    gss_initialize();
+
+    if (context_handle == GSS_C_NO_CONTEXT)
+       return GSS_S_NO_CONTEXT;
+
+    /*
+     * select the approprate underlying mechanism routine and
+     * call it.
+     */
+
+    ctx = (gss_union_ctx_id_t) context_handle;
+    mech = get_mechanism (ctx->mech_type);
+
+    if (mech) {
+       if (mech->gss_unseal) 
+           status = mech->gss_unseal(
+                                     mech->context,
+                                     minor_status,
+                                     ctx->internal_ctx_id,
+                                     input_message_buffer,
+                                     output_message_buffer,
+                                     conf_state,
+                                     qop_state);
+       else
+           status = GSS_S_BAD_BINDINGS;
+
+       return(status);
+    }
+
+    return(GSS_S_NO_CONTEXT);
+}
diff --git a/src/lib/gssapi/mechglue/gss_verify.c b/src/lib/gssapi/mechglue/gss_verify.c
new file mode 100644 (file)
index 0000000..5078493
--- /dev/null
@@ -0,0 +1,58 @@
+#ident  "@(#)gss_verify.c 1.9     95/08/07 SMI"
+/*
+ *  glue routine for gss_verify
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32
+gss_verify (minor_status,
+            context_handle,
+            message_buffer,
+            token_buffer,
+            qop_state)
+
+OM_uint32 *            minor_status;
+gss_ctx_id_t           context_handle;
+gss_buffer_t           message_buffer;
+gss_buffer_t           token_buffer;
+int *                  qop_state;
+
+{
+    OM_uint32          status;
+    gss_union_ctx_id_t ctx;
+    gss_mechanism      mech;
+
+    gss_initialize();
+
+    if (context_handle == GSS_C_NO_CONTEXT)
+       return GSS_S_NO_CONTEXT;
+
+    /*
+     * select the approprate underlying mechanism routine and
+     * call it.
+     */
+
+    ctx = (gss_union_ctx_id_t) context_handle;
+    mech = get_mechanism (ctx->mech_type);
+
+    if (mech) {
+       if (mech->gss_verify)
+           status = mech->gss_verify(
+                                     mech->context,
+                                     minor_status,
+                                     ctx->internal_ctx_id,
+                                     message_buffer,
+                                     token_buffer,
+                                     qop_state);
+       else
+           status = GSS_S_BAD_BINDINGS;
+
+       return(status);
+    }
+
+    return(GSS_S_NO_CONTEXT);
+}
diff --git a/src/lib/gssapi/mechglue/gssd_pname_to_uid.c b/src/lib/gssapi/mechglue/gssd_pname_to_uid.c
new file mode 100644 (file)
index 0000000..da0da92
--- /dev/null
@@ -0,0 +1,45 @@
+#ident  "@(#)gssd_pname_to_uid.c 1.5     95/08/02 SMI"
+/*
+ *  glue routines that test the mech id either passed in to
+ *  gss_init_sec_contex() or gss_accept_sec_context() or within the glue
+ *  routine supported version of the security context and then call
+ *  the appropriate underlying mechanism library procedure. 
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+int gssd_pname_to_uid(pname, name_type, mech_type, uid)
+
+char * pname;
+gss_OID name_type;
+gss_OID mech_type;
+uid_t * uid;
+{
+    int status;
+    gss_mechanism      mech;
+
+    gss_initialize();
+
+    /*
+     * find the appropriate mechanism specific pname_to_uid procedure and
+     * call it.
+     */
+
+    mech = get_mechanism (mech_type);
+
+    if (mech) {
+       if (mech_type == GSS_C_NULL_OID)
+           mech_type = &mech->mech_type;
+
+       if (mech->pname_to_uid)
+           status = mech->pname_to_uid(pname, name_type, mech_type, uid);
+       else
+           status = GSS_S_BAD_MECH;
+    } else
+       status = GSS_S_BAD_MECH;
+
+    return(status);
+}
diff --git a/src/lib/gssapi/mechglue/internal_name.c b/src/lib/gssapi/mechglue/internal_name.c
new file mode 100644 (file)
index 0000000..0fba73f
--- /dev/null
@@ -0,0 +1,90 @@
+#ident  "@(#)internal_name.c 1.5     95/08/07 SMI"
+/*
+ *  Internal routines to get and release an internal mechanism name
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#include "mechglueP.h"
+
+OM_uint32 import_internal_name (minor_status, mech_type, union_name, 
+                               internal_name)
+OM_uint32      *minor_status;
+gss_OID                mech_type;
+gss_union_name_t       union_name;
+gss_name_t     *internal_name;
+{
+    OM_uint32          status;
+    gss_mechanism      mech;
+
+    mech = get_mechanism (mech_type);
+    if (mech) {
+       if (mech->gss_import_name)
+           status = mech->gss_import_name (
+                                           mech->context,
+                                           minor_status,
+                                           union_name->external_name,
+                                           union_name->name_type,
+                                           internal_name);
+       else
+           status = GSS_S_BAD_BINDINGS;
+
+       return (status);
+    }
+
+    return (GSS_S_BAD_MECH);
+}
+
+OM_uint32 display_internal_name (minor_status, mech_type, internal_name, 
+                                external_name, name_type)
+OM_uint32      *minor_status;
+gss_OID                mech_type;
+gss_name_t     internal_name;
+gss_buffer_t   external_name;
+gss_OID                *name_type;
+{
+    OM_uint32          status;
+    gss_mechanism      mech;
+
+    mech = get_mechanism (mech_type);
+    if (mech) {
+       if (mech->gss_display_name)
+           status = mech->gss_display_name (
+                                            mech->context,
+                                            minor_status,
+                                            internal_name,
+                                            external_name,
+                                            name_type);
+       else
+           status = GSS_S_BAD_BINDINGS;
+
+       return (status);
+    }
+
+    return (GSS_S_BAD_MECH);
+}
+
+OM_uint32 release_internal_name (minor_status, mech_type, internal_name)
+OM_uint32      *minor_status;
+gss_OID                mech_type;
+gss_name_t     *internal_name;
+{
+    OM_uint32          status;
+    gss_mechanism      mech;
+
+    mech = get_mechanism (mech_type);
+    if (mech) {
+       if (mech->gss_release_name)
+           status = mech->gss_release_name (
+                                            mech->context,
+                                            minor_status,
+                                            internal_name);
+       else
+           status = GSS_S_BAD_BINDINGS;
+
+       return (status);
+    }
+
+    return (GSS_S_BAD_MECH);
+}
diff --git a/src/lib/gssapi/mechglue/mechglue.h b/src/lib/gssapi/mechglue/mechglue.h
new file mode 100644 (file)
index 0000000..304bcfb
--- /dev/null
@@ -0,0 +1,22 @@
+#ident  "@(#)mechglue.h 1.13     95/08/07 SMI"
+/*
+ * This header contains the mechglue definitions.
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _GSS_MECHGLUE_H
+#define _GSS_MECHGLUE_H
+
+#include <gssapi/gssapi.h>
+#include <sys/types.h>
+
+/********************************************************/
+/* GSSAPI Extension functions -- these functions aren't */
+/* in the GSSAPI, but they are provided in this library */
+
+int gssd_pname_to_uid (char *, gss_OID, gss_OID, uid_t *);
+void gss_initialize (void);
+
+#endif /* _GSS_MECHGLUE_H */
diff --git a/src/lib/gssapi/mechglue/mechglueP.h b/src/lib/gssapi/mechglue/mechglueP.h
new file mode 100644 (file)
index 0000000..34f007f
--- /dev/null
@@ -0,0 +1,239 @@
+#ident  "%Z%%M% %I%     %E% SMI"
+/*
+ * This header contains the private mechglue definitions.
+ *
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _GSS_MECHGLUEP_H
+#define _GSS_MECHGLUEP_H
+
+#include <gssapi/mechglue.h>
+#include <sys/types.h>
+
+/*
+ * Array of context IDs typed by mechanism OID
+ */
+typedef struct gss_union_ctx_id_t {
+       gss_OID                 mech_type;
+       gss_ctx_id_t            internal_ctx_id;
+} gss_union_ctx_id_desc, *gss_union_ctx_id_t;
+
+/*
+ * Array of names typed by the name OID (XXX - mechanism OID?)
+ */
+typedef struct gss_union_name_t {
+       gss_OID                 name_type;
+       gss_buffer_t            external_name;
+} gss_union_name_desc, *gss_union_name_t;
+
+/*
+ * Credential auxiliary info, used in the credential structure
+ */
+typedef struct gss_union_cred_auxinfo {
+       gss_buffer_desc         name;
+       gss_OID                 name_type;
+       time_t                  creation_time;
+       OM_uint32               time_rec;
+       int                     cred_usage;
+} gss_union_cred_auxinfo;
+
+/*
+ * Set of Credentials typed on mechanism OID
+ */
+typedef struct gss_union_cred_t {
+       int                     count;
+       gss_OID                 mechs_array;
+       gss_cred_id_t *         cred_array;
+       gss_union_cred_auxinfo  auxinfo;
+} gss_union_cred_desc, *gss_union_cred_t;
+/********************************************************/
+/* The Mechanism Dispatch Table -- a mechanism needs to */
+/* define one of these and provide a function to return */
+/* it to initialize the GSSAPI library                  */
+
+/*
+ * This is the definition of the mechs_array struct, which is used to
+ * define the mechs array table. This table is used to indirectly
+ * access mechanism specific versions of the gssapi routines through
+ * the routines in the glue module (gssd_mech_glue.c)
+ *
+ * This contants all of the functions defined in gssapi.h except for
+ * gss_release_buffer() and gss_release_oid_set(), which I am
+ * assuming, for now, to be equal across mechanisms.  
+ */
+typedef struct gss_config {
+    gss_OID_desc    mech_type;
+    void *         context;
+    OM_uint32       (*gss_acquire_cred)
+       (void*,                 /* context */
+        OM_uint32*,            /* minor_status */
+        gss_name_t,            /* desired_name */
+        OM_uint32,             /* time_req */
+        gss_OID_set,           /* desired_mechs */
+        int,                   /* cred_usage */
+        gss_cred_id_t*,        /* output_cred_handle */
+        gss_OID_set*,          /* actual_mechs */
+        OM_uint32*             /* time_rec */
+        );
+    OM_uint32       (*gss_release_cred)
+       (void*,                 /* context */                  
+        OM_uint32*,            /* minor_status */
+        gss_cred_id_t*         /* cred_handle */
+        );
+    OM_uint32       (*gss_init_sec_context)
+       (void*,                 /* context */
+        OM_uint32*,            /* minor_status */
+        gss_cred_id_t,         /* claimant_cred_handle */
+        gss_ctx_id_t*,         /* context_handle */
+        gss_name_t,            /* target_name */
+        const_gss_OID,         /* mech_type */
+        int,                   /* req_flags */
+        OM_uint32,             /* time_req */
+        gss_channel_bindings_t, /* input_chan_bindings */
+        gss_buffer_t,          /* input_token */
+        gss_OID*,              /* actual_mech_type */
+        gss_buffer_t,          /* output_token */
+        int*,                  /* ret_flags */
+        OM_uint32*             /* time_rec */
+        );
+    OM_uint32       (*gss_accept_sec_context)
+       (void*,                 /* context */
+        OM_uint32*,            /* minor_status */
+        gss_ctx_id_t*,         /* context_handle */
+        gss_cred_id_t,         /* verifier_cred_handle */
+        gss_buffer_t,          /* input_token_buffer */
+        gss_channel_bindings_t, /* input_chan_bindings */
+        gss_name_t*,           /* src_name */
+        gss_OID*,              /* mech_type */
+        gss_buffer_t,          /* output_token */
+        int*,                  /* ret_flags */
+        OM_uint32*,            /* time_rec */
+        gss_cred_id_t*         /* delegated_cred_handle */
+        );
+    OM_uint32       (*gss_process_context_token)
+       (void*,                 /* context */
+        OM_uint32*,            /* minor_status */
+        gss_ctx_id_t,          /* context_handle */
+        gss_buffer_t           /* token_buffer */
+        );
+    OM_uint32       (*gss_delete_sec_context)
+       (void*,                 /* context */
+        OM_uint32*,            /* minor_status */
+        gss_ctx_id_t*,         /* context_handle */
+        gss_buffer_t           /* output_token */
+        );
+    OM_uint32       (*gss_context_time)
+       (void*,                 /* context */
+        OM_uint32*,            /* minor_status */
+        gss_ctx_id_t,          /* context_handle */
+        OM_uint32*             /* time_rec */
+        );
+    OM_uint32       (*gss_sign)
+       (void*,                 /* context */
+        OM_uint32*,            /* minor_status */
+        gss_ctx_id_t,          /* context_handle */
+        int,                   /* qop_req */
+        gss_buffer_t,          /* message_buffer */
+        gss_buffer_t           /* message_token */
+        );
+    OM_uint32       (*gss_verify)
+       (void*,                 /* context */
+        OM_uint32*,            /* minor_status */
+        gss_ctx_id_t,          /* context_handle */
+        gss_buffer_t,          /* message_buffer */
+        gss_buffer_t,          /* token_buffer */
+        int*                   /* qop_state */
+        );
+    OM_uint32       (*gss_seal)
+       (void*,                 /* context */
+        OM_uint32*,            /* minor_status */
+        gss_ctx_id_t,          /* context_handle */
+        int,                   /* conf_req_flag */
+        int,                   /* qop_req */
+        gss_buffer_t,          /* input_message_buffer */
+        int*,                  /* conf_state */
+        gss_buffer_t           /* output_message_buffer */
+        );
+    OM_uint32       (*gss_unseal)
+       (void*,                 /* context */
+        OM_uint32*,            /* minor_status */
+        gss_ctx_id_t,          /* context_handle */
+        gss_buffer_t,          /* input_message_buffer */
+        gss_buffer_t,          /* output_message_buffer */
+        int*,                  /* conf_state */
+        int*                   /* qop_state */
+        );
+    OM_uint32       (*gss_display_status)
+       (void*,                 /* context */
+        OM_uint32*,            /* minor_status */
+        OM_uint32,             /* status_value */
+        int,                   /* status_type */
+        const_gss_OID,         /* mech_type */
+        int*,                  /* message_context */
+        gss_buffer_t           /* status_string */
+        );
+    OM_uint32       (*gss_indicate_mechs)
+       (void*,                 /* context */
+        OM_uint32*,            /* minor_status */
+        gss_OID_set*           /* mech_set */
+        );
+    OM_uint32       (*gss_compare_name)
+       (void*,                 /* context */
+        OM_uint32*,            /* minor_status */
+        gss_name_t,            /* name1 */
+        gss_name_t,            /* name2 */
+        int*                   /* name_equal */
+        );
+    OM_uint32       (*gss_display_name)
+       (void*,                 /* context */
+        OM_uint32*,            /* minor_status */
+        gss_name_t,            /* input_name */
+        gss_buffer_t,          /* output_name_buffer */
+        gss_OID*               /* output_name_type */
+        );
+    OM_uint32       (*gss_import_name)
+       (void*,                 /* context */
+        OM_uint32*,            /* minor_status */
+        gss_buffer_t,          /* input_name_buffer */
+        const_gss_OID,         /* input_name_type */
+        gss_name_t*            /* output_name */
+        );
+    OM_uint32       (*gss_release_name)
+       (void*,                 /* context */
+        OM_uint32*,            /* minor_status */
+        gss_name_t*            /* input_name */
+        );
+    OM_uint32       (*gss_inquire_cred)
+       (void*,                 /* context */
+        OM_uint32 *,           /* minor_status */
+        gss_cred_id_t,         /* cred_handle */
+        gss_name_t *,          /* name */
+        OM_uint32 *,           /* lifetime */
+        int *,                 /* cred_usage */
+        gss_OID_set *          /* mechanisms */
+        );
+    int                     (*pname_to_uid)
+       (char *,                /* pname */
+        gss_OID,               /* name type */
+        gss_OID,               /* mech type */
+        uid_t *                /* uid */
+        );
+} *gss_mechanism;
+
+/********************************************************/
+/* Internal mechglue routines */
+
+gss_mechanism get_mechanism (const_gss_OID);
+OM_uint32 add_mechanism (gss_mechanism, int);
+OM_uint32 get_mech_type(gss_OID *, gss_buffer_t);
+OM_uint32 import_internal_name (OM_uint32 *, gss_OID, gss_union_name_t,
+                               gss_name_t *);
+OM_uint32 display_internal_name (OM_uint32 *, gss_OID, gss_name_t,
+                                gss_buffer_t, gss_OID *);
+OM_uint32 release_internal_name (OM_uint32 *, gss_OID, gss_name_t *);
+
+#endif /* _GSS_MECHGLUEP_H */