aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/gssapi/mechglue
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2017-07-07 17:03:42 +0000
committerCy Schubert <cy@FreeBSD.org>2017-07-07 17:03:42 +0000
commit33a9b234e7087f573ef08cd7318c6497ba08b439 (patch)
treed0ea40ad3bf5463a3c55795977c71bcb7d781b4b /src/lib/gssapi/mechglue
downloadsrc-33a9b234e7087f573ef08cd7318c6497ba08b439.tar.gz
src-33a9b234e7087f573ef08cd7318c6497ba08b439.zip
Import MIT KRB5 1.15.1, which will gracefully replace KTH Heimdal.vendor/krb5/1.15.1
The tarball used in this import is the same tarball used in ports/krb5-115 r435378. Obtained from: http://web.mit.edu/kerberos/dist/ Thanks to: pfg (for all your tireless behind-the-scenes effort)
Notes
Notes: svn path=/vendor-crypto/krb5/dist/; revision=320790 svn path=/vendor-crypto/krb5/1.15.1/; revision=320791; tag=vendor/krb5/1.15.1
Diffstat (limited to 'src/lib/gssapi/mechglue')
-rw-r--r--src/lib/gssapi/mechglue/Makefile.in224
-rw-r--r--src/lib/gssapi/mechglue/deps510
-rw-r--r--src/lib/gssapi/mechglue/g_accept_sec_context.c399
-rw-r--r--src/lib/gssapi/mechglue/g_acquire_cred.c565
-rw-r--r--src/lib/gssapi/mechglue/g_acquire_cred_imp_name.c529
-rw-r--r--src/lib/gssapi/mechglue/g_acquire_cred_with_pw.c524
-rw-r--r--src/lib/gssapi/mechglue/g_authorize_localname.c227
-rw-r--r--src/lib/gssapi/mechglue/g_buffer_set.c55
-rw-r--r--src/lib/gssapi/mechglue/g_canon_name.c176
-rw-r--r--src/lib/gssapi/mechglue/g_compare_name.c210
-rw-r--r--src/lib/gssapi/mechglue/g_complete_auth_token.c70
-rw-r--r--src/lib/gssapi/mechglue/g_context_time.c79
-rw-r--r--src/lib/gssapi/mechglue/g_decapsulate_token.c66
-rw-r--r--src/lib/gssapi/mechglue/g_del_name_attr.c66
-rw-r--r--src/lib/gssapi/mechglue/g_delete_sec_context.c104
-rw-r--r--src/lib/gssapi/mechglue/g_dsp_name.c118
-rw-r--r--src/lib/gssapi/mechglue/g_dsp_name_ext.c133
-rw-r--r--src/lib/gssapi/mechglue/g_dsp_status.c363
-rw-r--r--src/lib/gssapi/mechglue/g_dup_name.c144
-rw-r--r--src/lib/gssapi/mechglue/g_encapsulate_token.c65
-rw-r--r--src/lib/gssapi/mechglue/g_exp_sec_context.c144
-rw-r--r--src/lib/gssapi/mechglue/g_export_cred.c114
-rw-r--r--src/lib/gssapi/mechglue/g_export_name.c58
-rw-r--r--src/lib/gssapi/mechglue/g_export_name_comp.c72
-rw-r--r--src/lib/gssapi/mechglue/g_get_name_attr.c93
-rw-r--r--src/lib/gssapi/mechglue/g_glue.c752
-rw-r--r--src/lib/gssapi/mechglue/g_imp_cred.c177
-rw-r--r--src/lib/gssapi/mechglue/g_imp_name.c387
-rw-r--r--src/lib/gssapi/mechglue/g_imp_sec_context.c175
-rw-r--r--src/lib/gssapi/mechglue/g_init_sec_context.c254
-rw-r--r--src/lib/gssapi/mechglue/g_initialize.c1615
-rw-r--r--src/lib/gssapi/mechglue/g_inq_context.c168
-rw-r--r--src/lib/gssapi/mechglue/g_inq_context_oid.c68
-rw-r--r--src/lib/gssapi/mechglue/g_inq_cred.c233
-rw-r--r--src/lib/gssapi/mechglue/g_inq_cred_oid.c133
-rw-r--r--src/lib/gssapi/mechglue/g_inq_name.c97
-rw-r--r--src/lib/gssapi/mechglue/g_inq_names.c168
-rw-r--r--src/lib/gssapi/mechglue/g_map_name_to_any.c76
-rw-r--r--src/lib/gssapi/mechglue/g_mech_invoke.c72
-rw-r--r--src/lib/gssapi/mechglue/g_mechattr.c222
-rw-r--r--src/lib/gssapi/mechglue/g_mechname.c116
-rw-r--r--src/lib/gssapi/mechglue/g_oid_ops.c112
-rw-r--r--src/lib/gssapi/mechglue/g_prf.c81
-rw-r--r--src/lib/gssapi/mechglue/g_process_context.c82
-rw-r--r--src/lib/gssapi/mechglue/g_rel_buffer.c58
-rw-r--r--src/lib/gssapi/mechglue/g_rel_cred.c99
-rw-r--r--src/lib/gssapi/mechglue/g_rel_name.c86
-rw-r--r--src/lib/gssapi/mechglue/g_rel_name_mapping.c74
-rw-r--r--src/lib/gssapi/mechglue/g_rel_oid_set.c43
-rw-r--r--src/lib/gssapi/mechglue/g_saslname.c220
-rw-r--r--src/lib/gssapi/mechglue/g_seal.c249
-rw-r--r--src/lib/gssapi/mechglue/g_set_context_option.c107
-rw-r--r--src/lib/gssapi/mechglue/g_set_cred_option.c198
-rw-r--r--src/lib/gssapi/mechglue/g_set_name_attr.c70
-rw-r--r--src/lib/gssapi/mechglue/g_set_neg_mechs.c73
-rw-r--r--src/lib/gssapi/mechglue/g_sign.c134
-rw-r--r--src/lib/gssapi/mechglue/g_store_cred.c266
-rw-r--r--src/lib/gssapi/mechglue/g_unseal.c130
-rw-r--r--src/lib/gssapi/mechglue/g_unwrap_aead.c197
-rw-r--r--src/lib/gssapi/mechglue/g_unwrap_iov.c141
-rw-r--r--src/lib/gssapi/mechglue/g_verify.c106
-rw-r--r--src/lib/gssapi/mechglue/g_wrap_aead.c267
-rw-r--r--src/lib/gssapi/mechglue/g_wrap_iov.c261
-rw-r--r--src/lib/gssapi/mechglue/gssd_pname_to_uid.c226
-rw-r--r--src/lib/gssapi/mechglue/mechglue.h42
-rw-r--r--src/lib/gssapi/mechglue/mglueP.h854
66 files changed, 13997 insertions, 0 deletions
diff --git a/src/lib/gssapi/mechglue/Makefile.in b/src/lib/gssapi/mechglue/Makefile.in
new file mode 100644
index 000000000000..5e1ed6df6a4c
--- /dev/null
+++ b/src/lib/gssapi/mechglue/Makefile.in
@@ -0,0 +1,224 @@
+mydir=lib$(S)gssapi$(S)mechglue
+BUILDTOP=$(REL)..$(S)..$(S)..
+LOCALINCLUDES = -I. -I$(srcdir) -I$(srcdir)/.. -I../generic -I$(srcdir)/../generic -I../krb5 -I$(srcdir)/../krb5 -I../spnego -I$(srcdir)/../spnego
+DEFINES=-D_GSS_STATIC_LINK=1
+
+##DOSBUILDTOP = ..\..\..
+##DOS##PREFIXDIR=mechglue
+##DOS##OBJFILE=..\$(OUTPRE)mechglue.lst
+
+##DOS##DLL_EXP_TYPE=GSS
+
+SRCS = \
+ $(srcdir)/g_accept_sec_context.c \
+ $(srcdir)/g_acquire_cred.c \
+ $(srcdir)/g_acquire_cred_with_pw.c \
+ $(srcdir)/g_acquire_cred_imp_name.c \
+ $(srcdir)/g_authorize_localname.c \
+ $(srcdir)/g_buffer_set.c \
+ $(srcdir)/g_canon_name.c \
+ $(srcdir)/g_compare_name.c \
+ $(srcdir)/g_complete_auth_token.c \
+ $(srcdir)/g_context_time.c \
+ $(srcdir)/g_decapsulate_token.c \
+ $(srcdir)/g_delete_sec_context.c \
+ $(srcdir)/g_del_name_attr.c \
+ $(srcdir)/g_dsp_name.c \
+ $(srcdir)/g_dsp_name_ext.c \
+ $(srcdir)/g_dsp_status.c \
+ $(srcdir)/g_dup_name.c \
+ $(srcdir)/g_encapsulate_token.c \
+ $(srcdir)/g_exp_sec_context.c \
+ $(srcdir)/g_export_cred.c \
+ $(srcdir)/g_export_name.c \
+ $(srcdir)/g_export_name_comp.c \
+ $(srcdir)/g_get_name_attr.c \
+ $(srcdir)/g_glue.c \
+ $(srcdir)/g_imp_cred.c \
+ $(srcdir)/g_imp_name.c \
+ $(srcdir)/g_imp_sec_context.c \
+ $(srcdir)/g_init_sec_context.c \
+ $(srcdir)/g_initialize.c \
+ $(srcdir)/g_inq_context.c \
+ $(srcdir)/g_inq_context_oid.c \
+ $(srcdir)/g_inq_cred.c \
+ $(srcdir)/g_inq_cred_oid.c \
+ $(srcdir)/g_inq_name.c \
+ $(srcdir)/g_inq_names.c \
+ $(srcdir)/g_map_name_to_any.c \
+ $(srcdir)/g_mech_invoke.c \
+ $(srcdir)/g_mechattr.c \
+ $(srcdir)/g_mechname.c \
+ $(srcdir)/g_oid_ops.c \
+ $(srcdir)/g_prf.c \
+ $(srcdir)/g_process_context.c \
+ $(srcdir)/g_rel_buffer.c \
+ $(srcdir)/g_rel_cred.c \
+ $(srcdir)/g_rel_name.c \
+ $(srcdir)/g_rel_name_mapping.c \
+ $(srcdir)/g_rel_oid_set.c \
+ $(srcdir)/g_saslname.c \
+ $(srcdir)/g_seal.c \
+ $(srcdir)/g_set_context_option.c \
+ $(srcdir)/g_set_cred_option.c \
+ $(srcdir)/g_set_name_attr.c \
+ $(srcdir)/g_set_neg_mechs.c \
+ $(srcdir)/g_sign.c \
+ $(srcdir)/g_store_cred.c \
+ $(srcdir)/g_unseal.c \
+ $(srcdir)/g_unwrap_aead.c \
+ $(srcdir)/g_unwrap_iov.c \
+ $(srcdir)/g_verify.c \
+ $(srcdir)/g_wrap_aead.c \
+ $(srcdir)/g_wrap_iov.c \
+ $(srcdir)/gssd_pname_to_uid.c
+
+OBJS = \
+ $(OUTPRE)g_accept_sec_context.$(OBJEXT) \
+ $(OUTPRE)g_acquire_cred.$(OBJEXT) \
+ $(OUTPRE)g_acquire_cred_with_pw.$(OBJEXT) \
+ $(OUTPRE)g_acquire_cred_imp_name.$(OBJEXT) \
+ $(OUTPRE)g_authorize_localname.$(OBJEXT) \
+ $(OUTPRE)g_buffer_set.$(OBJEXT) \
+ $(OUTPRE)g_canon_name.$(OBJEXT) \
+ $(OUTPRE)g_compare_name.$(OBJEXT) \
+ $(OUTPRE)g_complete_auth_token.$(OBJEXT) \
+ $(OUTPRE)g_context_time.$(OBJEXT) \
+ $(OUTPRE)g_decapsulate_token.$(OBJEXT) \
+ $(OUTPRE)g_delete_sec_context.$(OBJEXT) \
+ $(OUTPRE)g_del_name_attr.$(OBJEXT) \
+ $(OUTPRE)g_dsp_name.$(OBJEXT) \
+ $(OUTPRE)g_dsp_name_ext.$(OBJEXT) \
+ $(OUTPRE)g_dsp_status.$(OBJEXT) \
+ $(OUTPRE)g_dup_name.$(OBJEXT) \
+ $(OUTPRE)g_encapsulate_token.$(OBJEXT) \
+ $(OUTPRE)g_exp_sec_context.$(OBJEXT) \
+ $(OUTPRE)g_export_cred.$(OBJEXT) \
+ $(OUTPRE)g_export_name.$(OBJEXT) \
+ $(OUTPRE)g_export_name_comp.$(OBJEXT) \
+ $(OUTPRE)g_get_name_attr.$(OBJEXT) \
+ $(OUTPRE)g_glue.$(OBJEXT) \
+ $(OUTPRE)g_imp_cred.$(OBJEXT) \
+ $(OUTPRE)g_imp_name.$(OBJEXT) \
+ $(OUTPRE)g_imp_sec_context.$(OBJEXT) \
+ $(OUTPRE)g_init_sec_context.$(OBJEXT) \
+ $(OUTPRE)g_initialize.$(OBJEXT) \
+ $(OUTPRE)g_inq_context.$(OBJEXT) \
+ $(OUTPRE)g_inq_context_oid.$(OBJEXT) \
+ $(OUTPRE)g_inq_cred.$(OBJEXT) \
+ $(OUTPRE)g_inq_cred_oid.$(OBJEXT) \
+ $(OUTPRE)g_inq_name.$(OBJEXT) \
+ $(OUTPRE)g_inq_names.$(OBJEXT) \
+ $(OUTPRE)g_map_name_to_any.$(OBJEXT) \
+ $(OUTPRE)g_mech_invoke.$(OBJEXT) \
+ $(OUTPRE)g_mechattr.$(OBJEXT) \
+ $(OUTPRE)g_mechname.$(OBJEXT) \
+ $(OUTPRE)g_oid_ops.$(OBJEXT) \
+ $(OUTPRE)g_prf.$(OBJEXT) \
+ $(OUTPRE)g_process_context.$(OBJEXT) \
+ $(OUTPRE)g_rel_buffer.$(OBJEXT) \
+ $(OUTPRE)g_rel_cred.$(OBJEXT) \
+ $(OUTPRE)g_rel_name.$(OBJEXT) \
+ $(OUTPRE)g_rel_name_mapping.$(OBJEXT) \
+ $(OUTPRE)g_rel_oid_set.$(OBJEXT) \
+ $(OUTPRE)g_saslname.$(OBJEXT) \
+ $(OUTPRE)g_seal.$(OBJEXT) \
+ $(OUTPRE)g_set_context_option.$(OBJEXT) \
+ $(OUTPRE)g_set_cred_option.$(OBJEXT) \
+ $(OUTPRE)g_set_name_attr.$(OBJEXT) \
+ $(OUTPRE)g_set_neg_mechs.$(OBJEXT) \
+ $(OUTPRE)g_sign.$(OBJEXT) \
+ $(OUTPRE)g_store_cred.$(OBJEXT) \
+ $(OUTPRE)g_unseal.$(OBJEXT) \
+ $(OUTPRE)g_unwrap_aead.$(OBJEXT) \
+ $(OUTPRE)g_unwrap_iov.$(OBJEXT) \
+ $(OUTPRE)g_verify.$(OBJEXT) \
+ $(OUTPRE)g_wrap_aead.$(OBJEXT) \
+ $(OUTPRE)g_wrap_iov.$(OBJEXT) \
+ $(OUTPRE)gssd_pname_to_uid.$(OBJEXT)
+
+STLIBOBJS = \
+ g_accept_sec_context.o \
+ g_acquire_cred.o \
+ g_acquire_cred_with_pw.o \
+ g_acquire_cred_imp_name.o \
+ g_authorize_localname.o \
+ g_buffer_set.o \
+ g_canon_name.o \
+ g_compare_name.o \
+ g_complete_auth_token.o \
+ g_context_time.o \
+ g_decapsulate_token.o \
+ g_delete_sec_context.o \
+ g_del_name_attr.o \
+ g_dsp_name.o \
+ g_dsp_name_ext.o \
+ g_dsp_status.o \
+ g_dup_name.o \
+ g_encapsulate_token.o \
+ g_exp_sec_context.o \
+ g_export_cred.o \
+ g_export_name.o \
+ g_export_name_comp.o \
+ g_get_name_attr.o \
+ g_glue.o \
+ g_imp_cred.o \
+ g_imp_name.o \
+ g_imp_sec_context.o \
+ g_init_sec_context.o \
+ g_initialize.o \
+ g_inq_context.o \
+ g_inq_context_oid.o \
+ g_inq_cred.o \
+ g_inq_cred_oid.o \
+ g_inq_name.o \
+ g_inq_names.o \
+ g_map_name_to_any.o \
+ g_mech_invoke.o \
+ g_mechattr.o \
+ g_mechname.o \
+ g_oid_ops.o \
+ g_prf.o \
+ g_process_context.o \
+ g_rel_buffer.o \
+ g_rel_cred.o \
+ g_rel_name.o \
+ g_rel_name_mapping.o \
+ g_rel_oid_set.o \
+ g_saslname.o \
+ g_seal.o \
+ g_set_context_option.o \
+ g_set_cred_option.o \
+ g_set_name_attr.o \
+ g_set_neg_mechs.o \
+ g_sign.o \
+ g_store_cred.o \
+ g_unseal.o \
+ g_unwrap_aead.o \
+ g_unwrap_iov.o \
+ g_verify.o \
+ g_wrap_aead.o \
+ g_wrap_iov.o \
+ gssd_pname_to_uid.o
+
+EHDRDIR= $(BUILDTOP)$(S)include$(S)gssapi
+EXPORTED_HEADERS = mechglue.h
+
+$(OBJS): $(EXPORTED_HEADERS)
+
+all-unix: all-libobjs
+
+##DOS##LIBOBJS = $(OBJS)
+
+clean-unix:: clean-libobjs
+
+# 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
+
+includes:
+
+@libobj_frag@
diff --git a/src/lib/gssapi/mechglue/deps b/src/lib/gssapi/mechglue/deps
new file mode 100644
index 000000000000..26f62aa8a2ec
--- /dev/null
+++ b/src/lib/gssapi/mechglue/deps
@@ -0,0 +1,510 @@
+#
+# Generated makefile dependencies follow.
+#
+g_accept_sec_context.so g_accept_sec_context.po $(OUTPRE)g_accept_sec_context.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_accept_sec_context.c mechglue.h mglueP.h
+g_acquire_cred.so g_acquire_cred.po $(OUTPRE)g_acquire_cred.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_acquire_cred.c mechglue.h mglueP.h
+g_acquire_cred_with_pw.so g_acquire_cred_with_pw.po \
+ $(OUTPRE)g_acquire_cred_with_pw.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_alloc.h \
+ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \
+ $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_ext.h \
+ $(srcdir)/../generic/gssapi_generic.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
+ ../generic/gssapi_err_generic.h g_acquire_cred_with_pw.c \
+ mechglue.h mglueP.h
+g_acquire_cred_imp_name.so g_acquire_cred_imp_name.po \
+ $(OUTPRE)g_acquire_cred_imp_name.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_alloc.h \
+ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \
+ $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_ext.h \
+ $(srcdir)/../generic/gssapi_generic.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
+ ../generic/gssapi_err_generic.h g_acquire_cred_imp_name.c \
+ mechglue.h mglueP.h
+g_authorize_localname.so g_authorize_localname.po $(OUTPRE)g_authorize_localname.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_authorize_localname.c mechglue.h mglueP.h
+g_buffer_set.so g_buffer_set.po $(OUTPRE)g_buffer_set.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_buffer_set.c mechglue.h mglueP.h
+g_canon_name.so g_canon_name.po $(OUTPRE)g_canon_name.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_canon_name.c mechglue.h mglueP.h
+g_compare_name.so g_compare_name.po $(OUTPRE)g_compare_name.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_compare_name.c mechglue.h mglueP.h
+g_complete_auth_token.so g_complete_auth_token.po $(OUTPRE)g_complete_auth_token.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_complete_auth_token.c mechglue.h mglueP.h
+g_context_time.so g_context_time.po $(OUTPRE)g_context_time.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_context_time.c mechglue.h mglueP.h
+g_decapsulate_token.so g_decapsulate_token.po $(OUTPRE)g_decapsulate_token.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_decapsulate_token.c mechglue.h mglueP.h
+g_delete_sec_context.so g_delete_sec_context.po $(OUTPRE)g_delete_sec_context.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_delete_sec_context.c mechglue.h mglueP.h
+g_del_name_attr.so g_del_name_attr.po $(OUTPRE)g_del_name_attr.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_del_name_attr.c mechglue.h mglueP.h
+g_dsp_name.so g_dsp_name.po $(OUTPRE)g_dsp_name.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_dsp_name.c mechglue.h mglueP.h
+g_dsp_name_ext.so g_dsp_name_ext.po $(OUTPRE)g_dsp_name_ext.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_dsp_name_ext.c mechglue.h mglueP.h
+g_dsp_status.so g_dsp_status.po $(OUTPRE)g_dsp_status.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_dsp_status.c mechglue.h mglueP.h
+g_dup_name.so g_dup_name.po $(OUTPRE)g_dup_name.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_dup_name.c mechglue.h mglueP.h
+g_encapsulate_token.so g_encapsulate_token.po $(OUTPRE)g_encapsulate_token.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_encapsulate_token.c mechglue.h mglueP.h
+g_exp_sec_context.so g_exp_sec_context.po $(OUTPRE)g_exp_sec_context.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_exp_sec_context.c mechglue.h mglueP.h
+g_export_cred.so g_export_cred.po $(OUTPRE)g_export_cred.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_export_cred.c mechglue.h mglueP.h
+g_export_name.so g_export_name.po $(OUTPRE)g_export_name.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_export_name.c mechglue.h mglueP.h
+g_export_name_comp.so g_export_name_comp.po $(OUTPRE)g_export_name_comp.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_export_name_comp.c mechglue.h mglueP.h
+g_get_name_attr.so g_get_name_attr.po $(OUTPRE)g_get_name_attr.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_get_name_attr.c mechglue.h mglueP.h
+g_glue.so g_glue.po $(OUTPRE)g_glue.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_alloc.h \
+ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \
+ $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_ext.h \
+ $(srcdir)/../generic/gssapi_generic.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
+ ../generic/gssapi_err_generic.h g_glue.c mechglue.h \
+ mglueP.h
+g_imp_cred.so g_imp_cred.po $(OUTPRE)g_imp_cred.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_imp_cred.c mechglue.h mglueP.h
+g_imp_name.so g_imp_name.po $(OUTPRE)g_imp_name.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_imp_name.c mechglue.h mglueP.h
+g_imp_sec_context.so g_imp_sec_context.po $(OUTPRE)g_imp_sec_context.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_imp_sec_context.c mechglue.h mglueP.h
+g_init_sec_context.so g_init_sec_context.po $(OUTPRE)g_init_sec_context.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_init_sec_context.c mechglue.h mglueP.h
+g_initialize.so g_initialize.po $(OUTPRE)g_initialize.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(srcdir)/../krb5/gssapiP_krb5.h $(srcdir)/../krb5/gssapi_krb5.h \
+ $(srcdir)/../spnego/gssapiP_spnego.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h ../generic/gssapi_err_generic.h \
+ ../krb5/gssapi_err_krb5.h g_initialize.c mechglue.h \
+ mglueP.h
+g_inq_context.so g_inq_context.po $(OUTPRE)g_inq_context.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_inq_context.c mechglue.h mglueP.h
+g_inq_context_oid.so g_inq_context_oid.po $(OUTPRE)g_inq_context_oid.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_inq_context_oid.c mechglue.h mglueP.h
+g_inq_cred.so g_inq_cred.po $(OUTPRE)g_inq_cred.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_inq_cred.c mechglue.h mglueP.h
+g_inq_cred_oid.so g_inq_cred_oid.po $(OUTPRE)g_inq_cred_oid.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_inq_cred_oid.c mechglue.h mglueP.h
+g_inq_name.so g_inq_name.po $(OUTPRE)g_inq_name.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_inq_name.c mechglue.h mglueP.h
+g_inq_names.so g_inq_names.po $(OUTPRE)g_inq_names.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_inq_names.c mechglue.h mglueP.h
+g_map_name_to_any.so g_map_name_to_any.po $(OUTPRE)g_map_name_to_any.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_map_name_to_any.c mechglue.h mglueP.h
+g_mech_invoke.so g_mech_invoke.po $(OUTPRE)g_mech_invoke.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_mech_invoke.c mechglue.h mglueP.h
+g_mechattr.so g_mechattr.po $(OUTPRE)g_mechattr.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_mechattr.c mechglue.h mglueP.h
+g_mechname.so g_mechname.po $(OUTPRE)g_mechname.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_mechname.c mechglue.h mglueP.h
+g_oid_ops.so g_oid_ops.po $(OUTPRE)g_oid_ops.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_oid_ops.c mechglue.h mglueP.h
+g_prf.so g_prf.po $(OUTPRE)g_prf.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_alloc.h \
+ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \
+ $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_ext.h \
+ $(srcdir)/../generic/gssapi_generic.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
+ ../generic/gssapi_err_generic.h g_prf.c mechglue.h \
+ mglueP.h
+g_process_context.so g_process_context.po $(OUTPRE)g_process_context.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_process_context.c mechglue.h mglueP.h
+g_rel_buffer.so g_rel_buffer.po $(OUTPRE)g_rel_buffer.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_rel_buffer.c mechglue.h mglueP.h
+g_rel_cred.so g_rel_cred.po $(OUTPRE)g_rel_cred.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_rel_cred.c mechglue.h mglueP.h
+g_rel_name.so g_rel_name.po $(OUTPRE)g_rel_name.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_rel_name.c mechglue.h mglueP.h
+g_rel_name_mapping.so g_rel_name_mapping.po $(OUTPRE)g_rel_name_mapping.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_rel_name_mapping.c mechglue.h mglueP.h
+g_rel_oid_set.so g_rel_oid_set.po $(OUTPRE)g_rel_oid_set.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_rel_oid_set.c mechglue.h mglueP.h
+g_saslname.so g_saslname.po $(OUTPRE)g_saslname.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_saslname.c mechglue.h mglueP.h
+g_seal.so g_seal.po $(OUTPRE)g_seal.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_alloc.h \
+ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \
+ $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_ext.h \
+ $(srcdir)/../generic/gssapi_generic.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
+ ../generic/gssapi_err_generic.h g_seal.c mechglue.h \
+ mglueP.h
+g_set_context_option.so g_set_context_option.po $(OUTPRE)g_set_context_option.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_set_context_option.c mechglue.h mglueP.h
+g_set_cred_option.so g_set_cred_option.po $(OUTPRE)g_set_cred_option.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_set_cred_option.c mechglue.h mglueP.h
+g_set_name_attr.so g_set_name_attr.po $(OUTPRE)g_set_name_attr.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_set_name_attr.c mechglue.h mglueP.h
+g_set_neg_mechs.so g_set_neg_mechs.po $(OUTPRE)g_set_neg_mechs.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_set_neg_mechs.c mechglue.h mglueP.h
+g_sign.so g_sign.po $(OUTPRE)g_sign.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_alloc.h \
+ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(COM_ERR_DEPS) \
+ $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_ext.h \
+ $(srcdir)/../generic/gssapi_generic.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
+ ../generic/gssapi_err_generic.h g_sign.c mechglue.h \
+ mglueP.h
+g_store_cred.so g_store_cred.po $(OUTPRE)g_store_cred.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_store_cred.c mechglue.h mglueP.h
+g_unseal.so g_unseal.po $(OUTPRE)g_unseal.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_unseal.c mechglue.h mglueP.h
+g_unwrap_aead.so g_unwrap_aead.po $(OUTPRE)g_unwrap_aead.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_unwrap_aead.c mechglue.h mglueP.h
+g_unwrap_iov.so g_unwrap_iov.po $(OUTPRE)g_unwrap_iov.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_unwrap_iov.c mechglue.h mglueP.h
+g_verify.so g_verify.po $(OUTPRE)g_verify.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_verify.c mechglue.h mglueP.h
+g_wrap_aead.so g_wrap_aead.po $(OUTPRE)g_wrap_aead.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_wrap_aead.c mechglue.h mglueP.h
+g_wrap_iov.so g_wrap_iov.po $(OUTPRE)g_wrap_iov.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ g_wrap_iov.c mechglue.h mglueP.h
+gssd_pname_to_uid.so gssd_pname_to_uid.po $(OUTPRE)gssd_pname_to_uid.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_alloc.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
+ $(COM_ERR_DEPS) $(srcdir)/../generic/gssapiP_generic.h \
+ $(srcdir)/../generic/gssapi_ext.h $(srcdir)/../generic/gssapi_generic.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-thread.h ../generic/gssapi_err_generic.h \
+ gssd_pname_to_uid.c mechglue.h mglueP.h
diff --git a/src/lib/gssapi/mechglue/g_accept_sec_context.c b/src/lib/gssapi/mechglue/g_accept_sec_context.c
new file mode 100644
index 000000000000..ddaf87412e9e
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_accept_sec_context.c
@@ -0,0 +1,399 @@
+/* #pragma ident "@(#)g_accept_sec_context.c 1.19 04/02/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_accept_sec_context
+ */
+
+#include "mglueP.h"
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+#ifndef LEAN_CLIENT
+static OM_uint32
+val_acc_sec_ctx_args(
+ 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,
+ OM_uint32 *ret_flags,
+ OM_uint32 *time_rec,
+ gss_cred_id_t *d_cred)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (src_name != NULL)
+ *src_name = GSS_C_NO_NAME;
+
+ if (mech_type != NULL)
+ *mech_type = GSS_C_NO_OID;
+
+ if (output_token != GSS_C_NO_BUFFER) {
+ output_token->length = 0;
+ output_token->value = NULL;
+ }
+
+ if (d_cred != NULL)
+ *d_cred = GSS_C_NO_CREDENTIAL;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (context_handle == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (input_token_buffer == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ if (output_token == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ return (GSS_S_COMPLETE);
+}
+
+/* Return true if mech should be accepted with no acceptor credential. */
+static int
+allow_mech_by_default(gss_OID mech)
+{
+ OM_uint32 status, minor;
+ gss_OID_set attrs;
+ int reject = 0, p;
+
+ /* Whether we accept an interposer mech depends on whether we accept the
+ * mech it interposes. */
+ mech = gssint_get_public_oid(mech);
+ if (mech == GSS_C_NO_OID)
+ return 0;
+
+ status = gss_inquire_attrs_for_mech(&minor, mech, &attrs, NULL);
+ if (status)
+ return 0;
+
+ /* Check for each attribute which would cause us to exclude this mech from
+ * the default credential. */
+ if (generic_gss_test_oid_set_member(&minor, GSS_C_MA_DEPRECATED,
+ attrs, &p) != GSS_S_COMPLETE || p)
+ reject = 1;
+ else if (generic_gss_test_oid_set_member(&minor, GSS_C_MA_NOT_DFLT_MECH,
+ attrs, &p) != GSS_S_COMPLETE || p)
+ reject = 1;
+
+ (void) gss_release_oid_set(&minor, &attrs);
+ return !reject;
+}
+
+OM_uint32 KRB5_CALLCONV
+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,
+ d_cred)
+
+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;
+OM_uint32 * ret_flags;
+OM_uint32 * time_rec;
+gss_cred_id_t * d_cred;
+
+{
+ OM_uint32 status, temp_status, temp_minor_status;
+ OM_uint32 temp_ret_flags = 0;
+ gss_union_ctx_id_t union_ctx_id = NULL;
+ gss_cred_id_t input_cred_handle = GSS_C_NO_CREDENTIAL;
+ gss_cred_id_t tmp_d_cred = GSS_C_NO_CREDENTIAL;
+ gss_name_t internal_name = GSS_C_NO_NAME;
+ gss_name_t tmp_src_name = GSS_C_NO_NAME;
+ gss_OID_desc token_mech_type_desc;
+ gss_OID token_mech_type = &token_mech_type_desc;
+ gss_OID actual_mech = GSS_C_NO_OID;
+ gss_OID selected_mech = GSS_C_NO_OID;
+ gss_OID public_mech;
+ gss_mechanism mech = NULL;
+ gss_union_cred_t uc;
+ int i;
+
+ status = val_acc_sec_ctx_args(minor_status,
+ context_handle,
+ verifier_cred_handle,
+ input_token_buffer,
+ input_chan_bindings,
+ src_name,
+ mech_type,
+ output_token,
+ ret_flags,
+ time_rec,
+ d_cred);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ /*
+ * 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) {
+
+ if (input_token_buffer == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ /* Get the token mech type */
+ status = gssint_get_mech_type(token_mech_type, input_token_buffer);
+ if (status)
+ return status;
+
+ /*
+ * An interposer calling back into the mechglue can't pass in a special
+ * mech, so we have to recognize it using verifier_cred_handle. Use
+ * the mechanism for which we have matching creds, if available.
+ */
+ if (verifier_cred_handle != GSS_C_NO_CREDENTIAL) {
+ uc = (gss_union_cred_t)verifier_cred_handle;
+ for (i = 0; i < uc->count; i++) {
+ public_mech = gssint_get_public_oid(&uc->mechs_array[i]);
+ if (public_mech && g_OID_equal(token_mech_type, public_mech)) {
+ selected_mech = &uc->mechs_array[i];
+ break;
+ }
+ }
+ }
+
+ if (selected_mech == GSS_C_NO_OID) {
+ status = gssint_select_mech_type(minor_status, token_mech_type,
+ &selected_mech);
+ if (status)
+ return status;
+ }
+
+ } else {
+ union_ctx_id = (gss_union_ctx_id_t)*context_handle;
+ selected_mech = union_ctx_id->mech_type;
+ }
+
+ /* Now create a new context if we didn't get one. */
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ status = GSS_S_FAILURE;
+ union_ctx_id = (gss_union_ctx_id_t)
+ malloc(sizeof(gss_union_ctx_id_desc));
+ if (!union_ctx_id)
+ return (GSS_S_FAILURE);
+
+ union_ctx_id->loopback = union_ctx_id;
+ union_ctx_id->internal_ctx_id = GSS_C_NO_CONTEXT;
+ status = generic_gss_copy_oid(&temp_minor_status, selected_mech,
+ &union_ctx_id->mech_type);
+ if (status != GSS_S_COMPLETE) {
+ free(union_ctx_id);
+ return (status);
+ }
+
+ /* set the new context handle to caller's data */
+ *context_handle = (gss_ctx_id_t)union_ctx_id;
+ }
+
+ /*
+ * get the appropriate cred handle from the union cred struct.
+ */
+ if (verifier_cred_handle != GSS_C_NO_CREDENTIAL) {
+ input_cred_handle =
+ gssint_get_mechanism_cred((gss_union_cred_t)verifier_cred_handle,
+ selected_mech);
+ if (input_cred_handle == GSS_C_NO_CREDENTIAL) {
+ /* verifier credential specified but no acceptor credential found */
+ status = GSS_S_NO_CRED;
+ goto error_out;
+ }
+ } else if (!allow_mech_by_default(selected_mech)) {
+ status = GSS_S_NO_CRED;
+ goto error_out;
+ }
+
+ /*
+ * now select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ mech = gssint_get_mechanism(selected_mech);
+ if (mech && mech->gss_accept_sec_context) {
+
+ status = mech->gss_accept_sec_context(minor_status,
+ &union_ctx_id->internal_ctx_id,
+ input_cred_handle,
+ input_token_buffer,
+ input_chan_bindings,
+ src_name ? &internal_name : NULL,
+ &actual_mech,
+ output_token,
+ &temp_ret_flags,
+ time_rec,
+ d_cred ? &tmp_d_cred : NULL);
+
+ /* If there's more work to do, keep going... */
+ if (status == GSS_S_CONTINUE_NEEDED)
+ return GSS_S_CONTINUE_NEEDED;
+
+ /* if the call failed, return with failure */
+ if (status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ goto error_out;
+ }
+
+ /*
+ * 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) {
+ if (internal_name != GSS_C_NO_NAME) {
+ /* consumes internal_name regardless of success */
+ temp_status = gssint_convert_name_to_union_name(
+ &temp_minor_status, mech,
+ internal_name, &tmp_src_name);
+ if (temp_status != GSS_S_COMPLETE) {
+ status = temp_status;
+ *minor_status = temp_minor_status;
+ map_error(minor_status, mech);
+ if (output_token->length)
+ (void) gss_release_buffer(&temp_minor_status,
+ output_token);
+ goto error_out;
+ }
+ *src_name = tmp_src_name;
+ } else
+ *src_name = GSS_C_NO_NAME;
+ }
+
+#define g_OID_prefix_equal(o1, o2) \
+ (((o1)->length >= (o2)->length) && \
+ (memcmp((o1)->elements, (o2)->elements, (o2)->length) == 0))
+
+ /* Ensure we're returning correct creds format */
+ if ((temp_ret_flags & GSS_C_DELEG_FLAG) &&
+ tmp_d_cred != GSS_C_NO_CREDENTIAL) {
+ public_mech = gssint_get_public_oid(selected_mech);
+ if (actual_mech != GSS_C_NO_OID &&
+ public_mech != GSS_C_NO_OID &&
+ !g_OID_prefix_equal(actual_mech, public_mech)) {
+ *d_cred = tmp_d_cred; /* unwrapped pseudo-mech */
+ } else {
+ gss_union_cred_t d_u_cred = NULL;
+
+ d_u_cred = malloc(sizeof (gss_union_cred_desc));
+ if (d_u_cred == NULL) {
+ status = GSS_S_FAILURE;
+ goto error_out;
+ }
+ (void) memset(d_u_cred, 0, sizeof (gss_union_cred_desc));
+
+ d_u_cred->count = 1;
+
+ status = generic_gss_copy_oid(&temp_minor_status,
+ selected_mech,
+ &d_u_cred->mechs_array);
+
+ if (status != GSS_S_COMPLETE) {
+ free(d_u_cred);
+ goto error_out;
+ }
+
+ d_u_cred->cred_array = malloc(sizeof(gss_cred_id_t));
+ if (d_u_cred->cred_array != NULL) {
+ d_u_cred->cred_array[0] = tmp_d_cred;
+ } else {
+ free(d_u_cred);
+ status = GSS_S_FAILURE;
+ goto error_out;
+ }
+
+ d_u_cred->loopback = d_u_cred;
+ *d_cred = (gss_cred_id_t)d_u_cred;
+ }
+ }
+
+ if (mech_type != NULL)
+ *mech_type = gssint_get_public_oid(actual_mech);
+ if (ret_flags != NULL)
+ *ret_flags = temp_ret_flags;
+ return (status);
+ } else {
+
+ status = GSS_S_BAD_MECH;
+ }
+
+error_out:
+ if (union_ctx_id) {
+ if (union_ctx_id->mech_type) {
+ if (union_ctx_id->mech_type->elements)
+ free(union_ctx_id->mech_type->elements);
+ free(union_ctx_id->mech_type);
+ }
+ if (union_ctx_id->internal_ctx_id && mech &&
+ mech->gss_delete_sec_context) {
+ mech->gss_delete_sec_context(&temp_minor_status,
+ &union_ctx_id->internal_ctx_id,
+ GSS_C_NO_BUFFER);
+ }
+ free(union_ctx_id);
+ *context_handle = GSS_C_NO_CONTEXT;
+ }
+
+ if (src_name)
+ *src_name = GSS_C_NO_NAME;
+
+ if (tmp_src_name != GSS_C_NO_NAME)
+ (void) gss_release_buffer(&temp_minor_status,
+ (gss_buffer_t)tmp_src_name);
+
+ return (status);
+}
+#endif /* LEAN_CLIENT */
diff --git a/src/lib/gssapi/mechglue/g_acquire_cred.c b/src/lib/gssapi/mechglue/g_acquire_cred.c
new file mode 100644
index 000000000000..9bd500b60285
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_acquire_cred.c
@@ -0,0 +1,565 @@
+/* #pragma ident "@(#)g_acquire_cred.c 1.22 04/02/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_acquire_cred
+ */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+static OM_uint32
+val_acq_cred_args(
+ OM_uint32 *minor_status,
+ gss_name_t desired_name,
+ OM_uint32 time_req,
+ gss_OID_set desired_mechs,
+ int cred_usage,
+ gss_const_key_value_set_t cred_store,
+ gss_cred_id_t *output_cred_handle,
+ gss_OID_set *actual_mechs,
+ OM_uint32 *time_rec)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (output_cred_handle != NULL)
+ *output_cred_handle = GSS_C_NO_CREDENTIAL;
+
+ if (actual_mechs != NULL)
+ *actual_mechs = GSS_C_NULL_OID_SET;
+
+ if (time_rec != NULL)
+ *time_rec = 0;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (output_cred_handle == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (cred_usage != GSS_C_ACCEPT
+ && cred_usage != GSS_C_INITIATE
+ && cred_usage != GSS_C_BOTH) {
+ if (minor_status) {
+ *minor_status = EINVAL;
+ map_errcode(minor_status);
+ }
+ return GSS_S_FAILURE;
+ }
+
+ return (GSS_S_COMPLETE);
+}
+
+
+OM_uint32 KRB5_CALLCONV
+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;
+
+{
+ return gss_acquire_cred_from(minor_status, desired_name, time_req,
+ desired_mechs, cred_usage, NULL,
+ output_cred_handle, actual_mechs, time_rec);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_acquire_cred_from(minor_status,
+ desired_name,
+ time_req,
+ desired_mechs,
+ cred_usage,
+ cred_store,
+ 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_const_key_value_set_t cred_store;
+gss_cred_id_t * output_cred_handle;
+gss_OID_set * actual_mechs;
+OM_uint32 * time_rec;
+
+{
+ OM_uint32 major = GSS_S_FAILURE, tmpMinor;
+ OM_uint32 first_major = GSS_S_COMPLETE, first_minor = 0;
+ OM_uint32 initTimeOut = 0, acceptTimeOut = 0, outTime = GSS_C_INDEFINITE;
+ gss_OID_set mechs = GSS_C_NO_OID_SET;
+ gss_OID_set_desc except_attrs;
+ gss_OID_desc attr_oids[2];
+ unsigned int i;
+ gss_union_cred_t creds = NULL;
+
+ major = val_acq_cred_args(minor_status,
+ desired_name,
+ time_req,
+ desired_mechs,
+ cred_usage,
+ cred_store,
+ output_cred_handle,
+ actual_mechs,
+ time_rec);
+ if (major != GSS_S_COMPLETE)
+ goto cleanup;
+
+ /*
+ * if desired_mechs equals GSS_C_NULL_OID_SET, then try to
+ * acquire credentials for all non-deprecated mechanisms.
+ */
+ if (desired_mechs == GSS_C_NULL_OID_SET) {
+ attr_oids[0] = *GSS_C_MA_DEPRECATED;
+ attr_oids[1] = *GSS_C_MA_NOT_DFLT_MECH;
+ except_attrs.count = 2;
+ except_attrs.elements = attr_oids;
+ major = gss_indicate_mechs_by_attrs(minor_status, GSS_C_NO_OID_SET,
+ &except_attrs, GSS_C_NO_OID_SET,
+ &mechs);
+ if (major != GSS_S_COMPLETE)
+ goto cleanup;
+ } else
+ mechs = desired_mechs;
+
+ if (mechs->count == 0) {
+ major = GSS_S_BAD_MECH;
+ goto cleanup;
+ }
+
+ /* allocate the output credential structure */
+ creds = (gss_union_cred_t)calloc(1, sizeof (gss_union_cred_desc));
+ if (creds == NULL) {
+ major = GSS_S_FAILURE;
+ *minor_status = ENOMEM;
+ goto cleanup;
+ }
+
+ creds->count = 0;
+ creds->loopback = creds;
+
+ /* for each requested mech attempt to obtain a credential */
+ for (i = 0, major = GSS_S_UNAVAILABLE; i < mechs->count; i++) {
+ major = gss_add_cred_from(&tmpMinor, (gss_cred_id_t)creds,
+ desired_name, &mechs->elements[i],
+ cred_usage, time_req, time_req,
+ cred_store, NULL, NULL,
+ time_rec ? &initTimeOut : NULL,
+ time_rec ? &acceptTimeOut : NULL);
+ if (major == GSS_S_COMPLETE) {
+ /* update the credential's time */
+ if (cred_usage == GSS_C_ACCEPT) {
+ if (outTime > acceptTimeOut)
+ outTime = acceptTimeOut;
+ } else if (cred_usage == GSS_C_INITIATE) {
+ if (outTime > initTimeOut)
+ outTime = initTimeOut;
+ } else {
+ /*
+ * time_rec is the lesser of the
+ * init/accept times
+ */
+ if (initTimeOut > acceptTimeOut)
+ outTime = (outTime > acceptTimeOut) ?
+ acceptTimeOut : outTime;
+ else
+ outTime = (outTime > initTimeOut) ?
+ initTimeOut : outTime;
+ }
+ } else if (first_major == GSS_S_COMPLETE) {
+ first_major = major;
+ first_minor = tmpMinor;
+ }
+ } /* for */
+
+ /* If we didn't get any creds, return the error status from the first mech
+ * (which is often the preferred one). */
+ if (creds->count < 1) {
+ major = first_major;
+ *minor_status = first_minor;
+ goto cleanup;
+ }
+ major = GSS_S_COMPLETE;
+
+ /*
+ * fill in output parameters
+ * setup the actual mechs output parameter
+ */
+ if (actual_mechs != NULL) {
+ major = gssint_make_public_oid_set(minor_status, creds->mechs_array,
+ creds->count, actual_mechs);
+ if (GSS_ERROR(major))
+ goto cleanup;
+ }
+
+ if (time_rec)
+ *time_rec = outTime;
+
+ *output_cred_handle = (gss_cred_id_t)creds;
+
+cleanup:
+ if (GSS_ERROR(major))
+ gss_release_cred(&tmpMinor, (gss_cred_id_t *)&creds);
+ if (desired_mechs == GSS_C_NO_OID_SET)
+ generic_gss_release_oid_set(&tmpMinor, &mechs);
+
+ return (major);
+}
+
+static OM_uint32
+val_add_cred_args(
+ OM_uint32 *minor_status,
+ gss_cred_id_t input_cred_handle,
+ gss_name_t desired_name,
+ gss_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ gss_const_key_value_set_t cred_store,
+ OM_uint32 initiator_time_req,
+ OM_uint32 acceptor_time_req,
+ gss_cred_id_t *output_cred_handle,
+ gss_OID_set *actual_mechs,
+ OM_uint32 *initiator_time_rec,
+ OM_uint32 *acceptor_time_rec)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (output_cred_handle != NULL)
+ *output_cred_handle = GSS_C_NO_CREDENTIAL;
+
+ if (actual_mechs != NULL)
+ *actual_mechs = GSS_C_NO_OID_SET;
+
+ if (acceptor_time_rec != NULL)
+ *acceptor_time_rec = 0;
+
+ if (initiator_time_rec != NULL)
+ *initiator_time_rec = 0;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (input_cred_handle == GSS_C_NO_CREDENTIAL &&
+ output_cred_handle == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE | GSS_S_NO_CRED);
+
+ if (cred_usage != GSS_C_ACCEPT
+ && cred_usage != GSS_C_INITIATE
+ && cred_usage != GSS_C_BOTH) {
+ if (minor_status) {
+ *minor_status = EINVAL;
+ map_errcode(minor_status);
+ }
+ return GSS_S_FAILURE;
+ }
+
+ return (GSS_S_COMPLETE);
+}
+
+
+/* V2 KRB5_CALLCONV */
+OM_uint32 KRB5_CALLCONV
+gss_add_cred(minor_status, input_cred_handle,
+ desired_name, desired_mech, cred_usage,
+ initiator_time_req, acceptor_time_req,
+ output_cred_handle, actual_mechs,
+ initiator_time_rec, acceptor_time_rec)
+ OM_uint32 *minor_status;
+ gss_cred_id_t input_cred_handle;
+ gss_name_t desired_name;
+ gss_OID desired_mech;
+ gss_cred_usage_t cred_usage;
+ OM_uint32 initiator_time_req;
+ OM_uint32 acceptor_time_req;
+ gss_cred_id_t *output_cred_handle;
+ gss_OID_set *actual_mechs;
+ OM_uint32 *initiator_time_rec;
+ OM_uint32 *acceptor_time_rec;
+{
+ return gss_add_cred_from(minor_status, input_cred_handle, desired_name,
+ desired_mech, cred_usage, initiator_time_req,
+ acceptor_time_req, NULL, output_cred_handle,
+ actual_mechs, initiator_time_rec,
+ acceptor_time_rec);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_add_cred_from(minor_status, input_cred_handle,
+ desired_name, desired_mech,
+ cred_usage,
+ initiator_time_req, acceptor_time_req,
+ cred_store,
+ output_cred_handle, actual_mechs,
+ initiator_time_rec, acceptor_time_rec)
+ OM_uint32 *minor_status;
+ gss_cred_id_t input_cred_handle;
+ gss_name_t desired_name;
+ gss_OID desired_mech;
+ gss_cred_usage_t cred_usage;
+ OM_uint32 initiator_time_req;
+ OM_uint32 acceptor_time_req;
+ gss_const_key_value_set_t cred_store;
+ gss_cred_id_t *output_cred_handle;
+ gss_OID_set *actual_mechs;
+ OM_uint32 *initiator_time_rec;
+ OM_uint32 *acceptor_time_rec;
+{
+ OM_uint32 status, temp_minor_status;
+ OM_uint32 time_req, time_rec = 0, *time_recp = NULL;
+ gss_union_name_t union_name;
+ gss_union_cred_t new_union_cred, union_cred;
+ gss_name_t internal_name = GSS_C_NO_NAME;
+ gss_name_t allocated_name = GSS_C_NO_NAME;
+ gss_mechanism mech;
+ gss_cred_id_t cred = NULL;
+ gss_OID new_mechs_array = NULL;
+ gss_cred_id_t * new_cred_array = NULL;
+ gss_OID_set target_mechs = GSS_C_NO_OID_SET;
+ gss_OID selected_mech = GSS_C_NO_OID;
+
+ status = val_add_cred_args(minor_status,
+ input_cred_handle,
+ desired_name,
+ desired_mech,
+ cred_usage,
+ cred_store,
+ initiator_time_req,
+ acceptor_time_req,
+ output_cred_handle,
+ actual_mechs,
+ initiator_time_rec,
+ acceptor_time_rec);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ status = gssint_select_mech_type(minor_status, desired_mech,
+ &selected_mech);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ mech = gssint_get_mechanism(selected_mech);
+ if (!mech)
+ return GSS_S_BAD_MECH;
+ else if (!mech->gss_acquire_cred)
+ return (GSS_S_UNAVAILABLE);
+
+ if (input_cred_handle == GSS_C_NO_CREDENTIAL) {
+ union_cred = malloc(sizeof (gss_union_cred_desc));
+ if (union_cred == NULL)
+ return (GSS_S_FAILURE);
+
+ (void) memset(union_cred, 0, sizeof (gss_union_cred_desc));
+ } else {
+ union_cred = (gss_union_cred_t)input_cred_handle;
+ if (gssint_get_mechanism_cred(union_cred, selected_mech) !=
+ GSS_C_NO_CREDENTIAL)
+ return (GSS_S_DUPLICATE_ELEMENT);
+ }
+
+ /* for default credentials we will use GSS_C_NO_NAME */
+ if (input_cred_handle != GSS_C_NO_CREDENTIAL ||
+ cred_store != GSS_C_NO_CRED_STORE) {
+ /* may need to create a mechanism specific name */
+ if (desired_name) {
+ union_name = (gss_union_name_t)desired_name;
+ if (union_name->mech_type &&
+ g_OID_equal(union_name->mech_type, selected_mech))
+ internal_name = union_name->mech_name;
+ else {
+ if (gssint_import_internal_name(minor_status, selected_mech,
+ union_name, &allocated_name) !=
+ GSS_S_COMPLETE)
+ return (GSS_S_BAD_NAME);
+ internal_name = allocated_name;
+ }
+ }
+ }
+
+
+ if (cred_usage == GSS_C_ACCEPT)
+ time_req = acceptor_time_req;
+ else if (cred_usage == GSS_C_INITIATE)
+ time_req = initiator_time_req;
+ else if (cred_usage == GSS_C_BOTH)
+ time_req = (acceptor_time_req > initiator_time_req) ?
+ acceptor_time_req : initiator_time_req;
+ else
+ time_req = 0;
+
+ status = gss_create_empty_oid_set(minor_status, &target_mechs);
+ if (status != GSS_S_COMPLETE)
+ goto errout;
+
+ status = gss_add_oid_set_member(minor_status,
+ gssint_get_public_oid(selected_mech),
+ &target_mechs);
+ if (status != GSS_S_COMPLETE)
+ goto errout;
+
+ if (initiator_time_rec != NULL || acceptor_time_rec != NULL)
+ time_recp = &time_rec;
+
+ if (mech->gss_acquire_cred_from) {
+ status = mech->gss_acquire_cred_from(minor_status, internal_name,
+ time_req, target_mechs,
+ cred_usage, cred_store, &cred,
+ NULL, time_recp);
+ } else if (cred_store == GSS_C_NO_CRED_STORE) {
+ status = mech->gss_acquire_cred(minor_status, internal_name, time_req,
+ target_mechs, cred_usage, &cred, NULL,
+ time_recp);
+ } else {
+ return GSS_S_UNAVAILABLE;
+ }
+
+ if (status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ goto errout;
+ }
+
+ /* now add the new credential elements */
+ new_mechs_array = (gss_OID)
+ malloc(sizeof (gss_OID_desc) * (union_cred->count+1));
+
+ new_cred_array = (gss_cred_id_t *)
+ malloc(sizeof (gss_cred_id_t) * (union_cred->count+1));
+
+ if (!new_mechs_array || !new_cred_array) {
+ status = GSS_S_FAILURE;
+ goto errout;
+ }
+
+ if (acceptor_time_rec)
+ if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH)
+ *acceptor_time_rec = time_rec;
+ if (initiator_time_rec)
+ if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH)
+ *initiator_time_rec = time_rec;
+
+ /*
+ * OK, expand the mechanism array and the credential array
+ */
+ (void) memcpy(new_mechs_array, union_cred->mechs_array,
+ sizeof (gss_OID_desc) * union_cred->count);
+ (void) memcpy(new_cred_array, union_cred->cred_array,
+ sizeof (gss_cred_id_t) * union_cred->count);
+
+ new_cred_array[union_cred->count] = cred;
+ if ((new_mechs_array[union_cred->count].elements =
+ malloc(selected_mech->length)) == NULL)
+ goto errout;
+
+ g_OID_copy(&new_mechs_array[union_cred->count], selected_mech);
+
+ if (actual_mechs != NULL) {
+ status = gssint_make_public_oid_set(minor_status, new_mechs_array,
+ union_cred->count + 1,
+ actual_mechs);
+ if (GSS_ERROR(status)) {
+ free(new_mechs_array[union_cred->count].elements);
+ goto errout;
+ }
+ }
+
+ if (output_cred_handle == NULL) {
+ free(union_cred->mechs_array);
+ free(union_cred->cred_array);
+ new_union_cred = union_cred;
+ } else {
+ new_union_cred = malloc(sizeof (gss_union_cred_desc));
+ if (new_union_cred == NULL) {
+ free(new_mechs_array[union_cred->count].elements);
+ goto errout;
+ }
+ *new_union_cred = *union_cred;
+ *output_cred_handle = (gss_cred_id_t)new_union_cred;
+ }
+
+ new_union_cred->mechs_array = new_mechs_array;
+ new_union_cred->cred_array = new_cred_array;
+ new_union_cred->count++;
+ new_union_cred->loopback = new_union_cred;
+
+ /* We're done with the internal name. Free it if we allocated it. */
+
+ if (allocated_name)
+ (void) gssint_release_internal_name(&temp_minor_status,
+ selected_mech,
+ &allocated_name);
+ (void) generic_gss_release_oid_set(&temp_minor_status, &target_mechs);
+
+ return (GSS_S_COMPLETE);
+
+errout:
+ if (new_mechs_array)
+ free(new_mechs_array);
+ if (new_cred_array)
+ free(new_cred_array);
+
+ if (cred != NULL && mech->gss_release_cred)
+ mech->gss_release_cred(&temp_minor_status, &cred);
+
+ if (allocated_name)
+ (void) gssint_release_internal_name(&temp_minor_status,
+ selected_mech,
+ &allocated_name);
+
+ if (input_cred_handle == GSS_C_NO_CREDENTIAL && union_cred)
+ free(union_cred);
+
+ (void) generic_gss_release_oid_set(&temp_minor_status, &target_mechs);
+
+ return (status);
+}
diff --git a/src/lib/gssapi/mechglue/g_acquire_cred_imp_name.c b/src/lib/gssapi/mechglue/g_acquire_cred_imp_name.c
new file mode 100644
index 000000000000..9eab25e4cd8e
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_acquire_cred_imp_name.c
@@ -0,0 +1,529 @@
+/* #pragma ident "@(#)g_acquire_cred.c 1.22 04/02/23 SMI" */
+
+/*
+ * Copyright 2009 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* Glue routine for gss_acquire_cred_impersonate_name */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+static OM_uint32
+val_acq_cred_impersonate_name_args(
+ OM_uint32 *minor_status,
+ const gss_cred_id_t impersonator_cred_handle,
+ const gss_name_t desired_name,
+ OM_uint32 time_req,
+ gss_OID_set desired_mechs,
+ gss_cred_usage_t cred_usage,
+ gss_cred_id_t *output_cred_handle,
+ gss_OID_set *actual_mechs,
+ OM_uint32 *time_rec)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (output_cred_handle != NULL)
+ *output_cred_handle = GSS_C_NO_CREDENTIAL;
+
+ if (actual_mechs != NULL)
+ *actual_mechs = GSS_C_NULL_OID_SET;
+
+ if (time_rec != NULL)
+ *time_rec = 0;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (impersonator_cred_handle == GSS_C_NO_CREDENTIAL)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CRED);
+
+ if (desired_name == GSS_C_NO_NAME)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
+
+ if (output_cred_handle == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (cred_usage != GSS_C_ACCEPT
+ && cred_usage != GSS_C_INITIATE
+ && cred_usage != GSS_C_BOTH) {
+ if (minor_status) {
+ *minor_status = EINVAL;
+ map_errcode(minor_status);
+ }
+ return GSS_S_FAILURE;
+ }
+
+ return (GSS_S_COMPLETE);
+}
+
+
+OM_uint32 KRB5_CALLCONV
+gss_acquire_cred_impersonate_name(OM_uint32 *minor_status,
+ const gss_cred_id_t impersonator_cred_handle,
+ const gss_name_t desired_name,
+ OM_uint32 time_req,
+ const gss_OID_set desired_mechs,
+ gss_cred_usage_t cred_usage,
+ gss_cred_id_t *output_cred_handle,
+ gss_OID_set *actual_mechs,
+ OM_uint32 *time_rec)
+{
+ OM_uint32 major = GSS_S_FAILURE;
+ OM_uint32 initTimeOut, acceptTimeOut, outTime = GSS_C_INDEFINITE;
+ gss_OID_set_desc default_OID_set;
+ gss_OID_set mechs;
+ gss_OID_desc default_OID;
+ gss_mechanism mech;
+ unsigned int i;
+ gss_union_cred_t creds;
+
+ major = val_acq_cred_impersonate_name_args(minor_status,
+ impersonator_cred_handle,
+ desired_name,
+ time_req,
+ desired_mechs,
+ cred_usage,
+ output_cred_handle,
+ actual_mechs,
+ time_rec);
+ if (major != GSS_S_COMPLETE)
+ return (major);
+
+ /* Initial value needed below. */
+ major = GSS_S_FAILURE;
+
+ /*
+ * if desired_mechs equals GSS_C_NULL_OID_SET, then pick an
+ * appropriate default. We use the first mechanism in the
+ * mechansim list as the default. This set is created with
+ * statics thus needs not be freed
+ */
+ if(desired_mechs == GSS_C_NULL_OID_SET) {
+ mech = gssint_get_mechanism(NULL);
+ if (mech == NULL)
+ return (GSS_S_BAD_MECH);
+
+ 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;
+ } else
+ mechs = desired_mechs;
+
+ if (mechs->count == 0)
+ return (GSS_S_BAD_MECH);
+
+ /* allocate the output credential structure */
+ creds = (gss_union_cred_t)malloc(sizeof (gss_union_cred_desc));
+ if (creds == NULL)
+ return (GSS_S_FAILURE);
+
+ /* initialize to 0s */
+ (void) memset(creds, 0, sizeof (gss_union_cred_desc));
+ creds->loopback = creds;
+
+ /* for each requested mech attempt to obtain a credential */
+ for (i = 0; i < mechs->count; i++) {
+ major = gss_add_cred_impersonate_name(minor_status,
+ (gss_cred_id_t)creds,
+ impersonator_cred_handle,
+ desired_name,
+ &mechs->elements[i],
+ cred_usage,
+ time_req,
+ time_req, NULL,
+ NULL,
+ &initTimeOut,
+ &acceptTimeOut);
+ if (major == GSS_S_COMPLETE) {
+ /* update the credential's time */
+ if (cred_usage == GSS_C_ACCEPT) {
+ if (outTime > acceptTimeOut)
+ outTime = acceptTimeOut;
+ } else if (cred_usage == GSS_C_INITIATE) {
+ if (outTime > initTimeOut)
+ outTime = initTimeOut;
+ } else {
+ /*
+ * time_rec is the lesser of the
+ * init/accept times
+ */
+ if (initTimeOut > acceptTimeOut)
+ outTime = (outTime > acceptTimeOut) ?
+ acceptTimeOut : outTime;
+ else
+ outTime = (outTime > initTimeOut) ?
+ initTimeOut : outTime;
+ }
+ }
+ } /* for */
+
+ /* ensure that we have at least one credential element */
+ if (creds->count < 1) {
+ free(creds);
+ return (major);
+ }
+
+ /*
+ * fill in output parameters
+ * setup the actual mechs output parameter
+ */
+ if (actual_mechs != NULL) {
+ gss_OID_set_desc oids;
+
+ oids.count = creds->count;
+ oids.elements = creds->mechs_array;
+
+ major = generic_gss_copy_oid_set(minor_status, &oids, actual_mechs);
+ if (GSS_ERROR(major)) {
+ (void) gss_release_cred(minor_status,
+ (gss_cred_id_t *)&creds);
+ return (major);
+ }
+ }
+
+ if (time_rec)
+ *time_rec = outTime;
+
+
+ creds->loopback = creds;
+ *output_cred_handle = (gss_cred_id_t)creds;
+ return (GSS_S_COMPLETE);
+}
+
+static OM_uint32
+val_add_cred_impersonate_name_args(
+ OM_uint32 *minor_status,
+ gss_cred_id_t input_cred_handle,
+ const gss_cred_id_t impersonator_cred_handle,
+ gss_name_t desired_name,
+ gss_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ OM_uint32 initiator_time_req,
+ OM_uint32 acceptor_time_req,
+ gss_cred_id_t *output_cred_handle,
+ gss_OID_set *actual_mechs,
+ OM_uint32 *initiator_time_rec,
+ OM_uint32 *acceptor_time_rec)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (output_cred_handle != NULL)
+ *output_cred_handle = GSS_C_NO_CREDENTIAL;
+
+ if (actual_mechs != NULL)
+ *actual_mechs = GSS_C_NO_OID_SET;
+
+ if (acceptor_time_rec != NULL)
+ *acceptor_time_rec = 0;
+
+ if (initiator_time_rec != NULL)
+ *initiator_time_rec = 0;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (impersonator_cred_handle == GSS_C_NO_CREDENTIAL)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CRED);
+
+ if (desired_name == GSS_C_NO_NAME)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
+
+ if (input_cred_handle == GSS_C_NO_CREDENTIAL &&
+ output_cred_handle == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE | GSS_S_NO_CRED);
+
+ if (cred_usage != GSS_C_ACCEPT
+ && cred_usage != GSS_C_INITIATE
+ && cred_usage != GSS_C_BOTH) {
+ if (minor_status) {
+ *minor_status = EINVAL;
+ map_errcode(minor_status);
+ }
+ return GSS_S_FAILURE;
+ }
+
+ return (GSS_S_COMPLETE);
+}
+
+
+/* V2 KRB5_CALLCONV */
+OM_uint32 KRB5_CALLCONV
+gss_add_cred_impersonate_name(OM_uint32 *minor_status,
+ gss_cred_id_t input_cred_handle,
+ const gss_cred_id_t impersonator_cred_handle,
+ const gss_name_t desired_name,
+ const gss_OID desired_mech,
+ gss_cred_usage_t cred_usage,
+ OM_uint32 initiator_time_req,
+ OM_uint32 acceptor_time_req,
+ gss_cred_id_t *output_cred_handle,
+ gss_OID_set *actual_mechs,
+ OM_uint32 *initiator_time_rec,
+ OM_uint32 *acceptor_time_rec)
+{
+ OM_uint32 status, temp_minor_status;
+ OM_uint32 time_req, time_rec;
+ gss_union_name_t union_name;
+ gss_union_cred_t new_union_cred, union_cred;
+ gss_cred_id_t mech_impersonator_cred;
+ gss_name_t internal_name = GSS_C_NO_NAME;
+ gss_name_t allocated_name = GSS_C_NO_NAME;
+ gss_mechanism mech;
+ gss_cred_id_t cred = NULL;
+ gss_OID new_mechs_array = NULL;
+ gss_cred_id_t * new_cred_array = NULL;
+ gss_OID_set target_mechs = GSS_C_NO_OID_SET;
+ gss_OID selected_mech = GSS_C_NO_OID;
+
+ status = val_add_cred_impersonate_name_args(minor_status,
+ input_cred_handle,
+ impersonator_cred_handle,
+ desired_name,
+ desired_mech,
+ cred_usage,
+ initiator_time_req,
+ acceptor_time_req,
+ output_cred_handle,
+ actual_mechs,
+ initiator_time_rec,
+ acceptor_time_rec);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ status = gssint_select_mech_type(minor_status, desired_mech,
+ &selected_mech);
+ if (status != GSS_S_COMPLETE)
+ return status;
+
+ mech = gssint_get_mechanism(selected_mech);
+ if (!mech)
+ return GSS_S_BAD_MECH;
+ else if (!mech->gss_acquire_cred_impersonate_name)
+ return (GSS_S_UNAVAILABLE);
+
+ if (input_cred_handle == GSS_C_NO_CREDENTIAL) {
+ union_cred = malloc(sizeof (gss_union_cred_desc));
+ if (union_cred == NULL)
+ return (GSS_S_FAILURE);
+
+ (void) memset(union_cred, 0, sizeof (gss_union_cred_desc));
+
+ /* for default credentials we will use GSS_C_NO_NAME */
+ internal_name = GSS_C_NO_NAME;
+ } else {
+ union_cred = (gss_union_cred_t)input_cred_handle;
+ if (gssint_get_mechanism_cred(union_cred, selected_mech) !=
+ GSS_C_NO_CREDENTIAL)
+ return (GSS_S_DUPLICATE_ELEMENT);
+ }
+
+ mech_impersonator_cred =
+ gssint_get_mechanism_cred((gss_union_cred_t)impersonator_cred_handle,
+ selected_mech);
+ if (mech_impersonator_cred == GSS_C_NO_CREDENTIAL)
+ return (GSS_S_NO_CRED);
+
+ /* may need to create a mechanism specific name */
+ union_name = (gss_union_name_t)desired_name;
+ if (union_name->mech_type &&
+ g_OID_equal(union_name->mech_type, selected_mech))
+ internal_name = union_name->mech_name;
+ else {
+ if (gssint_import_internal_name(minor_status,
+ selected_mech, union_name,
+ &allocated_name) != GSS_S_COMPLETE)
+ return (GSS_S_BAD_NAME);
+ internal_name = allocated_name;
+ }
+
+ if (cred_usage == GSS_C_ACCEPT)
+ time_req = acceptor_time_req;
+ else if (cred_usage == GSS_C_INITIATE)
+ time_req = initiator_time_req;
+ else if (cred_usage == GSS_C_BOTH)
+ time_req = (acceptor_time_req > initiator_time_req) ?
+ acceptor_time_req : initiator_time_req;
+ else
+ time_req = 0;
+
+ status = gss_create_empty_oid_set(minor_status, &target_mechs);
+ if (status != GSS_S_COMPLETE)
+ goto errout;
+
+ status = gss_add_oid_set_member(minor_status,
+ gssint_get_public_oid(selected_mech),
+ &target_mechs);
+ if (status != GSS_S_COMPLETE)
+ goto errout;
+
+ status = mech->gss_acquire_cred_impersonate_name(minor_status,
+ mech_impersonator_cred,
+ internal_name,
+ time_req,
+ target_mechs,
+ cred_usage,
+ &cred,
+ NULL,
+ &time_rec);
+ if (status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ goto errout;
+ }
+
+ /* now add the new credential elements */
+ new_mechs_array = (gss_OID)
+ malloc(sizeof (gss_OID_desc) * (union_cred->count+1));
+
+ new_cred_array = (gss_cred_id_t *)
+ malloc(sizeof (gss_cred_id_t) * (union_cred->count+1));
+
+ if (!new_mechs_array || !new_cred_array) {
+ status = GSS_S_FAILURE;
+ goto errout;
+ }
+
+ if (acceptor_time_rec)
+ if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH)
+ *acceptor_time_rec = time_rec;
+ if (initiator_time_rec)
+ if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH)
+ *initiator_time_rec = time_rec;
+
+ /*
+ * OK, expand the mechanism array and the credential array
+ */
+ (void) memcpy(new_mechs_array, union_cred->mechs_array,
+ sizeof (gss_OID_desc) * union_cred->count);
+ (void) memcpy(new_cred_array, union_cred->cred_array,
+ sizeof (gss_cred_id_t) * union_cred->count);
+
+ new_cred_array[union_cred->count] = cred;
+ if ((new_mechs_array[union_cred->count].elements =
+ malloc(selected_mech->length)) == NULL)
+ goto errout;
+
+ g_OID_copy(&new_mechs_array[union_cred->count], selected_mech);
+
+ if (actual_mechs != NULL) {
+ status = gssint_make_public_oid_set(minor_status, new_mechs_array,
+ union_cred->count + 1,
+ actual_mechs);
+ if (GSS_ERROR(status)) {
+ free(new_mechs_array[union_cred->count].elements);
+ goto errout;
+ }
+ }
+
+ if (output_cred_handle == NULL) {
+ free(union_cred->mechs_array);
+ free(union_cred->cred_array);
+ new_union_cred = union_cred;
+ } else {
+ new_union_cred = malloc(sizeof (gss_union_cred_desc));
+ if (new_union_cred == NULL) {
+ free(new_mechs_array[union_cred->count].elements);
+ goto errout;
+ }
+ *new_union_cred = *union_cred;
+ *output_cred_handle = (gss_cred_id_t)new_union_cred;
+ }
+
+ new_union_cred->mechs_array = new_mechs_array;
+ new_union_cred->cred_array = new_cred_array;
+ new_union_cred->count++;
+ new_union_cred->loopback = new_union_cred;
+
+ /* We're done with the internal name. Free it if we allocated it. */
+
+ if (allocated_name)
+ (void) gssint_release_internal_name(&temp_minor_status, selected_mech,
+ &allocated_name);
+
+ if (target_mechs)
+ (void) gss_release_oid_set(&temp_minor_status, &target_mechs);
+
+ return (GSS_S_COMPLETE);
+
+errout:
+ if (new_mechs_array)
+ free(new_mechs_array);
+ if (new_cred_array)
+ free(new_cred_array);
+
+ if (cred != NULL && mech->gss_release_cred)
+ mech->gss_release_cred(&temp_minor_status, &cred);
+
+ if (allocated_name)
+ (void) gssint_release_internal_name(&temp_minor_status,
+ selected_mech, &allocated_name);
+
+ if (target_mechs)
+ (void) gss_release_oid_set(&temp_minor_status, &target_mechs);
+
+ if (input_cred_handle == GSS_C_NO_CREDENTIAL && union_cred)
+ free(union_cred);
+
+ return (status);
+}
diff --git a/src/lib/gssapi/mechglue/g_acquire_cred_with_pw.c b/src/lib/gssapi/mechglue/g_acquire_cred_with_pw.c
new file mode 100644
index 000000000000..7835d59726d3
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_acquire_cred_with_pw.c
@@ -0,0 +1,524 @@
+/* #pragma ident "@(#)g_acquire_cred.c 1.22 04/02/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_acquire_cred_with_password
+ */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+static OM_uint32
+val_acq_cred_pw_args(
+ OM_uint32 *minor_status,
+ const gss_name_t desired_name,
+ const gss_buffer_t password,
+ OM_uint32 time_req,
+ const gss_OID_set desired_mechs,
+ int cred_usage,
+ gss_cred_id_t *output_cred_handle,
+ gss_OID_set *actual_mechs,
+ OM_uint32 *time_rec)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (output_cred_handle != NULL)
+ *output_cred_handle = GSS_C_NO_CREDENTIAL;
+
+ if (actual_mechs != NULL)
+ *actual_mechs = GSS_C_NULL_OID_SET;
+
+ if (time_rec != NULL)
+ *time_rec = 0;
+
+ /* Validate arguments. */
+
+ if (desired_name == GSS_C_NO_NAME)
+ return (GSS_S_BAD_NAME);
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (output_cred_handle == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (cred_usage != GSS_C_ACCEPT
+ && cred_usage != GSS_C_INITIATE
+ && cred_usage != GSS_C_BOTH) {
+ if (minor_status) {
+ *minor_status = EINVAL;
+ map_errcode(minor_status);
+ }
+ return GSS_S_FAILURE;
+ }
+
+ if (password == GSS_C_NO_BUFFER ||
+ password->length == 0 ||
+ password->value == NULL) {
+ if (minor_status) {
+ *minor_status = EINVAL;
+ map_errcode(minor_status);
+ }
+ return GSS_S_FAILURE;
+ }
+
+ return (GSS_S_COMPLETE);
+}
+
+
+OM_uint32 KRB5_CALLCONV
+gss_acquire_cred_with_password(
+ minor_status,
+ desired_name,
+ password,
+ time_req,
+ desired_mechs,
+ cred_usage,
+ output_cred_handle,
+ actual_mechs,
+ time_rec)
+
+OM_uint32 * minor_status;
+const gss_name_t desired_name;
+const gss_buffer_t password;
+OM_uint32 time_req;
+const 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 major = GSS_S_FAILURE;
+ OM_uint32 initTimeOut, acceptTimeOut, outTime = GSS_C_INDEFINITE;
+ gss_OID_set_desc default_OID_set;
+ gss_OID_set mechs;
+ gss_OID_desc default_OID;
+ gss_mechanism mech;
+ unsigned int i;
+ gss_union_cred_t creds;
+
+ major = val_acq_cred_pw_args(minor_status,
+ desired_name,
+ password,
+ time_req,
+ desired_mechs,
+ cred_usage,
+ output_cred_handle,
+ actual_mechs,
+ time_rec);
+ if (major != GSS_S_COMPLETE)
+ return (major);
+
+ /* Initial value needed below. */
+ major = GSS_S_FAILURE;
+
+ /*
+ * if desired_mechs equals GSS_C_NULL_OID_SET, then pick an
+ * appropriate default. We use the first mechanism in the
+ * mechansim list as the default. This set is created with
+ * statics thus needs not be freed
+ */
+ if(desired_mechs == GSS_C_NULL_OID_SET) {
+ mech = gssint_get_mechanism(NULL);
+ if (mech == NULL)
+ return (GSS_S_BAD_MECH);
+
+ 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;
+ } else
+ mechs = desired_mechs;
+
+ if (mechs->count == 0)
+ return (GSS_S_BAD_MECH);
+
+ /* allocate the output credential structure */
+ creds = (gss_union_cred_t)malloc(sizeof (gss_union_cred_desc));
+ if (creds == NULL)
+ return (GSS_S_FAILURE);
+
+ /* initialize to 0s */
+ (void) memset(creds, 0, sizeof (gss_union_cred_desc));
+ creds->loopback = creds;
+
+ /* for each requested mech attempt to obtain a credential */
+ for (i = 0; i < mechs->count; i++) {
+ major = gss_add_cred_with_password(minor_status, (gss_cred_id_t)creds,
+ desired_name,
+ &mechs->elements[i],
+ password,
+ cred_usage, time_req, time_req, NULL,
+ NULL, &initTimeOut, &acceptTimeOut);
+ if (major == GSS_S_COMPLETE) {
+ /* update the credential's time */
+ if (cred_usage == GSS_C_ACCEPT) {
+ if (outTime > acceptTimeOut)
+ outTime = acceptTimeOut;
+ } else if (cred_usage == GSS_C_INITIATE) {
+ if (outTime > initTimeOut)
+ outTime = initTimeOut;
+ } else {
+ /*
+ * time_rec is the lesser of the
+ * init/accept times
+ */
+ if (initTimeOut > acceptTimeOut)
+ outTime = (outTime > acceptTimeOut) ?
+ acceptTimeOut : outTime;
+ else
+ outTime = (outTime > initTimeOut) ?
+ initTimeOut : outTime;
+ }
+ }
+ } /* for */
+
+ /* ensure that we have at least one credential element */
+ if (creds->count < 1) {
+ free(creds);
+ return (major);
+ }
+
+ /*
+ * fill in output parameters
+ * setup the actual mechs output parameter
+ */
+ if (actual_mechs != NULL) {
+ major = gssint_make_public_oid_set(minor_status, creds->mechs_array,
+ creds->count, actual_mechs);
+ if (GSS_ERROR(major)) {
+ (void) gss_release_cred(minor_status,
+ (gss_cred_id_t *)&creds);
+ return (major);
+ }
+ }
+
+ if (time_rec)
+ *time_rec = outTime;
+
+
+ creds->loopback = creds;
+ *output_cred_handle = (gss_cred_id_t)creds;
+ return (GSS_S_COMPLETE);
+}
+
+static OM_uint32
+val_add_cred_pw_args(
+ OM_uint32 *minor_status,
+ gss_cred_id_t input_cred_handle,
+ const gss_name_t desired_name,
+ const gss_OID desired_mech,
+ const gss_buffer_t password,
+ gss_cred_usage_t cred_usage,
+ OM_uint32 initiator_time_req,
+ OM_uint32 acceptor_time_req,
+ gss_cred_id_t *output_cred_handle,
+ gss_OID_set *actual_mechs,
+ OM_uint32 *initiator_time_rec,
+ OM_uint32 *acceptor_time_rec)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (output_cred_handle != NULL)
+ *output_cred_handle = GSS_C_NO_CREDENTIAL;
+
+ if (actual_mechs != NULL)
+ *actual_mechs = GSS_C_NO_OID_SET;
+
+ if (acceptor_time_rec != NULL)
+ *acceptor_time_rec = 0;
+
+ if (initiator_time_rec != NULL)
+ *initiator_time_rec = 0;
+
+ /* Validate arguments. */
+
+ if (desired_name == GSS_C_NO_NAME)
+ return (GSS_S_BAD_NAME);
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (input_cred_handle == GSS_C_NO_CREDENTIAL &&
+ output_cred_handle == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE | GSS_S_NO_CRED);
+
+ if (cred_usage != GSS_C_ACCEPT
+ && cred_usage != GSS_C_INITIATE
+ && cred_usage != GSS_C_BOTH) {
+ if (minor_status) {
+ *minor_status = EINVAL;
+ map_errcode(minor_status);
+ }
+ return GSS_S_FAILURE;
+ }
+
+ if (password == GSS_C_NO_BUFFER ||
+ password->length == 0 ||
+ password->value == NULL) {
+ if (minor_status) {
+ *minor_status = EINVAL;
+ map_errcode(minor_status);
+ }
+ return GSS_S_FAILURE;
+ }
+
+
+ return (GSS_S_COMPLETE);
+}
+
+
+/* V2 KRB5_CALLCONV */
+OM_uint32 KRB5_CALLCONV
+gss_add_cred_with_password(minor_status, input_cred_handle,
+ desired_name, desired_mech, password, cred_usage,
+ initiator_time_req, acceptor_time_req,
+ output_cred_handle, actual_mechs,
+ initiator_time_rec, acceptor_time_rec)
+ OM_uint32 *minor_status;
+ const gss_cred_id_t input_cred_handle;
+ const gss_name_t desired_name;
+ const gss_OID desired_mech;
+ const gss_buffer_t password;
+ gss_cred_usage_t cred_usage;
+ OM_uint32 initiator_time_req;
+ OM_uint32 acceptor_time_req;
+ gss_cred_id_t *output_cred_handle;
+ gss_OID_set *actual_mechs;
+ OM_uint32 *initiator_time_rec;
+ OM_uint32 *acceptor_time_rec;
+{
+ OM_uint32 status, temp_minor_status;
+ OM_uint32 time_req, time_rec;
+ gss_union_name_t union_name;
+ gss_union_cred_t new_union_cred, union_cred;
+ gss_name_t internal_name = GSS_C_NO_NAME;
+ gss_name_t allocated_name = GSS_C_NO_NAME;
+ gss_mechanism mech;
+ gss_cred_id_t cred = NULL;
+ gss_OID new_mechs_array = NULL;
+ gss_cred_id_t * new_cred_array = NULL;
+ gss_OID_set target_mechs = GSS_C_NO_OID_SET;
+ gss_OID selected_mech = GSS_C_NO_OID;
+
+ status = val_add_cred_pw_args(minor_status,
+ input_cred_handle,
+ desired_name,
+ desired_mech,
+ password,
+ cred_usage,
+ initiator_time_req,
+ acceptor_time_req,
+ output_cred_handle,
+ actual_mechs,
+ initiator_time_rec,
+ acceptor_time_rec);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ status = gssint_select_mech_type(minor_status, desired_mech,
+ &selected_mech);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ mech = gssint_get_mechanism(selected_mech);
+ if (!mech)
+ return GSS_S_BAD_MECH;
+ if (!mech->gssspi_acquire_cred_with_password)
+ return GSS_S_UNAVAILABLE;
+
+ if (input_cred_handle == GSS_C_NO_CREDENTIAL) {
+ union_cred = malloc(sizeof (gss_union_cred_desc));
+ if (union_cred == NULL)
+ return (GSS_S_FAILURE);
+
+ (void) memset(union_cred, 0, sizeof (gss_union_cred_desc));
+
+ /* for default credentials we will use GSS_C_NO_NAME */
+ internal_name = GSS_C_NO_NAME;
+ } else {
+ union_cred = (gss_union_cred_t)input_cred_handle;
+ if (gssint_get_mechanism_cred(union_cred, selected_mech) !=
+ GSS_C_NO_CREDENTIAL)
+ return (GSS_S_DUPLICATE_ELEMENT);
+ }
+
+ /* may need to create a mechanism specific name */
+ union_name = (gss_union_name_t)desired_name;
+ if (union_name->mech_type &&
+ g_OID_equal(union_name->mech_type, selected_mech))
+ internal_name = union_name->mech_name;
+ else {
+ if (gssint_import_internal_name(minor_status,
+ selected_mech, union_name,
+ &allocated_name) != GSS_S_COMPLETE)
+ return (GSS_S_BAD_NAME);
+ internal_name = allocated_name;
+ }
+
+ if (cred_usage == GSS_C_ACCEPT)
+ time_req = acceptor_time_req;
+ else if (cred_usage == GSS_C_INITIATE)
+ time_req = initiator_time_req;
+ else if (cred_usage == GSS_C_BOTH)
+ time_req = (acceptor_time_req > initiator_time_req) ?
+ acceptor_time_req : initiator_time_req;
+ else
+ time_req = 0;
+
+ status = gss_create_empty_oid_set(minor_status, &target_mechs);
+ if (status != GSS_S_COMPLETE)
+ goto errout;
+
+ status = gss_add_oid_set_member(minor_status,
+ gssint_get_public_oid(selected_mech),
+ &target_mechs);
+ if (status != GSS_S_COMPLETE)
+ goto errout;
+
+ status = mech->gssspi_acquire_cred_with_password(minor_status,
+ internal_name,
+ password,
+ time_req,
+ target_mechs,
+ cred_usage,
+ &cred,
+ NULL,
+ &time_rec);
+ if (status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ goto errout;
+ }
+
+ /* now add the new credential elements */
+ new_mechs_array = (gss_OID)
+ malloc(sizeof (gss_OID_desc) * (union_cred->count+1));
+
+ new_cred_array = (gss_cred_id_t *)
+ malloc(sizeof (gss_cred_id_t) * (union_cred->count+1));
+
+ if (!new_mechs_array || !new_cred_array) {
+ status = GSS_S_FAILURE;
+ goto errout;
+ }
+
+ if (acceptor_time_rec)
+ if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH)
+ *acceptor_time_rec = time_rec;
+ if (initiator_time_rec)
+ if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH)
+ *initiator_time_rec = time_rec;
+
+ /*
+ * OK, expand the mechanism array and the credential array
+ */
+ (void) memcpy(new_mechs_array, union_cred->mechs_array,
+ sizeof (gss_OID_desc) * union_cred->count);
+ (void) memcpy(new_cred_array, union_cred->cred_array,
+ sizeof (gss_cred_id_t) * union_cred->count);
+
+ new_cred_array[union_cred->count] = cred;
+ if ((new_mechs_array[union_cred->count].elements =
+ malloc(selected_mech->length)) == NULL)
+ goto errout;
+
+ g_OID_copy(&new_mechs_array[union_cred->count], selected_mech);
+
+ if (actual_mechs != NULL) {
+ status = gssint_make_public_oid_set(minor_status, new_mechs_array,
+ union_cred->count + 1,
+ actual_mechs);
+ if (GSS_ERROR(status)) {
+ free(new_mechs_array[union_cred->count].elements);
+ goto errout;
+ }
+ }
+
+ if (output_cred_handle == NULL) {
+ free(union_cred->mechs_array);
+ free(union_cred->cred_array);
+ new_union_cred = union_cred;
+ } else {
+ new_union_cred = malloc(sizeof (gss_union_cred_desc));
+ if (new_union_cred == NULL) {
+ free(new_mechs_array[union_cred->count].elements);
+ goto errout;
+ }
+ *new_union_cred = *union_cred;
+ *output_cred_handle = (gss_cred_id_t)new_union_cred;
+ }
+
+ new_union_cred->mechs_array = new_mechs_array;
+ new_union_cred->cred_array = new_cred_array;
+ new_union_cred->count++;
+ new_union_cred->loopback = new_union_cred;
+
+ /* We're done with the internal name. Free it if we allocated it. */
+
+ if (allocated_name)
+ (void) gssint_release_internal_name(&temp_minor_status,
+ selected_mech,
+ &allocated_name);
+
+ if (target_mechs)
+ (void)gss_release_oid_set(&temp_minor_status, &target_mechs);
+
+ return (GSS_S_COMPLETE);
+
+errout:
+ if (new_mechs_array)
+ free(new_mechs_array);
+ if (new_cred_array)
+ free(new_cred_array);
+
+ if (cred != NULL && mech->gss_release_cred)
+ mech->gss_release_cred(&temp_minor_status, &cred);
+
+ if (allocated_name)
+ (void) gssint_release_internal_name(&temp_minor_status,
+ selected_mech, &allocated_name);
+
+ if (target_mechs)
+ (void)gss_release_oid_set(&temp_minor_status, &target_mechs);
+
+ if (input_cred_handle == GSS_C_NO_CREDENTIAL && union_cred)
+ free(union_cred);
+
+ return (status);
+}
diff --git a/src/lib/gssapi/mechglue/g_authorize_localname.c b/src/lib/gssapi/mechglue/g_authorize_localname.c
new file mode 100644
index 000000000000..0e4fb0722924
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_authorize_localname.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2011, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * 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 PADL Software 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 BY PADL SOFTWARE AND CONTRIBUTORS ``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 PADL SOFTWARE 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.
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* #pragma ident "@(#)g_userok.c 1.1 04/03/25 SMI" */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <mglueP.h>
+#include <gssapi/gssapi.h>
+
+static OM_uint32
+mech_authorize_localname(OM_uint32 *minor,
+ const gss_union_name_t unionName,
+ const gss_union_name_t unionUser)
+{
+ OM_uint32 major = GSS_S_UNAVAILABLE;
+ gss_mechanism mech;
+
+ if (unionName->mech_type == GSS_C_NO_OID)
+ return (GSS_S_NAME_NOT_MN);
+
+ mech = gssint_get_mechanism(unionName->mech_type);
+ if (mech == NULL)
+ return (GSS_S_UNAVAILABLE);
+
+ if (mech->gssspi_authorize_localname != NULL) {
+ major = mech->gssspi_authorize_localname(minor,
+ unionName->mech_name,
+ unionUser->external_name,
+ unionUser->name_type);
+ if (major != GSS_S_COMPLETE)
+ map_error(minor, mech);
+ }
+
+ return (major);
+}
+
+/*
+ * Naming extensions based local login authorization.
+ */
+static OM_uint32
+attr_authorize_localname(OM_uint32 *minor,
+ const gss_name_t name,
+ const gss_union_name_t unionUser)
+{
+ OM_uint32 major = GSS_S_UNAVAILABLE; /* attribute not present */
+ gss_buffer_t externalName;
+ int more = -1;
+
+ if (unionUser->name_type != GSS_C_NO_OID &&
+ !g_OID_equal(unionUser->name_type, GSS_C_NT_USER_NAME))
+ return (GSS_S_BAD_NAMETYPE);
+
+ externalName = unionUser->external_name;
+ assert(externalName != GSS_C_NO_BUFFER);
+
+ while (more != 0 && major != GSS_S_COMPLETE) {
+ OM_uint32 tmpMajor, tmpMinor;
+ gss_buffer_desc value;
+ gss_buffer_desc display_value;
+ int authenticated = 0, complete = 0;
+
+ tmpMajor = gss_get_name_attribute(minor,
+ name,
+ GSS_C_ATTR_LOCAL_LOGIN_USER,
+ &authenticated,
+ &complete,
+ &value,
+ &display_value,
+ &more);
+ if (GSS_ERROR(tmpMajor)) {
+ major = tmpMajor;
+ break;
+ }
+
+ if (authenticated &&
+ value.length == externalName->length &&
+ memcmp(value.value, externalName->value, externalName->length) == 0)
+ major = GSS_S_COMPLETE;
+ else
+ major = GSS_S_UNAUTHORIZED;
+
+ gss_release_buffer(&tmpMinor, &value);
+ gss_release_buffer(&tmpMinor, &display_value);
+ }
+
+ return (major);
+}
+
+/*
+ * Equality based local login authorization.
+ */
+static OM_uint32
+compare_names_authorize_localname(OM_uint32 *minor,
+ const gss_union_name_t unionName,
+ const gss_name_t user)
+{
+
+ OM_uint32 status, tmpMinor;
+ gss_name_t canonName;
+ int match = 0;
+
+ status = gss_canonicalize_name(minor,
+ user,
+ unionName->mech_type,
+ &canonName);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ status = gss_compare_name(minor,
+ (gss_name_t)unionName,
+ canonName,
+ &match);
+ if (status == GSS_S_COMPLETE && match == 0)
+ status = GSS_S_UNAUTHORIZED;
+
+ (void) gss_release_name(&tmpMinor, &canonName);
+
+ return (status);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_authorize_localname(OM_uint32 *minor,
+ const gss_name_t name,
+ const gss_name_t user)
+
+{
+ OM_uint32 major;
+ gss_union_name_t unionName;
+ gss_union_name_t unionUser;
+ int mechAvailable = 0;
+
+ if (minor == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (name == GSS_C_NO_NAME || user == GSS_C_NO_NAME)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ *minor = 0;
+
+ unionName = (gss_union_name_t)name;
+ unionUser = (gss_union_name_t)user;
+
+ if (unionUser->mech_type != GSS_C_NO_OID)
+ return (GSS_S_BAD_NAME);
+
+ /* If mech returns yes, we return yes */
+ major = mech_authorize_localname(minor, unionName, unionUser);
+ if (major == GSS_S_COMPLETE)
+ return (GSS_S_COMPLETE);
+ else if (major != GSS_S_UNAVAILABLE)
+ mechAvailable = 1;
+
+ /* If attribute exists, we evaluate attribute */
+ major = attr_authorize_localname(minor, unionName, unionUser);
+ if (major == GSS_S_COMPLETE || major == GSS_S_UNAUTHORIZED)
+ return (major);
+
+ /* If mech did not implement SPI, compare the local name */
+ if (mechAvailable == 0 &&
+ unionName->mech_type != GSS_C_NO_OID) {
+ major = compare_names_authorize_localname(minor,
+ unionName,
+ unionUser);
+ }
+
+ return (major);
+}
+
+int KRB5_CALLCONV
+gss_userok(const gss_name_t name,
+ const char *user)
+{
+ OM_uint32 major, minor;
+ gss_buffer_desc userBuf;
+ gss_name_t userName;
+
+ userBuf.value = (void *)user;
+ userBuf.length = strlen(user);
+
+ major = gss_import_name(&minor, &userBuf, GSS_C_NT_USER_NAME, &userName);
+ if (GSS_ERROR(major))
+ return (0);
+
+ major = gss_authorize_localname(&minor, name, userName);
+
+ (void) gss_release_name(&minor, &userName);
+
+ return (major == GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/mechglue/g_buffer_set.c b/src/lib/gssapi/mechglue/g_buffer_set.c
new file mode 100644
index 000000000000..9310ddb4b728
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_buffer_set.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2008 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+OM_uint32 KRB5_CALLCONV gss_create_empty_buffer_set
+ (OM_uint32 * minor_status,
+ gss_buffer_set_t *buffer_set)
+{
+ return generic_gss_create_empty_buffer_set(minor_status, buffer_set);
+}
+
+OM_uint32 KRB5_CALLCONV gss_add_buffer_set_member
+ (OM_uint32 * minor_status,
+ const gss_buffer_t member_buffer,
+ gss_buffer_set_t *buffer_set)
+{
+ return generic_gss_add_buffer_set_member(minor_status,
+ member_buffer,
+ buffer_set);
+}
+
+OM_uint32 KRB5_CALLCONV gss_release_buffer_set
+ (OM_uint32 * minor_status,
+ gss_buffer_set_t *buffer_set)
+{
+ return generic_gss_release_buffer_set(minor_status, buffer_set);
+}
diff --git a/src/lib/gssapi/mechglue/g_canon_name.c b/src/lib/gssapi/mechglue/g_canon_name.c
new file mode 100644
index 000000000000..61f657f91f71
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_canon_name.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* #pragma ident "@(#)g_canon_name.c 1.15 04/02/23 SMI" */
+
+/*
+ * routine gss_canonicalize_name
+ *
+ * This routine is used to produce a mechanism specific
+ * representation of name that has been previously
+ * imported with gss_import_name. The routine uses the mechanism
+ * specific implementation of gss_import_name to implement this
+ * function.
+ *
+ * We allow a NULL output_name, in which case we modify the
+ * input_name to include the mechanism specific name.
+ */
+
+#include <mglueP.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+static OM_uint32
+val_canon_name_args(
+ OM_uint32 *minor_status,
+ const gss_name_t input_name,
+ const gss_OID mech_type,
+ gss_name_t *output_name)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (output_name != NULL)
+ *output_name = GSS_C_NO_NAME;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (input_name == GSS_C_NO_NAME || mech_type == GSS_C_NULL_OID)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ return (GSS_S_COMPLETE);
+}
+
+
+OM_uint32 KRB5_CALLCONV
+gss_canonicalize_name(minor_status,
+ input_name,
+ mech_type,
+ output_name)
+OM_uint32 *minor_status;
+const gss_name_t input_name;
+const gss_OID mech_type;
+gss_name_t *output_name;
+{
+ gss_union_name_t in_union, out_union = NULL, dest_union = NULL;
+ OM_uint32 major_status = GSS_S_FAILURE, tmpmin;
+ gss_OID selected_mech;
+
+ major_status = val_canon_name_args(minor_status,
+ input_name,
+ mech_type,
+ output_name);
+ if (major_status != GSS_S_COMPLETE)
+ return (major_status);
+
+ major_status = gssint_select_mech_type(minor_status, mech_type,
+ &selected_mech);
+ if (major_status != GSS_S_COMPLETE)
+ return (major_status);
+
+ /* Initial value needed below. */
+ major_status = GSS_S_FAILURE;
+
+ in_union = (gss_union_name_t)input_name;
+ /*
+ * If the caller wants to reuse the name, and the name has already
+ * been converted, then there is nothing for us to do.
+ */
+ if (!output_name && in_union->mech_type &&
+ g_OID_equal(in_union->mech_type, selected_mech))
+ return (GSS_S_COMPLETE);
+
+ /* ok, then we need to do something - start by creating data struct */
+ if (output_name) {
+ out_union =
+ (gss_union_name_t)malloc(sizeof (gss_union_name_desc));
+ if (!out_union)
+ goto allocation_failure;
+
+ out_union->mech_type = 0;
+ out_union->mech_name = 0;
+ out_union->name_type = 0;
+ out_union->external_name = 0;
+ out_union->loopback = out_union;
+
+ /* Allocate the buffer for the user specified representation */
+ if (gssint_create_copy_buffer(in_union->external_name,
+ &out_union->external_name, 1))
+ goto allocation_failure;
+
+ if (in_union->name_type != GSS_C_NULL_OID) {
+ major_status = generic_gss_copy_oid(minor_status,
+ in_union->name_type,
+ &out_union->name_type);
+ if (major_status) {
+ map_errcode(minor_status);
+ goto allocation_failure;
+ }
+ }
+
+ }
+
+ /*
+ * might need to delete any old mechanism names if we are
+ * reusing the buffer.
+ */
+ if (!output_name) {
+ if (in_union->mech_type) {
+ (void) gssint_release_internal_name(minor_status,
+ in_union->mech_type,
+ &in_union->mech_name);
+ (void) gss_release_oid(minor_status,
+ &in_union->mech_type);
+ in_union->mech_type = 0;
+ }
+ dest_union = in_union;
+ } else
+ dest_union = out_union;
+
+ /* now let's create the new mech name */
+ if ((major_status = generic_gss_copy_oid(minor_status, selected_mech,
+ &dest_union->mech_type))) {
+ map_errcode(minor_status);
+ goto allocation_failure;
+ }
+
+ if ((major_status =
+ gssint_import_internal_name(minor_status, selected_mech,
+ in_union,
+ &dest_union->mech_name)))
+ goto allocation_failure;
+
+ if (output_name)
+ *output_name = (gss_name_t)dest_union;
+
+ return (GSS_S_COMPLETE);
+
+allocation_failure:
+ if (out_union) {
+ /* Release the partly constructed out_union. */
+ gss_name_t name = (gss_name_t)out_union;
+ (void) gss_release_name(&tmpmin, &name);
+ } else if (!output_name) {
+ /* Release only the mech name fields in in_union. */
+ if (in_union->mech_name) {
+ (void) gssint_release_internal_name(&tmpmin,
+ dest_union->mech_type,
+ &dest_union->mech_name);
+ }
+ if (in_union->mech_type)
+ (void) gss_release_oid(&tmpmin, &dest_union->mech_type);
+ }
+
+ return (major_status);
+} /********** gss_canonicalize_name ********/
diff --git a/src/lib/gssapi/mechglue/g_compare_name.c b/src/lib/gssapi/mechglue/g_compare_name.c
new file mode 100644
index 000000000000..af2e76bbdabd
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_compare_name.c
@@ -0,0 +1,210 @@
+/* #pragma ident "@(#)g_compare_name.c 1.16 04/02/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_compare_name
+ *
+ */
+
+#include "mglueP.h"
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+
+static OM_uint32
+val_comp_name_args(
+ OM_uint32 *minor_status,
+ gss_name_t name1,
+ gss_name_t name2,
+ int *name_equal)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ /* Validate arguments. */
+
+ if (name1 == GSS_C_NO_NAME || name2 == GSS_C_NO_NAME)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
+
+ if (name_equal == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ return (GSS_S_COMPLETE);
+}
+
+
+OM_uint32 KRB5_CALLCONV
+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 major_status, temp_minor;
+ gss_union_name_t union_name1, union_name2;
+ gss_mechanism mech = NULL;
+ gss_name_t internal_name;
+
+ major_status = val_comp_name_args(minor_status,
+ name1, name2, name_equal);
+ if (major_status != GSS_S_COMPLETE)
+ return (major_status);
+
+ union_name1 = (gss_union_name_t) name1;
+ union_name2 = (gss_union_name_t) name2;
+ /*
+ * Try our hardest to make union_name1 be the mechanism-specific
+ * name. (Of course we can't if both names aren't
+ * mechanism-specific.)
+ */
+ if (union_name1->mech_type == 0) {
+ union_name1 = (gss_union_name_t) name2;
+ union_name2 = (gss_union_name_t) name1;
+ }
+ /*
+ * If union_name1 is mechanism specific, then fetch its mechanism
+ * information.
+ */
+ if (union_name1->mech_type) {
+ mech = gssint_get_mechanism (union_name1->mech_type);
+ if (!mech)
+ return (GSS_S_BAD_MECH);
+ if (!mech->gss_compare_name)
+ return (GSS_S_UNAVAILABLE);
+ }
+
+ *name_equal = 0; /* Default to *not* equal.... */
+
+ /*
+ * First case... both names are mechanism-specific
+ */
+ if (union_name1->mech_type && union_name2->mech_type) {
+ if (!g_OID_equal(union_name1->mech_type, union_name2->mech_type))
+ return (GSS_S_COMPLETE);
+ if ((union_name1->mech_name == 0) || (union_name2->mech_name == 0))
+ /* should never happen */
+ return (GSS_S_BAD_NAME);
+ if (!mech)
+ return (GSS_S_BAD_MECH);
+ if (!mech->gss_compare_name)
+ return (GSS_S_UNAVAILABLE);
+ major_status = mech->gss_compare_name(minor_status,
+ union_name1->mech_name,
+ union_name2->mech_name,
+ name_equal);
+ if (major_status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ return major_status;
+ }
+
+ /*
+ * Second case... both names are NOT mechanism specific.
+ *
+ * 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().
+ */
+ if (!union_name1->mech_type && !union_name2->mech_type) {
+ /*
+ * Second case, first sub-case... one name has null
+ * name_type, the other doesn't.
+ *
+ * Not knowing a mech_type we can't import the name with
+ * null name_type so we can't compare.
+ */
+ if ((union_name1->name_type == GSS_C_NULL_OID &&
+ union_name2->name_type != GSS_C_NULL_OID) ||
+ (union_name1->name_type != GSS_C_NULL_OID &&
+ union_name2->name_type == GSS_C_NULL_OID))
+ return (GSS_S_COMPLETE);
+ /*
+ * Second case, second sub-case... both names have
+ * name_types, but they are different.
+ */
+ if ((union_name1->name_type != GSS_C_NULL_OID &&
+ union_name2->name_type != GSS_C_NULL_OID) &&
+ !g_OID_equal(union_name1->name_type,
+ union_name2->name_type))
+ return (GSS_S_COMPLETE);
+ /*
+ * Second case, third sub-case... both names have equal
+ * name_types (and both have no mech_types) so we just
+ * compare the external_names.
+ */
+ 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))
+ return (GSS_S_COMPLETE);
+ *name_equal = 1;
+ return (GSS_S_COMPLETE);
+ }
+
+ /*
+ * Final case... one name is mechanism specific, the other isn't.
+ *
+ * We attempt to convert the general name to the mechanism type of
+ * the mechanism-specific name, and then do the compare. If we
+ * can't import the general name, then we return that the name is
+ * _NOT_ equal.
+ */
+ if (union_name2->mech_type) {
+ /* We make union_name1 the mechanism specific name. */
+ union_name1 = (gss_union_name_t) name2;
+ union_name2 = (gss_union_name_t) name1;
+ }
+ major_status = gssint_import_internal_name(minor_status,
+ union_name1->mech_type,
+ union_name2,
+ &internal_name);
+ if (major_status != GSS_S_COMPLETE)
+ return (GSS_S_COMPLETE); /* return complete, but not equal */
+
+ if (!mech)
+ return (GSS_S_BAD_MECH);
+ if (!mech->gss_compare_name)
+ return (GSS_S_UNAVAILABLE);
+ major_status = mech->gss_compare_name(minor_status,
+ union_name1->mech_name,
+ internal_name, name_equal);
+ if (major_status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ gssint_release_internal_name(&temp_minor, union_name1->mech_type,
+ &internal_name);
+ return (major_status);
+
+}
diff --git a/src/lib/gssapi/mechglue/g_complete_auth_token.c b/src/lib/gssapi/mechglue/g_complete_auth_token.c
new file mode 100644
index 000000000000..91815513017f
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_complete_auth_token.c
@@ -0,0 +1,70 @@
+/* #ident "@(#)gss_seal.c 1.10 95/08/07 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_complete_auth_token
+ */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+OM_uint32 KRB5_CALLCONV
+gss_complete_auth_token (OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ gss_buffer_t input_message_buffer)
+{
+ OM_uint32 status;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+
+ 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 = gssint_get_mechanism (ctx->mech_type);
+
+ if (mech != NULL) {
+ if (mech->gss_complete_auth_token != NULL) {
+ status = mech->gss_complete_auth_token(minor_status,
+ ctx->internal_ctx_id,
+ input_message_buffer);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_COMPLETE;
+ } else
+ status = GSS_S_BAD_MECH;
+
+ return status;
+}
diff --git a/src/lib/gssapi/mechglue/g_context_time.c b/src/lib/gssapi/mechglue/g_context_time.c
new file mode 100644
index 000000000000..2ff8d0996ef0
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_context_time.c
@@ -0,0 +1,79 @@
+/* #pragma ident "@(#)g_context_time.c 1.12 98/01/22 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routines for gss_context_time
+ */
+
+#include "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+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;
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+ *minor_status = 0;
+
+ if (time_rec == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+
+ if (mech) {
+
+ if (mech->gss_context_time) {
+ status = mech->gss_context_time(
+ minor_status,
+ ctx->internal_ctx_id,
+ time_rec);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return(status);
+ }
+
+ return (GSS_S_BAD_MECH);
+}
diff --git a/src/lib/gssapi/mechglue/g_decapsulate_token.c b/src/lib/gssapi/mechglue/g_decapsulate_token.c
new file mode 100644
index 000000000000..934d2607cc6c
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_decapsulate_token.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * 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 PADL Software 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 BY PADL SOFTWARE AND CONTRIBUTORS ``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 PADL SOFTWARE 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 "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_decapsulate_token(gss_const_buffer_t input_token,
+ gss_const_OID token_oid,
+ gss_buffer_t output_token)
+{
+ OM_uint32 minor;
+ unsigned int body_size = 0;
+ unsigned char *buf_in;
+
+ if (input_token == GSS_C_NO_BUFFER || token_oid == GSS_C_NO_OID)
+ return GSS_S_CALL_INACCESSIBLE_READ;
+
+ if (output_token == GSS_C_NO_BUFFER)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ buf_in = input_token->value;
+
+ minor = g_verify_token_header(token_oid, &body_size, &buf_in,
+ -1, input_token->length,
+ G_VFY_TOKEN_HDR_WRAPPER_REQUIRED);
+ if (minor != 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ output_token->value = malloc(body_size);
+ if (output_token->value == NULL)
+ return GSS_S_FAILURE;
+
+ memcpy(output_token->value, buf_in, body_size);
+ output_token->length = body_size;
+
+ return GSS_S_COMPLETE;
+}
diff --git a/src/lib/gssapi/mechglue/g_del_name_attr.c b/src/lib/gssapi/mechglue/g_del_name_attr.c
new file mode 100644
index 000000000000..e81e3315ade4
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_del_name_attr.c
@@ -0,0 +1,66 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2009 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/* Glue routine for gss_delete_name_attribute */
+
+#include "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_delete_name_attribute(OM_uint32 *minor_status,
+ gss_name_t name,
+ gss_buffer_t attr)
+{
+ OM_uint32 status;
+ gss_union_name_t union_name;
+ gss_mechanism mech;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (name == GSS_C_NO_NAME)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME;
+
+ *minor_status = 0;
+
+ union_name = (gss_union_name_t)name;
+
+ if (union_name->mech_type == GSS_C_NO_OID)
+ return GSS_S_UNAVAILABLE;
+
+ mech = gssint_get_mechanism(name->mech_type);
+ if (mech == NULL)
+ return GSS_S_BAD_NAME;
+
+ if (mech->gss_delete_name_attribute == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ status = (*mech->gss_delete_name_attribute)(minor_status,
+ union_name->mech_name,
+ attr);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+
+ return status;
+}
diff --git a/src/lib/gssapi/mechglue/g_delete_sec_context.c b/src/lib/gssapi/mechglue/g_delete_sec_context.c
new file mode 100644
index 000000000000..4bf0dec5ce33
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_delete_sec_context.c
@@ -0,0 +1,104 @@
+/* #pragma ident "@(#)g_delete_sec_context.c 1.11 97/11/09 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_delete_sec_context
+ */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+static OM_uint32
+val_del_sec_ctx_args(
+ OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ gss_buffer_t output_token)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (output_token != GSS_C_NO_BUFFER) {
+ output_token->length = 0;
+ output_token->value = NULL;
+ }
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE | GSS_S_NO_CONTEXT);
+
+ return (GSS_S_COMPLETE);
+}
+
+
+OM_uint32 KRB5_CALLCONV
+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;
+
+ status = val_del_sec_ctx_args(minor_status, context_handle, output_token);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) *context_handle;
+ if (GSSINT_CHK_LOOP(ctx))
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
+
+ status = gssint_delete_internal_sec_context(minor_status,
+ ctx->mech_type,
+ &ctx->internal_ctx_id,
+ output_token);
+ if (status)
+ return status;
+
+ /* now free up the space for the union context structure */
+ free(ctx->mech_type->elements);
+ free(ctx->mech_type);
+ free(*context_handle);
+ *context_handle = GSS_C_NO_CONTEXT;
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/mechglue/g_dsp_name.c b/src/lib/gssapi/mechglue/g_dsp_name.c
new file mode 100644
index 000000000000..21867c814ec5
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_dsp_name.c
@@ -0,0 +1,118 @@
+/* #pragma ident "@(#)g_dsp_name.c 1.13 04/02/23 SMI" */
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_display_name()
+ *
+ */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+
+static OM_uint32
+val_dsp_name_args(
+ OM_uint32 *minor_status,
+ gss_name_t input_name,
+ gss_buffer_t output_name_buffer,
+ gss_OID *output_name_type)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (output_name_buffer != GSS_C_NO_BUFFER) {
+ output_name_buffer->length = 0;
+ output_name_buffer->value = NULL;
+ }
+
+ if (output_name_type != NULL)
+ *output_name_type = GSS_C_NO_OID;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (output_name_buffer == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (input_name == GSS_C_NO_NAME)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
+
+ return (GSS_S_COMPLETE);
+}
+
+
+OM_uint32 KRB5_CALLCONV
+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;
+
+{
+ OM_uint32 major_status;
+ gss_union_name_t union_name;
+
+ major_status = val_dsp_name_args(minor_status, input_name,
+ output_name_buffer, output_name_type);
+ if (major_status != GSS_S_COMPLETE)
+ return (major_status);
+
+ union_name = (gss_union_name_t) input_name;
+
+ if (union_name->mech_type) {
+ /*
+ * OK, we have a mechanism-specific name; let's use it!
+ */
+ return (gssint_display_internal_name(minor_status,
+ union_name->mech_type,
+ union_name->mech_name,
+ output_name_buffer,
+ output_name_type));
+ }
+
+ if ((output_name_buffer->value =
+ gssalloc_malloc(union_name->external_name->length + 1)) == NULL)
+ return (GSS_S_FAILURE);
+ output_name_buffer->length = union_name->external_name->length;
+ (void) memcpy(output_name_buffer->value,
+ union_name->external_name->value,
+ union_name->external_name->length);
+ ((char *)output_name_buffer->value)[output_name_buffer->length] = '\0';
+
+ if (output_name_type != NULL)
+ *output_name_type = union_name->name_type;
+
+ return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/mechglue/g_dsp_name_ext.c b/src/lib/gssapi/mechglue/g_dsp_name_ext.c
new file mode 100644
index 000000000000..be08dd16c4a3
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_dsp_name_ext.c
@@ -0,0 +1,133 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_display_name_ext()
+ *
+ */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+
+static OM_uint32
+val_dsp_name_ext_args(
+ OM_uint32 *minor_status,
+ gss_name_t input_name,
+ gss_OID display_as_name_type,
+ gss_buffer_t output_name_buffer)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (output_name_buffer != GSS_C_NO_BUFFER) {
+ output_name_buffer->length = 0;
+ output_name_buffer->value = NULL;
+ }
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (output_name_buffer == GSS_C_NO_BUFFER)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (input_name == GSS_C_NO_NAME)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME;
+
+ if (display_as_name_type == GSS_C_NO_OID)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAMETYPE;
+
+ return GSS_S_COMPLETE;
+}
+
+
+OM_uint32 KRB5_CALLCONV
+gss_display_name_ext (OM_uint32 *minor_status,
+ gss_name_t input_name,
+ gss_OID display_as_name_type,
+ gss_buffer_t output_name_buffer)
+{
+ OM_uint32 status;
+ gss_union_name_t union_name;
+ gss_mechanism mech;
+
+ status = val_dsp_name_ext_args(minor_status,
+ input_name,
+ display_as_name_type,
+ output_name_buffer);
+ if (status != GSS_S_COMPLETE)
+ return status;
+
+ union_name = (gss_union_name_t) input_name;
+
+ if (union_name->mech_type) {
+ mech = gssint_get_mechanism(union_name->mech_type);
+ if (mech == NULL)
+ status = GSS_S_BAD_NAME;
+ else if (mech->gss_display_name_ext == NULL) {
+ if (mech->gss_display_name != NULL &&
+ union_name->name_type != GSS_C_NO_OID &&
+ g_OID_equal(display_as_name_type, union_name->name_type)) {
+ status = (*mech->gss_display_name)(minor_status,
+ union_name->mech_name,
+ output_name_buffer,
+ NULL);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+ } else {
+ status = (*mech->gss_display_name_ext)(minor_status,
+ union_name->mech_name,
+ display_as_name_type,
+ output_name_buffer);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ }
+ return status;
+ }
+
+ if (union_name->name_type == GSS_C_NO_OID ||
+ !g_OID_equal(display_as_name_type, union_name->name_type))
+ return GSS_S_UNAVAILABLE;
+
+ if ((output_name_buffer->value =
+ malloc(union_name->external_name->length + 1)) == NULL) {
+ return GSS_S_FAILURE;
+ }
+ output_name_buffer->length = union_name->external_name->length;
+ (void) memcpy(output_name_buffer->value,
+ union_name->external_name->value,
+ union_name->external_name->length);
+ ((char *)output_name_buffer->value)[output_name_buffer->length] = '\0';
+
+ return GSS_S_COMPLETE;
+}
diff --git a/src/lib/gssapi/mechglue/g_dsp_status.c b/src/lib/gssapi/mechglue/g_dsp_status.c
new file mode 100644
index 000000000000..70e8492636ad
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_dsp_status.c
@@ -0,0 +1,363 @@
+/* #pragma ident "@(#)g_dsp_status.c 1.17 04/02/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine gss_display_status
+ *
+ */
+
+#include "mglueP.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* local function */
+static OM_uint32 displayMajor(OM_uint32, OM_uint32 *, gss_buffer_t);
+
+OM_uint32 KRB5_CALLCONV
+gss_display_status (minor_status,
+ status_value,
+ status_type,
+ req_mech_type,
+ message_context,
+ status_string)
+
+OM_uint32 * minor_status;
+OM_uint32 status_value;
+int status_type;
+gss_OID req_mech_type;
+OM_uint32 * message_context;
+gss_buffer_t status_string;
+
+{
+ gss_OID mech_type = (gss_OID) req_mech_type;
+ gss_mechanism mech;
+ gss_OID_desc m_oid = { 0, 0 };
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (status_string != GSS_C_NO_BUFFER) {
+ status_string->length = 0;
+ status_string->value = NULL;
+ }
+
+ if (minor_status == NULL ||
+ message_context == NULL ||
+ status_string == GSS_C_NO_BUFFER)
+
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ /* we handle major status codes, and the mechs do the minor */
+ if (status_type == GSS_C_GSS_CODE)
+ return (displayMajor(status_value, message_context,
+ status_string));
+
+ /*
+ * must be the minor status - let mechs do the work
+ * select the appropriate underlying mechanism routine and
+ * call it.
+ */
+
+ /* In this version, we only handle status codes that have been
+ mapped to a flat numbering space. Look up the value we got
+ passed. If it's not found, complain. */
+ if (status_value == 0) {
+ status_string->value = gssalloc_strdup("Unknown error");
+ if (status_string->value == NULL) {
+ *minor_status = ENOMEM;
+ map_errcode(minor_status);
+ return GSS_S_FAILURE;
+ }
+ status_string->length = strlen(status_string->value);
+ *message_context = 0;
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+ }
+ {
+ int err;
+ OM_uint32 m_status = 0, status;
+
+ err = gssint_mecherrmap_get(status_value, &m_oid, &m_status);
+ if (err) {
+ *minor_status = err;
+ map_errcode(minor_status);
+ return GSS_S_BAD_STATUS;
+ }
+ if (m_oid.length == 0) {
+ /* Magic flag for com_err values. */
+ status = g_display_com_err_status(minor_status, m_status, status_string);
+ if (status != GSS_S_COMPLETE)
+ map_errcode(minor_status);
+ return status;
+ }
+ mech_type = &m_oid;
+ status_value = m_status;
+ }
+
+ mech = gssint_get_mechanism (mech_type);
+
+ if (mech && mech->gss_display_status) {
+ OM_uint32 r;
+
+ r = mech->gss_display_status(minor_status,
+ status_value, status_type, mech_type,
+ message_context, status_string);
+ /* How's this for weird? If we get an error returning the
+ mechanism-specific error code, we save away the
+ mechanism-specific error code describing the error. */
+ if (r != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ return r;
+ }
+
+ if (!mech)
+ return (GSS_S_BAD_MECH);
+
+ return (GSS_S_UNAVAILABLE);
+}
+
+/*
+ * function to map the major error codes
+ * it uses case statements so that the strings could be wrapped by gettext
+ * msgCtxt is interpreted as:
+ * 0 - first call
+ * 1 - routine error
+ * >= 2 - the supplementary error code bit shifted by 1
+ */
+static OM_uint32
+displayMajor(status, msgCtxt, outStr)
+OM_uint32 status;
+OM_uint32 *msgCtxt;
+gss_buffer_t outStr;
+{
+ OM_uint32 oneVal, mask = 0x1, currErr;
+ char *errStr = NULL;
+ int i, haveErr = 0;
+
+ /* take care of the success value first */
+ if (status == GSS_S_COMPLETE)
+ errStr = _("The routine completed successfully");
+ else if (*msgCtxt == 0 && (oneVal = GSS_CALLING_ERROR(status))) {
+ switch (oneVal) {
+ case GSS_S_CALL_INACCESSIBLE_READ:
+ errStr = _("A required input parameter could not be "
+ "read");
+ break;
+
+ case GSS_S_CALL_INACCESSIBLE_WRITE:
+ errStr = _("A required output parameter could not be "
+ "written");
+ break;
+
+ case GSS_S_CALL_BAD_STRUCTURE:
+ errStr = _("A parameter was malformed");
+ break;
+
+ default:
+ errStr = _("An invalid status code was supplied");
+ break;
+ }
+
+ /* we now need to determine new value of msgCtxt */
+ if (GSS_ROUTINE_ERROR(status))
+ *msgCtxt = 1;
+ else if ((oneVal = GSS_SUPPLEMENTARY_INFO(status)) != 0)
+ *msgCtxt = (OM_uint32)(oneVal << 1);
+ else
+ *msgCtxt = 0;
+
+ } else if ((*msgCtxt == 0 || *msgCtxt == 1) &&
+ (oneVal = GSS_ROUTINE_ERROR(status))) {
+ switch (oneVal) {
+ case GSS_S_BAD_MECH:
+ errStr = _("An unsupported mechanism was requested");
+ break;
+
+ case GSS_S_BAD_NAME:
+ errStr = _("An invalid name was supplied");
+ break;
+
+ case GSS_S_BAD_NAMETYPE:
+ errStr = _("A supplied name was of an unsupported "
+ "type");
+ break;
+
+ case GSS_S_BAD_BINDINGS:
+ errStr = _("Incorrect channel bindings were supplied");
+ break;
+
+ case GSS_S_BAD_SIG: /* same as GSS_S_BAD_MIC: */
+ errStr = _("A token had an invalid Message Integrity "
+ "Check (MIC)");
+ break;
+
+ case GSS_S_NO_CRED:
+ errStr = _("No credentials were supplied, or the "
+ "credentials were unavailable or "
+ "inaccessible");
+ break;
+
+ case GSS_S_NO_CONTEXT:
+ errStr = _("No context has been established");
+ break;
+
+ case GSS_S_DEFECTIVE_TOKEN:
+ errStr = _("Invalid token was supplied");
+ break;
+
+ case GSS_S_DEFECTIVE_CREDENTIAL:
+ errStr = _("Invalid credential was supplied");
+ break;
+
+ case GSS_S_CREDENTIALS_EXPIRED:
+ errStr = _("The referenced credential has expired");
+ break;
+
+ case GSS_S_CONTEXT_EXPIRED:
+ errStr = _("The referenced context has expired");
+ break;
+
+ case GSS_S_FAILURE:
+ errStr = _("Unspecified GSS failure. Minor code "
+ "may provide more information");
+ break;
+
+ case GSS_S_BAD_QOP:
+ errStr = _("The quality-of-protection (QOP) "
+ "requested could not be provided");
+ break;
+
+ case GSS_S_UNAUTHORIZED:
+ errStr = _("The operation is forbidden by local "
+ "security policy");
+ break;
+
+ case GSS_S_UNAVAILABLE:
+ errStr = _("The operation or option is not "
+ "available or unsupported");
+ break;
+
+ case GSS_S_DUPLICATE_ELEMENT:
+ errStr = _("The requested credential element "
+ "already exists");
+ break;
+
+ case GSS_S_NAME_NOT_MN:
+ errStr = _("The provided name was not mechanism "
+ "specific (MN)");
+ break;
+
+ case GSS_S_BAD_STATUS:
+ default:
+ errStr = _("An invalid status code was supplied");
+ }
+
+ /* we must determine if the caller should call us again */
+ if ((oneVal = GSS_SUPPLEMENTARY_INFO(status)) != 0)
+ *msgCtxt = (OM_uint32)(oneVal << 1);
+ else
+ *msgCtxt = 0;
+
+ } else if ((*msgCtxt == 0 || *msgCtxt >= 2) &&
+ (oneVal = GSS_SUPPLEMENTARY_INFO(status))) {
+ /*
+ * if msgCtxt is not 0, then it should encode
+ * the supplementary error code we should be printing
+ */
+ if (*msgCtxt >= 2)
+ oneVal = (OM_uint32) (*msgCtxt) >> 1;
+ else
+ oneVal = GSS_SUPPLEMENTARY_INFO(status);
+
+ /* we display the errors LSB first */
+ for (i = 0; i < 16; i++) {
+ if (oneVal & mask) {
+ haveErr = 1;
+ break;
+ }
+ mask <<= 1;
+ }
+
+ /* isolate the bit or if not found set to illegal value */
+ if (haveErr)
+ currErr = oneVal & mask;
+ else
+ currErr = 1 << 17; /* illegal value */
+
+ switch (currErr) {
+ case GSS_S_CONTINUE_NEEDED:
+ errStr = _("The routine must be called again to "
+ "complete its function");
+ break;
+
+ case GSS_S_DUPLICATE_TOKEN:
+ errStr = _("The token was a duplicate of an earlier "
+ "token");
+ break;
+
+ case GSS_S_OLD_TOKEN:
+ errStr = _("The token's validity period has expired");
+ break;
+
+ case GSS_S_UNSEQ_TOKEN:
+ errStr = _("A later token has already been processed");
+ break;
+
+ case GSS_S_GAP_TOKEN:
+ errStr = _("An expected per-message token was not "
+ "received");
+ break;
+
+ default:
+ errStr = _("An invalid status code was supplied");
+ }
+
+ /*
+ * we must check if there is any other supplementary errors
+ * if found, then turn off current bit, and store next value
+ * in msgCtxt shifted by 1 bit
+ */
+ if (!haveErr)
+ *msgCtxt = 0;
+ else if (GSS_SUPPLEMENTARY_INFO(oneVal) ^ mask)
+ *msgCtxt = (OM_uint32)
+ ((GSS_SUPPLEMENTARY_INFO(oneVal) ^ mask) << 1);
+ else
+ *msgCtxt = 0;
+ }
+
+ if (errStr == NULL)
+ errStr = "An invalid status code was supplied";
+
+ /* now copy the status code and return to caller */
+ outStr->length = strlen(errStr);
+ outStr->value = gssalloc_strdup(errStr);
+ if (outStr->value == NULL) {
+ outStr->length = 0;
+ return (GSS_S_FAILURE);
+ }
+
+ return (GSS_S_COMPLETE);
+} /* displayMajor */
diff --git a/src/lib/gssapi/mechglue/g_dup_name.c b/src/lib/gssapi/mechglue/g_dup_name.c
new file mode 100644
index 000000000000..85306fcc1913
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_dup_name.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* #pragma ident "@(#)g_dup_name.c 1.14 04/02/23 SMI" */
+
+/*
+ * routine gss_duplicate_name
+ *
+ * This routine does not rely on mechanism implementation of this
+ * name, but instead uses mechanism specific gss_import_name routine.
+ */
+
+#include <mglueP.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+static OM_uint32
+val_dup_name_args(
+ OM_uint32 *minor_status,
+ const gss_name_t src_name,
+ gss_name_t *dest_name)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (dest_name != NULL)
+ *dest_name = GSS_C_NO_NAME;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ /* if output_name is NULL, simply return */
+ if (dest_name == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (src_name == GSS_C_NO_NAME)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
+
+ return (GSS_S_COMPLETE);
+}
+
+
+OM_uint32 KRB5_CALLCONV
+gss_duplicate_name(minor_status,
+ src_name,
+ dest_name)
+OM_uint32 *minor_status;
+const gss_name_t src_name;
+gss_name_t *dest_name;
+{
+ gss_union_name_t src_union, dest_union;
+ OM_uint32 major_status = GSS_S_FAILURE;
+
+ major_status = val_dup_name_args(minor_status, src_name, dest_name);
+ if (major_status != GSS_S_COMPLETE)
+ return (major_status);
+
+ src_union = (gss_union_name_t)src_name;
+
+ /*
+ * First create the union name struct that will hold the external
+ * name and the name type.
+ */
+ dest_union = (gss_union_name_t)malloc(sizeof (gss_union_name_desc));
+ if (!dest_union)
+ goto allocation_failure;
+
+ dest_union->loopback = 0;
+ dest_union->mech_type = 0;
+ dest_union->mech_name = 0;
+ dest_union->name_type = 0;
+ dest_union->external_name = 0;
+
+ /* Now copy the external representaion */
+ if (gssint_create_copy_buffer(src_union->external_name,
+ &dest_union->external_name, 0))
+ goto allocation_failure;
+
+ if (src_union->name_type != GSS_C_NULL_OID) {
+ major_status = generic_gss_copy_oid(minor_status,
+ src_union->name_type,
+ &dest_union->name_type);
+ if (major_status != GSS_S_COMPLETE) {
+ map_errcode(minor_status);
+ goto allocation_failure;
+ }
+ }
+
+ /*
+ * See if source name is mechanim specific, if so then need to import it
+ */
+ if (src_union->mech_type) {
+ major_status = generic_gss_copy_oid(minor_status,
+ src_union->mech_type,
+ &dest_union->mech_type);
+ if (major_status != GSS_S_COMPLETE) {
+ map_errcode(minor_status);
+ goto allocation_failure;
+ }
+
+ major_status = gssint_import_internal_name(minor_status,
+ src_union->mech_type,
+ src_union,
+ &dest_union->mech_name);
+ if (major_status != GSS_S_COMPLETE)
+ goto allocation_failure;
+ }
+
+
+ dest_union->loopback = dest_union;
+ *dest_name = (gss_name_t)dest_union;
+ return (GSS_S_COMPLETE);
+
+allocation_failure:
+ if (dest_union) {
+ if (dest_union->external_name) {
+ if (dest_union->external_name->value)
+ free(dest_union->external_name->value);
+ free(dest_union->external_name);
+ }
+ if (dest_union->name_type)
+ (void) generic_gss_release_oid(minor_status,
+ &dest_union->name_type);
+ if (dest_union->mech_name)
+ (void) gssint_release_internal_name(minor_status,
+ dest_union->mech_type,
+ &dest_union->mech_name);
+ if (dest_union->mech_type)
+ (void) generic_gss_release_oid(minor_status,
+ &dest_union->mech_type);
+ free(dest_union);
+ }
+ return (major_status);
+} /* gss_duplicate_name */
diff --git a/src/lib/gssapi/mechglue/g_encapsulate_token.c b/src/lib/gssapi/mechglue/g_encapsulate_token.c
new file mode 100644
index 000000000000..6ce0eeb0f5d0
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_encapsulate_token.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * 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 PADL Software 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 BY PADL SOFTWARE AND CONTRIBUTORS ``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 PADL SOFTWARE 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 "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_encapsulate_token(gss_const_buffer_t input_token,
+ gss_const_OID token_oid,
+ gss_buffer_t output_token)
+{
+ unsigned int tokenSize;
+ unsigned char *buf;
+
+ if (input_token == GSS_C_NO_BUFFER || token_oid == GSS_C_NO_OID)
+ return GSS_S_CALL_INACCESSIBLE_READ;
+
+ if (output_token == GSS_C_NO_BUFFER)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ tokenSize = g_token_size(token_oid, input_token->length);
+
+ assert(tokenSize > 2);
+ tokenSize -= 2; /* TOK_ID */
+
+ output_token->value = malloc(tokenSize);
+ if (output_token->value == NULL)
+ return GSS_S_FAILURE;
+
+ buf = output_token->value;
+
+ g_make_token_header(token_oid, input_token->length, &buf, -1);
+ memcpy(buf, input_token->value, input_token->length);
+ output_token->length = tokenSize;
+
+ return GSS_S_COMPLETE;
+}
diff --git a/src/lib/gssapi/mechglue/g_exp_sec_context.c b/src/lib/gssapi/mechglue/g_exp_sec_context.c
new file mode 100644
index 000000000000..b63745299f64
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_exp_sec_context.c
@@ -0,0 +1,144 @@
+/* #pragma ident "@(#)g_exp_sec_context.c 1.14 04/02/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_export_sec_context
+ */
+#ifndef LEAN_CLIENT
+
+#include "mglueP.h"
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+
+static OM_uint32
+val_exp_sec_ctx_args(
+ OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ gss_buffer_t interprocess_token)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (interprocess_token != GSS_C_NO_BUFFER) {
+ interprocess_token->length = 0;
+ interprocess_token->value = NULL;
+ }
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
+
+ if (interprocess_token == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ return (GSS_S_COMPLETE);
+}
+
+
+OM_uint32 KRB5_CALLCONV
+gss_export_sec_context(minor_status,
+ context_handle,
+ interprocess_token)
+
+OM_uint32 * minor_status;
+gss_ctx_id_t * context_handle;
+gss_buffer_t interprocess_token;
+
+{
+ OM_uint32 status;
+ OM_uint32 length;
+ gss_union_ctx_id_t ctx = NULL;
+ gss_mechanism mech;
+ gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
+ char *buf;
+
+ status = val_exp_sec_ctx_args(minor_status,
+ context_handle, interprocess_token);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) *context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+ if (!mech)
+ return GSS_S_BAD_MECH;
+ if (!mech->gss_export_sec_context)
+ return (GSS_S_UNAVAILABLE);
+
+ status = mech->gss_export_sec_context(minor_status,
+ &ctx->internal_ctx_id, &token);
+ if (status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ goto cleanup;
+ }
+
+ length = token.length + 4 + ctx->mech_type->length;
+ interprocess_token->length = length;
+ interprocess_token->value = malloc(length);
+ if (interprocess_token->value == 0) {
+ *minor_status = ENOMEM;
+ status = GSS_S_FAILURE;
+ goto cleanup;
+ }
+ buf = interprocess_token->value;
+ length = ctx->mech_type->length;
+ buf[3] = (unsigned char) (length & 0xFF);
+ length >>= 8;
+ buf[2] = (unsigned char) (length & 0xFF);
+ length >>= 8;
+ buf[1] = (unsigned char) (length & 0xFF);
+ length >>= 8;
+ buf[0] = (unsigned char) (length & 0xFF);
+ memcpy(buf+4, ctx->mech_type->elements, (size_t) ctx->mech_type->length);
+ memcpy(buf+4+ctx->mech_type->length, token.value, token.length);
+
+ status = GSS_S_COMPLETE;
+
+cleanup:
+ (void) gss_release_buffer(minor_status, &token);
+ if (ctx != NULL && ctx->internal_ctx_id == GSS_C_NO_CONTEXT) {
+ /* If the mech deleted its context, delete the union context. */
+ free(ctx->mech_type->elements);
+ free(ctx->mech_type);
+ free(ctx);
+ *context_handle = GSS_C_NO_CONTEXT;
+ }
+ return status;
+}
+#endif /*LEAN_CLIENT */
diff --git a/src/lib/gssapi/mechglue/g_export_cred.c b/src/lib/gssapi/mechglue/g_export_cred.c
new file mode 100644
index 000000000000..8f5fe4ad5a2b
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_export_cred.c
@@ -0,0 +1,114 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/gssapi/mechglue/g_export_cred.c - gss_export_cred definition */
+/*
+ * Copyright (C) 2012 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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
+ * COPYRIGHT HOLDER 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 "mglueP.h"
+
+static OM_uint32
+val_exp_cred_args(OM_uint32 *minor_status, gss_cred_id_t cred_handle,
+ gss_buffer_t token)
+{
+
+ /* Initialize outputs. */
+ if (minor_status != NULL)
+ *minor_status = 0;
+ if (token != GSS_C_NO_BUFFER) {
+ token->length = 0;
+ token->value = NULL;
+ }
+
+ /* Validate arguments. */
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+ if (cred_handle == GSS_C_NO_CREDENTIAL)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CRED;
+ if (token == GSS_C_NO_BUFFER)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_export_cred(OM_uint32 * minor_status, gss_cred_id_t cred_handle,
+ gss_buffer_t token)
+{
+ OM_uint32 status, tmpmin;
+ gss_union_cred_t cred;
+ gss_OID mech_oid;
+ gss_OID public_oid;
+ gss_mechanism mech;
+ gss_buffer_desc mech_token;
+ struct k5buf buf;
+ char lenbuf[4];
+ int i;
+
+ status = val_exp_cred_args(minor_status, cred_handle, token);
+ if (status != GSS_S_COMPLETE)
+ return status;
+
+ k5_buf_init_dynamic(&buf);
+
+ cred = (gss_union_cred_t) cred_handle;
+ for (i = 0; i < cred->count; i++) {
+ /* Get an export token for this mechanism. */
+ mech_oid = &cred->mechs_array[i];
+ public_oid = gssint_get_public_oid(mech_oid);
+ mech = gssint_get_mechanism(mech_oid);
+ if (mech == NULL) {
+ status = GSS_S_DEFECTIVE_CREDENTIAL;
+ goto error;
+ }
+ if (mech->gss_export_cred == NULL) {
+ status = GSS_S_UNAVAILABLE;
+ goto error;
+ }
+ status = mech->gss_export_cred(minor_status, cred->cred_array[i],
+ &mech_token);
+ if (status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ goto error;
+ }
+
+ /* Append the mech OID and token to buf. */
+ store_32_be(public_oid->length, lenbuf);
+ k5_buf_add_len(&buf, lenbuf, 4);
+ k5_buf_add_len(&buf, public_oid->elements, public_oid->length);
+ store_32_be(mech_token.length, lenbuf);
+ k5_buf_add_len(&buf, lenbuf, 4);
+ k5_buf_add_len(&buf, mech_token.value, mech_token.length);
+ gss_release_buffer(&tmpmin, &mech_token);
+ }
+
+ return k5buf_to_gss(minor_status, &buf, token);
+
+error:
+ k5_buf_free(&buf);
+ return status;
+}
diff --git a/src/lib/gssapi/mechglue/g_export_name.c b/src/lib/gssapi/mechglue/g_export_name.c
new file mode 100644
index 000000000000..c845f8caf70f
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_export_name.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1996,1997, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+/* #pragma ident "@(#)g_export_name.c 1.11 00/07/17 SMI" */
+
+/*
+ * glue routine gss_export_name
+ *
+ * Will either call the mechanism defined gss_export_name, or if one is
+ * not defined will call a generic_gss_export_name routine.
+ */
+
+#include <mglueP.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+OM_uint32 KRB5_CALLCONV
+gss_export_name(minor_status,
+ input_name,
+ exported_name)
+OM_uint32 * minor_status;
+const gss_name_t input_name;
+gss_buffer_t exported_name;
+{
+ gss_union_name_t union_name;
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (exported_name != GSS_C_NO_BUFFER) {
+ exported_name->value = NULL;
+ exported_name->length = 0;
+ }
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL || exported_name == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (input_name == GSS_C_NO_NAME)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
+
+ union_name = (gss_union_name_t)input_name;
+
+ /* the name must be in mechanism specific format */
+ if (!union_name->mech_type)
+ return (GSS_S_NAME_NOT_MN);
+
+ return gssint_export_internal_name(minor_status, union_name->mech_type,
+ union_name->mech_name, exported_name);
+}
diff --git a/src/lib/gssapi/mechglue/g_export_name_comp.c b/src/lib/gssapi/mechglue/g_export_name_comp.c
new file mode 100644
index 000000000000..ab538a095d6a
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_export_name_comp.c
@@ -0,0 +1,72 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2009 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+/*
+ * glue routine for gss_export_name_composite
+ */
+
+#include "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_export_name_composite(OM_uint32 *minor_status,
+ gss_name_t name,
+ gss_buffer_t exp_composite_name)
+{
+ OM_uint32 status;
+ gss_union_name_t union_name;
+ gss_mechanism mech;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (name == GSS_C_NO_NAME)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME;
+
+ if (exp_composite_name == GSS_C_NO_BUFFER)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ *minor_status = 0;
+
+ union_name = (gss_union_name_t)name;
+
+ if (union_name->mech_type == GSS_C_NO_OID)
+ return GSS_S_UNAVAILABLE;
+
+ mech = gssint_get_mechanism(name->mech_type);
+ if (mech == NULL)
+ return GSS_S_BAD_NAME;
+
+ if (mech->gss_export_name_composite == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ status = (*mech->gss_export_name_composite)(minor_status,
+ union_name->mech_name,
+ exp_composite_name);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+
+ return status;
+}
diff --git a/src/lib/gssapi/mechglue/g_get_name_attr.c b/src/lib/gssapi/mechglue/g_get_name_attr.c
new file mode 100644
index 000000000000..047d5d428fb0
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_get_name_attr.c
@@ -0,0 +1,93 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2009 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/* Glue routine for gss_get_name_attribute */
+
+#include "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_get_name_attribute(OM_uint32 *minor_status,
+ gss_name_t name,
+ gss_buffer_t attr,
+ int *authenticated,
+ int *complete,
+ gss_buffer_t value,
+ gss_buffer_t display_value,
+ int *more)
+{
+ OM_uint32 status;
+ gss_union_name_t union_name;
+ gss_mechanism mech;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (name == GSS_C_NO_NAME)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME;
+ if (attr == GSS_C_NO_BUFFER)
+ return GSS_S_CALL_INACCESSIBLE_READ;
+ if (more == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (authenticated != NULL)
+ *authenticated = 0;
+ if (complete != NULL)
+ *complete = 0;
+ if (value != GSS_C_NO_BUFFER) {
+ value->value = NULL;
+ value->length = 0;
+ }
+ if (display_value != GSS_C_NO_BUFFER) {
+ display_value->value = NULL;
+ display_value->length = 0;
+ }
+
+ *minor_status = 0;
+
+ union_name = (gss_union_name_t)name;
+
+ if (union_name->mech_type == GSS_C_NO_OID)
+ return GSS_S_UNAVAILABLE;
+
+ mech = gssint_get_mechanism(name->mech_type);
+ if (mech == NULL)
+ return GSS_S_BAD_NAME;
+
+ if (mech->gss_get_name_attribute == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ status = (*mech->gss_get_name_attribute)(minor_status,
+ union_name->mech_name,
+ attr,
+ authenticated,
+ complete,
+ value,
+ display_value,
+ more);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+
+ return status;
+}
diff --git a/src/lib/gssapi/mechglue/g_glue.c b/src/lib/gssapi/mechglue/g_glue.c
new file mode 100644
index 000000000000..4aa3591a0d06
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_glue.c
@@ -0,0 +1,752 @@
+/* #pragma ident "@(#)g_glue.c 1.25 04/02/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+#define MSO_BIT (8*(sizeof (int) - 1)) /* Most significant octet bit */
+
+extern gss_mechanism *gssint_mechs_array;
+
+/*
+ * This file contains the support routines for the glue layer.
+ */
+
+/*
+ * get_der_length: Givin a pointer to a buffer that contains a DER encoded
+ * length, decode the length updating the buffer to point to the character
+ * after the DER encoding. The parameter bytes will point to the number of
+ * bytes that made up the DER encoding of the length originally pointed to
+ * by the buffer. Note we return -1 on error.
+ */
+int
+gssint_get_der_length(unsigned char **buf, unsigned int buf_len, unsigned int *bytes)
+{
+ /* p points to the beginning of the buffer */
+ unsigned char *p = *buf;
+ int length, new_length;
+ unsigned int octets;
+
+ if (buf_len < 1)
+ return (-1);
+
+ /* We should have at least one byte */
+ *bytes = 1;
+
+ /*
+ * If the High order bit is not set then the length is just the value
+ * of *p.
+ */
+ if (*p < 128) {
+ *buf = p+1; /* Advance the buffer */
+ return (*p); /* return the length */
+ }
+
+ /*
+ * if the High order bit is set, then the low order bits represent
+ * the number of bytes that contain the DER encoding of the length.
+ */
+
+ octets = *p++ & 0x7f;
+ *bytes += octets;
+
+ /* See if the supplied buffer contains enough bytes for the length. */
+ if (octets > buf_len - 1)
+ return (-1);
+
+ /*
+ * Calculate a multibyte length. The length is encoded as an
+ * unsigned integer base 256.
+ */
+ for (length = 0; octets; octets--) {
+ new_length = (length << 8) + *p++;
+ if (new_length < length) /* overflow */
+ return (-1);
+ length = new_length;
+ }
+
+ *buf = p; /* Advance the buffer */
+
+ return (length);
+}
+
+/*
+ * der_length_size: Return the number of bytes to encode a given length.
+ */
+unsigned int
+gssint_der_length_size(unsigned int len)
+{
+ int i;
+
+ if (len < 128)
+ return (1);
+
+ for (i = 0; len; i++) {
+ len >>= 8;
+ }
+
+ return (i+1);
+}
+
+/*
+ * put_der_length: Encode the supplied length into the buffer pointed to
+ * by buf. max_length represents the maximum length of the buffer pointed
+ * to by buff. We will advance buf to point to the character after the newly
+ * DER encoded length. We return 0 on success or -l it the length cannot
+ * be encoded in max_len characters.
+ */
+int
+gssint_put_der_length(unsigned int length, unsigned char **buf, unsigned int max_len)
+{
+ unsigned char *s, *p;
+ unsigned int buf_len = 0;
+ int i, first;
+
+ /* Oops */
+ if (buf == 0 || max_len < 1)
+ return (-1);
+
+ s = *buf;
+
+ /* Single byte is the length */
+ if (length < 128) {
+ *s++ = length;
+ *buf = s;
+ return (0);
+ }
+
+ /* First byte contains the number of octets */
+ p = s + 1;
+
+ /* Running total of the DER encoding length */
+ buf_len = 0;
+
+ /*
+ * Encode MSB first. We do the encoding by setting a shift
+ * factor to MSO_BIT (24 for 32 bit words) and then shifting the length
+ * by the factor. We then encode the resulting low order byte.
+ * We subtract 8 from the shift factor and repeat to ecnode the next
+ * byte. We stop when the shift factor is zero or we've run out of
+ * buffer to encode into.
+ */
+ first = 0;
+ for (i = MSO_BIT; i >= 0 && buf_len <= max_len; i -= 8) {
+ unsigned int v;
+ v = (length >> i) & 0xff;
+ if ((v) || first) {
+ buf_len += 1;
+ *p++ = v;
+ first = 1;
+ }
+ }
+ if (i >= 0) /* buffer overflow */
+ return (-1);
+
+ /*
+ * We go back now and set the first byte to be the length with
+ * the high order bit set.
+ */
+ *s = buf_len | 0x80;
+ *buf = p;
+
+ return (0);
+}
+
+
+/*
+ * glue routine for get_mech_type
+ *
+ */
+
+OM_uint32 gssint_get_mech_type_oid(OID, token)
+ gss_OID OID;
+ gss_buffer_t token;
+{
+ unsigned char * buffer_ptr;
+ int length;
+
+ /*
+ * 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 fills in the OID value and returns an error as necessary.
+ */
+
+ if (OID == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if ((token == NULL) || (token->value == NULL))
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ /* Skip past the APP/Sequnce byte and the token length */
+
+ buffer_ptr = (unsigned char *) token->value;
+
+ if (*(buffer_ptr++) != 0x60)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ length = *buffer_ptr++;
+
+ /* check if token length is null */
+ if (length == 0)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ if (length & 0x80) {
+ if ((length & 0x7f) > 4)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ buffer_ptr += length & 0x7f;
+ }
+
+ if (*(buffer_ptr++) != 0x06)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ OID->length = (OM_uint32) *(buffer_ptr++);
+ OID->elements = (void *) buffer_ptr;
+ return (GSS_S_COMPLETE);
+}
+
+/*
+ * The following mechanisms do not always identify themselves
+ * per the GSS-API specification, when interoperating with MS
+ * peers. We include the OIDs here so we do not have to ilnk
+ * with the mechanism.
+ */
+static gss_OID_desc gss_ntlm_mechanism_oid_desc =
+ {10, (void *)"\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a"};
+static gss_OID_desc gss_spnego_mechanism_oid_desc =
+ {6, (void *)"\x2b\x06\x01\x05\x05\x02"};
+static gss_OID_desc gss_krb5_mechanism_oid_desc =
+ {9, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"};
+
+#define NTLMSSP_SIGNATURE "NTLMSSP"
+
+OM_uint32 gssint_get_mech_type(OID, token)
+ gss_OID OID;
+ gss_buffer_t token;
+{
+ /* Check for interoperability exceptions */
+ if (token->length >= sizeof(NTLMSSP_SIGNATURE) &&
+ memcmp(token->value, NTLMSSP_SIGNATURE,
+ sizeof(NTLMSSP_SIGNATURE)) == 0) {
+ *OID = gss_ntlm_mechanism_oid_desc;
+ } else if (token->length != 0 &&
+ ((char *)token->value)[0] == 0x6E) {
+ /* Could be a raw AP-REQ (check for APPLICATION tag) */
+ *OID = gss_krb5_mechanism_oid_desc;
+ } else if (token->length == 0) {
+ *OID = gss_spnego_mechanism_oid_desc;
+ } else {
+ return gssint_get_mech_type_oid(OID, token);
+ }
+
+ return (GSS_S_COMPLETE);
+}
+
+static OM_uint32
+import_internal_attributes(OM_uint32 *minor,
+ gss_mechanism dmech,
+ gss_union_name_t sname,
+ gss_name_t dname)
+{
+ OM_uint32 major, tmpMinor;
+ gss_mechanism smech;
+ gss_buffer_set_t attrs = GSS_C_NO_BUFFER_SET;
+ size_t i;
+
+ if (sname->mech_name == GSS_C_NO_NAME)
+ return (GSS_S_UNAVAILABLE);
+
+ smech = gssint_get_mechanism (sname->mech_type);
+ if (smech == NULL)
+ return (GSS_S_BAD_MECH);
+
+ if (smech->gss_inquire_name == NULL ||
+ smech->gss_get_name_attribute == NULL)
+ return (GSS_S_UNAVAILABLE);
+
+ if (dmech->gss_set_name_attribute == NULL)
+ return (GSS_S_UNAVAILABLE);
+
+ major = smech->gss_inquire_name(minor, sname->mech_name,
+ NULL, NULL, &attrs);
+ if (GSS_ERROR(major) || attrs == GSS_C_NO_BUFFER_SET) {
+ gss_release_buffer_set(&tmpMinor, &attrs);
+ return (major);
+ }
+
+ for (i = 0; i < attrs->count; i++) {
+ int more = -1;
+
+ while (more != 0) {
+ gss_buffer_desc value, display_value;
+ int authenticated, complete;
+
+ major = smech->gss_get_name_attribute(minor, sname->mech_name,
+ &attrs->elements[i],
+ &authenticated, &complete,
+ &value, &display_value,
+ &more);
+ if (GSS_ERROR(major))
+ continue;
+
+ if (authenticated) {
+ dmech->gss_set_name_attribute(minor, dname, complete,
+ &attrs->elements[i], &value);
+ }
+
+ gss_release_buffer(&tmpMinor, &value);
+ gss_release_buffer(&tmpMinor, &display_value);
+ }
+ }
+
+ gss_release_buffer_set(&tmpMinor, &attrs);
+
+ return (GSS_S_COMPLETE);
+}
+
+/*
+ * Internal routines to get and release an internal mechanism name
+ */
+
+OM_uint32 gssint_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, tmpMinor;
+ gss_mechanism mech;
+ gss_OID public_mech;
+
+ mech = gssint_get_mechanism (mech_type);
+ if (mech == NULL)
+ return (GSS_S_BAD_MECH);
+
+ /*
+ * If we are importing a name for the same mechanism, and the
+ * mechanism implements gss_duplicate_name, then use that.
+ */
+ if (union_name->mech_type != GSS_C_NO_OID &&
+ union_name->mech_name != GSS_C_NO_NAME &&
+ g_OID_equal(union_name->mech_type, mech_type) &&
+ mech->gss_duplicate_name != NULL) {
+ status = mech->gss_duplicate_name(minor_status,
+ union_name->mech_name,
+ internal_name);
+ if (status != GSS_S_UNAVAILABLE) {
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ return (status);
+ }
+ }
+
+ if (mech->gssspi_import_name_by_mech) {
+ public_mech = gssint_get_public_oid(mech_type);
+ status = mech->gssspi_import_name_by_mech(minor_status, public_mech,
+ union_name->external_name,
+ union_name->name_type,
+ internal_name);
+ } else if (mech->gss_import_name) {
+ status = mech->gss_import_name(minor_status, union_name->external_name,
+ union_name->name_type, internal_name);
+ } else {
+ return (GSS_S_UNAVAILABLE);
+ }
+
+ if (status == GSS_S_COMPLETE) {
+ /* Attempt to round-trip attributes */
+ (void) import_internal_attributes(&tmpMinor, mech,
+ union_name, *internal_name);
+ } else {
+ map_error(minor_status, mech);
+ }
+
+ return (status);
+}
+
+OM_uint32 gssint_export_internal_name(minor_status, mech_type,
+ internal_name, name_buf)
+ OM_uint32 *minor_status;
+ const gss_OID mech_type;
+ const gss_name_t internal_name;
+ gss_buffer_t name_buf;
+{
+ OM_uint32 status;
+ gss_mechanism mech;
+ gss_buffer_desc dispName;
+ gss_OID nameOid;
+ unsigned char *buf = NULL;
+ const unsigned char tokId[] = "\x04\x01";
+ const unsigned int tokIdLen = 2;
+ const int mechOidLenLen = 2, mechOidTagLen = 1, nameLenLen = 4;
+ int mechOidDERLen = 0;
+ int mechOidLen = 0;
+
+ mech = gssint_get_mechanism(mech_type);
+ if (!mech)
+ return (GSS_S_BAD_MECH);
+
+ if (mech->gss_export_name) {
+ status = mech->gss_export_name(minor_status,
+ internal_name,
+ name_buf);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ return status;
+ }
+
+ /*
+ * if we are here it is because the mechanism does not provide
+ * a gss_export_name so we will use our implementation. We
+ * do required that the mechanism define a gss_display_name.
+ */
+ if (!mech->gss_display_name)
+ return (GSS_S_UNAVAILABLE);
+
+ /*
+ * NOTE: RFC2743 (section 3.2) governs the format of the outer
+ * wrapper of exported names; the mechanisms' specs govern
+ * the format of the inner portion of the exported name
+ * and, for some (e.g., RFC1964, the Kerberos V mech), a
+ * generic default as implemented here will do.
+ *
+ * The outer wrapper of an exported MN is: 2-octet tok Id
+ * (0x0401) + 2-octet network-byte order mech OID length + mech
+ * oid (in DER format, including DER tag and DER length) +
+ * 4-octet network-byte order length of inner portion + inner
+ * portion.
+ *
+ * For the Kerberos V mechanism the inner portion of an exported
+ * MN is the display name string and ignores the name type OID
+ * altogether. And we hope this will be so for any future
+ * mechanisms also, so that factoring name export/import out of
+ * the mech and into libgss pays off.
+ */
+ if ((status = mech->gss_display_name(minor_status,
+ internal_name,
+ &dispName,
+ &nameOid))
+ != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ return (status);
+ }
+
+ /* determine the size of the buffer needed */
+ mechOidDERLen = gssint_der_length_size(mech_type->length);
+ name_buf->length = tokIdLen + mechOidLenLen +
+ mechOidTagLen + mechOidDERLen +
+ mech_type->length +
+ nameLenLen + dispName.length;
+ if ((name_buf->value = (void*)gssalloc_malloc(name_buf->length)) ==
+ (void*)NULL) {
+ name_buf->length = 0;
+ (void) gss_release_buffer(&status, &dispName);
+ return (GSS_S_FAILURE);
+ }
+
+ /* now create the name ..... */
+ buf = (unsigned char *)name_buf->value;
+ (void) memset(name_buf->value, 0, name_buf->length);
+ (void) memcpy(buf, tokId, tokIdLen);
+ buf += tokIdLen;
+
+ /* spec allows only 2 bytes for the mech oid length */
+ mechOidLen = mechOidDERLen + mechOidTagLen + mech_type->length;
+ store_16_be(mechOidLen, buf);
+ buf += 2;
+
+ /*
+ * DER Encoding of mech OID contains OID Tag (0x06), length and
+ * mech OID value
+ */
+ *buf++ = 0x06;
+ if (gssint_put_der_length(mech_type->length, &buf,
+ (name_buf->length - tokIdLen -2)) != 0) {
+ name_buf->length = 0;
+ free(name_buf->value);
+ (void) gss_release_buffer(&status, &dispName);
+ return (GSS_S_FAILURE);
+ }
+
+ (void) memcpy(buf, mech_type->elements, mech_type->length);
+ buf += mech_type->length;
+
+ /* spec designates the next 4 bytes for the name length */
+ store_32_be(dispName.length, buf);
+ buf += 4;
+
+ /* for the final ingredient - add the name from gss_display_name */
+ (void) memcpy(buf, dispName.value, dispName.length);
+
+ /* release the buffer obtained from gss_display_name */
+ (void) gss_release_buffer(minor_status, &dispName);
+ return (GSS_S_COMPLETE);
+} /* gssint_export_internal_name */
+
+OM_uint32 gssint_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 = gssint_get_mechanism (mech_type);
+ if (mech) {
+ if (mech->gss_display_name) {
+ status = mech->gss_display_name (
+ minor_status,
+ internal_name,
+ external_name,
+ name_type);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return (status);
+ }
+
+ return (GSS_S_BAD_MECH);
+}
+
+OM_uint32 gssint_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 = gssint_get_mechanism (mech_type);
+ if (mech) {
+ if (mech->gss_release_name) {
+ status = mech->gss_release_name (
+ minor_status,
+ internal_name);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return (status);
+ }
+
+ return (GSS_S_BAD_MECH);
+}
+
+OM_uint32 gssint_delete_internal_sec_context (minor_status,
+ mech_type,
+ internal_ctx,
+ output_token)
+OM_uint32 *minor_status;
+gss_OID mech_type;
+gss_ctx_id_t *internal_ctx;
+gss_buffer_t output_token;
+{
+ OM_uint32 status;
+ gss_mechanism mech;
+
+ mech = gssint_get_mechanism (mech_type);
+ if (mech) {
+ if (mech->gss_delete_sec_context)
+ status = mech->gss_delete_sec_context (minor_status,
+ internal_ctx,
+ output_token);
+ else
+ status = GSS_S_UNAVAILABLE;
+
+ return (status);
+ }
+
+ return (GSS_S_BAD_MECH);
+}
+
+/*
+ * This function converts an internal gssapi name to a union gssapi
+ * name. Note that internal_name should be considered "consumed" by
+ * this call, whether or not we return an error.
+ */
+OM_uint32 gssint_convert_name_to_union_name(minor_status, mech,
+ internal_name, external_name)
+ OM_uint32 *minor_status;
+ gss_mechanism mech;
+ gss_name_t internal_name;
+ gss_name_t *external_name;
+{
+ OM_uint32 major_status,tmp;
+ gss_union_name_t union_name;
+
+ union_name = (gss_union_name_t) malloc (sizeof(gss_union_name_desc));
+ if (!union_name) {
+ major_status = GSS_S_FAILURE;
+ *minor_status = ENOMEM;
+ map_errcode(minor_status);
+ goto allocation_failure;
+ }
+ union_name->mech_type = 0;
+ union_name->mech_name = internal_name;
+ union_name->name_type = 0;
+ union_name->external_name = 0;
+
+ major_status = generic_gss_copy_oid(minor_status, &mech->mech_type,
+ &union_name->mech_type);
+ if (major_status != GSS_S_COMPLETE) {
+ map_errcode(minor_status);
+ goto allocation_failure;
+ }
+
+ union_name->external_name =
+ (gss_buffer_t) malloc(sizeof(gss_buffer_desc));
+ if (!union_name->external_name) {
+ major_status = GSS_S_FAILURE;
+ goto allocation_failure;
+ }
+ union_name->external_name->length = 0;
+ union_name->external_name->value = NULL;
+
+ major_status = mech->gss_display_name(minor_status,
+ internal_name,
+ union_name->external_name,
+ &union_name->name_type);
+ if (major_status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ goto allocation_failure;
+ }
+
+ union_name->loopback = union_name;
+ *external_name = /*(gss_name_t) CHECK */union_name;
+ return (GSS_S_COMPLETE);
+
+allocation_failure:
+ if (union_name) {
+ if (union_name->external_name) {
+ if (union_name->external_name->value)
+ free(union_name->external_name->value);
+ free(union_name->external_name);
+ }
+ if (union_name->name_type)
+ gss_release_oid(&tmp, &union_name->name_type);
+ if (union_name->mech_type)
+ gss_release_oid(&tmp, &union_name->mech_type);
+ free(union_name);
+ }
+ /*
+ * do as the top comment says - since we are now owners of
+ * internal_name, we must clean it up
+ */
+ if (internal_name)
+ (void) gssint_release_internal_name(&tmp, &mech->mech_type,
+ &internal_name);
+ return (major_status);
+}
+
+/*
+ * Glue routine for returning the mechanism-specific credential from a
+ * external union credential.
+ */
+gss_cred_id_t
+gssint_get_mechanism_cred(union_cred, mech_type)
+ gss_union_cred_t union_cred;
+ gss_OID mech_type;
+{
+ int i;
+
+ if (union_cred == GSS_C_NO_CREDENTIAL)
+ return GSS_C_NO_CREDENTIAL;
+
+ for (i=0; i < union_cred->count; i++) {
+ if (g_OID_equal(mech_type, &union_cred->mechs_array[i]))
+ return union_cred->cred_array[i];
+ }
+ return GSS_C_NO_CREDENTIAL;
+}
+
+/*
+ * Routine to create and copy the gss_buffer_desc structure.
+ * Both space for the structure and the data is allocated.
+ */
+OM_uint32
+gssint_create_copy_buffer(srcBuf, destBuf, addNullChar)
+ const gss_buffer_t srcBuf;
+ gss_buffer_t *destBuf;
+ int addNullChar;
+{
+ gss_buffer_t aBuf;
+ unsigned int len;
+
+ if (destBuf == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ *destBuf = 0;
+
+ aBuf = (gss_buffer_t)malloc(sizeof (gss_buffer_desc));
+ if (!aBuf)
+ return (GSS_S_FAILURE);
+
+ if (addNullChar)
+ len = srcBuf->length + 1;
+ else
+ len = srcBuf->length;
+
+ if (!(aBuf->value = (void*)gssalloc_malloc(len))) {
+ free(aBuf);
+ return (GSS_S_FAILURE);
+ }
+
+
+ (void) memcpy(aBuf->value, srcBuf->value, srcBuf->length);
+ aBuf->length = srcBuf->length;
+ *destBuf = aBuf;
+
+ /* optionally add a NULL character */
+ if (addNullChar)
+ ((char *)aBuf->value)[aBuf->length] = '\0';
+
+ return (GSS_S_COMPLETE);
+} /* ****** gssint_create_copy_buffer ****** */
diff --git a/src/lib/gssapi/mechglue/g_imp_cred.c b/src/lib/gssapi/mechglue/g_imp_cred.c
new file mode 100644
index 000000000000..77e2ff55ce57
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_imp_cred.c
@@ -0,0 +1,177 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/gssapi/mechglue/g_imp_cred.c - gss_import_cred definition */
+/*
+ * Copyright (C) 2012 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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
+ * COPYRIGHT HOLDER 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 "mglueP.h"
+
+static OM_uint32
+val_imp_cred_args(OM_uint32 *minor_status, gss_buffer_t token,
+ gss_cred_id_t *cred_handle)
+{
+ /* Initialize outputs. */
+ if (minor_status != NULL)
+ *minor_status = 0;
+ if (cred_handle != NULL)
+ *cred_handle = GSS_C_NO_CREDENTIAL;
+
+ /* Validate arguments. */
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+ if (cred_handle == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+ if (token == GSS_C_NO_BUFFER)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_DEFECTIVE_TOKEN;
+ if (GSS_EMPTY_BUFFER(token))
+ return GSS_S_DEFECTIVE_TOKEN;
+ return GSS_S_COMPLETE;
+}
+
+/* Populate mech_oid and mech_token with the next entry in token, using aliased
+ * memory from token. Advance token by the amount consumed. */
+static OM_uint32
+get_entry(OM_uint32 *minor_status, gss_buffer_t token, gss_OID mech_oid,
+ gss_buffer_t mech_token)
+{
+ OM_uint32 len;
+
+ /* Get the mechanism OID. */
+ if (token->length < 4)
+ return GSS_S_DEFECTIVE_TOKEN;
+ len = load_32_be(token->value);
+ if (token->length - 4 < len)
+ return GSS_S_DEFECTIVE_TOKEN;
+ mech_oid->length = len;
+ mech_oid->elements = (char *)token->value + 4;
+ token->value = (char *)token->value + 4 + len;
+ token->length -= 4 + len;
+
+ /* Get the mechanism token. */
+ if (token->length < 4)
+ return GSS_S_DEFECTIVE_TOKEN;
+ len = load_32_be(token->value);
+ if (token->length - 4 < len)
+ return GSS_S_DEFECTIVE_TOKEN;
+ mech_token->length = len;
+ mech_token->value = (char *)token->value + 4;
+ token->value = (char *)token->value + 4 + len;
+ token->length -= 4 + len;
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_import_cred(OM_uint32 *minor_status, gss_buffer_t token,
+ gss_cred_id_t *cred_handle)
+{
+ OM_uint32 status, tmpmin, count;
+ gss_union_cred_t cred = NULL;
+ gss_mechanism mech;
+ gss_buffer_desc tok, mech_token;
+ gss_OID_desc mech_oid;
+ gss_OID selected_mech;
+ gss_cred_id_t mech_cred;
+ void *elemcopy;
+
+ status = val_imp_cred_args(minor_status, token, cred_handle);
+ if (status != GSS_S_COMPLETE)
+ return status;
+
+ /* Count the entries in token. */
+ for (tok = *token, count = 0; tok.length > 0; count++) {
+ status = get_entry(minor_status, &tok, &mech_oid, &mech_token);
+ if (status != GSS_S_COMPLETE)
+ return status;
+ }
+
+ /* Allocate a union credential. */
+ cred = calloc(1, sizeof(*cred));
+ if (cred == NULL)
+ goto oom;
+ cred->loopback = cred;
+ cred->count = 0;
+ cred->mechs_array = calloc(count, sizeof(*cred->mechs_array));
+ if (cred->mechs_array == NULL)
+ goto oom;
+ cred->cred_array = calloc(count, sizeof(*cred->cred_array));
+ if (cred->cred_array == NULL)
+ goto oom;
+
+ tok = *token;
+ while (tok.length > 0) {
+ (void)get_entry(minor_status, &tok, &mech_oid, &mech_token);
+
+ /* Import this entry's mechanism token. */
+ status = gssint_select_mech_type(minor_status, &mech_oid,
+ &selected_mech);
+ if (status != GSS_S_COMPLETE)
+ goto error;
+ mech = gssint_get_mechanism(selected_mech);
+ if (mech == NULL || (mech->gss_import_cred == NULL &&
+ mech->gssspi_import_cred_by_mech == NULL)) {
+ status = GSS_S_DEFECTIVE_TOKEN;
+ goto error;
+ }
+ if (mech->gssspi_import_cred_by_mech) {
+ status = mech->gssspi_import_cred_by_mech(minor_status,
+ gssint_get_public_oid(selected_mech),
+ &mech_token, &mech_cred);
+ } else {
+ status = mech->gss_import_cred(minor_status, &mech_token,
+ &mech_cred);
+ }
+ if (status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ goto error;
+ }
+
+ /* Add the resulting mechanism cred to the union cred. */
+ elemcopy = malloc(selected_mech->length);
+ if (elemcopy == NULL) {
+ if (mech->gss_release_cred != NULL)
+ mech->gss_release_cred(&tmpmin, &mech_cred);
+ goto oom;
+ }
+ memcpy(elemcopy, selected_mech->elements, selected_mech->length);
+ cred->mechs_array[cred->count].length = selected_mech->length;
+ cred->mechs_array[cred->count].elements = elemcopy;
+ cred->cred_array[cred->count++] = mech_cred;
+ }
+
+ *cred_handle = cred;
+ return GSS_S_COMPLETE;
+
+oom:
+ status = GSS_S_FAILURE;
+ *minor_status = ENOMEM;
+error:
+ (void)gss_release_cred(&tmpmin, &cred);
+ return status;
+}
diff --git a/src/lib/gssapi/mechglue/g_imp_name.c b/src/lib/gssapi/mechglue/g_imp_name.c
new file mode 100644
index 000000000000..374965bc9288
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_imp_name.c
@@ -0,0 +1,387 @@
+/* #pragma ident "@(#)g_imp_name.c 1.26 04/02/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine gss_import_name
+ *
+ */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+/* local function to import GSS_C_EXPORT_NAME names */
+static OM_uint32 importExportName(OM_uint32 *, gss_union_name_t, gss_OID);
+
+static OM_uint32
+val_imp_name_args(
+ OM_uint32 *minor_status,
+ gss_buffer_t input_name_buffer,
+ gss_OID input_name_type,
+ gss_name_t *output_name)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (output_name != NULL)
+ *output_name = GSS_C_NO_NAME;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (output_name == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (input_name_buffer == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
+
+ if (input_name_type == GSS_C_NO_OID ||
+ !g_OID_equal(input_name_type, GSS_C_NT_ANONYMOUS)) {
+ if (input_name_buffer->length == 0)
+ return (GSS_S_BAD_NAME);
+
+ if (input_name_buffer->value == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
+ }
+
+ return (GSS_S_COMPLETE);
+}
+
+static gss_buffer_desc emptyNameBuffer;
+
+OM_uint32 KRB5_CALLCONV
+gss_import_name(minor_status,
+ input_name_buffer,
+ input_name_type,
+ output_name)
+
+OM_uint32 * minor_status;
+gss_buffer_t input_name_buffer;
+gss_OID input_name_type;
+gss_name_t * output_name;
+
+{
+ gss_union_name_t union_name;
+ OM_uint32 tmp, major_status = GSS_S_FAILURE;
+
+ if (input_name_buffer == GSS_C_NO_BUFFER)
+ input_name_buffer = &emptyNameBuffer;
+
+ major_status = val_imp_name_args(minor_status,
+ input_name_buffer, input_name_type,
+ output_name);
+ if (major_status != GSS_S_COMPLETE)
+ return (major_status);
+
+ /*
+ * First create the union name struct that will hold the external
+ * name and the name type.
+ */
+ union_name = (gss_union_name_t) malloc (sizeof(gss_union_name_desc));
+ if (!union_name)
+ return (GSS_S_FAILURE);
+
+ union_name->loopback = 0;
+ union_name->mech_type = 0;
+ union_name->mech_name = 0;
+ union_name->name_type = 0;
+ union_name->external_name = 0;
+
+ /*
+ * 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. The exception to this
+ * rule is when the name of GSS_C_NT_EXPORT_NAME type. If that is
+ * the case, then we make it MN in this call.
+ */
+ major_status = gssint_create_copy_buffer(input_name_buffer,
+ &union_name->external_name, 0);
+ if (major_status != GSS_S_COMPLETE) {
+ free(union_name);
+ return (major_status);
+ }
+
+ if (input_name_type != GSS_C_NULL_OID) {
+ major_status = generic_gss_copy_oid(minor_status,
+ input_name_type,
+ &union_name->name_type);
+ if (major_status != GSS_S_COMPLETE) {
+ map_errcode(minor_status);
+ goto allocation_failure;
+ }
+ }
+
+ /*
+ * In MIT Distribution the mechanism is determined from the nametype;
+ * This is not a good idea - first mechanism that supports a given
+ * name type is picked up; later on the caller can request a
+ * different mechanism. So we don't determine the mechanism here. Now
+ * the user level and kernel level import_name routine looks similar
+ * except the kernel routine makes a copy of the nametype structure. We
+ * do however make this an MN for names of GSS_C_NT_EXPORT_NAME type.
+ */
+ if (input_name_type != GSS_C_NULL_OID &&
+ (g_OID_equal(input_name_type, GSS_C_NT_EXPORT_NAME) ||
+ g_OID_equal(input_name_type, GSS_C_NT_COMPOSITE_EXPORT))) {
+ major_status = importExportName(minor_status, union_name, input_name_type);
+ if (major_status != GSS_S_COMPLETE)
+ goto allocation_failure;
+ }
+
+ union_name->loopback = union_name;
+ *output_name = (gss_name_t)union_name;
+ return (GSS_S_COMPLETE);
+
+allocation_failure:
+ if (union_name) {
+ if (union_name->external_name) {
+ if (union_name->external_name->value)
+ free(union_name->external_name->value);
+ free(union_name->external_name);
+ }
+ if (union_name->name_type)
+ generic_gss_release_oid(&tmp, &union_name->name_type);
+ if (union_name->mech_name)
+ gssint_release_internal_name(minor_status, union_name->mech_type,
+ &union_name->mech_name);
+ if (union_name->mech_type)
+ generic_gss_release_oid(&tmp, &union_name->mech_type);
+ free(union_name);
+ }
+ return (major_status);
+}
+
+/*
+ * GSS export name constants
+ */
+static const unsigned int expNameTokIdLen = 2;
+static const unsigned int mechOidLenLen = 2;
+static const unsigned int nameTypeLenLen = 2;
+
+static OM_uint32
+importExportName(minor, unionName, inputNameType)
+ OM_uint32 *minor;
+ gss_union_name_t unionName;
+ gss_OID inputNameType;
+{
+ gss_OID_desc mechOid;
+ gss_buffer_desc expName;
+ unsigned char *buf;
+ gss_mechanism mech;
+ OM_uint32 major, mechOidLen, nameLen, curLength;
+ unsigned int bytes;
+
+ expName.value = unionName->external_name->value;
+ expName.length = unionName->external_name->length;
+
+ curLength = expNameTokIdLen + mechOidLenLen;
+ if (expName.length < curLength)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ buf = (unsigned char *)expName.value;
+ if (buf[0] != 0x04)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ if (buf[1] != 0x01 && buf[1] != 0x02) /* allow composite names */
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ buf += expNameTokIdLen;
+
+ /* extract the mechanism oid length */
+ mechOidLen = (*buf++ << 8);
+ mechOidLen |= (*buf++);
+ curLength += mechOidLen;
+ if (expName.length < curLength)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ /*
+ * The mechOid itself is encoded in DER format, OID Tag (0x06)
+ * length and the value of mech_OID
+ */
+ if (*buf++ != 0x06)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ /*
+ * mechoid Length is encoded twice; once in 2 bytes as
+ * explained in RFC2743 (under mechanism independent exported
+ * name object format) and once using DER encoding
+ *
+ * We verify both lengths.
+ */
+
+ mechOid.length = gssint_get_der_length(&buf,
+ (expName.length - curLength), &bytes);
+ mechOid.elements = (void *)buf;
+
+ /*
+ * 'bytes' is the length of the DER length, '1' is for the DER
+ * tag for OID
+ */
+ if ((bytes + mechOid.length + 1) != mechOidLen)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ buf += mechOid.length;
+ if ((mech = gssint_get_mechanism(&mechOid)) == NULL)
+ return (GSS_S_BAD_MECH);
+
+ if (mech->gssspi_import_name_by_mech == NULL &&
+ mech->gss_import_name == NULL)
+ return (GSS_S_UNAVAILABLE);
+
+ /*
+ * we must now determine if we should unwrap the name ourselves
+ * or make the mechanism do it - we should only unwrap it
+ * if we create it; so if mech->gss_export_name == NULL, we must
+ * have created it.
+ */
+ if (mech->gss_export_name) {
+ if (mech->gssspi_import_name_by_mech) {
+ major = mech->gssspi_import_name_by_mech(minor, &mechOid, &expName,
+ inputNameType,
+ &unionName->mech_name);
+ } else {
+ major = mech->gss_import_name(minor, &expName, inputNameType,
+ &unionName->mech_name);
+ }
+ if (major != GSS_S_COMPLETE)
+ map_error(minor, mech);
+ else {
+ major = generic_gss_copy_oid(minor, &mechOid,
+ &unionName->mech_type);
+ if (major != GSS_S_COMPLETE)
+ map_errcode(minor);
+ }
+ return (major);
+ }
+ /*
+ * we must have exported the name - so we now need to reconstruct it
+ * and call the mechanism to create it
+ *
+ * WARNING: Older versions of gssint_export_internal_name() did
+ * not export names correctly, but now it does. In
+ * order to stay compatible with existing exported
+ * names we must support names exported the broken
+ * way.
+ *
+ * Specifically, gssint_export_internal_name() used to include
+ * the name type OID in the encoding of the exported MN.
+ * Additionally, the Kerberos V mech used to make display names
+ * that included a null terminator which was counted in the
+ * display name gss_buffer_desc.
+ */
+ curLength += 4; /* 4 bytes for name len */
+ if (expName.length < curLength)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ /* next 4 bytes in the name are the name length */
+ nameLen = load_32_be(buf);
+ buf += 4;
+
+ /*
+ * we use < here because bad code in rpcsec_gss rounds up exported
+ * name token lengths and pads with nulls, otherwise != would be
+ * appropriate
+ */
+ curLength += nameLen; /* this is the total length */
+ if (expName.length < curLength)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ /*
+ * We detect broken exported names here: they always start with
+ * a two-octet network-byte order OID length, which is always
+ * less than 256 bytes, so the first octet of the length is
+ * always '\0', which is not allowed in GSS-API display names
+ * (or never occurs in them anyways). Of course, the OID
+ * shouldn't be there, but it is. After the OID (sans DER tag
+ * and length) there's the name itself, though null-terminated;
+ * this null terminator should also not be there, but it is.
+ */
+ if (nameLen > 0 && *buf == '\0') {
+ OM_uint32 nameTypeLen;
+ /* next two bytes are the name oid */
+ if (nameLen < nameTypeLenLen)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ nameLen -= nameTypeLenLen;
+
+ nameTypeLen = (*buf++) << 8;
+ nameTypeLen |= (*buf++);
+
+ if (nameLen < nameTypeLen)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ buf += nameTypeLen;
+ nameLen -= nameTypeLen;
+
+ /*
+ * adjust for expected null terminator that should
+ * really not be there
+ */
+ if (nameLen > 0 && *(buf + nameLen - 1) == '\0')
+ nameLen--;
+ }
+
+ /*
+ * Can a name be null? Let the mech decide.
+ *
+ * NOTE: We use GSS_C_NULL_OID as the name type when importing
+ * the unwrapped name. Presumably the exported name had,
+ * prior to being exported been obtained in such a way
+ * that it has been properly perpared ("canonicalized," in
+ * GSS-API terms) accroding to some name type; we cannot
+ * tell what that name type was now, but the name should
+ * need no further preparation other than the lowest
+ * common denominator afforded by the mech to names
+ * imported with GSS_C_NULL_OID. For the Kerberos V mech
+ * this means doing less busywork too (particularly once
+ * IDN is thrown in with Kerberos V extensions).
+ */
+ expName.length = nameLen;
+ expName.value = nameLen ? (void *)buf : NULL;
+ if (mech->gssspi_import_name_by_mech) {
+ major = mech->gssspi_import_name_by_mech(minor, &mechOid, &expName,
+ GSS_C_NULL_OID,
+ &unionName->mech_name);
+ } else {
+ major = mech->gss_import_name(minor, &expName,
+ GSS_C_NULL_OID, &unionName->mech_name);
+ }
+ if (major != GSS_S_COMPLETE) {
+ map_error(minor, mech);
+ return (major);
+ }
+
+ major = generic_gss_copy_oid(minor, &mechOid, &unionName->mech_type);
+ if (major != GSS_S_COMPLETE) {
+ map_errcode(minor);
+ }
+ return major;
+} /* importExportName */
diff --git a/src/lib/gssapi/mechglue/g_imp_sec_context.c b/src/lib/gssapi/mechglue/g_imp_sec_context.c
new file mode 100644
index 000000000000..a0e2d71221b6
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_imp_sec_context.c
@@ -0,0 +1,175 @@
+/* #pragma ident "@(#)g_imp_sec_context.c 1.18 04/02/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine gss_export_sec_context
+ */
+
+#ifndef LEAN_CLIENT
+
+#include "mglueP.h"
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+
+static OM_uint32
+val_imp_sec_ctx_args(
+ OM_uint32 *minor_status,
+ gss_buffer_t interprocess_token,
+ gss_ctx_id_t *context_handle)
+{
+
+ /* Initialize outputs. */
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (context_handle != NULL)
+ *context_handle = GSS_C_NO_CONTEXT;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (context_handle == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (interprocess_token == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_DEFECTIVE_TOKEN);
+
+ if (GSS_EMPTY_BUFFER(interprocess_token))
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_DEFECTIVE_TOKEN);
+
+ return (GSS_S_COMPLETE);
+}
+
+
+OM_uint32 KRB5_CALLCONV
+gss_import_sec_context(minor_status,
+ interprocess_token,
+ context_handle)
+
+OM_uint32 * minor_status;
+gss_buffer_t interprocess_token;
+gss_ctx_id_t * context_handle;
+
+{
+ OM_uint32 length = 0;
+ OM_uint32 status;
+ char *p;
+ gss_union_ctx_id_t ctx;
+ gss_ctx_id_t mctx;
+ gss_buffer_desc token;
+ gss_OID_desc token_mech;
+ gss_OID selected_mech = GSS_C_NO_OID;
+ gss_OID public_mech;
+ gss_mechanism mech;
+
+ status = val_imp_sec_ctx_args(minor_status,
+ interprocess_token, context_handle);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ /* Initial value needed below. */
+ status = GSS_S_FAILURE;
+
+ ctx = (gss_union_ctx_id_t) malloc(sizeof(gss_union_ctx_id_desc));
+ if (!ctx)
+ return (GSS_S_FAILURE);
+
+ if (interprocess_token->length >= sizeof (OM_uint32)) {
+ p = interprocess_token->value;
+ length = (OM_uint32)*p++;
+ length = (OM_uint32)(length << 8) + *p++;
+ length = (OM_uint32)(length << 8) + *p++;
+ length = (OM_uint32)(length << 8) + *p++;
+ }
+
+ if (length == 0 ||
+ length > (interprocess_token->length - sizeof (OM_uint32))) {
+ free(ctx);
+ return (GSS_S_CALL_BAD_STRUCTURE | GSS_S_DEFECTIVE_TOKEN);
+ }
+
+ token_mech.length = length;
+ token_mech.elements = p;
+
+ p += length;
+
+ token.length = interprocess_token->length - sizeof (OM_uint32) - length;
+ token.value = p;
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ status = gssint_select_mech_type(minor_status, &token_mech,
+ &selected_mech);
+ if (status != GSS_S_COMPLETE)
+ goto error_out;
+
+ mech = gssint_get_mechanism(selected_mech);
+ if (!mech) {
+ status = GSS_S_BAD_MECH;
+ goto error_out;
+ }
+ if (!mech->gssspi_import_sec_context_by_mech &&
+ !mech->gss_import_sec_context) {
+ status = GSS_S_UNAVAILABLE;
+ goto error_out;
+ }
+
+ if (generic_gss_copy_oid(minor_status, selected_mech,
+ &ctx->mech_type) != GSS_S_COMPLETE) {
+ status = GSS_S_FAILURE;
+ goto error_out;
+ }
+
+ if (mech->gssspi_import_sec_context_by_mech) {
+ public_mech = gssint_get_public_oid(selected_mech);
+ status = mech->gssspi_import_sec_context_by_mech(minor_status,
+ public_mech,
+ &token, &mctx);
+ } else {
+ status = mech->gss_import_sec_context(minor_status, &token, &mctx);
+ }
+ if (status == GSS_S_COMPLETE) {
+ ctx->internal_ctx_id = mctx;
+ ctx->loopback = ctx;
+ *context_handle = (gss_ctx_id_t)ctx;
+ return (GSS_S_COMPLETE);
+ }
+ map_error(minor_status, mech);
+ free(ctx->mech_type->elements);
+ free(ctx->mech_type);
+
+error_out:
+ free(ctx);
+ return status;
+}
+#endif /* LEAN_CLIENT */
diff --git a/src/lib/gssapi/mechglue/g_init_sec_context.c b/src/lib/gssapi/mechglue/g_init_sec_context.c
new file mode 100644
index 000000000000..9f154b8936d0
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_init_sec_context.c
@@ -0,0 +1,254 @@
+/* #pragma ident "@(#)g_init_sec_context.c 1.20 03/10/24 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_init_sec_context
+ */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+
+static OM_uint32
+val_init_sec_ctx_args(
+ OM_uint32 *minor_status,
+ gss_cred_id_t claimant_cred_handle,
+ gss_ctx_id_t *context_handle,
+ gss_name_t target_name,
+ gss_OID req_mech_type,
+ OM_uint32 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,
+ OM_uint32 *ret_flags,
+ OM_uint32 *time_rec)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (actual_mech_type != NULL)
+ *actual_mech_type = GSS_C_NO_OID;
+
+ if (output_token != GSS_C_NO_BUFFER) {
+ output_token->length = 0;
+ output_token->value = NULL;
+ }
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (context_handle == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE | GSS_S_NO_CONTEXT);
+
+ if (target_name == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
+
+ if (output_token == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ return (GSS_S_COMPLETE);
+}
+
+
+OM_uint32 KRB5_CALLCONV
+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;
+gss_OID req_mech_type;
+OM_uint32 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;
+OM_uint32 * ret_flags;
+OM_uint32 * time_rec;
+
+{
+ OM_uint32 status, temp_minor_status;
+ gss_union_name_t union_name;
+ gss_union_cred_t union_cred;
+ gss_name_t internal_name;
+ gss_union_ctx_id_t union_ctx_id;
+ gss_OID selected_mech;
+ gss_mechanism mech;
+ gss_cred_id_t input_cred_handle;
+
+ status = val_init_sec_ctx_args(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);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ status = gssint_select_mech_type(minor_status, req_mech_type,
+ &selected_mech);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ union_name = (gss_union_name_t)target_name;
+
+ /*
+ * obtain the gss mechanism information for the requested
+ * mechanism. If mech_type is NULL, set it to the resultant
+ * mechanism
+ */
+ mech = gssint_get_mechanism(selected_mech);
+ if (mech == NULL)
+ return (GSS_S_BAD_MECH);
+
+ if (mech->gss_init_sec_context == NULL)
+ return (GSS_S_UNAVAILABLE);
+
+ /*
+ * If target_name is mechanism_specific, then it must match the
+ * mech_type that we're about to use. Otherwise, do an import on
+ * the external_name form of the target name.
+ */
+ if (union_name->mech_type &&
+ g_OID_equal(union_name->mech_type, selected_mech)) {
+ internal_name = union_name->mech_name;
+ } else {
+ if ((status = gssint_import_internal_name(minor_status, selected_mech,
+ union_name,
+ &internal_name)) != GSS_S_COMPLETE)
+ return (status);
+ }
+
+ /*
+ * 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) {
+ status = GSS_S_FAILURE;
+ union_ctx_id = (gss_union_ctx_id_t)
+ malloc(sizeof(gss_union_ctx_id_desc));
+ if (union_ctx_id == NULL)
+ goto end;
+
+ if (generic_gss_copy_oid(&temp_minor_status, selected_mech,
+ &union_ctx_id->mech_type) != GSS_S_COMPLETE) {
+ free(union_ctx_id);
+ goto end;
+ }
+
+ /* copy the supplied context handle */
+ union_ctx_id->internal_ctx_id = GSS_C_NO_CONTEXT;
+ } else
+ union_ctx_id = (gss_union_ctx_id_t)*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) claimant_cred_handle;
+ input_cred_handle = gssint_get_mechanism_cred(union_cred, selected_mech);
+
+ /*
+ * now call the approprate underlying mechanism routine
+ */
+
+ status = mech->gss_init_sec_context(
+ minor_status,
+ input_cred_handle,
+ &union_ctx_id->internal_ctx_id,
+ internal_name,
+ gssint_get_public_oid(selected_mech),
+ req_flags,
+ time_req,
+ input_chan_bindings,
+ input_token,
+ actual_mech_type,
+ output_token,
+ ret_flags,
+ time_rec);
+
+ if (status != GSS_S_COMPLETE && status != GSS_S_CONTINUE_NEEDED) {
+ /*
+ * The spec says the preferred method is to delete all context info on
+ * the first call to init, and on all subsequent calls make the caller
+ * responsible for calling gss_delete_sec_context. However, if the
+ * mechanism decided to delete the internal context, we should also
+ * delete the union context.
+ */
+ map_error(minor_status, mech);
+ if (union_ctx_id->internal_ctx_id == GSS_C_NO_CONTEXT)
+ *context_handle = GSS_C_NO_CONTEXT;
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ free(union_ctx_id->mech_type->elements);
+ free(union_ctx_id->mech_type);
+ free(union_ctx_id);
+ }
+ } else if (*context_handle == GSS_C_NO_CONTEXT) {
+ union_ctx_id->loopback = union_ctx_id;
+ *context_handle = (gss_ctx_id_t)union_ctx_id;
+ }
+
+end:
+ if (union_name->mech_name == NULL ||
+ union_name->mech_name != internal_name) {
+ (void) gssint_release_internal_name(&temp_minor_status,
+ selected_mech, &internal_name);
+ }
+
+ return(status);
+}
diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c
new file mode 100644
index 000000000000..9197666e1072
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_initialize.c
@@ -0,0 +1,1615 @@
+/* #pragma ident "@(#)g_initialize.c 1.36 05/02/02 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This function will initialize the gssapi mechglue library
+ */
+
+#include "mglueP.h"
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#ifndef _WIN32
+#include <glob.h>
+#endif
+
+#define M_DEFAULT "default"
+
+#include "k5-thread.h"
+#include "k5-plugin.h"
+#include "osconf.h"
+#ifdef _GSS_STATIC_LINK
+#include "gssapiP_krb5.h"
+#include "gssapiP_spnego.h"
+#endif
+
+#define MECH_SYM "gss_mech_initialize"
+#define MECH_INTERPOSER_SYM "gss_mech_interposer"
+
+#ifndef MECH_CONF
+#define MECH_CONF "/etc/gss/mech"
+#endif
+#define MECH_CONF_PATTERN MECH_CONF ".d/*.conf"
+
+/* Local functions */
+static void addConfigEntry(const char *oidStr, const char *oid,
+ const char *sharedLib, const char *kernMod,
+ const char *modOptions, const char *modType);
+static gss_mech_info searchMechList(gss_const_OID);
+static void loadConfigFile(const char *);
+#if defined(_WIN32)
+#ifndef MECH_KEY
+#define MECH_KEY "SOFTWARE\\gss\\mech"
+#endif
+static time_t getRegKeyModTime(HKEY hBaseKey, const char *keyPath);
+static time_t getRegConfigModTime(const char *keyPath);
+static void getRegKeyValue(HKEY key, const char *keyPath, const char *valueName, void **data, DWORD *dataLen);
+static void loadConfigFromRegistry(HKEY keyBase, const char *keyPath);
+#endif
+static void updateMechList(void);
+static void initMechList(void);
+static void loadInterMech(gss_mech_info aMech);
+static void freeMechList(void);
+
+static OM_uint32 build_mechSet(void);
+static void free_mechSet(void);
+
+/*
+ * list of mechanism libraries and their entry points.
+ * the list also maintains state of the mech libraries (loaded or not).
+ */
+static gss_mech_info g_mechList = NULL;
+static gss_mech_info g_mechListTail = NULL;
+static k5_mutex_t g_mechListLock = K5_MUTEX_PARTIAL_INITIALIZER;
+static time_t g_confFileModTime = (time_t)0;
+static time_t g_confLastCall = (time_t)0;
+
+static gss_OID_set_desc g_mechSet = { 0, NULL };
+static k5_mutex_t g_mechSetLock = K5_MUTEX_PARTIAL_INITIALIZER;
+
+MAKE_INIT_FUNCTION(gssint_mechglue_init);
+MAKE_FINI_FUNCTION(gssint_mechglue_fini);
+
+int
+gssint_mechglue_init(void)
+{
+ int err;
+
+#ifdef SHOW_INITFINI_FUNCS
+ printf("gssint_mechglue_init\n");
+#endif
+
+ add_error_table(&et_ggss_error_table);
+
+ err = k5_mutex_finish_init(&g_mechSetLock);
+ err = k5_mutex_finish_init(&g_mechListLock);
+
+#ifdef _GSS_STATIC_LINK
+ err = gss_krb5int_lib_init();
+ err = gss_spnegoint_lib_init();
+#endif
+
+ err = gssint_mecherrmap_init();
+ return err;
+}
+
+void
+gssint_mechglue_fini(void)
+{
+ if (!INITIALIZER_RAN(gssint_mechglue_init) || PROGRAM_EXITING()) {
+#ifdef SHOW_INITFINI_FUNCS
+ printf("gssint_mechglue_fini: skipping\n");
+#endif
+ return;
+ }
+
+#ifdef SHOW_INITFINI_FUNCS
+ printf("gssint_mechglue_fini\n");
+#endif
+#ifdef _GSS_STATIC_LINK
+ gss_spnegoint_lib_fini();
+ gss_krb5int_lib_fini();
+#endif
+ k5_mutex_destroy(&g_mechSetLock);
+ k5_mutex_destroy(&g_mechListLock);
+ free_mechSet();
+ freeMechList();
+ remove_error_table(&et_ggss_error_table);
+ gssint_mecherrmap_destroy();
+}
+
+int
+gssint_mechglue_initialize_library(void)
+{
+ return CALL_INIT_FUNCTION(gssint_mechglue_init);
+}
+
+/*
+ * function used to reclaim the memory used by a gss_OID structure.
+ * This routine requires direct access to the mechList.
+ */
+OM_uint32 KRB5_CALLCONV
+gss_release_oid(minor_status, oid)
+OM_uint32 *minor_status;
+gss_OID *oid;
+{
+ OM_uint32 major;
+ gss_mech_info aMech;
+
+ if (minor_status == NULL || oid == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ *minor_status = gssint_mechglue_initialize_library();
+ if (*minor_status != 0)
+ return (GSS_S_FAILURE);
+
+ k5_mutex_lock(&g_mechListLock);
+ aMech = g_mechList;
+ while (aMech != NULL) {
+
+ /*
+ * look through the loaded mechanism libraries for
+ * gss_internal_release_oid until one returns success.
+ * gss_internal_release_oid will only return success when
+ * the OID was recognized as an internal mechanism OID. if no
+ * mechanisms recognize the OID, then call the generic version.
+ */
+ if (aMech->mech && aMech->mech->gss_internal_release_oid) {
+ major = aMech->mech->gss_internal_release_oid(
+ minor_status, oid);
+ if (major == GSS_S_COMPLETE) {
+ k5_mutex_unlock(&g_mechListLock);
+ return (GSS_S_COMPLETE);
+ }
+ map_error(minor_status, aMech->mech);
+ }
+ aMech = aMech->next;
+ } /* while */
+ k5_mutex_unlock(&g_mechListLock);
+
+ return (generic_gss_release_oid(minor_status, oid));
+} /* gss_release_oid */
+
+/*
+ * Wrapper around inquire_attrs_for_mech to determine whether a mechanism has
+ * the deprecated attribute. Must be called without g_mechSetLock since it
+ * will call into the mechglue.
+ */
+static int
+is_deprecated(gss_OID element)
+{
+ OM_uint32 major, minor;
+ gss_OID_set mech_attrs = GSS_C_NO_OID_SET;
+ int deprecated = 0;
+
+ major = gss_inquire_attrs_for_mech(&minor, element, &mech_attrs, NULL);
+ if (major == GSS_S_COMPLETE) {
+ gss_test_oid_set_member(&minor, (gss_OID)GSS_C_MA_DEPRECATED,
+ mech_attrs, &deprecated);
+ }
+
+ if (mech_attrs != GSS_C_NO_OID_SET)
+ gss_release_oid_set(&minor, &mech_attrs);
+
+ return deprecated;
+}
+
+/*
+ * Removes mechs with the deprecated attribute from an OID set. Must be
+ * called without g_mechSetLock held since it calls into the mechglue.
+ */
+static void
+prune_deprecated(gss_OID_set mech_set)
+{
+ OM_uint32 i, j;
+
+ j = 0;
+ for (i = 0; i < mech_set->count; i++) {
+ if (!is_deprecated(&mech_set->elements[i]))
+ mech_set->elements[j++] = mech_set->elements[i];
+ else
+ gssalloc_free(mech_set->elements[i].elements);
+ }
+ mech_set->count = j;
+}
+
+/*
+ * this function will return an oid set indicating available mechanisms.
+ * The set returned is based on configuration file entries and
+ * NOT on the loaded mechanisms. This function does not check if any
+ * of these can actually be loaded.
+ * Deprecated mechanisms will not be returned.
+ * This routine needs direct access to the mechanism list.
+ * To avoid reading the configuration file each call, we will save a
+ * a mech oid set, and only update it once the file has changed.
+ */
+OM_uint32 KRB5_CALLCONV
+gss_indicate_mechs(minorStatus, mechSet_out)
+OM_uint32 *minorStatus;
+gss_OID_set *mechSet_out;
+{
+ OM_uint32 status;
+
+ /* Initialize outputs. */
+
+ if (minorStatus != NULL)
+ *minorStatus = 0;
+
+ if (mechSet_out != NULL)
+ *mechSet_out = GSS_C_NO_OID_SET;
+
+ /* Validate arguments. */
+ if (minorStatus == NULL || mechSet_out == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ *minorStatus = gssint_mechglue_initialize_library();
+ if (*minorStatus != 0)
+ return (GSS_S_FAILURE);
+
+ if (build_mechSet())
+ return GSS_S_FAILURE;
+
+ /*
+ * need to lock the g_mechSet in case someone tries to update it while
+ * I'm copying it.
+ */
+ k5_mutex_lock(&g_mechSetLock);
+ status = generic_gss_copy_oid_set(minorStatus, &g_mechSet, mechSet_out);
+ k5_mutex_unlock(&g_mechSetLock);
+
+ if (*mechSet_out != GSS_C_NO_OID_SET)
+ prune_deprecated(*mechSet_out);
+
+ return (status);
+} /* gss_indicate_mechs */
+
+
+/* Call with g_mechSetLock held, or during final cleanup. */
+static void
+free_mechSet(void)
+{
+ unsigned int i;
+
+ if (g_mechSet.count != 0) {
+ for (i = 0; i < g_mechSet.count; i++)
+ free(g_mechSet.elements[i].elements);
+ free(g_mechSet.elements);
+ g_mechSet.elements = NULL;
+ g_mechSet.count = 0;
+ }
+}
+
+static OM_uint32
+build_mechSet(void)
+{
+ gss_mech_info mList;
+ size_t i;
+ size_t count;
+ gss_OID curItem;
+
+ /*
+ * lock the mutex since we will be updating
+ * the mechList structure
+ * we need to keep the lock while we build the mechanism list
+ * since we are accessing parts of the mechList which could be
+ * modified.
+ */
+ k5_mutex_lock(&g_mechListLock);
+
+ updateMechList();
+
+ /*
+ * we need to lock the mech set so that no one else will
+ * try to read it as we are re-creating it
+ */
+ k5_mutex_lock(&g_mechSetLock);
+
+ /* if the oid list already exists we must free it first */
+ free_mechSet();
+
+ /* determine how many elements to have in the list */
+ mList = g_mechList;
+ count = 0;
+ while (mList != NULL) {
+ count++;
+ mList = mList->next;
+ }
+
+ /* this should always be true, but.... */
+ if (count > 0) {
+ g_mechSet.elements =
+ (gss_OID) calloc(count, sizeof (gss_OID_desc));
+ if (g_mechSet.elements == NULL) {
+ k5_mutex_unlock(&g_mechSetLock);
+ k5_mutex_unlock(&g_mechListLock);
+ return (GSS_S_FAILURE);
+ }
+
+ (void) memset(g_mechSet.elements, 0,
+ count * sizeof (gss_OID_desc));
+
+ /* now copy each oid element */
+ count = 0;
+ for (mList = g_mechList; mList != NULL; mList = mList->next) {
+ /* Don't expose interposer mechanisms. */
+ if (mList->is_interposer)
+ continue;
+ curItem = &(g_mechSet.elements[count]);
+ curItem->elements = (void*)
+ malloc(mList->mech_type->length);
+ if (curItem->elements == NULL) {
+ /*
+ * this is nasty - we must delete the
+ * part of the array already copied
+ */
+ for (i = 0; i < count; i++) {
+ free(g_mechSet.elements[i].
+ elements);
+ }
+ free(g_mechSet.elements);
+ g_mechSet.count = 0;
+ g_mechSet.elements = NULL;
+ k5_mutex_unlock(&g_mechSetLock);
+ k5_mutex_unlock(&g_mechListLock);
+ return (GSS_S_FAILURE);
+ }
+ g_OID_copy(curItem, mList->mech_type);
+ count++;
+ }
+ g_mechSet.count = count;
+ }
+
+#if 0
+ g_mechSetTime = fileInfo.st_mtime;
+#endif
+ k5_mutex_unlock(&g_mechSetLock);
+ k5_mutex_unlock(&g_mechListLock);
+
+ return GSS_S_COMPLETE;
+}
+
+
+/*
+ * this function has been added for use by modules that need to
+ * know what (if any) optional parameters are supplied in the
+ * config file (MECH_CONF).
+ * It will return the option string for a specified mechanism.
+ * caller is responsible for freeing the memory
+ */
+char *
+gssint_get_modOptions(oid)
+const gss_OID oid;
+{
+ gss_mech_info aMech;
+ char *modOptions = NULL;
+
+ if (gssint_mechglue_initialize_library() != 0)
+ return (NULL);
+
+ /* make sure we have fresh data */
+ k5_mutex_lock(&g_mechListLock);
+ updateMechList();
+
+ if ((aMech = searchMechList(oid)) == NULL ||
+ aMech->optionStr == NULL) {
+ k5_mutex_unlock(&g_mechListLock);
+ return (NULL);
+ }
+
+ if (aMech->optionStr)
+ modOptions = strdup(aMech->optionStr);
+ k5_mutex_unlock(&g_mechListLock);
+
+ return (modOptions);
+} /* gssint_get_modOptions */
+
+/* Return the mtime of filename or its eventual symlink target (if it is a
+ * symlink), whichever is larger. Return (time_t)-1 if lstat or stat fails. */
+static time_t
+check_link_mtime(const char *filename, time_t *mtime_out)
+{
+ struct stat st1, st2;
+
+ if (lstat(filename, &st1) != 0)
+ return (time_t)-1;
+ if (!S_ISLNK(st1.st_mode))
+ return st1.st_mtime;
+ if (stat(filename, &st2) != 0)
+ return (time_t)-1;
+ return (st1.st_mtime > st2.st_mtime) ? st1.st_mtime : st2.st_mtime;
+}
+
+/* Load pathname if it is newer than last. Update *highest to the maximum of
+ * its current value and pathname's mod time. */
+static void
+load_if_changed(const char *pathname, time_t last, time_t *highest)
+{
+ time_t mtime;
+
+ mtime = check_link_mtime(pathname, &mtime);
+ if (mtime == (time_t)-1)
+ return;
+ if (mtime > *highest)
+ *highest = mtime;
+ if (mtime > last)
+ loadConfigFile(pathname);
+}
+
+#ifndef _WIN32
+/* Try to load any config files which have changed since the last call. Config
+ * files are MECH_CONF and any files matching MECH_CONF_PATTERN. */
+static void
+loadConfigFiles()
+{
+ glob_t globbuf;
+ time_t highest = 0, now;
+ char **path;
+
+ /* Don't glob and stat more than once per second. */
+ if (time(&now) == (time_t)-1 || now == g_confLastCall)
+ return;
+ g_confLastCall = now;
+
+ load_if_changed(MECH_CONF, g_confFileModTime, &highest);
+
+ memset(&globbuf, 0, sizeof(globbuf));
+ if (glob(MECH_CONF_PATTERN, 0, NULL, &globbuf) == 0) {
+ for (path = globbuf.gl_pathv; *path != NULL; path++)
+ load_if_changed(*path, g_confFileModTime, &highest);
+ }
+ globfree(&globbuf);
+
+ g_confFileModTime = highest;
+}
+#endif
+
+/*
+ * determines if the mechList needs to be updated from file
+ * and performs the update.
+ * this functions must be called with a lock of g_mechListLock
+ */
+static void
+updateMechList(void)
+{
+ gss_mech_info minfo;
+
+#if defined(_WIN32)
+ time_t lastConfModTime = getRegConfigModTime(MECH_KEY);
+ if (g_confFileModTime >= lastConfModTime)
+ return;
+ g_confFileModTime = lastConfModTime;
+ loadConfigFromRegistry(HKEY_CURRENT_USER, MECH_KEY);
+ loadConfigFromRegistry(HKEY_LOCAL_MACHINE, MECH_KEY);
+#else /* _WIN32 */
+ loadConfigFiles();
+#endif /* !_WIN32 */
+
+ /* Load any unloaded interposer mechanisms immediately, to make sure we
+ * interpose other mechanisms before they are used. */
+ for (minfo = g_mechList; minfo != NULL; minfo = minfo->next) {
+ if (minfo->is_interposer && minfo->mech == NULL)
+ loadInterMech(minfo);
+ }
+} /* updateMechList */
+
+/* Update the mech list from system configuration if we have never done so.
+ * Must be invoked with the g_mechListLock mutex held. */
+static void
+initMechList(void)
+{
+ static int lazy_init = 0;
+
+ if (lazy_init == 0) {
+ updateMechList();
+ lazy_init = 1;
+ }
+}
+
+static void
+releaseMechInfo(gss_mech_info *pCf)
+{
+ gss_mech_info cf;
+ OM_uint32 minor_status;
+
+ if (*pCf == NULL) {
+ return;
+ }
+
+ cf = *pCf;
+
+ if (cf->kmodName != NULL)
+ free(cf->kmodName);
+ if (cf->uLibName != NULL)
+ free(cf->uLibName);
+ if (cf->mechNameStr != NULL)
+ free(cf->mechNameStr);
+ if (cf->optionStr != NULL)
+ free(cf->optionStr);
+ if (cf->mech_type != GSS_C_NO_OID &&
+ cf->mech_type != &cf->mech->mech_type)
+ generic_gss_release_oid(&minor_status, &cf->mech_type);
+ if (cf->freeMech)
+ zapfree(cf->mech, sizeof(*cf->mech));
+ if (cf->dl_handle != NULL)
+ krb5int_close_plugin(cf->dl_handle);
+ if (cf->int_mech_type != GSS_C_NO_OID)
+ generic_gss_release_oid(&minor_status, &cf->int_mech_type);
+
+ memset(cf, 0, sizeof(*cf));
+ free(cf);
+
+ *pCf = NULL;
+}
+
+#ifdef _GSS_STATIC_LINK
+/*
+ * Register a mechanism. Called with g_mechListLock held.
+ */
+int
+gssint_register_mechinfo(gss_mech_info template)
+{
+ gss_mech_info cf, new_cf;
+
+ new_cf = calloc(1, sizeof(*new_cf));
+ if (new_cf == NULL) {
+ return ENOMEM;
+ }
+
+ new_cf->dl_handle = template->dl_handle;
+ /* copy mech so we can rewrite canonical mechanism OID */
+ new_cf->mech = (gss_mechanism)calloc(1, sizeof(struct gss_config));
+ if (new_cf->mech == NULL) {
+ releaseMechInfo(&new_cf);
+ return ENOMEM;
+ }
+ *new_cf->mech = *template->mech;
+ if (template->mech_type != NULL)
+ new_cf->mech->mech_type = *(template->mech_type);
+ new_cf->mech_type = &new_cf->mech->mech_type;
+ new_cf->priority = template->priority;
+ new_cf->freeMech = 1;
+ new_cf->next = NULL;
+
+ if (template->kmodName != NULL) {
+ new_cf->kmodName = strdup(template->kmodName);
+ if (new_cf->kmodName == NULL) {
+ releaseMechInfo(&new_cf);
+ return ENOMEM;
+ }
+ }
+ if (template->uLibName != NULL) {
+ new_cf->uLibName = strdup(template->uLibName);
+ if (new_cf->uLibName == NULL) {
+ releaseMechInfo(&new_cf);
+ return ENOMEM;
+ }
+ }
+ if (template->mechNameStr != NULL) {
+ new_cf->mechNameStr = strdup(template->mechNameStr);
+ if (new_cf->mechNameStr == NULL) {
+ releaseMechInfo(&new_cf);
+ return ENOMEM;
+ }
+ }
+ if (template->optionStr != NULL) {
+ new_cf->optionStr = strdup(template->optionStr);
+ if (new_cf->optionStr == NULL) {
+ releaseMechInfo(&new_cf);
+ return ENOMEM;
+ }
+ }
+ if (g_mechList == NULL) {
+ g_mechList = new_cf;
+ g_mechListTail = new_cf;
+ return 0;
+ } else if (new_cf->priority < g_mechList->priority) {
+ new_cf->next = g_mechList;
+ g_mechList = new_cf;
+ return 0;
+ }
+
+ for (cf = g_mechList; cf != NULL; cf = cf->next) {
+ if (cf->next == NULL ||
+ new_cf->priority < cf->next->priority) {
+ new_cf->next = cf->next;
+ cf->next = new_cf;
+ if (g_mechListTail == cf) {
+ g_mechListTail = new_cf;
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+#endif /* _GSS_STATIC_LINK */
+
+#define GSS_ADD_DYNAMIC_METHOD(_dl, _mech, _symbol) \
+ do { \
+ struct errinfo errinfo; \
+ \
+ memset(&errinfo, 0, sizeof(errinfo)); \
+ if (krb5int_get_plugin_func(_dl, \
+ #_symbol, \
+ (void (**)())&(_mech)->_symbol, \
+ &errinfo) || errinfo.code) { \
+ (_mech)->_symbol = NULL; \
+ k5_clear_error(&errinfo); \
+ } \
+ } while (0)
+
+/*
+ * If _symbol is undefined in the shared object but the shared object
+ * is linked against the mechanism glue, it's possible for dlsym() to
+ * return the mechanism glue implementation. Guard against that.
+ */
+#define GSS_ADD_DYNAMIC_METHOD_NOLOOP(_dl, _mech, _symbol) \
+ do { \
+ GSS_ADD_DYNAMIC_METHOD(_dl, _mech, _symbol); \
+ if ((_mech)->_symbol == _symbol) \
+ (_mech)->_symbol = NULL; \
+ } while (0)
+
+static gss_mechanism
+build_dynamicMech(void *dl, const gss_OID mech_type)
+{
+ gss_mechanism mech;
+
+ mech = (gss_mechanism)calloc(1, sizeof(*mech));
+ if (mech == NULL) {
+ return NULL;
+ }
+
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_acquire_cred);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_release_cred);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_init_sec_context);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_accept_sec_context);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_process_context_token);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_delete_sec_context);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_context_time);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_get_mic);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_verify_mic);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_wrap);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_unwrap);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_display_status);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_indicate_mechs);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_compare_name);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_display_name);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_import_name);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_release_name);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_inquire_cred);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_add_cred);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_export_sec_context);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_import_sec_context);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_inquire_cred_by_mech);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_inquire_names_for_mech);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_inquire_context);
+ GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_internal_release_oid);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_wrap_size_limit);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_localname);
+ GSS_ADD_DYNAMIC_METHOD(dl, mech, gssspi_authorize_localname);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_export_name);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_duplicate_name);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_store_cred);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_inquire_sec_context_by_oid);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_inquire_cred_by_oid);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_set_sec_context_option);
+ GSS_ADD_DYNAMIC_METHOD(dl, mech, gssspi_set_cred_option);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gssspi_mech_invoke);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_wrap_aead);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_unwrap_aead);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_wrap_iov);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_unwrap_iov);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_wrap_iov_length);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_complete_auth_token);
+ /* Services4User (introduced in 1.8) */
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_acquire_cred_impersonate_name);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_add_cred_impersonate_name);
+ /* Naming extensions (introduced in 1.8) */
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_display_name_ext);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_inquire_name);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_get_name_attribute);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_set_name_attribute);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_delete_name_attribute);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_export_name_composite);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_map_name_to_any);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_release_any_name_mapping);
+ /* RFC 4401 (introduced in 1.8) */
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_pseudo_random);
+ /* RFC 4178 (introduced in 1.8; gss_get_neg_mechs not implemented) */
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_set_neg_mechs);
+ /* draft-ietf-sasl-gs2 */
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_inquire_saslname_for_mech);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_inquire_mech_for_saslname);
+ /* RFC 5587 */
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_inquire_attrs_for_mech);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_acquire_cred_from);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_store_cred_into);
+ GSS_ADD_DYNAMIC_METHOD(dl, mech, gssspi_acquire_cred_with_password);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_export_cred);
+ GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_import_cred);
+ GSS_ADD_DYNAMIC_METHOD(dl, mech, gssspi_import_sec_context_by_mech);
+ GSS_ADD_DYNAMIC_METHOD(dl, mech, gssspi_import_name_by_mech);
+ GSS_ADD_DYNAMIC_METHOD(dl, mech, gssspi_import_cred_by_mech);
+
+ assert(mech_type != GSS_C_NO_OID);
+
+ mech->mech_type = *(mech_type);
+
+ return mech;
+}
+
+#define RESOLVE_GSSI_SYMBOL(_dl, _mech, _psym, _nsym) \
+ do { \
+ struct errinfo errinfo; \
+ memset(&errinfo, 0, sizeof(errinfo)); \
+ if (krb5int_get_plugin_func(_dl, \
+ "gssi" #_nsym, \
+ (void (**)())&(_mech)->_psym \
+ ## _nsym, \
+ &errinfo) || errinfo.code) { \
+ (_mech)->_psym ## _nsym = NULL; \
+ k5_clear_error(&errinfo); \
+ } \
+ } while (0)
+
+/* Build an interposer mechanism function table from dl. */
+static gss_mechanism
+build_interMech(void *dl, const gss_OID mech_type)
+{
+ gss_mechanism mech;
+
+ mech = calloc(1, sizeof(*mech));
+ if (mech == NULL) {
+ return NULL;
+ }
+
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _acquire_cred);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _release_cred);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _init_sec_context);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _accept_sec_context);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _process_context_token);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _delete_sec_context);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _context_time);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _get_mic);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _verify_mic);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _wrap);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _unwrap);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _display_status);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _indicate_mechs);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _compare_name);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _display_name);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _import_name);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _release_name);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _inquire_cred);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _add_cred);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _export_sec_context);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _import_sec_context);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _inquire_cred_by_mech);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _inquire_names_for_mech);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _inquire_context);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _internal_release_oid);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _wrap_size_limit);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _localname);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gssspi, _authorize_localname);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _export_name);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _duplicate_name);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _store_cred);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _inquire_sec_context_by_oid);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _inquire_cred_by_oid);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _set_sec_context_option);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gssspi, _set_cred_option);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gssspi, _mech_invoke);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _wrap_aead);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _unwrap_aead);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _wrap_iov);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _unwrap_iov);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _wrap_iov_length);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _complete_auth_token);
+ /* Services4User (introduced in 1.8) */
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _acquire_cred_impersonate_name);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _add_cred_impersonate_name);
+ /* Naming extensions (introduced in 1.8) */
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _display_name_ext);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _inquire_name);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _get_name_attribute);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _set_name_attribute);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _delete_name_attribute);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _export_name_composite);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _map_name_to_any);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _release_any_name_mapping);
+ /* RFC 4401 (introduced in 1.8) */
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _pseudo_random);
+ /* RFC 4178 (introduced in 1.8; get_neg_mechs not implemented) */
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _set_neg_mechs);
+ /* draft-ietf-sasl-gs2 */
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _inquire_saslname_for_mech);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _inquire_mech_for_saslname);
+ /* RFC 5587 */
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _inquire_attrs_for_mech);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _acquire_cred_from);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _store_cred_into);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gssspi, _acquire_cred_with_password);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _export_cred);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gss, _import_cred);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gssspi, _import_sec_context_by_mech);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gssspi, _import_name_by_mech);
+ RESOLVE_GSSI_SYMBOL(dl, mech, gssspi, _import_cred_by_mech);
+
+ mech->mech_type = *mech_type;
+ return mech;
+}
+
+/*
+ * Concatenate an interposer mech OID and a real mech OID to create an
+ * identifier for the interposed mech. (The concatenation will not be a valid
+ * DER OID encoding, but the OID is only used internally.)
+ */
+static gss_OID
+interposed_oid(gss_OID pre, gss_OID real)
+{
+ gss_OID o;
+
+ o = (gss_OID)malloc(sizeof(gss_OID_desc));
+ if (!o)
+ return NULL;
+
+ o->length = pre->length + real->length;
+ o->elements = malloc(o->length);
+ if (!o->elements) {
+ free(o);
+ return NULL;
+ }
+
+ memcpy(o->elements, pre->elements, pre->length);
+ memcpy((char *)o->elements + pre->length, real->elements,
+ real->length);
+
+ return o;
+}
+
+static void
+loadInterMech(gss_mech_info minfo)
+{
+ struct plugin_file_handle *dl = NULL;
+ struct errinfo errinfo;
+ gss_OID_set (*isym)(const gss_OID);
+ gss_OID_set list;
+ gss_OID oid;
+ OM_uint32 min;
+ gss_mech_info mi;
+ size_t i;
+
+ memset(&errinfo, 0, sizeof(errinfo));
+
+ if (krb5int_open_plugin(minfo->uLibName, &dl, &errinfo) != 0 ||
+ errinfo.code != 0) {
+#if 0
+ (void) syslog(LOG_INFO, "libgss dlopen(%s): %s\n",
+ aMech->uLibName, dlerror());
+#endif
+ return;
+ }
+
+ if (krb5int_get_plugin_func(dl, MECH_INTERPOSER_SYM,
+ (void (**)())&isym, &errinfo) != 0)
+ goto cleanup;
+
+ /* Get a list of mechs to interpose. */
+ list = (*isym)(minfo->mech_type);
+ if (!list)
+ goto cleanup;
+ minfo->mech = build_interMech(dl, minfo->mech_type);
+ if (minfo->mech == NULL)
+ goto cleanup;
+ minfo->freeMech = 1;
+
+ /* Add interposer fields for each interposed mech. */
+ for (i = 0; i < list->count; i++) {
+ /* Skip this mech if it doesn't exist or is already
+ * interposed. */
+ oid = &list->elements[i];
+ mi = searchMechList(oid);
+ if (mi == NULL || mi->int_mech_type != NULL)
+ continue;
+
+ /* Construct a special OID to represent the interposed mech. */
+ mi->int_mech_type = interposed_oid(minfo->mech_type, oid);
+ if (mi->int_mech_type == NULL)
+ continue;
+
+ /* Save an alias to the interposer's function table. */
+ mi->int_mech = minfo->mech;
+ }
+ (void)gss_release_oid_set(&min, &list);
+
+ minfo->dl_handle = dl;
+ dl = NULL;
+
+cleanup:
+#if 0
+ if (aMech->mech == NULL) {
+ (void) syslog(LOG_INFO, "unable to initialize mechanism"
+ " library [%s]\n", aMech->uLibName);
+ }
+#endif
+ if (dl != NULL)
+ krb5int_close_plugin(dl);
+ k5_clear_error(&errinfo);
+}
+
+static void
+freeMechList(void)
+{
+ gss_mech_info cf, next_cf;
+
+ for (cf = g_mechList; cf != NULL; cf = next_cf) {
+ next_cf = cf->next;
+ releaseMechInfo(&cf);
+ }
+}
+
+/*
+ * Determine the mechanism to use for a caller-specified mech OID. For the
+ * real mech OID of an interposed mech, return the interposed OID. For an
+ * interposed mech OID (which an interposer mech uses when re-entering the
+ * mechglue), return the real mech OID. The returned OID is an alias and
+ * should not be modified or freed.
+ */
+OM_uint32
+gssint_select_mech_type(OM_uint32 *minor, gss_const_OID oid,
+ gss_OID *selected_oid)
+{
+ gss_mech_info minfo;
+ OM_uint32 status;
+
+ *selected_oid = GSS_C_NO_OID;
+
+ if (gssint_mechglue_initialize_library() != 0)
+ return GSS_S_FAILURE;
+
+ k5_mutex_lock(&g_mechListLock);
+
+ /* Read conf file at least once so that interposer plugins have a
+ * chance of getting initialized. */
+ initMechList();
+
+ minfo = g_mechList;
+ if (oid == GSS_C_NULL_OID)
+ oid = minfo->mech_type;
+ while (minfo != NULL) {
+ if (g_OID_equal(minfo->mech_type, oid)) {
+ if (minfo->int_mech_type != GSS_C_NO_OID)
+ *selected_oid = minfo->int_mech_type;
+ else
+ *selected_oid = minfo->mech_type;
+ status = GSS_S_COMPLETE;
+ goto done;
+ } else if ((minfo->int_mech_type != GSS_C_NO_OID) &&
+ (g_OID_equal(minfo->int_mech_type, oid))) {
+ *selected_oid = minfo->mech_type;
+ status = GSS_S_COMPLETE;
+ goto done;
+ }
+ minfo = minfo->next;
+ }
+ status = GSS_S_BAD_MECH;
+
+done:
+ k5_mutex_unlock(&g_mechListLock);
+ return status;
+}
+
+/* If oid is an interposed OID, return the corresponding real mech OID. If
+ * it's a real mech OID, return it unmodified. Otherwised return null. */
+gss_OID
+gssint_get_public_oid(gss_const_OID oid)
+{
+ gss_mech_info minfo;
+ gss_OID public_oid = GSS_C_NO_OID;
+
+ /* if oid is null -> then get default which is the first in the list */
+ if (oid == GSS_C_NO_OID)
+ return GSS_C_NO_OID;
+
+ if (gssint_mechglue_initialize_library() != 0)
+ return GSS_C_NO_OID;
+
+ k5_mutex_lock(&g_mechListLock);
+
+ for (minfo = g_mechList; minfo != NULL; minfo = minfo->next) {
+ if (minfo->is_interposer)
+ continue;
+ if (g_OID_equal(minfo->mech_type, oid) ||
+ ((minfo->int_mech_type != GSS_C_NO_OID) &&
+ (g_OID_equal(minfo->int_mech_type, oid)))) {
+ public_oid = minfo->mech_type;
+ break;
+ }
+ }
+
+ k5_mutex_unlock(&g_mechListLock);
+ return public_oid;
+}
+
+/* Translate a vector of oids (as from a union cred struct) into a set of
+ * public OIDs using gssint_get_public_oid. */
+OM_uint32
+gssint_make_public_oid_set(OM_uint32 *minor_status, gss_OID oids, int count,
+ gss_OID_set *public_set)
+{
+ OM_uint32 status, tmpmin;
+ gss_OID_set set;
+ gss_OID public_oid;
+ int i;
+
+ *public_set = GSS_C_NO_OID_SET;
+
+ status = generic_gss_create_empty_oid_set(minor_status, &set);
+ if (GSS_ERROR(status))
+ return status;
+
+ for (i = 0; i < count; i++) {
+ public_oid = gssint_get_public_oid(&oids[i]);
+ if (public_oid == GSS_C_NO_OID)
+ continue;
+ status = generic_gss_add_oid_set_member(minor_status,
+ public_oid, &set);
+ if (GSS_ERROR(status)) {
+ (void) generic_gss_release_oid_set(&tmpmin, &set);
+ return status;
+ }
+ }
+
+ *public_set = set;
+ return GSS_S_COMPLETE;
+}
+
+/*
+ * Register a mechanism. Called with g_mechListLock held.
+ */
+
+/*
+ * given the mechanism type, return the mechanism structure
+ * containing the mechanism library entry points.
+ * will return NULL if mech type is not found
+ * This function will also trigger the loading of the mechanism
+ * module if it has not been already loaded.
+ */
+gss_mechanism
+gssint_get_mechanism(gss_const_OID oid)
+{
+ gss_mech_info aMech;
+ gss_mechanism (*sym)(const gss_OID);
+ struct plugin_file_handle *dl;
+ struct errinfo errinfo;
+
+ if (gssint_mechglue_initialize_library() != 0)
+ return (NULL);
+
+ k5_mutex_lock(&g_mechListLock);
+
+ /* Check if the mechanism is already loaded. */
+ aMech = g_mechList;
+ if (oid == GSS_C_NULL_OID)
+ oid = aMech->mech_type;
+ while (aMech != NULL) {
+ if (g_OID_equal(aMech->mech_type, oid) && aMech->mech) {
+ k5_mutex_unlock(&g_mechListLock);
+ return aMech->mech;
+ } else if (aMech->int_mech_type != GSS_C_NO_OID &&
+ g_OID_equal(aMech->int_mech_type, oid)) {
+ k5_mutex_unlock(&g_mechListLock);
+ return aMech->int_mech;
+ }
+ aMech = aMech->next;
+ }
+
+ /*
+ * might need to re-read the configuration file before loading
+ * the mechanism to ensure we have the latest info.
+ */
+ updateMechList();
+
+ aMech = searchMechList(oid);
+
+ /* is the mechanism present in the list ? */
+ if (aMech == NULL) {
+ k5_mutex_unlock(&g_mechListLock);
+ return ((gss_mechanism)NULL);
+ }
+
+ /* has another thread loaded the mech */
+ if (aMech->mech) {
+ k5_mutex_unlock(&g_mechListLock);
+ return (aMech->mech);
+ }
+
+ memset(&errinfo, 0, sizeof(errinfo));
+
+ if (krb5int_open_plugin(aMech->uLibName, &dl, &errinfo) != 0 ||
+ errinfo.code != 0) {
+#if 0
+ (void) syslog(LOG_INFO, "libgss dlopen(%s): %s\n",
+ aMech->uLibName, dlerror());
+#endif
+ k5_mutex_unlock(&g_mechListLock);
+ return ((gss_mechanism)NULL);
+ }
+
+ if (krb5int_get_plugin_func(dl, MECH_SYM, (void (**)())&sym,
+ &errinfo) == 0) {
+ /* Call the symbol to get the mechanism table */
+ aMech->mech = (*sym)(aMech->mech_type);
+ } else {
+ /* Try dynamic dispatch table */
+ aMech->mech = build_dynamicMech(dl, aMech->mech_type);
+ aMech->freeMech = 1;
+ }
+ if (aMech->mech == NULL) {
+ (void) krb5int_close_plugin(dl);
+#if 0
+ (void) syslog(LOG_INFO, "unable to initialize mechanism"
+ " library [%s]\n", aMech->uLibName);
+#endif
+ k5_mutex_unlock(&g_mechListLock);
+ return ((gss_mechanism)NULL);
+ }
+
+ aMech->dl_handle = dl;
+
+ k5_mutex_unlock(&g_mechListLock);
+ return (aMech->mech);
+} /* gssint_get_mechanism */
+
+/*
+ * this routine is used for searching the list of mechanism data.
+ *
+ * this needs to be called with g_mechListLock held.
+ */
+static gss_mech_info searchMechList(gss_const_OID oid)
+{
+ gss_mech_info aMech = g_mechList;
+
+ /* if oid is null -> then get default which is the first in the list */
+ if (oid == GSS_C_NULL_OID)
+ return (aMech);
+
+ while (aMech != NULL) {
+ if (g_OID_equal(aMech->mech_type, oid))
+ return (aMech);
+ aMech = aMech->next;
+ }
+
+ /* none found */
+ return ((gss_mech_info) NULL);
+} /* searchMechList */
+
+/* Return the first non-whitespace character starting from str. */
+static char *
+skip_whitespace(char *str)
+{
+ while (isspace(*str))
+ str++;
+ return str;
+}
+
+/* Truncate str at the first whitespace character and return the first
+ * non-whitespace character after that point. */
+static char *
+delimit_ws(char *str)
+{
+ while (*str != '\0' && !isspace(*str))
+ str++;
+ if (*str != '\0')
+ *str++ = '\0';
+ return skip_whitespace(str);
+}
+
+/* Truncate str at the first occurrence of delimiter and return the first
+ * non-whitespace character after that point. */
+static char *
+delimit(char *str, char delimiter)
+{
+ while (*str != '\0' && *str != delimiter)
+ str++;
+ if (*str != '\0')
+ *str++ = '\0';
+ return skip_whitespace(str);
+}
+
+/*
+ * loads the configuration file
+ * this is called while having a mutex lock on the mechanism list
+ * entries for libraries that have been loaded can't be modified
+ * mechNameStr and mech_type fields are not updated during updates
+ */
+static void
+loadConfigFile(const char *fileName)
+{
+ char *sharedLib, *kernMod, *modOptions, *modType, *oid, *next;
+ char buffer[BUFSIZ], *oidStr;
+ FILE *confFile;
+
+ if ((confFile = fopen(fileName, "r")) == NULL) {
+ return;
+ }
+
+ (void) memset(buffer, 0, sizeof (buffer));
+ while (fgets(buffer, BUFSIZ, confFile) != NULL) {
+
+ /* ignore lines beginning with # */
+ if (*buffer == '#')
+ continue;
+
+ /* Parse out the name, oid, and shared library path. */
+ oidStr = buffer;
+ oid = delimit_ws(oidStr);
+ if (*oid == '\0')
+ continue;
+ sharedLib = delimit_ws(oid);
+ if (*sharedLib == '\0')
+ continue;
+ next = delimit_ws(sharedLib);
+
+ /* Parse out the kernel module name if present. */
+ if (*next != '\0' && *next != '[' && *next != '<') {
+ kernMod = next;
+ next = delimit_ws(kernMod);
+ } else {
+ kernMod = NULL;
+ }
+
+ /* Parse out the module options if present. */
+ if (*next == '[') {
+ modOptions = next + 1;
+ next = delimit(modOptions, ']');
+ } else {
+ modOptions = NULL;
+ }
+
+ /* Parse out the module type if present. */
+ if (*next == '<') {
+ modType = next + 1;
+ (void)delimit(modType, '>');
+ } else {
+ modType = NULL;
+ }
+
+ addConfigEntry(oidStr, oid, sharedLib, kernMod, modOptions,
+ modType);
+ } /* while */
+ (void) fclose(confFile);
+} /* loadConfigFile */
+
+#if defined(_WIN32)
+
+static time_t
+filetimeToTimet(const FILETIME *ft)
+{
+ ULARGE_INTEGER ull;
+
+ ull.LowPart = ft->dwLowDateTime;
+ ull.HighPart = ft->dwHighDateTime;
+ return (time_t)(ull.QuadPart / 10000000ULL - 11644473600ULL);
+}
+
+static time_t
+getRegConfigModTime(const char *keyPath)
+{
+ time_t currentUserModTime = getRegKeyModTime(HKEY_CURRENT_USER,
+ keyPath);
+ time_t localMachineModTime = getRegKeyModTime(HKEY_LOCAL_MACHINE,
+ keyPath);
+
+ return currentUserModTime > localMachineModTime ? currentUserModTime :
+ localMachineModTime;
+}
+
+static time_t
+getRegKeyModTime(HKEY hBaseKey, const char *keyPath)
+{
+ HKEY hConfigKey;
+ HRESULT rc;
+ int iSubKey = 0;
+ time_t modTime = 0, keyModTime;
+ FILETIME keyLastWriteTime;
+ char subKeyName[256];
+
+ if ((rc = RegOpenKeyEx(hBaseKey, keyPath, 0, KEY_ENUMERATE_SUB_KEYS,
+ &hConfigKey)) != ERROR_SUCCESS) {
+ /* TODO: log error message */
+ return 0;
+ }
+ do {
+ int subKeyNameSize=sizeof(subKeyName)/sizeof(subKeyName[0]);
+ if ((rc = RegEnumKeyEx(hConfigKey, iSubKey++, subKeyName,
+ &subKeyNameSize, NULL, NULL, NULL,
+ &keyLastWriteTime)) != ERROR_SUCCESS) {
+ break;
+ }
+ keyModTime = filetimeToTimet(&keyLastWriteTime);
+ if (modTime < keyModTime) {
+ modTime = keyModTime;
+ }
+ } while (1);
+ RegCloseKey(hConfigKey);
+ return modTime;
+}
+
+static void
+getRegKeyValue(HKEY hKey, const char *keyPath, const char *valueName,
+ void **data, DWORD* dataLen)
+{
+ DWORD sizeRequired=*dataLen;
+ HRESULT hr;
+ /* Get data length required */
+ if ((hr = RegGetValue(hKey, keyPath, valueName, RRF_RT_REG_SZ, NULL,
+ NULL, &sizeRequired)) != ERROR_SUCCESS) {
+ /* TODO: LOG registry error */
+ return;
+ }
+ /* adjust data buffer size if necessary */
+ if (*dataLen < sizeRequired) {
+ *dataLen = sizeRequired;
+ *data = realloc(*data, sizeRequired);
+ if (!*data) {
+ *dataLen = 0;
+ /* TODO: LOG OOM ERROR! */
+ return;
+ }
+ }
+ /* get data */
+ if ((hr = RegGetValue(hKey, keyPath, valueName, RRF_RT_REG_SZ, NULL,
+ *data, &sizeRequired)) != ERROR_SUCCESS) {
+ /* LOG registry error */
+ return;
+ }
+}
+
+static void
+loadConfigFromRegistry(HKEY hBaseKey, const char *keyPath)
+{
+ HKEY hConfigKey;
+ DWORD iSubKey, nSubKeys, maxSubKeyNameLen, modTypeLen;
+ char *oidStr = NULL, *oid = NULL, *sharedLib = NULL, *kernMod = NULL;
+ char *modOptions = NULL, *modType = NULL;
+ DWORD oidStrLen = 0, oidLen = 0, sharedLibLen = 0, kernModLen = 0;
+ DWORD modOptionsLen = 0;
+ HRESULT rc;
+
+ if ((rc = RegOpenKeyEx(hBaseKey, keyPath, 0,
+ KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE,
+ &hConfigKey)) != ERROR_SUCCESS) {
+ /* TODO: log registry error */
+ return;
+ }
+
+ if ((rc = RegQueryInfoKey(hConfigKey,
+ NULL, /* lpClass */
+ NULL, /* lpcClass */
+ NULL, /* lpReserved */
+ &nSubKeys,
+ &maxSubKeyNameLen,
+ NULL, /* lpcMaxClassLen */
+ NULL, /* lpcValues */
+ NULL, /* lpcMaxValueNameLen */
+ NULL, /* lpcMaxValueLen */
+ NULL, /* lpcbSecurityDescriptor */
+ NULL /* lpftLastWriteTime */ )) != ERROR_SUCCESS) {
+ goto cleanup;
+ }
+ oidStr = malloc(++maxSubKeyNameLen);
+ if (!oidStr) {
+ goto cleanup;
+ }
+ for (iSubKey=0; iSubKey<nSubKeys; iSubKey++) {
+ oidStrLen = maxSubKeyNameLen;
+ if ((rc = RegEnumKeyEx(hConfigKey, iSubKey, oidStr, &oidStrLen,
+ NULL, NULL, NULL, NULL)) !=
+ ERROR_SUCCESS) {
+ /* TODO: log registry error */
+ continue;
+ }
+ getRegKeyValue(hConfigKey, oidStr, "OID", &oid, &oidLen);
+ getRegKeyValue(hConfigKey, oidStr, "Shared Library",
+ &sharedLib, &sharedLibLen);
+ getRegKeyValue(hConfigKey, oidStr, "Kernel Module", &kernMod,
+ &kernModLen);
+ getRegKeyValue(hConfigKey, oidStr, "Options", &modOptions,
+ &modOptionsLen);
+ getRegKeyValue(hConfigKey, oidStr, "Type", &modType,
+ &modTypeLen);
+ addConfigEntry(oidStr, oid, sharedLib, kernMod, modOptions,
+ modType);
+ }
+cleanup:
+ RegCloseKey(hConfigKey);
+ if (oidStr) {
+ free(oidStr);
+ }
+ if (oid) {
+ free(oid);
+ }
+ if (sharedLib) {
+ free(sharedLib);
+ }
+ if (kernMod) {
+ free(kernMod);
+ }
+ if (modOptions) {
+ free(modOptions);
+ }
+}
+#endif
+
+static void
+addConfigEntry(const char *oidStr, const char *oid, const char *sharedLib,
+ const char *kernMod, const char *modOptions,
+ const char *modType)
+{
+#if defined(_WIN32)
+ const char *sharedPath;
+#else
+ char sharedPath[sizeof (MECH_LIB_PREFIX) + BUFSIZ];
+#endif
+ char *tmpStr;
+ gss_OID mechOid;
+ gss_mech_info aMech, tmp;
+ OM_uint32 minor;
+ gss_buffer_desc oidBuf;
+
+ if ((!oid) || (!oidStr)) {
+ return;
+ }
+ /*
+ * check if an entry for this oid already exists
+ * if it does, and the library is already loaded then
+ * we can't modify it, so skip it
+ */
+ oidBuf.value = (void *)oid;
+ oidBuf.length = strlen(oid);
+ if (generic_gss_str_to_oid(&minor, &oidBuf, &mechOid)
+ != GSS_S_COMPLETE) {
+#if 0
+ (void) syslog(LOG_INFO, "invalid mechanism oid"
+ " [%s] in configuration file", oid);
+#endif
+ return;
+ }
+
+ aMech = searchMechList(mechOid);
+ if (aMech && aMech->mech) {
+ generic_gss_release_oid(&minor, &mechOid);
+ return;
+ }
+
+ /*
+ * If that's all, then this is a corrupt entry. Skip it.
+ */
+ if (! *sharedLib) {
+ generic_gss_release_oid(&minor, &mechOid);
+ return;
+ }
+#if defined(_WIN32)
+ sharedPath = sharedLib;
+#else
+ if (sharedLib[0] == '/')
+ snprintf(sharedPath, sizeof(sharedPath), "%s", sharedLib);
+ else
+ snprintf(sharedPath, sizeof(sharedPath), "%s%s",
+ MECH_LIB_PREFIX, sharedLib);
+#endif
+ /*
+ * are we creating a new mechanism entry or
+ * just modifying existing (non loaded) mechanism entry
+ */
+ if (aMech) {
+ /*
+ * delete any old values and set new
+ * mechNameStr and mech_type are not modified
+ */
+ if (aMech->kmodName) {
+ free(aMech->kmodName);
+ aMech->kmodName = NULL;
+ }
+
+ if (aMech->optionStr) {
+ free(aMech->optionStr);
+ aMech->optionStr = NULL;
+ }
+
+ if ((tmpStr = strdup(sharedPath)) != NULL) {
+ if (aMech->uLibName)
+ free(aMech->uLibName);
+ aMech->uLibName = tmpStr;
+ }
+
+ if (kernMod) /* this is an optional parameter */
+ aMech->kmodName = strdup(kernMod);
+
+ if (modOptions) /* optional module options */
+ aMech->optionStr = strdup(modOptions);
+
+ /* the oid is already set */
+ generic_gss_release_oid(&minor, &mechOid);
+ return;
+ }
+
+ /* adding a new entry */
+ aMech = calloc(1, sizeof (struct gss_mech_config));
+ if (aMech == NULL) {
+ generic_gss_release_oid(&minor, &mechOid);
+ return;
+ }
+ aMech->mech_type = mechOid;
+ aMech->uLibName = strdup(sharedPath);
+ aMech->mechNameStr = strdup(oidStr);
+ aMech->freeMech = 0;
+
+ /* check if any memory allocations failed - bad news */
+ if (aMech->uLibName == NULL || aMech->mechNameStr == NULL) {
+ if (aMech->uLibName)
+ free(aMech->uLibName);
+ if (aMech->mechNameStr)
+ free(aMech->mechNameStr);
+ generic_gss_release_oid(&minor, &mechOid);
+ free(aMech);
+ return;
+ }
+ if (kernMod) /* this is an optional parameter */
+ aMech->kmodName = strdup(kernMod);
+
+ if (modOptions)
+ aMech->optionStr = strdup(modOptions);
+
+ if (modType && strcmp(modType, "interposer") == 0)
+ aMech->is_interposer = 1;
+
+ /*
+ * add the new entry to the end of the list - make sure
+ * that only complete entries are added because other
+ * threads might currently be searching the list.
+ */
+ tmp = g_mechListTail;
+ g_mechListTail = aMech;
+
+ if (tmp != NULL)
+ tmp->next = aMech;
+
+ if (g_mechList == NULL)
+ g_mechList = aMech;
+}
+
diff --git a/src/lib/gssapi/mechglue/g_inq_context.c b/src/lib/gssapi/mechglue/g_inq_context.c
new file mode 100644
index 000000000000..6f1c71eede9d
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_inq_context.c
@@ -0,0 +1,168 @@
+/* #pragma ident "@(#)g_inquire_context.c 1.15 04/02/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_inquire_context
+ */
+
+#include "mglueP.h"
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+static OM_uint32
+val_inq_ctx_args(
+ OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ gss_name_t *src_name,
+ gss_name_t *targ_name,
+ OM_uint32 *lifetime_rec,
+ gss_OID *mech_type,
+ OM_uint32 *ctx_flags,
+ int *locally_initiated,
+ int *opened)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (src_name != NULL)
+ *src_name = GSS_C_NO_NAME;
+
+ if (targ_name != NULL)
+ *targ_name = GSS_C_NO_NAME;
+
+ if (mech_type != NULL)
+ *mech_type = GSS_C_NO_OID;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
+
+ return (GSS_S_COMPLETE);
+}
+
+
+/* Last argument new for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_inquire_context(
+ OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ gss_name_t *src_name,
+ gss_name_t *targ_name,
+ OM_uint32 *lifetime_rec,
+ gss_OID *mech_type,
+ OM_uint32 *ctx_flags,
+ int *locally_initiated,
+ int *opened)
+{
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+ OM_uint32 status, temp_minor;
+ gss_OID actual_mech;
+ gss_name_t localTargName = NULL, localSourceName = NULL;
+
+ status = val_inq_ctx_args(minor_status,
+ context_handle,
+ src_name, targ_name,
+ lifetime_rec,
+ mech_type, ctx_flags,
+ locally_initiated, opened);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+
+ if (!mech || !mech->gss_inquire_context || !mech->gss_display_name ||
+ !mech->gss_release_name) {
+ return (GSS_S_UNAVAILABLE);
+ }
+
+ status = mech->gss_inquire_context(
+ minor_status,
+ ctx->internal_ctx_id,
+ (src_name ? &localSourceName : NULL),
+ (targ_name ? &localTargName : NULL),
+ lifetime_rec,
+ &actual_mech,
+ ctx_flags,
+ locally_initiated,
+ opened);
+
+ if (status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ return status;
+ }
+
+ /* need to convert names */
+
+ if (src_name) {
+ if (localSourceName) {
+ status = gssint_convert_name_to_union_name(minor_status, mech,
+ localSourceName, src_name);
+
+ if (status != GSS_S_COMPLETE) {
+ if (localTargName)
+ mech->gss_release_name(&temp_minor, &localTargName);
+ return (status);
+ }
+ } else {
+ *src_name = GSS_C_NO_NAME;
+ }
+ }
+
+ if (targ_name) {
+ if (localTargName) {
+ status = gssint_convert_name_to_union_name(minor_status, mech,
+ localTargName, targ_name);
+
+ if (status != GSS_S_COMPLETE) {
+ if (src_name)
+ (void) gss_release_name(&temp_minor, src_name);
+
+ return (status);
+ }
+ }
+ else {
+ *targ_name = GSS_C_NO_NAME;
+ }
+ }
+
+ if (mech_type)
+ *mech_type = gssint_get_public_oid(actual_mech);
+
+ return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/mechglue/g_inq_context_oid.c b/src/lib/gssapi/mechglue/g_inq_context_oid.c
new file mode 100644
index 000000000000..ebdeaaee88b2
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_inq_context_oid.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2008 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/* Glue routine for gss_inquire_sec_context_by_oid */
+
+#include "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_inquire_sec_context_by_oid (OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ OM_uint32 status;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT;
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+
+ if (mech != NULL) {
+ if (mech->gss_inquire_sec_context_by_oid != NULL) {
+ status = mech->gss_inquire_sec_context_by_oid(minor_status,
+ ctx->internal_ctx_id,
+ desired_object,
+ data_set);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return status;
+ }
+
+ return GSS_S_BAD_MECH;
+}
diff --git a/src/lib/gssapi/mechglue/g_inq_cred.c b/src/lib/gssapi/mechglue/g_inq_cred.c
new file mode 100644
index 000000000000..911196264f1f
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_inq_cred.c
@@ -0,0 +1,233 @@
+/* #pragma ident "@(#)g_inquire_cred.c 1.16 04/02/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_inquire_cred
+ */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <time.h>
+
+OM_uint32 KRB5_CALLCONV
+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, temp_minor_status;
+ gss_union_cred_t union_cred;
+ gss_mechanism mech;
+ gss_cred_id_t mech_cred;
+ gss_name_t mech_name;
+ gss_OID_set mechs = NULL;
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (name != NULL)
+ *name = GSS_C_NO_NAME;
+
+ if (mechanisms != NULL)
+ *mechanisms = GSS_C_NO_OID_SET;
+
+ /* Validate arguments. */
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ /*
+ * XXX We should iterate over all mechanisms in the credential and
+ * aggregate the results. This requires a union name structure containing
+ * multiple mechanism names, which we don't currently have. For now,
+ * inquire the first mechanism in the credential; this is consistent with
+ * our historical behavior.
+ */
+
+ /* Determine mechanism and mechanism credential. */
+ if (cred_handle != GSS_C_NO_CREDENTIAL) {
+ union_cred = (gss_union_cred_t) cred_handle;
+ if (union_cred->count <= 0)
+ return (GSS_S_DEFECTIVE_CREDENTIAL);
+ mech_cred = union_cred->cred_array[0];
+ mech = gssint_get_mechanism(&union_cred->mechs_array[0]);
+ } else {
+ union_cred = NULL;
+ mech_cred = GSS_C_NO_CREDENTIAL;
+ mech = gssint_get_mechanism(GSS_C_NULL_OID);
+ }
+
+ /* Skip the call into the mech if the caller doesn't care about any of the
+ * values we would ask for. */
+ if (name != NULL || lifetime != NULL || cred_usage != NULL) {
+ if (mech == NULL)
+ return (GSS_S_DEFECTIVE_CREDENTIAL);
+ if (!mech->gss_inquire_cred)
+ return (GSS_S_UNAVAILABLE);
+
+ status = mech->gss_inquire_cred(minor_status, mech_cred,
+ name ? &mech_name : NULL,
+ lifetime, cred_usage, NULL);
+ if (status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ return(status);
+ }
+
+ if (name) {
+ /* Convert mech_name into a union_name equivalent. */
+ status = gssint_convert_name_to_union_name(&temp_minor_status,
+ mech, mech_name, name);
+ if (status != GSS_S_COMPLETE) {
+ *minor_status = temp_minor_status;
+ map_error(minor_status, mech);
+ return (status);
+ }
+ }
+ }
+
+ /*
+ * copy the mechanism set in union_cred into an OID set and return in
+ * the mechanisms parameter.
+ */
+
+ if(mechanisms != NULL) {
+ if (union_cred) {
+ status = gssint_make_public_oid_set(minor_status,
+ union_cred->mechs_array,
+ union_cred->count, &mechs);
+ if (GSS_ERROR(status))
+ goto error;
+ } else {
+ status = gss_create_empty_oid_set(minor_status, &mechs);
+ if (GSS_ERROR(status))
+ goto error;
+
+ status = gss_add_oid_set_member(minor_status,
+ &mech->mech_type, &mechs);
+ if (GSS_ERROR(status))
+ goto error;
+ }
+ *mechanisms = mechs;
+ }
+
+ return(GSS_S_COMPLETE);
+
+error:
+ if (mechs != NULL)
+ (void) gss_release_oid_set(&temp_minor_status, &mechs);
+
+ if (name && *name != NULL)
+ (void) gss_release_name(&temp_minor_status, name);
+
+ return (status);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_inquire_cred_by_mech(minor_status, cred_handle, mech_type, name,
+ initiator_lifetime, acceptor_lifetime, cred_usage)
+ OM_uint32 *minor_status;
+ gss_cred_id_t cred_handle;
+ gss_OID mech_type;
+ gss_name_t *name;
+ OM_uint32 *initiator_lifetime;
+ OM_uint32 *acceptor_lifetime;
+ gss_cred_usage_t *cred_usage;
+{
+ gss_union_cred_t union_cred;
+ gss_cred_id_t mech_cred;
+ gss_mechanism mech;
+ OM_uint32 status, temp_minor_status;
+ gss_name_t internal_name;
+ gss_OID selected_mech, public_mech;
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (name != NULL)
+ *name = GSS_C_NO_NAME;
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ status = gssint_select_mech_type(minor_status, mech_type, &selected_mech);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ mech = gssint_get_mechanism(selected_mech);
+ if (!mech)
+ return (GSS_S_BAD_MECH);
+ if (!mech->gss_inquire_cred_by_mech)
+ return (GSS_S_BAD_BINDINGS);
+
+ union_cred = (gss_union_cred_t) cred_handle;
+ mech_cred = gssint_get_mechanism_cred(union_cred, selected_mech);
+
+#if 0
+ if (mech_cred == NULL)
+ return (GSS_S_DEFECTIVE_CREDENTIAL);
+#endif
+
+ public_mech = gssint_get_public_oid(selected_mech);
+ status = mech->gss_inquire_cred_by_mech(minor_status,
+ mech_cred, public_mech,
+ name ? &internal_name : NULL,
+ initiator_lifetime,
+ acceptor_lifetime, cred_usage);
+
+ if (status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ return (status);
+ }
+
+ if (name) {
+ /*
+ * Convert internal_name into a union_name equivalent.
+ */
+ status = gssint_convert_name_to_union_name(
+ &temp_minor_status, mech,
+ internal_name, name);
+ if (status != GSS_S_COMPLETE) {
+ *minor_status = temp_minor_status;
+ map_error(minor_status, mech);
+ return (status);
+ }
+ }
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/mechglue/g_inq_cred_oid.c b/src/lib/gssapi/mechglue/g_inq_cred_oid.c
new file mode 100644
index 000000000000..4c23dfcbd364
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_inq_cred_oid.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2008 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/* Glue routine for gss_inquire_cred_by_oid */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <time.h>
+
+static OM_uint32 append_to_buffer_set(OM_uint32 *minor_status,
+ gss_buffer_set_t *dst,
+ const gss_buffer_set_t src)
+{
+ size_t i;
+ OM_uint32 status;
+
+ if (src == GSS_C_NO_BUFFER_SET)
+ return GSS_S_COMPLETE;
+
+ if (*dst == GSS_C_NO_BUFFER_SET) {
+ status = gss_create_empty_buffer_set(minor_status, dst);
+ if (status != GSS_S_COMPLETE)
+ return status;
+ }
+
+ status = GSS_S_COMPLETE;
+
+ for (i = 0; i < src->count; i++) {
+ status = gss_add_buffer_set_member(minor_status,
+ &src->elements[i],
+ dst);
+ if (status != GSS_S_COMPLETE)
+ break;
+ }
+
+ return status;
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_inquire_cred_by_oid(OM_uint32 *minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ gss_union_cred_t union_cred;
+ gss_mechanism mech;
+ int i;
+ gss_buffer_set_t union_set = GSS_C_NO_BUFFER_SET;
+ gss_buffer_set_t ret_set = GSS_C_NO_BUFFER_SET;
+ OM_uint32 status, minor;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (cred_handle == GSS_C_NO_CREDENTIAL)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CRED;
+
+ *minor_status = 0;
+ *data_set = GSS_C_NO_BUFFER_SET;
+
+ union_cred = (gss_union_cred_t) cred_handle;
+
+ status = gss_create_empty_buffer_set(minor_status, &ret_set);
+ if (status != GSS_S_COMPLETE) {
+ return status;
+ }
+
+ status = GSS_S_UNAVAILABLE;
+
+ for (i = 0; i < union_cred->count; i++) {
+ mech = gssint_get_mechanism(&union_cred->mechs_array[i]);
+ if (mech == NULL) {
+ status = GSS_S_BAD_MECH;
+ break;
+ }
+
+ if (mech->gss_inquire_cred_by_oid == NULL) {
+ status = GSS_S_UNAVAILABLE;
+ continue;
+ }
+
+ status = (mech->gss_inquire_cred_by_oid)(minor_status,
+ union_cred->cred_array[i],
+ desired_object,
+ &ret_set);
+ if (status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ continue;
+ }
+
+ if (union_cred->count == 1) {
+ union_set = ret_set;
+ break;
+ }
+
+ status = append_to_buffer_set(minor_status, &union_set, ret_set);
+ gss_release_buffer_set(&minor, &ret_set);
+ if (status != GSS_S_COMPLETE)
+ break;
+ }
+
+ if (status != GSS_S_COMPLETE)
+ gss_release_buffer_set(&minor, &union_set);
+
+ *data_set = union_set;
+
+ return status;
+}
diff --git a/src/lib/gssapi/mechglue/g_inq_name.c b/src/lib/gssapi/mechglue/g_inq_name.c
new file mode 100644
index 000000000000..60a3b54e7990
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_inq_name.c
@@ -0,0 +1,97 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2009 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/* Glue routine for gss_inquire_name */
+
+#include "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_inquire_name(OM_uint32 *minor_status,
+ gss_name_t name,
+ int *name_is_MN,
+ gss_OID *MN_mech,
+ gss_buffer_set_t *attrs)
+{
+ OM_uint32 status, tmp;
+ gss_union_name_t union_name;
+ gss_mechanism mech;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (name == GSS_C_NO_NAME)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME;
+
+ if (MN_mech != NULL)
+ *MN_mech = GSS_C_NO_OID;
+
+ if (attrs != NULL)
+ *attrs = GSS_C_NO_BUFFER_SET;
+
+ *minor_status = 0;
+ union_name = (gss_union_name_t)name;
+
+ if (union_name->mech_type == GSS_C_NO_OID) {
+ /* We don't yet support non-mechanism attributes */
+ if (name_is_MN != NULL)
+ *name_is_MN = 0;
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+ }
+
+ if (name_is_MN != NULL)
+ *name_is_MN = 1;
+
+ if (MN_mech != NULL) {
+ status = generic_gss_copy_oid(minor_status,
+ union_name->mech_type,
+ MN_mech);
+ if (GSS_ERROR(status))
+ return status;
+ }
+
+ mech = gssint_get_mechanism(name->mech_type);
+ if (mech == NULL) {
+ gss_release_oid(&tmp, MN_mech);
+ return GSS_S_BAD_NAME;
+ }
+
+ if (mech->gss_inquire_name == NULL) {
+ gss_release_oid(&tmp, MN_mech);
+ return GSS_S_UNAVAILABLE;
+ }
+
+ status = (*mech->gss_inquire_name)(minor_status,
+ union_name->mech_name,
+ NULL,
+ NULL,
+ attrs);
+ if (status != GSS_S_COMPLETE) {
+ generic_gss_release_oid(&tmp, MN_mech);
+ map_error(minor_status, mech);
+ }
+
+ return status;
+}
diff --git a/src/lib/gssapi/mechglue/g_inq_names.c b/src/lib/gssapi/mechglue/g_inq_names.c
new file mode 100644
index 000000000000..d22af8bcf958
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_inq_names.c
@@ -0,0 +1,168 @@
+/* #pragma ident "@(#)g_inquire_names.c 1.16 04/02/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_inquire_context
+ */
+
+#include "mglueP.h"
+
+#define MAX_MECH_OID_PAIRS 32
+
+/* Last argument new for V2 */
+OM_uint32 KRB5_CALLCONV
+gss_inquire_names_for_mech(minor_status, mechanism, name_types)
+
+OM_uint32 * minor_status;
+gss_OID mechanism;
+gss_OID_set * name_types;
+
+{
+ OM_uint32 status;
+ gss_OID selected_mech = GSS_C_NO_OID, public_mech;
+ gss_mechanism mech;
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (name_types != NULL)
+ *name_types = GSS_C_NO_OID_SET;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (name_types == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ status = gssint_select_mech_type(minor_status, mechanism,
+ &selected_mech);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ mech = gssint_get_mechanism(selected_mech);
+ if (mech == NULL)
+ return GSS_S_BAD_MECH;
+ else if (mech->gss_inquire_names_for_mech == NULL)
+ return GSS_S_UNAVAILABLE;
+ public_mech = gssint_get_public_oid(selected_mech);
+ status = mech->gss_inquire_names_for_mech(minor_status, public_mech,
+ name_types);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+
+ return status;
+}
+
+static OM_uint32
+val_inq_mechs4name_args(
+ OM_uint32 *minor_status,
+ const gss_name_t input_name,
+ gss_OID_set *mech_set)
+{
+
+ /* Initialize outputs. */
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (mech_set != NULL)
+ *mech_set = GSS_C_NO_OID_SET;
+
+ /* Validate arguments.e
+ */
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (input_name == GSS_C_NO_NAME)
+ return (GSS_S_BAD_NAME);
+
+ return (GSS_S_COMPLETE);
+}
+
+static int
+mech_supports_nametype(gss_OID mech_oid, gss_OID name_type)
+{
+ OM_uint32 status, minor;
+ gss_OID_set types = GSS_C_NO_OID_SET;
+ int present;
+
+ status = gss_inquire_names_for_mech(&minor, mech_oid, &types);
+ if (status != GSS_S_COMPLETE)
+ return (0);
+ status = gss_test_oid_set_member(&minor, name_type, types, &present);
+ (void) gss_release_oid_set(&minor, &types);
+ return (status == GSS_S_COMPLETE && present);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_inquire_mechs_for_name(OM_uint32 *minor_status,
+ const gss_name_t input_name, gss_OID_set *mech_set)
+{
+ OM_uint32 status, tmpmin;
+ gss_OID_set all_mechs = GSS_C_NO_OID_SET;
+ gss_OID_set mechs = GSS_C_NO_OID_SET;
+ gss_OID mech_oid, name_type;
+ gss_buffer_desc name_buffer = GSS_C_EMPTY_BUFFER;
+ size_t i;
+
+ status = val_inq_mechs4name_args(minor_status, input_name, mech_set);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ status = gss_display_name(minor_status, input_name, &name_buffer,
+ &name_type);
+ if (status != GSS_S_COMPLETE)
+ goto cleanup;
+ status = gss_indicate_mechs(minor_status, &all_mechs);
+ if (status != GSS_S_COMPLETE)
+ goto cleanup;
+ status = gss_create_empty_oid_set(minor_status, &mechs);
+ if (status != GSS_S_COMPLETE)
+ goto cleanup;
+ for (i = 0; i < all_mechs->count; i++) {
+ mech_oid = &all_mechs->elements[i];
+ if (mech_supports_nametype(mech_oid, name_type)) {
+ status = gss_add_oid_set_member(minor_status, mech_oid, &mechs);
+ if (status != GSS_S_COMPLETE)
+ goto cleanup;
+ }
+ }
+
+ *mech_set = mechs;
+ mechs = GSS_C_NO_OID_SET;
+
+cleanup:
+ (void) gss_release_buffer(&tmpmin, &name_buffer);
+ (void) gss_release_oid_set(&tmpmin, &all_mechs);
+ (void) gss_release_oid_set(&tmpmin, &mechs);
+ return (status);
+}
diff --git a/src/lib/gssapi/mechglue/g_map_name_to_any.c b/src/lib/gssapi/mechglue/g_map_name_to_any.c
new file mode 100644
index 000000000000..ebf49450f062
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_map_name_to_any.c
@@ -0,0 +1,76 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2009 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/* Glue routine for gss_map_name_to_any */
+
+#include "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_map_name_to_any(OM_uint32 *minor_status,
+ gss_name_t name,
+ int authenticated,
+ gss_buffer_t type_id,
+ gss_any_t *output)
+{
+ OM_uint32 status;
+ gss_union_name_t union_name;
+ gss_mechanism mech;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (name == GSS_C_NO_NAME)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME;
+
+ if (type_id == GSS_C_NO_BUFFER)
+ return GSS_S_CALL_INACCESSIBLE_READ;
+
+ if (output == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ *minor_status = 0;
+
+ union_name = (gss_union_name_t)name;
+
+ if (union_name->mech_type == GSS_C_NO_OID)
+ return GSS_S_UNAVAILABLE;
+
+ mech = gssint_get_mechanism(name->mech_type);
+ if (mech == NULL)
+ return GSS_S_BAD_NAME;
+
+ if (mech->gss_map_name_to_any == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ status = (*mech->gss_map_name_to_any)(minor_status,
+ union_name->mech_name,
+ authenticated,
+ type_id,
+ output);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+
+ return status;
+}
diff --git a/src/lib/gssapi/mechglue/g_mech_invoke.c b/src/lib/gssapi/mechglue/g_mech_invoke.c
new file mode 100644
index 000000000000..0647cda96945
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_mech_invoke.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2008 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/* Glue routine for gssspi_mech_invoke */
+
+#include "mglueP.h"
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+OM_uint32 KRB5_CALLCONV
+gssspi_mech_invoke (OM_uint32 *minor_status,
+ const gss_OID desired_mech,
+ const gss_OID desired_object,
+ gss_buffer_t value)
+{
+ OM_uint32 status;
+ gss_OID selected_mech = GSS_C_NO_OID;
+ gss_mechanism mech;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ *minor_status = 0;
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ status = gssint_select_mech_type(minor_status, desired_mech,
+ &selected_mech);
+ if (status != GSS_S_COMPLETE)
+ return status;
+
+ mech = gssint_get_mechanism(selected_mech);
+ if (mech == NULL || mech->gssspi_mech_invoke == NULL) {
+ return GSS_S_BAD_MECH;
+ }
+
+ status = mech->gssspi_mech_invoke(minor_status,
+ gssint_get_public_oid(selected_mech),
+ desired_object,
+ value);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+
+ return status;
+}
diff --git a/src/lib/gssapi/mechglue/g_mechattr.c b/src/lib/gssapi/mechglue/g_mechattr.c
new file mode 100644
index 000000000000..e49651eb6ade
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_mechattr.c
@@ -0,0 +1,222 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/gssapi/mechglue/g_mechattr.c */
+/*
+ * Copyright (C) 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "mglueP.h"
+
+static int
+testMechAttr(gss_const_OID attr,
+ gss_const_OID_set against)
+{
+ int present = 0;
+ OM_uint32 minor;
+
+ if (GSS_ERROR(generic_gss_test_oid_set_member(&minor, attr,
+ (gss_OID_set)against,
+ &present)))
+ return 0;
+
+ return present;
+}
+
+/*
+ * Return TRUE iff all the elements of desired and none of the elements
+ * of except exist in available.
+ */
+static int
+testMechAttrsOffered(gss_const_OID_set desired,
+ gss_const_OID_set except,
+ gss_const_OID_set available)
+{
+ size_t i;
+
+ if (desired != GSS_C_NO_OID_SET) {
+ for (i = 0; i < desired->count; i++) {
+ if (!testMechAttr(&desired->elements[i], available))
+ return 0;
+ }
+ }
+
+ if (except != GSS_C_NO_OID_SET) {
+ for (i = 0; i < except->count; i++) {
+ if (testMechAttr(&except->elements[i], available))
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Return TRUE iff all the elements of critical exist in known.
+ */
+static int
+testMechAttrsKnown(gss_const_OID_set critical,
+ gss_const_OID_set known)
+{
+ size_t i;
+
+ if (critical != GSS_C_NO_OID_SET) {
+ for (i = 0; i < critical->count; i++) {
+ if (!testMechAttr(&critical->elements[i], known))
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_indicate_mechs_by_attrs(
+ OM_uint32 *minor,
+ gss_const_OID_set desired_mech_attrs,
+ gss_const_OID_set except_mech_attrs,
+ gss_const_OID_set critical_mech_attrs,
+ gss_OID_set *mechs)
+{
+ OM_uint32 status, tmpMinor;
+ gss_OID_set allMechs = GSS_C_NO_OID_SET;
+ size_t i;
+
+ if (minor == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ *minor = 0;
+
+ if (mechs == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ *mechs = GSS_C_NO_OID_SET;
+
+ status = gss_indicate_mechs(minor, &allMechs);
+ if (GSS_ERROR(status))
+ goto cleanup;
+
+ status = generic_gss_create_empty_oid_set(minor, mechs);
+ if (GSS_ERROR(status))
+ goto cleanup;
+
+ for (i = 0; i < allMechs->count; i++) {
+ gss_OID_set supportedAttrs = GSS_C_NO_OID_SET;
+ gss_OID_set knownAttrs = GSS_C_NO_OID_SET;
+
+ status = gss_inquire_attrs_for_mech(minor, &allMechs->elements[i],
+ &supportedAttrs, &knownAttrs);
+ if (GSS_ERROR(status))
+ continue;
+
+ if (testMechAttrsOffered(desired_mech_attrs,
+ except_mech_attrs, supportedAttrs) &&
+ testMechAttrsKnown(critical_mech_attrs, knownAttrs)) {
+ status = gss_add_oid_set_member(minor, &allMechs->elements[i],
+ mechs);
+ if (GSS_ERROR(status)) {
+ gss_release_oid_set(&tmpMinor, &supportedAttrs);
+ gss_release_oid_set(&tmpMinor, &knownAttrs);
+ goto cleanup;
+ }
+ }
+
+ gss_release_oid_set(&tmpMinor, &supportedAttrs);
+ gss_release_oid_set(&tmpMinor, &knownAttrs);
+ }
+
+ *minor = 0;
+ status = GSS_S_COMPLETE;
+
+cleanup:
+ gss_release_oid_set(&tmpMinor, &allMechs);
+
+ return status;
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_inquire_attrs_for_mech(
+ OM_uint32 *minor,
+ gss_const_OID mech_oid,
+ gss_OID_set *mech_attrs,
+ gss_OID_set *known_mech_attrs)
+{
+ OM_uint32 status, tmpMinor;
+ gss_OID selected_mech, public_mech;
+ gss_mechanism mech;
+
+ if (minor == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ *minor = 0;
+
+ if (mech_attrs != NULL)
+ *mech_attrs = GSS_C_NO_OID_SET;
+
+ if (known_mech_attrs != NULL)
+ *known_mech_attrs = GSS_C_NO_OID_SET;
+
+ status = gssint_select_mech_type(minor, mech_oid, &selected_mech);
+ if (status != GSS_S_COMPLETE)
+ return status;
+
+ mech = gssint_get_mechanism(selected_mech);
+ if (mech == NULL)
+ return GSS_S_BAD_MECH;
+
+ /* If the mech does not implement RFC 5587, return success with an empty
+ * mech_attrs and known_mech_attrs. */
+ if (mech->gss_inquire_attrs_for_mech == NULL)
+ return GSS_S_COMPLETE;
+
+ public_mech = gssint_get_public_oid(selected_mech);
+ status = mech->gss_inquire_attrs_for_mech(minor, public_mech, mech_attrs,
+ known_mech_attrs);
+ if (GSS_ERROR(status)) {
+ map_error(minor, mech);
+ return status;
+ }
+
+ if (known_mech_attrs != NULL && *known_mech_attrs == GSS_C_NO_OID_SET) {
+ status = generic_gss_copy_oid_set(minor,
+ gss_ma_known_attrs,
+ known_mech_attrs);
+ if (GSS_ERROR(status)) {
+ gss_release_oid_set(&tmpMinor, mech_attrs);
+ if (mech_attrs != NULL)
+ *mech_attrs = GSS_C_NO_OID_SET;
+ }
+ }
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_display_mech_attr(
+ OM_uint32 *minor,
+ gss_const_OID mech_attr,
+ gss_buffer_t name,
+ gss_buffer_t short_desc,
+ gss_buffer_t long_desc)
+{
+ return generic_gss_display_mech_attr(minor, mech_attr,
+ name, short_desc, long_desc);
+}
diff --git a/src/lib/gssapi/mechglue/g_mechname.c b/src/lib/gssapi/mechglue/g_mechname.c
new file mode 100644
index 000000000000..cfb0a0d2af8e
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_mechname.c
@@ -0,0 +1,116 @@
+/*
+ * g_mechname.c --- registry of mechanism-specific name types
+ *
+ * This file contains a registry of mechanism-specific name types. It
+ * is used to determine which name types not should be lazy evaluated,
+ * but rather evaluated on the spot.
+ */
+
+#include "mglueP.h"
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+static gss_mech_spec_name name_list = NULL;
+
+/*
+ * generic searching helper function.
+ */
+static gss_mech_spec_name search_mech_spec(name_type)
+ gss_OID name_type;
+{
+ gss_mech_spec_name p;
+
+ for (p = name_list; p; p = p->next) {
+ if (g_OID_equal(name_type, p->name_type))
+ return p;
+ }
+ return NULL;
+}
+
+/*
+ * Given a name_type, if it is specific to a mechanism, return the
+ * mechanism OID. Otherwise, return NULL.
+ */
+gss_OID gss_find_mechanism_from_name_type(name_type)
+ gss_OID name_type;
+{
+ gss_mech_spec_name p;
+
+ p = search_mech_spec(name_type);
+ if (!p)
+ return NULL;
+ return p->mech;
+}
+
+/*
+ * This function adds a (name_type, mechanism) pair to the
+ * mechanism-specific name type registry. If an entry for the
+ * name_type already exists, then zero out the mechanism entry.
+ * Otherwise, enter the pair into the registry.
+ */
+OM_uint32
+gss_add_mech_name_type(minor_status, name_type, mech)
+ OM_uint32 *minor_status;
+ gss_OID name_type;
+ gss_OID mech;
+{
+ OM_uint32 major_status, tmp;
+ gss_mech_spec_name p;
+
+ p = search_mech_spec(name_type);
+ if (p) {
+ /*
+ * We found an entry for this name type; mark it as not being
+ * a mechanism-specific name type.
+ */
+ if (p->mech) {
+ if (!g_OID_equal(mech, p->mech)) {
+ generic_gss_release_oid(minor_status, &p->mech);
+ p->mech = 0;
+ }
+ }
+ return GSS_S_COMPLETE;
+ }
+ p = malloc(sizeof(gss_mech_spec_name_desc));
+ if (!p) {
+ *minor_status = ENOMEM;
+ map_errcode(minor_status);
+ goto allocation_failure;
+ }
+ p->name_type = 0;
+ p->mech = 0;
+
+ major_status = generic_gss_copy_oid(minor_status, name_type,
+ &p->name_type);
+ if (major_status) {
+ map_errcode(minor_status);
+ goto allocation_failure;
+ }
+ major_status = generic_gss_copy_oid(minor_status, mech,
+ &p->mech);
+ if (major_status) {
+ map_errcode(minor_status);
+ goto allocation_failure;
+ }
+
+ p->next = name_list;
+ p->prev = 0;
+ name_list = p;
+
+ return GSS_S_COMPLETE;
+
+allocation_failure:
+ if (p) {
+ if (p->mech)
+ generic_gss_release_oid(&tmp, &p->mech);
+ if (p->name_type)
+ generic_gss_release_oid(&tmp, &p->name_type);
+ free(p);
+ }
+ return GSS_S_FAILURE;
+}
diff --git a/src/lib/gssapi/mechglue/g_oid_ops.c b/src/lib/gssapi/mechglue/g_oid_ops.c
new file mode 100644
index 000000000000..1d75c63e69d7
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_oid_ops.c
@@ -0,0 +1,112 @@
+/* #pragma ident "@(#)g_oid_ops.c 1.11 98/01/22 SMI" */
+/* lib/gssapi/mechglue/g_oid_ops.c - GSSAPI V2 interfaces to manipulate OIDs */
+/*
+ * Copyright 1995, 2007 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "mglueP.h"
+
+/*
+ * gss_release_oid has been moved to g_initialize, becasue it requires access
+ * to the mechanism list. All functions requiring direct access to the
+ * mechanism list are now in g_initialize.c
+ */
+
+OM_uint32 KRB5_CALLCONV
+gss_create_empty_oid_set(minor_status, oid_set)
+ OM_uint32 *minor_status;
+ gss_OID_set *oid_set;
+{
+ OM_uint32 status;
+ status = generic_gss_create_empty_oid_set(minor_status, oid_set);
+ if (status != GSS_S_COMPLETE)
+ map_errcode(minor_status);
+ return status;
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_add_oid_set_member(minor_status, member_oid, oid_set)
+ OM_uint32 *minor_status;
+ gss_OID member_oid;
+ gss_OID_set *oid_set;
+{
+ OM_uint32 status;
+ status = generic_gss_add_oid_set_member(minor_status, member_oid, oid_set);
+ if (status != GSS_S_COMPLETE)
+ map_errcode(minor_status);
+ return status;
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_test_oid_set_member(minor_status, member, set, present)
+ OM_uint32 *minor_status;
+ gss_OID member;
+ gss_OID_set set;
+ int *present;
+{
+ return generic_gss_test_oid_set_member(minor_status, member, set, present);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_oid_to_str(minor_status, oid, oid_str)
+ OM_uint32 *minor_status;
+ gss_OID oid;
+ gss_buffer_t oid_str;
+{
+ OM_uint32 status = generic_gss_oid_to_str(minor_status, oid, oid_str);
+ if (status != GSS_S_COMPLETE)
+ map_errcode(minor_status);
+ return status;
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_str_to_oid(minor_status, oid_str, oid)
+ OM_uint32 *minor_status;
+ gss_buffer_t oid_str;
+ gss_OID *oid;
+{
+ OM_uint32 status = generic_gss_str_to_oid(minor_status, oid_str, oid);
+ if (status != GSS_S_COMPLETE)
+ map_errcode(minor_status);
+ return status;
+}
+
+OM_uint32
+gssint_copy_oid_set(
+ OM_uint32 *minor_status,
+ const gss_OID_set_desc * const oidset,
+ gss_OID_set *new_oidset)
+{
+ return generic_gss_copy_oid_set(minor_status, oidset, new_oidset);
+}
+
+int KRB5_CALLCONV
+gss_oid_equal(
+ gss_const_OID first_oid,
+ gss_const_OID second_oid)
+{
+ /* GSS_C_NO_OID doesn't match itself, per draft-josefsson-gss-capsulate. */
+ if (first_oid == GSS_C_NO_OID || second_oid == GSS_C_NO_OID)
+ return 0;
+ return g_OID_equal(first_oid, second_oid);
+}
diff --git a/src/lib/gssapi/mechglue/g_prf.c b/src/lib/gssapi/mechglue/g_prf.c
new file mode 100644
index 000000000000..fcca3e44c4c0
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_prf.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2009 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/* Glue routine for gss_pseudo_random */
+
+#include "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_pseudo_random (OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int prf_key,
+ const gss_buffer_t prf_in,
+ ssize_t desired_output_len,
+ gss_buffer_t prf_out)
+{
+ OM_uint32 status;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT;
+
+ if (prf_in == GSS_C_NO_BUFFER)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT;
+
+ if (prf_out == GSS_C_NO_BUFFER)
+ return GSS_S_CALL_INACCESSIBLE_WRITE | GSS_S_NO_CONTEXT;
+
+ prf_out->length = 0;
+ prf_out->value = NULL;
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+
+ if (mech != NULL) {
+ if (mech->gss_pseudo_random != NULL) {
+ status = mech->gss_pseudo_random(minor_status,
+ ctx->internal_ctx_id,
+ prf_key,
+ prf_in,
+ desired_output_len,
+ prf_out);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return status;
+ }
+
+ return GSS_S_BAD_MECH;
+}
diff --git a/src/lib/gssapi/mechglue/g_process_context.c b/src/lib/gssapi/mechglue/g_process_context.c
new file mode 100644
index 000000000000..bc260aeb10b2
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_process_context.c
@@ -0,0 +1,82 @@
+/* #pragma ident "@(#)g_process_context.c 1.12 98/01/22 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine gss_process_context
+ */
+
+#include "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+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;
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
+
+ if (token_buffer == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ if (GSS_EMPTY_BUFFER(token_buffer))
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+
+ if (mech) {
+
+ if (mech->gss_process_context_token) {
+ status = mech->gss_process_context_token(
+ minor_status,
+ ctx->internal_ctx_id,
+ token_buffer);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return(status);
+ }
+
+ return (GSS_S_BAD_MECH);
+}
diff --git a/src/lib/gssapi/mechglue/g_rel_buffer.c b/src/lib/gssapi/mechglue/g_rel_buffer.c
new file mode 100644
index 000000000000..8c3328acc5a6
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_rel_buffer.c
@@ -0,0 +1,58 @@
+/* #ident "@(#)g_rel_buffer.c 1.2 96/02/06 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_release_buffer
+ */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+OM_uint32 KRB5_CALLCONV
+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)) {
+ gssalloc_free(buffer->value);
+ buffer->length = 0;
+ buffer->value = NULL;
+ }
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/mechglue/g_rel_cred.c b/src/lib/gssapi/mechglue/g_rel_cred.c
new file mode 100644
index 000000000000..ccdee05a5625
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_rel_cred.c
@@ -0,0 +1,99 @@
+/* #pragma ident "@(#)g_rel_cred.c 1.14 04/02/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* Glue routine for gss_release_cred */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+OM_uint32 KRB5_CALLCONV
+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;
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ *minor_status = 0;
+
+ if (cred_handle == NULL)
+ return (GSS_S_NO_CRED | GSS_S_CALL_INACCESSIBLE_READ);
+
+ /*
+ * 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;
+ if (union_cred == (gss_union_cred_t)GSS_C_NO_CREDENTIAL)
+ return (GSS_S_COMPLETE);
+
+ if (GSSINT_CHK_LOOP(union_cred))
+ return (GSS_S_NO_CRED | GSS_S_CALL_INACCESSIBLE_READ);
+ *cred_handle = NULL;
+
+ status = GSS_S_COMPLETE;
+
+ for(j=0; j < union_cred->count; j++) {
+
+ mech = gssint_get_mechanism (&union_cred->mechs_array[j]);
+
+ if (union_cred->mechs_array[j].elements)
+ free(union_cred->mechs_array[j].elements);
+ if (mech) {
+ if (mech->gss_release_cred) {
+ temp_status = mech->gss_release_cred
+ (
+ minor_status,
+ &union_cred->cred_array[j]);
+
+ if (temp_status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ status = GSS_S_NO_CRED;
+ }
+
+ } else
+ status = GSS_S_UNAVAILABLE;
+ } else
+ status = GSS_S_DEFECTIVE_CREDENTIAL;
+ }
+
+ free(union_cred->cred_array);
+ free(union_cred->mechs_array);
+ free(union_cred);
+
+ return(status);
+}
diff --git a/src/lib/gssapi/mechglue/g_rel_name.c b/src/lib/gssapi/mechglue/g_rel_name.c
new file mode 100644
index 000000000000..e00869238323
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_rel_name.c
@@ -0,0 +1,86 @@
+/* #pragma ident "@(#)g_rel_name.c 1.11 04/02/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_release_name
+ */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+
+OM_uint32 KRB5_CALLCONV
+gss_release_name (minor_status,
+ input_name)
+
+OM_uint32 * minor_status;
+gss_name_t * input_name;
+
+{
+ gss_union_name_t union_name;
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+ *minor_status = 0;
+
+ /* if input_name is NULL, return error */
+ if (input_name == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
+
+ if (*input_name == GSS_C_NO_NAME)
+ return GSS_S_COMPLETE;
+
+ /*
+ * free up the space for the external_name and then
+ * free the union_name descriptor
+ */
+
+ union_name = (gss_union_name_t) *input_name;
+ if (GSSINT_CHK_LOOP(union_name))
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME);
+ *input_name = 0;
+ *minor_status = 0;
+
+ if (union_name->name_type != GSS_C_NO_OID)
+ gss_release_oid(minor_status, &union_name->name_type);
+
+ if (union_name->external_name != GSS_C_NO_BUFFER) {
+ if (union_name->external_name->value != NULL)
+ gssalloc_free(union_name->external_name->value);
+ free(union_name->external_name);
+ }
+
+ if (union_name->mech_type) {
+ gssint_release_internal_name(minor_status, union_name->mech_type,
+ &union_name->mech_name);
+ gss_release_oid(minor_status, &union_name->mech_type);
+ }
+
+ free(union_name);
+
+ return(GSS_S_COMPLETE);
+}
diff --git a/src/lib/gssapi/mechglue/g_rel_name_mapping.c b/src/lib/gssapi/mechglue/g_rel_name_mapping.c
new file mode 100644
index 000000000000..f09136afee74
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_rel_name_mapping.c
@@ -0,0 +1,74 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2009 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/* Glue routine for gss_release_any_name_mapping */
+
+#include "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_release_any_name_mapping(OM_uint32 *minor_status,
+ gss_name_t name,
+ gss_buffer_t type_id,
+ gss_any_t *input)
+{
+ OM_uint32 status;
+ gss_union_name_t union_name;
+ gss_mechanism mech;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (name == GSS_C_NO_NAME)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME;
+
+ if (type_id == GSS_C_NO_BUFFER)
+ return GSS_S_CALL_INACCESSIBLE_READ;
+
+ if (input == NULL)
+ return GSS_S_CALL_INACCESSIBLE_READ;
+
+ *minor_status = 0;
+
+ union_name = (gss_union_name_t)name;
+
+ if (union_name->mech_type == GSS_C_NO_OID)
+ return GSS_S_UNAVAILABLE;
+
+ mech = gssint_get_mechanism(name->mech_type);
+ if (mech == NULL)
+ return GSS_S_BAD_NAME;
+
+ if (mech->gss_release_any_name_mapping == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ status = (*mech->gss_release_any_name_mapping)(minor_status,
+ union_name->mech_name,
+ type_id,
+ input);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+
+ return status;
+}
diff --git a/src/lib/gssapi/mechglue/g_rel_oid_set.c b/src/lib/gssapi/mechglue/g_rel_oid_set.c
new file mode 100644
index 000000000000..fa008d6bb9bb
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_rel_oid_set.c
@@ -0,0 +1,43 @@
+/* #pragma ident "@(#)g_rel_oid_set.c 1.12 97/11/11 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_release_oid_set
+ */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+OM_uint32 KRB5_CALLCONV
+gss_release_oid_set (minor_status,
+ set)
+
+OM_uint32 * minor_status;
+gss_OID_set * set;
+{
+ return generic_gss_release_oid_set(minor_status, set);
+}
diff --git a/src/lib/gssapi/mechglue/g_saslname.c b/src/lib/gssapi/mechglue/g_saslname.c
new file mode 100644
index 000000000000..48060c367172
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_saslname.c
@@ -0,0 +1,220 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/gssapi/mechglue/g_saslname.c */
+/*
+ * Copyright (C) 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "mglueP.h"
+#include <krb5/krb5.h>
+
+static char basis_32[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
+
+#define OID_SASL_NAME_LENGTH (sizeof("GS2-XXXXXXXXXXX") - 1)
+
+static OM_uint32
+oidToSaslName(OM_uint32 *minor, const gss_OID mech,
+ char sasl_name[OID_SASL_NAME_LENGTH + 1])
+{
+ unsigned char derBuf[2];
+ krb5_crypto_iov iov[3];
+ unsigned char cksumBuf[20], *q = cksumBuf;
+ char *p = sasl_name;
+
+ if (mech->length > 127) {
+ *minor = ERANGE;
+ return GSS_S_BAD_MECH;
+ }
+
+ derBuf[0] = 0x06;
+ derBuf[1] = (unsigned char)mech->length;
+
+ iov[0].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+ iov[0].data.length = 2;
+ iov[0].data.data = (char *)derBuf;
+ iov[1].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+ iov[1].data.length = mech->length;
+ iov[1].data.data = (char *)mech->elements;
+ iov[2].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
+ iov[2].data.length = sizeof(cksumBuf);
+ iov[2].data.data = (char *)cksumBuf;
+
+ *minor = krb5_k_make_checksum_iov(NULL, CKSUMTYPE_NIST_SHA,
+ NULL, 0, iov, 3);
+ if (*minor != 0)
+ return GSS_S_FAILURE;
+
+ memcpy(p, "GS2-", 4);
+ p += 4;
+
+ *p++ = basis_32[q[0] >> 3];
+ *p++ = basis_32[((q[0] & 7) << 2) | (q[1] >> 6)];
+ *p++ = basis_32[(q[1] & 0x3f) >> 1];
+ *p++ = basis_32[((q[1] & 1) << 4) | (q[2] >> 4)];
+ *p++ = basis_32[((q[2] & 0xf) << 1) | (q[3] >> 7)];
+ *p++ = basis_32[(q[3] & 0x7f) >> 2];
+ *p++ = basis_32[((q[3] & 3) << 3) | (q[4] >> 5)];
+ *p++ = basis_32[(q[4] & 0x1f)];
+ *p++ = basis_32[q[5] >> 3];
+ *p++ = basis_32[((q[5] & 7) << 2) | (q[6] >> 6)];
+ *p++ = basis_32[(q[6] & 0x3f) >> 1];
+
+ *p++ = '\0';
+
+ *minor = 0;
+ return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+oidToSaslNameAlloc(OM_uint32 *minor, const gss_OID mech,
+ gss_buffer_t sasl_name)
+{
+ OM_uint32 status, tmpMinor;
+
+ sasl_name->value = malloc(OID_SASL_NAME_LENGTH + 1);
+ if (sasl_name->value == NULL) {
+ *minor = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ sasl_name->length = OID_SASL_NAME_LENGTH;
+
+ status = oidToSaslName(minor, mech, (char *)sasl_name->value);
+ if (GSS_ERROR(status)) {
+ gss_release_buffer(&tmpMinor, sasl_name);
+ return status;
+ }
+
+ return GSS_S_COMPLETE;
+}
+
+OM_uint32 KRB5_CALLCONV gss_inquire_saslname_for_mech(
+ OM_uint32 *minor_status,
+ const gss_OID desired_mech,
+ gss_buffer_t sasl_mech_name,
+ gss_buffer_t mech_name,
+ gss_buffer_t mech_description)
+{
+ OM_uint32 status;
+ gss_OID selected_mech, public_mech;
+ gss_mechanism mech;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ *minor_status = 0;
+
+ if (sasl_mech_name != GSS_C_NO_BUFFER) {
+ sasl_mech_name->length = 0;
+ sasl_mech_name->value = NULL;
+ }
+
+ if (mech_name != GSS_C_NO_BUFFER) {
+ mech_name->length = 0;
+ mech_name->value = NULL;
+ }
+
+ if (mech_description != GSS_C_NO_BUFFER) {
+ mech_description->length = 0;
+ mech_description->value = NULL;
+ }
+
+ status = gssint_select_mech_type(minor_status, desired_mech,
+ &selected_mech);
+ if (status != GSS_S_COMPLETE)
+ return status;
+
+ mech = gssint_get_mechanism(desired_mech);
+ if (mech == NULL) {
+ return GSS_S_BAD_MECH;
+ } else if (mech->gss_inquire_saslname_for_mech == NULL) {
+ status = GSS_S_UNAVAILABLE;
+ } else {
+ public_mech = gssint_get_public_oid(selected_mech);
+ status = mech->gss_inquire_saslname_for_mech(minor_status, public_mech,
+ sasl_mech_name, mech_name,
+ mech_description);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ }
+
+ if (status == GSS_S_UNAVAILABLE) {
+ if (sasl_mech_name != GSS_C_NO_BUFFER)
+ status = oidToSaslNameAlloc(minor_status, desired_mech,
+ sasl_mech_name);
+ else
+ status = GSS_S_COMPLETE;
+ }
+
+ return status;
+}
+
+/* We cannot interpose this function as mech_type is an output parameter. */
+OM_uint32 KRB5_CALLCONV gss_inquire_mech_for_saslname(
+ OM_uint32 *minor_status,
+ const gss_buffer_t sasl_mech_name,
+ gss_OID *mech_type)
+{
+ OM_uint32 status, tmpMinor;
+ gss_OID_set mechSet = GSS_C_NO_OID_SET;
+ size_t i;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ *minor_status = 0;
+
+ if (mech_type != NULL)
+ *mech_type = GSS_C_NO_OID;
+
+ status = gss_indicate_mechs(minor_status, &mechSet);
+ if (status != GSS_S_COMPLETE)
+ return status;
+
+ for (i = 0, status = GSS_S_BAD_MECH; i < mechSet->count; i++) {
+ gss_mechanism mech;
+ char mappedName[OID_SASL_NAME_LENGTH + 1];
+
+ mech = gssint_get_mechanism(&mechSet->elements[i]);
+ if (mech != NULL && mech->gss_inquire_mech_for_saslname != NULL) {
+ status = mech->gss_inquire_mech_for_saslname(minor_status,
+ sasl_mech_name,
+ mech_type);
+ if (status == GSS_S_COMPLETE)
+ break;
+ }
+ if (status == GSS_S_BAD_MECH &&
+ sasl_mech_name->length == OID_SASL_NAME_LENGTH &&
+ oidToSaslName(&tmpMinor, &mechSet->elements[i],
+ mappedName) == GSS_S_COMPLETE &&
+ memcmp(sasl_mech_name->value, mappedName,
+ OID_SASL_NAME_LENGTH) == 0) {
+ if (mech_type != NULL)
+ *mech_type = &mech->mech_type;
+ status = GSS_S_COMPLETE;
+ break;
+ }
+ }
+
+ gss_release_oid_set(&tmpMinor, &mechSet);
+
+ return status;
+}
diff --git a/src/lib/gssapi/mechglue/g_seal.c b/src/lib/gssapi/mechglue/g_seal.c
new file mode 100644
index 000000000000..f17241c90891
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_seal.c
@@ -0,0 +1,249 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_wrap
+ */
+
+#include "mglueP.h"
+
+static OM_uint32
+val_wrap_args(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ gss_buffer_t input_message_buffer,
+ int *conf_state,
+ gss_buffer_t output_message_buffer)
+{
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (output_message_buffer != GSS_C_NO_BUFFER) {
+ output_message_buffer->length = 0;
+ output_message_buffer->value = NULL;
+ }
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
+
+ if (input_message_buffer == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ if (output_message_buffer == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ return (GSS_S_COMPLETE);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_wrap( OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ gss_buffer_t input_message_buffer,
+ int *conf_state,
+ gss_buffer_t output_message_buffer)
+{
+
+ /* EXPORT DELETE START */
+
+ OM_uint32 status;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+
+ status = val_wrap_args(minor_status, context_handle,
+ conf_req_flag, qop_req,
+ input_message_buffer, conf_state,
+ output_message_buffer);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+
+ if (mech) {
+ if (mech->gss_wrap) {
+ status = mech->gss_wrap(minor_status,
+ ctx->internal_ctx_id,
+ conf_req_flag,
+ qop_req,
+ input_message_buffer,
+ conf_state,
+ output_message_buffer);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else if (mech->gss_wrap_aead ||
+ (mech->gss_wrap_iov && mech->gss_wrap_iov_length)) {
+ status = gssint_wrap_aead(mech,
+ minor_status,
+ ctx,
+ conf_req_flag,
+ (gss_qop_t)qop_req,
+ GSS_C_NO_BUFFER,
+ input_message_buffer,
+ conf_state,
+ output_message_buffer);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return(status);
+ }
+ /* EXPORT DELETE END */
+
+ return (GSS_S_BAD_MECH);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_seal(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)
+{
+
+ return gss_wrap(minor_status, context_handle,
+ conf_req_flag, (gss_qop_t) qop_req,
+ input_message_buffer, conf_state,
+ output_message_buffer);
+}
+
+/*
+ * It is only possible to implement gss_wrap_size_limit() on top
+ * of gss_wrap_iov_length() for mechanisms that do not use any
+ * padding and have fixed length headers/trailers.
+ */
+static OM_uint32
+gssint_wrap_size_limit_iov_shim(gss_mechanism mech,
+ OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ OM_uint32 req_output_size,
+ OM_uint32 *max_input_size)
+{
+ gss_iov_buffer_desc iov[4];
+ OM_uint32 status;
+ OM_uint32 ohlen;
+
+ iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
+ iov[0].buffer.value = NULL;
+ iov[0].buffer.length = 0;
+
+ iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
+ iov[1].buffer.length = req_output_size;
+ iov[1].buffer.value = NULL;
+
+ iov[2].type = GSS_IOV_BUFFER_TYPE_PADDING;
+ iov[2].buffer.value = NULL;
+ iov[2].buffer.length = 0;
+
+ iov[3].type = GSS_IOV_BUFFER_TYPE_TRAILER;
+ iov[3].buffer.value = NULL;
+ iov[3].buffer.length = 0;
+
+ assert(mech->gss_wrap_iov_length);
+
+ status = mech->gss_wrap_iov_length(minor_status, context_handle,
+ conf_req_flag, qop_req,
+ NULL, iov,
+ sizeof(iov)/sizeof(iov[0]));
+ if (status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ return status;
+ }
+
+ ohlen = iov[0].buffer.length + iov[3].buffer.length;
+
+ if (iov[2].buffer.length == 0 && ohlen < req_output_size)
+ *max_input_size = req_output_size - ohlen;
+ else
+ *max_input_size = 0;
+
+ return GSS_S_COMPLETE;
+}
+
+/*
+ * New for V2
+ */
+OM_uint32 KRB5_CALLCONV
+gss_wrap_size_limit(OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req, OM_uint32 req_output_size, OM_uint32 *max_input_size)
+{
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+ OM_uint32 major_status;
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
+
+ if (max_input_size == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+
+ if (!mech)
+ return (GSS_S_BAD_MECH);
+
+ if (mech->gss_wrap_size_limit)
+ major_status = mech->gss_wrap_size_limit(minor_status,
+ ctx->internal_ctx_id,
+ conf_req_flag, qop_req,
+ req_output_size, max_input_size);
+ else if (mech->gss_wrap_iov_length)
+ major_status = gssint_wrap_size_limit_iov_shim(mech, minor_status,
+ ctx->internal_ctx_id,
+ conf_req_flag, qop_req,
+ req_output_size, max_input_size);
+ else
+ major_status = GSS_S_UNAVAILABLE;
+ if (major_status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ return major_status;
+}
diff --git a/src/lib/gssapi/mechglue/g_set_context_option.c b/src/lib/gssapi/mechglue/g_set_context_option.c
new file mode 100644
index 000000000000..87db240df3db
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_set_context_option.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2008 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/* Glue routine for gss_set_sec_context_option */
+
+#include "mglueP.h"
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+OM_uint32 KRB5_CALLCONV
+gss_set_sec_context_option (OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ const gss_OID desired_object,
+ const gss_buffer_t value)
+{
+ OM_uint32 status, minor;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+ gss_ctx_id_t internal_ctx = GSS_C_NO_CONTEXT;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (context_handle == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ *minor_status = 0;
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) *context_handle;
+ if (ctx == NULL) {
+ mech = gssint_get_mechanism (GSS_C_NO_OID);
+ } else {
+ mech = gssint_get_mechanism (ctx->mech_type);
+ }
+
+ if (mech == NULL)
+ return GSS_S_BAD_MECH;
+ if (mech->gss_set_sec_context_option == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ status = mech->gss_set_sec_context_option(minor_status,
+ ctx ? &ctx->internal_ctx_id :
+ &internal_ctx,
+ desired_object,
+ value);
+ if (status == GSS_S_COMPLETE) {
+ if (ctx == NULL && internal_ctx != GSS_C_NO_CONTEXT) {
+ /* Allocate a union context handle to wrap new context */
+ ctx = (gss_union_ctx_id_t)malloc(sizeof(*ctx));
+ if (ctx == NULL) {
+ *minor_status = ENOMEM;
+ gssint_delete_internal_sec_context(&minor,
+ &mech->mech_type,
+ &internal_ctx,
+ GSS_C_NO_BUFFER);
+ return GSS_S_FAILURE;
+ }
+
+ status = generic_gss_copy_oid(minor_status,
+ &mech->mech_type,
+ &ctx->mech_type);
+ if (status != GSS_S_COMPLETE) {
+ gssint_delete_internal_sec_context(&minor,
+ ctx->mech_type,
+ &internal_ctx,
+ GSS_C_NO_BUFFER);
+ free(ctx);
+ return status;
+ }
+
+ ctx->internal_ctx_id = internal_ctx;
+ *context_handle = (gss_ctx_id_t)ctx;
+ }
+ } else
+ map_error(minor_status, mech);
+
+ return status;
+}
diff --git a/src/lib/gssapi/mechglue/g_set_cred_option.c b/src/lib/gssapi/mechglue/g_set_cred_option.c
new file mode 100644
index 000000000000..90e5756e5199
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_set_cred_option.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2008-2010 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/* Glue routine for gssspi_set_cred_option */
+
+#include "mglueP.h"
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <time.h>
+
+static OM_uint32
+alloc_union_cred(OM_uint32 *minor_status,
+ gss_mechanism mech,
+ gss_cred_id_t mech_cred,
+ gss_union_cred_t *pcred)
+{
+ OM_uint32 status;
+ OM_uint32 temp_minor_status;
+ gss_union_cred_t cred = NULL;
+
+ *pcred = NULL;
+
+ status = GSS_S_FAILURE;
+
+ cred = calloc(1, sizeof(*cred));
+ if (cred == NULL) {
+ *minor_status = ENOMEM;
+ goto cleanup;
+ }
+
+ cred->loopback = cred;
+ cred->count = 1;
+
+ cred->cred_array = calloc(cred->count, sizeof(gss_cred_id_t));
+ if (cred->cred_array == NULL) {
+ *minor_status = ENOMEM;
+ goto cleanup;
+ }
+ cred->cred_array[0] = mech_cred;
+
+ status = generic_gss_copy_oid(minor_status,
+ &mech->mech_type,
+ &cred->mechs_array);
+ if (status != GSS_S_COMPLETE)
+ goto cleanup;
+
+ status = GSS_S_COMPLETE;
+ *pcred = cred;
+
+cleanup:
+ if (status != GSS_S_COMPLETE)
+ gss_release_cred(&temp_minor_status, (gss_cred_id_t *)&cred);
+
+ return status;
+}
+
+/*
+ * This differs from gssspi_set_cred_option() as shipped in 1.7, in that
+ * it can return a cred handle. To denote this change we have changed the
+ * name of the function from gssspi_set_cred_option() to gss_set_cred_option().
+ * However, the dlsym() entry point is still gssspi_set_cred_option(). This
+ * fixes a separate issue, namely that a dynamically loaded mechanism could
+ * not itself call set_cred_option() without calling its own implementation
+ * instead of the mechanism glue's. (This is useful where a mechanism wishes
+ * to export a mechanism-specific API that is a wrapper around this function.)
+ */
+OM_uint32 KRB5_CALLCONV
+gss_set_cred_option(OM_uint32 *minor_status,
+ gss_cred_id_t *cred_handle,
+ const gss_OID desired_object,
+ const gss_buffer_t value)
+{
+ gss_union_cred_t union_cred;
+ gss_mechanism mech;
+ int i;
+ OM_uint32 status;
+ OM_uint32 mech_status;
+ OM_uint32 mech_minor_status;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (cred_handle == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ *minor_status = 0;
+
+ status = GSS_S_UNAVAILABLE;
+
+ if (*cred_handle == GSS_C_NO_CREDENTIAL) {
+ gss_cred_id_t mech_cred = GSS_C_NO_CREDENTIAL;
+
+ /*
+ * We need to give a mechanism the opportunity to allocate a
+ * credentials handle. Unfortunately this does mean that only
+ * the default mechanism can allocate a credentials handle.
+ */
+ mech = gssint_get_mechanism(NULL);
+ if (mech == NULL)
+ return GSS_S_BAD_MECH;
+
+ if (mech->gssspi_set_cred_option == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ status = mech->gssspi_set_cred_option(minor_status,
+ &mech_cred,
+ desired_object,
+ value);
+ if (status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ return status;
+ }
+
+ if (mech_cred != GSS_C_NO_CREDENTIAL) {
+ status = alloc_union_cred(minor_status,
+ mech,
+ mech_cred,
+ &union_cred);
+ if (status != GSS_S_COMPLETE)
+ return status;
+ *cred_handle = (gss_cred_id_t)union_cred;
+ }
+ } else {
+ union_cred = (gss_union_cred_t)*cred_handle;
+
+ for (i = 0; i < union_cred->count; i++) {
+ mech = gssint_get_mechanism(&union_cred->mechs_array[i]);
+ if (mech == NULL) {
+ status = GSS_S_BAD_MECH;
+ break;
+ }
+
+ if (mech->gssspi_set_cred_option == NULL)
+ continue;
+
+ mech_status = mech->gssspi_set_cred_option(&mech_minor_status,
+ &union_cred->cred_array[i],
+ desired_object,
+ value);
+ if (mech_status == GSS_S_UNAVAILABLE)
+ continue;
+ else {
+ status = mech_status;
+ *minor_status = mech_minor_status;
+ }
+ if (status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ break;
+ }
+ }
+ }
+
+ return status;
+}
+
+/*
+ * Provide this for backward ABI compatibility, but remove it from the
+ * header.
+ */
+OM_uint32 KRB5_CALLCONV
+gssspi_set_cred_option(OM_uint32 *minor_status,
+ gss_cred_id_t cred,
+ const gss_OID desired_object,
+ const gss_buffer_t value);
+
+OM_uint32 KRB5_CALLCONV
+gssspi_set_cred_option(OM_uint32 *minor_status,
+ gss_cred_id_t cred,
+ const gss_OID desired_object,
+ const gss_buffer_t value)
+{
+ return gss_set_cred_option(minor_status, &cred,
+ desired_object, value);
+}
diff --git a/src/lib/gssapi/mechglue/g_set_name_attr.c b/src/lib/gssapi/mechglue/g_set_name_attr.c
new file mode 100644
index 000000000000..a479762a7609
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_set_name_attr.c
@@ -0,0 +1,70 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2009 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/* Glue routine for gss_set_name_attribute */
+
+#include "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_set_name_attribute(OM_uint32 *minor_status,
+ gss_name_t name,
+ int complete,
+ gss_buffer_t attr,
+ gss_buffer_t value)
+{
+ OM_uint32 status;
+ gss_union_name_t union_name;
+ gss_mechanism mech;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (name == GSS_C_NO_NAME)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME;
+
+ *minor_status = 0;
+
+ union_name = (gss_union_name_t)name;
+
+ if (union_name->mech_type == GSS_C_NO_OID)
+ return GSS_S_UNAVAILABLE;
+
+ mech = gssint_get_mechanism(name->mech_type);
+ if (mech == NULL)
+ return GSS_S_BAD_NAME;
+
+ if (mech->gss_set_name_attribute == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ status = (*mech->gss_set_name_attribute)(minor_status,
+ union_name->mech_name,
+ complete,
+ attr,
+ value);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+
+ return status;
+}
diff --git a/src/lib/gssapi/mechglue/g_set_neg_mechs.c b/src/lib/gssapi/mechglue/g_set_neg_mechs.c
new file mode 100644
index 000000000000..69cac7037334
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_set_neg_mechs.c
@@ -0,0 +1,73 @@
+/* lib/gssapi/mechglue/g_set_neg_mechs.c - Glue for gss_set_neg_mechs */
+/*
+ * Copyright (C) 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_set_neg_mechs(OM_uint32 *minor_status,
+ gss_cred_id_t cred_handle,
+ const gss_OID_set mech_set)
+{
+ gss_union_cred_t union_cred;
+ gss_mechanism mech;
+ int i, avail;
+ OM_uint32 status;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (cred_handle == GSS_C_NO_CREDENTIAL)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CRED;
+
+ *minor_status = 0;
+
+ union_cred = (gss_union_cred_t) cred_handle;
+
+ avail = 0;
+ status = GSS_S_COMPLETE;
+ for (i = 0; i < union_cred->count; i++) {
+ mech = gssint_get_mechanism(&union_cred->mechs_array[i]);
+ if (mech == NULL) {
+ status = GSS_S_BAD_MECH;
+ break;
+ }
+
+ if (mech->gss_set_neg_mechs == NULL)
+ continue;
+
+ avail = 1;
+ status = (mech->gss_set_neg_mechs)(minor_status,
+ union_cred->cred_array[i],
+ mech_set);
+ if (status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ break;
+ }
+ }
+
+ if (status == GSS_S_COMPLETE && !avail)
+ return GSS_S_UNAVAILABLE;
+ return status;
+}
diff --git a/src/lib/gssapi/mechglue/g_sign.c b/src/lib/gssapi/mechglue/g_sign.c
new file mode 100644
index 000000000000..86d641aa2e28
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_sign.c
@@ -0,0 +1,134 @@
+/* #pragma ident "@(#)g_sign.c 1.14 98/04/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine gss_get_mic
+ */
+
+#include "mglueP.h"
+
+static OM_uint32
+val_get_mic_args(
+ OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ gss_qop_t qop_req,
+ gss_buffer_t message_buffer,
+ gss_buffer_t msg_token)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (msg_token != GSS_C_NO_BUFFER) {
+ msg_token->value = NULL;
+ msg_token->length = 0;
+ }
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
+
+ if (message_buffer == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ if (msg_token == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ return (GSS_S_COMPLETE);
+}
+
+
+OM_uint32 KRB5_CALLCONV
+gss_get_mic (minor_status,
+ context_handle,
+ qop_req,
+ message_buffer,
+ msg_token)
+
+OM_uint32 * minor_status;
+gss_ctx_id_t context_handle;
+gss_qop_t qop_req;
+gss_buffer_t message_buffer;
+gss_buffer_t msg_token;
+
+{
+ OM_uint32 status;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+
+ status = val_get_mic_args(minor_status, context_handle,
+ qop_req, message_buffer, msg_token);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+
+ if (mech) {
+ if (mech->gss_get_mic) {
+ status = mech->gss_get_mic(
+ minor_status,
+ ctx->internal_ctx_id,
+ qop_req,
+ message_buffer,
+ msg_token);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return(status);
+ }
+
+ return (GSS_S_BAD_MECH);
+}
+
+OM_uint32 KRB5_CALLCONV
+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;
+
+{
+ return (gss_get_mic(minor_status, context_handle, (gss_qop_t) qop_req,
+ message_buffer, msg_token));
+}
diff --git a/src/lib/gssapi/mechglue/g_store_cred.c b/src/lib/gssapi/mechglue/g_store_cred.c
new file mode 100644
index 000000000000..c2b6ddf3c0d0
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_store_cred.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* #pragma ident "@(#)g_store_cred.c 1.2 04/04/05 SMI" */
+
+/*
+ * glue routine for gss_store_cred
+ */
+
+#include <mglueP.h>
+
+static OM_uint32
+store_cred_fallback(
+ OM_uint32 *minor_status,
+ gss_mechanism mech,
+ gss_cred_id_t mech_cred,
+ gss_cred_usage_t cred_usage,
+ gss_OID desired_mech,
+ OM_uint32 overwrite_cred,
+ OM_uint32 default_cred,
+ gss_const_key_value_set_t cred_store,
+ gss_OID_set *elements_stored,
+ gss_cred_usage_t *cred_usage_stored)
+{
+ gss_OID public_mech = gssint_get_public_oid(desired_mech);
+
+ if (mech->gss_store_cred_into != NULL) {
+ return mech->gss_store_cred_into(minor_status, mech_cred,
+ cred_usage, public_mech,
+ overwrite_cred, default_cred,
+ cred_store, elements_stored,
+ cred_usage_stored);
+ } else if (cred_store == GSS_C_NO_CRED_STORE) {
+ return mech->gss_store_cred(minor_status, mech_cred,
+ cred_usage, public_mech,
+ overwrite_cred, default_cred,
+ elements_stored,
+ cred_usage_stored);
+ } else {
+ return GSS_S_UNAVAILABLE;
+ }
+}
+
+static OM_uint32
+val_store_cred_args(
+ OM_uint32 *minor_status,
+ const gss_cred_id_t input_cred_handle,
+ gss_cred_usage_t cred_usage,
+ const gss_OID desired_mech,
+ OM_uint32 overwrite_cred,
+ OM_uint32 default_cred,
+ gss_const_key_value_set_t cred_store,
+ gss_OID_set *elements_stored,
+ gss_cred_usage_t *cred_usage_stored)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (elements_stored != NULL)
+ *elements_stored = GSS_C_NULL_OID_SET;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (input_cred_handle == GSS_C_NO_CREDENTIAL)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CRED);
+
+ if (cred_usage != GSS_C_ACCEPT
+ && cred_usage != GSS_C_INITIATE
+ && cred_usage != GSS_C_BOTH) {
+ if (minor_status) {
+ *minor_status = EINVAL;
+ map_errcode(minor_status);
+ }
+ return GSS_S_FAILURE;
+ }
+
+ if (cred_store != NULL && cred_store->count == 0) {
+ *minor_status = EINVAL;
+ map_errcode(minor_status);
+ return GSS_S_FAILURE;
+ }
+
+ return (GSS_S_COMPLETE);
+}
+
+
+OM_uint32 KRB5_CALLCONV
+gss_store_cred(minor_status,
+ input_cred_handle,
+ cred_usage,
+ desired_mech,
+ overwrite_cred,
+ default_cred,
+ elements_stored,
+ cred_usage_stored)
+
+OM_uint32 *minor_status;
+gss_cred_id_t input_cred_handle;
+gss_cred_usage_t cred_usage;
+const gss_OID desired_mech;
+OM_uint32 overwrite_cred;
+OM_uint32 default_cred;
+gss_OID_set *elements_stored;
+gss_cred_usage_t *cred_usage_stored;
+
+{
+ return gss_store_cred_into(minor_status, input_cred_handle, cred_usage,
+ desired_mech, overwrite_cred, default_cred,
+ GSS_C_NO_CRED_STORE, elements_stored,
+ cred_usage_stored);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_store_cred_into(minor_status,
+ input_cred_handle,
+ cred_usage,
+ desired_mech,
+ overwrite_cred,
+ default_cred,
+ cred_store,
+ elements_stored,
+ cred_usage_stored)
+
+OM_uint32 *minor_status;
+gss_cred_id_t input_cred_handle;
+gss_cred_usage_t cred_usage;
+gss_OID desired_mech;
+OM_uint32 overwrite_cred;
+OM_uint32 default_cred;
+gss_const_key_value_set_t cred_store;
+gss_OID_set *elements_stored;
+gss_cred_usage_t *cred_usage_stored;
+
+{
+ OM_uint32 major_status = GSS_S_FAILURE;
+ gss_union_cred_t union_cred;
+ gss_cred_id_t mech_cred;
+ gss_mechanism mech;
+ gss_OID dmech;
+ gss_OID selected_mech;
+ int i;
+
+ major_status = val_store_cred_args(minor_status,
+ input_cred_handle,
+ cred_usage,
+ desired_mech,
+ overwrite_cred,
+ default_cred,
+ cred_store,
+ elements_stored,
+ cred_usage_stored);
+ if (major_status != GSS_S_COMPLETE)
+ return (major_status);
+
+ /* Initial value needed below. */
+ major_status = GSS_S_FAILURE;
+
+ if (cred_usage_stored != NULL)
+ *cred_usage_stored = GSS_C_BOTH; /* there's no GSS_C_NEITHER */
+
+ union_cred = (gss_union_cred_t)input_cred_handle;
+
+ /* desired_mech != GSS_C_NULL_OID -> store one element */
+ if (desired_mech != GSS_C_NULL_OID) {
+ major_status = gssint_select_mech_type(minor_status,
+ desired_mech,
+ &selected_mech);
+ if (major_status != GSS_S_COMPLETE)
+ return (major_status);
+
+ mech = gssint_get_mechanism(selected_mech);
+ if (mech == NULL)
+ return (GSS_S_BAD_MECH);
+
+ if (mech->gss_store_cred_into == NULL &&
+ cred_store != GSS_C_NO_CRED_STORE)
+ return (major_status);
+
+ if (mech->gss_store_cred == NULL &&
+ mech->gss_store_cred_into == NULL)
+ return (major_status);
+
+ mech_cred = gssint_get_mechanism_cred(union_cred, selected_mech);
+ if (mech_cred == GSS_C_NO_CREDENTIAL)
+ return (GSS_S_NO_CRED);
+
+ major_status = store_cred_fallback(minor_status, mech,
+ mech_cred, cred_usage,
+ selected_mech,
+ overwrite_cred,
+ default_cred, cred_store,
+ elements_stored,
+ cred_usage_stored);
+ if (major_status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ return major_status;
+ }
+
+ /* desired_mech == GSS_C_NULL_OID -> store all elements */
+
+ *minor_status = 0;
+
+ for (i = 0; i < union_cred->count; i++) {
+ /* Get mech and cred element */
+ dmech = &union_cred->mechs_array[i];
+ mech = gssint_get_mechanism(dmech);
+ if (mech == NULL)
+ continue;
+
+ if (mech->gss_store_cred_into == NULL &&
+ cred_store != GSS_C_NO_CRED_STORE)
+ continue;
+
+ if (mech->gss_store_cred == NULL &&
+ mech->gss_store_cred_into == NULL)
+ continue;
+
+ mech_cred = gssint_get_mechanism_cred(union_cred, dmech);
+ if (mech_cred == GSS_C_NO_CREDENTIAL)
+ continue; /* can't happen, but safe to ignore */
+
+ major_status = store_cred_fallback(minor_status, mech,
+ mech_cred, cred_usage,
+ dmech, overwrite_cred,
+ default_cred, cred_store,
+ NULL, cred_usage_stored);
+ if (major_status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ continue;
+ }
+
+ /* Succeeded for at least one mech */
+
+ if (elements_stored == NULL)
+ continue;
+
+ if (*elements_stored == GSS_C_NULL_OID_SET) {
+ major_status = gss_create_empty_oid_set(minor_status,
+ elements_stored);
+
+ if (GSS_ERROR(major_status))
+ return (major_status);
+ }
+
+ major_status = gss_add_oid_set_member(minor_status, dmech,
+ elements_stored);
+
+ /* The caller should clean up elements_stored */
+ if (GSS_ERROR(major_status))
+ return (major_status);
+ }
+
+ /*
+ * Success with some mechs may mask failure with others, but
+ * that's what elements_stored is for.
+ */
+ return (major_status);
+}
diff --git a/src/lib/gssapi/mechglue/g_unseal.c b/src/lib/gssapi/mechglue/g_unseal.c
new file mode 100644
index 000000000000..3e8053c6e9af
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_unseal.c
@@ -0,0 +1,130 @@
+/* #pragma ident "@(#)g_unseal.c 1.13 98/01/22 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine gss_unwrap
+ */
+
+#include "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_unwrap (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;
+gss_qop_t * qop_state;
+
+{
+/* EXPORT DELETE START */
+ OM_uint32 status;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (output_message_buffer != GSS_C_NO_BUFFER) {
+ output_message_buffer->length = 0;
+ output_message_buffer->value = NULL;
+ }
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
+
+ if (input_message_buffer == GSS_C_NO_BUFFER ||
+ GSS_EMPTY_BUFFER(input_message_buffer))
+
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ if (output_message_buffer == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+ ctx = (gss_union_ctx_id_t) context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+
+ if (mech) {
+ if (mech->gss_unwrap) {
+ status = mech->gss_unwrap(minor_status,
+ ctx->internal_ctx_id,
+ input_message_buffer,
+ output_message_buffer,
+ conf_state,
+ qop_state);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else if (mech->gss_unwrap_aead || mech->gss_unwrap_iov) {
+ status = gssint_unwrap_aead(mech,
+ minor_status,
+ ctx,
+ input_message_buffer,
+ GSS_C_NO_BUFFER,
+ output_message_buffer,
+ conf_state,
+ (gss_qop_t *)qop_state);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return(status);
+ }
+
+/* EXPORT DELETE END */
+
+ return (GSS_S_BAD_MECH);
+}
+
+OM_uint32 KRB5_CALLCONV
+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;
+
+{
+ return (gss_unwrap(minor_status, context_handle,
+ input_message_buffer,
+ output_message_buffer, conf_state, (gss_qop_t *) qop_state));
+}
diff --git a/src/lib/gssapi/mechglue/g_unwrap_aead.c b/src/lib/gssapi/mechglue/g_unwrap_aead.c
new file mode 100644
index 000000000000..e78bff2d3289
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_unwrap_aead.c
@@ -0,0 +1,197 @@
+/* #pragma ident "@(#)g_seal.c 1.19 98/04/21 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_unwrap_aead
+ */
+
+#include "mglueP.h"
+
+static OM_uint32
+val_unwrap_aead_args(
+ OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ gss_buffer_t input_message_buffer,
+ gss_buffer_t input_assoc_buffer,
+ gss_buffer_t output_payload_buffer,
+ int *conf_state,
+ gss_qop_t *qop_state)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
+
+ if (input_message_buffer == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ if (output_payload_buffer == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ return (GSS_S_COMPLETE);
+}
+
+static OM_uint32
+gssint_unwrap_aead_iov_shim(gss_mechanism mech,
+ OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ gss_buffer_t input_message_buffer,
+ gss_buffer_t input_assoc_buffer,
+ gss_buffer_t output_payload_buffer,
+ int *conf_state,
+ gss_qop_t *qop_state)
+{
+ OM_uint32 status;
+ gss_iov_buffer_desc iov[3];
+ int i = 0;
+
+ iov[i].type = GSS_IOV_BUFFER_TYPE_STREAM;
+ iov[i].buffer = *input_message_buffer;
+ i++;
+
+ if (input_assoc_buffer != NULL) {
+ iov[i].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
+ iov[i].buffer = *input_assoc_buffer;
+ i++;
+ }
+
+ iov[i].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE;
+ iov[i].buffer.value = NULL;
+ iov[i].buffer.length = 0;
+ i++;
+
+ assert(mech->gss_unwrap_iov);
+
+ status = mech->gss_unwrap_iov(minor_status, context_handle, conf_state,
+ qop_state, iov, i);
+ if (status == GSS_S_COMPLETE) {
+ *output_payload_buffer = iov[i - 1].buffer;
+ } else {
+ OM_uint32 minor;
+
+ map_error(minor_status, mech);
+
+ if (iov[i - 1].type & GSS_IOV_BUFFER_FLAG_ALLOCATED) {
+ gss_release_buffer(&minor, &iov[i - 1].buffer);
+ iov[i - 1].type &= ~(GSS_IOV_BUFFER_FLAG_ALLOCATED);
+ }
+ }
+
+ return status;
+}
+
+OM_uint32
+gssint_unwrap_aead (gss_mechanism mech,
+ OM_uint32 *minor_status,
+ gss_union_ctx_id_t ctx,
+ gss_buffer_t input_message_buffer,
+ gss_buffer_t input_assoc_buffer,
+ gss_buffer_t output_payload_buffer,
+ int *conf_state,
+ gss_qop_t *qop_state)
+{
+ OM_uint32 status;
+
+ assert(mech != NULL);
+ assert(ctx != NULL);
+
+ /* EXPORT DELETE START */
+
+ if (mech->gss_unwrap_aead) {
+ status = mech->gss_unwrap_aead(minor_status,
+ ctx->internal_ctx_id,
+ input_message_buffer,
+ input_assoc_buffer,
+ output_payload_buffer,
+ conf_state,
+ qop_state);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else if (mech->gss_unwrap_iov) {
+ status = gssint_unwrap_aead_iov_shim(mech,
+ minor_status,
+ ctx->internal_ctx_id,
+ input_message_buffer,
+ input_assoc_buffer,
+ output_payload_buffer,
+ conf_state,
+ qop_state);
+ } else
+ status = GSS_S_UNAVAILABLE;
+ /* EXPORT DELETE END */
+
+ return (status);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_unwrap_aead (minor_status,
+ context_handle,
+ input_message_buffer,
+ input_assoc_buffer,
+ output_payload_buffer,
+ conf_state,
+ qop_state)
+OM_uint32 * minor_status;
+gss_ctx_id_t context_handle;
+gss_buffer_t input_message_buffer;
+gss_buffer_t input_assoc_buffer;
+gss_buffer_t output_payload_buffer;
+int *conf_state;
+gss_qop_t *qop_state;
+{
+
+ OM_uint32 status;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+
+ status = val_unwrap_aead_args(minor_status, context_handle,
+ input_message_buffer, input_assoc_buffer,
+ output_payload_buffer,
+ conf_state, qop_state);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+ ctx = (gss_union_ctx_id_t) context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+
+ if (!mech)
+ return (GSS_S_BAD_MECH);
+
+ return gssint_unwrap_aead(mech, minor_status, ctx,
+ input_message_buffer, input_assoc_buffer,
+ output_payload_buffer, conf_state, qop_state);
+}
diff --git a/src/lib/gssapi/mechglue/g_unwrap_iov.c b/src/lib/gssapi/mechglue/g_unwrap_iov.c
new file mode 100644
index 000000000000..c0dd314b1be8
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_unwrap_iov.c
@@ -0,0 +1,141 @@
+/* #pragma ident "@(#)g_seal.c 1.19 98/04/21 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_unwrap_iov
+ */
+
+#include "mglueP.h"
+
+static OM_uint32
+val_unwrap_iov_args(
+ OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int *conf_state,
+ gss_qop_t *qop_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
+
+ if (iov == GSS_C_NO_IOV_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ return (GSS_S_COMPLETE);
+}
+
+
+OM_uint32 KRB5_CALLCONV
+gss_unwrap_iov (minor_status,
+ context_handle,
+ conf_state,
+ qop_state,
+ iov,
+ iov_count)
+OM_uint32 * minor_status;
+gss_ctx_id_t context_handle;
+int * conf_state;
+gss_qop_t *qop_state;
+gss_iov_buffer_desc * iov;
+int iov_count;
+{
+ /* EXPORT DELETE START */
+
+ OM_uint32 status;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+
+ status = val_unwrap_iov_args(minor_status, context_handle,
+ conf_state, qop_state, iov, iov_count);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+
+ if (mech) {
+ if (mech->gss_unwrap_iov) {
+ status = mech->gss_unwrap_iov(
+ minor_status,
+ ctx->internal_ctx_id,
+ conf_state,
+ qop_state,
+ iov,
+ iov_count);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return(status);
+ }
+ /* EXPORT DELETE END */
+
+ return (GSS_S_BAD_MECH);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_verify_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
+ gss_qop_t *qop_state, gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ OM_uint32 status;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+
+ status = val_unwrap_iov_args(minor_status, context_handle, NULL,
+ qop_state, iov, iov_count);
+ if (status != GSS_S_COMPLETE)
+ return status;
+
+ /* Select the approprate underlying mechanism routine and call it. */
+ ctx = (gss_union_ctx_id_t)context_handle;
+ mech = gssint_get_mechanism(ctx->mech_type);
+ if (mech == NULL)
+ return GSS_S_BAD_MECH;
+ if (mech->gss_verify_mic_iov == NULL)
+ return GSS_S_UNAVAILABLE;
+ status = mech->gss_verify_mic_iov(minor_status, ctx->internal_ctx_id,
+ qop_state, iov, iov_count);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ return status;
+}
diff --git a/src/lib/gssapi/mechglue/g_verify.c b/src/lib/gssapi/mechglue/g_verify.c
new file mode 100644
index 000000000000..1578ae111092
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_verify.c
@@ -0,0 +1,106 @@
+/* #pragma ident "@(#)g_verify.c 1.13 98/04/23 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_verify_mic
+ */
+
+#include "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_verify_mic (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;
+gss_qop_t * qop_state;
+
+{
+ OM_uint32 status;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+ *minor_status = 0;
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
+
+ if ((message_buffer == GSS_C_NO_BUFFER) ||
+ GSS_EMPTY_BUFFER(token_buffer))
+
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+
+ if (mech) {
+ if (mech->gss_verify_mic) {
+ status = mech->gss_verify_mic(
+ minor_status,
+ ctx->internal_ctx_id,
+ message_buffer,
+ token_buffer,
+ qop_state);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return(status);
+ }
+
+ return (GSS_S_BAD_MECH);
+}
+
+OM_uint32 KRB5_CALLCONV
+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;
+
+{
+ return (gss_verify_mic(minor_status, context_handle,
+ message_buffer, token_buffer,
+ (gss_qop_t *) qop_state));
+}
diff --git a/src/lib/gssapi/mechglue/g_wrap_aead.c b/src/lib/gssapi/mechglue/g_wrap_aead.c
new file mode 100644
index 000000000000..96cdf3ce6ab8
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_wrap_aead.c
@@ -0,0 +1,267 @@
+/* #pragma ident "@(#)g_seal.c 1.19 98/04/21 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_wrap_aead
+ */
+
+#include "mglueP.h"
+
+static OM_uint32
+val_wrap_aead_args(
+ OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ gss_buffer_t input_assoc_buffer,
+ gss_buffer_t input_payload_buffer,
+ int *conf_state,
+ gss_buffer_t output_message_buffer)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
+
+ if (input_payload_buffer == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ if (output_message_buffer == GSS_C_NO_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ return (GSS_S_COMPLETE);
+}
+
+static OM_uint32
+gssint_wrap_aead_iov_shim(gss_mechanism mech,
+ OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ gss_buffer_t input_assoc_buffer,
+ gss_buffer_t input_payload_buffer,
+ int *conf_state,
+ gss_buffer_t output_message_buffer)
+{
+ gss_iov_buffer_desc iov[5];
+ OM_uint32 status;
+ size_t offset;
+ int i = 0, iov_count;
+
+ /* HEADER | SIGN_ONLY_DATA | DATA | PADDING | TRAILER */
+
+ iov[i].type = GSS_IOV_BUFFER_TYPE_HEADER;
+ iov[i].buffer.value = NULL;
+ iov[i].buffer.length = 0;
+ i++;
+
+ if (input_assoc_buffer != GSS_C_NO_BUFFER) {
+ iov[i].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
+ iov[i].buffer = *input_assoc_buffer;
+ i++;
+ }
+
+ iov[i].type = GSS_IOV_BUFFER_TYPE_DATA;
+ iov[i].buffer = *input_payload_buffer;
+ i++;
+
+ iov[i].type = GSS_IOV_BUFFER_TYPE_PADDING;
+ iov[i].buffer.value = NULL;
+ iov[i].buffer.length = 0;
+ i++;
+
+ iov[i].type = GSS_IOV_BUFFER_TYPE_TRAILER;
+ iov[i].buffer.value = NULL;
+ iov[i].buffer.length = 0;
+ i++;
+
+ iov_count = i;
+
+ assert(mech->gss_wrap_iov_length);
+
+ status = mech->gss_wrap_iov_length(minor_status, context_handle,
+ conf_req_flag, qop_req,
+ NULL, iov, iov_count);
+ if (status != GSS_S_COMPLETE) {
+ map_error(minor_status, mech);
+ return status;
+ }
+
+ /* Format output token (does not include associated data) */
+ for (i = 0, output_message_buffer->length = 0; i < iov_count; i++) {
+ if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_SIGN_ONLY)
+ continue;
+
+ output_message_buffer->length += iov[i].buffer.length;
+ }
+
+ output_message_buffer->value = gssalloc_malloc(output_message_buffer->length);
+ if (output_message_buffer->value == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ i = 0, offset = 0;
+
+ /* HEADER */
+ iov[i].buffer.value = (unsigned char *)output_message_buffer->value + offset;
+ offset += iov[i].buffer.length;
+ i++;
+
+ /* SIGN_ONLY_DATA */
+ if (input_assoc_buffer != GSS_C_NO_BUFFER)
+ i++;
+
+ /* DATA */
+ iov[i].buffer.value = (unsigned char *)output_message_buffer->value + offset;
+ offset += iov[i].buffer.length;
+
+ memcpy(iov[i].buffer.value, input_payload_buffer->value, iov[i].buffer.length);
+ i++;
+
+ /* PADDING */
+ iov[i].buffer.value = (unsigned char *)output_message_buffer->value + offset;
+ offset += iov[i].buffer.length;
+ i++;
+
+ /* TRAILER */
+ iov[i].buffer.value = (unsigned char *)output_message_buffer->value + offset;
+ offset += iov[i].buffer.length;
+ i++;
+
+ assert(offset == output_message_buffer->length);
+
+ assert(mech->gss_wrap_iov);
+
+ status = mech->gss_wrap_iov(minor_status, context_handle,
+ conf_req_flag, qop_req,
+ conf_state, iov, iov_count);
+ if (status != GSS_S_COMPLETE) {
+ OM_uint32 minor;
+
+ map_error(minor_status, mech);
+ gss_release_buffer(&minor, output_message_buffer);
+ }
+
+ return status;
+}
+
+OM_uint32
+gssint_wrap_aead (gss_mechanism mech,
+ OM_uint32 *minor_status,
+ gss_union_ctx_id_t ctx,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ gss_buffer_t input_assoc_buffer,
+ gss_buffer_t input_payload_buffer,
+ int *conf_state,
+ gss_buffer_t output_message_buffer)
+{
+ /* EXPORT DELETE START */
+ OM_uint32 status;
+
+ assert(ctx != NULL);
+ assert(mech != NULL);
+
+ if (mech->gss_wrap_aead) {
+ status = mech->gss_wrap_aead(minor_status,
+ ctx->internal_ctx_id,
+ conf_req_flag,
+ qop_req,
+ input_assoc_buffer,
+ input_payload_buffer,
+ conf_state,
+ output_message_buffer);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else if (mech->gss_wrap_iov && mech->gss_wrap_iov_length) {
+ status = gssint_wrap_aead_iov_shim(mech,
+ minor_status,
+ ctx->internal_ctx_id,
+ conf_req_flag,
+ qop_req,
+ input_assoc_buffer,
+ input_payload_buffer,
+ conf_state,
+ output_message_buffer);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ /* EXPORT DELETE END */
+
+ return status;
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_wrap_aead (minor_status,
+ context_handle,
+ conf_req_flag,
+ qop_req,
+ input_assoc_buffer,
+ input_payload_buffer,
+ conf_state,
+ output_message_buffer)
+OM_uint32 * minor_status;
+gss_ctx_id_t context_handle;
+int conf_req_flag;
+gss_qop_t qop_req;
+gss_buffer_t input_assoc_buffer;
+gss_buffer_t input_payload_buffer;
+int * conf_state;
+gss_buffer_t output_message_buffer;
+{
+ OM_uint32 status;
+ gss_mechanism mech;
+ gss_union_ctx_id_t ctx;
+
+ status = val_wrap_aead_args(minor_status, context_handle,
+ conf_req_flag, qop_req,
+ input_assoc_buffer, input_payload_buffer,
+ conf_state, output_message_buffer);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+ ctx = (gss_union_ctx_id_t)context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+ if (!mech)
+ return (GSS_S_BAD_MECH);
+
+ return gssint_wrap_aead(mech, minor_status, ctx,
+ conf_req_flag, qop_req,
+ input_assoc_buffer, input_payload_buffer,
+ conf_state, output_message_buffer);
+}
diff --git a/src/lib/gssapi/mechglue/g_wrap_iov.c b/src/lib/gssapi/mechglue/g_wrap_iov.c
new file mode 100644
index 000000000000..40cd98fc91cd
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_wrap_iov.c
@@ -0,0 +1,261 @@
+/* #pragma ident "@(#)g_seal.c 1.19 98/04/21 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * glue routine for gss_wrap_iov
+ */
+
+#include "mglueP.h"
+
+static OM_uint32
+val_wrap_iov_args(
+ OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ int *conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+
+ /* Initialize outputs. */
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ /* Validate arguments. */
+
+ if (minor_status == NULL)
+ return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT);
+
+ if (iov == GSS_C_NO_IOV_BUFFER)
+ return (GSS_S_CALL_INACCESSIBLE_READ);
+
+ return (GSS_S_COMPLETE);
+}
+
+
+OM_uint32 KRB5_CALLCONV
+gss_wrap_iov (minor_status,
+ context_handle,
+ conf_req_flag,
+ qop_req,
+ conf_state,
+ iov,
+ iov_count)
+OM_uint32 * minor_status;
+gss_ctx_id_t context_handle;
+int conf_req_flag;
+gss_qop_t qop_req;
+int * conf_state;
+gss_iov_buffer_desc * iov;
+int iov_count;
+{
+ /* EXPORT DELETE START */
+
+ OM_uint32 status;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+
+ status = val_wrap_iov_args(minor_status, context_handle,
+ conf_req_flag, qop_req,
+ conf_state, iov, iov_count);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+
+ if (mech) {
+ if (mech->gss_wrap_iov) {
+ status = mech->gss_wrap_iov(
+ minor_status,
+ ctx->internal_ctx_id,
+ conf_req_flag,
+ qop_req,
+ conf_state,
+ iov,
+ iov_count);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return(status);
+ }
+ /* EXPORT DELETE END */
+
+ return (GSS_S_BAD_MECH);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_wrap_iov_length (minor_status,
+ context_handle,
+ conf_req_flag,
+ qop_req,
+ conf_state,
+ iov,
+ iov_count)
+OM_uint32 * minor_status;
+gss_ctx_id_t context_handle;
+int conf_req_flag;
+gss_qop_t qop_req;
+int * conf_state;
+gss_iov_buffer_desc * iov;
+int iov_count;
+{
+ /* EXPORT DELETE START */
+
+ OM_uint32 status;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+
+ status = val_wrap_iov_args(minor_status, context_handle,
+ conf_req_flag, qop_req,
+ conf_state, iov, iov_count);
+ if (status != GSS_S_COMPLETE)
+ return (status);
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+
+ if (mech) {
+ if (mech->gss_wrap_iov_length) {
+ status = mech->gss_wrap_iov_length(
+ minor_status,
+ ctx->internal_ctx_id,
+ conf_req_flag,
+ qop_req,
+ conf_state,
+ iov,
+ iov_count);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return(status);
+ }
+ /* EXPORT DELETE END */
+
+ return (GSS_S_BAD_MECH);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_get_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
+ gss_qop_t qop_req, gss_iov_buffer_desc *iov, int iov_count)
+{
+ OM_uint32 status;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+
+ status = val_wrap_iov_args(minor_status, context_handle, 0, qop_req, NULL,
+ iov, iov_count);
+ if (status != GSS_S_COMPLETE)
+ return status;
+
+ /* Select the approprate underlying mechanism routine and call it. */
+ ctx = (gss_union_ctx_id_t)context_handle;
+ mech = gssint_get_mechanism(ctx->mech_type);
+ if (mech == NULL)
+ return GSS_S_BAD_MECH;
+ if (mech->gss_get_mic_iov == NULL)
+ return GSS_S_UNAVAILABLE;
+ status = mech->gss_get_mic_iov(minor_status, ctx->internal_ctx_id, qop_req,
+ iov, iov_count);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ return status;
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_get_mic_iov_length(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
+ gss_qop_t qop_req, gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ OM_uint32 status;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+
+ status = val_wrap_iov_args(minor_status, context_handle, 0, qop_req, NULL,
+ iov, iov_count);
+ if (status != GSS_S_COMPLETE)
+ return status;
+
+ /* Select the approprate underlying mechanism routine and call it. */
+ ctx = (gss_union_ctx_id_t)context_handle;
+ mech = gssint_get_mechanism(ctx->mech_type);
+ if (mech == NULL)
+ return GSS_S_BAD_MECH;
+ if (mech->gss_get_mic_iov_length == NULL)
+ return GSS_S_UNAVAILABLE;
+ status = mech->gss_get_mic_iov_length(minor_status, ctx->internal_ctx_id,
+ qop_req, iov, iov_count);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ return status;
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_release_iov_buffer (minor_status,
+ iov,
+ iov_count)
+OM_uint32 * minor_status;
+gss_iov_buffer_desc * iov;
+int iov_count;
+{
+ OM_uint32 status = GSS_S_COMPLETE;
+ int i;
+
+ if (minor_status)
+ *minor_status = 0;
+
+ if (iov == GSS_C_NO_IOV_BUFFER)
+ return GSS_S_COMPLETE;
+
+ for (i = 0; i < iov_count; i++) {
+ if (iov[i].type & GSS_IOV_BUFFER_FLAG_ALLOCATED) {
+ status = gss_release_buffer(minor_status, &iov[i].buffer);
+ if (status != GSS_S_COMPLETE)
+ break;
+
+ iov[i].type &= ~(GSS_IOV_BUFFER_FLAG_ALLOCATED);
+ }
+ }
+
+ return status;
+}
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
index 000000000000..4caa751657b7
--- /dev/null
+++ b/src/lib/gssapi/mechglue/gssd_pname_to_uid.c
@@ -0,0 +1,226 @@
+/* #pragma ident "@(#)gssd_pname_to_uid.c 1.18 04/02/23 SMI" */
+/*
+ * Copyright (c) 2011, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * 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 PADL Software 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 BY PADL SOFTWARE AND CONTRIBUTORS ``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 PADL SOFTWARE 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.
+ */
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * 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.
+ *
+ */
+
+#include "mglueP.h"
+
+#ifndef NO_PASSWORD
+#include <pwd.h>
+#endif
+
+static OM_uint32
+attr_localname(OM_uint32 *minor,
+ const gss_mechanism mech,
+ const gss_name_t mech_name,
+ gss_buffer_t localname)
+{
+ OM_uint32 major = GSS_S_UNAVAILABLE;
+ OM_uint32 tmpMinor;
+ int more = -1;
+ gss_buffer_desc value;
+ gss_buffer_desc display_value;
+ int authenticated = 0, complete = 0;
+
+ value.value = NULL;
+ display_value.value = NULL;
+ if (mech->gss_get_name_attribute == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ major = mech->gss_get_name_attribute(minor,
+ mech_name,
+ GSS_C_ATTR_LOCAL_LOGIN_USER,
+ &authenticated,
+ &complete,
+ &value,
+ &display_value,
+ &more);
+ if (GSS_ERROR(major)) {
+ map_error(minor, mech);
+ goto cleanup;
+ }
+
+ if (!authenticated)
+ major = GSS_S_UNAVAILABLE;
+ else {
+ localname->value = value.value;
+ localname->length = value.length;
+ value.value = NULL;
+ }
+
+cleanup:
+ if (display_value.value)
+ gss_release_buffer(&tmpMinor, &display_value);
+ if (value.value)
+ gss_release_buffer(&tmpMinor, &value);
+ return major;
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_localname(OM_uint32 *minor,
+ const gss_name_t pname,
+ gss_const_OID mech_type,
+ gss_buffer_t localname)
+{
+ OM_uint32 major, tmpMinor;
+ gss_mechanism mech;
+ gss_union_name_t unionName;
+ gss_name_t mechName = GSS_C_NO_NAME, mechNameP;
+ gss_OID selected_mech = GSS_C_NO_OID, public_mech;
+
+ if (localname != GSS_C_NO_BUFFER) {
+ localname->length = 0;
+ localname->value = NULL;
+ }
+
+ if (minor == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ *minor = 0;
+
+ if (pname == GSS_C_NO_NAME)
+ return GSS_S_CALL_INACCESSIBLE_READ;
+
+ if (localname == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ unionName = (gss_union_name_t)pname;
+
+ if (mech_type != GSS_C_NO_OID) {
+ major = gssint_select_mech_type(minor, mech_type, &selected_mech);
+ if (major != GSS_S_COMPLETE)
+ return major;
+ mech = gssint_get_mechanism(selected_mech);
+ } else
+ mech = gssint_get_mechanism(unionName->mech_type);
+
+ if (mech == NULL)
+ return GSS_S_BAD_MECH;
+
+ /* may need to create a mechanism specific name */
+ if (unionName->mech_type == GSS_C_NO_OID ||
+ (unionName->mech_type != GSS_C_NO_OID &&
+ !g_OID_equal(unionName->mech_type, &mech->mech_type))) {
+ major = gssint_import_internal_name(minor, &mech->mech_type,
+ unionName, &mechName);
+ if (GSS_ERROR(major))
+ return major;
+
+ mechNameP = mechName;
+ } else
+ mechNameP = unionName->mech_name;
+
+ major = GSS_S_UNAVAILABLE;
+
+ if (mech->gss_localname != NULL) {
+ public_mech = gssint_get_public_oid(selected_mech);
+ major = mech->gss_localname(minor, mechNameP, public_mech, localname);
+ if (GSS_ERROR(major))
+ map_error(minor, mech);
+ }
+
+ if (GSS_ERROR(major))
+ major = attr_localname(minor, mech, mechNameP, localname);
+
+ if (mechName != GSS_C_NO_NAME)
+ gssint_release_internal_name(&tmpMinor, &mech->mech_type, &mechName);
+
+ return major;
+}
+
+#ifndef _WIN32
+OM_uint32 KRB5_CALLCONV
+gss_pname_to_uid(OM_uint32 *minor,
+ const gss_name_t name,
+ const gss_OID mech_type,
+ uid_t *uidOut)
+{
+ OM_uint32 major = GSS_S_UNAVAILABLE, tmpminor;
+#ifndef NO_PASSWORD
+ gss_buffer_desc localname;
+ char pwbuf[BUFSIZ];
+ char *localuser = NULL;
+ struct passwd *pwd = NULL;
+ struct passwd pw;
+ int code = 0;
+
+ localname.value = NULL;
+ major = gss_localname(minor, name, mech_type, &localname);
+ if (!GSS_ERROR(major) && localname.value) {
+ localuser = malloc(localname.length + 1);
+ if (localuser == NULL)
+ code = ENOMEM;
+ if (code == 0) {
+ memcpy(localuser, localname.value, localname.length);
+ localuser[localname.length] = '\0';
+ code = k5_getpwnam_r(localuser, &pw, pwbuf, sizeof(pwbuf), &pwd);
+ }
+ if ((code == 0) && pwd)
+ *uidOut = pwd->pw_uid;
+ else
+ major = GSS_S_FAILURE;
+ }
+ free(localuser);
+ if (localname.value)
+ gss_release_buffer(&tmpminor, &localname);
+#endif /*NO_PASSWORD*/
+ return major;
+}
+#endif /*_WIN32*/
diff --git a/src/lib/gssapi/mechglue/mechglue.h b/src/lib/gssapi/mechglue/mechglue.h
new file mode 100644
index 000000000000..85983694a258
--- /dev/null
+++ b/src/lib/gssapi/mechglue/mechglue.h
@@ -0,0 +1,42 @@
+/* #ident "@(#)mechglue.h 1.13 95/08/07 SMI" */
+
+/*
+ * Copyright 1996 by Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Sun Microsystems not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Sun Microsystems makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This header contains the mechglue definitions.
+ */
+
+#ifndef _GSS_MECHGLUE_H
+#define _GSS_MECHGLUE_H
+
+#include <gssapi/gssapi.h>
+
+/********************************************************/
+/* GSSAPI Extension functions -- these functions aren't */
+/* in the GSSAPI, but they are provided in this library */
+
+#include <gssapi/gssapi_ext.h>
+
+void KRB5_CALLCONV gss_initialize(void);
+
+#endif /* _GSS_MECHGLUE_H */
diff --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h
new file mode 100644
index 000000000000..2b5145e079fe
--- /dev/null
+++ b/src/lib/gssapi/mechglue/mglueP.h
@@ -0,0 +1,854 @@
+/* lib/gssapi/mechglue/mglueP.h */
+
+/*
+ * Copyright (c) 1995, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+/* This header contains the private mechglue definitions. */
+
+#ifndef _GSS_MECHGLUEP_H
+#define _GSS_MECHGLUEP_H
+
+#include "autoconf.h"
+#include "mechglue.h"
+#include "gssapiP_generic.h"
+
+#define g_OID_copy(o1, o2) \
+do { \
+ memcpy((o1)->elements, (o2)->elements, (o2)->length); \
+ (o1)->length = (o2)->length; \
+} while (0)
+
+/*
+ * Array of context IDs typed by mechanism OID
+ */
+typedef struct gss_union_ctx_id_struct {
+ struct gss_union_ctx_id_struct *loopback;
+ gss_OID mech_type;
+ gss_ctx_id_t internal_ctx_id;
+} gss_union_ctx_id_desc, *gss_union_ctx_id_t;
+
+/*
+ * Generic GSSAPI names. A name can either be a generic name, or a
+ * mechanism specific name....
+ */
+typedef struct gss_name_struct {
+ struct gss_name_struct *loopback;
+ gss_OID name_type;
+ gss_buffer_t external_name;
+ /*
+ * These last two fields are only filled in for mechanism
+ * names.
+ */
+ gss_OID mech_type;
+ gss_name_t mech_name;
+} gss_union_name_desc, *gss_union_name_t;
+
+/*
+ * Structure for holding list of mechanism-specific name types
+ */
+typedef struct gss_mech_spec_name_t {
+ gss_OID name_type;
+ gss_OID mech;
+ struct gss_mech_spec_name_t *next, *prev;
+} gss_mech_spec_name_desc, *gss_mech_spec_name;
+
+/*
+ * Set of Credentials typed on mechanism OID
+ */
+typedef struct gss_cred_id_struct {
+ struct gss_cred_id_struct *loopback;
+ int count;
+ gss_OID mechs_array;
+ gss_cred_id_t *cred_array;
+} gss_union_cred_desc, *gss_union_cred_t;
+
+/*
+ * Rudimentary pointer validation macro to check whether the
+ * "loopback" field of an opaque struct points back to itself. This
+ * field also catches some programming errors where an opaque pointer
+ * is passed to a function expecting the address of the opaque
+ * pointer.
+ */
+#define GSSINT_CHK_LOOP(p) (!((p) != NULL && (p)->loopback == (p)))
+
+/********************************************************/
+/* The Mechanism Dispatch Table -- a mechanism needs to */
+/* define one of these and provide a function to return */
+/* it to initialize the GSSAPI library */
+int gssint_mechglue_initialize_library(void);
+
+OM_uint32 gssint_get_mech_type_oid(gss_OID OID, gss_buffer_t token);
+
+/*
+ * 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 (KRB5_CALLCONV *gss_acquire_cred)
+ (
+ 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 (KRB5_CALLCONV *gss_release_cred)
+ (
+ OM_uint32*, /* minor_status */
+ gss_cred_id_t* /* cred_handle */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_init_sec_context)
+ (
+ OM_uint32*, /* minor_status */
+ gss_cred_id_t, /* claimant_cred_handle */
+ gss_ctx_id_t*, /* context_handle */
+ gss_name_t, /* target_name */
+ gss_OID, /* mech_type */
+ OM_uint32, /* 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 */
+ OM_uint32*, /* ret_flags */
+ OM_uint32* /* time_rec */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_accept_sec_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 */
+ OM_uint32*, /* ret_flags */
+ OM_uint32*, /* time_rec */
+ gss_cred_id_t* /* delegated_cred_handle */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_process_context_token)
+ (
+ OM_uint32*, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_buffer_t /* token_buffer */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_delete_sec_context)
+ (
+ OM_uint32*, /* minor_status */
+ gss_ctx_id_t*, /* context_handle */
+ gss_buffer_t /* output_token */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_context_time)
+ (
+ OM_uint32*, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ OM_uint32* /* time_rec */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_get_mic)
+ (
+ OM_uint32*, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_qop_t, /* qop_req */
+ gss_buffer_t, /* message_buffer */
+ gss_buffer_t /* message_token */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_verify_mic)
+ (
+ OM_uint32*, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_buffer_t, /* message_buffer */
+ gss_buffer_t, /* token_buffer */
+ gss_qop_t* /* qop_state */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_wrap)
+ (
+ OM_uint32*, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ gss_qop_t, /* qop_req */
+ gss_buffer_t, /* input_message_buffer */
+ int*, /* conf_state */
+ gss_buffer_t /* output_message_buffer */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_unwrap)
+ (
+ 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 */
+ gss_qop_t* /* qop_state */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_display_status)
+ (
+ OM_uint32*, /* minor_status */
+ OM_uint32, /* status_value */
+ int, /* status_type */
+ gss_OID, /* mech_type */
+ OM_uint32*, /* message_context */
+ gss_buffer_t /* status_string */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_indicate_mechs)
+ (
+ OM_uint32*, /* minor_status */
+ gss_OID_set* /* mech_set */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_compare_name)
+ (
+ OM_uint32*, /* minor_status */
+ gss_name_t, /* name1 */
+ gss_name_t, /* name2 */
+ int* /* name_equal */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_display_name)
+ (
+ OM_uint32*, /* minor_status */
+ gss_name_t, /* input_name */
+ gss_buffer_t, /* output_name_buffer */
+ gss_OID* /* output_name_type */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_import_name)
+ (
+ OM_uint32*, /* minor_status */
+ gss_buffer_t, /* input_name_buffer */
+ gss_OID, /* input_name_type */
+ gss_name_t* /* output_name */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_release_name)
+ (
+ OM_uint32*, /* minor_status */
+ gss_name_t* /* input_name */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_inquire_cred)
+ (
+ 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 (KRB5_CALLCONV *gss_add_cred)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* input_cred_handle */
+ gss_name_t, /* desired_name */
+ gss_OID, /* desired_mech */
+ gss_cred_usage_t, /* cred_usage */
+ OM_uint32, /* initiator_time_req */
+ OM_uint32, /* acceptor_time_req */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 *, /* initiator_time_rec */
+ OM_uint32 * /* acceptor_time_rec */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_export_sec_context)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t *, /* context_handle */
+ gss_buffer_t /* interprocess_token */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_import_sec_context)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_buffer_t, /* interprocess_token */
+ gss_ctx_id_t * /* context_handle */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_inquire_cred_by_mech)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* cred_handle */
+ gss_OID, /* mech_type */
+ gss_name_t *, /* name */
+ OM_uint32 *, /* initiator_lifetime */
+ OM_uint32 *, /* acceptor_lifetime */
+ gss_cred_usage_t * /* cred_usage */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_inquire_names_for_mech)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_OID, /* mechanism */
+ gss_OID_set * /* name_types */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_inquire_context)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_name_t *, /* src_name */
+ gss_name_t *, /* targ_name */
+ OM_uint32 *, /* lifetime_rec */
+ gss_OID *, /* mech_type */
+ OM_uint32 *, /* ctx_flags */
+ int *, /* locally_initiated */
+ int * /* open */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_internal_release_oid)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_OID * /* OID */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_wrap_size_limit)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ gss_qop_t, /* qop_req */
+ OM_uint32, /* req_output_size */
+ OM_uint32 * /* max_input_size */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_localname)
+ (
+ OM_uint32 *, /* minor */
+ const gss_name_t, /* name */
+ gss_const_OID, /* mech_type */
+ gss_buffer_t /* localname */
+ );
+ OM_uint32 (KRB5_CALLCONV *gssspi_authorize_localname)
+ (
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* pname */
+ gss_const_buffer_t, /* local user */
+ gss_const_OID /* local nametype */
+ /* */);
+ OM_uint32 (KRB5_CALLCONV *gss_export_name)
+ (
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_buffer_t /* exported_name */
+ /* */);
+ OM_uint32 (KRB5_CALLCONV *gss_duplicate_name)
+ (
+ OM_uint32*, /* minor_status */
+ const gss_name_t, /* input_name */
+ gss_name_t * /* output_name */
+ /* */);
+ OM_uint32 (KRB5_CALLCONV *gss_store_cred)
+ (
+ OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* input_cred */
+ gss_cred_usage_t, /* cred_usage */
+ const gss_OID, /* desired_mech */
+ OM_uint32, /* overwrite_cred */
+ OM_uint32, /* default_cred */
+ gss_OID_set *, /* elements_stored */
+ gss_cred_usage_t * /* cred_usage_stored */
+ /* */);
+
+
+ /* GGF extensions */
+
+ OM_uint32 (KRB5_CALLCONV *gss_inquire_sec_context_by_oid)
+ (
+ OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ const gss_OID, /* OID */
+ gss_buffer_set_t * /* data_set */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_inquire_cred_by_oid)
+ (
+ OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* cred_handle */
+ const gss_OID, /* OID */
+ gss_buffer_set_t * /* data_set */
+ );
+ OM_uint32 (KRB5_CALLCONV *gss_set_sec_context_option)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t *, /* context_handle */
+ const gss_OID, /* OID */
+ const gss_buffer_t /* value */
+ );
+ OM_uint32 (KRB5_CALLCONV *gssspi_set_cred_option)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t *, /* cred_handle */
+ const gss_OID, /* OID */
+ const gss_buffer_t /* value */
+ );
+ OM_uint32 (KRB5_CALLCONV *gssspi_mech_invoke)
+ (
+ OM_uint32*, /* minor_status */
+ const gss_OID, /* mech OID */
+ const gss_OID, /* OID */
+ gss_buffer_t /* value */
+ );
+
+ /* AEAD extensions */
+ OM_uint32 (KRB5_CALLCONV *gss_wrap_aead)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ gss_qop_t, /* qop_req */
+ gss_buffer_t, /* input_assoc_buffer */
+ gss_buffer_t, /* input_payload_buffer */
+ int *, /* conf_state */
+ gss_buffer_t /* output_message_buffer */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_unwrap_aead)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_buffer_t, /* input_message_buffer */
+ gss_buffer_t, /* input_assoc_buffer */
+ gss_buffer_t, /* output_payload_buffer */
+ int *, /* conf_state */
+ gss_qop_t * /* qop_state */
+ /* */);
+
+ /* SSPI extensions */
+ OM_uint32 (KRB5_CALLCONV *gss_wrap_iov)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag */
+ gss_qop_t, /* qop_req */
+ int *, /* conf_state */
+ gss_iov_buffer_desc *, /* iov */
+ int /* iov_count */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_unwrap_iov)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int *, /* conf_state */
+ gss_qop_t *, /* qop_state */
+ gss_iov_buffer_desc *, /* iov */
+ int /* iov_count */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_wrap_iov_length)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ int, /* conf_req_flag*/
+ gss_qop_t, /* qop_req */
+ int *, /* conf_state */
+ gss_iov_buffer_desc *, /* iov */
+ int /* iov_count */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_complete_auth_token)
+ (
+ OM_uint32*, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ gss_buffer_t /* input_message_buffer */
+ );
+
+ /* New for 1.8 */
+
+ OM_uint32 (KRB5_CALLCONV *gss_acquire_cred_impersonate_name)
+ (
+ OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* impersonator_cred_handle */
+ const gss_name_t, /* desired_name */
+ OM_uint32, /* time_req */
+ const gss_OID_set, /* desired_mechs */
+ gss_cred_usage_t, /* cred_usage */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 * /* time_rec */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_add_cred_impersonate_name)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* input_cred_handle */
+ const gss_cred_id_t, /* impersonator_cred_handle */
+ const gss_name_t, /* desired_name */
+ const gss_OID, /* desired_mech */
+ gss_cred_usage_t, /* cred_usage */
+ OM_uint32, /* initiator_time_req */
+ OM_uint32, /* acceptor_time_req */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 *, /* initiator_time_rec */
+ OM_uint32 * /* acceptor_time_rec */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_display_name_ext)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_OID, /* display_as_name_type */
+ gss_buffer_t /* display_name */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_inquire_name)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ int *, /* name_is_MN */
+ gss_OID *, /* MN_mech */
+ gss_buffer_set_t * /* attrs */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_get_name_attribute)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_buffer_t, /* attr */
+ int *, /* authenticated */
+ int *, /* complete */
+ gss_buffer_t, /* value */
+ gss_buffer_t, /* display_value */
+ int * /* more */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_set_name_attribute)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ int, /* complete */
+ gss_buffer_t, /* attr */
+ gss_buffer_t /* value */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_delete_name_attribute)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_buffer_t /* attr */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_export_name_composite)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_buffer_t /* exp_composite_name */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_map_name_to_any)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ int, /* authenticated */
+ gss_buffer_t, /* type_id */
+ gss_any_t * /* output */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_release_any_name_mapping)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* name */
+ gss_buffer_t, /* type_id */
+ gss_any_t * /* input */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_pseudo_random)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context */
+ int, /* prf_key */
+ const gss_buffer_t, /* prf_in */
+ ssize_t, /* desired_output_len */
+ gss_buffer_t /* prf_out */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_set_neg_mechs)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* cred_handle */
+ const gss_OID_set /* mech_set */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_inquire_saslname_for_mech)
+ (
+ OM_uint32 *, /* minor_status */
+ const gss_OID, /* desired_mech */
+ gss_buffer_t, /* sasl_mech_name */
+ gss_buffer_t, /* mech_name */
+ gss_buffer_t /* mech_description */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_inquire_mech_for_saslname)
+ (
+ OM_uint32 *, /* minor_status */
+ const gss_buffer_t, /* sasl_mech_name */
+ gss_OID * /* mech_type */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_inquire_attrs_for_mech)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_const_OID, /* mech */
+ gss_OID_set *, /* mech_attrs */
+ gss_OID_set * /* known_mech_attrs */
+ /* */);
+
+ /* Credential store extensions */
+
+ OM_uint32 (KRB5_CALLCONV *gss_acquire_cred_from)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_name_t, /* desired_name */
+ OM_uint32, /* time_req */
+ gss_OID_set, /* desired_mechs */
+ gss_cred_usage_t, /* cred_usage */
+ gss_const_key_value_set_t, /* cred_store */
+ gss_cred_id_t *, /* output_cred_handle */
+ gss_OID_set *, /* actual_mechs */
+ OM_uint32 * /* time_rec */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_store_cred_into)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* input_cred_handle */
+ gss_cred_usage_t, /* input_usage */
+ gss_OID, /* desired_mech */
+ OM_uint32, /* overwrite_cred */
+ OM_uint32, /* default_cred */
+ gss_const_key_value_set_t, /* cred_store */
+ gss_OID_set *, /* elements_stored */
+ gss_cred_usage_t * /* cred_usage_stored */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gssspi_acquire_cred_with_password)
+ (
+ OM_uint32 *, /* minor_status */
+ const gss_name_t, /* desired_name */
+ const gss_buffer_t, /* password */
+ OM_uint32, /* time_req */
+ const 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 (KRB5_CALLCONV *gss_export_cred)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_cred_id_t, /* cred_handle */
+ gss_buffer_t /* token */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gss_import_cred)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_buffer_t, /* token */
+ gss_cred_id_t * /* cred_handle */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gssspi_import_sec_context_by_mech)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_OID, /* desired_mech */
+ gss_buffer_t, /* interprocess_token */
+ gss_ctx_id_t * /* context_handle */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gssspi_import_name_by_mech)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_OID, /* mech_type */
+ gss_buffer_t, /* input_name_buffer */
+ gss_OID, /* input_name_type */
+ gss_name_t* /* output_name */
+ /* */);
+
+ OM_uint32 (KRB5_CALLCONV *gssspi_import_cred_by_mech)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_OID, /* mech_type */
+ gss_buffer_t, /* token */
+ gss_cred_id_t * /* cred_handle */
+ /* */);
+
+ /* get_mic_iov extensions, added in 1.12 */
+
+ OM_uint32 (KRB5_CALLCONV *gss_get_mic_iov)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_qop_t, /* qop_req */
+ gss_iov_buffer_desc *, /* iov */
+ int /* iov_count */
+ );
+
+ OM_uint32 (KRB5_CALLCONV *gss_verify_mic_iov)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_qop_t *, /* qop_state */
+ gss_iov_buffer_desc *, /* iov */
+ int /* iov_count */
+ );
+
+ OM_uint32 (KRB5_CALLCONV *gss_get_mic_iov_length)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context_handle */
+ gss_qop_t, /* qop_req */
+ gss_iov_buffer_desc *, /* iov */
+ int /* iov_count */
+ );
+
+} *gss_mechanism;
+
+/*
+ * In the user space we use a wrapper structure to encompass the
+ * mechanism entry points. The wrapper contain the mechanism
+ * entry points and other data which is only relevant to the gss-api
+ * layer. In the kernel we use only the gss_config strucutre because
+ * the kernal does not cantain any of the extra gss-api specific data.
+ */
+typedef struct gss_mech_config {
+ char *kmodName; /* kernel module name */
+ char *uLibName; /* user library name */
+ char *mechNameStr; /* mechanism string name */
+ char *optionStr; /* optional mech parameters */
+ void *dl_handle; /* RTLD object handle for the mech */
+ gss_OID mech_type; /* mechanism oid */
+ gss_mechanism mech; /* mechanism initialization struct */
+ int priority; /* mechanism preference order */
+ int freeMech; /* free mech table */
+ int is_interposer; /* interposer mechanism flag */
+ gss_OID int_mech_type; /* points to the interposer OID */
+ gss_mechanism int_mech; /* points to the interposer mech */
+ struct gss_mech_config *next; /* next element in the list */
+} *gss_mech_info;
+
+/********************************************************/
+/* Internal mechglue routines */
+
+#if 0
+int gssint_mechglue_init(void);
+void gssint_mechglue_fini(void);
+#endif
+
+OM_uint32 gssint_select_mech_type(OM_uint32 *minor, gss_const_OID in_oid,
+ gss_OID *selected_oid);
+gss_OID gssint_get_public_oid(gss_const_OID internal_oid);
+OM_uint32 gssint_make_public_oid_set(OM_uint32 *minor_status, gss_OID oids,
+ int count, gss_OID_set *public_set);
+gss_mechanism gssint_get_mechanism (gss_const_OID);
+OM_uint32 gssint_get_mech_type (gss_OID, gss_buffer_t);
+char *gssint_get_kmodName(const gss_OID);
+char *gssint_get_modOptions(const gss_OID);
+OM_uint32 gssint_import_internal_name (OM_uint32 *, gss_OID, gss_union_name_t,
+ gss_name_t *);
+OM_uint32 gssint_export_internal_name(OM_uint32 *, const gss_OID,
+ const gss_name_t, gss_buffer_t);
+OM_uint32 gssint_display_internal_name (OM_uint32 *, gss_OID, gss_name_t,
+ gss_buffer_t, gss_OID *);
+OM_uint32 gssint_release_internal_name (OM_uint32 *, gss_OID, gss_name_t *);
+OM_uint32 gssint_delete_internal_sec_context (OM_uint32 *, gss_OID,
+ gss_ctx_id_t *, gss_buffer_t);
+#ifdef _GSS_STATIC_LINK
+int gssint_register_mechinfo(gss_mech_info template);
+#endif
+
+OM_uint32 gssint_convert_name_to_union_name
+ (OM_uint32 *, /* minor_status */
+ gss_mechanism, /* mech */
+ gss_name_t, /* internal_name */
+ gss_name_t * /* external_name */
+ );
+gss_cred_id_t gssint_get_mechanism_cred
+ (gss_union_cred_t, /* union_cred */
+ gss_OID /* mech_type */
+ );
+
+OM_uint32 gssint_create_copy_buffer(
+ const gss_buffer_t, /* src buffer */
+ gss_buffer_t *, /* destination buffer */
+ int /* NULL terminate buffer ? */
+);
+
+OM_uint32 gssint_copy_oid_set(
+ OM_uint32 *, /* minor_status */
+ const gss_OID_set_desc * const, /* oid set */
+ gss_OID_set * /* new oid set */
+);
+
+gss_OID gss_find_mechanism_from_name_type (gss_OID); /* name_type */
+
+OM_uint32 gss_add_mech_name_type
+ (OM_uint32 *, /* minor_status */
+ gss_OID, /* name_type */
+ gss_OID /* mech */
+ );
+
+/*
+ * Sun extensions to GSS-API v2
+ */
+
+int
+gssint_get_der_length(
+ unsigned char **, /* buf */
+ unsigned int, /* buf_len */
+ unsigned int * /* bytes */
+);
+
+unsigned int
+gssint_der_length_size(unsigned int /* len */);
+
+int
+gssint_put_der_length(
+ unsigned int, /* length */
+ unsigned char **, /* buf */
+ unsigned int /* max_len */
+);
+
+OM_uint32
+gssint_wrap_aead (gss_mechanism, /* mech */
+ OM_uint32 *, /* minor_status */
+ gss_union_ctx_id_t, /* ctx */
+ int, /* conf_req_flag */
+ gss_qop_t, /* qop_req_flag */
+ gss_buffer_t, /* input_assoc_buffer */
+ gss_buffer_t, /* input_payload_buffer */
+ int *, /* conf_state */
+ gss_buffer_t); /* output_message_buffer */
+OM_uint32
+gssint_unwrap_aead (gss_mechanism, /* mech */
+ OM_uint32 *, /* minor_status */
+ gss_union_ctx_id_t, /* ctx */
+ gss_buffer_t, /* input_message_buffer */
+ gss_buffer_t, /* input_assoc_buffer */
+ gss_buffer_t, /* output_payload_buffer */
+ int *, /* conf_state */
+ gss_qop_t *); /* qop_state */
+
+
+/* Use this to map an error code that was returned from a mech
+ operation; the mech will be asked to produce the associated error
+ messages.
+
+ Remember that if the minor status code cannot be returned to the
+ caller (e.g., if it's stuffed in an automatic variable and then
+ ignored), then we don't care about producing a mapping. */
+#define map_error(MINORP, MECH) \
+ (*(MINORP) = gssint_mecherrmap_map(*(MINORP), &(MECH)->mech_type))
+#define map_error_oid(MINORP, MECHOID) \
+ (*(MINORP) = gssint_mecherrmap_map(*(MINORP), (MECHOID)))
+
+/* Use this to map an errno value or com_err error code being
+ generated within the mechglue code (e.g., by calling generic oid
+ ops). Any errno or com_err values produced by mech operations
+ should be processed with map_error. This means they'll be stored
+ separately even if the mech uses com_err, because we can't assume
+ that it will use com_err. */
+#define map_errcode(MINORP) \
+ (*(MINORP) = gssint_mecherrmap_map_errcode(*(MINORP)))
+
+#endif /* _GSS_MECHGLUEP_H */