changeset 5053:532e59d6bffd

6573019 mit 1.4 sub-glue layer resync
author gtb
date Fri, 14 Sep 2007 15:01:24 -0700
parents 82bdd5527b91
children bd0f88647368
files deleted_files/usr/src/lib/gss_mechs/mech_krb5/mech/k5mech.c usr/src/lib/gss_mechs/mech_krb5/Makefile usr/src/lib/gss_mechs/mech_krb5/Makefile.com usr/src/lib/gss_mechs/mech_krb5/crypto/old_api_glue.c usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/file/ktfile.h usr/src/lib/gss_mechs/mech_krb5/krb5/os/an_to_ln.c usr/src/lib/gss_mechs/mech_krb5/krb5/os/kuserok.c usr/src/lib/gss_mechs/mech_krb5/mapfile-vers usr/src/lib/gss_mechs/mech_krb5/mech/accept_sec_context.c usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred.c usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred_with_pw.c usr/src/lib/gss_mechs/mech_krb5/mech/add_cred.c usr/src/lib/gss_mechs/mech_krb5/mech/compare_name.c usr/src/lib/gss_mechs/mech_krb5/mech/context_time.c usr/src/lib/gss_mechs/mech_krb5/mech/copy_ccache.c usr/src/lib/gss_mechs/mech_krb5/mech/disp_com_err_status.c usr/src/lib/gss_mechs/mech_krb5/mech/disp_major_status.c usr/src/lib/gss_mechs/mech_krb5/mech/disp_name.c usr/src/lib/gss_mechs/mech_krb5/mech/disp_status.c usr/src/lib/gss_mechs/mech_krb5/mech/export_name.c usr/src/lib/gss_mechs/mech_krb5/mech/export_sec_context.c usr/src/lib/gss_mechs/mech_krb5/mech/get_tkt_flags.c usr/src/lib/gss_mechs/mech_krb5/mech/gss_libinit.c usr/src/lib/gss_mechs/mech_krb5/mech/gss_libinit.h usr/src/lib/gss_mechs/mech_krb5/mech/import_name.c usr/src/lib/gss_mechs/mech_krb5/mech/indicate_mechs.c usr/src/lib/gss_mechs/mech_krb5/mech/init_sec_context.c usr/src/lib/gss_mechs/mech_krb5/mech/inq_context.c usr/src/lib/gss_mechs/mech_krb5/mech/inq_cred.c usr/src/lib/gss_mechs/mech_krb5/mech/inq_names.c usr/src/lib/gss_mechs/mech_krb5/mech/k5mech.c usr/src/lib/gss_mechs/mech_krb5/mech/krb5_gss_glue.c usr/src/lib/gss_mechs/mech_krb5/mech/lucid_context.c usr/src/lib/gss_mechs/mech_krb5/mech/oid_ops.c usr/src/lib/gss_mechs/mech_krb5/mech/pname_to_uid.c usr/src/lib/gss_mechs/mech_krb5/mech/process_context_token.c usr/src/lib/gss_mechs/mech_krb5/mech/rel_buffer.c usr/src/lib/gss_mechs/mech_krb5/mech/rel_cred.c usr/src/lib/gss_mechs/mech_krb5/mech/rel_name.c usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid.c usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid_set.c usr/src/lib/gss_mechs/mech_krb5/mech/set_allowable_enctypes.c usr/src/lib/gss_mechs/mech_krb5/mech/set_ccache.c usr/src/lib/gss_mechs/mech_krb5/mech/store_cred.c usr/src/lib/gss_mechs/mech_krb5/mech/util_buffer.c usr/src/lib/gss_mechs/mech_krb5/mech/util_cksum.c usr/src/lib/gss_mechs/mech_krb5/mech/util_localhost.c usr/src/lib/gss_mechs/mech_krb5/mech/utl_nohash_validate.c usr/src/lib/krb5/kadm5/clnt/client_init.c usr/src/lib/libgss/g_acquire_cred.c usr/src/lib/libgss/g_canon_name.c usr/src/lib/libgss/g_dup_name.c usr/src/lib/libgss/g_glue.c usr/src/lib/libgss/g_imp_name.c usr/src/uts/common/gssapi/include/mechglueP.h usr/src/uts/common/gssapi/include/mglueP.h usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_generic.h usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_krb5.h usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_err_krb5.h usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_krb5.h usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform.h usr/src/uts/common/gssapi/mechs/krb5/include/k5-thread.h usr/src/uts/common/gssapi/mechs/krb5/krb5mech.c usr/src/uts/common/gssapi/mechs/krb5/mech/delete_sec_context.c usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c usr/src/uts/common/gssapi/mechs/krb5/mech/import_sec_context.c usr/src/uts/common/gssapi/mechs/krb5/mech/k5seal.c usr/src/uts/common/gssapi/mechs/krb5/mech/k5sealv3.c usr/src/uts/common/gssapi/mechs/krb5/mech/k5unseal.c usr/src/uts/common/gssapi/mechs/krb5/mech/seal.c usr/src/uts/common/gssapi/mechs/krb5/mech/ser_sctx.c usr/src/uts/common/gssapi/mechs/krb5/mech/sign.c usr/src/uts/common/gssapi/mechs/krb5/mech/unseal.c usr/src/uts/common/gssapi/mechs/krb5/mech/util_crypt.c usr/src/uts/common/gssapi/mechs/krb5/mech/util_ordering.c usr/src/uts/common/gssapi/mechs/krb5/mech/util_seed.c usr/src/uts/common/gssapi/mechs/krb5/mech/util_seqnum.c usr/src/uts/common/gssapi/mechs/krb5/mech/util_set.c usr/src/uts/common/gssapi/mechs/krb5/mech/util_token.c usr/src/uts/common/gssapi/mechs/krb5/mech/util_validate.c usr/src/uts/common/gssapi/mechs/krb5/mech/val_cred.c usr/src/uts/common/gssapi/mechs/krb5/mech/verify.c usr/src/uts/common/gssapi/mechs/krb5/mech/wrap_size_limit.c usr/src/xmod/cry_files
diffstat 85 files changed, 6754 insertions(+), 3539 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/deleted_files/usr/src/lib/gss_mechs/mech_krb5/mech/k5mech.c	Fri Sep 14 15:01:24 2007 -0700
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*
+ * XXX: I know where to find this header, but it really is using a
+ * private interface.  I dont want to export the gss_mechanism
+ * structure, so I hide it in a non-published header.  Thats ok,
+ * we know where to find it.
+ */
+#include <mechglueP.h>
+
+#include <gssapiP_krb5.h>
+#include <syslog.h>
+#include <libintl.h>
+/*
+ * These are the extern declarations, one group per mechanism. They are
+ * contained in the files named <mech>_gssd_extern_srvr.conf.
+ */
+
+static OM_uint32
+krb5_gss_get_context
+	PROTOTYPE((void**));
+
+/*
+ * This is the declaration of the mechs_array table for Kerberos V5.
+ * If the gss_mechanism structure changes, so should this array!  I
+ * told you it was a private interface!
+ */
+
+static struct gss_config krb5_mechanism = {
+	{9, "\052\206\110\206\367\022\001\002\002"},
+	0,			/* context, to be filled */
+	krb5_gss_acquire_cred,
+	krb5_gss_release_cred,
+	krb5_gss_init_sec_context,
+	krb5_gss_accept_sec_context,
+/* EXPORT DELETE START */ /* CRYPT DELETE START */
+	krb5_gss_unseal,
+/* EXPORT DELETE END */ /* CRYPT DELETE END */
+	krb5_gss_process_context_token,
+	krb5_gss_delete_sec_context,
+	krb5_gss_context_time,
+	krb5_gss_display_status,
+	krb5_gss_indicate_mechs,
+	krb5_gss_compare_name,
+	krb5_gss_display_name,
+	krb5_gss_import_name,
+	krb5_gss_release_name,
+	krb5_gss_inquire_cred,
+	krb5_gss_add_cred,
+/* EXPORT DELETE START */ /* CRYPT DELETE START */
+        krb5_gss_seal,
+/* EXPORT DELETE END */ /* CRYPT DELETE END */
+	krb5_gss_export_sec_context,
+	krb5_gss_import_sec_context,
+	krb5_gss_inquire_cred_by_mech,
+	krb5_gss_inquire_names_for_mech,
+	krb5_gss_inquire_context,
+	krb5_gss_internal_release_oid,
+	krb5_gss_wrap_size_limit,
+	krb5_pname_to_uid,
+	krb5_gss_userok,
+	NULL,	/* export_name */
+/* EXPORT DELETE START */
+/* CRYPT DELETE START */
+#if 0
+/* CRYPT DELETE END */
+	krb5_gss_seal,
+	krb5_gss_unseal,
+/* CRYPT DELETE START */
+#endif
+/* CRYPT DELETE END */
+/* EXPORT DELETE END */
+	krb5_gss_sign,
+	krb5_gss_verify,
+	krb5_gss_store_cred,
+	};
+
+#include <k5-int.h>
+
+
+OM_uint32
+krb5_gss_get_context(context)
+void **	context;
+{
+	/* Solaris Kerberos:  the following is a global variable declared
+         * and initialized in gssapi_krb5.c */
+	/* static krb5_context kg_context = NULL; */
+	krb5_error_code errCode = 0;
+
+	if (context == NULL)
+		return (GSS_S_FAILURE);
+	if (kg_context) {
+		*context = kg_context;
+		return (GSS_S_COMPLETE);
+	}
+
+	if ((errCode = krb5_init_context(&kg_context)))
+		goto error;	
+
+	if (((errCode = krb5_ser_context_init(kg_context)) != 0) ||
+		((errCode = krb5_ser_auth_context_init(kg_context)) != 0) ||
+		((errCode = krb5_ser_ccache_init(kg_context)) != 0) ||
+		((errCode = krb5_ser_rcache_init(kg_context)) != 0) ||
+		((errCode = krb5_ser_keytab_init(kg_context)) != 0) ||
+		((errCode = krb5_ser_context_init(kg_context)) != 0)) {
+		krb5_free_context(kg_context);
+		kg_context = 0;
+		goto error;
+	}
+
+	*context = kg_context;
+	return (GSS_S_COMPLETE);
+
+error:
+	if (errCode != 0) {
+		syslog(LOG_ERR,
+			dgettext(TEXT_DOMAIN,
+			
+				"Kerberos mechanism library"
+				" initialization error: %s."),
+		    error_message((long)errCode));
+	}
+	return (GSS_S_FAILURE);
+}
+
+/*
+ * entry point for the gss layer,
+ * called "krb5_gss_initialize()" in MIT 1.2.1
+ */
+gss_mechanism
+gss_mech_initialize(oid)
+const gss_OID oid;
+{
+	/* ensure that the requested oid matches our oid */
+	if (oid == NULL || !g_OID_equal(oid, &krb5_mechanism.mech_type))
+		return (NULL);
+
+	if (krb5_gss_get_context(&(krb5_mechanism.context)) !=
+		GSS_S_COMPLETE)
+		return (NULL);
+
+	return (&krb5_mechanism);
+}
--- a/usr/src/lib/gss_mechs/mech_krb5/Makefile	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/Makefile	Fri Sep 14 15:01:24 2007 -0700
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -99,7 +99,7 @@
 	$(RM) Makefile+ Makefile.mech_krb5+\
 		crypto/des/afsstring2key.c+ \
 		crypto/des/string2key.c+ \
-		mech/k5mech.c+
+		mech/krb5_gss_glue.c+
 
 	$(SED) -e "/EXPORT DELETE START/,/EXPORT DELETE END/d" \
 		< crypto/des/afsstring2key.c > crypto/des/afsstring2key.c+
@@ -110,8 +110,8 @@
 	$(MV) crypto/des/string2key.c+ crypto/des/string2key.c
 
 	$(SED) -e "/EXPORT DELETE START/,/EXPORT DELETE END/d" \
-		< mech/k5mech.c > mech/k5mech.c+
-	$(MV) mech/k5mech.c+ mech/k5mech.c
+		< mech/krb5_gss_glue.c > mech/krb5_gss_glue.c+
+	$(MV) mech/krb5_gss_glue.c+ mech/krb5_gss_glue.c
 
 	$(SED) -e "/^# EXPORT DELETE START/,/^# EXPORT DELETE END/d" \
 		< Makefile.mech_krb5 > Makefile.mech_krb5+
@@ -124,18 +124,18 @@
 	$(CHMOD) 444 Makefile Makefile.mech_krb5 \
 		crypto/des/afsstring2key.c \
 		crypto/des/string2key.c \
-		mech/k5mech.c
+		mech/krb5_gss_glue.c
 
 
 # CRYPT DELETE START
 # Special target to clean up the source tree for domestic distribution
 # Warning: This target changes the source tree
 CRYPT_SRC:
-	$(RM) Makefile+ mech/k5mech.c+
+	$(RM) Makefile+ mech/krb5_gss_glue.c+
 
 	$(SED) -e "/CRYPT DELETE START/,/CRYPT DELETE END/d" \
-		> mech/k5mech.c+ < mech/k5mech.c
-	$(MV) mech/k5mech.c+ mech/k5mech.c
+		> mech/krb5_gss_glue.c+ < mech/krb5_gss_glue.c
+	$(MV) mech/krb5_gss_glue.c+ mech/krb5_gss_glue.c
 
 	$(SED) -e "/^# CRYPT DELETE START/,/^# CRYPT DELETE END/d"	\
 			< Makefile 				\
@@ -143,7 +143,7 @@
 			> Makefile+
 	$(MV) Makefile+ Makefile
 
-	$(CHMOD) 444 mech/k5mech.c Makefile
+	$(CHMOD) 444 mech/krb5_gss_glue.c Makefile
 
 # CRYPT DELETE END
 # EXPORT DELETE END
--- a/usr/src/lib/gss_mechs/mech_krb5/Makefile.com	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/Makefile.com	Fri Sep 14 15:01:24 2007 -0700
@@ -169,13 +169,14 @@
 	disp_name.o disp_status.o export_sec_context.o \
 	get_tkt_flags.o import_name.o indicate_mechs.o \
 	inq_context.o inq_cred.o inq_names.o \
-	k5mech.o \
+	krb5_gss_glue.o \
 	pname_to_uid.o process_context_token.o \
         rel_buffer.o rel_oid.o rel_oid_set.o \
 	rel_cred.o  rel_name.o util_buffer.o \
 	util_dup.o util_localhost.o \
 	util_cksum.o acquire_cred.o init_sec_context.o \
-	util_ctxsetup.o set_ccache.o acquire_cred_with_pw.o
+	set_ccache.o acquire_cred_with_pw.o lucid_context.o \
+	set_allowable_enctypes.o oid_ops.o export_name.o gss_libinit.o
 
 MECH_UTS= delete_sec_context.o gssapi_krb5.o \
 	import_sec_context.o k5seal.o k5sealv3.o \
@@ -185,13 +186,15 @@
 	util_set.o  util_token.o util_validate.o \
 	val_cred.o verify.o wrap_size_limit.o
 
+GSSAPI_UTS= gen_oids.o
+
 PROFILE_OBJS= prof_tree.o prof_file.o prof_parse.o prof_init.o \
 	prof_set.o prof_get.o
 
-SUPPORT_OBJS= fake-addrinfo.o  threads.o errors.o plugins.o
+SUPPORT_OBJS= fake-addrinfo.o threads.o errors.o plugins.o
 
 OBJECTS= \
-	$(MECH)  $(MECH_UTS) \
+	$(MECH) $(MECH_UTS) $(GSSAPI_UTS)\
 	$(SUPPORT_OBJS) \
 	$(PROFILE_OBJS) \
 	$(CRYPTO) $(CRYPTO_UTS) \
@@ -230,6 +233,7 @@
 CPPFLAGS += -I$(REL_PATH)/libgss -I../include  \
 		-I$(SRC)/uts/common/gssapi \
 		-I$(SRC)/uts/common/gssapi/include \
+		-I$(SRC)/lib/gss_mechs/mech_krb5/mech \
 		-I$(SRC)/lib/gss_mechs/mech_krb5/include/krb5 \
 		-I../include/krb5 \
 		-I../krb5/keytab \
@@ -302,6 +306,10 @@
 # mech lib needs special initialization at load time
 DYNFLAGS += -zinitarray=krb5_ld_init
 
+objs/%.o pics/%.o: $(SRC)/uts/common/gssapi/%.c
+	$(COMPILE.c)  -o $@ $<
+	$(POST_PROCESS_O)
+
 objs/%.o pics/%.o: $(SRC)/uts/common/gssapi/mechs/krb5/mech/%.c
 	$(COMPILE.c)  -o $@ $<
 	$(POST_PROCESS_O)
@@ -481,8 +489,7 @@
 	-DHAVE_ERRNO -DHAVE_STRFTIME -DHAVE_STRPTIME -DHAVE_STRERROR \
 	-DHAVE_STAT -DSIZEOF_INT=4 -DPROVIDE_KERNEL_IMPORT \
 	-DHAVE_STDINT_H -DPOSIX_SIGNALS -DHAVE_GETENV -DHAVE_SETENV \
-	-DHAVE_UNSETENV -DHAVE_FCHMOD -DHAVE_STRUCT_LIFCONF \
-	-DHAVE_ACCESS
+	-DHAVE_UNSETENV -DHAVE_FCHMOD -DHAVE_STRUCT_LIFCONF
 
 CPPFLAGS += -I$(REL_PATH)krb5/ccache/file $(OS_FLAGS)
 
@@ -522,6 +529,7 @@
 	$(K5_RCACHE:%.o= $(SRC)/lib/gss_mechs/mech_krb5/krb5/rcache/%.c) \
 	$(MECH:%.o= $(SRC)/lib/gss_mechs/mech_krb5/mech/%.c) \
 	$(MECH_UTS:%.o= $(SRC)/uts/common/gssapi/mechs/krb5/mech/%.c) \
+	$(GSSAPI_UTS:%.o= $(SRC)/uts/common/gssapi/%.c) \
 	$(PROFILE_OBJS:%.o= $(SRC)/lib/gss_mechs/mech_krb5/profile/%.c) \
 	$(SUPPORT_OBJS:%.o= $(SRC)/lib/gss_mechs/mech_krb5/support/%.c)
 
--- a/usr/src/lib/gss_mechs/mech_krb5/crypto/old_api_glue.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/crypto/old_api_glue.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -66,3 +66,14 @@
 
   return(ret);
 }
+
+size_t KRB5_CALLCONV
+krb5_encrypt_size(size_t length, krb5_enctype crypto)
+{
+    size_t ret;
+
+    if (krb5_c_encrypt_length(/* XXX */ 0, crypto, length, &ret))
+        return(-1); /* XXX */
+
+    return(ret);
+}
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/file/ktfile.h	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/file/ktfile.h	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  *
  * lib/krb5/keytab/file/ktfile.h
@@ -79,103 +79,103 @@
 extern struct _krb5_kt_ops krb5_ktf_writable_ops;
 
 krb5_error_code KRB5_CALLCONV krb5_ktfile_resolve 
-	PROTOTYPE((krb5_context,
+	(krb5_context,
 		   const char *,
-		   krb5_keytab *));
+		   krb5_keytab *);
 
 krb5_error_code KRB5_CALLCONV krb5_ktfile_wresolve 
-	PROTOTYPE((krb5_context,
+	(krb5_context,
 		   const char *,
-		   krb5_keytab *));
+		   krb5_keytab *);
 
 krb5_error_code KRB5_CALLCONV krb5_ktfile_get_name 
-	PROTOTYPE((krb5_context,
+	(krb5_context,
 		   krb5_keytab,
 		   char *,
-		   int));
+		   int);
 
 krb5_error_code KRB5_CALLCONV krb5_ktfile_close 
-	PROTOTYPE((krb5_context,
-		   krb5_keytab));
+	(krb5_context,
+		   krb5_keytab);
 
 krb5_error_code KRB5_CALLCONV krb5_ktfile_get_entry 
-	PROTOTYPE((krb5_context,
+	(krb5_context,
 		   krb5_keytab,
 		   krb5_const_principal,
 		   krb5_kvno,
 		   krb5_enctype,
-		   krb5_keytab_entry *));
+		   krb5_keytab_entry *);
 
 krb5_error_code KRB5_CALLCONV krb5_ktfile_start_seq_get 
-	PROTOTYPE((krb5_context,
+	(krb5_context,
 		   krb5_keytab,
-		   krb5_kt_cursor *));
+		   krb5_kt_cursor *);
 
 krb5_error_code KRB5_CALLCONV krb5_ktfile_get_next 
-	PROTOTYPE((krb5_context,
+	(krb5_context,
 		   krb5_keytab,
 		   krb5_keytab_entry *,
-		   krb5_kt_cursor *));
+		   krb5_kt_cursor *);
 
 krb5_error_code KRB5_CALLCONV krb5_ktfile_end_get 
-	PROTOTYPE((krb5_context,
+	(krb5_context,
 		   krb5_keytab,
-		   krb5_kt_cursor *));
+		   krb5_kt_cursor *);
 
 /* routines to be included on extended version (write routines) */
 krb5_error_code KRB5_CALLCONV krb5_ktfile_add 
-	PROTOTYPE((krb5_context,
+	(krb5_context,
 		   krb5_keytab,
-		   krb5_keytab_entry *));
+		   krb5_keytab_entry *);
 
 krb5_error_code KRB5_CALLCONV krb5_ktfile_remove 
-	PROTOTYPE((krb5_context,
+	(krb5_context,
 		   krb5_keytab,
-		   krb5_keytab_entry *));
+		   krb5_keytab_entry *);
 
 krb5_error_code krb5_ktfileint_openr 
-	PROTOTYPE((krb5_context,
-		   krb5_keytab));
+	(krb5_context,
+		   krb5_keytab);
 
 krb5_error_code krb5_ktfileint_openw 
-	PROTOTYPE((krb5_context,
-		   krb5_keytab));
+	(krb5_context,
+		   krb5_keytab);
 
 krb5_error_code krb5_ktfileint_close 
-	PROTOTYPE((krb5_context,
-		   krb5_keytab));
+	(krb5_context,
+		   krb5_keytab);
 
 krb5_error_code krb5_ktfileint_read_entry 
-	PROTOTYPE((krb5_context,
+	(krb5_context,
 		   krb5_keytab,
-		   krb5_keytab_entry *));
+		   krb5_keytab_entry *);
 
 krb5_error_code krb5_ktfileint_write_entry 
-	PROTOTYPE((krb5_context,
+	(krb5_context,
 		   krb5_keytab,
-		   krb5_keytab_entry *));
+		   krb5_keytab_entry *);
 
 krb5_error_code krb5_ktfileint_delete_entry 
-	PROTOTYPE((krb5_context,
+	(krb5_context,
 		   krb5_keytab,
-                   krb5_int32));
+                   krb5_int32);
 
 krb5_error_code krb5_ktfileint_internal_read_entry 
-	PROTOTYPE((krb5_context,
+	(krb5_context,
 		   krb5_keytab,
 		   krb5_keytab_entry *,
-                   krb5_int32 *));
+                   krb5_int32 *);
 
 krb5_error_code krb5_ktfileint_size_entry 
-	PROTOTYPE((krb5_context,
+	(krb5_context,
 		   krb5_keytab_entry *,
-                   krb5_int32 *));
+                   krb5_int32 *);
 
 krb5_error_code krb5_ktfileint_find_slot 
-	PROTOTYPE((krb5_context,
+	(krb5_context,
 		   krb5_keytab,
                    krb5_int32 *,
-                   krb5_int32 *));
+                   krb5_int32 *);
 
 
 #endif /* _KRB5_KTFILE */
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/an_to_ln.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/an_to_ln.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -721,14 +721,18 @@
             if (strncmp(krb5_princ_component(context, aname, 1)->data,
 			def_realm, realm_length) ||
 		realm_length !=
-		    krb5_princ_component(context, aname, 1)->length)
+		    krb5_princ_component(context, aname, 1)->length) {
 		    /* XXX an_to_ln_realm_chk ? */
+		free(def_realm);
                 return KRB5_LNAME_NOTRANS;
+	    }
         }
-        else
+        else {
            /* no components or more than one component to non-realm part of name
            --no translation. */
+	    free(def_realm);
             return KRB5_LNAME_NOTRANS;
+	}
     }
 
     free(def_realm);
--- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/kuserok.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/kuserok.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -359,12 +359,14 @@
 }
 
 OM_uint32
-krb5_gss_userok(void *ctxt,
-		OM_uint32 *minor,
+krb5_gss_userok(OM_uint32 *minor,
 		const gss_name_t pname,
 		const char *user,
 		int *user_ok)
 {
+	krb5_context ctxt;
+	OM_uint32 kret;
+
 	if (pname == NULL || user == NULL)
 		return (GSS_S_CALL_INACCESSIBLE_READ);
 
@@ -373,13 +375,22 @@
 
 	*user_ok = 0;
 
+	kret = krb5_gss_init_context(&ctxt); 
+	if (kret) { 
+		*minor = kret; 
+		return (GSS_S_FAILURE); 
+	}
+
 	if (! kg_validate_name(pname)) {
-                 *minor = (OM_uint32) G_VALIDATE_FAILED;
-                 return (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
+		*minor = (OM_uint32) G_VALIDATE_FAILED;
+		krb5_free_context(ctxt);
+		return (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
 	}
 
 	if (krb5_kuserok(ctxt, (krb5_principal) pname, user)) {
 		*user_ok = 1;
 	}
+
+	krb5_free_context(ctxt);
 	return (GSS_S_COMPLETE);
 }
--- a/usr/src/lib/gss_mechs/mech_krb5/mapfile-vers	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mapfile-vers	Fri Sep 14 15:01:24 2007 -0700
@@ -212,7 +212,6 @@
 	decode_krb5_tgs_rep;
 	decode_krb5_tgs_req;
 	decode_krb5_ticket;
-	display_unknown;
 	encode_krb5_alt_method;
 	encode_krb5_ap_rep;
 	encode_krb5_ap_rep_enc_part;
@@ -247,47 +246,16 @@
 	encode_krb5_tgs_req;
 	encode_krb5_ticket;
 	error_message;
-	g_delete_cred_id;
-	g_delete_ctx_id;
-	g_delete_name;
-	g_display_com_err_status;
-	g_display_major_status;
-	g_local_host_name;
-	g_make_string_buffer;
-	g_make_token_header;
-	g_order_check;
-	g_order_free;
-	g_order_init;
-	g_queue_externalize;
-	g_queue_internalize;
-	g_queue_size;
-	g_save_cred_id;
-	g_save_ctx_id;
-	g_save_name;
-	g_set_destroy;
-	g_set_entry_add;
-	g_set_entry_delete;
-	g_set_entry_get;
-	g_set_init;
-	g_strdup;
-	g_token_size;
-	g_validate_cred_id;
-	g_validate_ctx_id;
-	g_validate_name;
-	g_verify_token_header;
 	ggss_error_table;
 	gmt_mktime;
+	gss_krb5int_get_tkt_flags;
 	gss_krb5_ccache_name;
 	gss_krb5_copy_ccache;
-	gss_krb5_get_tkt_flags;
 	gss_mech_krb5;
 	gss_mech_krb5_old;
-	gss_mech_krb5_v2;
 	gss_mech_set_krb5;
 	gss_mech_set_krb5_both;
 	gss_mech_set_krb5_old;
-	gss_mech_set_krb5_v1v2;
-	gss_mech_set_krb5_v2;
 	gss_nt_krb5_name;
 	gss_nt_krb5_principal;
 	gssspi_acquire_cred_with_password;
@@ -298,25 +266,18 @@
 	kadm_error_table;
 	kdb5_error_table;
 	kdc5_error_table;
-	kg2_parse_token;
-	kg_checksum_channel_bindings;
 	kg_confounder_size;
-	kg_context;
 	kg_ctx_externalize;
 	kg_ctx_internalize;
 	kg_ctx_size;
 	kg_decrypt;
 	kg_encrypt;
 	kg_encrypt_size;
-	kg_get_context;
 	kg_get_defcred;
 	kg_get_seq_num;
 	kg_make_confounder;
 	kg_make_seed;
 	kg_make_seq_num;
-	kg_oid_size;
-	kg_queue_size;
-	kg_release_defcred;
 	kg_seal;
 	kg_unseal;
 	kg_vdb;
@@ -551,7 +512,6 @@
 	krb5_get_validated_creds;
 	krb5_getenv;
 	krb5_gss_import_name;
-	krb5_gss_init_sec_context;
 	krb5_gss_oid_array;
 	krb5_gss_userok;
 	krb5_hmac;
@@ -619,7 +579,6 @@
 	krb5_mk_req;
 	krb5_mk_req_extended;
 	krb5_mk_safe;
-	krb5_mutex;
 	krb5_net_read;
 	krb5_net_write;
 	krb5_nfold;
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/accept_sec_context.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/accept_sec_context.c	Fri Sep 14 15:01:24 2007 -0700
@@ -6,7 +6,7 @@
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
- * Copyright 2000 by the Massachusetts Institute of Technology.
+ * Copyright 2000, 2004  by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -80,20 +80,21 @@
 #include <k5-int.h>
 #include <auth_con.h>
 #include <gssapiP_krb5.h>
+#ifdef HAVE_MEMORY_H
 #include <memory.h>
+#endif
 #include <assert.h>
-#define	CACHENAME_LEN 35
 
 /* Solaris kerberos: XXX kludgy but there is no include file for the
  * krb5_fcc_ops extern declaration.
  */
 extern krb5_cc_ops krb5_fcc_ops;
 
+#ifdef CFX_EXERCISE
+#define CFX_ACCEPTOR_SUBKEY (time(0) & 1)
+#else
 #define CFX_ACCEPTOR_SUBKEY 1
-
-/*
- * $Id: accept_sec_context.c,v 1.51.2.3 2000/06/08 00:25:48 tlyu Exp $
- */
+#endif
 
 /*
  * Decode, decrypt and store the forwarded creds in the local ccache.
@@ -109,6 +110,7 @@
 {
     krb5_creds ** creds;
     krb5_error_code retval;
+    krb5_ccache template_ccache = NULL;
     krb5_ccache ccache = NULL;
     krb5_gss_cred_id_t cred = NULL;
     krb5_auth_context new_auth_ctx = NULL;
@@ -177,13 +179,15 @@
     /* Lots of kludging going on here... Some day the ccache interface
        will be rewritten though */
 
-    retval = krb5_cc_resolve(context, "MEMORY:GSSAPI", &ccache);
+    retval = krb5_cc_resolve(context, "MEMORY:GSSAPI", &template_ccache);
     if (retval) {
 	KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error "
 		"krb5_cc_resolve() retval = %d\n", retval);
 	goto cleanup;
     }
 
+    ccache = template_ccache; /* krb5_cc_gen_new will replace so make a copy */
+
     retval = krb5_cc_gen_new(context, &ccache);
     if (retval) {
 	KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error "
@@ -218,11 +222,19 @@
 	/* zero it out... */
 	(void) memset(cred, 0, sizeof(krb5_gss_cred_id_rec));
 
+ 	retval = k5_mutex_init(&cred->lock);
+	if (retval) {
+	    xfree(cred);
+	    cred = NULL;
+	    goto cleanup;
+	}
+
 	/* copy the client principle into it... */
 	if ((retval = krb5_copy_principal(context, creds[0]->client,
 			&(cred->princ)))) {
 	    KRB5_LOG(KRB5_ERR, "rd_and_store_for_creds() error "
 		    "krb5_copy_principal() retval = %d\n", retval);
+	    k5_mutex_destroy(&cred->lock);
 	    retval = ENOMEM; /* out of memory? */
 	    xfree(cred); /* clean up memory on failure */
 	    *out_cred = cred = NULL;
@@ -231,15 +243,13 @@
 
 	cred->usage = GSS_C_INITIATE; /* we can't accept with this */
 	/* cred->princ already set */
-        cred->actual_mechs = gss_mech_set_krb5_both;
 	cred->prerfc_mech = 1; /* this cred will work with all three mechs */
 	cred->rfc_mech = 1;
 	cred->keytab = NULL; /* no keytab associated with this... */
-	cred->ccache = ccache; /* but there is a credential cache */
         /* The cred expires when the original cred was set to expire */
 	cred->tgt_expire = creds[0]->times.endtime;
-
-    	*out_cred = cred;
+	cred->ccache = ccache; /* the ccache containing the credential */
+	ccache = NULL; /* cred takes ownership so don't destroy */
     }
 
     /* If there were errors, there might have been a memory leak
@@ -248,10 +258,19 @@
        goto cleanup;
     */
 cleanup:
-    krb5_free_tgt_creds(context, creds);
+    if (creds)
+        krb5_free_tgt_creds(context, creds);
+
+    if (ccache)
+	(void)krb5_cc_destroy(context, ccache);
 
-    if (!cred && ccache)
-	(void)krb5_cc_close(context, ccache);
+    /*
+     * SUNW15resync
+     * Added this cc_destroy for template_cache, w/out it causes memory
+     * leak via "ssh -o gssapidelegatecredentials=yes ..."
+     */
+    if (template_ccache)
+	(void)krb5_cc_destroy(context, template_ccache);
 
     if (out_cred)
 	*out_cred = cred; /* return credential */
@@ -265,13 +284,17 @@
     return retval;
 }
 
+/*
+ * SUNW15resync
+ * Most of the logic here left "as is" because of lots of fixes MIT
+ * does not have yet
+ */
 OM_uint32
-krb5_gss_accept_sec_context(ct, minor_status, context_handle,
+krb5_gss_accept_sec_context(minor_status, context_handle,
 			    verifier_cred_handle, input_token,
 			    input_chan_bindings, src_name, mech_type,
 			    output_token, ret_flags, time_rec,
 			    delegated_cred_handle)
-     void *ct;
      OM_uint32 *minor_status;
      gss_ctx_id_t *context_handle;
      gss_cred_id_t verifier_cred_handle;
@@ -284,7 +307,7 @@
      OM_uint32 *time_rec;
      gss_cred_id_t *delegated_cred_handle;
 {
-   krb5_context context = ct;
+   krb5_context context;
    unsigned char *ptr, *ptr2;
    char *sptr;
    long tmp;
@@ -314,17 +337,22 @@
    gss_cred_id_t cred_handle = NULL;
    krb5_gss_cred_id_t deleg_cred = NULL;
    OM_uint32 saved_ap_options = 0;
+   krb5int_access kaccess;
+   int cred_rcache = 0;
 
    KRB5_LOG0(KRB5_INFO,"krb5_gss_accept_sec_context() start");
 
-   mutex_lock(&krb5_mutex);
+   code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
+   if (code) {
+       *minor_status = code;
+       return(GSS_S_FAILURE);
+   }
 
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, &context)))
-      return(GSS_S_FAILURE);
-#endif
+   code = krb5_gss_init_context(&context);
+   if (code) {
+       *minor_status = code;
+       return GSS_S_FAILURE;
+   }
 
    /* set up returns to be freeable */
 
@@ -363,7 +391,7 @@
       major_status = GSS_S_NO_CONTEXT;
       KRB5_LOG0(KRB5_ERR,"krb5_gss_accept_sec_context() "
 	      "error GSS_S_NO_CONTEXT");
-      goto unlock;
+      goto cleanup;
    }
 
    /* verify the token's integrity, and leave the token in ap_req.
@@ -371,13 +399,13 @@
 
    ptr = (unsigned char *) input_token->value;
 
-   if (!(code = g_verify_token_header((gss_OID) gss_mech_krb5,
+   if (!(code = g_verify_token_header(gss_mech_krb5,
 				      (uint32_t *)&(ap_req.length),
 				      &ptr, KG_TOK_CTX_AP_REQ,
 				      input_token->length, 1))) {
        mech_used = gss_mech_krb5;
    } else if ((code == G_WRONG_MECH) &&
-	      !(code = g_verify_token_header((gss_OID) gss_mech_krb5_old,
+	      !(code = g_verify_token_header(gss_mech_krb5_old,
 				     (uint32_t *)&(ap_req.length),
 				     &ptr, KG_TOK_CTX_AP_REQ,
 				     input_token->length, 1))) {
@@ -446,7 +474,7 @@
 	   major_status = GSS_S_FAILURE;
 	   goto fail;
        }
-       major_status = krb5_gss_acquire_cred_no_lock(context, (OM_uint32*) &code,
+       major_status = krb5_gss_acquire_cred((OM_uint32*) &code,
 					    (gss_name_t) princ,
 					    GSS_C_INDEFINITE, GSS_C_NO_OID_SET,
 					    GSS_C_ACCEPT, &cred_handle,
@@ -470,7 +498,7 @@
        cred_handle = verifier_cred_handle;
    }
 
-   major_status = krb5_gss_validate_cred_no_lock(context, (OM_uint32*) &code,
+   major_status = krb5_gss_validate_cred((OM_uint32*) &code,
 						 cred_handle);
 
    if (GSS_ERROR(major_status)){
@@ -527,12 +555,14 @@
    (void) krb5_auth_con_setflags(context, auth_context,
                           KRB5_AUTH_CONTEXT_DO_SEQUENCE);
 
-   if (cred->rcache &&
-       (code = krb5_auth_con_setrcache(context, auth_context, cred->rcache))) {
-       major_status = GSS_S_FAILURE;
-       KRB5_LOG(KRB5_ERR, "krb5_gss_accept_sec_context() "
-	      "krb5_auth_con_setrcache() error code %d", code);
-       goto fail;
+   if (cred->rcache) {
+       cred_rcache = 1;
+       if ((code = krb5_auth_con_setrcache(context, auth_context, cred->rcache))) {
+	    major_status = GSS_S_FAILURE;
+	    KRB5_LOG(KRB5_ERR, "krb5_gss_accept_sec_context() "
+		    "krb5_auth_con_setrcache() error code %d", code);
+	    goto fail;
+       }
    }
    if ((code = krb5_auth_con_setaddrs(context, auth_context, NULL, paddr))) {
        major_status = GSS_S_FAILURE;
@@ -731,24 +761,7 @@
 
    memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec));
 
-   /* Solaris Kerberos:  we allocate the memory for mech_used here
-    * because we store mech_used as a gss_OID and not a (gss_OID *)
-    */
-#if 0
-   ctx->mech_used = mech_used;
-#else
-   /* begin Solaris Kerberos solution */
-   ctx->mech_used.elements = (void *)malloc(mech_used->length);
-   if ( (ctx->mech_used.elements) == NULL )
-   {
-       code = ENOMEM;
-       major_status = GSS_S_FAILURE;
-       goto fail;
-   }
-   ctx->mech_used.length = mech_used->length;
-   memcpy(ctx->mech_used.elements, mech_used->elements, mech_used->length);
-#endif
-
+   ctx->mech_used = (gss_OID) mech_used;
    ctx->auth_context = auth_context;
    ctx->initiate = 0;
    ctx->gss_flags = (GSS_C_TRANS_FLAG |
@@ -757,6 +770,7 @@
                              GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG)));
    ctx->seed_init = 0;
    ctx->big_endian = bigend;
+   ctx->cred_rcache = cred_rcache;
 
    /* Intern the ctx pointer so that delete_sec_context works */
    if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
@@ -970,7 +984,7 @@
        /* the reply token hasn't been sent yet, but that's ok. */
        ctx->gss_flags |= GSS_C_PROT_READY_FLAG;
        ctx->established = 1;
-       token.length = g_token_size((gss_OID) mech_used, ap_rep.length);
+       token.length = g_token_size(mech_used, ap_rep.length);
 
        if ((token.value = (unsigned char *) xmalloc(token.length))
 	   == NULL) {
@@ -979,7 +993,7 @@
 	   goto fail;
        }
        ptr = token.value;
-       g_make_token_header((gss_OID) mech_used, ap_rep.length,
+       g_make_token_header(mech_used, ap_rep.length,
 			   &ptr, KG_TOK_CTX_AP_REP);
 
        TWRITE_STR(ptr, ap_rep.data, ap_rep.length);
@@ -1040,9 +1054,12 @@
  fail:
    if (authdat)
        krb5_free_authenticator(context, authdat);
+   /* The ctx structure has the handle of the auth_context */
    if (auth_context && !ctx) {
-	(void)krb5_auth_con_setrcache(context, auth_context, NULL);
-	krb5_auth_con_free(context, auth_context);
+       if (cred_rcache)
+	   (void)krb5_auth_con_setrcache(context, auth_context, NULL);
+
+       krb5_auth_con_free(context, auth_context);
    }
    if (reqcksum.contents)
        xfree(reqcksum.contents);
@@ -1055,13 +1072,21 @@
 	request = NULL;
    }
 
-   if (!GSS_ERROR(major_status))
-       goto unlock;
+   if (!GSS_ERROR(major_status) && major_status != GSS_S_CONTINUE_NEEDED) {
+	if (!verifier_cred_handle && cred_handle) {
+		krb5_gss_release_cred(minor_status, &cred_handle);
+	}
+
+	if (ctx)
+	    ctx->k5_context = context;
+
+        return(major_status);
+   }
 
    /* from here on is the real "fail" code */
 
    if (ctx)
-       (void) krb5_gss_delete_sec_context_no_lock(context, minor_status,
+	(void) krb5_gss_delete_sec_context(minor_status,
 					  (gss_ctx_id_t *) &ctx, NULL);
    if (deleg_cred) { /* free memory associated with the deleg credential */
        if (deleg_cred->ccache)
@@ -1104,18 +1129,18 @@
 	
        code = krb5_mk_error(context, &krb_error_data, &scratch);
        if (code)
-           goto unlock;
+           goto cleanup;
 
        tmsglen = scratch.length;
        toktype = KG_TOK_CTX_ERROR;
 
-       token.length = g_token_size((gss_OID) mech_used, tmsglen);
+       token.length = g_token_size(mech_used, tmsglen);
        token.value = (unsigned char *) xmalloc(token.length);
        if (!token.value)
-	  goto unlock;
+	  goto cleanup;
 
        ptr = token.value;
-       g_make_token_header((gss_OID) mech_used, tmsglen, &ptr, toktype);
+       g_make_token_header(mech_used, tmsglen, &ptr, toktype);
 
        TWRITE_STR(ptr, scratch.data, scratch.length);
        xfree(scratch.data);
@@ -1123,12 +1148,13 @@
        *output_token = token;
    }
 
-unlock:
+cleanup:
    if (!verifier_cred_handle && cred_handle) {
-      krb5_gss_release_cred_no_lock(context, (OM_uint32*) &code, &cred_handle);
+      krb5_gss_release_cred(minor_status, &cred_handle);
    }
 
-   mutex_unlock(&krb5_mutex);
+   krb5_free_context(context);
+
    KRB5_LOG(KRB5_ERR,"krb5_gss_accept_sec_context() end, "
 	      "major_status = %d", major_status);
    return (major_status);
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred.c	Fri Sep 14 15:01:24 2007 -0700
@@ -13,7 +13,7 @@
  *   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
@@ -27,12 +27,11 @@
  * 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 1993 by OpenVision Technologies, 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
@@ -42,7 +41,7 @@
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
- *
+ * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -54,14 +53,14 @@
 
 /*
  * Copyright (C) 1998 by the FundsXpress, INC.
- *
+ * 
  * 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
@@ -72,24 +71,70 @@
  * permission.  FundsXpress makes no representations about the suitability of
  * this software for any purpose.  It is provided "as is" without express
  * or implied warranty.
- *
+ * 
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#include <gssapiP_krb5.h>
-#include <k5-int.h>
-
+#include "k5-int.h"
+#include "gss_libinit.h"
+#include "gssapiP_krb5.h"
+#include "mglueP.h"
 #ifdef HAVE_STRING_H
 #include <string.h>
 #else
 #include <strings.h>
 #endif
 
-/*
- * $Id: acquire_cred.c,v 1.25.6.2 2000/05/22 20:41:32 meeroh Exp $
- */
+/* SUNW15resync - Solaris kerberos does not need this feature in this file */ 
+#ifdef USE_LOGIN_LIBRARY
+#undef USE_LOGIN_LIBRARY
+#endif
+
+#if defined(USE_LOGIN_LIBRARY)
+#include <Kerberos/KerberosLoginPrivate.h>
+#elif defined(USE_LEASH)
+static void (*pLeash_AcquireInitialTicketsIfNeeded)(krb5_context,krb5_principal,char*,int) = NULL;
+static HANDLE hLeashDLL = INVALID_HANDLE_VALUE;
+#endif
+
+k5_mutex_t gssint_krb5_keytab_lock = K5_MUTEX_PARTIAL_INITIALIZER;
+static char *krb5_gss_keytab = NULL;
+
+/* Heimdal calls this gsskrb5_register_acceptor_identity. */
+OM_uint32 KRB5_CALLCONV
+krb5_gss_register_acceptor_identity(const char *keytab)
+{
+    size_t	len;
+    char *new, *old;
+    int err;
+
+    err = gssint_initialize_library();
+    if (err != 0)
+	return GSS_S_FAILURE;
+
+    if (keytab == NULL)
+	return GSS_S_FAILURE;
+
+    len = strlen(keytab);
+    new = malloc(len + 1);
+    if (new == NULL)
+	return GSS_S_FAILURE;
+    strcpy(new, keytab);
+
+    err = k5_mutex_lock(&gssint_krb5_keytab_lock);
+    if (err) {
+	free(new);
+	return GSS_S_FAILURE;
+    }
+    old = krb5_gss_keytab;
+    krb5_gss_keytab = new;
+    k5_mutex_unlock(&gssint_krb5_keytab_lock);
+    if (old != NULL)
+	free(old);
+    return GSS_S_COMPLETE;
+}
 
 /* get credentials corresponding to a key in the krb5 keytab.
    If the default name is requested, return the name in output_princ.
@@ -98,7 +143,7 @@
    If successful, set the keytab-specific fields in cred
    */
 
-static OM_uint32
+static OM_uint32 
 acquire_accept_cred(context, minor_status, desired_name, output_princ, cred)
      krb5_context context;
      OM_uint32 *minor_status;
@@ -116,9 +161,27 @@
 
    /* open the default keytab */
 
-   if ((code = krb5_kt_default(context, &kt))) {
+   code = gssint_initialize_library();
+   if (code != 0) {
+       *minor_status = code;
+       return GSS_S_FAILURE;
+   }
+   code = k5_mutex_lock(&gssint_krb5_keytab_lock);
+   if (code) {
+       *minor_status = code;
+       return GSS_S_FAILURE;
+   }
+   if (krb5_gss_keytab != NULL) {
+      code = krb5_kt_resolve(context, krb5_gss_keytab, &kt);
+      k5_mutex_unlock(&gssint_krb5_keytab_lock);
+   } else {
+      k5_mutex_unlock(&gssint_krb5_keytab_lock);
+      code = krb5_kt_default(context, &kt);
+   }
+
+   if (code) {
       *minor_status = code;
-      /* NOTE: GSS_S_CRED_UNAVAIL is not RFC 2743 compliant */
+      /* Solaris Kerb NOTE: GSS_S_CRED_UNAVAIL is not RFC 2743 compliant */
       return(GSS_S_NO_CRED);
    }
 
@@ -130,7 +193,7 @@
 	    *minor_status = KG_KEYTAB_NOMATCH;
 	 else
 	    *minor_status = code;
-      /* NOTE: GSS_S_CRED_UNAVAIL is not RFC 2743 compliant */
+	 /* Solaris Kerb NOTE: GSS_S_CRED_UNAVAIL is not RFC 2743 compliant */
 	 return(GSS_S_NO_CRED);
       }
       krb5_kt_free_entry(context, &entry);
@@ -145,7 +208,7 @@
 
    }
 
-   /* hooray.  we made it */
+/* hooray.  we made it */
 
    cred->keytab = kt;
 
@@ -159,7 +222,7 @@
    If successful, set the ccache-specific fields in cred.
    */
 
-static OM_uint32
+static OM_uint32 
 acquire_init_cred(context, minor_status, desired_name, output_princ, cred)
      krb5_context context;
      OM_uint32 *minor_status;
@@ -177,19 +240,77 @@
 
    cred->ccache = NULL;
 
-   /* SUNW14resync - do we need this? */
-#if 0
    /* load the GSS ccache name into the kg_context */
+   
    if (GSS_ERROR(kg_sync_ccache_name(context, minor_status)))
        return(GSS_S_FAILURE);
-#endif
-
-   /* open the default credential cache */
 
-   code = krb5int_cc_default(context, &ccache);
-   if (code) {
-      *minor_status = code;
-      return(GSS_S_NO_CRED);
+#if defined(USE_LOGIN_LIBRARY) || defined(USE_LEASH)
+   if (desired_name != NULL) {
+#if defined(USE_LOGIN_LIBRARY)
+       char *ccache_name = NULL;
+       KLPrincipal kl_desired_princ = NULL;
+       
+       if ((code = __KLCreatePrincipalFromKerberos5Principal ((krb5_principal) desired_name,
+                                                              &kl_desired_princ))) {
+           *minor_status = code;
+           return(GSS_S_NO_CRED);
+       }
+       
+       if ((code = KLAcquireInitialTickets (kl_desired_princ, NULL, NULL, &ccache_name))) {
+           KLDisposePrincipal (kl_desired_princ);
+           *minor_status = code;
+           return(GSS_S_NO_CRED);
+       }
+       
+       if ((code = krb5_cc_resolve (context, ccache_name, &ccache))) {
+           KLDisposeString (ccache_name);
+           KLDisposePrincipal (kl_desired_princ);
+           *minor_status = code;
+           return(GSS_S_NO_CRED);
+       }
+   
+       if (kl_desired_princ != NULL) { KLDisposePrincipal (kl_desired_princ); }
+       if (ccache_name      != NULL) { KLDisposeString (ccache_name); }
+#elif defined(USE_LEASH)
+       if ( hLeashDLL == INVALID_HANDLE_VALUE ) {
+	   hLeashDLL = LoadLibrary("leashw32.dll");
+	   if ( hLeashDLL != INVALID_HANDLE_VALUE ) {
+	       (FARPROC) pLeash_AcquireInitialTicketsIfNeeded =
+		   GetProcAddress(hLeashDLL, "not_an_API_Leash_AcquireInitialTicketsIfNeeded");
+	   }
+       }
+    
+       if ( pLeash_AcquireInitialTicketsIfNeeded ) {
+	   char ccname[256]="";
+	   pLeash_AcquireInitialTicketsIfNeeded(context, (krb5_principal) desired_name, ccname, sizeof(ccname));
+	   if (!ccname[0]) {
+	       *minor_status = KRB5_CC_NOTFOUND;
+	       return(GSS_S_NO_CRED);
+	   }
+
+	   if ((code = krb5_cc_resolve (context, ccname, &ccache))) {
+	       *minor_status = code;
+	       return(GSS_S_NO_CRED);
+	   }
+       } else {
+	   /* leash dll not available, open the default credential cache */
+   
+	   if ((code = krb5int_cc_default(context, &ccache))) {
+	       *minor_status = code;
+	       return(GSS_S_NO_CRED);
+	   }
+       }
+#endif /* USE_LEASH */
+   } else
+#endif /* USE_LOGIN_LIBRARY || USE_LEASH */
+   {
+       /* open the default credential cache */
+   
+       if ((code = krb5int_cc_default(context, &ccache))) {
+	   *minor_status = code;
+	   return(GSS_S_NO_CRED);
+       }
    }
 
    /* turn off OPENCLOSE mode while extensive frobbing is going on */
@@ -200,7 +321,7 @@
     * the file like it used to and caused STC test gss.27 to fail.
     */
    flags = 0;		/* turns off OPENCLOSE mode */
-   if ((code = krb5_cc_set_flags(context, ccache, flags)) != 0) {
+   if ((code = krb5_cc_set_flags(context, ccache, flags))) {
       (void)krb5_cc_close(context, ccache);
       *minor_status = code;
       return(GSS_S_NO_CRED);
@@ -208,7 +329,7 @@
 
    /* get out the principal name and see if it matches */
 
-   if ((code = krb5_cc_get_principal(context, ccache, &princ)) != 0) {
+   if ((code = krb5_cc_get_principal(context, ccache, &princ))) {
       (void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE);
       (void)krb5_cc_close(context, ccache);
       *minor_status = code;
@@ -218,7 +339,7 @@
    if (desired_name != (gss_name_t) NULL) {
       if (! krb5_principal_compare(context, princ, (krb5_principal) desired_name)) {
 	 (void)krb5_free_principal(context, princ);
-         (void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE);
+	 (void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE);
 	 (void)krb5_cc_close(context, ccache);
 	 *minor_status = KG_CCACHE_NOMATCH;
 	 return(GSS_S_NO_CRED);
@@ -231,7 +352,7 @@
 
    /* iterate over the ccache, find the tgt */
 
-   if ((code = krb5_cc_start_seq_get(context, ccache, &cur)) != 0) {
+   if ((code = krb5_cc_start_seq_get(context, ccache, &cur))) {
       (void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE);
       (void)krb5_cc_close(context, ccache);
       *minor_status = code;
@@ -257,7 +378,7 @@
       *minor_status = code;
       return(GSS_S_FAILURE);
    }
-   while ((code = krb5_cc_next_cred(context, ccache, &cur, &creds)) == 0) {
+   while (!(code = krb5_cc_next_cred(context, ccache, &cur, &creds))) {
       if (krb5_principal_compare(context, tmp_princ, creds.server)) {
 	 cred->tgt_expire = creds.times.endtime;
 	 got_endtime = 1;
@@ -290,14 +411,14 @@
       return(GSS_S_FAILURE);
    } else {
       /* this means that we found an endtime to use. */
-      if ((code = krb5_cc_end_seq_get(context, ccache, &cur)) != 0) {
+      if ((code = krb5_cc_end_seq_get(context, ccache, &cur))) {
 	 (void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE);
 	 (void)krb5_cc_close(context, ccache);
 	 *minor_status = code;
 	 return(GSS_S_FAILURE);
       }
       flags = KRB5_TC_OPENCLOSE;	/* turns on OPENCLOSE mode */
-      if ((code = krb5_cc_set_flags(context, ccache, flags)) != 0) {
+      if ((code = krb5_cc_set_flags(context, ccache, flags))) {
 	 (void)krb5_cc_close(context, ccache);
 	 *minor_status = code;
 	 return(GSS_S_FAILURE);
@@ -310,37 +431,12 @@
    /* minor_status is set while we are iterating over the ccache */
    return(GSS_S_COMPLETE);
 }
-
+   
+/*ARGSUSED*/
 OM_uint32
-krb5_gss_acquire_cred(ctx, minor_status, desired_name, time_req,
+krb5_gss_acquire_cred(minor_status, desired_name, time_req,
 		      desired_mechs, cred_usage, output_cred_handle,
 		      actual_mechs, time_rec)
-     void *ctx;
-     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_cred_id_t *output_cred_handle;
-     gss_OID_set *actual_mechs;
-     OM_uint32 *time_rec;
-{
-    OM_uint32 ret;
-
-    mutex_lock(&krb5_mutex);
-    ret = krb5_gss_acquire_cred_no_lock(ctx, minor_status, desired_name,
-	    time_req, desired_mechs, cred_usage, output_cred_handle,
-	    actual_mechs, time_rec);
-    mutex_unlock(&krb5_mutex);
-    return(ret);
-}
-
-/*ARGSUSED*/
-OM_uint32
-krb5_gss_acquire_cred_no_lock(ctx, minor_status, desired_name, time_req,
-		      desired_mechs, cred_usage, output_cred_handle,
-		      actual_mechs, time_rec)
-     void *ctx;
      OM_uint32 *minor_status;
      gss_name_t desired_name;
      OM_uint32 time_req;
@@ -353,20 +449,22 @@
    krb5_context context;
    size_t i;
    krb5_gss_cred_id_t cred;
-   gss_OID_set ret_mechs = GSS_C_NULL_OID_SET;
-   const gss_OID_set_desc * valid_mechs;
+   gss_OID_set ret_mechs;
    int req_old, req_new;
    OM_uint32 ret;
    krb5_error_code code;
 
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, &context)))
-      return(GSS_S_FAILURE);
-#endif
+   code = gssint_initialize_library();
+   if (code) {
+       *minor_status = code;
+       return GSS_S_FAILURE;
+   }
 
-   context = ctx;
+   code = krb5_gss_init_context(&context);
+   if (code) {
+       *minor_status = code;
+       return GSS_S_FAILURE;
+   }
 
    /* make sure all outputs are valid */
 
@@ -382,6 +480,7 @@
    if ((desired_name != (gss_name_t) NULL) &&
        (! kg_validate_name(desired_name))) {
       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+      krb5_free_context(context);
       return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
    }
 
@@ -389,7 +488,6 @@
       contains krb5 */
 
    if (desired_mechs == GSS_C_NULL_OID_SET) {
-      valid_mechs = gss_mech_set_krb5_both;
       req_old = 1;
       req_new = 1;
    } else {
@@ -405,6 +503,7 @@
 
       if (!req_old && !req_new) {
 	 *minor_status = 0;
+	 krb5_free_context(context);
 	 return(GSS_S_BAD_MECH);
       }
    }
@@ -414,24 +513,36 @@
    if ((cred =
 	(krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec))) == NULL) {
       *minor_status = ENOMEM;
+      krb5_free_context(context);
       return(GSS_S_FAILURE);
    }
    memset(cred, 0, sizeof(krb5_gss_cred_id_rec));
 
    cred->usage = cred_usage;
    cred->princ = NULL;
-   cred->actual_mechs = valid_mechs;
    cred->prerfc_mech = req_old;
    cred->rfc_mech = req_new;
 
    cred->keytab = NULL;
    cred->ccache = NULL;
 
+   code = k5_mutex_init(&cred->lock);
+   if (code) {
+       *minor_status = code;
+       krb5_free_context(context);
+       return GSS_S_FAILURE;
+   }
+   /* Note that we don't need to lock this GSSAPI credential record
+      here, because no other thread can gain access to it until we
+      return it.  */
+
    if ((cred_usage != GSS_C_INITIATE) &&
        (cred_usage != GSS_C_ACCEPT) &&
        (cred_usage != GSS_C_BOTH)) {
+      k5_mutex_destroy(&cred->lock);
       xfree(cred);
       *minor_status = (OM_uint32) G_BAD_USAGE;
+      krb5_free_context(context);
       return(GSS_S_FAILURE);
    }
 
@@ -445,8 +556,10 @@
 	  != GSS_S_COMPLETE) {
 	 if (cred->princ)
 	    krb5_free_principal(context, cred->princ);
-	 xfree(cred);
+         k5_mutex_destroy(&cred->lock);
+         xfree(cred);
 	 /* minor_status set by acquire_accept_cred() */
+	 krb5_free_context(context);
 	 return(ret);
       }
 
@@ -462,18 +575,21 @@
 			     &(cred->princ), cred))
 	  != GSS_S_COMPLETE) {
 	 if (cred->keytab)
-	    (void) krb5_kt_close(context, cred->keytab);
+	    krb5_kt_close(context, cred->keytab);
 	 if (cred->princ)
 	    krb5_free_principal(context, cred->princ);
-	 xfree(cred);
+         k5_mutex_destroy(&cred->lock);
+         xfree(cred);
 	 /* minor_status set by acquire_init_cred() */
+	 krb5_free_context(context);
 	 return(ret);
       }
 
    /* Solaris Kerberos:
-    * if the princ wasn't filled in already, fill it in now unless 
+    * if the princ wasn't filled in already, fill it in now unless
     * a cred with no associated princ is requested (will invoke default
     * behaviour when gss_accept_init_context() is called).
+    * Note MIT 1.4 has GSS_C_NO_CREDENTIAL instead of GSS_C_NO_NAME
     */
    if (!cred->princ && (desired_name != GSS_C_NO_NAME))
       if ((code = krb5_copy_principal(context, (krb5_principal) desired_name,
@@ -482,8 +598,10 @@
 	    (void)krb5_cc_close(context, cred->ccache);
 	 if (cred->keytab)
 	    (void)krb5_kt_close(context, cred->keytab);
-	 xfree(cred);
+         k5_mutex_destroy(&cred->lock);
+         xfree(cred);
 	 *minor_status = code;
+	 krb5_free_context(context);
 	 return(GSS_S_FAILURE);
       }
 
@@ -504,8 +622,10 @@
 	    (void)krb5_kt_close(context, cred->keytab);
 	 if (cred->princ)
 	    krb5_free_principal(context, cred->princ);
-	 xfree(cred);
+         k5_mutex_destroy(&cred->lock);
+         xfree(cred);
 	 *minor_status = code;
+	 krb5_free_context(context);
 	 return(GSS_S_FAILURE);
       }
 
@@ -516,15 +636,15 @@
    /* create mechs */
 
    if (actual_mechs) {
-       if (GSS_ERROR(ret = gss_create_empty_oid_set(minor_status,
+       if (GSS_ERROR(ret = generic_gss_create_empty_oid_set(minor_status,
 							    &ret_mechs)) ||
 	   (cred->prerfc_mech &&
-	    GSS_ERROR(ret = gss_add_oid_set_member(minor_status,
-							   (gss_OID) gss_mech_krb5_old,
+	    GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
+							(const gss_OID) gss_mech_krb5_old,
 							   &ret_mechs))) ||
 	   (cred->rfc_mech &&
-	    GSS_ERROR(ret = gss_add_oid_set_member(minor_status,
-							   (gss_OID) gss_mech_krb5,
+	    GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
+							(const gss_OID)	   gss_mech_krb5,
 							   &ret_mechs)))) {
 	   if (cred->ccache)
 	       (void)krb5_cc_close(context, cred->ccache);
@@ -532,8 +652,10 @@
 	       (void)krb5_kt_close(context, cred->keytab);
 	   if (cred->princ)
 	       krb5_free_principal(context, cred->princ);
+           k5_mutex_destroy(&cred->lock);
 	   xfree(cred);
-	   /* (*minor_status) set above */
+	   /* *minor_status set above */
+	   krb5_free_context(context);
 	   return(ret);
        }
    }
@@ -541,7 +663,6 @@
    /* intern the credential handle */
 
    if (! kg_save_cred_id((gss_cred_id_t) cred)) {
-      (void) gss_release_oid_set(NULL, &ret_mechs);
       free(ret_mechs->elements);
       free(ret_mechs);
       if (cred->ccache)
@@ -550,8 +671,10 @@
 	 (void)krb5_kt_close(context, cred->keytab);
       if (cred->princ)
 	 krb5_free_principal(context, cred->princ);
+      k5_mutex_destroy(&cred->lock);
       xfree(cred);
       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+      krb5_free_context(context);
       return(GSS_S_FAILURE);
    }
 
@@ -561,5 +684,7 @@
    *output_cred_handle = (gss_cred_id_t) cred;
    if (actual_mechs)
       *actual_mechs = ret_mechs;
+
+   krb5_free_context(context);
    return(GSS_S_COMPLETE);
 }
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred_with_pw.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/acquire_cred_with_pw.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -78,6 +78,7 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
+#include "gss_libinit.h"
 #include <gssapiP_krb5.h>
 #include <k5-int.h>
 
@@ -203,12 +204,11 @@
 
 /*ARGSUSED*/
 OM_uint32
-krb5_gss_acquire_cred_with_password_no_lock(ctx, minor_status,
+krb5_gss_acquire_cred_with_password(minor_status,
 				desired_name, password, time_req,
 				desired_mechs, cred_usage,
 				output_cred_handle, actual_mechs,
 				time_rec)
-void *ctx;
 OM_uint32 *minor_status;
 gss_name_t desired_name;
 const gss_buffer_t password;
@@ -228,16 +228,21 @@
 	OM_uint32 ret;
 	krb5_error_code code;
 
-#if 0
-	if (GSS_ERROR(kg_get_context(minor_status, &context)))
-		return (GSS_S_FAILURE);
-#endif
-
-	context = ctx;
-
 	if (desired_name == GSS_C_NO_NAME)
 		return (GSS_S_BAD_NAME);
 
+	code = gssint_initialize_library();
+	if (code) {
+		*minor_status = code;
+		return (GSS_S_FAILURE);
+	}
+
+	code = krb5_gss_init_context(&context);
+	if (code) {
+		*minor_status = code;
+		return (GSS_S_FAILURE);
+	}
+
 	/* make sure all outputs are valid */
 
 	*output_cred_handle = NULL;
@@ -249,6 +254,7 @@
 	/* validate the name */
 	if (!kg_validate_name(desired_name)) {
 		*minor_status = (OM_uint32) G_VALIDATE_FAILED;
+		krb5_free_context(context);
 		return (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
 	}
 
@@ -276,6 +282,7 @@
 
 		if (!req_old && !req_new) {
 			*minor_status = 0;
+			krb5_free_context(context);
 			return (GSS_S_BAD_MECH);
 		}
 	}
@@ -284,13 +291,13 @@
 	if ((cred = (krb5_gss_cred_id_t)
 		    xmalloc(sizeof (krb5_gss_cred_id_rec))) == NULL) {
 		*minor_status = ENOMEM;
+		krb5_free_context(context);
 		return (GSS_S_FAILURE);
 	}
 	memset(cred, 0, sizeof (krb5_gss_cred_id_rec));
 
 	cred->usage = cred_usage;
 	cred->princ = NULL;
-	cred->actual_mechs = valid_mechs;
 	cred->prerfc_mech = req_old;
 	cred->rfc_mech = req_new;
 
@@ -302,6 +309,7 @@
 			(cred_usage != GSS_C_BOTH)) {
 		xfree(cred);
 		*minor_status = (OM_uint32) G_BAD_USAGE;
+		krb5_free_context(context);
 		return (GSS_S_FAILURE);
 	}
 
@@ -319,6 +327,7 @@
 			if (cred->princ)
 				krb5_free_principal(context, cred->princ);
 			xfree(cred);
+			krb5_free_context(context);
 			/* minor_status set by acquire_accept_cred() */
 			return (ret);
 		}
@@ -340,6 +349,7 @@
 			if (cred->princ)
 				krb5_free_principal(context, cred->princ);
 			xfree(cred);
+			krb5_free_context(context);
 			/* minor_status set by acquire_init_cred() */
 			return (ret);
 		}
@@ -355,6 +365,7 @@
 				(void) krb5_kt_close(context, cred->keytab);
 			xfree(cred);
 			*minor_status = code;
+			krb5_free_context(context);
 			return (GSS_S_FAILURE);
 		}
 
@@ -377,6 +388,7 @@
 				krb5_free_principal(context, cred->princ);
 			xfree(cred);
 			*minor_status = code;
+			krb5_free_context(context);
 			return (GSS_S_FAILURE);
 		}
 
@@ -405,6 +417,7 @@
 			if (cred->princ)
 				krb5_free_principal(context, cred->princ);
 			xfree(cred);
+			krb5_free_context(context);
 			/* (*minor_status) set above */
 			return (ret);
 		}
@@ -423,12 +436,14 @@
 		if (cred->princ)
 			krb5_free_principal(context, cred->princ);
 		xfree(cred);
+		krb5_free_context(context);
 		*minor_status = (OM_uint32) G_VALIDATE_FAILED;
 		return (GSS_S_FAILURE);
 	}
 
+	krb5_free_context(context);
+
 	/* return success */
-
 	*minor_status = 0;
 	*output_cred_handle = (gss_cred_id_t)cred;
 	if (actual_mechs)
@@ -436,6 +451,7 @@
 	return (GSS_S_COMPLETE);
 }
 
+/*ARGSUSED*/
 OM_uint32
 gssspi_acquire_cred_with_password(ctx, minor_status, desired_name,
 		password, time_req, desired_mechs, cred_usage,
@@ -453,10 +469,8 @@
 {
 	OM_uint32 ret;
 
-	mutex_lock(&krb5_mutex);
-	ret = krb5_gss_acquire_cred_with_password_no_lock(ctx, minor_status,
+	ret = krb5_gss_acquire_cred_with_password(minor_status,
 			desired_name, password, time_req, desired_mechs,
 			cred_usage, output_cred_handle, actual_mechs, time_rec);
-	mutex_unlock(&krb5_mutex);
 	return (ret);
 }
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/add_cred.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/add_cred.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,8 +1,3 @@
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
@@ -13,7 +8,7 @@
  *   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
@@ -27,18 +22,18 @@
  * 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 (C) 1998 by the FundsXpress, INC.
- *
+ * 
  * 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
@@ -49,15 +44,13 @@
  * permission.  FundsXpress makes no representations about the suitability of
  * this software for any purpose.  It is provided "as is" without express
  * or implied warranty.
- *
+ * 
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#include <gssapiP_krb5.h>
-#include <gssapiP_generic.h>
-#include <k5-int.h>
+#include "gssapiP_krb5.h"
 #ifdef HAVE_STRING_H
 #include <string.h>
 #else
@@ -65,19 +58,16 @@
 #endif
 
 /*
- * $Id: add_cred.c,v 1.2.6.2 2000/05/03 20:00:26 raeburn Exp $
+ * $Id: add_cred.c 18015 2006-05-17 05:26:12Z raeburn $
  */
 
 /* V2 interface */
-/*ARGSUSED*/
 OM_uint32
-krb5_gss_add_cred(ct, minor_status, input_cred_handle,
+krb5_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,
+		  output_cred_handle, actual_mechs, 
 		  initiator_time_rec, acceptor_time_rec)
-
-    void *		ct;
     OM_uint32		*minor_status;
     gss_cred_id_t	input_cred_handle;
     gss_name_t		desired_name;
@@ -90,13 +80,10 @@
     OM_uint32		*initiator_time_rec;
     OM_uint32		*acceptor_time_rec;
 {
-    krb5_context	context = ct;
-    OM_uint32		lifetime;
+    krb5_context	context;
+    OM_uint32		major_status, lifetime;
     krb5_gss_cred_id_t	cred;
     krb5_error_code	code;
-    OM_uint32 		major_status = GSS_S_FAILURE;
-
-    *minor_status = 0;
 
     /* this is pretty simple, since there's not really any difference
        between the underlying mechanisms.  The main hair is in copying
@@ -104,8 +91,7 @@
 
     /* check if the desired_mech is bogus */
 
-    if (!g_OID_equal(desired_mech, gss_mech_krb5_v2) &&
-	!g_OID_equal(desired_mech, gss_mech_krb5) &&
+    if (!g_OID_equal(desired_mech, gss_mech_krb5) &&
 	!g_OID_equal(desired_mech, gss_mech_krb5_old)) {
 	*minor_status = 0;
 	return(GSS_S_BAD_MECH);
@@ -129,22 +115,21 @@
 	return(GSS_S_DUPLICATE_ELEMENT);
     }
 
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-    if (GSS_ERROR(kg_get_context(minor_status, (krb5_context*) &context)))
-	return(GSS_S_FAILURE);
-#endif
+    code = krb5_gss_init_context(&context);
+    if (code) {
+	*minor_status = code;
+	return GSS_S_FAILURE;
+    }
 
-    mutex_lock(&krb5_mutex);
-
-    /* verify the credential */
-    if (GSS_ERROR(major_status = krb5_gss_validate_cred_no_lock(&context,
-	minor_status, input_cred_handle))) {
-	goto unlock;
+    major_status = krb5_gss_validate_cred_1(minor_status, input_cred_handle,
+					    context);
+    if (GSS_ERROR(major_status)) {
+	krb5_free_context(context);
+	return major_status;
     }
 
     cred = (krb5_gss_cred_id_t) input_cred_handle;
+    k5_mutex_assert_locked(&cred->lock);
 
     /* check if the cred_usage is equal or "less" than the passed-in cred
        if copying */
@@ -152,9 +137,9 @@
     if (!((cred->usage == cred_usage) ||
 	  ((cred->usage == GSS_C_BOTH) &&
 	   (output_cred_handle != NULL)))) {
-	*minor_status = (OM_uint32) G_BAD_USAGE;
-	major_status = GSS_S_FAILURE;
-	goto unlock;
+      *minor_status = (OM_uint32) G_BAD_USAGE;
+      krb5_free_context(context);
+      return(GSS_S_FAILURE);
     }
 
     /* check that desired_mech isn't already in the credential */
@@ -162,8 +147,13 @@
     if ((g_OID_equal(desired_mech, gss_mech_krb5_old) && cred->prerfc_mech) ||
 	(g_OID_equal(desired_mech, gss_mech_krb5) && cred->rfc_mech)) {
 	*minor_status = 0;
-	major_status = GSS_S_DUPLICATE_ELEMENT;
-	goto unlock;
+	krb5_free_context(context);
+	return(GSS_S_DUPLICATE_ELEMENT);
+    }
+
+    if (GSS_ERROR(kg_sync_ccache_name(context, minor_status))) {
+	krb5_free_context(context);
+	return GSS_S_FAILURE;
     }
 
     /* verify the desired_name */
@@ -172,8 +162,8 @@
     if ((desired_name != (gss_name_t) NULL) &&
 	(! kg_validate_name(desired_name))) {
 	*minor_status = (OM_uint32) G_VALIDATE_FAILED;
-	major_status = (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
-	goto unlock;
+	krb5_free_context(context);
+	return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
     }
 
     /* make sure the desired_name is the same as the existing one */
@@ -182,8 +172,8 @@
 	!krb5_principal_compare(context, (krb5_principal) desired_name,
 				cred->princ)) {
 	*minor_status = 0;
-	major_status = GSS_S_BAD_NAME;
-	goto unlock;
+	krb5_free_context(context);
+	return(GSS_S_BAD_NAME);
     }
 
     /* copy the cred if necessary */
@@ -199,8 +189,8 @@
 	     (krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec)))
 	    == NULL) {
 	    *minor_status = ENOMEM;
-	    major_status = GSS_S_FAILURE;
-	    goto unlock;
+	    krb5_free_context(context);
+	    return(GSS_S_FAILURE);
 	}
 	memset(new_cred, 0, sizeof(krb5_gss_cred_id_rec));
 	
@@ -209,48 +199,54 @@
 	new_cred->rfc_mech = cred->rfc_mech;
 	new_cred->tgt_expire = cred->tgt_expire;
 
-	if (code = krb5_copy_principal(context, cred->princ,
-				       &new_cred->princ)) {
-	    free(new_cred);
+	if (cred->princ)
+	    code = krb5_copy_principal(context, cred->princ, &new_cred->princ);
+	if (code) {
+	    xfree(new_cred);
 
 	    *minor_status = code;
-	    major_status = GSS_S_FAILURE;
-	    goto unlock;
+	    krb5_free_context(context);
+	    return(GSS_S_FAILURE);
 	}
-	
+	    
 	if (cred->keytab) {
 	    kttype = krb5_kt_get_type(context, cred->keytab);
 	    if ((strlen(kttype)+2) > sizeof(ktboth)) {
-		krb5_free_principal(context, new_cred->princ);
-		free(new_cred);
+		if (new_cred->princ)
+		    krb5_free_principal(context, new_cred->princ);
+		xfree(new_cred);
 
 		*minor_status = ENOMEM;
-		major_status = GSS_S_FAILURE;
-		goto unlock;
+		krb5_free_context(context);
+		return(GSS_S_FAILURE);
 	    }
 
 	    strncpy(ktboth, kttype, sizeof(ktboth) - 1);
 	    ktboth[sizeof(ktboth) - 1] = '\0';
 	    strncat(ktboth, ":", sizeof(ktboth) - 1 - strlen(ktboth));
 
-	    code = krb5_kt_get_name(context, cred->keytab,
-		ktboth+strlen(ktboth), sizeof(ktboth)-strlen(ktboth));
+	    code = krb5_kt_get_name(context, cred->keytab, 
+				    ktboth+strlen(ktboth),
+				    sizeof(ktboth)-strlen(ktboth));
 	    if (code) {
-		krb5_free_principal(context, new_cred->princ);
-		free(new_cred);
+		if(new_cred->princ)
+		    krb5_free_principal(context, new_cred->princ);
+		xfree(new_cred);
 
 		*minor_status = code;
-		major_status = GSS_S_FAILURE;
-		goto unlock;
+		krb5_free_context(context);
+		return(GSS_S_FAILURE);
 	    }
 
-	    if (code = krb5_kt_resolve(context, ktboth, &new_cred->keytab)) {
+	    code = krb5_kt_resolve(context, ktboth, &new_cred->keytab);
+	    if (code) {
+		if (new_cred->princ)
 		krb5_free_principal(context, new_cred->princ);
-		free(new_cred);
+		xfree(new_cred);
 
 		*minor_status = code;
-		major_status = GSS_S_FAILURE;
-		goto unlock;
+		krb5_free_context(context);
+		return(GSS_S_FAILURE);
 	    }
 	} else {
 	    new_cred->keytab = NULL;
@@ -263,12 +259,13 @@
 					       &new_cred->rcache))) {
 		if (new_cred->keytab)
 		    krb5_kt_close(context, new_cred->keytab);
-		krb5_free_principal(context, new_cred->princ);
-		free(new_cred);
+		if (new_cred->princ)
+		    krb5_free_principal(context, new_cred->princ);
+		xfree(new_cred);
 
+		krb5_free_context(context);
 		*minor_status = code;
-		major_status = GSS_S_FAILURE;
-		goto unlock;
+		return(GSS_S_FAILURE);
 	    }
 	} else {
 	    new_cred->rcache = NULL;
@@ -283,12 +280,13 @@
 		    krb5_rc_close(context, new_cred->rcache);
 		if (new_cred->keytab)
 		    krb5_kt_close(context, new_cred->keytab);
+		if (new_cred->princ)
 		krb5_free_principal(context, new_cred->princ);
-		free(new_cred);
+		xfree(new_cred);
 
+		krb5_free_context(context);
 		*minor_status = ENOMEM;
-		major_status = GSS_S_FAILURE;
-		goto unlock;
+		return(GSS_S_FAILURE);
 	    }
 
 	    strncpy(ccboth, cctype, sizeof(ccboth) - 1);
@@ -296,17 +294,19 @@
 	    strncat(ccboth, ":", sizeof(ccboth) - 1 - strlen(ccboth));
 	    strncat(ccboth, ccname, sizeof(ccboth) - 1 - strlen(ccboth));
 
-	    if (code = krb5_cc_resolve(context, ccboth, &new_cred->ccache)) {
+	    code = krb5_cc_resolve(context, ccboth, &new_cred->ccache);
+	    if (code) {
 		if (new_cred->rcache)
 		    krb5_rc_close(context, new_cred->rcache);
 		if (new_cred->keytab)
 		    krb5_kt_close(context, new_cred->keytab);
-		krb5_free_principal(context, new_cred->princ);
-		free(new_cred);
+		if (new_cred->princ)
+		    krb5_free_principal(context, new_cred->princ);
+		xfree(new_cred);
+		krb5_free_context(context);
 
 		*minor_status = code;
-		major_status = GSS_S_FAILURE;
-		goto unlock;
+		return(GSS_S_FAILURE);
 	    }
 	} else {
 	    new_cred->ccache = NULL;
@@ -321,12 +321,13 @@
 		krb5_rc_close(context, new_cred->rcache);
 	    if (new_cred->keytab)
 		krb5_kt_close(context, new_cred->keytab);
+	    if (new_cred->princ)
 	    krb5_free_principal(context, new_cred->princ);
-	    free(new_cred);
+	    xfree(new_cred);
+	    krb5_free_context(context);
 
 	    *minor_status = (OM_uint32) G_VALIDATE_FAILED;
-	    major_status = GSS_S_FAILURE;
-	    goto unlock;
+	    return(GSS_S_FAILURE);
 	}
 
 	/* modify new_cred */
@@ -343,18 +344,17 @@
 
     /* set the outputs */
 
-    major_status = krb5_gss_inquire_cred_no_lock(&context, minor_status, 
-					    (gss_cred_id_t)cred,
-					   NULL, &lifetime,
-					   NULL, actual_mechs);
-
-    if (GSS_ERROR(major_status)) {
+    if (GSS_ERROR(major_status = krb5_gss_inquire_cred(minor_status, 
+						       (gss_cred_id_t) cred,
+						       NULL, &lifetime,
+						       NULL, actual_mechs))) {
 	OM_uint32 dummy;
 	
 	if (output_cred_handle)
-	    (void) krb5_gss_release_cred_no_lock(&context, &dummy, (gss_cred_id_t *) &cred);
+	    (void) krb5_gss_release_cred(&dummy, (gss_cred_id_t *) &cred);
+	krb5_free_context(context);
 
-		goto unlock;
+	return(major_status);
     }
 
     if (initiator_time_rec)
@@ -363,12 +363,9 @@
 	*acceptor_time_rec = lifetime;
 
     if (output_cred_handle)
-	*output_cred_handle = (gss_cred_id_t)cred;
-
-    *minor_status = 0;
-    major_status = GSS_S_COMPLETE;
+      *output_cred_handle = (gss_cred_id_t) cred;
 
-unlock:
-    mutex_unlock(&krb5_mutex);
-    return(major_status);
+    krb5_free_context(context);
+    *minor_status = 0;
+    return(GSS_S_COMPLETE);
 }
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/compare_name.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/compare_name.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,13 +1,8 @@
-/*
- * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
  * Copyright 1993 by OpenVision Technologies, 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
@@ -17,7 +12,7 @@
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
- *
+ * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -28,45 +23,40 @@
  */
 
 /*
- * $Id: compare_name.c,v 1.9 1996/07/22 20:33:38 marc Exp $
+ * $Id: compare_name.c 18015 2006-05-17 05:26:12Z raeburn $
  */
 
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
 
 OM_uint32
-krb5_gss_compare_name(ctx, minor_status, name1, name2, name_equal)
-     void	*ctx;
+krb5_gss_compare_name(minor_status, name1, name2, name_equal)
      OM_uint32 *minor_status;
      gss_name_t name1;
      gss_name_t name2;
      int *name_equal;
-{
+{ 
    krb5_context context;
-   mutex_lock(&krb5_mutex);
-   context = ctx;
-
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, (krb5_context*) &context)))
-      return(GSS_S_FAILURE);
-#endif
+   krb5_error_code code;
 
    if (! kg_validate_name(name1)) {
       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
-      mutex_unlock(&krb5_mutex);
       return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
    }
 
    if (! kg_validate_name(name2)) {
       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
-      mutex_unlock(&krb5_mutex);
       return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
    }
 
+   code = krb5_gss_init_context(&context);
+   if (code) {
+       *minor_status = code;
+       return GSS_S_FAILURE;
+   }
+
    *minor_status = 0;
    *name_equal = krb5_principal_compare(context, (krb5_principal) name1,
 					(krb5_principal) name2);
-   mutex_unlock(&krb5_mutex);
+   krb5_free_context(context);
    return(GSS_S_COMPLETE);
 }
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/context_time.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/context_time.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,13 +1,7 @@
-/*
- * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
-/*
- * Copyright 1993 by OpenVision Technologies, Inc.
- *
+/* Copyright 1993 by OpenVision Technologies, 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
@@ -17,7 +11,7 @@
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
- *
+ * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -27,38 +21,26 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
 
 /*
- * $Id: context_time.c,v 1.9 1996/07/22 20:33:41 marc Exp $
+ * $Id: context_time.c 16187 2004-03-19 09:33:57Z raeburn $
  */
 
 OM_uint32
-krb5_gss_context_time(ct, minor_status, context_handle, time_rec)
-     void *ct;
+krb5_gss_context_time(minor_status, context_handle, time_rec)
      OM_uint32 *minor_status;
      gss_ctx_id_t context_handle;
      OM_uint32 *time_rec;
 {
-   krb5_context context = ct;
    krb5_error_code code;
    krb5_gss_ctx_id_rec *ctx;
    krb5_timestamp now;
    krb5_deltat lifetime;
 
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, (krb5_context*) &context)))
-      return(GSS_S_FAILURE);
-#endif
-
-   mutex_lock(&krb5_mutex);
-
    /* validate the context handle */
    if (! kg_validate_ctx_id(context_handle)) {
       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
-      mutex_unlock(&krb5_mutex);
       return(GSS_S_NO_CONTEXT);
    }
 
@@ -66,25 +48,21 @@
 
    if (! ctx->established) {
       *minor_status = KG_CTX_INCOMPLETE;
-      mutex_unlock(&krb5_mutex);
       return(GSS_S_NO_CONTEXT);
    }
 
-   if (code = krb5_timeofday(context, &now)) {
+   if ((code = krb5_timeofday(ctx->k5_context, &now))) {
       *minor_status = code;
-      mutex_unlock(&krb5_mutex);
       return(GSS_S_FAILURE);
    }
 
    if ((lifetime = ctx->endtime - now) <= 0) {
       *time_rec = 0;
       *minor_status = 0;
-      mutex_unlock(&krb5_mutex);
       return(GSS_S_CONTEXT_EXPIRED);
    } else {
       *time_rec = lifetime;
       *minor_status = 0;
-      mutex_unlock(&krb5_mutex);
       return(GSS_S_COMPLETE);
    }
 }
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/copy_ccache.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/copy_ccache.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,75 +1,61 @@
-/*
- * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
-/*
- * /usr/src/lib/gss_mechs/mech_krb5/mech/copy_ccache.c
- */
+#include "gssapiP_krb5.h"
 
-#include <gssapiP_krb5.h>
-
-GSS_DLLIMP OM_uint32 KRB5_CALLCONV
-gss_krb5_copy_ccache(ctx, minor_status, cred_handle, out_ccache)
-     void *ctx;
+OM_uint32 KRB5_CALLCONV 
+gss_krb5int_copy_ccache(minor_status, cred_handle, out_ccache)
      OM_uint32 *minor_status;
      gss_cred_id_t cred_handle;
      krb5_ccache out_ccache;
 {
-   OM_uint32 major_status;
+   OM_uint32 stat;
    krb5_gss_cred_id_t k5creds;
    krb5_cc_cursor cursor;
    krb5_creds creds;
    krb5_error_code code;
-   krb5_context context = ctx;
-
-   mutex_lock(&krb5_mutex);
-
-   *minor_status = 0;
+   krb5_context context;
 
    /* validate the cred handle */
-   major_status = krb5_gss_validate_cred_no_lock(context, minor_status,
-					         cred_handle);
-   if (major_status)
-       goto unlock;
-
+   stat = krb5_gss_validate_cred(minor_status, cred_handle);
+   if (stat)
+       return(stat);
+   
    k5creds = (krb5_gss_cred_id_t) cred_handle;
+   code = k5_mutex_lock(&k5creds->lock);
+   if (code) {
+       *minor_status = code;
+       return GSS_S_FAILURE;
+   }
    if (k5creds->usage == GSS_C_ACCEPT) {
+       k5_mutex_unlock(&k5creds->lock);
        *minor_status = (OM_uint32) G_BAD_USAGE;
-	major_status = GSS_S_FAILURE;
-	goto unlock;
+       return(GSS_S_FAILURE);
    }
 
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, &context)))
-       return (GSS_S_FAILURE);
-#endif
+   code = krb5_gss_init_context(&context);
+   if (code) {
+       k5_mutex_unlock(&k5creds->lock);
+       *minor_status = code;
+       return GSS_S_FAILURE;
+   }
 
    code = krb5_cc_start_seq_get(context, k5creds->ccache, &cursor);
    if (code) {
+       k5_mutex_unlock(&k5creds->lock);
        *minor_status = code;
-	major_status = GSS_S_FAILURE;
-	goto unlock;
+       krb5_free_context(context);
+       return(GSS_S_FAILURE);
    }
-   while (!code && !krb5_cc_next_cred(context, k5creds->ccache, &cursor, &creds))
+   while (!code && !krb5_cc_next_cred(context, k5creds->ccache, &cursor, &creds)) 
        code = krb5_cc_store_cred(context, out_ccache, &creds);
    krb5_cc_end_seq_get(context, k5creds->ccache, &cursor);
-
+   k5_mutex_unlock(&k5creds->lock);
+   krb5_free_context(context);
    if (code) {
        *minor_status = code;
-	major_status = GSS_S_FAILURE;
-	goto unlock;
+       return(GSS_S_FAILURE);
    } else {
        *minor_status = 0;
-	major_status = GSS_S_COMPLETE;
-	goto unlock;
+       return(GSS_S_COMPLETE);
    }
-
-unlock:
-   mutex_unlock(&krb5_mutex);
-   return(major_status);
 }
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/disp_com_err_status.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/disp_com_err_status.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,13 +1,8 @@
-/*
- * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
  * Copyright 1993 by OpenVision Technologies, 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
@@ -17,7 +12,7 @@
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
- *
+ * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -28,28 +23,28 @@
  */
 
 /*
- * $Id: disp_com_err_status.c,v 1.5 1996/07/22 20:32:59 marc Exp $
+ * $Id: disp_com_err_status.c 16391 2004-06-02 23:40:12Z raeburn $
  */
 
-#include <gssapiP_generic.h>
-#include <com_err.h>
+#include "gssapiP_generic.h"
+#include "com_err.h"
+#include "gss_libinit.h"
 
-/*
- * Solaris Kerberos does not dynamically load the error tables
- */
-#if 0
-static int init_et = 0;
-#endif
+/* XXXX internationalization!! */
+
+/**/
+
 static const char * const no_error = "No error";
 
-/*
- * if status_type == GSS_C_GSS_CODE, return up to three error messages,
- * for routine errors, call error, and status, in that order.
- * message_context == 0 : print the routine error
- * message_context == 1 : print the calling error
- * message_context > 2  : print supplementary info bit (message_context-2)
- * if status_type == GSS_C_MECH_CODE, return the output from error_message()
- */
+/**/
+
+/* if status_type == GSS_C_GSS_CODE, return up to three error messages,
+     for routine errors, call error, and status, in that order.
+     message_context == 0 : print the routine error
+     message_context == 1 : print the calling error
+     message_context > 2  : print supplementary info bit (message_context-2)
+   if status_type == GSS_C_MECH_CODE, return the output from error_message()
+   */
 
 OM_uint32
 g_display_com_err_status(minor_status, status_value, status_string)
@@ -60,13 +55,7 @@
    status_string->length = 0;
    status_string->value = NULL;
 
-/* Solaris Kerberos does not dynamically load the error tables */
-#if 0
-   if (!init_et) {
-      initialize_ggss_error_table();
-      init_et = 1;
-   }
-#endif
+   (void) gssint_initialize_library();
 
    if (! g_make_string_buffer(((status_value == 0)?no_error:
 			       error_message(status_value)),
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/disp_major_status.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/disp_major_status.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,4 +1,5 @@
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
+
 /*
  * Copyright 1993 by OpenVision Technologies, Inc.
  * 
@@ -21,19 +22,24 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_generic.h>
+#include "gssapiP_generic.h"
 #include <string.h>
 #include <stdio.h>
 
 /*
- * $Id: disp_major_status.c,v 1.6 1996/07/22 20:33:01 marc Exp $
+ * $Id: disp_major_status.c 13236 2001-05-08 17:10:18Z epeisach $
  */
 
-#define	GSS_CALLING_ERROR_FIELD(x) \
-	(((x) >> GSS_C_CALLING_ERROR_OFFSET) & GSS_C_CALLING_ERROR_MASK)
+/* XXXX these are not part of the GSSAPI C bindings!  (but should be) */
+/* SUNW15resync - MIT 1.5 has these in gssapi.h */
 
-#define	GSS_ROUTINE_ERROR_FIELD(x) \
-	(((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK)
+#define GSS_CALLING_ERROR_FIELD(x) \
+   (((x) >> GSS_C_CALLING_ERROR_OFFSET) & GSS_C_CALLING_ERROR_MASK)
+#define GSS_ROUTINE_ERROR_FIELD(x) \
+   (((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK)
+#define GSS_SUPPLEMENTARY_INFO_FIELD(x) \
+   (((x) >> GSS_C_SUPPLEMENTARY_OFFSET) & GSS_C_SUPPLEMENTARY_MASK)
+
 
 /* This code has knowledge of the min and max errors of each type
    within the gssapi major status */
@@ -114,16 +120,16 @@
 
 /**/
 
-int display_unknown(kind, value, buffer)
+static int 
+display_unknown(kind, value, buffer)
      const char *kind;
      OM_uint32 value;
      gss_buffer_t buffer;
 {
-   size_t len;
    char *str;
 
-   str = (char *) xmalloc(strlen(unknown_error)+strlen(kind)+7);
-   if (str == NULL)
+   if ((str =
+	(char *) xmalloc(strlen(unknown_error)+strlen(kind)+7)) == NULL)
       return(0);
 
    sprintf(str, unknown_error, kind, value);
@@ -143,7 +149,7 @@
 {
    const char *str;
 
-   if ((str = GSS_CALLING_ERROR_STR(code)) != NULL) {
+   if ((str = GSS_CALLING_ERROR_STR(code))) {
       if (! g_make_string_buffer(str, status_string)) {
 	 *minor_status = ENOMEM;
 	 return(GSS_S_FAILURE);
@@ -168,7 +174,7 @@
 {
    const char *str;
 
-   if ((str = GSS_ROUTINE_ERROR_STR(code)) != NULL) {
+   if ((str = GSS_ROUTINE_ERROR_STR(code))) {
       if (! g_make_string_buffer(str, status_string)) {
 	 *minor_status = ENOMEM;
 	 return(GSS_S_FAILURE);
@@ -193,7 +199,7 @@
 {
    const char *str;
 
-   if ((str = GSS_SINFO_STR(code)) != NULL) {
+   if ((str = GSS_SINFO_STR(code))) {
       if (! g_make_string_buffer(str, status_string)) {
 	 *minor_status = ENOMEM;
 	 return(GSS_S_FAILURE);
@@ -242,7 +248,7 @@
    /*** do routine error */
 
    if (*message_context == 0) {
-      if ((tmp = GSS_ROUTINE_ERROR(status_value)) != 0) {
+      if ((tmp = GSS_ROUTINE_ERROR(status_value))) {
 	 status_value -= tmp;
 	 if ((ret = display_routine(minor_status, tmp, status_string)))
 	    return(ret);
@@ -264,7 +270,7 @@
    /*** do calling error */
 
    if (*message_context == 1) {
-      if ((tmp = GSS_CALLING_ERROR(status_value)) != 0) {
+      if ((tmp = GSS_CALLING_ERROR(status_value))) {
 	 status_value -= tmp;
 	 if ((ret = display_calling(minor_status, tmp, status_string)))
 	    return(ret);
@@ -285,7 +291,7 @@
 
    /*** do sinfo bits (*message_context == 2 + number of bits done) */
 
-   tmp = ((GSS_SUPPLEMENTARY_INFO(status_value)) >> GSS_C_SUPPLEMENTARY_OFFSET);
+   tmp = GSS_SUPPLEMENTARY_INFO_FIELD(status_value);
    /* mask off the bits which have been done */
    if (*message_context > 2) {
       tmp &= ~LSBMASK(*message_context-3);
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/disp_name.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/disp_name.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,13 +1,8 @@
-/*
- * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
  * Copyright 1993 by OpenVision Technologies, 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
@@ -17,7 +12,7 @@
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
- *
+ * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -27,59 +22,55 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
 
 OM_uint32
-krb5_gss_display_name(ctx, minor_status, input_name, output_name_buffer,
+krb5_gss_display_name(minor_status, input_name, output_name_buffer, 
 		      output_name_type)
-     void	*ctx;
      OM_uint32 *minor_status;
      gss_name_t input_name;
      gss_buffer_t output_name_buffer;
      gss_OID *output_name_type;
 {
-   krb5_context context = ctx;
+   krb5_context context;
    krb5_error_code code;
    char *str;
 
-   mutex_lock(&krb5_mutex);
-
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, &context)))
-	return(GSS_S_FAILURE);
-#endif
+   code = krb5_gss_init_context(&context);
+   if (code) {
+       *minor_status = code;
+       return GSS_S_FAILURE;
+   }
 
    output_name_buffer->length = 0;
    output_name_buffer->value = NULL;
 
    if (! kg_validate_name(input_name)) {
       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
-      mutex_unlock(&krb5_mutex);
+      krb5_free_context(context);
       return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
    }
 
    if ((code = krb5_unparse_name(context,
 				 (krb5_principal) input_name, &str))) {
       *minor_status = code;
-      mutex_unlock(&krb5_mutex);
+      krb5_free_context(context);
       return(GSS_S_FAILURE);
    }
 
    if (! g_make_string_buffer(str, output_name_buffer)) {
-      xfree(str);
+      krb5_free_unparsed_name(context, str);
+      krb5_free_context(context);
 
       *minor_status = (OM_uint32) G_BUFFER_ALLOC;
-      mutex_unlock(&krb5_mutex);
       return(GSS_S_FAILURE);
    }
 
-   xfree(str);
+   krb5_free_unparsed_name(context, str);
+   krb5_free_context(context);
 
    *minor_status = 0;
    if (output_name_type)
       *output_name_type = (gss_OID) gss_nt_krb5_name;
-   mutex_unlock(&krb5_mutex);
    return(GSS_S_COMPLETE);
 }
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/disp_status.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/disp_status.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,13 +1,6 @@
-/*
- * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * Copyright 1993 by OpenVision Technologies, 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
@@ -17,7 +10,7 @@
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
- *
+ * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -27,21 +20,19 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_krb5.h>
-#include <com_err.h>
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include "gssapiP_krb5.h"
+#include "gss_libinit.h"
+#include "com_err.h"
 
 /* XXXX internationalization!! */
 
-/* Solaris Kerberos does not dynamically load the error tables */
-#if 0
-static int init_et = 0;
-#endif
+/**/
 
-/*ARGSUSED*/
 OM_uint32
-krb5_gss_display_status(ctx, minor_status, status_value, status_type,
+krb5_gss_display_status(minor_status, status_value, status_type,
 			mech_type, message_context, status_string)
-     void	*ctx;
      OM_uint32 *minor_status;
      OM_uint32 status_value;
      int status_type;
@@ -49,57 +40,31 @@
      OM_uint32 *message_context;
      gss_buffer_t status_string;
 {
-   OM_uint32	major_status = 0;
-
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-     if (GSS_ERROR(kg_get_context(minor_status, (krb5_context*) &context)))
-        return(GSS_S_FAILURE);
-#endif
-
-   mutex_lock(&krb5_mutex);
    status_string->length = 0;
    status_string->value = NULL;
 
    if ((mech_type != GSS_C_NULL_OID) &&
-       !g_OID_equal(gss_mech_krb5_v2, mech_type) &&
        !g_OID_equal(gss_mech_krb5, mech_type) &&
        !g_OID_equal(gss_mech_krb5_old, mech_type)) {
        *minor_status = 0;
-       mutex_unlock(&krb5_mutex);
        return(GSS_S_BAD_MECH);
     }
 
    if (status_type == GSS_C_GSS_CODE) {
-
-      major_status = g_display_major_status(minor_status, status_value,
-				    message_context, status_string);
-      mutex_unlock(&krb5_mutex);
-      return(major_status);
+      return(g_display_major_status(minor_status, status_value,
+				    message_context, status_string));
    } else if (status_type == GSS_C_MECH_CODE) {
-
-/* Solaris Kerberos does not dynamically load the error tables */
-#if 0
-      if (!init_et) {
-	 initialize_k5g_error_table();
-	 init_et = 1;
-      }
-#endif
+      (void) gssint_initialize_library();
 
       if (*message_context) {
 	 *minor_status = (OM_uint32) G_BAD_MSG_CTX;
-         mutex_unlock(&krb5_mutex);
 	 return(GSS_S_FAILURE);
       }
 
-      major_status = g_display_com_err_status(minor_status, status_value,
-				      status_string);
-      mutex_unlock(&krb5_mutex);
-      return(major_status);
+      return(g_display_com_err_status(minor_status, status_value,
+				      status_string));
    } else {
       *minor_status = 0;
-      mutex_unlock(&krb5_mutex);
       return(GSS_S_BAD_STATUS);
    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/export_name.c	Fri Sep 14 15:01:24 2007 -0700
@@ -0,0 +1,98 @@
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*
+ * lib/gssapi/krb5/export_name.c
+ *
+ * Copyright 1997 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 "gssapiP_krb5.h"
+
+OM_uint32 krb5_gss_export_name(OM_uint32  *minor_status,
+			       const gss_name_t input_name,
+			       gss_buffer_t exported_name)
+{
+	krb5_context context;
+	krb5_error_code code;
+	size_t length;
+	char *str, *cp;
+
+	if (minor_status)
+		*minor_status = 0;
+
+	code = krb5_gss_init_context(&context);
+	if (code) {
+	    if (minor_status)
+		*minor_status = code;
+	    return GSS_S_FAILURE;
+	}
+
+	exported_name->length = 0;
+	exported_name->value = NULL;
+	
+	if (! kg_validate_name(input_name)) {
+		if (minor_status)
+			*minor_status = (OM_uint32) G_VALIDATE_FAILED;
+		krb5_free_context(context);
+		return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
+	}
+
+	if ((code = krb5_unparse_name(context, (krb5_principal) input_name, 
+				      &str))) {
+		if (minor_status)
+			*minor_status = code;
+		krb5_free_context(context);
+		return(GSS_S_FAILURE);
+	}
+
+	krb5_free_context(context);
+	length = strlen(str);
+	exported_name->length = 10 + length + gss_mech_krb5->length;
+	exported_name->value = malloc(exported_name->length);
+	if (!exported_name->value) {
+		free(str);
+		if (minor_status)
+			*minor_status = ENOMEM;
+		return(GSS_S_FAILURE);
+	}
+	cp = exported_name->value;
+
+	/* Note: we assume the OID will be less than 128 bytes... */
+	*cp++ = 0x04; *cp++ = 0x01;
+	*cp++ = (gss_mech_krb5->length+2) >> 8;
+	*cp++ = (gss_mech_krb5->length+2) & 0xFF;
+	*cp++ = 0x06;
+	*cp++ = (gss_mech_krb5->length) & 0xFF;
+	memcpy(cp, gss_mech_krb5->elements, gss_mech_krb5->length);
+	cp += gss_mech_krb5->length;
+	*cp++ = length >> 24;
+	*cp++ = length >> 16;
+	*cp++ = length >> 8;
+	*cp++ = length & 0xFF;
+	memcpy(cp, str, length);
+
+	free(str);
+
+	return(GSS_S_COMPLETE);
+}
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/export_sec_context.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/export_sec_context.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,8 +1,3 @@
-/*
- * Copyright 1999-2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
@@ -35,33 +30,21 @@
 /*
  * export_sec_context.c	- Externalize the security context.
  */
-#include <gssapiP_krb5.h>
-#include <k5-int.h>
+#include "gssapiP_krb5.h"
 
 OM_uint32
-krb5_gss_export_sec_context(ct, minor_status, context_handle, interprocess_token)
-    void		*ct;
+krb5_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;
 {
-    krb5_context	context = ct;
+    krb5_context	context;
     krb5_error_code	kret;
     OM_uint32		retval;
     size_t		bufsize, blen;
     krb5_gss_ctx_id_t	ctx;
     krb5_octet		*obuffer, *obp;
 
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-    if (GSS_ERROR(kg_get_context(minor_status, (krb5_context*) &context)))
-        return(GSS_S_FAILURE);
-#endif
-
-    mutex_lock(&krb5_mutex);
-    context = ct;
-
     /* Assume a tragic failure */
     obuffer = (krb5_octet *) NULL;
     retval = GSS_S_FAILURE;
@@ -74,6 +57,14 @@
     }
 
     ctx = (krb5_gss_ctx_id_t) *context_handle;
+    context = ctx->k5_context;
+    kret = krb5_gss_ser_init(context);
+    if (kret)
+	goto error_out;
+
+    { gss_OID go = ctx->mech_used;
+    printf("export ctx len=%lu\n", go->length);
+    }
 
     /* Determine size needed for externalization of context */
     bufsize = 0;
@@ -101,20 +92,17 @@
     retval = GSS_S_COMPLETE;
 
     /* Now, clean up the context state */
-    /* Note, calling non-locking interface */
-    (void)krb5_gss_delete_sec_context_no_lock(context, minor_status, context_handle, NULL);
+    (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
     *context_handle = GSS_C_NO_CONTEXT;
 
-    mutex_unlock(&krb5_mutex);
     return (GSS_S_COMPLETE);
 
 error_out:
     if (obuffer && bufsize) {
 	    memset(obuffer, 0, bufsize);
-	    krb5_xfree(obuffer);
+	    xfree(obuffer);
     }
-    if (*minor_status == 0)
+    if (*minor_status == 0) 
 	    *minor_status = (OM_uint32) kret;
-    mutex_unlock(&krb5_mutex);
     return(retval);
 }
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/get_tkt_flags.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/get_tkt_flags.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,4 +1,5 @@
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
+
 /*
  * Copyright 1993 by OpenVision Technologies, Inc.
  * 
@@ -21,14 +22,14 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
 
 /*
- * $Id: get_tkt_flags.c,v 1.7.4.1 1996/11/21 02:19:40 marc Exp $
+ * $Id: get_tkt_flags.c 18131 2006-06-14 22:27:54Z tlyu $
  */
 
-OM_uint32
-gss_krb5_get_tkt_flags(minor_status, context_handle, ticket_flags)
+OM_uint32 KRB5_CALLCONV 
+gss_krb5int_get_tkt_flags(minor_status, context_handle, ticket_flags)
      OM_uint32 *minor_status;
      gss_ctx_id_t context_handle;
      krb5_flags *ticket_flags;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/gss_libinit.c	Fri Sep 14 15:01:24 2007 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <assert.h>
+
+#include "gssapi_err_generic.h"
+#include "gssapi_err_krb5.h"
+#include "gssapiP_krb5.h"
+
+#include "gss_libinit.h"
+#include "k5-platform.h"
+
+#include "mglueP.h"
+
+/*
+ * Initialize the GSSAPI library.
+ */
+
+MAKE_INIT_FUNCTION(gssint_lib_init);
+MAKE_FINI_FUNCTION(gssint_lib_fini);
+
+int gssint_lib_init(void)
+{
+    int err;
+
+#ifdef SHOW_INITFINI_FUNCS
+    printf("gssint_lib_init\n");
+#endif
+
+#if !USE_BUNDLE_ERROR_STRINGS
+    add_error_table(&et_k5g_error_table);
+    add_error_table(&et_ggss_error_table);
+#endif
+#if 0 /* SUNW15resync */
+    err = gssint_mechglue_init();
+    if (err)
+	return err;
+#endif
+    err = k5_mutex_finish_init(&gssint_krb5_keytab_lock);
+    if (err)
+	return err;
+    err = k5_key_register(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME, free);
+    if (err)
+	return err;
+    err = k5_key_register(K5_KEY_GSS_KRB5_CCACHE_NAME, free);
+    if (err)
+	return err;
+#if 0 /* SUNW15resync - revisit when mech resynced w/1.5 */
+    err = k5_mutex_finish_init(&kg_kdc_flag_mutex);
+    if (err)
+	return err;
+#endif
+    return k5_mutex_finish_init(&kg_vdb.mutex);
+}
+
+void gssint_lib_fini(void)
+{
+    if (!INITIALIZER_RAN(gssint_lib_init) || PROGRAM_EXITING()) {
+#ifdef SHOW_INITFINI_FUNCS
+	printf("gssint_lib_fini: skipping\n");
+#endif
+	return;
+    }
+#ifdef SHOW_INITFINI_FUNCS
+    printf("gssint_lib_fini\n");
+#endif
+#if !USE_BUNDLE_ERROR_STRINGS
+    remove_error_table(&et_k5g_error_table);
+    remove_error_table(&et_ggss_error_table);
+#endif
+    k5_key_delete(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME);
+    k5_key_delete(K5_KEY_GSS_KRB5_CCACHE_NAME);
+    k5_mutex_destroy(&kg_vdb.mutex);
+#if 0 /* SUNW15resync - revisit when mech resynced w/1.5 */
+    k5_mutex_destroy(&kg_kdc_flag_mutex);
+#endif
+    k5_mutex_destroy(&gssint_krb5_keytab_lock);
+#if 0 /* SUNW15resync */
+    gssint_mechglue_fini();
+#endif
+}
+
+OM_uint32 gssint_initialize_library (void)
+{
+    return CALL_INIT_FUNCTION(gssint_lib_init);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/gss_libinit.h	Fri Sep 14 15:01:24 2007 -0700
@@ -0,0 +1,11 @@
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#ifndef GSSAPI_LIBINIT_H
+#define GSSAPI_LIBINIT_H
+
+#include "gssapi.h"
+
+OM_uint32 gssint_initialize_library (void);
+void gssint_cleanup_library (void);
+
+#endif /* GSSAPI_LIBINIT_H */
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/import_name.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/import_name.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,13 +1,8 @@
-/*
- * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
  * Copyright 1993 by OpenVision Technologies, 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
@@ -17,7 +12,7 @@
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
- *
+ * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -28,14 +23,14 @@
  */
 
 /*
- * $Id: import_name.c,v 1.17 1998/10/30 02:54:21 marc Exp $
+ * $Id: import_name.c 18015 2006-05-17 05:26:12Z raeburn $
  */
 
-#include <gssapiP_krb5.h>
-#include <gssapi_generic.h>
+#include "gssapiP_krb5.h"
 
 #ifndef NO_PASSWORD
 #include <pwd.h>
+#include <stdio.h>
 #endif
 
 #ifdef HAVE_STRING_H
@@ -52,9 +47,8 @@
  */
 
 OM_uint32
-krb5_gss_import_name(ctx, minor_status, input_name_buffer,
+krb5_gss_import_name(minor_status, input_name_buffer, 
 		     input_name_type, output_name)
-     void	*ctx;
      OM_uint32 *minor_status;
      gss_buffer_t input_name_buffer;
      gss_OID input_name_type;
@@ -69,15 +63,11 @@
    struct passwd *pw;
 #endif
 
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, &context)))
-      return(GSS_S_FAILURE);
-#endif
-
-   mutex_lock(&krb5_mutex);
-   context = ctx;
+   code = krb5_gss_init_context(&context);
+   if (code) {
+       *minor_status = code;
+       return GSS_S_FAILURE;
+   }
 
    /* set up default returns */
 
@@ -86,21 +76,15 @@
 
    /* Go find the appropriate string rep to pass into parse_name */
 
-   /* We support both nametypes: new and official nametype
-   *  GSS_C_NT_HOSTBASED_SERVICE and
-   *  old and unofficial nametype gss_nt_service_name
-   */
-
    if ((input_name_type != GSS_C_NULL_OID) &&
-       (g_OID_equal(input_name_type, GSS_C_NT_HOSTBASED_SERVICE) ||
-	g_OID_equal(input_name_type, gss_nt_service_name) ||
+       (g_OID_equal(input_name_type, gss_nt_service_name) ||
 	g_OID_equal(input_name_type, gss_nt_service_name_v2))) {
       char *service, *host;
 
       if ((tmp =
 	   (char *) xmalloc(input_name_buffer->length + 1)) == NULL) {
 	 *minor_status = ENOMEM;
-	 mutex_unlock(&krb5_mutex);
+	 krb5_free_context(context);
 	 return(GSS_S_FAILURE);
       }
 
@@ -108,7 +92,7 @@
       tmp[input_name_buffer->length] = 0;
 
       service = tmp;
-      if (host = strchr(tmp, '@')) {
+      if ((host = strchr(tmp, '@'))) {
 	 *host = '\0';
 	 host++;
       }
@@ -123,7 +107,7 @@
 
       if (input_name_buffer->length != sizeof(krb5_principal)) {
 	 *minor_status = (OM_uint32) G_WRONG_SIZE;
-	 mutex_unlock(&krb5_mutex);
+	 krb5_free_context(context);
 	 return(GSS_S_BAD_NAME);
       }
 
@@ -131,16 +115,22 @@
 
       if ((code = krb5_copy_principal(context, input, &princ))) {
 	 *minor_status = code;
-	 mutex_unlock(&krb5_mutex);
+	 krb5_free_context(context);
 	 return(GSS_S_FAILURE);
       }
    } else {
+#ifndef NO_PASSWORD
+      uid_t uid;
+      struct passwd pwx;
+      char pwbuf[BUFSIZ];
+#endif
+
       stringrep = NULL;
 
       if ((tmp =
 	   (char *) xmalloc(input_name_buffer->length + 1)) == NULL) {
 	 *minor_status = ENOMEM;
-	 mutex_unlock(&krb5_mutex);
+	 krb5_free_context(context);
 	 return(GSS_S_FAILURE);
       }
       tmp2 = 0;
@@ -150,19 +140,19 @@
 
       if ((input_name_type == GSS_C_NULL_OID) ||
 	  g_OID_equal(input_name_type, gss_nt_krb5_name) ||
-	  g_OID_equal(input_name_type, GSS_C_NT_USER_NAME)) {
+	  g_OID_equal(input_name_type, gss_nt_user_name)) {
 	 stringrep = (char *) tmp;
 #ifndef NO_PASSWORD
-      } else if (g_OID_equal(input_name_type, GSS_C_NT_MACHINE_UID_NAME)) {
-	 if ((pw = getpwuid(*((uid_t *) input_name_buffer->value))))
-	    stringrep = pw->pw_name;
+      } else if (g_OID_equal(input_name_type, gss_nt_machine_uid_name)) {
+	 uid = *(uid_t *) input_name_buffer->value;
+      do_getpwuid:
+	 if (k5_getpwuid_r(uid, &pwx, pwbuf, sizeof(pwbuf), &pw) == 0)
+	     stringrep = pw->pw_name;
 	 else
 	    *minor_status = (OM_uint32) G_NOUSER;
-      } else if (g_OID_equal(input_name_type, GSS_C_NT_STRING_UID_NAME)) {
-	 if ((pw = getpwuid((uid_t) atoi(tmp))))
-	    stringrep = pw->pw_name;
-	 else
-	    *minor_status = (OM_uint32) G_NOUSER;
+      } else if (g_OID_equal(input_name_type, gss_nt_string_uid_name)) {
+	 uid = atoi(tmp);
+	 goto do_getpwuid;
 #endif
       } else if (g_OID_equal(input_name_type, gss_nt_exported_name)) {
 	 cp = tmp;
@@ -191,15 +181,16 @@
 	 if (tmp2 == NULL) {
 		 xfree(tmp);
 		 *minor_status = ENOMEM;
-		 mutex_unlock(&krb5_mutex);
+		 krb5_free_context(context);
 		 return GSS_S_FAILURE;
 	 }
 	 strncpy(tmp2, cp, length);
 	 tmp2[length] = 0;
-	
+	 
 	 stringrep = tmp2;
      } else {
-	 mutex_unlock(&krb5_mutex);
+	 xfree(tmp);
+	 krb5_free_context(context);
 	 return(GSS_S_BAD_NAMETYPE);
       }
 
@@ -212,10 +203,10 @@
 	 xfree(tmp);
 	 if (tmp2)
 		 xfree(tmp2);
-	 mutex_unlock(&krb5_mutex);
+	 krb5_free_context(context);
 	 return(GSS_S_BAD_NAME);
       }
-
+      
       if (tmp2)
 	      xfree(tmp2);
       xfree(tmp);
@@ -226,7 +217,7 @@
 
    if (code) {
       *minor_status = (OM_uint32) code;
-      mutex_unlock(&krb5_mutex);
+      krb5_free_context(context);
       return(GSS_S_BAD_NAME);
    }
 
@@ -234,14 +225,15 @@
 
    if (! kg_save_name((gss_name_t) princ)) {
       krb5_free_principal(context, princ);
+      krb5_free_context(context);
       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
-      mutex_unlock(&krb5_mutex);
       return(GSS_S_FAILURE);
    }
 
+   krb5_free_context(context);
+
    /* return it */
 
    *output_name = (gss_name_t) princ;
-   mutex_unlock(&krb5_mutex);
    return(GSS_S_COMPLETE);
 }
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/indicate_mechs.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/indicate_mechs.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,8 +1,3 @@
-/*
- * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
@@ -28,26 +23,22 @@
  */
 
 /*
- * $Id: indicate_mechs.c,v 1.11 1999/03/26 03:51:43 tytso Exp $
+ * $Id: indicate_mechs.c 18131 2006-06-14 22:27:54Z tlyu $
  */
 
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
+#include "mglueP.h"
 
-/*ARGSUSED*/
 OM_uint32
-krb5_gss_indicate_mechs(ctx, minor_status, mech_set)
-     void	*ctx;
+krb5_gss_indicate_mechs(minor_status, mech_set)
      OM_uint32 *minor_status;
      gss_OID_set *mech_set;
 {
    *minor_status = 0;
 
-   /* Solaris Kerberos:  note that we use gss_copy_oid_set() here
-    * instead of g_copy_OID_set().  Ours is defined in oid_ops.c
-    */
-   if (gss_copy_oid_set(minor_status, gss_mech_set_krb5_v1v2, 
-	mech_set) == GSS_S_FAILURE) {
+   if (! gssint_copy_oid_set(minor_status, gss_mech_set_krb5_both, mech_set)) {
          *mech_set     = GSS_C_NO_OID_SET;
+         *minor_status = ENOMEM;
          return(GSS_S_FAILURE);
    }
 
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/init_sec_context.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/init_sec_context.c	Fri Sep 14 15:01:24 2007 -0700
@@ -6,14 +6,14 @@
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
- * Copyright 2000 by the Massachusetts Institute of Technology.
+ * Copyright 2000,2002, 2003 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
@@ -27,11 +27,11 @@
  * 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 1993 by OpenVision Technologies, 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
@@ -41,7 +41,7 @@
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
- *
+ * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -53,14 +53,14 @@
 
 /*
  * Copyright (C) 1998 by the FundsXpress, INC.
- *
+ * 
  * 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
@@ -71,33 +71,32 @@
  * permission.  FundsXpress makes no representations about the suitability of
  * this software for any purpose.  It is provided "as is" without express
  * or implied warranty.
- *
+ * 
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#include <gssapiP_krb5.h>
-#include <k5-int.h>
+#include "k5-int.h"
+#include "gssapiP_krb5.h"
+#include "gss_libinit.h"
+#include "mglueP.h"
+#ifdef HAVE_MEMORY_H
 #include <memory.h>
+#endif
 #include <stdlib.h>
-#include <syslog.h>
 #include <assert.h>
-#define ROOT_UID 0
-#define KRB5_DEFAULT_LIFE 60*60*10
-#define CACHE_FILENAME_LEN 35
+
+/* Solaris Kerberos start */
+static OM_uint32 get_default_cred(OM_uint32 *, void *, gss_cred_id_t *);
+/* Solaris Kerberos end */
 
 /*
- * $Id: init_sec_context.c,v 1.51.2.7 2000/06/28 02:48:22 tlyu Exp $
+ * $Id: init_sec_context.c 18131 2006-06-14 22:27:54Z tlyu $
  */
 
-extern int
-safechown(const char *src, uid_t uid, gid_t gid, int mode);
-
-/*
- * XXX This is for debugging only!!!  Should become a real bitfield
- * at some point
- */
+/* XXX This is for debugging only!!!  Should become a real bitfield
+   at some point */
 int krb5_gss_dbg_client_expcreds = 0;
 
 /*
@@ -116,8 +115,7 @@
     krb5_error_code	code;
     krb5_creds 		in_creds;
 
-    KRB5_LOG0(KRB5_INFO, "get_credentials() start\n");
-
+    k5_mutex_assert_locked(&cred->lock);
     memset((char *) &in_creds, 0, sizeof(krb5_creds));
 
     if ((code = krb5_copy_principal(context, cred->princ, &in_creds.client)))
@@ -143,18 +141,14 @@
 	code = KRB5KRB_AP_ERR_TKT_EXPIRED;
 	goto cleanup;
     }
-
+    
 cleanup:
     if (in_creds.client)
 	    krb5_free_principal(context, in_creds.client);
     if (in_creds.server)
 	    krb5_free_principal(context, in_creds.server);
-
-    KRB5_LOG(KRB5_INFO, "get_credentials() end, code = %d\n", code);
-
     return code;
 }
-
 struct gss_checksum_data {
     krb5_gss_ctx_id_rec *ctx;
     krb5_gss_cred_id_t cred;
@@ -162,16 +156,19 @@
     krb5_data checksum_data;
 };
 
+#ifdef CFX_EXERCISE
+#include "../../krb5/krb/auth_con.h"
+#endif
 static krb5_error_code KRB5_CALLCONV
 make_gss_checksum (krb5_context context, krb5_auth_context auth_context,
-                   void *cksum_data, krb5_data **out)
+		   void *cksum_data, krb5_data **out)
 {
     krb5_error_code code;
     krb5_int32 con_flags;
     unsigned char *ptr;
     struct gss_checksum_data *data = cksum_data;
     krb5_data credmsg;
-    int junk;
+    unsigned int junk;
 
     data->checksum_data.data = 0;
     credmsg.data = 0;
@@ -183,19 +180,19 @@
 	/* clear the time check flag that was set in krb5_auth_con_init() */
 	krb5_auth_con_getflags(context, auth_context, &con_flags);
 	krb5_auth_con_setflags(context, auth_context,
-		con_flags & ~KRB5_AUTH_CONTEXT_DO_TIME);
+			       con_flags & ~KRB5_AUTH_CONTEXT_DO_TIME);
 
 	code = krb5_fwd_tgt_creds(context, auth_context, 0,
-		data->cred->princ, data->ctx->there,
-		data->cred->ccache, 1,
-		&credmsg);
+				  data->cred->princ, data->ctx->there,
+				  data->cred->ccache, 1,
+				  &credmsg);
 
 	/* turn KRB5_AUTH_CONTEXT_DO_TIME back on */
 	krb5_auth_con_setflags(context, auth_context, con_flags);
 
 	if (code) {
 	    /* don't fail here; just don't accept/do the delegation
-		request */
+               request */
 	    data->ctx->gss_flags &= ~GSS_C_DELEG_FLAG;
 
 	    data->checksum_data.length = 24;
@@ -203,22 +200,23 @@
 	    if (credmsg.length+28 > KRB5_INT16_MAX) {
 		krb5_free_data_contents(context, &credmsg);
 		return(KRB5KRB_ERR_FIELD_TOOLONG);
-            }
+	    }
 
-            data->checksum_data.length = 28+credmsg.length;
+	    data->checksum_data.length = 28+credmsg.length;
 	}
     } else {
 	data->checksum_data.length = 24;
     }
 #ifdef CFX_EXERCISE
-    if (data->ctx->auth_context->keyblock->enctype == 18) {
+    if (data->ctx->auth_context->keyblock != NULL
+	&& data->ctx->auth_context->keyblock->enctype == 18) {
 	srand(time(0) ^ getpid());
 	/* Our ftp client code stupidly assumes a base64-encoded
 	   version of the token will fit in 10K, so don't make this
 	   too big.  */
 	junk = rand() & 0xff;
     } else
-        junk = 0;
+	junk = 0;
 #else
     junk = 0;
 #endif
@@ -226,16 +224,16 @@
     data->checksum_data.length += junk;
 
     /* now allocate a buffer to hold the checksum data and
-	(maybe) KRB_CRED msg */
+       (maybe) KRB_CRED msg */
 
     if ((data->checksum_data.data =
 	 (char *) xmalloc(data->checksum_data.length)) == NULL) {
 	if (credmsg.data)
-            krb5_free_data_contents(context, &credmsg);
+	    krb5_free_data_contents(context, &credmsg);
 	return(ENOMEM);
     }
 
-    ptr = (uchar_t *)data->checksum_data.data;
+    ptr = (uchar_t *)data->checksum_data.data; /* SUNW15resync */
 
     TWRITE_INT(ptr, data->md5.length, 0);
     TWRITE_STR(ptr, (unsigned char *) data->md5.contents, data->md5.length);
@@ -257,7 +255,7 @@
     *out = &data->checksum_data;
     return 0;
 }
-
+    
 static krb5_error_code
 make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
     krb5_context context;
@@ -276,13 +274,11 @@
     krb5_data *checksum_data = NULL;
     unsigned char *ptr;
     unsigned char *t;
-    int tlen;
+    unsigned int tlen;
 
+    k5_mutex_assert_locked(&cred->lock);
     ap_req.data = 0;
 
-    /* build the checksum buffer */
-    KRB5_LOG0(KRB5_INFO, "make_ap_req_v1() start\n");
-
     /* compute the hash of the channel bindings */
 
     if ((code = kg_checksum_channel_bindings(context, chan_bindings, &md5, 0)))
@@ -290,7 +286,6 @@
 
     krb5_auth_con_set_req_cksumtype(context, ctx->auth_context,
 				    CKSUMTYPE_KG_CB);
-
     cksum_struct.md5 = md5;
     cksum_struct.ctx = ctx;
     cksum_struct.cred = cred;
@@ -300,17 +295,18 @@
     case ENCTYPE_DES_CBC_MD4:
     case ENCTYPE_DES_CBC_MD5:
     case ENCTYPE_DES3_CBC_SHA1:
-	code = make_gss_checksum(context, ctx->auth_context, &cksum_struct,
-		&checksum_data);
-	if (code)
+      code = make_gss_checksum(context, ctx->auth_context, &cksum_struct,
+				 &checksum_data);
+	    if (code)
 		goto cleanup;
-        break;
+	break;
     default:
 	krb5_auth_con_set_checksum_func(context, ctx->auth_context,
-		make_gss_checksum, &cksum_struct);
-	break;
+					make_gss_checksum, &cksum_struct);
+	    break;
     }
 
+
     /* call mk_req.  subkey and ap_req need to be used or destroyed */
 
     mk_req_flags = AP_OPTS_USE_SUBKEY;
@@ -318,8 +314,10 @@
     if (ctx->gss_flags & GSS_C_MUTUAL_FLAG)
 	mk_req_flags |= AP_OPTS_MUTUAL_REQUIRED;
 
-    if ((code = krb5_mk_req_extended(context, &ctx->auth_context, mk_req_flags,
-				     checksum_data, k_cred, &ap_req)))
+    code = krb5_mk_req_extended(context, &ctx->auth_context, mk_req_flags,
+				checksum_data, k_cred, &ap_req);
+    krb5_free_data_contents(context, &cksum_struct.checksum_data);
+    if (code)
 	goto cleanup;
 
    /* store the interesting stuff from creds and authent */
@@ -340,7 +338,7 @@
 
    ptr = t;
 
-   g_make_token_header((gss_OID) mech_type, ap_req.length,
+   g_make_token_header(mech_type, ap_req.length,
 		       &ptr, KG_TOK_CTX_AP_REQ);
 
    TWRITE_STR(ptr, (unsigned char *) ap_req.data, ap_req.length);
@@ -351,23 +349,712 @@
    token->value = (void *) t;
 
    code = 0;
-
-cleanup:
-   /*
-    * We only free cksum_struct.checksum_data here, because checksum_data
-    * could point to cksum_struct.checksum_data or NULL.
-    */
-   if (cksum_struct.checksum_data.data)
-	krb5_free_data_contents(context, &cksum_struct.checksum_data);
+    
+ cleanup:
+   if (checksum_data && checksum_data->data)
+       krb5_free_data_contents(context, checksum_data);
    if (ap_req.data)
-       xfree(ap_req.data);
-
-   KRB5_LOG(KRB5_INFO, "make_ap_req_v1() end, code = %d\n", code);
+       krb5_free_data_contents(context, &ap_req);
 
    return (code);
 }
 
+/*
+ * setup_enc
+ *
+ * Fill in the encryption descriptors.  Called after AP-REQ is made.
+ */
+static OM_uint32
+setup_enc(
+   OM_uint32 *minor_status,
+   krb5_gss_ctx_id_rec *ctx,
+   krb5_context context)
+{
 
+   krb5_error_code code;
+   OM_uint32 ret = GSS_S_COMPLETE;
+   int i;
+   krb5int_access kaccess;
+
+   code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
+   if (code)
+       goto fail;
+
+   ctx->have_acceptor_subkey = 0;
+   ctx->proto = 0;
+   ctx->cksumtype = 0;
+   switch(ctx->subkey->enctype) {
+   case ENCTYPE_DES_CBC_MD5:
+   case ENCTYPE_DES_CBC_MD4:
+   case ENCTYPE_DES_CBC_CRC:
+      ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
+      ctx->signalg = SGN_ALG_DES_MAC_MD5;
+      ctx->cksum_size = 8;
+      ctx->sealalg = SEAL_ALG_DES;
+
+      /* The encryption key is the session key XOR
+	 0xf0f0f0f0f0f0f0f0.  */
+      if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc)))
+	 goto fail;
+
+      for (i=0; i<ctx->enc->length; i++)
+	 ctx->enc->contents[i] ^= 0xf0;
+
+      goto copy_subkey_to_seq;
+
+   case ENCTYPE_DES3_CBC_SHA1:
+       /* MIT extension */
+      ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
+      ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
+      ctx->cksum_size = 20;
+      ctx->sealalg = SEAL_ALG_DES3KD;
+
+   copy_subkey:
+      code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc);
+      if (code)
+	 goto fail;
+   copy_subkey_to_seq:
+      code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq);
+      if (code) {
+	 krb5_free_keyblock (context, ctx->enc);
+	 goto fail;
+      }
+      goto success;
+
+   case ENCTYPE_ARCFOUR_HMAC:
+       /* Microsoft extension */
+      ctx->signalg = SGN_ALG_HMAC_MD5 ;
+      ctx->cksum_size = 8;
+      ctx->sealalg = SEAL_ALG_MICROSOFT_RC4 ;
+
+      goto copy_subkey;
+
+   default:
+       /* Fill some fields we shouldn't be using on this path
+	  with garbage.  */
+       ctx->signalg = -10;
+       ctx->sealalg = -10;
+
+       ctx->proto = 1;
+       code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, ctx->subkey->enctype,
+					    &ctx->cksumtype);
+       if (code)
+	   goto fail;
+       code = krb5_c_checksum_length(context, ctx->cksumtype,
+				     &ctx->cksum_size);
+       if (code)
+	   goto fail;
+       goto copy_subkey;
+   }
+
+fail:
+   /* SUNW15resync - (as in prev snv code) add if-code and success label fix */
+  if (code) {
+      *minor_status = code;
+      return GSS_S_FAILURE;
+  }
+
+success:
+   return (ret);
+}
+
+/*
+ * new_connection
+ *
+ * Do the grunt work of setting up a new context.
+ */
+static OM_uint32
+new_connection(
+   OM_uint32 *minor_status,
+   krb5_gss_cred_id_t cred,
+   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,
+   krb5_context context,
+   int default_mech)
+{
+   OM_uint32 major_status;
+   krb5_error_code code;
+   krb5_creds *k_cred;
+   krb5_gss_ctx_id_rec *ctx, *ctx_free;
+   krb5_timestamp now;
+   gss_buffer_desc token;
+
+   k5_mutex_assert_locked(&cred->lock);
+   major_status = GSS_S_FAILURE;
+   token.length = 0;
+   token.value = NULL;
+
+   /* make sure the cred is usable for init */
+
+   if ((cred->usage != GSS_C_INITIATE) &&
+       (cred->usage != GSS_C_BOTH)) {
+      *minor_status = 0;
+      return(GSS_S_NO_CRED);
+   }
+
+   /* complain if the input token is non-null */
+
+   if (input_token != GSS_C_NO_BUFFER && input_token->length != 0) {
+       *minor_status = 0;
+       return(GSS_S_DEFECTIVE_TOKEN);
+   }
+
+   /* create the ctx */
+
+   if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec)))
+       == NULL) {
+      *minor_status = ENOMEM;
+      return(GSS_S_FAILURE);
+   }
+
+   /* fill in the ctx */
+   memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec));
+   ctx_free = ctx;
+   if ((code = krb5_auth_con_init(context, &ctx->auth_context)))
+      goto fail;
+   krb5_auth_con_setflags(context, ctx->auth_context,
+			  KRB5_AUTH_CONTEXT_DO_SEQUENCE);
+
+   /* limit the encryption types negotiated (if requested) */
+   if (cred->req_enctypes) {
+	if ((code = krb5_set_default_tgs_enctypes(context,
+						  cred->req_enctypes))) {
+	    goto fail;
+	}
+   }
+
+   ctx->initiate = 1;
+   ctx->gss_flags = (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG |
+                     GSS_C_TRANS_FLAG | 
+                     ((req_flags) & (GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
+                                     GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG)));
+   ctx->seed_init = 0;
+   ctx->big_endian = 0;  /* all initiators do little-endian, as per spec */
+   ctx->seqstate = 0;
+
+   if ((code = krb5_timeofday(context, &now)))
+      goto fail;
+
+   if (time_req == 0 || time_req == GSS_C_INDEFINITE) {
+      ctx->endtime = 0;
+   } else {
+      ctx->endtime = now + time_req;
+   }
+
+   if ((code = krb5_copy_principal(context, cred->princ, &ctx->here)))
+      goto fail;
+      
+   if ((code = krb5_copy_principal(context, (krb5_principal) target_name,
+				   &ctx->there)))
+      goto fail;
+
+   code = get_credentials(context, cred, ctx->there, now,
+			  ctx->endtime, &k_cred);
+   if (code)
+      goto fail;
+
+   if (default_mech) {
+      mech_type = (gss_OID) gss_mech_krb5;
+   }
+
+   if (generic_gss_copy_oid(minor_status, mech_type, &ctx->mech_used)
+       != GSS_S_COMPLETE) {
+      code = *minor_status;
+      goto fail;
+   }
+   /*
+    * Now try to make it static if at all possible....
+    */
+   ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used);
+
+   {
+      /* gsskrb5 v1 */
+      krb5_ui_4 seq_temp;
+      if ((code = make_ap_req_v1(context, ctx,
+				 cred, k_cred, input_chan_bindings, 
+				 mech_type, &token))) {
+	 if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) ||
+	     (code == KG_EMPTY_CCACHE))
+	    major_status = GSS_S_NO_CRED;
+	 if (code == KRB5KRB_AP_ERR_TKT_EXPIRED)
+	    major_status = GSS_S_CREDENTIALS_EXPIRED;
+	 goto fail;
+      }
+
+      krb5_auth_con_getlocalseqnumber(context, ctx->auth_context,
+			    (krb5_int32 *)&seq_temp); /* SUNW15resync */
+      ctx->seq_send = seq_temp;
+      krb5_auth_con_getsendsubkey(context, ctx->auth_context,
+				  &ctx->subkey);
+   }
+
+   major_status = setup_enc(minor_status, ctx, context);
+
+   if (k_cred) {
+      krb5_free_creds(context, k_cred);
+      k_cred = 0;
+   }
+      
+   /* at this point, the context is constructed and valid,
+      hence, releaseable */
+
+   /* intern the context handle */
+
+   if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
+      code = G_VALIDATE_FAILED;
+      goto fail;
+   }
+   *context_handle = (gss_ctx_id_t) ctx;
+   ctx_free = 0;
+
+   /* compute time_rec */
+   if (time_rec) {
+      if ((code = krb5_timeofday(context, &now)))
+	 goto fail;
+      *time_rec = ctx->endtime - now;
+   }
+
+   /* set the other returns */
+   *output_token = token;
+
+   if (ret_flags)
+      *ret_flags = ctx->gss_flags;
+
+   if (actual_mech_type)
+      *actual_mech_type = mech_type;
+
+   /* return successfully */
+
+   *minor_status = 0;
+   if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) {
+      ctx->established = 0;
+      return(GSS_S_CONTINUE_NEEDED);
+   } else {
+      ctx->seq_recv = ctx->seq_send;
+      g_order_init(&(ctx->seqstate), ctx->seq_recv,
+		   (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0, 
+		   (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0, ctx->proto);
+      ctx->gss_flags |= GSS_C_PROT_READY_FLAG;
+      ctx->established = 1;
+      return(GSS_S_COMPLETE);
+   }
+
+fail:
+   if (ctx_free) {
+       if (ctx_free->auth_context)
+	   krb5_auth_con_free(context, ctx_free->auth_context);
+       if (ctx_free->here)
+	   krb5_free_principal(context, ctx_free->here);
+       if (ctx_free->there)
+	   krb5_free_principal(context, ctx_free->there);
+       if (ctx_free->subkey)
+	   krb5_free_keyblock(context, ctx_free->subkey);
+       xfree(ctx_free);
+   } else
+	(void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
+
+   *minor_status = code;
+   return (major_status);
+}
+
+/*
+ * mutual_auth
+ *
+ * Handle the reply from the acceptor, if we're doing mutual auth.
+ */
+static OM_uint32
+mutual_auth(
+   OM_uint32 *minor_status,
+   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,
+   krb5_context context)
+{
+   OM_uint32 major_status;
+   unsigned char *ptr;
+   char *sptr;
+   krb5_data ap_rep;
+   krb5_ap_rep_enc_part *ap_rep_data;
+   krb5_timestamp now;
+   krb5_gss_ctx_id_rec *ctx;
+   krb5_error *krb_error;
+   krb5_error_code code;
+   krb5int_access kaccess;
+
+   major_status = GSS_S_FAILURE;
+
+   code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
+   if (code)
+       goto fail;
+
+   /* validate the context handle */
+   /*SUPPRESS 29*/
+   if (! kg_validate_ctx_id(*context_handle)) {
+      *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+      return(GSS_S_NO_CONTEXT);
+   }
+
+   ctx = (krb5_gss_ctx_id_rec *)*context_handle; /* SUNW15resync */
+
+   /* make sure the context is non-established, and that certain
+      arguments are unchanged */
+
+   if ((ctx->established) ||
+       ((ctx->gss_flags & GSS_C_MUTUAL_FLAG) == 0)) {
+      code = KG_CONTEXT_ESTABLISHED;
+      goto fail;
+   }
+
+   if (! krb5_principal_compare(context, ctx->there, 
+				(krb5_principal) target_name)) {
+      (void)krb5_gss_delete_sec_context(minor_status, 
+					context_handle, NULL);
+      code = 0;
+      major_status = GSS_S_BAD_NAME;
+      goto fail;
+   }
+
+   /* verify the token and leave the AP_REP message in ap_rep */
+
+   if (input_token == GSS_C_NO_BUFFER) {
+      (void)krb5_gss_delete_sec_context(minor_status, 
+					context_handle, NULL);
+      code = 0;
+      major_status = GSS_S_DEFECTIVE_TOKEN;
+      goto fail;
+   }
+
+   ptr = (unsigned char *) input_token->value;
+
+   if (g_verify_token_header(ctx->mech_used,
+			     &(ap_rep.length),
+			     &ptr, KG_TOK_CTX_AP_REP,
+			     input_token->length, 1)) {
+      if (g_verify_token_header((gss_OID) ctx->mech_used,
+				&(ap_rep.length),
+				&ptr, KG_TOK_CTX_ERROR,
+				input_token->length, 1) == 0) {
+
+	 /* Handle a KRB_ERROR message from the server */
+
+	 sptr = (char *) ptr;           /* PC compiler bug */
+	 TREAD_STR(sptr, ap_rep.data, ap_rep.length);
+		      
+	 code = krb5_rd_error(context, &ap_rep, &krb_error);
+	 if (code)
+	    goto fail;
+	 if (krb_error->error)
+	    code = krb_error->error + ERROR_TABLE_BASE_krb5;
+	 else
+	    code = 0;
+	 krb5_free_error(context, krb_error);
+	 goto fail;
+      } else {
+	 *minor_status = 0;
+	 return(GSS_S_DEFECTIVE_TOKEN);
+      }
+   }
+
+   sptr = (char *) ptr;                      /* PC compiler bug */
+   TREAD_STR(sptr, ap_rep.data, ap_rep.length);
+
+   /* decode the ap_rep */
+   if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep,
+			   &ap_rep_data))) {
+      /*
+       * XXX A hack for backwards compatiblity.
+       * To be removed in 1999 -- proven 
+       */
+      krb5_auth_con_setuseruserkey(context, ctx->auth_context,
+				   ctx->subkey);
+      if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep,
+		       &ap_rep_data)))
+	 goto fail;
+   }
+
+   /* store away the sequence number */
+   ctx->seq_recv = ap_rep_data->seq_number;
+   g_order_init(&(ctx->seqstate), ctx->seq_recv,
+		(ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
+		(ctx->gss_flags & GSS_C_SEQUENCE_FLAG) !=0, ctx->proto);
+
+   if (ctx->proto == 1 && ap_rep_data->subkey) {
+       /* Keep acceptor's subkey.  */
+       ctx->have_acceptor_subkey = 1;
+       code = krb5_copy_keyblock(context, ap_rep_data->subkey,
+				 &ctx->acceptor_subkey);
+       if (code)
+	   goto fail;
+       code = (*kaccess.krb5int_c_mandatory_cksumtype)(context,
+					    ctx->acceptor_subkey->enctype,
+					    &ctx->acceptor_subkey_cksumtype);
+       if (code)
+	   goto fail;
+   }
+
+   /* free the ap_rep_data */
+   krb5_free_ap_rep_enc_part(context, ap_rep_data);
+
+   /* set established */
+   ctx->established = 1;
+
+   /* set returns */
+
+   if (time_rec) {
+      if ((code = krb5_timeofday(context, &now)))
+	 goto fail;
+      *time_rec = ctx->endtime - now;
+   }
+
+   if (ret_flags)
+      *ret_flags = ctx->gss_flags;
+
+   if (actual_mech_type)
+      *actual_mech_type = mech_type;
+
+   /* success */
+
+   *minor_status = 0;
+   return GSS_S_COMPLETE;
+
+fail:
+   (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
+
+   *minor_status = code;
+   return (major_status);
+}
+
+OM_uint32
+krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
+			  context_handle, target_name, 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 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;
+{
+   krb5_context context;
+   krb5_gss_cred_id_t cred;
+   int err;
+   krb5_error_code kerr;
+   int default_mech = 0;
+   OM_uint32 major_status;
+   OM_uint32 tmp_min_stat;
+
+   if (*context_handle == GSS_C_NO_CONTEXT) {
+       kerr = krb5_gss_init_context(&context);
+       if (kerr) {
+	   *minor_status = kerr;
+	   return GSS_S_FAILURE;
+       }
+       if (GSS_ERROR(kg_sync_ccache_name(context, minor_status)))
+	   return GSS_S_FAILURE;
+   } else {
+       context = ((krb5_gss_ctx_id_rec *)*context_handle)->k5_context;
+   }
+
+   /* set up return values so they can be "freed" successfully */
+
+   major_status = GSS_S_FAILURE; /* Default major code */
+   output_token->length = 0;
+   output_token->value = NULL;
+   if (actual_mech_type)
+      *actual_mech_type = NULL;
+
+   /* verify that the target_name is valid and usable */
+
+   if (! kg_validate_name(target_name)) {
+      *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+      if (*context_handle == GSS_C_NO_CONTEXT)
+	  krb5_free_context(context);
+      return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
+   }
+
+   /* verify the credential, or use the default */
+   /*SUPPRESS 29*/
+   if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) {
+      /*
+       * Solaris Kerberos: here we are using the Solaris specific
+       * function get_default_cred() to handle the special case of a
+       * root principal
+       */
+      major_status = get_default_cred(minor_status, context,
+				    (gss_cred_id_t *)&cred);
+      if (major_status && GSS_ERROR(major_status)) {
+	 if (*context_handle == GSS_C_NO_CONTEXT)
+	    krb5_free_context(context);
+	 return(major_status);
+      }
+   } else {
+      major_status = krb5_gss_validate_cred(minor_status, claimant_cred_handle);
+      if (GSS_ERROR(major_status)) {
+	  if (*context_handle == GSS_C_NO_CONTEXT)
+	      krb5_free_context(context);
+	  return(major_status);
+      }
+      cred = (krb5_gss_cred_id_t) claimant_cred_handle;
+   }
+   kerr = k5_mutex_lock(&cred->lock);
+   if (kerr) {
+       krb5_free_context(context);
+       *minor_status = kerr;
+       return GSS_S_FAILURE;
+   }
+
+   /* verify the mech_type */
+
+   err = 0;
+   if (mech_type == GSS_C_NULL_OID) {
+       default_mech = 1;
+       if (cred->rfc_mech) {
+	   mech_type = (gss_OID) gss_mech_krb5;
+       } else if (cred->prerfc_mech) {
+	   mech_type = (gss_OID) gss_mech_krb5_old;
+       } else {
+	   err = 1;
+       }
+   } else if (g_OID_equal(mech_type, gss_mech_krb5)) {
+       if (!cred->rfc_mech)
+	   err = 1;
+   } else if (g_OID_equal(mech_type, gss_mech_krb5_old)) {
+       if (!cred->prerfc_mech)
+	   err = 1;
+   } else if (g_OID_equal(mech_type, gss_mech_krb5_wrong)) {
+       if (!cred->rfc_mech)
+	   err = 1;
+   } else {
+       err = 1;
+   }
+   
+   if (err) {
+      k5_mutex_unlock(&cred->lock);
+      if (claimant_cred_handle == GSS_C_NO_CREDENTIAL)
+	 krb5_gss_release_cred(minor_status, (gss_cred_id_t *)&cred);
+      *minor_status = 0;
+      if (*context_handle == GSS_C_NO_CONTEXT)
+	 krb5_free_context(context);
+      return(GSS_S_BAD_MECH);
+   }
+
+   /* is this a new connection or not? */
+
+   /*SUPPRESS 29*/
+   if (*context_handle == GSS_C_NO_CONTEXT) {
+      major_status = new_connection(minor_status, cred, context_handle,
+				    target_name, mech_type, req_flags,
+				    time_req, input_chan_bindings,
+				    input_token, actual_mech_type,
+				    output_token, ret_flags, time_rec,
+				    context, default_mech);
+      k5_mutex_unlock(&cred->lock);
+      if (*context_handle == GSS_C_NO_CONTEXT)
+	  krb5_free_context(context);
+      else
+	  ((krb5_gss_ctx_id_rec *) *context_handle)->k5_context = context;
+   } else {
+      /* mutual_auth doesn't care about the credentials */
+      k5_mutex_unlock(&cred->lock);
+      major_status = mutual_auth(minor_status, context_handle,
+				 target_name, mech_type, req_flags,
+				 time_req, input_chan_bindings,
+				 input_token, actual_mech_type,
+				 output_token, ret_flags, time_rec,
+				 context);
+      /* If context_handle is now NO_CONTEXT, mutual_auth called
+	 delete_sec_context, which would've zapped the krb5 context
+	 too.  */
+   }
+
+   if (claimant_cred_handle == GSS_C_NO_CREDENTIAL)
+      krb5_gss_release_cred(&tmp_min_stat, (gss_cred_id_t *)&cred);
+
+   return(major_status);
+}
+
+#if 0 /* SUNW15resync - revisit when mech resynced w/1.5 */
+k5_mutex_t kg_kdc_flag_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
+static int kdc_flag = 0;
+#endif
+
+krb5_error_code
+krb5_gss_init_context (krb5_context *ctxp)
+{
+    krb5_error_code err;
+    int is_kdc;
+
+    err = gssint_initialize_library();
+    if (err)
+	return err;
+#if 0 /* SUNW15resync - revisit when mech resynced w/1.5 */
+    err = k5_mutex_lock(&kg_kdc_flag_mutex);
+    if (err)
+	return err;
+    is_kdc = kdc_flag;
+    k5_mutex_unlock(&kg_kdc_flag_mutex);
+
+    if (is_kdc)
+	return krb5int_init_context_kdc(ctxp);
+    else
+	return krb5_init_context(ctxp);
+#endif
+    return krb5_init_context(ctxp);
+
+}
+
+#if 0 /* SUNW15resync - revisit when mech resynced w/1.5 */
+krb5_error_code
+krb5_gss_use_kdc_context()
+{
+    krb5_error_code err;
+
+    err = gssint_initialize_library();
+    if (err)
+	return err;
+    err = k5_mutex_lock(&kg_kdc_flag_mutex);
+    if (err)
+	return err;
+    kdc_flag = 1;
+    k5_mutex_unlock(&kg_kdc_flag_mutex);
+    return 0;
+}
+#endif
+
+/* Solaris Kerberos specific routines start */
+
+#define ROOT_UID 0
+#define KRB5_DEFAULT_LIFE 60*60*10
+#define CACHE_FILENAME_LEN 35
+
+extern int
+safechown(const char *src, uid_t uid, gid_t gid, int mode);
 
 static krb5_boolean
 principal_ignore_inst_compare(context, princ1, princ2)
@@ -709,7 +1396,6 @@
 		*minor_status = code;
 		return (GSS_S_FAILURE);
 	}
-
 	/*
 	 * Solaris Kerberos:
 	 * If the client's realm is empty (using a fallback method to determine
@@ -774,6 +1460,11 @@
 
 		return (GSS_S_FAILURE);
 	}
+	/*
+	 * Evidently (sigh), on success, krb5_get_init_creds_keytab
+	 * changes the my_creds princ ptrs so we need to free those
+	 * princs (me&server) as well as freeing all of my_creds contents.
+	 */
 	code = krb5_get_init_creds_keytab(context,
                                 &my_creds, me, keytab,
                                 0, svcname, &opt);
@@ -788,16 +1479,23 @@
 
 		return (GSS_S_FAILURE);
 	}
+
+	krb5_free_principal(context, server);
+	server = NULL;
+
 	code = krb5_cc_resolve (context,
 				krb5_cc_default_name(context),
 				&ccache);
 	if (code != 0) {
 		*minor_status = code;
 		krb5_free_cred_contents(context, &my_creds);
+		krb5_free_principal(context, me);
 
 		return (GSS_S_FAILURE);
 	}
 	code = krb5_cc_initialize (context, ccache, me);
+	krb5_free_principal(context, me);
+	me = NULL;
 	if (code != 0) {
 		*minor_status = code;
 		krb5_free_cred_contents(context, &my_creds);
@@ -981,13 +1679,13 @@
 	
 	/* If we can't get the time, assume the worst. */
 	if (krb5_timeofday(context, &now)) {
-		(void) krb5_gss_release_cred_no_lock(ct, &mntmp, cred_handle);
+		(void) krb5_gss_release_cred(&mntmp, cred_handle);
 		return (GSS_S_CREDENTIALS_EXPIRED);
 	}
 
 	/* If root's cred has expired re-get it */
 	if (cred->tgt_expire < now + MIN_REFRESH_TIME && uid == ROOT_UID) {
-		(void) krb5_gss_release_cred_no_lock(ct, &mntmp, cred_handle);
+		(void) krb5_gss_release_cred(&mntmp, cred_handle);
 
 		major = load_root_cred_using_keytab(minor_status,
 						    context, "root", 1);
@@ -1010,7 +1708,7 @@
 	/* Any body else is SOL unless we can renew their credential cache */
 	} else if ((cred->tgt_expire < now + MIN_RENEW_TIME) &&
 			(cred->tgt_expire > now)) {
-		(void) krb5_gss_release_cred_no_lock(ct, &mntmp, cred_handle);
+		(void) krb5_gss_release_cred(&mntmp, cred_handle);
 
 		major = renew_ccache(minor_status, context, uid);
 		if ((major != GSS_S_COMPLETE) &&
@@ -1030,617 +1728,4 @@
 	return (GSS_S_COMPLETE);
 }
 
-/*
- * setup_enc
- *
- * Fill in the encryption descriptors.	Called after AP-REQ is made.
- */
-static OM_uint32
-setup_enc(
-   OM_uint32 *minor_status,
-   krb5_gss_ctx_id_rec *ctx,
-   krb5_context context)
-{
-   krb5_error_code code;
-   OM_uint32 ret = GSS_S_COMPLETE;
-   int i;
-
-   ctx->have_acceptor_subkey = 0;
-   ctx->proto = 0;
-   ctx->cksumtype = 0;
-
-   KRB5_LOG(KRB5_ERR, "setup_enc() enctype = %d\n",
-	ctx->subkey->enctype);
-
-   switch(ctx->subkey->enctype) {
-   case ENCTYPE_DES_CBC_MD5:
-   case ENCTYPE_DES_CBC_MD4:
-   case ENCTYPE_DES_CBC_CRC:
-	ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
-	ctx->signalg = SGN_ALG_DES_MAC_MD5;
-	ctx->cksum_size = 8;
-	ctx->sealalg = SEAL_ALG_DES;
-
-	/* The encryption key is the session key XOR
-	 0xf0f0f0f0f0f0f0f0.  */
-	if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc)))
-	    goto fail;
-
-	for (i=0; i<ctx->enc->length; i++)
-	    ctx->enc->contents[i] ^= 0xf0;
-
-	goto copy_subkey_to_seq;
-
-   case ENCTYPE_DES3_CBC_SHA1:
-	/* MIT extension */
-	ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
-	ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
-	ctx->cksum_size = 20;
-	ctx->sealalg = SEAL_ALG_DES3KD;
-
-   copy_subkey:
-	code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc);
-	if (code)
-	    goto fail;
-   copy_subkey_to_seq:
-	code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq);
-	if (code) {
-	    krb5_free_keyblock (context, ctx->enc);
-	    goto fail;
-	}
-	break;
-
-   case ENCTYPE_ARCFOUR_HMAC:
-	/* Microsoft extension */
-	ctx->signalg = SGN_ALG_HMAC_MD5 ;
-	ctx->cksum_size = 8;
-	ctx->sealalg = SEAL_ALG_MICROSOFT_RC4 ;
-
-	goto copy_subkey;
-
-   default:
-       /* Fill some fields we shouldn't be using on this path
-	  with garbage.	 */
-	ctx->signalg = -10;
-	ctx->sealalg = -10;
-
-	ctx->proto = 1;
-	code = krb5int_c_mandatory_cksumtype(context, ctx->subkey->enctype,
-		&ctx->cksumtype);
-	if (code)
-	    goto fail;
-	code = krb5_c_checksum_length(context, ctx->cksumtype,
-				(size_t *)&ctx->cksum_size);
-	if (code)
-	    goto fail;
-	goto copy_subkey;
-   }
-fail:
-   if (code) {
-	*minor_status = code;
-	ret = GSS_S_FAILURE;
-   }
-success:
-   return (ret);
-}
-
-/*
- * new_connection
- *
- * Do the grunt work of setting up a new context.
- */
-static OM_uint32
-new_connection(
-   OM_uint32 *minor_status,
-   krb5_gss_cred_id_t cred,
-   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,
-   krb5_context context,
-   int default_mech)
-{
-   OM_uint32 major_status;
-   krb5_error_code code;
-   krb5_creds *k_cred;
-   krb5_gss_ctx_id_rec *ctx, *ctx_free;
-   krb5_timestamp now;
-   gss_buffer_desc token;
-
-   major_status = GSS_S_FAILURE;
-   token.length = 0;
-   token.value = NULL;
-
-   /* make sure the cred is usable for init */
-
-   if ((cred->usage != GSS_C_INITIATE) &&
-	(cred->usage != GSS_C_BOTH)) {
-	*minor_status = 0;
-	return(GSS_S_NO_CRED);
-   }
-
-   /* complain if the input token is non-null */
-
-   if (input_token != GSS_C_NO_BUFFER && input_token->length != 0) {
-       *minor_status = 0;
-	return(GSS_S_DEFECTIVE_TOKEN);
-   }
-
-   /* create the ctx */
-
-   if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec)))
-	== NULL) {
-	*minor_status = ENOMEM;
-	return(GSS_S_FAILURE);
-   }
-
-   /* fill in the ctx */
-   memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec));
-   ctx_free = ctx;
-   if ((code = krb5_auth_con_init(context, &ctx->auth_context)))
-	goto fail;
-   krb5_auth_con_setflags(context, ctx->auth_context,
-                          KRB5_AUTH_CONTEXT_DO_SEQUENCE);
-   ctx->initiate = 1;
-   ctx->gss_flags = (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG |
-                      GSS_C_TRANS_FLAG |  GSS_C_PROT_READY_FLAG |
-                      ((req_flags) & (GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
-                                      GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG)));
-   ctx->seed_init = 0;
-   ctx->big_endian = 0;	 /* all initiators do little-endian, as per spec */
-   ctx->seqstate = 0;
-   if ((code = krb5_timeofday(context, &now)))
-	goto fail;
-
-   if (time_req == 0 || time_req == GSS_C_INDEFINITE) {
-	ctx->endtime = 0;
-   } else {
-      ctx->endtime = now + time_req;
-   }
-
-   if ((code = krb5_copy_principal(context, cred->princ, &ctx->here)))
-	goto fail;
-
-   if ((code = krb5_copy_principal(context, (krb5_principal) target_name,
-                                   &ctx->there)))
-	goto fail;
-
-   code = get_credentials(context, cred, ctx->there, now,
-                          ctx->endtime, &k_cred);
-   if (code)
-      goto fail;
-
-   if (default_mech) {
-	mech_type = (gss_OID) gss_mech_krb5;
-   }
-      /* Solaris Kerberos:  we allocate the memory for mech_used here
-       * because we store mech_used as a gss_OID and not a (gss_OID *)
-       */
-   ctx->mech_used.elements = malloc(mech_type->length);
-   if ( (ctx->mech_used.elements) == NULL ) {
-	code = ENOMEM;
-	major_status = GSS_S_FAILURE;
-	goto fail;
-   }
-   ctx->mech_used.length = mech_type->length;
-   memcpy(ctx->mech_used.elements, mech_type->elements, mech_type->length);
-
-   /*
-    * Now try to make it static if at all possible....
-    */
-   /* Solaris Kerberos:  our mech_used is part of the ctx structure */
-   /* ctx->mech_used = krb5_gss_convert_static_mech_oid(&(ctx->mech_used)); */
-   {
-      /* gsskrb5 v1 */
-	krb5_ui_4 seq_temp;
-	if ((code = make_ap_req_v1(context, ctx,
-                                 cred, k_cred, input_chan_bindings,
-                                 mech_type, &token))) {
-	 if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) ||
-             (code == KG_EMPTY_CCACHE))
-            major_status = GSS_S_NO_CRED;
-	 if (code == KRB5KRB_AP_ERR_TKT_EXPIRED)
-            major_status = GSS_S_CREDENTIALS_EXPIRED;
-	 goto fail;
-	}
-
-	krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, 
-		(krb5_int32 *)&seq_temp);
-	ctx->seq_send = seq_temp;
-	krb5_auth_con_getsendsubkey(context, ctx->auth_context,
-                                  &ctx->subkey);
-   }
-
-   major_status = setup_enc(minor_status, ctx, context);
-
-   if (k_cred) {
-	krb5_free_creds(context, k_cred);
-	k_cred = 0;
-   }
-
-   /* at this point, the context is constructed and valid,
-	hence, releaseable */
-
-   /* intern the context handle */
-
-   if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
-	code = G_VALIDATE_FAILED;
-	goto fail;
-   }
-   *context_handle = (gss_ctx_id_t) ctx;
-   ctx_free = 0;
-   /* compute time_rec */
-   if (time_rec) {
-	if ((code = krb5_timeofday(context, &now)))
-	    goto fail;
-	*time_rec = ctx->endtime - now;
-   }
-
-   /* set the other returns */
-   *output_token = token;
-
-   if (ret_flags)
-	*ret_flags = ctx->gss_flags;
-
-   if (actual_mech_type)
-	*actual_mech_type = mech_type;
-
-   /* return successfully */
-
-   *minor_status = 0;
-   if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) {
-	ctx->established = 0;
-	return(GSS_S_CONTINUE_NEEDED);
-   } else {
-      ctx->seq_recv = ctx->seq_send;
-	g_order_init(&(ctx->seqstate), ctx->seq_recv,
-                   (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
-                   (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0, ctx->proto);
-	ctx->gss_flags |= GSS_C_PROT_READY_FLAG;
-	ctx->established = 1;
-	return(GSS_S_COMPLETE);
-   }
-
-fail:
-   if (ctx_free) {
-	if (ctx_free->auth_context)
-	   krb5_auth_con_free(context, ctx_free->auth_context);
-	if (ctx_free->here)
-	   krb5_free_principal(context, ctx_free->here);
-	if (ctx_free->there)
-	   krb5_free_principal(context, ctx_free->there);
-	if (ctx_free->subkey)
-	   krb5_free_keyblock(context, ctx_free->subkey);
-	xfree(ctx_free);
-   } else {
-        (void)krb5_gss_delete_sec_context_no_lock(context, minor_status,
-	    context_handle, NULL);
-   }
-
-   *minor_status = code;
-   return (major_status);
-}
-
-/*
- * mutual_auth
- *
- * Handle the reply from the acceptor, if we're doing mutual auth.
- */
-static OM_uint32
-mutual_auth(
-   OM_uint32 *minor_status,
-   krb5_gss_cred_id_t cred,
-   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,
-   krb5_context context)
-{
-   OM_uint32 major_status;
-   unsigned char *ptr;
-   char *sptr;
-   krb5_data ap_rep;
-   krb5_ap_rep_enc_part *ap_rep_data;
-   krb5_timestamp now;
-   krb5_gss_ctx_id_rec *ctx;
-   krb5_error *krb_error;
-   krb5_error_code code;
-
-   major_status = GSS_S_FAILURE;
-
-   /* validate the context handle */
-   /*SUPPRESS 29*/
-   if (! kg_validate_ctx_id(*context_handle)) {
-	*minor_status = (OM_uint32) G_VALIDATE_FAILED;
-	return(GSS_S_NO_CONTEXT);
-   }
-
-   ctx = (krb5_gss_ctx_id_rec *) *context_handle;
-
-   /* make sure the context is non-established, and that certain
-	arguments are unchanged */
-
-   if ((ctx->established) ||
-	((ctx->gss_flags & GSS_C_MUTUAL_FLAG) == 0)) {
-	code = KG_CONTEXT_ESTABLISHED;
-	goto fail;
-   }
-
-   if (! krb5_principal_compare(context, ctx->there,
-				(krb5_principal) target_name)) {
-	(void)krb5_gss_delete_sec_context_no_lock(context, minor_status,
-                                        context_handle, NULL);
-	code = 0;
-	major_status = GSS_S_BAD_NAME;
-	goto fail;
-   }
-
-   /* verify the token and leave the AP_REP message in ap_rep */
-
-   if (input_token == GSS_C_NO_BUFFER) {
-	(void)krb5_gss_delete_sec_context_no_lock(context, minor_status,
-                                        context_handle, NULL);
-	code = 0;
-	major_status = GSS_S_DEFECTIVE_TOKEN;
-	goto fail;
-   }
-
-   ptr = (unsigned char *) input_token->value;
-
-   if (g_verify_token_header(&ctx->mech_used,
-                             (uint32_t *)&(ap_rep.length),
-                             &ptr, KG_TOK_CTX_AP_REP,
-                             input_token->length, 1)) {
-	if (g_verify_token_header(&ctx->mech_used,
-				(uint32_t *)&(ap_rep.length),
-				&ptr, KG_TOK_CTX_ERROR,
-				input_token->length, 1) == 0) {
-
-	 /* Handle a KRB_ERROR message from the server */
-
-	 sptr = (char *) ptr;		/* PC compiler bug */
-	 TREAD_STR(sptr, ap_rep.data, ap_rep.length);
-
-	 code = krb5_rd_error(context, &ap_rep, &krb_error);
-	 if (code)
-            goto fail;
-	 if (krb_error->error)
-            code = krb_error->error + ERROR_TABLE_BASE_krb5;
-	 else
-            code = 0;
-	 krb5_free_error(context, krb_error);
-	 goto fail;
-	} else {
-	 *minor_status = 0;
-	 return(GSS_S_DEFECTIVE_TOKEN);
-	}
-   }
-
-   sptr = (char *) ptr;                      /* PC compiler bug */
-   TREAD_STR(sptr, ap_rep.data, ap_rep.length);
-
-   /* decode the ap_rep */
-   if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep,
-                           &ap_rep_data))) {
-	/*
-       * XXX A hack for backwards compatiblity.
-	* To be removed in 1999 -- proven
-	*/
-      krb5_auth_con_setuseruserkey(context, ctx->auth_context,
-                                   ctx->subkey);
-	if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep,
-			&ap_rep_data)))
-	 goto fail;
-   }
-
-   /* store away the sequence number */
-   ctx->seq_recv = ap_rep_data->seq_number;
-   g_order_init(&(ctx->seqstate), ctx->seq_recv,
-		(ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
-		(ctx->gss_flags & GSS_C_SEQUENCE_FLAG) !=0, ctx->proto);
-
-   if (ctx->proto == 1 && ap_rep_data->subkey) {
-	/* Keep acceptor's subkey.  */
-	ctx->have_acceptor_subkey = 1;
-	code = krb5_copy_keyblock(context, ap_rep_data->subkey,
-                                 &ctx->acceptor_subkey);
-	if (code)
-           goto fail;
-	code = krb5int_c_mandatory_cksumtype(context,
-		ctx->acceptor_subkey->enctype,
-		&ctx->acceptor_subkey_cksumtype);
-	if (code)
-           goto fail;
-   }
-
-   /* free the ap_rep_data */
-   krb5_free_ap_rep_enc_part(context, ap_rep_data);
-
-   /* set established */
-   ctx->established = 1;
-
-   /* set returns */
-
-   if (time_rec) {
-	if ((code = krb5_timeofday(context, &now)))
-	 goto fail;
-	*time_rec = ctx->endtime - now;
-   }
-   if (ret_flags)
-	*ret_flags = ctx->gss_flags;
-
-   if (actual_mech_type)
-	*actual_mech_type = mech_type;
-
-   /* success */
-
-   *minor_status = 0;
-   return GSS_S_COMPLETE;
-
-fail:
-   (void)krb5_gss_delete_sec_context_no_lock(context, minor_status,
-       context_handle, NULL);
-
-   *minor_status = code;
-   return (major_status);
-}
-
-/*
- * krb5_gss_init_sec_context
- * This has been broken up into smaller chunks for CFX support.
- * MIT KRB5 1.3.2
- */
-OM_uint32
-krb5_gss_init_sec_context(ct, minor_status, claimant_cred_handle,
-			  context_handle, target_name, mech_type,
-			  req_flags, time_req, input_chan_bindings,
-			  input_token, actual_mech_type, output_token,
-			  ret_flags, time_rec)
-    void      *ct;
-    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;
-{
-   krb5_context context;
-   krb5_gss_cred_id_t cred = NULL;
-   int err;
-   int default_mech = 0;
-   OM_uint32 major_status;
-   OM_uint32 tmp_min_stat;
-
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, &context)))
-      return(GSS_S_FAILURE);
-#endif
-
-   KRB5_LOG0(KRB5_INFO, "krb5_gss_init_sec_context() start\n");
-
-   mutex_lock(&krb5_mutex);
-   context = ct;
-
-   /* set up return values so they can be "freed" successfully */
-
-   major_status = GSS_S_FAILURE; /* Default major code */
-   output_token->length = 0;
-   output_token->value = NULL;
-   if (actual_mech_type)
-      *actual_mech_type = NULL;
-
-   /* verify that the target_name is valid and usable */
-
-   if (! kg_validate_name(target_name)) {
-      *minor_status = (OM_uint32) G_VALIDATE_FAILED;
-      major_status = (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
-      goto unlock;
-   }
-
-   /* verify the credential, or use the default */
-   /*SUPPRESS 29*/
-   if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) {
-      /*
-       * Solaris Kerberos: here we are using the Solaris specific
-       * function get_default_cred() to handle the special case of a
-       * root principal
-       */
-      major_status = get_default_cred(minor_status, ct, (gss_cred_id_t *)&cred);
-      if (major_status && GSS_ERROR(major_status)) {
-	    KRB5_LOG(KRB5_ERR, "krb5_gss_init_sec_context() end, error "
-		   "major_status = %d\n", major_status);
-	    goto unlock;
-      }
-   } else {
-      major_status = krb5_gss_validate_cred_no_lock(ct, minor_status,
-					     claimant_cred_handle);
-      if (GSS_ERROR(major_status)) {
-	  KRB5_LOG(KRB5_ERR, "krb5_gss_init_sec_context() end, error "
-		   "major_status = %d\n", major_status);
-	  goto unlock;
-      }
-      cred = (krb5_gss_cred_id_t) claimant_cred_handle;
-   }
-
-   /* verify the mech_type */
-
-   err = 0;
-   if (mech_type == GSS_C_NULL_OID) {
-       default_mech = 1;
-       if (cred->rfc_mech) {
-	   mech_type = (gss_OID) gss_mech_krb5;
-       } else if (cred->prerfc_mech) {
-	   mech_type = (gss_OID) gss_mech_krb5_old;
-       } else {
-	   err = 1;
-       }
-   } else if (g_OID_equal(mech_type, gss_mech_krb5)) {
-       if (!cred->rfc_mech)
-	   err = 1;
-   } else if (g_OID_equal(mech_type, gss_mech_krb5_old)) {
-       if (!cred->prerfc_mech)
-	   err = 1;
-   } else {
-       err = 1;
-   }
-
-   if (err) {
-      *minor_status = 0;
-      major_status = GSS_S_BAD_MECH;
-      goto unlock;
-   }
-
-   /* is this a new connection or not? */
-
-   /*SUPPRESS 29*/
-   if (*context_handle == GSS_C_NO_CONTEXT) {
-      major_status = new_connection(minor_status, cred, context_handle,
-                                    target_name, mech_type, req_flags,
-                                    time_req, input_chan_bindings,
-                                    input_token, actual_mech_type,
-                                    output_token, ret_flags, time_rec,
-                                    context, default_mech);
-   } else {
-      major_status = mutual_auth(minor_status, cred, context_handle,
-                                 target_name, mech_type, req_flags,
-                                 time_req, input_chan_bindings,
-                                 input_token, actual_mech_type,
-                                 output_token, ret_flags, time_rec,
-                                 context);
-   }
-
-unlock:
-   if (claimant_cred_handle == GSS_C_NO_CREDENTIAL && cred != NULL)
-	krb5_gss_release_cred_no_lock(context, &tmp_min_stat, (gss_cred_id_t *)cred);
-
-   mutex_unlock(&krb5_mutex);
-
-   KRB5_LOG1(KRB5_ERR, "krb5_gss_init_sec_context() end, error "
-	   "major_status = %d, minor_status = %d\n", 
-	   major_status, *minor_status);
-
-   return (major_status);
-}
+/* Solaris Kerberos specific routines end */
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/inq_context.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/inq_context.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,13 +1,8 @@
-/*
- * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
  * Copyright 1993 by OpenVision Technologies, 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
@@ -17,7 +12,7 @@
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
- *
+ * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -27,13 +22,12 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
 
 OM_uint32
-krb5_gss_inquire_context(ct, minor_status, context_handle, initiator_name,
+krb5_gss_inquire_context(minor_status, context_handle, initiator_name, 
 			 acceptor_name, lifetime_rec, mech_type, ret_flags,
 			 locally_initiated, open)
-     void      *ct;
      OM_uint32 *minor_status;
      gss_ctx_id_t context_handle;
      gss_name_t *initiator_name;
@@ -51,16 +45,6 @@
    krb5_timestamp now;
    krb5_deltat lifetime;
 
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, &context)))
-      return(GSS_S_FAILURE);
-#endif
-
-   mutex_lock(&krb5_mutex);
-   context = ct;
-
    if (initiator_name)
       *initiator_name = (gss_name_t) NULL;
    if (acceptor_name)
@@ -69,7 +53,6 @@
    /* validate the context handle */
    if (! kg_validate_ctx_id(context_handle)) {
       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
-      mutex_unlock(&krb5_mutex);
       return(GSS_S_NO_CONTEXT);
    }
 
@@ -77,16 +60,15 @@
 
    if (! ctx->established) {
       *minor_status = KG_CTX_INCOMPLETE;
-      mutex_unlock(&krb5_mutex);
       return(GSS_S_NO_CONTEXT);
    }
 
    init = NULL;
    accept = NULL;
+   context = ctx->k5_context;
 
-   if (code = krb5_timeofday(context, &now)) {
+   if ((code = krb5_timeofday(context, &now))) {
       *minor_status = code;
-      mutex_unlock(&krb5_mutex);
       return(GSS_S_FAILURE);
    }
 
@@ -94,28 +76,25 @@
       lifetime = 0;
 
    if (initiator_name) {
-      if (code = krb5_copy_principal(context,
-				     ctx->initiate?ctx->here:ctx->there,
-				     &init)) {
+      if ((code = krb5_copy_principal(context, 
+				      ctx->initiate?ctx->here:ctx->there,
+				      &init))) {
 	 *minor_status = code;
-	 mutex_unlock(&krb5_mutex);
 	 return(GSS_S_FAILURE);
       }
       if (! kg_save_name((gss_name_t) init)) {
 	 krb5_free_principal(context, init);
 	 *minor_status = (OM_uint32) G_VALIDATE_FAILED;
-	 mutex_unlock(&krb5_mutex);
 	 return(GSS_S_FAILURE);
       }
    }
 
    if (acceptor_name) {
-      if (code = krb5_copy_principal(context,
-				     ctx->initiate?ctx->there:ctx->here,
-				     &accept)) {
+      if ((code = krb5_copy_principal(context, 
+				      ctx->initiate?ctx->there:ctx->here,
+				      &accept))) {
 	 if (init) krb5_free_principal(context, init);
 	 *minor_status = code;
-	 mutex_unlock(&krb5_mutex);
 	 return(GSS_S_FAILURE);
       }
       if (! kg_save_name((gss_name_t) accept)) {
@@ -125,7 +104,6 @@
 	    krb5_free_principal(context, init);
 	 }
 	 *minor_status = (OM_uint32) G_VALIDATE_FAILED;
-	 mutex_unlock(&krb5_mutex);
 	 return(GSS_S_FAILURE);
       }
    }
@@ -140,8 +118,7 @@
       *lifetime_rec = lifetime;
 
    if (mech_type)
-     *mech_type =  &(ctx->mech_used);
-
+      *mech_type = (gss_OID) ctx->mech_used;
 
    if (ret_flags)
       *ret_flags = ctx->gss_flags;
@@ -153,6 +130,5 @@
       *open = ctx->established;
 
    *minor_status = 0;
-   mutex_unlock(&krb5_mutex);
    return((lifetime == 0)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE);
 }
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/inq_cred.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/inq_cred.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,8 +1,3 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
@@ -13,7 +8,7 @@
  *   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
@@ -27,11 +22,11 @@
  * 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 1993 by OpenVision Technologies, 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
@@ -41,7 +36,7 @@
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
- *
+ * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -53,14 +48,14 @@
 
 /*
  * Copyright (C) 1998 by the FundsXpress, INC.
- *
+ * 
  * 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
@@ -71,44 +66,18 @@
  * permission.  FundsXpress makes no representations about the suitability of
  * this software for any purpose.  It is provided "as is" without express
  * or implied warranty.
- *
+ * 
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#include <gssapiP_krb5.h>
-#include <k5-int.h>
-
-extern OM_uint32 gss_copy_oid_set();
-extern OM_uint32 gss_create_empty_oid_set();
-extern OM_uint32 gss_add_oid_set_member();
-
+#include "gssapiP_krb5.h"
+#include "mglueP.h"
 
 OM_uint32
-krb5_gss_inquire_cred(ctx, minor_status, cred_handle, name, lifetime_ret,
+krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
 		      cred_usage, mechanisms)
-     void	*ctx;
-     OM_uint32 *minor_status;
-     gss_cred_id_t cred_handle;
-     gss_name_t *name;
-     OM_uint32 *lifetime_ret;
-     gss_cred_usage_t *cred_usage;
-     gss_OID_set *mechanisms;
-{
-   OM_uint32 ret;
-
-   mutex_lock(&krb5_mutex);
-   ret = krb5_gss_inquire_cred_no_lock(ctx, minor_status, cred_handle, name,
-	   lifetime_ret, cred_usage, mechanisms);
-   mutex_unlock(&krb5_mutex);
-   return(ret);
-}
-
-OM_uint32
-krb5_gss_inquire_cred_no_lock(ctx, minor_status, cred_handle, name, 
-			      lifetime_ret, cred_usage, mechanisms)
-     void	*ctx;
      OM_uint32 *minor_status;
      gss_cred_id_t cred_handle;
      gss_name_t *name;
@@ -122,17 +91,17 @@
    krb5_timestamp now;
    krb5_deltat lifetime;
    krb5_principal ret_name;
-   gss_OID_set mechs = GSS_C_NULL_OID_SET;
+   gss_OID_set mechs;
    OM_uint32 ret;
 
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, &context)))
-      return(GSS_S_FAILURE);
-#endif
+   ret = GSS_S_FAILURE;
+   ret_name = NULL;
 
-   context = ctx;
+   code = krb5_gss_init_context(&context);
+   if (code) {
+       *minor_status = code;
+       return GSS_S_FAILURE;
+   }
 
    if (name) *name = NULL;
    if (mechanisms) *mechanisms = NULL;
@@ -141,27 +110,35 @@
    /*SUPPRESS 29*/
    if (cred_handle == GSS_C_NO_CREDENTIAL) {
       OM_uint32 major;
-      if (((major = kg_get_defcred(minor_status, &cred_handle)) != NULL) &&
+
+      if ((major = kg_get_defcred(minor_status, (gss_cred_id_t *)&cred)) &&
 	  GSS_ERROR(major)) {
+	 krb5_free_context(context);
 	 return(major);
       }
    } else {
       OM_uint32 major;
-	
-      major = krb5_gss_validate_cred_no_lock(context, minor_status,
-					     cred_handle);
+	   
+      major = krb5_gss_validate_cred(minor_status, cred_handle);
       if (GSS_ERROR(major)) {
+	  krb5_free_context(context);
 	  return(major);
       }
+      cred = (krb5_gss_cred_id_t) cred_handle;
    }
 
-   cred = (krb5_gss_cred_id_t) cred_handle;
-
    if ((code = krb5_timeofday(context, &now))) {
       *minor_status = code;
-      return(GSS_S_FAILURE);
+      ret = GSS_S_FAILURE;
+      goto fail;
    }
 
+   code = k5_mutex_lock(&cred->lock);
+   if (code != 0) {
+       *minor_status = code;
+       ret = GSS_S_FAILURE;
+       goto fail;
+   }
    if (cred->tgt_expire > 0) {
        if ((lifetime = cred->tgt_expire - now) < 0)
 	   lifetime = 0;
@@ -170,43 +147,50 @@
        lifetime = GSS_C_INDEFINITE;
 
    if (name) {
-     if (cred->princ &&
-      (code = krb5_copy_principal(context, cred->princ, &ret_name))) {
+      if (cred->princ &&
+	  (code = krb5_copy_principal(context, cred->princ, &ret_name))) {
+	 k5_mutex_unlock(&cred->lock);
 	 *minor_status = code;
-	 return(GSS_S_FAILURE);
+	 ret = GSS_S_FAILURE;
+	 goto fail;
       }
    }
 
    if (mechanisms) {
-       if (GSS_ERROR(ret = gss_create_empty_oid_set(minor_status,
+       if (GSS_ERROR(ret = generic_gss_create_empty_oid_set(minor_status,
 							    &mechs)) ||
 	   (cred->prerfc_mech &&
-	    GSS_ERROR(ret = gss_add_oid_set_member(minor_status,
-					(gss_OID) gss_mech_krb5_old,
+	    GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
+							(const gss_OID) gss_mech_krb5_old,
 							   &mechs))) ||
 	   (cred->rfc_mech &&
-	    GSS_ERROR(ret = gss_add_oid_set_member(minor_status,
-					(gss_OID) gss_mech_krb5,
+	    GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
+							(const gss_OID) gss_mech_krb5,
 							   &mechs)))) {
-	   krb5_free_principal(context, ret_name);
+	   k5_mutex_unlock(&cred->lock);
+	   if (ret_name)
+	       krb5_free_principal(context, ret_name);
 	   /* *minor_status set above */
-	   return(ret);
+	   goto fail;
        }
    }
 
-   /* Solaris Kerberos:
-    * Don't set name to ret_name if cred->princ is NULL.
-    * If cred->princ is NULL, ret_name is uninitialized and
-    * name already points to NULL. 
-    */ 
-   if (name && cred->princ) {
-      if (! kg_save_name((gss_name_t) ret_name)) {
+   if (name) {
+     if (ret_name != NULL && ! kg_save_name((gss_name_t) ret_name)) {
+	 k5_mutex_unlock(&cred->lock);
+	 if (cred_handle == GSS_C_NO_CREDENTIAL)
+	     krb5_gss_release_cred(minor_status, (gss_cred_id_t *)&cred);
+
 	 (void) gss_release_oid_set(minor_status, &mechs);
 	 krb5_free_principal(context, ret_name);
 	 *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+	 krb5_free_context(context);
 	 return(GSS_S_FAILURE);
       }
-      *name = (gss_name_t) ret_name;
+      if (ret_name != NULL)
+	  *name = (gss_name_t) ret_name;
+      else
+	  *name = GSS_C_NO_NAME;
    }
 
    if (lifetime_ret)
@@ -214,20 +198,32 @@
 
    if (cred_usage)
       *cred_usage = cred->usage;
+   k5_mutex_unlock(&cred->lock);
 
    if (mechanisms)
       *mechanisms = mechs;
 
+   if (cred_handle == GSS_C_NO_CREDENTIAL)
+       krb5_gss_release_cred(minor_status, (gss_cred_id_t *)&cred);
+
+   krb5_free_context(context);
    *minor_status = 0;
    return((lifetime == 0)?GSS_S_CREDENTIALS_EXPIRED:GSS_S_COMPLETE);
+fail:
+   if (cred_handle == GSS_C_NO_CREDENTIAL) {
+       OM_uint32 tmp_min_stat;
+
+       krb5_gss_release_cred(&tmp_min_stat, (gss_cred_id_t *)&cred);
+   }
+   krb5_free_context(context);
+   return ret;
 }
 
 /* V2 interface */
 OM_uint32
-krb5_gss_inquire_cred_by_mech(ctx, minor_status, cred_handle,
+krb5_gss_inquire_cred_by_mech(minor_status, cred_handle,
 			      mech_type, name, initiator_lifetime,
 			      acceptor_lifetime, cred_usage)
-    void		*ctx;
     OM_uint32		*minor_status;
     gss_cred_id_t	cred_handle;
     gss_OID		mech_type;
@@ -236,35 +232,22 @@
     OM_uint32		*acceptor_lifetime;
     gss_cred_usage_t *cred_usage;
 {
-    krb5_context	context;
     krb5_gss_cred_id_t	cred;
     OM_uint32		lifetime;
     OM_uint32		mstat;
 
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-    if (GSS_ERROR(kg_get_context(minor_status, &context)))
-       return(GSS_S_FAILURE);
-#endif
-
-    mutex_lock(&krb5_mutex);
-    context = ctx;
-
     /*
      * We only know how to handle our own creds.
      */
     if ((mech_type != GSS_C_NULL_OID) &&
 	!g_OID_equal(gss_mech_krb5_old, mech_type) &&
-	!g_OID_equal(gss_mech_krb5, mech_type) &&
-	!g_OID_equal(gss_mech_krb5_v2, mech_type)) {
+	!g_OID_equal(gss_mech_krb5, mech_type)) {
 	*minor_status = 0;
-	mutex_unlock(&krb5_mutex);
 	return(GSS_S_NO_CRED);
     }
 
     cred = (krb5_gss_cred_id_t) cred_handle;
-    mstat = krb5_gss_inquire_cred_no_lock(context, minor_status,
+    mstat = krb5_gss_inquire_cred(minor_status,
 				  cred_handle,
 				  name,
 				  &lifetime,
@@ -282,6 +265,6 @@
 	    acceptor_lifetime)
 	    *acceptor_lifetime = lifetime;
     }
-    mutex_unlock(&krb5_mutex);
     return(mstat);
 }
+
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/inq_names.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/inq_names.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,8 +1,3 @@
-/*
- * Copyright 2002-2003 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
@@ -35,36 +30,24 @@
 /*
  * inq_names.c - Return set of nametypes supported by the KRB5 mechanism.
  */
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
+#include "mglueP.h"
 
-/*ARGSUSED*/
 OM_uint32
-krb5_gss_inquire_names_for_mech(ctx, minor_status, mechanism, name_types)
-    void	*ctx;
+krb5_gss_inquire_names_for_mech(minor_status, mechanism, name_types)
     OM_uint32	*minor_status;
     gss_OID	mechanism;
     gss_OID_set	*name_types;
 {
     OM_uint32	major, minor;
 
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-    if (GSS_ERROR(kg_get_context(minor_status, &context)))
-       return(GSS_S_FAILURE);
-#endif
-
-    mutex_lock(&krb5_mutex);
-
     /*
      * We only know how to handle our own mechanism.
      */
     if ((mechanism != GSS_C_NULL_OID) &&
-	!g_OID_equal(gss_mech_krb5_v2, mechanism) &&
 	!g_OID_equal(gss_mech_krb5, mechanism) &&
 	!g_OID_equal(gss_mech_krb5_old, mechanism)) {
 	*minor_status = 0;
-	mutex_unlock(&krb5_mutex);
 	return(GSS_S_BAD_MECH);
     }
 
@@ -73,40 +56,38 @@
     if (major == GSS_S_COMPLETE) {
 	/* Now add our members. */
 	if (
-	    /* The following are GSS specified nametypes */
-	    ((major = gss_add_oid_set_member(minor_status,
-					     (gss_OID) GSS_C_NT_USER_NAME,
-					     name_types)
+	    ((major = generic_gss_add_oid_set_member(minor_status,
+						     gss_nt_user_name,
+						     name_types)
 	      ) == GSS_S_COMPLETE) &&
-	    ((major = gss_add_oid_set_member(minor_status,
-					     (gss_OID) GSS_C_NT_MACHINE_UID_NAME,
-					     name_types)
+	    ((major = generic_gss_add_oid_set_member(minor_status,
+						     gss_nt_machine_uid_name,
+						     name_types)
 	      ) == GSS_S_COMPLETE) &&
-	    ((major = gss_add_oid_set_member(minor_status,
-					     (gss_OID) GSS_C_NT_STRING_UID_NAME,
-					     name_types)
+	    ((major = generic_gss_add_oid_set_member(minor_status,
+						     gss_nt_string_uid_name,
+						     name_types)
 	      ) == GSS_S_COMPLETE) &&
-	    ((major = gss_add_oid_set_member(minor_status,
-					     (gss_OID) GSS_C_NT_HOSTBASED_SERVICE,
-					     name_types)
+	    ((major = generic_gss_add_oid_set_member(minor_status,
+						     gss_nt_service_name,
+						     name_types)
+	      ) == GSS_S_COMPLETE) &&
+	    ((major = generic_gss_add_oid_set_member(minor_status,
+						     gss_nt_service_name_v2,
+						     name_types)
 	      ) == GSS_S_COMPLETE) &&
-		/* The following are kerberos only nametypes */
-	    ((major = gss_add_oid_set_member(minor_status,
-					     (gss_OID) gss_nt_service_name_v2,
-					     name_types)
+	    ((major = generic_gss_add_oid_set_member(minor_status,
+						     gss_nt_exported_name,
+						     name_types)
 	      ) == GSS_S_COMPLETE) &&
-	    ((major = gss_add_oid_set_member(minor_status,
-					     (gss_OID) gss_nt_exported_name,
-					     name_types)
-	      ) == GSS_S_COMPLETE) &&
-	    ((major = gss_add_oid_set_member(minor_status,
-					     (gss_OID) gss_nt_krb5_name,
-					     name_types)
+	    ((major = generic_gss_add_oid_set_member(minor_status,
+						    (const gss_OID) gss_nt_krb5_name,
+						     name_types)
 	      ) == GSS_S_COMPLETE)
 	    ) {
-	    major = gss_add_oid_set_member(minor_status,
-					   (gss_OID) gss_nt_krb5_principal,
-					   name_types);
+	    major = generic_gss_add_oid_set_member(minor_status,
+						(const gss_OID) gss_nt_krb5_principal,
+						   name_types);
 	}
 
 	/*
@@ -117,6 +98,5 @@
 	    (void) gss_release_oid_set(&minor,
 				       name_types);
     }
-    mutex_unlock(&krb5_mutex);
     return(major);
 }
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/k5mech.c	Fri Sep 14 14:36:45 2007 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-/*
- * XXX: I know where to find this header, but it really is using a
- * private interface.  I dont want to export the gss_mechanism
- * structure, so I hide it in a non-published header.  Thats ok,
- * we know where to find it.
- */
-#include <mechglueP.h>
-
-#include <gssapiP_krb5.h>
-#include <syslog.h>
-#include <libintl.h>
-/*
- * These are the extern declarations, one group per mechanism. They are
- * contained in the files named <mech>_gssd_extern_srvr.conf.
- */
-
-static OM_uint32
-krb5_gss_get_context
-	PROTOTYPE((void**));
-
-/*
- * This is the declaration of the mechs_array table for Kerberos V5.
- * If the gss_mechanism structure changes, so should this array!  I
- * told you it was a private interface!
- */
-
-static struct gss_config krb5_mechanism = {
-	{9, "\052\206\110\206\367\022\001\002\002"},
-	0,			/* context, to be filled */
-	krb5_gss_acquire_cred,
-	krb5_gss_release_cred,
-	krb5_gss_init_sec_context,
-	krb5_gss_accept_sec_context,
-/* EXPORT DELETE START */ /* CRYPT DELETE START */
-	krb5_gss_unseal,
-/* EXPORT DELETE END */ /* CRYPT DELETE END */
-	krb5_gss_process_context_token,
-	krb5_gss_delete_sec_context,
-	krb5_gss_context_time,
-	krb5_gss_display_status,
-	krb5_gss_indicate_mechs,
-	krb5_gss_compare_name,
-	krb5_gss_display_name,
-	krb5_gss_import_name,
-	krb5_gss_release_name,
-	krb5_gss_inquire_cred,
-	krb5_gss_add_cred,
-/* EXPORT DELETE START */ /* CRYPT DELETE START */
-        krb5_gss_seal,
-/* EXPORT DELETE END */ /* CRYPT DELETE END */
-	krb5_gss_export_sec_context,
-	krb5_gss_import_sec_context,
-	krb5_gss_inquire_cred_by_mech,
-	krb5_gss_inquire_names_for_mech,
-	krb5_gss_inquire_context,
-	krb5_gss_internal_release_oid,
-	krb5_gss_wrap_size_limit,
-	krb5_pname_to_uid,
-	krb5_gss_userok,
-	NULL,	/* export_name */
-/* EXPORT DELETE START */
-/* CRYPT DELETE START */
-#if 0
-/* CRYPT DELETE END */
-	krb5_gss_seal,
-	krb5_gss_unseal,
-/* CRYPT DELETE START */
-#endif
-/* CRYPT DELETE END */
-/* EXPORT DELETE END */
-	krb5_gss_sign,
-	krb5_gss_verify,
-	krb5_gss_store_cred,
-	};
-
-#include <k5-int.h>
-
-
-OM_uint32
-krb5_gss_get_context(context)
-void **	context;
-{
-	/* Solaris Kerberos:  the following is a global variable declared
-         * and initialized in gssapi_krb5.c */
-	/* static krb5_context kg_context = NULL; */
-	krb5_error_code errCode = 0;
-
-	if (context == NULL)
-		return (GSS_S_FAILURE);
-	if (kg_context) {
-		*context = kg_context;
-		return (GSS_S_COMPLETE);
-	}
-
-	if ((errCode = krb5_init_context(&kg_context)))
-		goto error;	
-
-	if (((errCode = krb5_ser_context_init(kg_context)) != 0) ||
-		((errCode = krb5_ser_auth_context_init(kg_context)) != 0) ||
-		((errCode = krb5_ser_ccache_init(kg_context)) != 0) ||
-		((errCode = krb5_ser_rcache_init(kg_context)) != 0) ||
-		((errCode = krb5_ser_keytab_init(kg_context)) != 0) ||
-		((errCode = krb5_ser_context_init(kg_context)) != 0)) {
-		krb5_free_context(kg_context);
-		kg_context = 0;
-		goto error;
-	}
-
-	*context = kg_context;
-	return (GSS_S_COMPLETE);
-
-error:
-	if (errCode != 0) {
-		syslog(LOG_ERR,
-			dgettext(TEXT_DOMAIN,
-			
-				"Kerberos mechanism library"
-				" initialization error: %s."),
-		    error_message((long)errCode));
-	}
-	return (GSS_S_FAILURE);
-}
-
-/*
- * entry point for the gss layer,
- * called "krb5_gss_initialize()" in MIT 1.2.1
- */
-gss_mechanism
-gss_mech_initialize(oid)
-const gss_OID oid;
-{
-	/* ensure that the requested oid matches our oid */
-	if (oid == NULL || !g_OID_equal(oid, &krb5_mechanism.mech_type))
-		return (NULL);
-
-	if (krb5_gss_get_context(&(krb5_mechanism.context)) !=
-		GSS_S_COMPLETE)
-		return (NULL);
-
-	return (&krb5_mechanism);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/krb5_gss_glue.c	Fri Sep 14 15:01:24 2007 -0700
@@ -0,0 +1,1369 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*
+ * Copyright 1993 by OpenVision Technologies, 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 OpenVision not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. OpenVision makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ * 
+ * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OPENVISION 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.
+ */
+
+/*
+ * $Id: krb5_gss_glue.c 18268 2006-06-29 19:44:34Z tlyu $
+ */
+
+#include "gssapiP_krb5.h"
+#include "mglueP.h"
+#include <syslog.h>
+
+/** mechglue wrappers **/
+
+static OM_uint32 k5glue_acquire_cred
+(void *, 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_cred_id_t*,   /* output_cred_handle */
+            gss_OID_set*,     /* actual_mechs */
+            OM_uint32*        /* time_rec */
+           );
+
+static OM_uint32 k5glue_release_cred
+(void *, OM_uint32*,       /* minor_status */
+            gss_cred_id_t*    /* cred_handle */
+           );
+
+static OM_uint32 k5glue_init_sec_context
+(void *, 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 */
+           );
+
+static OM_uint32 k5glue_accept_sec_context
+(void *, 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 */
+           );
+
+static OM_uint32 k5glue_process_context_token
+(void *, OM_uint32*,       /* minor_status */
+            gss_ctx_id_t,     /* context_handle */
+            gss_buffer_t      /* token_buffer */
+           );
+
+static OM_uint32 k5glue_delete_sec_context
+(void *, OM_uint32*,       /* minor_status */
+            gss_ctx_id_t*,    /* context_handle */
+            gss_buffer_t      /* output_token */
+           );
+
+static OM_uint32 k5glue_context_time
+(void *, OM_uint32*,       /* minor_status */
+            gss_ctx_id_t,     /* context_handle */
+            OM_uint32*        /* time_rec */
+           );
+
+static OM_uint32 k5glue_sign
+(void *, OM_uint32*,       /* minor_status */
+            gss_ctx_id_t,     /* context_handle */
+            int,              /* qop_req */
+            gss_buffer_t,     /* message_buffer */
+            gss_buffer_t      /* message_token */
+           );
+
+static OM_uint32 k5glue_verify
+(void *, OM_uint32*,       /* minor_status */
+            gss_ctx_id_t,     /* context_handle */
+            gss_buffer_t,     /* message_buffer */
+            gss_buffer_t,     /* token_buffer */
+            int*              /* qop_state */
+           );
+
+/* EXPORT DELETE START */
+static OM_uint32 k5glue_seal
+(void *, 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 */
+           );
+
+static OM_uint32 k5glue_unseal
+(void *, 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 */
+           );
+/* EXPORT DELETE END */
+
+static OM_uint32 k5glue_display_status
+(void *, OM_uint32*,       /* minor_status */
+            OM_uint32,        /* status_value */
+            int,              /* status_type */
+            gss_OID,          /* mech_type */
+            OM_uint32*,       /* message_context */
+            gss_buffer_t      /* status_string */
+           );
+
+static OM_uint32 k5glue_indicate_mechs
+(void *, OM_uint32*,       /* minor_status */
+            gss_OID_set*      /* mech_set */
+           );
+
+static OM_uint32 k5glue_compare_name
+(void *, OM_uint32*,       /* minor_status */
+            gss_name_t,       /* name1 */
+            gss_name_t,       /* name2 */
+            int*              /* name_equal */
+           );
+
+static OM_uint32 k5glue_display_name
+(void *, OM_uint32*,      /* minor_status */
+            gss_name_t,      /* input_name */
+            gss_buffer_t,    /* output_name_buffer */
+            gss_OID*         /* output_name_type */
+           );
+
+static OM_uint32 k5glue_import_name
+(void *, OM_uint32*,       /* minor_status */
+            gss_buffer_t,     /* input_name_buffer */
+            gss_OID,          /* input_name_type */
+            gss_name_t*       /* output_name */
+           );
+
+static OM_uint32 k5glue_release_name
+(void *, OM_uint32*,       /* minor_status */
+            gss_name_t*       /* input_name */
+           );
+
+static OM_uint32 k5glue_inquire_cred
+(void *, OM_uint32 *,      /* minor_status */
+            gss_cred_id_t,    /* cred_handle */
+            gss_name_t *,     /* name */
+            OM_uint32 *,      /* lifetime */
+            gss_cred_usage_t*,/* cred_usage */
+            gss_OID_set *     /* mechanisms */
+           );
+
+static OM_uint32 k5glue_inquire_context
+(void *, OM_uint32*,       /* minor_status */
+	    gss_ctx_id_t,     /* context_handle */
+	    gss_name_t*,      /* initiator_name */
+	    gss_name_t*,      /* acceptor_name */
+	    OM_uint32*,       /* lifetime_rec */
+	    gss_OID*,         /* mech_type */
+	    OM_uint32*,       /* ret_flags */
+	    int*,             /* locally_initiated */
+	    int*              /* open */
+	   );
+
+#if 0
+/* New V2 entry points */
+static OM_uint32 k5glue_get_mic
+(void *, 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 */
+	   );
+
+static OM_uint32 k5glue_verify_mic
+(void *, OM_uint32 *,		/* minor_status */
+	    gss_ctx_id_t,		/* context_handle */
+	    gss_buffer_t,		/* message_buffer */
+	    gss_buffer_t,		/* message_token */
+	    gss_qop_t *			/* qop_state */
+	   );
+
+static OM_uint32 k5glue_wrap
+(void *, 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 */
+	   );
+
+static OM_uint32 k5glue_unwrap
+(void *, 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 */
+	   );
+#endif
+
+static OM_uint32 k5glue_wrap_size_limit
+(void *, 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 */
+	   );
+
+#if 0
+static OM_uint32 k5glue_import_name_object
+(void *, OM_uint32 *,		/* minor_status */
+	    void *,			/* input_name */
+	    gss_OID,			/* input_name_type */
+	    gss_name_t *		/* output_name */
+	   );
+
+static OM_uint32 k5glue_export_name_object
+(void *, OM_uint32 *,		/* minor_status */
+	    gss_name_t,			/* input_name */
+	    gss_OID,			/* desired_name_type */
+	    void * *			/* output_name */
+	   );
+#endif
+
+static OM_uint32 k5glue_add_cred
+(void *, 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 */
+	   );
+
+static OM_uint32 k5glue_inquire_cred_by_mech
+(void *, 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 */
+	   );
+
+static OM_uint32 k5glue_export_sec_context
+(void *, OM_uint32 *,		/* minor_status */
+	    gss_ctx_id_t *,		/* context_handle */
+	    gss_buffer_t		/* interprocess_token */
+	    );
+
+static OM_uint32 k5glue_import_sec_context
+(void *, OM_uint32 *,		/* minor_status */
+	    gss_buffer_t,		/* interprocess_token */
+	    gss_ctx_id_t *		/* context_handle */
+	    );
+
+krb5_error_code k5glue_ser_init(krb5_context);
+
+static OM_uint32 k5glue_internal_release_oid
+(void *, OM_uint32 *,		/* minor_status */
+	    gss_OID *			/* oid */
+	   );
+
+static OM_uint32 k5glue_inquire_names_for_mech
+(void *, OM_uint32 *,		/* minor_status */
+	    gss_OID,			/* mechanism */
+	    gss_OID_set *		/* name_types */
+	   );
+
+#if 0
+static OM_uint32 k5glue_canonicalize_name
+(void *, OM_uint32  *,		/* minor_status */
+	    const gss_name_t,		/* input_name */
+	    const gss_OID,		/* mech_type */
+	    gss_name_t *		/* output_name */
+	 );
+#endif
+
+static OM_uint32 k5glue_export_name
+(void *, OM_uint32  *,		/* minor_status */
+	    const gss_name_t,		/* input_name */
+	    gss_buffer_t		/* exported_name */
+	 );
+
+/* SUNW15resync - Solaris specific */
+static OM_uint32 k5glue_store_cred (
+	    void *,
+	    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 */
+	   );
+
+static OM_uint32
+k5glue_userok(
+		    void *,		/* context */
+		    OM_uint32 *,	/* minor_status */
+		    const gss_name_t,	/* pname */
+		    const char *,	/* local user */
+		    int *		/* user ok? */
+	/* */);
+
+static OM_uint32
+k5glue_pname_to_uid(
+		    void *,		/* context */
+		    OM_uint32 *,	/* minor_status */
+		    const gss_name_t,	/* pname */
+		    uid_t *		/* uid */
+	/* */);
+
+
+
+
+#if 0
+static OM_uint32 k5glue_duplicate_name
+(void *, OM_uint32  *,		/* minor_status */
+	    const gss_name_t,		/* input_name */
+	    gss_name_t *		/* dest_name */
+	 );
+#endif
+
+#if 0
+static OM_uint32 k5glue_validate_cred
+(void *, OM_uint32 *,		/* minor_status */
+	    gss_cred_id_t		/* cred */
+         );
+#endif
+
+#if 0
+/*
+ * SUNW15resync
+ * Solaris can't use the KRB5_GSS_CONFIG_INIT macro because of the src
+ * slicing&dicing needs of the "nightly -SD" build.  When it goes away,
+ * we should use it assuming MIT still uses it then.
+ */
+
+/*
+ * The krb5 mechanism provides two mech OIDs; use this initializer to
+ * ensure that both dispatch tables contain identical function
+ * pointers.
+ */
+#define KRB5_GSS_CONFIG_INIT				\
+    NULL,						\
+    ...
+#endif
+
+
+static struct gss_config krb5_mechanism = {
+#if 0 /* Solaris Kerberos */
+    100, "kerberos_v5",
+#endif
+    { GSS_MECH_KRB5_OID_LENGTH, GSS_MECH_KRB5_OID },
+    NULL,
+    k5glue_acquire_cred,
+    k5glue_release_cred,
+    k5glue_init_sec_context,
+    k5glue_accept_sec_context,
+/* EXPORT DELETE START */ /* CRYPT DELETE START */
+    k5glue_unseal,
+/* EXPORT DELETE END */ /* CRYPT DELETE END */
+    k5glue_process_context_token,
+    k5glue_delete_sec_context,
+    k5glue_context_time,
+    k5glue_display_status,
+    k5glue_indicate_mechs,
+    k5glue_compare_name,
+    k5glue_display_name,
+    k5glue_import_name,
+    k5glue_release_name,
+    k5glue_inquire_cred,
+    k5glue_add_cred,
+/* EXPORT DELETE START */ /* CRYPT DELETE START */
+    k5glue_seal,
+/* EXPORT DELETE END */ /* CRYPT DELETE END */
+    k5glue_export_sec_context,
+    k5glue_import_sec_context,
+    k5glue_inquire_cred_by_mech,
+    k5glue_inquire_names_for_mech,
+    k5glue_inquire_context,
+    k5glue_internal_release_oid,
+    k5glue_wrap_size_limit,
+    k5glue_pname_to_uid,
+    k5glue_userok,
+    k5glue_export_name,
+/* EXPORT DELETE START */
+/* CRYPT DELETE START */
+#if 0
+/* CRYPT DELETE END */
+    k5glue_seal,
+    k5glue_unseal,
+/* CRYPT DELETE START */
+#endif
+/* CRYPT DELETE END */
+/* EXPORT DELETE END */
+    k5glue_sign,
+    k5glue_verify,
+    k5glue_store_cred
+};
+
+static struct gss_config krb5_mechanism_old = {
+#if 0 /* Solaris Kerberos */
+    200, "kerberos_v5 (pre-RFC OID)",
+#endif
+    { GSS_MECH_KRB5_OLD_OID_LENGTH, GSS_MECH_KRB5_OLD_OID },
+    NULL,
+    k5glue_acquire_cred,
+    k5glue_release_cred,
+    k5glue_init_sec_context,
+    k5glue_accept_sec_context,
+/* EXPORT DELETE START */ /* CRYPT DELETE START */
+    k5glue_unseal,
+/* EXPORT DELETE END */ /* CRYPT DELETE END */
+    k5glue_process_context_token,
+    k5glue_delete_sec_context,
+    k5glue_context_time,
+    k5glue_display_status,
+    k5glue_indicate_mechs,
+    k5glue_compare_name,
+    k5glue_display_name,
+    k5glue_import_name,
+    k5glue_release_name,
+    k5glue_inquire_cred,
+    k5glue_add_cred,
+/* EXPORT DELETE START */ /* CRYPT DELETE START */
+    k5glue_seal,
+/* EXPORT DELETE END */ /* CRYPT DELETE END */
+    k5glue_export_sec_context,
+    k5glue_import_sec_context,
+    k5glue_inquire_cred_by_mech,
+    k5glue_inquire_names_for_mech,
+    k5glue_inquire_context,
+    k5glue_internal_release_oid,
+    k5glue_wrap_size_limit,
+    k5glue_pname_to_uid,
+    k5glue_userok,
+    k5glue_export_name,
+/* EXPORT DELETE START */
+/* CRYPT DELETE START */
+#if 0
+/* CRYPT DELETE END */
+    k5glue_seal,
+    k5glue_unseal,
+/* CRYPT DELETE START */
+#endif
+/* CRYPT DELETE END */
+/* EXPORT DELETE END */
+    k5glue_sign,
+    k5glue_verify,
+    k5glue_store_cred
+};
+
+static struct gss_config krb5_mechanism_wrong = {
+#if 0 /* Solaris Kerberos */
+    300, "kerberos_v5 (wrong OID)",
+#endif
+    { GSS_MECH_KRB5_WRONG_OID_LENGTH, GSS_MECH_KRB5_WRONG_OID },
+    NULL,
+    k5glue_acquire_cred,
+    k5glue_release_cred,
+    k5glue_init_sec_context,
+    k5glue_accept_sec_context,
+/* EXPORT DELETE START */ /* CRYPT DELETE START */
+    k5glue_unseal,
+/* EXPORT DELETE END */ /* CRYPT DELETE END */
+    k5glue_process_context_token,
+    k5glue_delete_sec_context,
+    k5glue_context_time,
+    k5glue_display_status,
+    k5glue_indicate_mechs,
+    k5glue_compare_name,
+    k5glue_display_name,
+    k5glue_import_name,
+    k5glue_release_name,
+    k5glue_inquire_cred,
+    k5glue_add_cred,
+/* EXPORT DELETE START */ /* CRYPT DELETE START */
+    k5glue_seal,
+/* EXPORT DELETE END */ /* CRYPT DELETE END */
+    k5glue_export_sec_context,
+    k5glue_import_sec_context,
+    k5glue_inquire_cred_by_mech,
+    k5glue_inquire_names_for_mech,
+    k5glue_inquire_context,
+    k5glue_internal_release_oid,
+    k5glue_wrap_size_limit,
+    k5glue_pname_to_uid,
+    k5glue_userok,
+    k5glue_export_name,
+/* EXPORT DELETE START */
+/* CRYPT DELETE START */
+#if 0
+/* CRYPT DELETE END */
+    k5glue_seal,
+    k5glue_unseal,
+/* CRYPT DELETE START */
+#endif
+/* CRYPT DELETE END */
+/* EXPORT DELETE END */
+    k5glue_sign,
+    k5glue_verify,
+    k5glue_store_cred
+};
+
+static gss_mechanism krb5_mech_configs[] = {
+    &krb5_mechanism, &krb5_mechanism_old, &krb5_mechanism_wrong, NULL
+};
+
+#ifdef MS_BUG_TEST
+static gss_mechanism krb5_mech_configs_hack[] = {
+    &krb5_mechanism, &krb5_mechanism_old, NULL
+};
+#endif
+
+#if 1
+#define gssint_get_mech_configs krb5_gss_get_mech_configs
+#endif
+
+gss_mechanism *
+gssint_get_mech_configs(void)
+{
+#ifdef MS_BUG_TEST
+    char *envstr = getenv("MS_FORCE_NO_MSOID");
+
+    if (envstr != NULL && strcmp(envstr, "1") == 0) {
+	return krb5_mech_configs_hack;
+    }
+#endif
+    return krb5_mech_configs;
+}
+
+static OM_uint32
+k5glue_accept_sec_context(ctx, minor_status, context_handle, verifier_cred_handle,
+		       input_token, input_chan_bindings, src_name, mech_type, 
+		       output_token, ret_flags, time_rec, delegated_cred_handle)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_ctx_id_t *context_handle;
+     gss_cred_id_t verifier_cred_handle;
+     gss_buffer_t input_token;
+     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;
+{
+   return(krb5_gss_accept_sec_context(minor_status,
+				      context_handle,
+				      verifier_cred_handle,
+				      input_token,
+				      input_chan_bindings,
+				      src_name,
+				      mech_type,
+				      output_token,
+				      ret_flags,
+				      time_rec,
+				      delegated_cred_handle));
+}
+
+static OM_uint32
+k5glue_acquire_cred(ctx, minor_status, desired_name, time_req, desired_mechs,
+		 cred_usage, output_cred_handle, actual_mechs, time_rec)
+    void *ctx;
+     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_cred_id_t *output_cred_handle;
+     gss_OID_set *actual_mechs;
+     OM_uint32 *time_rec;
+{
+   return(krb5_gss_acquire_cred(minor_status,
+				desired_name,
+				time_req,
+				desired_mechs,
+				cred_usage,
+				output_cred_handle,
+				actual_mechs,
+				time_rec));
+}
+
+/* V2 */
+static OM_uint32
+k5glue_add_cred(ctx, 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)
+    void *ctx;
+    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(krb5_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));
+}
+
+#if 0
+/* V2 */
+static OM_uint32
+k5glue_add_oid_set_member(ctx, minor_status, member_oid, oid_set)
+    void *ctx;
+    OM_uint32	 *minor_status;
+    gss_OID	member_oid;
+    gss_OID_set	 *oid_set;
+{
+    return(generic_gss_add_oid_set_member(minor_status, member_oid, oid_set));
+}
+#endif
+
+static OM_uint32
+k5glue_compare_name(ctx, minor_status, name1, name2, name_equal)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_name_t name1;
+     gss_name_t name2;
+     int *name_equal;
+{
+   return(krb5_gss_compare_name(minor_status, name1,
+				name2, name_equal));
+}
+
+static OM_uint32
+k5glue_context_time(ctx, minor_status, context_handle, time_rec)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_ctx_id_t context_handle;
+     OM_uint32 *time_rec;
+{
+   return(krb5_gss_context_time(minor_status, context_handle,
+				time_rec));
+}
+
+#if 0
+/* V2 */
+static OM_uint32
+k5glue_create_empty_oid_set(ctx, minor_status, oid_set)
+    void *ctx;
+    OM_uint32	 *minor_status;
+    gss_OID_set	 *oid_set;
+{
+    return(generic_gss_create_empty_oid_set(minor_status, oid_set));
+}
+#endif
+
+static OM_uint32
+k5glue_delete_sec_context(ctx, minor_status, context_handle, output_token)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_ctx_id_t *context_handle;
+     gss_buffer_t output_token;
+{
+   return(krb5_gss_delete_sec_context(minor_status,
+				      context_handle, output_token));
+}
+
+static OM_uint32
+k5glue_display_name(ctx, minor_status, input_name, output_name_buffer, output_name_type)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_name_t input_name;
+     gss_buffer_t output_name_buffer;
+     gss_OID *output_name_type;
+{
+   return(krb5_gss_display_name(minor_status, input_name,
+				output_name_buffer, output_name_type));
+}
+
+static OM_uint32
+k5glue_display_status(ctx, minor_status, status_value, status_type,
+		   mech_type, message_context, status_string)
+    void *ctx;
+     OM_uint32 *minor_status;
+     OM_uint32 status_value;
+     int status_type;
+     gss_OID mech_type;
+     OM_uint32 *message_context;
+     gss_buffer_t status_string;
+{
+   return(krb5_gss_display_status(minor_status, status_value,
+				  status_type, mech_type, message_context,
+				  status_string));
+}
+
+/* V2 */
+static OM_uint32
+k5glue_export_sec_context(ctx, minor_status, context_handle, interprocess_token)
+    void *ctx;
+     OM_uint32		 *minor_status;
+     gss_ctx_id_t	 *context_handle;
+     gss_buffer_t	interprocess_token;
+{
+   return(krb5_gss_export_sec_context(minor_status,
+				      context_handle,
+				      interprocess_token));
+}
+
+#if 0
+/* V2 */
+static OM_uint32
+k5glue_get_mic(ctx, minor_status, context_handle, qop_req,
+	    message_buffer, message_token)
+    void *ctx;
+     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;
+{
+    return(krb5_gss_get_mic(minor_status, context_handle,
+			    qop_req, message_buffer, message_token));
+}
+#endif
+
+static OM_uint32
+k5glue_import_name(ctx, minor_status, input_name_buffer, input_name_type, output_name)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_buffer_t input_name_buffer;
+     gss_OID input_name_type;
+     gss_name_t *output_name;
+{
+#if 0
+    OM_uint32 err;
+    err = gssint_initialize_library();
+    if (err) {
+	*minor_status = err;
+	return GSS_S_FAILURE;
+    }
+#endif
+    return(krb5_gss_import_name(minor_status, input_name_buffer,
+				input_name_type, output_name));
+}
+
+/* V2 */
+static OM_uint32
+k5glue_import_sec_context(ctx, minor_status, interprocess_token, context_handle)
+    void *ctx;
+     OM_uint32		 *minor_status;
+     gss_buffer_t	interprocess_token;
+     gss_ctx_id_t	 *context_handle;
+{
+   return(krb5_gss_import_sec_context(minor_status,
+				      interprocess_token,
+				      context_handle));
+}
+
+static OM_uint32
+k5glue_indicate_mechs(ctx, minor_status, mech_set)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_OID_set *mech_set;
+{
+   return(krb5_gss_indicate_mechs(minor_status, mech_set));
+}
+
+static OM_uint32
+k5glue_init_sec_context(ctx, minor_status, claimant_cred_handle, context_handle,
+		     target_name, mech_type, req_flags, time_req,
+		     input_chan_bindings, input_token, actual_mech_type,
+		     output_token, ret_flags, time_rec)
+    void *ctx;
+     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;
+{
+   return(krb5_gss_init_sec_context(minor_status,
+				    claimant_cred_handle, context_handle,
+				    target_name, mech_type, req_flags,
+				    time_req, input_chan_bindings, input_token,
+				    actual_mech_type, output_token, ret_flags,
+				    time_rec));
+}
+
+static OM_uint32
+k5glue_inquire_context(ctx, minor_status, context_handle, initiator_name, acceptor_name,
+		    lifetime_rec, mech_type, ret_flags,
+		    locally_initiated, open)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_ctx_id_t context_handle;
+     gss_name_t *initiator_name;
+     gss_name_t *acceptor_name;
+     OM_uint32 *lifetime_rec;
+     gss_OID *mech_type;
+     OM_uint32 *ret_flags;
+     int *locally_initiated;
+     int *open;
+{
+   return(krb5_gss_inquire_context(minor_status, context_handle,
+				   initiator_name, acceptor_name, lifetime_rec,
+				   mech_type, ret_flags, locally_initiated,
+				   open));
+}
+
+static OM_uint32
+k5glue_inquire_cred(ctx, minor_status, cred_handle, name, lifetime_ret,
+		 cred_usage, mechanisms)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_cred_id_t cred_handle;
+     gss_name_t *name;
+     OM_uint32 *lifetime_ret;
+     gss_cred_usage_t *cred_usage;
+     gss_OID_set *mechanisms;
+{
+   return(krb5_gss_inquire_cred(minor_status, cred_handle,
+				name, lifetime_ret, cred_usage, mechanisms));
+}
+
+/* V2 */
+static OM_uint32
+k5glue_inquire_cred_by_mech(ctx, minor_status, cred_handle, mech_type, name,
+			 initiator_lifetime, acceptor_lifetime, cred_usage)
+    void *ctx;
+     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;
+{
+   return(krb5_gss_inquire_cred_by_mech(minor_status, cred_handle,
+					mech_type, name, initiator_lifetime,
+					acceptor_lifetime, cred_usage));
+}
+
+/* V2 */
+static OM_uint32
+k5glue_inquire_names_for_mech(ctx, minor_status, mechanism, name_types)
+    void *ctx;
+    OM_uint32	 *minor_status;
+    gss_OID	mechanism;
+    gss_OID_set	 *name_types;
+{
+    return(krb5_gss_inquire_names_for_mech(minor_status,
+					   mechanism,
+					   name_types));
+}
+
+#if 0
+/* V2 */
+static OM_uint32
+k5glue_oid_to_str(ctx, minor_status, oid, oid_str)
+    void *ctx;
+    OM_uint32		 *minor_status;
+    gss_OID		oid;
+    gss_buffer_t	oid_str;
+{
+    return(generic_gss_oid_to_str(minor_status, oid, oid_str));
+}
+#endif
+
+static OM_uint32
+k5glue_process_context_token(ctx, minor_status, context_handle, token_buffer)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_ctx_id_t context_handle;
+     gss_buffer_t token_buffer;
+{
+   return(krb5_gss_process_context_token(minor_status,
+					 context_handle, token_buffer));
+}
+
+static OM_uint32
+k5glue_release_cred(ctx, minor_status, cred_handle)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_cred_id_t *cred_handle;
+{
+   return(krb5_gss_release_cred(minor_status, cred_handle));
+}
+
+static OM_uint32
+k5glue_release_name(ctx, minor_status, input_name)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_name_t *input_name;
+{
+   return(krb5_gss_release_name(minor_status, input_name));
+}
+
+#if 0
+static OM_uint32
+k5glue_release_buffer(ctx, minor_status, buffer)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_buffer_t buffer;
+{
+   return(generic_gss_release_buffer(minor_status,
+				     buffer));
+}
+#endif
+
+/* V2 */
+static OM_uint32
+k5glue_internal_release_oid(ctx, minor_status, oid)
+    void *ctx;
+     OM_uint32	 *minor_status;
+     gss_OID	 *oid;
+{
+    return(krb5_gss_internal_release_oid(minor_status, oid));
+}
+
+#if 0
+static OM_uint32
+k5glue_release_oid_set(ctx, minor_status, set)
+    void *ctx;
+     OM_uint32 * minor_status;
+     gss_OID_set *set;
+{
+   return(generic_gss_release_oid_set(minor_status, set));
+}
+#endif
+
+/* EXPORT DELETE START */
+/* V1 only */
+static OM_uint32
+k5glue_seal(ctx, minor_status, context_handle, conf_req_flag, qop_req,
+	 input_message_buffer, conf_state, output_message_buffer)
+    void *ctx;
+     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(krb5_gss_seal(minor_status, context_handle,
+			conf_req_flag, qop_req, input_message_buffer,
+			conf_state, output_message_buffer));
+}
+/* EXPORT DELETE END */
+
+static OM_uint32
+k5glue_sign(ctx, minor_status, context_handle,
+	      qop_req, message_buffer, 
+	      message_token)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_ctx_id_t context_handle;
+     int qop_req;
+     gss_buffer_t message_buffer;
+     gss_buffer_t message_token;
+{
+   return(krb5_gss_sign(minor_status, context_handle,
+			qop_req, message_buffer, message_token));
+}
+
+#if 0
+/* V2 */
+static OM_uint32
+k5glue_verify_mic(ctx, minor_status, context_handle,
+	       message_buffer, token_buffer, qop_state)
+    void *ctx;
+     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;
+{
+    return(krb5_gss_verify_mic(minor_status, context_handle,
+			       message_buffer, token_buffer, qop_state));
+}
+
+/* V2 */
+static OM_uint32
+k5glue_wrap(ctx, minor_status, context_handle, conf_req_flag, qop_req,
+	 input_message_buffer, conf_state, output_message_buffer)
+    void *ctx;
+    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;
+{
+    return(krb5_gss_wrap(minor_status, context_handle, conf_req_flag, qop_req,
+			 input_message_buffer, conf_state,
+			 output_message_buffer));
+}
+
+/* V2 */
+static OM_uint32
+k5glue_str_to_oid(ctx, minor_status, oid_str, oid)
+    void *ctx;
+    OM_uint32		 *minor_status;
+    gss_buffer_t	oid_str;
+    gss_OID		 *oid;
+{
+    return(generic_gss_str_to_oid(minor_status, oid_str, oid));
+}
+
+/* V2 */
+static OM_uint32
+k5glue_test_oid_set_member(ctx, minor_status, member, set, present)
+    void *ctx;
+    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));
+}
+#endif
+
+/* EXPORT DELETE START */
+/* V1 only */
+static OM_uint32
+k5glue_unseal(ctx, minor_status, context_handle, input_message_buffer,
+	   output_message_buffer, conf_state, qop_state)
+    void *ctx;
+     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(krb5_gss_unseal(minor_status, context_handle,
+			  input_message_buffer, output_message_buffer,
+			  conf_state, qop_state));
+}
+/* EXPORT DELETE END */
+
+#if 0
+/* V2 */
+static OM_uint32
+k5glue_unwrap(ctx, minor_status, context_handle, input_message_buffer, 
+	   output_message_buffer, conf_state, qop_state)
+    void *ctx;
+    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;
+{
+    return(krb5_gss_unwrap(minor_status, context_handle, input_message_buffer,
+			   output_message_buffer, conf_state, qop_state));
+}
+#endif
+
+/* V1 only */
+static OM_uint32
+k5glue_verify(ctx, minor_status, context_handle, message_buffer,
+	   token_buffer, qop_state)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_ctx_id_t context_handle;
+     gss_buffer_t message_buffer;
+     gss_buffer_t token_buffer;
+     int *qop_state;
+{
+   return(krb5_gss_verify(minor_status,
+			  context_handle,
+			  message_buffer,
+			  token_buffer,
+			  qop_state));
+}
+
+/* V2 interface */
+static OM_uint32
+k5glue_wrap_size_limit(ctx, minor_status, context_handle, conf_req_flag,
+		    qop_req, req_output_size, max_input_size)
+    void *ctx;
+    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;
+{
+   return(krb5_gss_wrap_size_limit(minor_status, context_handle,
+				   conf_req_flag, qop_req,
+				   req_output_size, max_input_size));
+}
+
+#if 0
+/* V2 interface */
+static OM_uint32
+k5glue_canonicalize_name(ctx, minor_status, input_name, mech_type, output_name)
+    void *ctx;
+	OM_uint32  *minor_status;
+	const gss_name_t input_name;
+	const gss_OID mech_type;
+	gss_name_t *output_name;
+{
+	return krb5_gss_canonicalize_name(minor_status, input_name,
+					  mech_type, output_name);
+}
+#endif
+
+/* V2 interface */
+static OM_uint32
+k5glue_export_name(ctx, minor_status, input_name, exported_name)
+    void *ctx;
+	OM_uint32  *minor_status;
+	const gss_name_t input_name;
+	gss_buffer_t exported_name;
+{
+	return krb5_gss_export_name(minor_status, input_name, exported_name);
+}
+
+/* SUNW15resync - this is not in the MIT mech (lib) yet */
+static OM_uint32
+k5glue_store_cred(ctx, minor_status, input_cred, cred_usage, desired_mech,
+			overwrite_cred, default_cred, elements_stored,
+			cred_usage_stored)
+void *ctx;
+OM_uint32 *minor_status;
+const gss_cred_id_t input_cred;
+gss_cred_usage_t cred_usage;
+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(krb5_gss_store_cred(minor_status, input_cred,
+			    cred_usage, desired_mech,
+			    overwrite_cred, default_cred, elements_stored,
+			    cred_usage_stored));
+}
+
+static OM_uint32
+k5glue_userok(
+		    void *ctxt,		/* context */
+		    OM_uint32 *minor,	/* minor_status */
+		    const gss_name_t pname,	/* pname */
+		    const char *user,	/* local user */
+		    int *user_ok		/* user ok? */
+	/* */)
+{
+  return(krb5_gss_userok(minor, pname, user, user_ok));
+}
+
+static OM_uint32
+k5glue_pname_to_uid(
+		    void *ctxt,		/* context */
+		    OM_uint32 *minor,	/* minor_status */
+		    const gss_name_t pname,	/* pname */
+		    uid_t *uidOut		/* uid */
+	/* */)
+{
+  return (krb5_pname_to_uid(minor, pname, uidOut));
+}
+
+
+
+#if 0
+/* V2 interface */
+static OM_uint32
+k5glue_duplicate_name(ctx, minor_status, input_name, dest_name)
+    void *ctx;
+	OM_uint32  *minor_status;
+	const gss_name_t input_name;
+	gss_name_t *dest_name;
+{
+	return krb5_gss_duplicate_name(minor_status, input_name, dest_name);
+}
+#endif
+
+OM_uint32 KRB5_CALLCONV
+gss_krb5_get_tkt_flags(
+    OM_uint32 *minor_status,
+    gss_ctx_id_t context_handle,
+    krb5_flags *ticket_flags)
+{
+    gss_union_ctx_id_t uctx;
+
+    uctx = (gss_union_ctx_id_t)context_handle;
+    if (!g_OID_equal(uctx->mech_type, &krb5_mechanism.mech_type) &&
+	!g_OID_equal(uctx->mech_type, &krb5_mechanism_old.mech_type))
+	return GSS_S_BAD_MECH;
+    return gss_krb5int_get_tkt_flags(minor_status, uctx->internal_ctx_id,
+				     ticket_flags);
+}
+
+OM_uint32 KRB5_CALLCONV 
+gss_krb5_copy_ccache(
+    OM_uint32 *minor_status,
+    gss_cred_id_t cred_handle,
+    krb5_ccache out_ccache)
+{
+    gss_union_cred_t ucred;
+    gss_cred_id_t mcred;
+
+    ucred = (gss_union_cred_t)cred_handle;
+
+    mcred = gssint_get_mechanism_cred(ucred, &krb5_mechanism.mech_type);
+    if (mcred != GSS_C_NO_CREDENTIAL)
+	return gss_krb5int_copy_ccache(minor_status, mcred, out_ccache);
+
+    mcred = gssint_get_mechanism_cred(ucred, &krb5_mechanism_old.mech_type);
+    if (mcred != GSS_C_NO_CREDENTIAL)
+	return gss_krb5int_copy_ccache(minor_status, mcred, out_ccache);
+
+    return GSS_S_DEFECTIVE_CREDENTIAL;
+}
+
+/* XXX need to delete mechglue ctx too */
+OM_uint32 KRB5_CALLCONV
+gss_krb5_export_lucid_sec_context(
+    OM_uint32 *minor_status,
+    gss_ctx_id_t *context_handle,
+    OM_uint32 version,
+    void **kctx)
+{
+    gss_union_ctx_id_t uctx;
+
+    uctx = (gss_union_ctx_id_t)*context_handle;
+    if (!g_OID_equal(uctx->mech_type, &krb5_mechanism.mech_type) &&
+	!g_OID_equal(uctx->mech_type, &krb5_mechanism_old.mech_type))
+	return GSS_S_BAD_MECH;
+    return gss_krb5int_export_lucid_sec_context(minor_status,
+						&uctx->internal_ctx_id,
+						version, kctx);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_krb5_set_allowable_enctypes(
+    OM_uint32 *minor_status, 
+    gss_cred_id_t cred,
+    OM_uint32 num_ktypes,
+    krb5_enctype *ktypes)
+{
+    gss_union_cred_t ucred;
+    gss_cred_id_t mcred;
+
+    ucred = (gss_union_cred_t)cred;
+    mcred = gssint_get_mechanism_cred(ucred, &krb5_mechanism.mech_type);
+    if (mcred != GSS_C_NO_CREDENTIAL)
+	return gss_krb5int_set_allowable_enctypes(minor_status, mcred,
+						  num_ktypes, ktypes);
+
+    mcred = gssint_get_mechanism_cred(ucred, &krb5_mechanism_old.mech_type);
+    if (mcred != GSS_C_NO_CREDENTIAL)
+	return gss_krb5int_set_allowable_enctypes(minor_status, mcred,
+						  num_ktypes, ktypes);
+
+    return GSS_S_DEFECTIVE_CREDENTIAL;
+}
+
+/*
+ * Glue routine for returning the mechanism-specific credential from a
+ * external union credential.
+ */
+/* SUNW15resync - in MIT 1.5, it's in g_glue.c (libgss) but we don't
+  want to link against libgss so we put it here since we need it in the mech */
+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_union_cred_t) 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;
+}
+
+
+
+/*
+ * entry point for the gss layer,
+ * called "krb5_gss_initialize()" in MIT 1.2.1
+ */
+/* SUNW15resync - this used to be in k5mech.c */
+gss_mechanism
+gss_mech_initialize(oid)
+     const gss_OID oid;
+{
+    /* ensure that the requested oid matches our oid */
+    if (oid == NULL || !g_OID_equal(oid, &krb5_mechanism.mech_type)) {
+      (void) syslog(LOG_INFO, "krb5mech: gss_mech_initialize: bad oid");
+      return (NULL);
+    }
+
+#if 0 /* SUNW15resync - no longer needed(?) */
+    if (krb5_gss_get_context(&(krb5_mechanism.context)) !=
+	GSS_S_COMPLETE)
+      return (NULL);
+#endif
+
+    return (&krb5_mechanism);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/lucid_context.c	Fri Sep 14 15:01:24 2007 -0700
@@ -0,0 +1,311 @@
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*
+ * lib/gssapi/krb5/lucid_context.c
+ *
+ * Copyright 2004 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.
+ *
+ */
+
+/*
+ * lucid_context.c  -  Externalize a "lucid" security
+ * context from a krb5_gss_ctx_id_rec structure.
+ */
+#include "gssapiP_krb5.h"
+#include "gssapi_krb5.h"
+
+/*
+ * Local routine prototypes
+ */
+static void
+free_external_lucid_ctx_v1(
+    gss_krb5_lucid_context_v1_t *ctx);
+
+static void
+free_lucid_key_data(
+    gss_krb5_lucid_key_t *key);
+
+static krb5_error_code
+copy_keyblock_to_lucid_key(
+    krb5_keyblock *k5key,
+    gss_krb5_lucid_key_t *lkey);
+
+static krb5_error_code
+make_external_lucid_ctx_v1(
+    krb5_gss_ctx_id_rec * gctx,
+    unsigned int version,
+    void **out_ptr);
+
+
+/*
+ * Exported routines
+ */
+
+OM_uint32 KRB5_CALLCONV
+gss_krb5int_export_lucid_sec_context(
+    OM_uint32		*minor_status,
+    gss_ctx_id_t	*context_handle,
+    OM_uint32		version,
+    void		**kctx)
+{
+    krb5_error_code	kret = 0;
+    OM_uint32		retval;
+    krb5_gss_ctx_id_t	ctx;
+    void		*lctx = NULL;
+
+    /* Assume failure */
+    retval = GSS_S_FAILURE;
+    *minor_status = 0;
+
+    if (kctx)
+	*kctx = NULL;
+    else {
+	kret = EINVAL;
+    	goto error_out;
+    }
+
+    if (!kg_validate_ctx_id(*context_handle)) {
+	    kret = (OM_uint32) G_VALIDATE_FAILED;
+	    retval = GSS_S_NO_CONTEXT;
+	    goto error_out;
+    }
+
+    ctx = (krb5_gss_ctx_id_t) *context_handle;
+    if (kret)
+	goto error_out;
+
+    /* Externalize a structure of the right version */
+    switch (version) {
+    case 1:
+	kret = make_external_lucid_ctx_v1((krb5_pointer)ctx,
+					      version, &lctx);
+        break;
+    default:
+	kret = (OM_uint32) KG_LUCID_VERSION;
+	break;
+    }
+
+    if (kret)
+	goto error_out;
+
+    /* Success!  Record the context and return the buffer */
+    if (! kg_save_lucidctx_id((void *)lctx)) {
+	kret = G_VALIDATE_FAILED;
+	goto error_out;
+    }
+
+    *kctx = lctx;
+    *minor_status = 0;
+    retval = GSS_S_COMPLETE;
+
+    /* Clean up the context state (it is an error for
+     * someone to attempt to use this context again)
+     */
+    (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
+    *context_handle = GSS_C_NO_CONTEXT;
+
+    return (retval);
+
+error_out:
+    if (*minor_status == 0) 
+	    *minor_status = (OM_uint32) kret;
+    return(retval);
+}
+
+/*
+ * Frees the storage associated with an
+ * exported lucid context structure.
+ */
+OM_uint32 KRB5_CALLCONV
+gss_krb5_free_lucid_sec_context(
+    OM_uint32 *minor_status,
+    void *kctx)
+{
+    OM_uint32		retval;
+    krb5_error_code	kret = 0;
+    int			version;
+
+    /* Assume failure */
+    retval = GSS_S_FAILURE;
+    *minor_status = 0;
+
+    if (!kctx) {
+	kret = EINVAL;
+	goto error_out;
+    }
+
+    /* Verify pointer is valid lucid context */
+    if (! kg_validate_lucidctx_id(kctx)) {
+	kret = G_VALIDATE_FAILED;
+	goto error_out;
+    }
+
+    /* Determine version and call correct free routine */
+    version = ((gss_krb5_lucid_context_version_t *)kctx)->version;
+    switch (version) {
+    case 1:
+	free_external_lucid_ctx_v1((gss_krb5_lucid_context_v1_t*) kctx);
+	break;
+    default:
+	kret = EINVAL;
+	break;
+    }
+
+    if (kret)
+	goto error_out;
+
+    /* Success! */
+    (void)kg_delete_lucidctx_id(kctx);
+    *minor_status = 0;
+    retval = GSS_S_COMPLETE;
+
+    return (retval);
+
+error_out:
+    if (*minor_status == 0) 
+	    *minor_status = (OM_uint32) kret;
+    return(retval);
+}
+
+/*
+ * Local routines
+ */
+
+static krb5_error_code
+make_external_lucid_ctx_v1(
+    krb5_gss_ctx_id_rec * gctx,
+    unsigned int version,
+    void **out_ptr)
+{
+    gss_krb5_lucid_context_v1_t *lctx = NULL;
+    unsigned int bufsize = sizeof(gss_krb5_lucid_context_v1_t);
+    krb5_error_code retval;
+
+    /* Allocate the structure */
+    if ((lctx = xmalloc(bufsize)) == NULL) {
+    	retval = ENOMEM;
+	goto error_out;
+    }
+
+    memset(lctx, 0, bufsize);
+
+    lctx->version = 1;
+    lctx->initiate = gctx->initiate ? 1 : 0;
+    lctx->endtime = gctx->endtime;
+    lctx->send_seq = gctx->seq_send;
+    lctx->recv_seq = gctx->seq_recv;
+    lctx->protocol = gctx->proto;
+    /* gctx->proto == 0 ==> rfc1964-style key information
+       gctx->proto == 1 ==> cfx-style (draft-ietf-krb-wg-gssapi-cfx-07) keys */
+    if (gctx->proto == 0) {
+	lctx->rfc1964_kd.sign_alg = gctx->signalg;
+	lctx->rfc1964_kd.seal_alg = gctx->sealalg;
+	/* Copy key */
+	if ((retval = copy_keyblock_to_lucid_key(gctx->subkey,
+	    				&lctx->rfc1964_kd.ctx_key)))
+	    goto error_out;
+    }
+    else if (gctx->proto == 1) {
+	/* Copy keys */
+	/* (subkey is always present, either a copy of the kerberos
+	   session key or a subkey) */
+	if ((retval = copy_keyblock_to_lucid_key(gctx->subkey,
+	    				&lctx->cfx_kd.ctx_key)))
+	    goto error_out;
+	if (gctx->have_acceptor_subkey) {
+	    if ((retval = copy_keyblock_to_lucid_key(gctx->enc,
+	    				&lctx->cfx_kd.acceptor_subkey)))
+		goto error_out;
+	    lctx->cfx_kd.have_acceptor_subkey = 1;
+	}
+    }
+    else {
+	return EINVAL;	/* XXX better error code? */
+    }
+
+    /* Success! */
+    *out_ptr = lctx;
+    return 0;
+
+error_out:
+    if (lctx) {
+	free_external_lucid_ctx_v1(lctx);
+    }
+    return retval;
+
+}
+
+/* Copy the contents of a krb5_keyblock to a gss_krb5_lucid_key_t structure */
+static krb5_error_code
+copy_keyblock_to_lucid_key(
+    krb5_keyblock *k5key,
+    gss_krb5_lucid_key_t *lkey)
+{
+    if (!k5key || !k5key->contents || k5key->length == 0)
+	return EINVAL;
+
+    memset(lkey, 0, sizeof(gss_krb5_lucid_key_t));
+
+    /* Allocate storage for the key data */
+    if ((lkey->data = xmalloc(k5key->length)) == NULL) {
+	return ENOMEM;
+    }
+    memcpy(lkey->data, k5key->contents, k5key->length);
+    lkey->length = k5key->length;
+    lkey->type = k5key->enctype;
+
+    return 0;
+}
+
+
+/* Free any storage associated with a gss_krb5_lucid_key_t structure */
+static void
+free_lucid_key_data(
+    gss_krb5_lucid_key_t *key)
+{
+    if (key) {
+	if (key->data && key->length) {
+	    memset(key->data, 0, key->length);
+	    xfree(key->data);
+	    memset(key, 0, sizeof(gss_krb5_lucid_key_t));
+	}
+    }
+}
+/* Free any storage associated with a gss_krb5_lucid_context_v1 structure */
+static void
+free_external_lucid_ctx_v1(
+    gss_krb5_lucid_context_v1_t *ctx)
+{
+    if (ctx) {
+	if (ctx->protocol == 0) {
+	    free_lucid_key_data(&ctx->rfc1964_kd.ctx_key);
+	}
+	if (ctx->protocol == 1) {
+	    free_lucid_key_data(&ctx->cfx_kd.ctx_key);
+	    if (ctx->cfx_kd.have_acceptor_subkey)
+		free_lucid_key_data(&ctx->cfx_kd.acceptor_subkey);
+	}
+	xfree(ctx);
+	ctx = NULL;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/oid_ops.c	Fri Sep 14 15:01:24 2007 -0700
@@ -0,0 +1,504 @@
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*
+ * lib/gssapi/generic/oid_ops.c
+ *
+ * Copyright 1995 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.
+ *
+ */
+
+/*
+ * oid_ops.c - GSS-API V2 interfaces to manipulate OIDs
+ */
+
+#include "mglueP.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <gssapi_generic.h>
+#include <errno.h>
+#include <ctype.h>
+
+OM_uint32
+generic_gss_release_oid(minor_status, oid)
+    OM_uint32	*minor_status;
+    gss_OID	*oid;
+{
+    if (minor_status)
+	*minor_status = 0;
+
+    if (*oid == GSS_C_NO_OID)
+	return(GSS_S_COMPLETE);
+
+    /*
+     * The V2 API says the following!
+     *
+     * gss_release_oid[()] will recognize any of the GSSAPI's own OID values,
+     * and will silently ignore attempts to free these OIDs; for other OIDs
+     * it will call the C free() routine for both the OID data and the
+     * descriptor.  This allows applications to freely mix their own heap-
+     * allocated OID values with OIDs returned by GSS-API.
+     */
+
+    /*
+     * We use the official OID definitions instead of the unofficial OID
+     * defintions. But we continue to support the unofficial OID
+     * gss_nt_service_name just in case if some gss applications use
+     * the old OID.
+     */
+
+    if ((*oid != GSS_C_NT_USER_NAME) &&
+	(*oid != GSS_C_NT_MACHINE_UID_NAME) &&
+	(*oid != GSS_C_NT_STRING_UID_NAME) &&
+	(*oid != GSS_C_NT_HOSTBASED_SERVICE) &&
+	(*oid != GSS_C_NT_ANONYMOUS) &&
+	(*oid != GSS_C_NT_EXPORT_NAME) &&
+	(*oid != gss_nt_service_name)) {
+	free((*oid)->elements);
+	free(*oid);
+    }
+    *oid = GSS_C_NO_OID;
+    return(GSS_S_COMPLETE);
+}
+
+OM_uint32
+generic_gss_copy_oid(minor_status, oid, new_oid)
+	OM_uint32	*minor_status;
+	gss_OID_desc * const oid;
+	gss_OID		*new_oid;
+{
+	gss_OID		p;
+
+	*minor_status = 0;
+
+	p = (gss_OID) malloc(sizeof(gss_OID_desc));
+	if (!p) {
+		*minor_status = ENOMEM;
+		return GSS_S_FAILURE;
+	}
+	p->length = oid->length;
+	p->elements = malloc(p->length);
+	if (!p->elements) {
+		free(p);
+		return GSS_S_FAILURE;
+	}
+	memcpy(p->elements, oid->elements, p->length);
+	*new_oid = p;
+	return(GSS_S_COMPLETE);
+}
+
+
+OM_uint32
+generic_gss_create_empty_oid_set(minor_status, oid_set)
+    OM_uint32	*minor_status;
+    gss_OID_set	*oid_set;
+{
+    *minor_status = 0;
+
+    if ((*oid_set = (gss_OID_set) malloc(sizeof(gss_OID_set_desc)))) {
+	memset(*oid_set, 0, sizeof(gss_OID_set_desc));
+	return(GSS_S_COMPLETE);
+    }
+    else {
+	*minor_status = ENOMEM;
+	return(GSS_S_FAILURE);
+    }
+}
+
+OM_uint32
+generic_gss_add_oid_set_member(minor_status, member_oid, oid_set)
+    OM_uint32	*minor_status;
+    gss_OID_desc * const member_oid;
+    gss_OID_set	*oid_set;
+{
+    gss_OID	elist;
+    gss_OID	lastel;
+
+    *minor_status = 0;
+
+    if (member_oid == NULL || member_oid->length == 0 ||
+	member_oid->elements == NULL)
+	return (GSS_S_CALL_INACCESSIBLE_READ);
+
+    elist = (*oid_set)->elements;
+    /* Get an enlarged copy of the array */
+    if (((*oid_set)->elements = (gss_OID) malloc(((*oid_set)->count+1) *
+						  sizeof(gss_OID_desc)))) {
+	/* Copy in the old junk */
+	if (elist)
+	    memcpy((*oid_set)->elements,
+		   elist,
+		   ((*oid_set)->count * sizeof(gss_OID_desc)));
+
+	/* Duplicate the input element */
+	lastel = &(*oid_set)->elements[(*oid_set)->count];
+	if ((lastel->elements =
+	     (void *) malloc((size_t) member_oid->length))) {
+	    /* Success - copy elements */
+	    memcpy(lastel->elements, member_oid->elements,
+		   (size_t) member_oid->length);
+	    /* Set length */
+	    lastel->length = member_oid->length;
+
+	    /* Update count */
+	    (*oid_set)->count++;
+	    if (elist)
+		free(elist);
+	    *minor_status = 0;
+	    return(GSS_S_COMPLETE);
+	}
+	else
+	    free((*oid_set)->elements);
+    }
+    /* Failure - restore old contents of list */
+    (*oid_set)->elements = elist;
+    *minor_status = ENOMEM;
+    return(GSS_S_FAILURE);
+}
+
+OM_uint32
+generic_gss_test_oid_set_member(minor_status, member, set, present)
+    OM_uint32	*minor_status;
+    gss_OID_desc * const member;
+    gss_OID_set	set;
+    int		*present;
+{
+    OM_uint32	i;
+    int		result;
+
+    *minor_status = 0;
+
+    if (member == NULL || set == NULL)
+	return (GSS_S_CALL_INACCESSIBLE_READ);
+
+    if (present == NULL)
+	return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+    result = 0;
+    for (i=0; i<set->count; i++) {
+	if ((set->elements[i].length == member->length) &&
+	    !memcmp(set->elements[i].elements,
+		    member->elements,
+		    (size_t) member->length)) {
+	    result = 1;
+	    break;
+	}
+    }
+    *present = result;
+    return(GSS_S_COMPLETE);
+}
+
+/*
+ * OID<->string routines.  These are uuuuugly.
+ */
+OM_uint32
+generic_gss_oid_to_str(minor_status, oid, oid_str)
+    OM_uint32		*minor_status;
+    gss_OID_desc * const oid;
+    gss_buffer_t	oid_str;
+{
+    char		numstr[128];
+    OM_uint32		number;
+    int			numshift;
+    OM_uint32 string_length;
+    OM_uint32 i;
+    unsigned char	*cp;
+    char		*bp;
+
+    *minor_status = 0;
+
+    if (oid == NULL || oid->length == 0 || oid->elements == NULL)
+	return (GSS_S_CALL_INACCESSIBLE_READ);
+
+    if (oid_str == NULL)
+	return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+    /* Decoded according to krb5/gssapi_krb5.c */
+
+    /* First determine the size of the string */
+    string_length = 0;
+    number = 0;
+    numshift = 0;
+    cp = (unsigned char *) oid->elements;
+    number = (unsigned long) cp[0];
+    snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number/40);
+    string_length += strlen(numstr);
+    snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number%40);
+    string_length += strlen(numstr);
+    for (i=1; i<oid->length; i++) {
+	if ((OM_uint32) (numshift+7) < (sizeof (OM_uint32)*8)) {/* XXX */
+	    number = (number << 7) | (cp[i] & 0x7f);
+	    numshift += 7;
+	}
+	else {
+	    return(GSS_S_FAILURE);
+	}
+	if ((cp[i] & 0x80) == 0) {
+	    snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number);
+	    string_length += strlen(numstr);
+	    number = 0;
+	    numshift = 0;
+	}
+    }
+    /*
+     * If we get here, we've calculated the length of "n n n ... n ".  Add 4
+     * here for "{ " and "}\0".
+     */
+    string_length += 4;
+    if ((bp = (char *) malloc(string_length))) {
+	strcpy(bp, "{ ");
+	number = (OM_uint32) cp[0];
+	snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number/40);
+	strcat(bp, numstr);
+	snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number%40);
+	strcat(bp, numstr);
+	number = 0;
+	cp = (unsigned char *) oid->elements;
+	for (i=1; i<oid->length; i++) {
+	    number = (number << 7) | (cp[i] & 0x7f);
+	    if ((cp[i] & 0x80) == 0) {
+	        snprintf(numstr, sizeof(numstr), "%lu ", (unsigned long)number);
+		strcat(bp, numstr);
+		number = 0;
+	    }
+	}
+	strcat(bp, "}");
+	oid_str->length = strlen(bp)+1;
+	oid_str->value = (void *) bp;
+	return(GSS_S_COMPLETE);
+    }
+    *minor_status = ENOMEM;
+    return(GSS_S_FAILURE);
+}
+
+OM_uint32
+generic_gss_str_to_oid(minor_status, oid_str, oid)
+    OM_uint32		*minor_status;
+    gss_buffer_t	oid_str;
+    gss_OID		*oid;
+{
+    unsigned char	*cp, *bp, *startp;
+    int		brace;
+    long	numbuf;
+    long	onumbuf;
+    OM_uint32	nbytes;
+    int		index;
+    unsigned char *op;
+
+    *minor_status = 0;
+
+    if (GSS_EMPTY_BUFFER(oid_str))
+	return (GSS_S_CALL_INACCESSIBLE_READ);
+
+    if (oid == NULL)
+	return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+    brace = 0;
+    bp = oid_str->value;
+    cp = bp;
+    /* Skip over leading space */
+    while ((bp < &cp[oid_str->length]) && isspace(*bp))
+	bp++;
+    if (*bp == '{') {
+	brace = 1;
+	bp++;
+    }
+    while ((bp < &cp[oid_str->length]) && isspace(*bp))
+	bp++;
+    startp = bp;
+    nbytes = 0;
+
+    /*
+     * The first two numbers are chewed up by the first octet.
+     */
+    if (sscanf((char *)bp, "%ld", &numbuf) != 1) {
+	*minor_status = EINVAL;
+	return(GSS_S_FAILURE);
+    }
+    while ((bp < &cp[oid_str->length]) && isdigit(*bp))
+	bp++;
+    while ((bp < &cp[oid_str->length]) && isspace(*bp))
+	bp++;
+    if (sscanf((char *)bp, "%ld", &numbuf) != 1) {
+	*minor_status = EINVAL;
+	return(GSS_S_FAILURE);
+    }
+    while ((bp < &cp[oid_str->length]) && isdigit(*bp))
+	bp++;
+    while ((bp < &cp[oid_str->length]) &&
+	   (isspace(*bp) || *bp == '.'))
+	bp++;
+    nbytes++;
+    while (isdigit(*bp)) {
+	if (sscanf((char *)bp, "%ld", &numbuf) != 1) {
+	    return(GSS_S_FAILURE);
+	}
+	while (numbuf) {
+	    nbytes++;
+	    numbuf >>= 7;
+	}
+	while ((bp < &cp[oid_str->length]) && isdigit(*bp))
+	    bp++;
+	while ((bp < &cp[oid_str->length]) &&
+	       (isspace(*bp) || *bp == '.'))
+	    bp++;
+    }
+    if (brace && (*bp != '}')) {
+	return(GSS_S_FAILURE);
+    }
+
+    /*
+     * Phew!  We've come this far, so the syntax is good.
+     */
+    if ((*oid = (gss_OID) malloc(sizeof(gss_OID_desc)))) {
+	if (((*oid)->elements = (void *) malloc(nbytes))) {
+	    (*oid)->length = nbytes;
+	    op = (unsigned char *) (*oid)->elements;
+	    bp = startp;
+	    (void) sscanf((char *)bp, "%ld", &numbuf);
+	    while (isdigit(*bp))
+		bp++;
+	    while (isspace(*bp) || *bp == '.')
+		bp++;
+	    onumbuf = 40*numbuf;
+	    (void) sscanf((char *)bp, "%ld", &numbuf);
+	    onumbuf += numbuf;
+	    *op = (unsigned char) onumbuf;
+	    op++;
+	    while (isdigit(*bp))
+		bp++;
+	    while (isspace(*bp) || *bp == '.')
+		bp++;
+	    while (isdigit(*bp)) {
+		(void) sscanf((char *)bp, "%ld", &numbuf);
+		nbytes = 0;
+		/* Have to fill in the bytes msb-first */
+		onumbuf = numbuf;
+		while (numbuf) {
+		    nbytes++;
+		    numbuf >>= 7;
+		}
+		numbuf = onumbuf;
+		op += nbytes;
+		index = -1;
+		while (numbuf) {
+		    op[index] = (unsigned char) numbuf & 0x7f;
+		    if (index != -1)
+			op[index] |= 0x80;
+		    index--;
+		    numbuf >>= 7;
+		}
+		while (isdigit(*bp))
+		    bp++;
+		while (isspace(*bp) || *bp == '.')
+		    bp++;
+	    }
+	    return(GSS_S_COMPLETE);
+	}
+	else {
+	    free(*oid);
+	    *oid = GSS_C_NO_OID;
+	}
+    }
+    return(GSS_S_FAILURE);
+}
+
+/*
+ * Copyright 1993 by OpenVision Technologies, 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 OpenVision not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. OpenVision makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OPENVISION 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.
+ */
+OM_uint32
+gssint_copy_oid_set(
+    OM_uint32 *minor_status,
+    const gss_OID_set_desc * const oidset,
+    gss_OID_set *new_oidset
+    )
+{
+    gss_OID_set_desc *copy;
+    OM_uint32 minor = 0;
+    OM_uint32 major = GSS_S_COMPLETE;
+    OM_uint32 index;
+
+    if (minor_status)
+	*minor_status = 0;
+
+    if (oidset == NULL)
+	return (GSS_S_CALL_INACCESSIBLE_READ);
+
+    if (new_oidset == NULL)
+	return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+    *new_oidset = NULL;
+
+    if ((copy = (gss_OID_set_desc *) calloc(1, sizeof (*copy))) == NULL) {
+	major = GSS_S_FAILURE;
+	goto done;
+    }
+
+    if ((copy->elements = (gss_OID_desc *)
+	 calloc(oidset->count, sizeof (*copy->elements))) == NULL) {
+	major = GSS_S_FAILURE;
+	goto done;
+    }
+    copy->count = oidset->count;
+
+    for (index = 0; index < copy->count; index++) {
+	gss_OID_desc *out = &copy->elements[index];
+	gss_OID_desc *in = &oidset->elements[index];
+
+	if ((out->elements = (void *) malloc(in->length)) == NULL) {
+	    major = GSS_S_FAILURE;
+	    goto done;
+	}
+	(void) memcpy(out->elements, in->elements, in->length);
+	out->length = in->length;
+    }
+
+    *new_oidset = copy;
+done:
+    if (major != GSS_S_COMPLETE) {
+	(void) gss_release_oid_set(&minor, &copy);
+    }
+
+    return (major);
+}
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/pname_to_uid.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/pname_to_uid.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -33,29 +33,32 @@
  * GSS_S_FAILURE is returned on failure.
  */
 OM_uint32
-krb5_pname_to_uid(ctxt, minor,  pname, uidOut)
-void * ctxt;
+krb5_pname_to_uid(minor,  pname, uidOut)
 OM_uint32 *minor;
 const gss_name_t pname;
 uid_t *uidOut;
 {
-	krb5_context context = (krb5_context)ctxt;
+	krb5_context context;
 	char lname[256];
 	struct passwd	*pw;
 	krb5_error_code stat;
 
-	mutex_lock(&krb5_mutex);
 	if (! kg_validate_name(pname))
 	{
-		mutex_unlock(&krb5_mutex);
 		*minor = (OM_uint32) G_VALIDATE_FAILED;
 		return (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
 	}
 
+	stat = krb5_init_context(&context);
+	if (stat) {
+		*minor = stat;
+		return GSS_S_FAILURE;
+	}
+
 	stat = krb5_aname_to_localname(context, (krb5_principal) pname,
 				    sizeof (lname), lname);
-	mutex_unlock(&krb5_mutex);
-
+	krb5_free_context(context);
+	context = NULL;
 	if (stat)
 		return (GSS_S_FAILURE);
 
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/process_context_token.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/process_context_token.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,13 +1,8 @@
-/*
- * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
  * Copyright 1993 by OpenVision Technologies, 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
@@ -17,7 +12,7 @@
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
- *
+ * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -27,63 +22,45 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
 
 /*
- * $Id: process_context_token.c,v 1.10 1996/07/22 20:34:23 marc Exp $
+ * $Id: process_context_token.c 16171 2004-03-15 17:45:01Z raeburn $
  */
 
 OM_uint32
-krb5_gss_process_context_token(ct, minor_status, context_handle,
+krb5_gss_process_context_token(minor_status, context_handle, 
 			       token_buffer)
-     void *ct;
      OM_uint32 *minor_status;
      gss_ctx_id_t context_handle;
      gss_buffer_t token_buffer;
 {
-   krb5_context context;
    krb5_gss_ctx_id_rec *ctx;
    OM_uint32 majerr;
 
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, &context)))
-      return(GSS_S_FAILURE);
-#endif
-
-   mutex_lock(&krb5_mutex);
-   context = ct;
-
    /* validate the context handle */
    if (! kg_validate_ctx_id(context_handle)) {
       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
-      mutex_unlock(&krb5_mutex);
       return(GSS_S_NO_CONTEXT);
    }
 
-   ctx = (krb5_gss_ctx_id_rec *) context_handle;
+   ctx = (krb5_gss_ctx_id_t) context_handle;
 
    if (! ctx->established) {
       *minor_status = KG_CTX_INCOMPLETE;
-      mutex_unlock(&krb5_mutex);
       return(GSS_S_NO_CONTEXT);
    }
 
    /* "unseal" the token */
 
-   if (GSS_ERROR(majerr = kg_unseal(context, minor_status, (gss_ctx_id_t)ctx, 
+   if (GSS_ERROR(majerr = kg_unseal(minor_status, context_handle, 
 				    token_buffer,
 				    GSS_C_NO_BUFFER, NULL, NULL,
-				    KG_TOK_DEL_CTX))) {
-      mutex_unlock(&krb5_mutex);
+				    KG_TOK_DEL_CTX)))
       return(majerr);
-   }
 
    /* that's it.  delete the context */
-   majerr = krb5_gss_delete_sec_context_no_lock(context, minor_status, 
-		   &context_handle, GSS_C_NO_BUFFER);
 
-   mutex_unlock(&krb5_mutex);
-   return(majerr);
+   return(krb5_gss_delete_sec_context(minor_status, &context_handle,
+				      GSS_C_NO_BUFFER));
 }
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/rel_buffer.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/rel_buffer.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,15 +1,32 @@
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
 /*
- * Copyright 1996-2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * 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.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  *  glue routine for gss_release_buffer
  */
 
-#include <gssapiP_generic.h>
+#include "gssapiP_generic.h"
 
 #include <stdio.h>
 #ifdef HAVE_STDLIB_H
@@ -30,8 +47,7 @@
     if (buffer == GSS_C_NO_BUFFER)
 	return(GSS_S_COMPLETE);
 
-    if ((buffer->length) &&
-	(buffer->value)) {
+    if (buffer->value) {
 	free(buffer->value);
 	buffer->length = 0;
 	buffer->value = NULL;
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/rel_cred.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/rel_cred.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,13 +1,8 @@
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
  * Copyright 1993 by OpenVision Technologies, 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
@@ -17,7 +12,7 @@
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
- *
+ * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -27,55 +22,44 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_krb5.h>
-#include <k5-int.h>
+#include "gssapiP_krb5.h"
 
-OM_uint32
-krb5_gss_release_cred(ctx, minor_status, cred_handle)
-     void      *ctx;
+OM_uint32 
+krb5_gss_release_cred(minor_status, cred_handle)
      OM_uint32 *minor_status;
      gss_cred_id_t *cred_handle;
 {
-    OM_uint32 status;
-
-    mutex_lock(&krb5_mutex);
-    status = krb5_gss_release_cred_no_lock(ctx, minor_status, cred_handle);
-    mutex_unlock(&krb5_mutex);
-    return(status);
-}
-
-OM_uint32
-krb5_gss_release_cred_no_lock(ctx, minor_status, cred_handle)
-     void      *ctx;
-     OM_uint32 *minor_status;
-     gss_cred_id_t *cred_handle;
-{
-   krb5_context context = ctx;
+   krb5_context context;
    krb5_gss_cred_id_t cred;
    krb5_error_code code1, code2, code3;
 
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, &context)))
-      return(GSS_S_FAILURE);
-#endif
+   code1 = krb5_gss_init_context(&context);
+   if (code1) {
+       *minor_status = code1;
+       return GSS_S_FAILURE;
+   }
 
-   if (*cred_handle == GSS_C_NO_CREDENTIAL)
-   {
-      /* Solaris Kerberos:  the followin function does nothing */
-      return(kg_release_defcred(minor_status));
+   if (*cred_handle == GSS_C_NO_CREDENTIAL) {
+      *minor_status = 0;
+      krb5_free_context(context);
+      return(GSS_S_COMPLETE);
    }
 
    if (! kg_delete_cred_id(*cred_handle)) {
       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+      krb5_free_context(context);
       return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_NO_CRED);
    }
 
    cred = (krb5_gss_cred_id_t)*cred_handle;
 
+   k5_mutex_destroy(&cred->lock);
+   /* ignore error destroying mutex */
+
+
    if (cred->ccache) {
       /*
+       * Solaris Kerberos
        * If the ccache is a MEMORY ccache then this credential handle
        * should be the only way to get to it, at least until the advent
        * of a GSS_Duplicate_cred() (which is needed and may well be
@@ -101,7 +85,12 @@
       code3 = 0;
    if (cred->princ)
       krb5_free_principal(context, cred->princ);
+
+   if (cred->req_enctypes)
+       free(cred->req_enctypes);
+
    xfree(cred);
+   krb5_free_context(context);
 
    *cred_handle = NULL;
 
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/rel_name.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/rel_name.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,13 +1,8 @@
-/*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
  * Copyright 1993 by OpenVision Technologies, 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
@@ -17,7 +12,7 @@
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
- *
+ * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -27,46 +22,32 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
 
 OM_uint32
-krb5_gss_release_name(ctx, minor_status, input_name)
-     void	*ctx;
+krb5_gss_release_name(minor_status, input_name)
      OM_uint32 *minor_status;
      gss_name_t *input_name;
 {
-    OM_uint32 rc;
-
-    mutex_lock(&krb5_mutex);
-    rc = krb5_gss_release_name_no_lock(ctx, minor_status, input_name);
-    mutex_unlock(&krb5_mutex);
-    return (rc);
-}
+   krb5_context context;
+   krb5_error_code code;
 
-OM_uint32
-krb5_gss_release_name_no_lock(ctx, minor_status, input_name)
-     void	*ctx;
-     OM_uint32 *minor_status;
-     gss_name_t *input_name;
-{
-   krb5_context context = ctx;
-
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, &context)))
-      return(GSS_S_FAILURE);
-#endif
-
+   code = krb5_gss_init_context(&context);
+   if (code) {
+       *minor_status = code;
+       return GSS_S_FAILURE;
+   }
 
    if (! kg_validate_name(*input_name)) {
       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+      krb5_free_context(context);
       return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
    }
 
    (void)kg_delete_name(*input_name);
 
    krb5_free_principal(context, (krb5_principal) *input_name);
+   krb5_free_context(context);
 
    *input_name = (gss_name_t) NULL;
 
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,8 +1,3 @@
-/*
- * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
@@ -23,7 +18,10 @@
  * 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.  M.I.T. makes no representations about the suitability of
+ * 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.
  *
@@ -32,7 +30,12 @@
 /*
  * rel_oid.c - Release an OID.
  */
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
+#include "mglueP.h"
+
+OM_uint32 krb5_gss_internal_release_oid (OM_uint32 *, /* minor_status */
+					 gss_OID * /* oid */
+    );
 
 OM_uint32
 krb5_gss_release_oid(minor_status, oid)
@@ -48,9 +51,9 @@
      * descriptor.  This allows applications to freely mix their own heap-
      * allocated OID values with OIDs returned by GSS-API.
      */
-    if (krb5_gss_internal_release_oid(NULL, minor_status, oid) != GSS_S_COMPLETE) {
+    if (krb5_gss_internal_release_oid(minor_status, oid) != GSS_S_COMPLETE) {
 	/* Pawn it off on the generic routine */
-	return(gss_release_oid(minor_status, oid));
+	return(generic_gss_release_oid(minor_status, oid));
     }
     else {
 	*oid = GSS_C_NO_OID;
@@ -59,10 +62,8 @@
     }
 }
 
-/*ARGSUSED*/
 OM_uint32
-krb5_gss_internal_release_oid(ct, minor_status, oid)
-    void	*ct;
+krb5_gss_internal_release_oid(minor_status, oid)
     OM_uint32	*minor_status;
     gss_OID	*oid;
 {
@@ -71,9 +72,9 @@
      * return GSS_S_CONTINUE_NEEDED for any OIDs it does not recognize.
      */
    
-    if ((*oid != gss_mech_krb5_v2) &&
-	(*oid != gss_mech_krb5) &&
+    if ((*oid != gss_mech_krb5) &&
 	(*oid != gss_mech_krb5_old) &&
+	(*oid != gss_mech_krb5_wrong) &&
 	(*oid != gss_nt_krb5_name) &&
 	(*oid != gss_nt_krb5_principal)) {
 	/* We don't know about this OID */
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid_set.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/rel_oid_set.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,15 +1,32 @@
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
 /*
- * Copyright 1996-2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * 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.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  *  glue routine for gss_release_oid_set
  */
 
-#include <gssapiP_generic.h>
+#include "gssapiP_generic.h"
 
 #include <stdio.h>
 #ifdef HAVE_STDLIB_H
@@ -39,6 +56,6 @@
     free(*set);
 
     *set = GSS_C_NULL_OID_SET;
-
+    
     return(GSS_S_COMPLETE);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/set_allowable_enctypes.c	Fri Sep 14 15:01:24 2007 -0700
@@ -0,0 +1,135 @@
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*
+ * lib/gssapi/krb5/set_allowable_enctypes.c
+ *
+ * Copyright 2004  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.
+ *
+ * krb5_gss_set_allowable_enctypes()
+ */
+
+/*
+ * gss_krb5_set_allowable_enctypes
+ *
+ * This function may be called by a context initiator after calling
+ * gss_acquire_cred(), but before calling gss_init_sec_context(),
+ * to restrict the set of enctypes which will be negotiated during
+ * context establishment to those in the provided array.
+ *
+ * 'cred_handle' must be a valid credential handle obtained via
+ * gss_acquire_cred().  It may not be GSS_C_NO_CREDENTIAL.
+ * gss_acquire_cred() may be called with GSS_C_NO_CREDENTIAL
+ * to get a handle to the default credential.
+ *
+ * The purpose of this function is to limit the keys that may
+ * be exported via gss_krb5_export_lucid_sec_context(); thus it
+ * should limit the enctypes of all keys that will be needed
+ * after the security context has been established.
+ * (i.e. context establishment may use a session key with a
+ * stronger enctype than in the provided array, however a
+ * subkey must be established within the enctype limits
+ * established by this function.)
+ *
+ */
+
+#include "gssapiP_krb5.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include "gssapi_krb5.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_krb5int_set_allowable_enctypes(OM_uint32 *minor_status, 
+				   gss_cred_id_t cred_handle,
+				   OM_uint32 num_ktypes,
+				   krb5_enctype *ktypes)
+{
+    int i;
+    krb5_enctype * new_ktypes;
+    OM_uint32 major_status;
+    krb5_gss_cred_id_t cred;
+    krb5_error_code kerr = 0;
+    OM_uint32 temp_status;
+
+    /* Assume a failure */
+    *minor_status = 0;
+    major_status = GSS_S_FAILURE;
+
+    /* verify and valildate cred handle */
+    if (cred_handle == GSS_C_NO_CREDENTIAL) {
+	kerr = KRB5_NOCREDS_SUPPLIED;
+	goto error_out;
+    }
+    major_status = krb5_gss_validate_cred(&temp_status, cred_handle);
+    if (GSS_ERROR(major_status)) {
+	kerr = temp_status;
+	goto error_out;
+    }
+    cred = (krb5_gss_cred_id_t) cred_handle;
+
+    if (ktypes) {
+	for (i = 0; i < num_ktypes && ktypes[i]; i++) {
+	    if (!krb5_c_valid_enctype(ktypes[i])) {
+		kerr = KRB5_PROG_ETYPE_NOSUPP;
+		goto error_out;
+	    }
+	}
+    } else {
+	kerr = k5_mutex_lock(&cred->lock);
+	if (kerr)
+	    goto error_out;
+	if (cred->req_enctypes)
+	    free(cred->req_enctypes);
+	cred->req_enctypes = NULL;
+	k5_mutex_unlock(&cred->lock);
+	return GSS_S_COMPLETE;
+    }
+
+    /* Copy the requested ktypes into the cred structure */
+    if ((new_ktypes = (krb5_enctype *)malloc(sizeof(krb5_enctype) * (i + 1)))) {
+	memcpy(new_ktypes, ktypes, sizeof(krb5_enctype) * i);
+	new_ktypes[i] = 0;	/* "null-terminate" the list */
+    }
+    else {
+	kerr = ENOMEM;
+	goto error_out;
+    }
+    kerr = k5_mutex_lock(&cred->lock);
+    if (kerr) {
+	free(new_ktypes);
+	goto error_out;
+    }
+    if (cred->req_enctypes)
+	free(cred->req_enctypes);
+    cred->req_enctypes = new_ktypes;
+    k5_mutex_unlock(&cred->lock);
+
+    /* Success! */
+    return GSS_S_COMPLETE;
+
+error_out:
+    *minor_status = kerr;
+    return(major_status);
+}
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/set_ccache.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/set_ccache.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,28 +1,99 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
-#include <gssapiP_krb5.h>
+/*
+ * lib/gssapi/krb5/set_ccache.c
+ *
+ * Copyright 1999, 2003 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.
+ *
+ * Set ccache name used by gssapi, and optionally obtain old ccache
+ * name.  Caller should not free returned name.
+ */
 
-GSS_DLLIMP OM_uint32 KRB5_CALLCONV 
+#include <string.h>
+#include "gssapiP_krb5.h"
+#include "gss_libinit.h"
+
+OM_uint32 KRB5_CALLCONV 
 gss_krb5_ccache_name(minor_status, name, out_name)
 	OM_uint32 *minor_status;
 	const char *name;
 	const char **out_name;
 {
-	krb5_context context;
-	krb5_error_code retval;
-	OM_uint32 foo_stat;
+    char *old_name = NULL;
+    OM_uint32 err = 0;
+    OM_uint32 minor = 0;
+    char *gss_out_name;
+
+    err = gssint_initialize_library();
+    if (err) {
+	*minor_status = err;
+	return GSS_S_FAILURE;
+    }
+
+    gss_out_name = k5_getspecific(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME);
 
-	if (GSS_ERROR(kg_get_context(minor_status, &context)))
-		return (GSS_S_FAILURE);
+    if (out_name) {
+        const char *tmp_name = NULL;
+
+        if (!err) {
+            kg_get_ccache_name (&err, &tmp_name);
+        }
+        if (!err) {
+            old_name = gss_out_name;
+            gss_out_name = (char *)tmp_name;
+        }            
+    }
+    /* If out_name was NULL, we keep the same gss_out_name value, and
+       don't free up any storage (leave old_name NULL).  */
 
-	if (out_name)
-		*out_name = krb5_cc_default_name(context);
+    if (!err)
+        kg_set_ccache_name (&err, name);
+
+    minor = k5_setspecific(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME, gss_out_name);
+    if (minor) {
+	/* Um.  Now what?  */
+	if (err == 0) {
+	    err = minor;
+	}
+	free(gss_out_name);
+	gss_out_name = NULL;
+    }
 
-	retval = krb5_cc_set_default_name(context, name);
-	if (retval) {
-		*minor_status = retval;
-		return GSS_S_FAILURE;
-	}
-	kg_release_defcred(&foo_stat);
-	return GSS_S_COMPLETE;
+    if (!err) {
+        if (out_name) {
+            *out_name = gss_out_name;
+        }
+    }
+    
+    if (old_name != NULL) {
+        free (old_name);
+    }
+    
+    *minor_status = err;
+    return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
 }
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/store_cred.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/store_cred.c	Fri Sep 14 15:01:24 2007 -0700
@@ -87,33 +87,9 @@
 }
 
 OM_uint32
-krb5_gss_store_cred(ct, minor_status, input_cred, cred_usage, desired_mech,
-			overwrite_cred, default_cred, elements_stored,
-			cred_usage_stored)
-void *ct;
-OM_uint32 *minor_status;
-const gss_cred_id_t input_cred;
-gss_cred_usage_t cred_usage;
-gss_OID desired_mech;
-OM_uint32 overwrite_cred;
-OM_uint32 default_cred;
-gss_OID_set *elements_stored;
-gss_cred_usage_t *cred_usage_stored;
-{
-	OM_uint32 ret;
-	mutex_lock(&krb5_mutex);
-	ret = krb5_gss_store_cred_no_lock(ct, minor_status, input_cred,
-			cred_usage, desired_mech, overwrite_cred, default_cred,
-			elements_stored, cred_usage_stored);
-	mutex_unlock(&krb5_mutex);
-	return (ret);
-}
-
-OM_uint32
-krb5_gss_store_cred_no_lock(ct, minor_status, input_cred, cred_usage,
+krb5_gss_store_cred(minor_status, input_cred, cred_usage,
 		desired_mech, overwrite_cred, default_cred, elements_stored,
 		cred_usage_stored)
-void *ct;
 OM_uint32 *minor_status;
 const gss_cred_id_t input_cred;
 gss_cred_usage_t cred_usage;
@@ -124,7 +100,7 @@
 gss_cred_usage_t *cred_usage_stored;
 {
 	OM_uint32 maj, maj2, min;
-	krb5_context ctx = (krb5_context)ct;
+	krb5_context ctx = NULL;
 	krb5_gss_cred_id_t cred = (krb5_gss_cred_id_t)input_cred;
 	krb5_gss_cred_id_t cur_cred = (krb5_gss_cred_id_t)GSS_C_NO_CREDENTIAL;
 	gss_OID_set desired_mechs = GSS_C_NULL_OID_SET;
@@ -162,8 +138,14 @@
 	if (cred_usage == GSS_C_BOTH)
 		cred_usage = GSS_C_INITIATE;
 
+	min = krb5_gss_init_context(&ctx);
+	if (min) {
+		*minor_status = min;
+		return (GSS_S_FAILURE);
+	}
+
 	/* * Find out the name, lifetime and cred usage of the input cred */
-	maj = krb5_gss_inquire_cred_no_lock(ctx, minor_status, input_cred,
+	maj = krb5_gss_inquire_cred(minor_status, input_cred,
 			&in_name, &in_time_rec, &in_usage, NULL);
 	if (GSS_ERROR(maj))
 		goto cleanup;
@@ -205,7 +187,7 @@
 	 * then we must be careful not to overwrite an existing
 	 * unexpired credential.
 	 */
-	maj2 = krb5_gss_acquire_cred_no_lock(ctx, &min,
+	maj2 = krb5_gss_acquire_cred(&min,
 			(default_cred) ?  GSS_C_NO_NAME : in_name,
 			0, desired_mechs, cred_usage,
 			(gss_cred_id_t *)&cur_cred, NULL, &cur_time_rec);
@@ -245,10 +227,13 @@
 	if (desired_mechs != GSS_C_NULL_OID_SET)
 		(void) gss_release_oid_set(&min, &desired_mechs);
 	if (cur_cred != (krb5_gss_cred_id_t)GSS_C_NO_CREDENTIAL)
-		(void) krb5_gss_release_cred_no_lock(ctx, &min,
+		(void) krb5_gss_release_cred(&min,
 				    (gss_cred_id_t *)&cur_cred);
 	if (in_name != GSS_C_NO_NAME)
-		(void) krb5_gss_release_name_no_lock(ctx, &min, &in_name);
+		(void) krb5_gss_release_name(&min, &in_name);
+
+	if (ctx)
+		krb5_free_context(ctx);
 
 	return (maj);
 }
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/util_buffer.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/util_buffer.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,11 +1,6 @@
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
- * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
  * Copyright 1993 by OpenVision Technologies, Inc.
  * 
  * Permission to use, copy, modify, distribute, and sell this software
@@ -28,10 +23,10 @@
  */
 
 /*
- * $Id: util_buffer.c,v 1.6 1996/07/22 20:33:19 marc Exp $
+ * $Id: util_buffer.c 11001 1998-10-30 02:56:35Z marc $
  */
 
-#include <gssapiP_generic.h>
+#include "gssapiP_generic.h"
 #include <string.h>
 
 /* return nonzero on success, 0 on failure
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/util_cksum.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/util_cksum.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,4 +1,10 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
+
 /*
  * Copyright 1993 by OpenVision Technologies, Inc.
  * 
@@ -21,15 +27,12 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/*
- * $Id: util_cksum.c,v 1.14.6.1 2000/04/22 03:01:36 raeburn Exp $
- */
-
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
+#ifdef HAVE_MEMORY_H
 #include <memory.h>
+#endif
 
 /* Checksumming the channel bindings always uses plain MD5.  */
-/*ARGSUSED*/
 krb5_error_code
 kg_checksum_channel_bindings(context, cb, cksum, bigend)
      krb5_context context;
@@ -37,14 +40,17 @@
      krb5_checksum *cksum;
      int bigend;
 {
-   int len;
-   char *buf, *ptr;
+   size_t len;
+   char *buf = 0;
+   char *ptr;
    size_t sumlen;
    krb5_data plaind;
    krb5_error_code code;
+   void *temp;
 
-   /* initialize the the cksum and allocate the contents buffer */
-   if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen))
+   /* initialize the the cksum */
+   code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen);
+   if (code)
        return(code);
 
    cksum->checksum_type = CKSUMTYPE_RSA_MD5;
@@ -86,15 +92,46 @@
    plaind.length = len;
    plaind.data = buf;
 
-   if (code = krb5_c_make_checksum(context, CKSUMTYPE_RSA_MD5, 0, 0,
-				   &plaind, cksum)) {
-      xfree(cksum->contents);
-      xfree(buf);
-      return(code);
+#if 0
+   /*
+    * SUNW15resync
+    * MIT 1.5-6 seems/is wrong here in 2 ways
+    *   - why free then alloc contents again?
+    *   - calling krb5_free_checksum_contents results in cksum->length
+    *     getting set to 0 which causes ftp to fail
+    * so lets stick w/oldey-but-goodey code.
+    */
+   code = krb5_c_make_checksum(context, CKSUMTYPE_RSA_MD5, 0, 0,
+			       &plaind, cksum);
+   if (code)
+       goto cleanup;
+
+   if ((temp = xmalloc(cksum->length)) == NULL) {
+       krb5_free_checksum_contents(context, cksum);
+       code = ENOMEM;
+       goto cleanup;
    }
 
+   memcpy(temp, cksum->contents, cksum->length);
+   krb5_free_checksum_contents(context, cksum);
+   cksum->contents = (krb5_octet *)temp;
+   /* SUNW15resync - need to reset cksum->length here */
+
    /* success */
+ cleanup:
+   if (buf)
+       xfree(buf);
+#endif /* 0 */
 
-   xfree(buf);
-   return(0);
+   if (code = krb5_c_make_checksum(context, CKSUMTYPE_RSA_MD5, 0, 0, 
+                                   &plaind, cksum)) { 
+      xfree(cksum->contents); /* SUNW15resync -just in case not already free */
+      xfree(buf); 
+      return(code); 
+   } 
+ 
+   /* success */ 
+ 
+   xfree(buf); 
+   return code;
 }
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/util_localhost.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/util_localhost.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -7,7 +7,7 @@
 
 /*
  * Copyright 1993 by OpenVision Technologies, 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
@@ -17,7 +17,7 @@
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
- *
+ * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -28,20 +28,16 @@
  */
 
 /*
- * $Id: util_localhost.c,v 1.1 1996/04/12 00:39:38 marc Exp $
+ * $Id: util_localhost.c 7797 1996-04-12 00:40:24Z marc $
  */
 
 /* This file could be OS specific */
 
-/*
- * Solaris Kerberos:  the MAXHOSTNAMELEN is defined in <netdb.h> not
- * in <sys/param.h>, and gethostname requires <unistd.h>
- */
-#include <unistd.h>
-#include <netdb.h>
-#include <string.h>
+#include <sys/param.h>
 
-#include <gssapiP_generic.h>
+#include "gssapiP_generic.h"
+#include <strings.h> /* SUNW15resync */
+#include <unistd.h>  /* SUNW15resync */
 
 #ifndef MAXHOSTNAMELEN
 #define MAXHOSTNAMELEN 64
--- a/usr/src/lib/gss_mechs/mech_krb5/mech/utl_nohash_validate.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/gss_mechs/mech_krb5/mech/utl_nohash_validate.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,4 +1,5 @@
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
+
 /*
  *  Copyright 1990,1994 by the Massachusetts Institute of Technology.
  *  All Rights Reserved.
@@ -15,7 +16,10 @@
  * 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.  M.I.T. makes no representations about the suitability of
+ * 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.
  * 
@@ -25,7 +29,7 @@
  * stub functions for those without the hash library.
  */
 
-#include <gssapiP_generic.h>
+#include "gssapiP_generic.h"
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -56,6 +60,12 @@
 {
 	return 1;
 }
+int g_save_lucidctx_id(vdb, lctx)
+     void **vdb;
+     void *lctx;
+{
+	return 1;
+}
 
 /* validate */
 
@@ -77,6 +87,12 @@
 {
 	return 1;
 }
+int g_validate_lucidctx_id(vdb, lctx)
+     void **vdb;
+     void *lctx;
+{
+	return 1;
+}
 
 /* delete */
 
@@ -98,4 +114,10 @@
 {
 	return 1;
 }
+int g_delete_lucidctx_id(vdb, lctx)
+     void **vdb;
+     void *lctx;
+{
+	return 1;
+}
 
--- a/usr/src/lib/krb5/kadm5/clnt/client_init.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/krb5/kadm5/clnt/client_init.c	Fri Sep 14 15:01:24 2007 -0700
@@ -773,8 +773,7 @@
 	} else {
 		input_name.value = service_name;
 		input_name.length = strlen((char *)input_name.value) + 1;
-		gssstat = krb5_gss_import_name(handle->context,
-				    &minor_stat,
+		gssstat = krb5_gss_import_name(&minor_stat,
 				    &input_name,
 				    (gss_OID)GSS_C_NT_HOSTBASED_SERVICE,
 				    (gss_name_t *)&creds.server);
--- a/usr/src/lib/libgss/g_acquire_cred.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/libgss/g_acquire_cred.c	Fri Sep 14 15:01:24 2007 -0700
@@ -36,6 +36,7 @@
 #include <string.h>
 #include <errno.h>
 #include <time.h>
+
 /* local functions */
 static gss_OID_set create_actual_mechs(const gss_OID, int);
 
--- a/usr/src/lib/libgss/g_canon_name.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/libgss/g_canon_name.c	Fri Sep 14 15:01:24 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -93,7 +92,7 @@
 		out_union->external_name = 0;
 
 		/* Allocate the buffer for the user specified representation */
-		if (__gss_create_copy_buffer(in_union->external_name,
+		if (gssint_create_copy_buffer(in_union->external_name,
 				&out_union->external_name, 1))
 			goto allocation_failure;
 
--- a/usr/src/lib/libgss/g_dup_name.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/libgss/g_dup_name.c	Fri Sep 14 15:01:24 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -82,7 +81,7 @@
 	dest_union->external_name = 0;
 
 	/* Now copy the external representaion */
-	if (__gss_create_copy_buffer(src_union->external_name,
+	if (gssint_create_copy_buffer(src_union->external_name,
 				&dest_union->external_name, 0))
 		goto allocation_failure;
 
--- a/usr/src/lib/libgss/g_glue.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/libgss/g_glue.c	Fri Sep 14 15:01:24 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -546,7 +545,7 @@
  * Both space for the structure and the data is allocated.
  */
 OM_uint32
-__gss_create_copy_buffer(srcBuf, destBuf, addNullChar)
+gssint_create_copy_buffer(srcBuf, destBuf, addNullChar)
 	const gss_buffer_t	srcBuf;
 	gss_buffer_t 		*destBuf;
 	int			addNullChar;
--- a/usr/src/lib/libgss/g_imp_name.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/lib/libgss/g_imp_name.c	Fri Sep 14 15:01:24 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -94,7 +93,7 @@
 	 * 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 = __gss_create_copy_buffer(input_name_buffer,
+	major_status = gssint_create_copy_buffer(input_name_buffer,
 					&union_name->external_name, 0);
 	if (major_status != GSS_S_COMPLETE) {
 		free(union_name);
--- a/usr/src/uts/common/gssapi/include/mechglueP.h	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/include/mechglueP.h	Fri Sep 14 15:01:24 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,33 +19,47 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-/*
- * This header contains the private mechglue definitions.
- */
-
-#ifndef	_MECHGLUEP_H
-#define	_MECHGLUEP_H
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
-#include <sys/types.h>
-#include <gssapi/gssapi.h>
-#include <gssapi/gssapi_ext.h>
+/*
+ * This header contains the private mechglue definitions.
+ *
+ */
+
+#ifndef _GSS_MECHGLUEP_H
+#define _GSS_MECHGLUEP_H
 
-#ifdef	__cplusplus
-extern "C" {
+#if 0 /* SUNW15resync - disable for sake of non-krb5 mechs */
+#include "autoconf.h"
+#endif
+
+/* SUNW15resync */
+#ifndef GSS_DLLIMP
+#define GSS_DLLIMP
 #endif
 
-/*
- * derived types for passing context and credential handles
- * between gssd and kernel
- */
-typedef unsigned int gssd_ctx_id_t;
-typedef unsigned int gssd_cred_id_t;
+#include <gssapi/gssapi_ext.h>   /* SUNW15resync - mechglue.h in mit 1.5 */
+/* #include "gssapiP_generic.h" */
+
+#ifdef _KERNEL
+#include <rpc/rpc.h>
+#endif 
+
+#ifndef g_OID_copy /* SUNW15resync */
+#define	g_OID_copy(o1, o2)					\
+do {								\
+	memcpy((o1)->elements, (o2)->elements, (o2)->length);	\
+	(o1)->length = (o2)->length;				\
+} while (0)
+#endif
+
+#define	GSS_EMPTY_BUFFER(buf)	((buf) == NULL ||\
+	(buf)->value == NULL || (buf)->length == 0)
+
 /*
  * Array of context IDs typed by mechanism OID
  */
@@ -74,9 +87,9 @@
  * 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_OID	name_type;
+    gss_OID	mech;
+    struct gss_mech_spec_name_t	*next, *prev;
 } gss_mech_spec_name_desc, *gss_mech_spec_name;
 
 /*
@@ -96,11 +109,11 @@
 typedef struct gss_union_cred_t {
 	int			count;
 	gss_OID			mechs_array;
-	gss_cred_id_t 		*cred_array;
+	gss_cred_id_t		*cred_array;
 	gss_union_cred_auxinfo	auxinfo;
 } gss_union_cred_desc, *gss_union_cred_t;
 
-
+/* Solaris Kerberos */
 typedef	OM_uint32	    (*gss_acquire_cred_with_password_sfct)(
 		    void *,		/* context */
 		    OM_uint32 *,	/* minor_status */
@@ -114,23 +127,34 @@
 		    OM_uint32 *		/* time_rec */
 	/* */);
 
+
+
+/********************************************************/
+/* The Mechanism Dispatch Table -- a mechanism needs to */
+/* define one of these and provide a function to return */
+/* it to initialize the GSSAPI library                  */
+
 /*
  * This is the definition of the mechs_array struct, which is used to
  * define the mechs array table. This table is used to indirectly
  * access mechanism specific versions of the gssapi routines through
  * the routines in the glue module (gssd_mech_glue.c)
  *
- * This contains all of the functions defined in gssapi.h except for
+ * 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.
+ * assuming, for now, to be equal across mechanisms.  
  */
-
+ 
 typedef struct gss_config {
-	gss_OID_desc    mech_type;
-	void *	    context;
+#if 0 /* Solaris Kerberos */
+    OM_uint32	    priority;
+    char *	    mechNameStr;
+#endif
+    gss_OID_desc    mech_type;
+    void *	    context;
 #ifdef	_KERNEL
-	struct gss_config *next;
-	bool_t	    uses_kmod;
+    struct gss_config *next;
+    bool_t	    uses_kmod;
 #endif
 
 #ifndef	_KERNEL
@@ -495,6 +519,8 @@
 #endif
 } *gss_mechanism;
 
+
+	
 #ifndef _KERNEL
 /* This structure MUST NOT be used by any code outside libgss */
 typedef struct gss_config_ext {
@@ -502,6 +528,7 @@
 } *gss_mechanism_ext;
 #endif /* _KERNEL */
 
+
 /*
  * In the user space we use a wrapper structure to encompass the
  * mechanism entry points.  The wrapper contain the mechanism
@@ -509,7 +536,6 @@
  * 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.
  */
-#ifndef _KERNEL
 typedef struct gss_mech_config {
 	char *kmodName;			/* kernel module name */
 	char *uLibName;			/* user library name */
@@ -518,29 +544,30 @@
 	void *dl_handle;		/* RTLD object handle for the mech */
 	gss_OID mech_type;		/* mechanism oid */
 	gss_mechanism mech;		/* mechanism initialization struct */
-	gss_mechanism_ext mech_ext;	/* extensions */
+#ifndef _KERNEL
+	gss_mechanism_ext mech_ext;	/* Solaris extensions */
+#endif /* _KERNEL */
 	struct gss_mech_config *next;	/* next element in the list */
 } *gss_mech_info;
-#endif
+
+/********************************************************/
+/* Internal mechglue routines */
 
-#ifndef	_KERNEL
-/*
- * Internal mechglue routines
- */
-
+/* SUNW15resync - Solaris versions - replace w/mit ones? */
 gss_mechanism __gss_get_mechanism(const gss_OID);
+#ifndef _KERNEL
 gss_mechanism_ext __gss_get_mechanism_ext(const gss_OID);
+#endif /* _KERNEL */
 char *__gss_get_kmodName(const gss_OID);
 char *__gss_get_modOptions(const gss_OID);
 OM_uint32 __gss_import_internal_name(OM_uint32 *, const gss_OID,
-	gss_union_name_t, gss_name_t *);
+ 	gss_union_name_t, gss_name_t *);
 OM_uint32 __gss_export_internal_name(OM_uint32 *, const gss_OID,
 	const gss_name_t, gss_buffer_t);
 OM_uint32 __gss_display_internal_name(OM_uint32 *, const gss_OID,
 	const gss_name_t, gss_buffer_t, gss_OID *);
 OM_uint32 __gss_release_internal_name(OM_uint32 *, const gss_OID,
 	gss_name_t *);
-
 OM_uint32 __gss_convert_name_to_union_name(
 	OM_uint32 *,		/* minor_status */
 	gss_mechanism,	/* mech */
@@ -548,68 +575,132 @@
 	gss_name_t *		/* external_name */
 );
 
-gss_cred_id_t __gss_get_mechanism_cred(
+ gss_cred_id_t __gss_get_mechanism_cred(
 	const gss_union_cred_t,	/* union_cred */
 	const gss_OID		/* mech_type */
 );
 
-OM_uint32 __gss_create_copy_buffer(
+
+
+
+
+int gssint_mechglue_init(void);
+void gssint_mechglue_fini(void);
+
+gss_mechanism gssint_get_mechanism (gss_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_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 generic_gss_release_oid(
-	OM_uint32 *,	/* minor_status */
-	gss_OID *		/* oid */
-);
 
-OM_uint32 generic_gss_copy_oid(
-	OM_uint32 *,	/* minor_status */
-	const gss_OID,		/* oid */
-	gss_OID *		/* new_oid */
-);
-
-OM_uint32 generic_gss_create_empty_oid_set(
-	OM_uint32 *,	/* minor_status */
-	gss_OID_set *	/* oid_set */
+OM_uint32 gssint_copy_oid_set(
+	OM_uint32 *,			/* minor_status */
+	const gss_OID_set_desc *,	/* oid set */
+	gss_OID_set *			/* new oid set */
 );
 
-OM_uint32 generic_gss_add_oid_set_member(
-	OM_uint32 *,	/* minor_status */
-	const gss_OID,		/* member_oid */
-	gss_OID_set *	/* oid_set */
-);
-
-OM_uint32 generic_gss_test_oid_set_member(
-	OM_uint32 *,	/* minor_status */
-	const gss_OID,		/* member */
-	const gss_OID_set,	/* set */
-	int *		/* present */
-);
-
-OM_uint32 generic_gss_oid_to_str(
-	OM_uint32 *,	/* minor_status */
-	const gss_OID,		/* oid */
-	gss_buffer_t	/* oid_str */
-);
-
-OM_uint32 generic_gss_str_to_oid(
-	OM_uint32 *,	/* minor_status */
-	const gss_buffer_t,	/* oid_str */
-	gss_OID *		/* oid */
-);
-
+/* SUNW15resync - for old Solaris version in libgss */
 OM_uint32 gss_copy_oid_set(
 	OM_uint32 *,			/* minor_status */
 	const gss_OID_set_desc *,	/* oid set */
 	gss_OID_set *			/* new oid set */
 );
 
-#endif
+
+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
+ */
+
+OM_uint32
+gssint_mech_to_oid(
+	const char *mech,		/* mechanism string name */
+	gss_OID *oid			/* mechanism oid */
+);
+
+const char *
+gssint_oid_to_mech(
+	const gss_OID oid		/* mechanism oid */
+);
+
+OM_uint32
+gssint_get_mechanisms(
+	char *mechArray[],		/* array to populate with mechs */
+	int arrayLen			/* length of passed in array */
+);
+
+OM_uint32
+gss_store_cred(
+	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_OID_set *,		/* elements_stored */
+	gss_cred_usage_t *	/* cred_usage_stored */
+);
+
+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 */
+);
+
+
+
+/* Solaris kernel and gssd support */
+
+/*
+ * derived types for passing context and credential handles
+ * between gssd and kernel
+ */
+typedef unsigned int gssd_ctx_id_t;
+typedef unsigned int gssd_cred_id_t;
 
 #ifdef	_KERNEL
-#include <rpc/rpc.h>
 
 #ifndef	_KRB5_H
 /* These macros are defined for Kerberos in krb5.h, and have priority */
@@ -693,7 +784,15 @@
 
 /* EXPORT DELETE END */
 
+#define KGSS_INIT_CONTEXT(ctx) krb5_init_context(ctx)
+#define KGSS_RELEASE_OID(minor_st, oid) krb5_gss_release_oid(minor_st, oid)
+extern OM_uint32 kgss_release_oid(OM_uint32 *, gss_OID *);
+
 #else /* !_KERNEL */
+
+#define KGSS_INIT_CONTEXT(ctx) krb5_gss_init_context(ctx)
+#define KGSS_RELEASE_OID(minor_st, oid) gss_release_oid(minor_st, oid)
+
 #define	KCTX_TO_CTX(ctx)  (KCTX_TO_KGSS_CTX(ctx)->gssd_ctx)
 #define	MALLOC(n) malloc(n)
 #define	FREE(x, n) free(x)
@@ -722,8 +821,57 @@
 		KCTX_TO_CTXV(ctx))
 #endif /* _KERNEL */
 
-#ifdef __cplusplus
-}
-#endif
+/* SUNW15resync - moved from gssapiP_generic.h for sake of non-krb5 mechs */
+OM_uint32 generic_gss_release_buffer
+(OM_uint32*,       /* minor_status */
+            gss_buffer_t      /* buffer */
+           );
+
+OM_uint32 generic_gss_release_oid_set
+(OM_uint32*,       /* minor_status */
+            gss_OID_set*      /* set */
+           );
+
+OM_uint32 generic_gss_release_oid
+(OM_uint32*,       /* minor_status */
+            gss_OID*         /* set */
+           );
+
+OM_uint32 generic_gss_copy_oid
+(OM_uint32 *,	/* minor_status */
+            gss_OID_desc * const,   /* oid */ /* SUNW15resync */
+	    gss_OID *		/* new_oid */
+	    );
+
+OM_uint32 generic_gss_create_empty_oid_set
+(OM_uint32 *,	/* minor_status */
+	    gss_OID_set *	/* oid_set */
+	   );
 
-#endif	/* _MECHGLUEP_H */
+OM_uint32 generic_gss_add_oid_set_member
+(OM_uint32 *,	/* minor_status */
+	    gss_OID_desc * const,		/* member_oid */
+	    gss_OID_set *	/* oid_set */
+	   );
+
+OM_uint32 generic_gss_test_oid_set_member
+(OM_uint32 *,	/* minor_status */
+	    gss_OID_desc * const,		/* member */
+	    gss_OID_set,	/* set */
+	    int *		/* present */
+	   );
+
+OM_uint32 generic_gss_oid_to_str
+(OM_uint32 *,	/* minor_status */
+	    gss_OID_desc * const,		/* oid */
+	    gss_buffer_t	/* oid_str */
+	   );
+
+OM_uint32 generic_gss_str_to_oid
+(OM_uint32 *,	/* minor_status */
+	    gss_buffer_t,	/* oid_str */
+	    gss_OID *		/* oid */
+	   );
+
+
+#endif /* _GSS_MECHGLUEP_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/gssapi/include/mglueP.h	Fri Sep 14 15:01:24 2007 -0700
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*
+ * SUNW15resync
+ * This file (mglueP.h) is the MIT name for the mech glue
+ * header file, but the Solaris one is mechglueP.h.  We keep this file
+ * so MIT files don't need to be changed to include the Solaris one.
+ */
+
+#include "mechglueP.h"
+
+
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_generic.h	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_generic.h	Fri Sep 14 15:01:24 2007 -0700
@@ -1,3 +1,10 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
 /*
  * Copyright 1993 by OpenVision Technologies, Inc.
  * 
@@ -20,57 +27,46 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #ifndef _GSSAPIP_GENERIC_H_
 #define _GSSAPIP_GENERIC_H_
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
- * $Id: gssapiP_generic.h,v 1.24 1998/10/30 02:54:06 marc Exp $
+ * $Id: gssapiP_generic.h 18131 2006-06-14 22:27:54Z tlyu $
  */
 
-#ifdef __cplusplus
-extern "C" {
+#if defined(_WIN32)
+#include "k5-int.h"
+#else
+#include "autoconf.h"
+#ifndef _KERNEL
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif /* !_KERNEL */
+#endif
 #endif
 
-#if !defined(PROTOTYPE) 
-#define     PROTOTYPE(x) x 
-#endif 
+#include "k5-thread.h"
+
+#include "gssapi_generic.h"
 
-#if (defined(_MSDOS) || defined(_WIN32) || defined(macintosh))
-#include <k5-int.h>
+#include "gssapi_err_generic.h"
+#ifndef _KERNEL
+#include <errno.h>
 #else
-#ifdef HAVE_STDLIB_H
-#ifndef _KERNEL
-#include <stdlib.h>
+#include <sys/errno.h>
 #endif /* !_KERNEL */
-#endif /* HAVE_STDLIB_H */
-#endif
 
-#include <mechglueP.h>
-#include <gssapi/gssapi_ext.h>
-#include <gssapi/gssapi.h>
-#include "gssapi_generic.h"
-#include "gssapi_err_generic.h"
-#ifdef  _KERNEL
-#include <sys/errno.h>
-#else
-#include <errno.h>
-#endif
+#include "k5-platform.h"
+typedef UINT64_TYPE gssint_uint64;
+
+#include "gssapi/gssapi_ext.h"
 
 /** helper macros **/
 
-typedef uint64_t gssint_uint64;
-
-#if 0 	/* this is defined in usr/src/uts/common/gssapi/gssapi_ext.h */
-#define g_OID_equal(o1,o2) \
-   (((o1)->length == (o2)->length) && \
-    (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0))
+#if 0 /* SUNW15resync - on Solaris g_OID_equal is in gssapi_ext.h */
+#define	g_OID_equal(o1, o2) \
+	(((o1)->length == (o2)->length) && \
+	(memcmp((o1)->elements, (o2)->elements, (o1)->length) == 0))
 #endif
 
 /* this code knows that an int on the wire is 32 bits.  The type of
@@ -102,7 +98,7 @@
    (ptr) += 2;
 
 #define TWRITE_STR(ptr, str, len) \
-   (void) memcpy((ptr), (char *) (str), (len)); \
+  (void) memcpy((ptr), (char *) (str), (len));	\
    (ptr) += (len);
 
 #define TREAD_STR(ptr, str, len) \
@@ -135,39 +131,80 @@
 
 /** helper functions **/
 
-typedef struct _g_set *g_set;
-
-int g_set_init (g_set *s);
-int g_set_destroy (g_set *s);
-int g_set_entry_add (g_set *s, void *key, void *value);
-int g_set_entry_delete (g_set *s, void *key);
-int g_set_entry_get (g_set *s, void *key, void **value);
+/* hide names from applications, especially glib applications */
+#define	g_set_init		gssint_g_set_init
+#define	g_set_destroy		gssint_g_set_destroy
+#define	g_set_entry_add		gssint_g_set_entry_add
+#define	g_set_entry_delete	gssint_g_set_entry_delete
+#define	g_set_entry_get		gssint_g_set_entry_get
+#define	g_save_name		gssint_g_save_name
+#define	g_save_cred_id		gssint_g_save_cred_id
+#define	g_save_ctx_id		gssint_g_save_ctx_id
+#define	g_save_lucidctx_id	gssint_g_save_lucidctx_id
+#define	g_validate_name		gssint_g_validate_name
+#define	g_validate_cred_id	gssint_g_validate_cred_id
+#define	g_validate_ctx_id	gssint_g_validate_ctx_id
+#define	g_validate_lucidctx_id	gssint_g_validate_lucidctx_id
+#define	g_delete_name		gssint_g_delete_name
+#define	g_delete_cred_id	gssint_g_delete_cred_id
+#define	g_delete_ctx_id		gssint_g_delete_ctx_id
+#define	g_delete_lucidctx_id	gssint_g_delete_lucidctx_id
+#define	g_make_string_buffer	gssint_g_make_string_buffer
+#define	g_token_size		gssint_g_token_size
+#define	g_make_token_header	gssint_g_make_token_header
+#define	g_verify_token_header	gssint_g_verify_token_header
+#define	g_display_major_status	gssint_g_display_major_status
+#define	g_display_com_err_status gssint_g_display_com_err_status
+#define	g_order_init		gssint_g_order_init
+#define	g_order_check		gssint_g_order_check
+#define	g_order_free		gssint_g_order_free
+#define	g_queue_size		gssint_g_queue_size
+#define	g_queue_externalize	gssint_g_queue_externalize
+#define	g_queue_internalize	gssint_g_queue_internalize
+#define	g_canonicalize_host	gssint_g_canonicalize_host
+#define	g_local_host_name	gssint_g_local_host_name
+#define	g_strdup		gssint_g_strdup
 
-int g_save_name (void **vdb, gss_name_t name);
-int g_save_cred_id (void **vdb, gss_cred_id_t cred);
-int g_save_ctx_id (void **vdb, gss_ctx_id_t ctx);
+typedef struct _g_set_elt *g_set_elt;
+typedef struct {
+    k5_mutex_t mutex;
+    void *data;
+} g_set;
+#define G_SET_INIT { K5_MUTEX_PARTIAL_INITIALIZER, 0 }
+
+int g_set_init (g_set_elt *s);
+int g_set_destroy (g_set_elt *s);
+int g_set_entry_add (g_set_elt *s, void *key, void *value);
+int g_set_entry_delete (g_set_elt *s, void *key);
+int g_set_entry_get (g_set_elt *s, void *key, void **value);
 
-int g_validate_name (void **vdb, gss_name_t name);
-int g_validate_cred_id (void **vdb, gss_cred_id_t cred);
-int g_validate_ctx_id (void **vdb, gss_ctx_id_t ctx);
+int g_save_name (g_set *vdb, gss_name_t name);
+int g_save_cred_id (g_set *vdb, gss_cred_id_t cred);
+int g_save_ctx_id (g_set *vdb, gss_ctx_id_t ctx);
+int g_save_lucidctx_id (g_set *vdb, void *lctx);
 
-int g_delete_name (void **vdb, gss_name_t name);
-int g_delete_cred_id (void **vdb, gss_cred_id_t cred);
-int g_delete_ctx_id (void **vdb, gss_ctx_id_t ctx);
+int g_validate_name (g_set *vdb, gss_name_t name);
+int g_validate_cred_id (g_set *vdb, gss_cred_id_t cred);
+int g_validate_ctx_id (g_set *vdb, gss_ctx_id_t ctx);
+int g_validate_lucidctx_id (g_set *vdb, void *lctx);
+
+int g_delete_name (g_set *vdb, gss_name_t name);
+int g_delete_cred_id (g_set *vdb, gss_cred_id_t cred);
+int g_delete_ctx_id (g_set *vdb, gss_ctx_id_t ctx);
+int g_delete_lucidctx_id (g_set *vdb, void *lctx);
 
 int g_make_string_buffer (const char *str, gss_buffer_t buffer);
 
-int g_copy_OID_set (const gss_OID_set_desc * const in, gss_OID_set *out);
+unsigned int g_token_size (const gss_OID_desc * mech, unsigned int body_size);
 
-int g_token_size (gss_OID mech, unsigned int body_size);
-
-void g_make_token_header (gss_OID mech, int body_size,
+void g_make_token_header (const gss_OID_desc * mech, unsigned int body_size,
 			  unsigned char **buf, int tok_type);
 
-gss_int32 g_verify_token_header (gss_OID mech, unsigned int *body_size,
-                                 unsigned char **buf, int tok_type,
-                                 unsigned int toksize_in,
-                                 int wrapper_required);
+gss_int32 g_verify_token_header (const gss_OID_desc * mech, 
+				 unsigned int *body_size,
+				 unsigned char **buf, int tok_type, 
+				 unsigned int toksize_in,
+				 int wrapper_required);
 
 OM_uint32 g_display_major_status (OM_uint32 *minor_status,
 				 OM_uint32 status_value,
@@ -179,7 +216,7 @@
 				   gss_buffer_t status_string);
 
 gss_int32 g_order_init (void **queue, gssint_uint64 seqnum,
-                                  int do_replay, int do_sequence, int wide);
+				  int do_replay, int do_sequence, int wide);
 
 gss_int32 g_order_check (void **queue, gssint_uint64 seqnum);
 
@@ -191,12 +228,61 @@
 gss_uint32 g_queue_internalize(void **vqueue, unsigned char **buf,
 			       size_t *lenremain);
 
-char *g_local_host_name (void);
-
 char *g_strdup (char *str);
 
-#ifdef __cplusplus
-}
-#endif
+/** declarations of internal name mechanism functions **/
+
+#if 0 /* SUNW15resync - mved to mglueP.h for sake of non-krb5 mechs */
+OM_uint32 generic_gss_release_buffer
+(OM_uint32*,       /* minor_status */
+            gss_buffer_t      /* buffer */
+           );
+
+OM_uint32 generic_gss_release_oid_set
+(OM_uint32*,       /* minor_status */
+            gss_OID_set*      /* set */
+           );
+
+OM_uint32 generic_gss_release_oid
+(OM_uint32*,       /* minor_status */
+            gss_OID*         /* set */
+           );
+
+OM_uint32 generic_gss_copy_oid
+(OM_uint32 *,	/* minor_status */
+            gss_OID_desc * const,   /* oid */ /* SUNW15resync */
+	    gss_OID *		/* new_oid */
+	    );
+
+OM_uint32 generic_gss_create_empty_oid_set
+(OM_uint32 *,	/* minor_status */
+	    gss_OID_set *	/* oid_set */
+	   );
+
+OM_uint32 generic_gss_add_oid_set_member
+(OM_uint32 *,	/* minor_status */
+	    gss_OID_desc * const,		/* member_oid */
+	    gss_OID_set *	/* oid_set */
+	   );
+
+OM_uint32 generic_gss_test_oid_set_member
+(OM_uint32 *,	/* minor_status */
+	    gss_OID_desc * const,		/* member */
+	    gss_OID_set,	/* set */
+	    int *		/* present */
+	   );
+
+OM_uint32 generic_gss_oid_to_str
+(OM_uint32 *,	/* minor_status */
+	    gss_OID_desc * const,		/* oid */
+	    gss_buffer_t	/* oid_str */
+	   );
+
+OM_uint32 generic_gss_str_to_oid
+(OM_uint32 *,	/* minor_status */
+	    gss_buffer_t,	/* oid_str */
+	    gss_OID *		/* oid */
+	   );
+#endif /* 0 */
 
 #endif /* _GSSAPIP_GENERIC_H_ */
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_krb5.h	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_krb5.h	Fri Sep 14 15:01:24 2007 -0700
@@ -1,8 +1,10 @@
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
 /*
  * Copyright 2000 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
@@ -47,70 +49,49 @@
  * 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.
- *
  */
 
-#ifndef _GSSAPIP_KRB5_H
-#define	_GSSAPIP_KRB5_H
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
+#ifndef _GSSAPIP_KRB5_H_
+#define _GSSAPIP_KRB5_H_
 
-/*
- * $Id:	gssapiP_krb5.h,v 1.40.6.2 2000/05/31 17:17:38 raeburn Exp $
- */
+#include <k5-int.h>
 
-#include <mechglueP.h>
-#include <krb5.h>
-#ifndef _KERNEL
+#ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
 
-/*
- * Solaris defines the minor() and major() macros for device numbers.
- * Undefine them here so we don't cause confusion for the minor
- * and major error numbers.
- */
-#ifdef	major
-#undef	major
+/* work around sunos braindamage */
+#ifdef major
+#undef major
 #endif
-#ifdef	minor
-#undef	minor
+#ifdef minor
+#undef minor
 #endif
 
 #include "gssapiP_generic.h"
 
-#ifndef	_KERNEL
-#ifdef DEBUG_ON
-
-#define	dprintf(a) printf(a)
-#define	dprintf1(a, b) printf(a, b)
-
-#else
-
-#define	dprintf(a)
-#define	dprintf1(a, b)
-#define	DUMMY_STATIC
-
-#endif	/* DEBUG_ON */
-
-#else	/* _KERNEL */
-
-#define	dprintf(a)	KRB5_LOG0(KRB5_INFO, a)
-#define	dprintf1(a, b)	KRB5_LOG(KRB5_INFO, a, b)
-#define	DUMMY_STATIC	static
-
-#endif	/* _KERNEL */
-
 /* The include of gssapi_krb5.h will dtrt with the above #defines in
  * effect.
  */
+#include "gssapi_krb5.h"
+#include "gssapi_err_krb5.h"
 
-#include <gssapi_krb5.h>
-#include <gssapi_err_krb5.h>
-#include <sys/systm.h>
+/* for debugging */
+#undef CFX_EXERCISE
 
 /** constants **/
 
+#define GSS_MECH_KRB5_OID_LENGTH 9
+#define GSS_MECH_KRB5_OID "\052\206\110\206\367\022\001\002\002"
+
+#define GSS_MECH_KRB5_OLD_OID_LENGTH 5
+#define GSS_MECH_KRB5_OLD_OID "\053\005\001\005\002"
+
+/* Incorrect krb5 mech OID emitted by MS. */
+#define GSS_MECH_KRB5_WRONG_OID_LENGTH 9
+#define GSS_MECH_KRB5_WRONG_OID "\052\206\110\202\367\022\001\002\002"
+
+
 #define CKSUMTYPE_KG_CB		0x8003
 
 #define KG_TOK_CTX_AP_REQ	0x0100
@@ -140,14 +121,14 @@
   SGN_ALG_MD2_5                 = 0x0001,
   SGN_ALG_DES_MAC               = 0x0002,
   SGN_ALG_3			= 0x0003, /* not published */
-  SGN_ALG_HMAC_MD5              = 0x0011, /* microsoft w2k; no support */
+  SGN_ALG_HMAC_MD5              = 0x0011, /* microsoft w2k;  */
   SGN_ALG_HMAC_SHA1_DES3_KD     = 0x0004
 };
 enum seal_alg {
   SEAL_ALG_NONE            = 0xffff,
   SEAL_ALG_DES             = 0x0000,
   SEAL_ALG_1		   = 0x0001, /* not published */
-  SEAL_ALG_MICROSOFT_RC4   = 0x0010, /* microsoft w2k; no support */
+  SEAL_ALG_MICROSOFT_RC4   = 0x0010, /* microsoft w2k;  */
   SEAL_ALG_DES3KD          = 0x0002
 };
 
@@ -159,8 +140,8 @@
 /* for draft-ietf-krb-wg-gssapi-cfx-01 */
 #define KG_USAGE_ACCEPTOR_SEAL	22
 #define KG_USAGE_ACCEPTOR_SIGN	23
-#define KG_USAGE_INITIATOR_SEAL 24
-#define KG_USAGE_INITIATOR_SIGN 25
+#define KG_USAGE_INITIATOR_SEAL	24
+#define KG_USAGE_INITIATOR_SIGN	25
 
 enum qop {
   GSS_KRB5_INTEG_C_QOP_MD5       = 0x0001, /* *partial* MD5 = "MD2.5" */
@@ -178,11 +159,13 @@
 typedef krb5_principal krb5_gss_name_t;
 
 typedef struct _krb5_gss_cred_id_rec {
+   /* protect against simultaneous accesses */
+   k5_mutex_t lock;
+
    /* name/type of credential */
    gss_cred_usage_t usage;
    krb5_principal princ;	/* this is not interned as a gss_name_t */
-   const gss_OID_set_desc *actual_mechs;
-   int prerfc_mech;		/* these are a cache of the set above */
+   int prerfc_mech;
    int rfc_mech;
 
    /* keytab (accept) data */
@@ -192,6 +175,7 @@
    /* ccache (init) data */
    krb5_ccache ccache;
    krb5_timestamp tgt_expire;
+   krb5_enctype *req_enctypes;	/* limit negotiated enctypes to this list */
 } krb5_gss_cred_id_rec, *krb5_gss_cred_id_t; 
 
 typedef struct _krb5_gss_ctx_id_rec {
@@ -200,9 +184,6 @@
    unsigned int big_endian : 1;
    unsigned int have_acceptor_subkey : 1;
    unsigned int seed_init : 1;	/* XXX tested but never actually set */
-#ifdef CFX_EXERCISE
-   unsigned int testing_unknown_tokid : 1; /* for testing only */
-#endif
    OM_uint32 gss_flags;
    unsigned char seed[16];
    krb5_principal here;
@@ -221,202 +202,141 @@
    gssint_uint64 seq_send;
    gssint_uint64 seq_recv;
    void *seqstate;
+   krb5_context k5_context;
    krb5_auth_context auth_context;
-   /*
-    * SOLARIS KERBEROS:
-    * MIT uses a 'gss_OID_desc *' here, we do not use the pointer.
-    */
-   gss_OID_desc mech_used;
+   gss_OID_desc *mech_used;
     /* Protocol spec revision
-	0 => RFC 1964 with 3DES and RC4 enhancements
-	1 => draft-ietf-krb-wg-gssapi-cfx-01
-	No others defined so far.  */
+       0 => RFC 1964 with 3DES and RC4 enhancements
+       1 => draft-ietf-krb-wg-gssapi-cfx-01
+       No others defined so far.  */
    int proto;
    krb5_cksumtype cksumtype;	/* for "main" subkey */
    krb5_keyblock *acceptor_subkey; /* CFX only */
    krb5_cksumtype acceptor_subkey_cksumtype;
+   int cred_rcache;		/* did we get rcache from creds? */
 } krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t;
 
-extern void *kg_vdb;
+extern g_set kg_vdb;
 
-extern krb5_context kg_context;
-#ifdef _KERNEL
-extern kmutex_t	krb5_mutex;
-#else
-extern mutex_t	krb5_mutex;
-#endif
+extern k5_mutex_t gssint_krb5_keytab_lock;
 
 /* helper macros */
 
 #define kg_save_name(name)		g_save_name(&kg_vdb,name)
 #define kg_save_cred_id(cred)		g_save_cred_id(&kg_vdb,cred)
 #define kg_save_ctx_id(ctx)		g_save_ctx_id(&kg_vdb,ctx)
+#define kg_save_lucidctx_id(lctx)	g_save_lucidctx_id(&kg_vdb,lctx)
 
 #define kg_validate_name(name)		g_validate_name(&kg_vdb,name)
 #define kg_validate_cred_id(cred)	g_validate_cred_id(&kg_vdb,cred)
 #define kg_validate_ctx_id(ctx)		g_validate_ctx_id(&kg_vdb,ctx)
+#define kg_validate_lucidctx_id(lctx)	g_validate_lucidctx_id(&kg_vdb,lctx)
 
 #define kg_delete_name(name)		g_delete_name(&kg_vdb,name)
 #define kg_delete_cred_id(cred)		g_delete_cred_id(&kg_vdb,cred)
 #define kg_delete_ctx_id(ctx)		g_delete_ctx_id(&kg_vdb,ctx)
+#define kg_delete_lucidctx_id(lctx)	g_delete_lucidctx_id(&kg_vdb,lctx)
 
 /** helper functions **/
 
-OM_uint32 kg_get_defcred (
-	OM_uint32 *minor_status, 
-	gss_cred_id_t *cred);
+OM_uint32 kg_get_defcred 
+	(OM_uint32 *minor_status, 
+		   gss_cred_id_t *cred);
 
-OM_uint32 kg_release_defcred (OM_uint32 *minor_status);
-
-krb5_error_code kg_checksum_channel_bindings (
-	krb5_context context, gss_channel_bindings_t cb,
-	krb5_checksum *cksum,
-	int bigend);
+krb5_error_code kg_checksum_channel_bindings
+         (krb5_context context, gss_channel_bindings_t cb,
+					     krb5_checksum *cksum,
+					     int bigend);
 
-krb5_error_code kg_make_seq_num (
-	krb5_context context,
-	krb5_keyblock *key,
-	int direction, 
-	krb5_ui_4 seqnum,
-	unsigned char *cksum,
-	unsigned char *buf);
+krb5_error_code kg_make_seq_num (krb5_context context,
+					   krb5_keyblock *key,
+            int direction, krb5_ui_4 seqnum, unsigned char *cksum,
+				unsigned char *buf);
 
-krb5_error_code kg_get_seq_num (
-	krb5_context context,
-	krb5_keyblock *key,
-	unsigned char *cksum,
-	unsigned char *buf,
-	int *direction,
-	krb5_ui_4 *seqnum);
+krb5_error_code kg_get_seq_num (krb5_context context,
+					  krb5_keyblock *key,
+            unsigned char *cksum, unsigned char *buf, int *direction,
+					  krb5_ui_4 *seqnum);
 
-krb5_error_code kg_make_seed (
-	krb5_context context,
-	krb5_keyblock *key,
-	unsigned char *seed);
+krb5_error_code kg_make_seed (krb5_context context,
+					krb5_keyblock *key,
+					unsigned char *seed);
 
 int kg_confounder_size (krb5_context context, krb5_keyblock *key);
 
 krb5_error_code kg_make_confounder (krb5_context context, 
 	    krb5_keyblock *key, unsigned char *buf);
 
-int kg_encrypt_size (
-	krb5_context context,
-	krb5_keyblock *key, 
-	int n);
-
-krb5_error_code kg_encrypt (
-	krb5_context context, 
-	krb5_keyblock *key,
-	int usage,
-	krb5_pointer iv,
-	krb5_pointer in,
-	krb5_pointer out,
-	int length);
-
+krb5_error_code kg_encrypt (krb5_context context, 
+				      krb5_keyblock *key, int usage,
+				      krb5_pointer iv,
+				      krb5_pointer in,
+				      krb5_pointer out,
+				      unsigned int length);
 krb5_error_code
 kg_arcfour_docrypt (krb5_context,
-		const krb5_keyblock *longterm_key , int ms_usage,
-		const unsigned char *kd_data, size_t kd_data_len,
-		const unsigned char *input_buf, size_t input_len,
-		unsigned char *output_buf);
+		    const krb5_keyblock *longterm_key , int ms_usage,
+		    const unsigned char *kd_data, size_t kd_data_len,
+		    const unsigned char *input_buf, size_t input_len,
+		    unsigned char *output_buf);
 
 krb5_error_code kg_decrypt (krb5_context context,
-	krb5_keyblock *key,
-	int usage,
-	krb5_pointer iv,
-	krb5_pointer in,
-	krb5_pointer out,
-	int length);
+				      krb5_keyblock *key,  int usage,
+				      krb5_pointer iv,
+				      krb5_pointer in,
+				      krb5_pointer out,
+				      unsigned int length);
 
-OM_uint32 kg_seal (
-	krb5_context context,
-	OM_uint32 *minor_status,
-	gss_ctx_id_t context_handle,
-	int conf_req_flag,
-	int qop_req,
-	gss_buffer_t input_message_buffer,
-	int *conf_state,
-	gss_buffer_t output_message_buffer,
-	int toktype);
+OM_uint32 kg_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,
+		  int toktype);
 
-OM_uint32 kg_unseal (
-	krb5_context context,
-	OM_uint32 *minor_status,
-	gss_ctx_id_t context_handle,
-	gss_buffer_t input_token_buffer,
-	gss_buffer_t message_buffer,
-	int *conf_state,
-	int *qop_state,
-	int toktype);
+OM_uint32 kg_unseal (OM_uint32 *minor_status,
+		    gss_ctx_id_t context_handle,
+		    gss_buffer_t input_token_buffer,
+		    gss_buffer_t message_buffer,
+		    int *conf_state,
+		    int *qop_state,
+		    int toktype);
 
-OM_uint32 kg_seal_size (
-	krb5_context context,
-	OM_uint32 *minor_status,
-	gss_ctx_id_t context_handle,
-	int conf_req_flag,
-	gss_qop_t qop_req,
-	OM_uint32 output_size,
-	OM_uint32 *input_size);
+OM_uint32 kg_seal_size (OM_uint32 *minor_status,
+				  gss_ctx_id_t context_handle,
+				  int conf_req_flag,
+				  gss_qop_t qop_req,
+				  OM_uint32 output_size,
+				  OM_uint32 *input_size);
 
-krb5_error_code kg_ctx_size (
-	krb5_context kcontext,
-	krb5_pointer arg,
-	size_t *sizep);
+krb5_error_code kg_ctx_size (krb5_context kcontext,
+				       krb5_pointer arg,
+				       size_t *sizep);
 
-krb5_error_code kg_ctx_externalize (
-	krb5_context kcontext,
-	krb5_pointer arg,
-	krb5_octet **buffer,
-	size_t *lenremain);
+krb5_error_code kg_ctx_externalize (krb5_context kcontext,
+					      krb5_pointer arg,
+					      krb5_octet **buffer,
+					      size_t *lenremain);
 
-krb5_error_code kg_ctx_internalize (
-	krb5_context kcontext,
-	krb5_pointer *argp,
-	krb5_octet **buffer,
-	size_t *lenremain);
+krb5_error_code kg_ctx_internalize (krb5_context kcontext,
+					      krb5_pointer *argp,
+					      krb5_octet **buffer,
+					      size_t *lenremain);
 
-OM_uint32 kg_get_context (
-	OM_uint32 *minor_status,
-	krb5_context *context);
+OM_uint32 kg_sync_ccache_name (krb5_context context, OM_uint32 *minor_status);
 
-OM_uint32 kg_sync_ccache_name (OM_uint32 *minor_status);
-
-OM_uint32 kg_get_ccache_name (OM_uint32 *minor_status,
+OM_uint32 kg_get_ccache_name (OM_uint32 *minor_status, 
                               const char **out_name);
 
-OM_uint32 kg_set_ccache_name (OM_uint32 *minor_status,
+OM_uint32 kg_set_ccache_name (OM_uint32 *minor_status, 
                               const char *name);
 
-struct kg2_option {
-    int option_id;		/* set by caller */
-    int length;			/* filled in by parser */
-    unsigned char *data;	/* filled in by parser.  points inside
-				   passed-in token, so nothing needs to
-				   be freed */
-};
-
-OM_uint32
-kg2_parse_token (OM_uint32 *minor_status,
-			   unsigned char *ptr,
-			   int length,
-			   krb5_ui_4 *flags,
-			   int *nctypes, /* OUT */
-			   krb5_cksumtype **ctypes, /* OUT */
-			   int noptions,
-			   struct kg2_option *options, /* INOUT */
-			   krb5_data *kmsg,
-			   krb5_data *mic);
-
-void kg2_intersect_ctypes (int *nc1, 
-		     krb5_cksumtype *c1,
-		     int nc2,
-		     const krb5_cksumtype *c2);
-
 /** declarations of internal name mechanism functions **/
 
-OM_uint32 krb5_gss_acquire_cred (
-	    void *,		/* krb5 context */
-       	    OM_uint32*,       /* minor_status */
+OM_uint32 krb5_gss_acquire_cred
+(OM_uint32*,       /* minor_status */
             gss_name_t,       /* desired_name */
             OM_uint32,        /* time_req */
             gss_OID_set,      /* desired_mechs */
@@ -426,57 +346,13 @@
             OM_uint32*        /* time_rec */
            );
 
-OM_uint32 krb5_gss_acquire_cred_no_lock (
-	    void *,		/* krb5 context */
-       	    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_cred_id_t*,   /* output_cred_handle */
-            gss_OID_set*,     /* actual_mechs */
-            OM_uint32*        /* time_rec */
-           );
-
-OM_uint32 krb5_gss_release_cred (
-	    void *,		/* krb5 context */
-	    OM_uint32*,       /* minor_status */
-            gss_cred_id_t*    /* cred_handle */
-           );
-
-OM_uint32 krb5_gss_release_cred_no_lock (
-	    void *,		/* krb5 context */
-	    OM_uint32*,       /* minor_status */
+OM_uint32 krb5_gss_release_cred
+(OM_uint32*,       /* minor_status */
             gss_cred_id_t*    /* cred_handle */
            );
 
-OM_uint32 krb5_gss_store_cred (
-	    void *,                 /* krb5 context */
-	    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 */
-	   );
-
-OM_uint32 krb5_gss_store_cred_no_lock (
-	    void *,                 /* krb5 context */
-	    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 */
-	   );
-
-OM_uint32 krb5_gss_init_sec_context (
-	    void *,		/* krb5 context */
-	    OM_uint32*,       /* minor_status */
+OM_uint32 krb5_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 */
@@ -492,9 +368,8 @@
             OM_uint32*        /* time_rec */
            );
 
-OM_uint32 krb5_gss_accept_sec_context (
-	    void *,		/* krb5 context */
-	    OM_uint32*,       /* minor_status */
+OM_uint32 krb5_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 */
@@ -508,68 +383,52 @@
             gss_cred_id_t*    /* delegated_cred_handle */
            );
 
-OM_uint32 krb5_gss_process_context_token (
-	    void *,		/* krb5 context */
-	    OM_uint32*,       /* minor_status */
+OM_uint32 krb5_gss_process_context_token
+(OM_uint32*,       /* minor_status */
             gss_ctx_id_t,     /* context_handle */
             gss_buffer_t      /* token_buffer */
            );
 
-OM_uint32 krb5_gss_delete_sec_context (
-	    void *,             /* krb5 context */
-            OM_uint32*,       /* minor_status */
+OM_uint32 krb5_gss_delete_sec_context
+(OM_uint32*,       /* minor_status */
             gss_ctx_id_t*,    /* context_handle */
             gss_buffer_t      /* output_token */
 #ifdef	_KERNEL
-	/* */, OM_uint32	/* context verifier */
+            /* */, OM_uint32	/* context verifier */
 #endif
-	);
+           );
 
-OM_uint32 krb5_gss_delete_sec_context_no_lock (
-	    void *,             /* krb5 context */
-            OM_uint32*,       /* minor_status */
-            gss_ctx_id_t*,    /* context_handle */
-            gss_buffer_t      /* output_token */
-#ifdef	_KERNEL
-	/* */, OM_uint32	/* context verifier */
-#endif
-	);
-
-OM_uint32 krb5_gss_context_time (
-	    void *,             /* krb5 context */
-            OM_uint32*,       /* minor_status */
+OM_uint32 krb5_gss_context_time
+(OM_uint32*,       /* minor_status */
             gss_ctx_id_t,     /* context_handle */
             OM_uint32*        /* time_rec */
            );
 
-OM_uint32 krb5_gss_sign (
-	    void *,             /* krb5 context */
-            OM_uint32*,       /* minor_status */
+OM_uint32 krb5_gss_sign
+(OM_uint32*,       /* minor_status */
             gss_ctx_id_t,     /* context_handle */
             int,              /* qop_req */
             gss_buffer_t,     /* message_buffer */
             gss_buffer_t      /* message_token */
 #ifdef	_KERNEL
-	/* */, OM_uint32	/* context verifier */
+            /* */, OM_uint32	/* context verifier */
 #endif
            );
 
-OM_uint32 krb5_gss_verify (
-	    void *,             /* krb5 context */
-            OM_uint32*,       /* minor_status */
+OM_uint32 krb5_gss_verify
+(OM_uint32*,       /* minor_status */
             gss_ctx_id_t,     /* context_handle */
             gss_buffer_t,     /* message_buffer */
             gss_buffer_t,     /* token_buffer */
             int*              /* qop_state */
 #ifdef	_KERNEL
-	/* */, OM_uint32	/* context verifier */
+            /* */, OM_uint32	/* context verifier */
 #endif
            );
 
 /* EXPORT DELETE START */
-OM_uint32 krb5_gss_seal (
-	    void *,             /* krb5 context */
-            OM_uint32*,       /* minor_status */
+OM_uint32 krb5_gss_seal
+(OM_uint32*,       /* minor_status */
             gss_ctx_id_t,     /* context_handle */
             int,              /* conf_req_flag */
             int,              /* qop_req */
@@ -577,27 +436,25 @@
             int*,             /* conf_state */
             gss_buffer_t      /* output_message_buffer */
 #ifdef	_KERNEL
-	/* */, OM_uint32	/* context verifier */
+            /* */, OM_uint32	/* context verifier */
 #endif
            );
 
-OM_uint32 krb5_gss_unseal (
-	    void *,             /* krb5 context */
-            OM_uint32*,       /* minor_status */
+OM_uint32 krb5_gss_unseal
+(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 */
 #ifdef	_KERNEL
-	/* */, OM_uint32	/* context verifier */
+            /* */, OM_uint32	/* context verifier */
 #endif
            );
 /* EXPORT DELETE END */
 
-OM_uint32 krb5_gss_display_status (
-	    void *,             /* krb5 context */
-            OM_uint32*,       /* minor_status */
+OM_uint32 krb5_gss_display_status
+(OM_uint32*,       /* minor_status */
             OM_uint32,        /* status_value */
             int,              /* status_type */
             gss_OID,          /* mech_type */
@@ -605,51 +462,39 @@
             gss_buffer_t      /* status_string */
            );
 
-OM_uint32 krb5_gss_indicate_mechs (
-	    void *,             /* krb5 context */
-            OM_uint32*,       /* minor_status */
+OM_uint32 krb5_gss_indicate_mechs
+(OM_uint32*,       /* minor_status */
             gss_OID_set*      /* mech_set */
            );
 
-OM_uint32 krb5_gss_compare_name (
-	    void *,             /* krb5 context */
-            OM_uint32*,       /* minor_status */
+OM_uint32 krb5_gss_compare_name
+(OM_uint32*,       /* minor_status */
             gss_name_t,       /* name1 */
             gss_name_t,       /* name2 */
             int*              /* name_equal */
            );
 
-OM_uint32 krb5_gss_display_name (
-	    void *,             /* krb5 context */
-            OM_uint32*,      /* minor_status */
+OM_uint32 krb5_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_gss_import_name (
-	    void *,             /* krb5 context */
-            OM_uint32*,       /* minor_status */
+OM_uint32 krb5_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_gss_release_name (
-	    void *,             /* krb5 context */
-            OM_uint32*,       /* minor_status */
+OM_uint32 krb5_gss_release_name
+(OM_uint32*,       /* minor_status */
             gss_name_t*       /* input_name */
            );
 
-OM_uint32 krb5_gss_release_name_no_lock (
-	    void *,             /* krb5 context */
-            OM_uint32*,       /* minor_status */
-            gss_name_t*       /* input_name */
-           );
-
-OM_uint32 krb5_gss_inquire_cred (
-	    void *,             /* krb5 context */
-            OM_uint32 *,      /* minor_status */
+OM_uint32 krb5_gss_inquire_cred
+(OM_uint32 *,      /* minor_status */
             gss_cred_id_t,    /* cred_handle */
             gss_name_t *,     /* name */
             OM_uint32 *,      /* lifetime */
@@ -657,19 +502,8 @@
             gss_OID_set *     /* mechanisms */
            );
 
-OM_uint32 krb5_gss_inquire_cred_no_lock (
-	    void *,             /* krb5 context */
-            OM_uint32 *,      /* minor_status */
-            gss_cred_id_t,    /* cred_handle */
-            gss_name_t *,     /* name */
-            OM_uint32 *,      /* lifetime */
-            gss_cred_usage_t*,/* cred_usage */
-            gss_OID_set *     /* mechanisms */
-           );
-
-OM_uint32 krb5_gss_inquire_context (
-	    void *,             /* krb5 context */
-            OM_uint32*,       /* minor_status */
+OM_uint32 krb5_gss_inquire_context
+(OM_uint32*,       /* minor_status */
 	    gss_ctx_id_t,     /* context_handle */
 	    gss_name_t*,      /* initiator_name */
 	    gss_name_t*,      /* acceptor_name */
@@ -681,27 +515,24 @@
 	   );
 
 /* New V2 entry points */
-OM_uint32 krb5_gss_get_mic (
-	    void *,             /* krb5 context */
-            OM_uint32 *,		/* minor_status */
+OM_uint32 krb5_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_gss_verify_mic (
-	    void *,             /* krb5 context */
-            OM_uint32 *,		/* minor_status */
+OM_uint32 krb5_gss_verify_mic
+(OM_uint32 *,		/* minor_status */
 	    gss_ctx_id_t,		/* context_handle */
 	    gss_buffer_t,		/* message_buffer */
 	    gss_buffer_t,		/* message_token */
 	    gss_qop_t *			/* qop_state */
 	   );
 
-OM_uint32 krb5_gss_wrap (
-	    void *,             /* krb5 context */
-            OM_uint32 *,		/* minor_status */
+OM_uint32 krb5_gss_wrap
+(OM_uint32 *,		/* minor_status */
 	    gss_ctx_id_t,		/* context_handle */
 	    int,			/* conf_req_flag */
 	    gss_qop_t,			/* qop_req */
@@ -710,9 +541,8 @@
 	    gss_buffer_t		/* output_message_buffer */
 	   );
 
-OM_uint32 krb5_gss_unwrap (
-	    void *,             /* krb5 context */
-            OM_uint32 *,		/* minor_status */
+OM_uint32 krb5_gss_unwrap
+(OM_uint32 *,		/* minor_status */
 	    gss_ctx_id_t,		/* context_handle */
 	    gss_buffer_t,		/* input_message_buffer */
 	    gss_buffer_t,		/* output_message_buffer */
@@ -720,9 +550,8 @@
 	    gss_qop_t *			/* qop_state */
 	   );
 
-OM_uint32 krb5_gss_wrap_size_limit (
-	    void *,             /* krb5 context */
-            OM_uint32 *,		/* minor_status */
+OM_uint32 krb5_gss_wrap_size_limit
+(OM_uint32 *,		/* minor_status */
 	    gss_ctx_id_t,		/* context_handle */
 	    int,			/* conf_req_flag */
 	    gss_qop_t,			/* qop_req */
@@ -730,9 +559,22 @@
 	    OM_uint32 *			/* max_input_size */
 	   );
 
-OM_uint32 krb5_gss_add_cred (
-	    void *,		/* krb5 context */
-	    OM_uint32 *,		/* minor_status */
+OM_uint32 krb5_gss_import_name_object
+(OM_uint32 *,		/* minor_status */
+	    void *,			/* input_name */
+	    gss_OID,			/* input_name_type */
+	    gss_name_t *		/* output_name */
+	   );
+
+OM_uint32 krb5_gss_export_name_object
+(OM_uint32 *,		/* minor_status */
+	    gss_name_t,			/* input_name */
+	    gss_OID,			/* desired_name_type */
+	    void * *			/* output_name */
+	   );
+
+OM_uint32 krb5_gss_add_cred
+(OM_uint32 *,		/* minor_status */
 	    gss_cred_id_t,		/* input_cred_handle */
 	    gss_name_t,			/* desired_name */
 	    gss_OID,			/* desired_mech */
@@ -745,9 +587,8 @@
 	    OM_uint32 *			/* acceptor_time_rec */
 	   );
 
-OM_uint32 krb5_gss_inquire_cred_by_mech (
-	    void *,             /* krb5 context */
-            OM_uint32  *,		/* minor_status */
+OM_uint32 krb5_gss_inquire_cred_by_mech
+(OM_uint32  *,		/* minor_status */
 	    gss_cred_id_t,		/* cred_handle */
 	    gss_OID,			/* mech_type */
 	    gss_name_t *,		/* name */
@@ -756,104 +597,149 @@
 	    gss_cred_usage_t * 		/* cred_usage */
 	   );
 
-OM_uint32 krb5_gss_export_sec_context (
-	    void *,             /* krb5 context */
-            OM_uint32 *,		/* minor_status */
+OM_uint32 krb5_gss_export_sec_context
+(OM_uint32 *,		/* minor_status */
 	    gss_ctx_id_t *,		/* context_handle */
 	    gss_buffer_t		/* interprocess_token */
 	    );
 
-OM_uint32 krb5_gss_import_sec_context(
-	void *,             /* krb5 context */
-	OM_uint32 *,		/* minor_status */
-	gss_buffer_t,		/* interprocess_token */
-	gss_ctx_id_t *		/* context_handle */
-	);
+OM_uint32 krb5_gss_import_sec_context
+(OM_uint32 *,		/* minor_status */
+	    gss_buffer_t,		/* interprocess_token */
+	    gss_ctx_id_t *		/* context_handle */
+            /* Note no _KERNEL context verifier */
+	    );
 
-OM_uint32 krb5_gss_internal_release_oid (
-	    void *,			/* krb5 context  */
-	    OM_uint32 *,		/* minor_status */
+krb5_error_code krb5_gss_ser_init(krb5_context);
+
+OM_uint32 krb5_gss_release_oid
+(OM_uint32 *,		/* minor_status */
 	    gss_OID *			/* oid */
 	   );
 
-OM_uint32 krb5_gss_inquire_names_for_mech (
-	    void *,             /* krb5 context */
-            OM_uint32 *,		/* minor_status */
+OM_uint32 krb5_gss_internal_release_oid
+(OM_uint32 *,		/* minor_status */
+	    gss_OID *			/* oid */
+	   );
+
+OM_uint32 krb5_gss_inquire_names_for_mech
+(OM_uint32 *,		/* minor_status */
 	    gss_OID,			/* mechanism */
 	    gss_OID_set *		/* name_types */
 	   );
 
+/* SUNW15resync - XXX nullify? */
+OM_uint32 krb5_gss_canonicalize_name
+(OM_uint32  *,		/* minor_status */
+	    const gss_name_t,		/* input_name */
+	    const gss_OID,		/* mech_type */
+	    gss_name_t *		/* output_name */
+	 );
+	
+OM_uint32 krb5_gss_export_name
+(OM_uint32  *,		/* minor_status */
+	    const gss_name_t,		/* input_name */
+	    gss_buffer_t		/* exported_name */
+	 );
+
+OM_uint32 krb5_gss_duplicate_name
+(OM_uint32  *,		/* minor_status */
+	    const gss_name_t,		/* input_name */
+	    gss_name_t *		/* dest_name */
+	 );
+
+OM_uint32 krb5_gss_validate_cred
+(OM_uint32 *,		/* minor_status */
+	    gss_cred_id_t		/* cred */
+         );
+
+OM_uint32
+krb5_gss_validate_cred_1(OM_uint32 * /* minor_status */,
+			 gss_cred_id_t /* cred_handle */,
+			 krb5_context /* context */);
+
+gss_OID krb5_gss_convert_static_mech_oid(gss_OID oid);
+	
+krb5_error_code gss_krb5int_make_seal_token_v3(krb5_context,
+					       krb5_gss_ctx_id_rec *,
+					       const gss_buffer_desc *,
+					       gss_buffer_t,
+					       int, int);
+
+OM_uint32 gss_krb5int_unseal_token_v3(krb5_context context,
+				      OM_uint32 *minor_status,
+				      krb5_gss_ctx_id_rec *ctx,
+				      unsigned char *ptr, int bodysize,
+				      gss_buffer_t message_buffer,
+				      int *conf_state, int *qop_state, 
+				      int toktype);
+
+/*
+ * SUNW15resync
+ * Solaris specific interfaces start
+ */
+
+OM_uint32 krb5_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 */
+	   );
+
 OM_uint32 krb5_pname_to_uid(
-		void *,			/* krb5 context */
 		OM_uint32 *,		/* minor status */
 		const gss_name_t,	/* pname */
 		uid_t *			/* uidOUt */
 		);
 
 OM_uint32 krb5_gss_userok(
-	void *,			/* krb5 context */
 	OM_uint32 *,		/* minor status */
 	const gss_name_t,	/* remote user principal name */
 	const char *,		/* local unix user name */
 	int *			/* remote user ok to login w/out pw? */
 	);
 
-/* Solaris Kerberos:  use gss_canonicalize_name() from /usr/src/lib/libgss
- * or define a wrapper in mechglue
+
+/*
+ * SUNW15resync
+ * Solaris specific interfaces end
  */
-#if 0
-OM_uint32 krb5_gss_canonicalize_name
- (OM_uint32  *,		/* minor_status */
-	    const gss_name_t,		/* input_name */
-	    const gss_OID,		/* mech_type */
-	    gss_name_t *		/* output_name */
-	 );
-#endif
-	
-OM_uint32 krb5_gss_export_name (
-	    OM_uint32  *,		/* minor_status */
-	    const gss_name_t,		/* input_name */
-	    gss_buffer_t		/* exported_name */
-	 );
+
 
-OM_uint32 krb5_gss_duplicate_name (
-	    OM_uint32  *,		/* minor_status */
-	    const gss_name_t,		/* input_name */
-	    gss_name_t *		/* dest_name */
-	 );
+/*
+ * These take unglued krb5-mech-specific contexts.
+ */
 
-OM_uint32 krb5_gss_validate_cred (
-	    void *,		/* krb5 context  */
-	    OM_uint32 *,		/* minor_status */
-	    gss_cred_id_t		/* cred */
-         );
+OM_uint32 KRB5_CALLCONV gss_krb5int_get_tkt_flags 
+	(OM_uint32 *minor_status,
+		   gss_ctx_id_t context_handle,
+		   krb5_flags *ticket_flags);
 
-OM_uint32 krb5_gss_validate_cred_no_lock (
-	    void *,		/* krb5 context  */
-	    OM_uint32 *,		/* minor_status */
-	    gss_cred_id_t		/* cred */
-         );
+OM_uint32 KRB5_CALLCONV gss_krb5int_copy_ccache
+	(OM_uint32 *minor_status,
+		   gss_cred_id_t cred_handle,
+		   krb5_ccache out_ccache);
 
-gss_OID_desc krb5_gss_convert_static_mech_oid (
-	    gss_OID oid
-	 );
+OM_uint32 KRB5_CALLCONV
+gss_krb5int_set_allowable_enctypes(OM_uint32 *minor_status, 
+				   gss_cred_id_t cred,
+				   OM_uint32 num_ktypes,
+				   krb5_enctype *ktypes);
 
-krb5_error_code gss_krb5int_make_seal_token_v3(krb5_context,
-		krb5_gss_ctx_id_rec *,
-		const gss_buffer_desc *,
-		gss_buffer_t,
-		int, int
-	);
+OM_uint32 KRB5_CALLCONV
+gss_krb5int_export_lucid_sec_context(OM_uint32 *minor_status,
+				     gss_ctx_id_t *context_handle,
+				     OM_uint32 version,
+				     void **kctx);
+
 
-OM_uint32
-gss_krb5int_unseal_token_v3(krb5_context,
-		OM_uint32 *,
-		krb5_gss_ctx_id_rec *,
-		unsigned char *,
-		int bodysize,
-		gss_buffer_t message_buffer,
-		int *conf_state,
-		int *qop_state,
-		int toktype);
+extern k5_mutex_t kg_kdc_flag_mutex;
+krb5_error_code krb5_gss_init_context (krb5_context *ctxp);
 
-#endif	/* _GSSAPIP_KRB5_H */
+krb5_error_code krb5_gss_use_kdc_context(void);
+
+#endif /* _GSSAPIP_KRB5_H_ */
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_err_krb5.h	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_err_krb5.h	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2002 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -26,6 +26,7 @@
 #define KG_BAD_SEQ                               (39756043L)
 #define KG_EMPTY_CCACHE                          (39756044L)
 #define KG_NO_CTYPES                             (39756045L)
+#define KG_LUCID_VERSION                         (39756046L)
 #define ERROR_TABLE_BASE_k5g (39756032L)
 
 /* for compatibility with older versions... */
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_krb5.h	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_krb5.h	Fri Sep 14 15:01:24 2007 -0700
@@ -1,11 +1,13 @@
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
 /*
  * Copyright 1993 by OpenVision Technologies, 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
@@ -15,7 +17,7 @@
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
- *
+ * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -28,41 +30,70 @@
 #ifndef _GSSAPI_KRB5_H_
 #define _GSSAPI_KRB5_H_
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-#include <krb5.h>
 #include <gssapi/gssapi.h>
 #include <gssapi/gssapi_ext.h>
-#include <gssapi_err_generic.h>
+#include <krb5.h>
+
+/* SUNW15resync */
+#ifndef GSS_DLLIMP
+#define GSS_DLLIMP
+#endif
 
 /* C++ friendlyness */
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
-#if !defined(PROTOTYPE)
-#define     PROTOTYPE(x) x
-#endif
+/* Reserved static storage for GSS_oids.  See rfc 1964 for more details. */
+
+/* 2.1.1. Kerberos Principal Name Form: */
+GSS_DLLIMP extern const gss_OID_desc * const GSS_KRB5_NT_PRINCIPAL_NAME;
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * krb5(2) krb5_name(1)}.  The recommended symbolic name for this type
+ * is "GSS_KRB5_NT_PRINCIPAL_NAME". */
+
+/* 2.1.2. Host-Based Service Name Form */
+#define GSS_KRB5_NT_HOSTBASED_SERVICE_NAME GSS_C_NT_HOSTBASED_SERVICE
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) service_name(4)}.  The previously recommended symbolic
+ * name for this type is "GSS_KRB5_NT_HOSTBASED_SERVICE_NAME".  The
+ * currently preferred symbolic name for this type is
+ * "GSS_C_NT_HOSTBASED_SERVICE". */
+
+/* 2.2.1. User Name Form */
+#define GSS_KRB5_NT_USER_NAME GSS_C_NT_USER_NAME    
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) user_name(1)}.  The recommended symbolic name for this
+ * type is "GSS_KRB5_NT_USER_NAME". */
 
-extern const gss_OID_desc * const gss_mech_krb5;
-extern const gss_OID_desc * const gss_mech_krb5_old;
-extern const gss_OID_desc * const gss_mech_krb5_v2;
-extern const gss_OID_set_desc * const gss_mech_set_krb5;
-extern const gss_OID_set_desc * const gss_mech_set_krb5_old;
-extern const gss_OID_set_desc * const gss_mech_set_krb5_both;
-extern const gss_OID_set_desc * const gss_mech_set_krb5_v2;
-extern const gss_OID_set_desc * const gss_mech_set_krb5_v1v2;
+/* 2.2.2. Machine UID Form */
+#define GSS_KRB5_NT_MACHINE_UID_NAME GSS_C_NT_MACHINE_UID_NAME
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) machine_uid_name(2)}.  The recommended symbolic name for
+ * this type is "GSS_KRB5_NT_MACHINE_UID_NAME". */
 
-extern const gss_OID_desc * const gss_nt_krb5_name;
-extern const gss_OID_desc * const gss_nt_krb5_principal;
+/* 2.2.3. String UID Form */
+#define GSS_KRB5_NT_STRING_UID_NAME GSS_C_NT_STRING_UID_NAME
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) string_uid_name(3)}.  The recommended symbolic name for
+ * this type is "GSS_KRB5_NT_STRING_UID_NAME". */ 
 
-/* Added name type definitions - declared in gen_oids.c */
-extern gss_OID gss_nt_user_name;
-extern gss_OID gss_nt_machine_uid_name;
-extern gss_OID gss_nt_string_uid_name;
-extern gss_OID gss_nt_service_name;
+GSS_DLLIMP extern const gss_OID_desc * const gss_mech_krb5;
+GSS_DLLIMP extern const gss_OID_desc * const gss_mech_krb5_old;
+GSS_DLLIMP extern const gss_OID_desc * const gss_mech_krb5_wrong;
+GSS_DLLIMP extern const gss_OID_set_desc * const gss_mech_set_krb5;
+GSS_DLLIMP extern const gss_OID_set_desc * const gss_mech_set_krb5_old;
+GSS_DLLIMP extern const gss_OID_set_desc * const gss_mech_set_krb5_both;
 
-extern const gss_OID_desc krb5_gss_oid_array[];
+GSS_DLLIMP extern const gss_OID_desc * const gss_nt_krb5_name;
+GSS_DLLIMP extern const gss_OID_desc * const gss_nt_krb5_principal;
+
+GSS_DLLIMP extern const gss_OID_desc krb5_gss_oid_array[];
 
 #define gss_krb5_nt_general_name	gss_nt_krb5_name
 #define gss_krb5_nt_principal		gss_nt_krb5_principal
@@ -71,13 +102,95 @@
 #define gss_krb5_nt_machine_uid_name	gss_nt_machine_uid_name
 #define gss_krb5_nt_string_uid_name	gss_nt_string_uid_name
 
-OM_uint32 KRB5_CALLCONV gss_krb5_get_tkt_flags
+
+#if defined(_WIN32)
+typedef  unsigned __int64 gss_uint64;
+#else /*windows*/
+
+#ifdef _KERNEL
+#include <sys/inttypes.h>
+#else /* _KERNEL */
+#include <inttypes.h>
+#endif /* _KERNEL */
+
+typedef  uint64_t gss_uint64;
+#endif
+
+
+typedef struct gss_krb5_lucid_key {
+	OM_uint32	type;		/* key encryption type */
+	OM_uint32	length;		/* length of key data */
+	void *		data;		/* actual key data */
+} gss_krb5_lucid_key_t;
+
+typedef struct gss_krb5_rfc1964_keydata {
+	OM_uint32	sign_alg;	/* signing algorthm */
+	OM_uint32	seal_alg;	/* seal/encrypt algorthm */
+	gss_krb5_lucid_key_t	ctx_key;
+					/* Context key
+					   (Kerberos session key or subkey) */
+} gss_krb5_rfc1964_keydata_t;
+
+typedef struct gss_krb5_cfx_keydata {
+	OM_uint32		have_acceptor_subkey;
+					/* 1 if there is an acceptor_subkey
+					   present, 0 otherwise */
+	gss_krb5_lucid_key_t	ctx_key;
+					/* Context key
+					   (Kerberos session key or subkey) */
+	gss_krb5_lucid_key_t	acceptor_subkey;
+					/* acceptor-asserted subkey or
+					   0's if no acceptor subkey */
+} gss_krb5_cfx_keydata_t;
+
+typedef struct gss_krb5_lucid_context_v1 {
+	OM_uint32	version;	/* Structure version number (1)
+					   MUST be at beginning of struct! */
+	OM_uint32	initiate;	/* Are we the initiator? */
+	OM_uint32	endtime;	/* expiration time of context */
+	gss_uint64	send_seq;	/* sender sequence number */
+	gss_uint64	recv_seq;	/* receive sequence number */
+	OM_uint32	protocol;	/* 0: rfc1964,
+					   1: draft-ietf-krb-wg-gssapi-cfx-07 */
+	/*
+	 * if (protocol == 0) rfc1964_kd should be used
+	 * and cfx_kd contents are invalid and should be zero
+	 * if (protocol == 1) cfx_kd should be used
+	 * and rfc1964_kd contents are invalid and should be zero
+	 */
+	gss_krb5_rfc1964_keydata_t rfc1964_kd;
+	gss_krb5_cfx_keydata_t	   cfx_kd;
+} gss_krb5_lucid_context_v1_t;
+
+/*
+ * Mask for determining the returned structure version.
+ * See example below for usage.
+ */
+typedef struct gss_krb5_lucid_context_version {
+	OM_uint32	version;	/* Structure version number */
+} gss_krb5_lucid_context_version_t;
+
+
+
+
+/* Alias for Heimdal compat. */
+#define gsskrb5_register_acceptor_identity krb5_gss_register_acceptor_identity
+
+OM_uint32 KRB5_CALLCONV krb5_gss_register_acceptor_identity(const char *);
+
+  /*
+   * SUNW15resync
+   * The name has changed (_krb5_ to _krb5int_) in MIT's
+   * get_tkt_flags.c but did not change here
+   * ...a bug I assume so we change it here.
+   */
+OM_uint32 KRB5_CALLCONV gss_krb5int_get_tkt_flags 
 	(OM_uint32 *minor_status,
 		   gss_ctx_id_t context_handle,
 		   krb5_flags *ticket_flags);
 
 OM_uint32 KRB5_CALLCONV gss_krb5_copy_ccache
-	(void *ctx, OM_uint32 *minor_status,
+	(OM_uint32 *minor_status,
 		   gss_cred_id_t cred_handle,
 		   krb5_ccache out_ccache);
 
@@ -85,6 +198,98 @@
 	(OM_uint32 *minor_status, const char *name,
 		   const char **out_name);
 
+/*
+ * gss_krb5_set_allowable_enctypes
+ *
+ * This function may be called by a context initiator after calling
+ * gss_acquire_cred(), but before calling gss_init_sec_context(),
+ * to restrict the set of enctypes which will be negotiated during
+ * context establishment to those in the provided array.
+ *
+ * 'cred' must be a valid credential handle obtained via
+ * gss_acquire_cred().  It may not be GSS_C_NO_CREDENTIAL.
+ * gss_acquire_cred() may have been called to get a handle to
+ * the default credential.
+ *
+ * The purpose of this function is to limit the keys that may
+ * be exported via gss_krb5_export_lucid_sec_context(); thus it
+ * should limit the enctypes of all keys that will be needed
+ * after the security context has been established.
+ * (i.e. context establishment may use a session key with a
+ * stronger enctype than in the provided array, however a
+ * subkey must be established within the enctype limits
+ * established by this function.)
+ *
+ */
+OM_uint32 KRB5_CALLCONV
+gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status, 
+				gss_cred_id_t cred,
+				OM_uint32 num_ktypes,
+				krb5_enctype *ktypes);
+
+/*
+ * Returns a non-opaque (lucid) version of the internal context
+ * information.  
+ *
+ * Note that context_handle must not be used again by the caller
+ * after this call.  The GSS implementation is free to release any
+ * resources associated with the original context.  It is up to the
+ * GSS implementation whether it returns pointers to existing data,
+ * or copies of the data.  The caller should treat the returned
+ * lucid context as read-only.
+ * 
+ * The caller must call gss_krb5_free_lucid_context() to free
+ * the context and allocated resources when it is finished with it.
+ *
+ * 'version' is an integer indicating the highest version of lucid
+ * context understood by the caller.  The highest version
+ * understood by both the caller and the GSS implementation must
+ * be returned.  The caller can determine which version of the
+ * structure was actually returned by examining the version field
+ * of the returned structure.  gss_krb5_lucid_context_version_t
+ * may be used as a mask to examine the returned structure version.
+ *
+ * If there are no common versions, an error should be returned.
+ * (XXX Need error definition(s))
+ *
+ * For example:
+ *	void *return_ctx;
+ *	gss_krb5_lucid_context_v1_t *ctx;
+ *	OM_uint32 min_stat, maj_stat;
+ *	OM_uint32 vers;
+ *	gss_ctx_id_t *ctx_handle;
+ *
+ *	maj_stat = gss_krb5_export_lucid_sec_context(&min_stat,
+ *			ctx_handle, 1, &return_ctx);
+ *	// Verify success 
+ *
+ *	vers = ((gss_krb5_lucid_context_version_t *)return_ctx)->version;
+ *	switch (vers) {
+ *	case 1:
+ *		ctx = (gss_krb5_lucid_context_v1_t *) return_ctx;
+ *		break;
+ *	default:
+ *		// Error, unknown version returned
+ *		break;
+ *	}
+ *
+ */
+
+OM_uint32 KRB5_CALLCONV
+gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status,
+				  gss_ctx_id_t *context_handle,
+				  OM_uint32 version,
+				  void **kctx);
+
+/*
+ * Frees the allocated storage associated with an
+ * exported struct gss_krb5_lucid_context.
+ */
+OM_uint32 KRB5_CALLCONV
+gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status,
+				void *kctx);
+
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h	Fri Sep 14 15:01:24 2007 -0700
@@ -6,44 +6,44 @@
 /*
  * Copyright (C) 1989,1990,1991,1992,1993,1994,1995,2000,2001, 2003,2006 by the Massachusetts Institute of Technology,
  * Cambridge, MA, USA.  All Rights Reserved.
- * 
- * This software is being provided to you, the LICENSEE, by the 
- * Massachusetts Institute of Technology (M.I.T.) under the following 
- * license.  By obtaining, using and/or copying this software, you agree 
- * that you have read, understood, and will comply with these terms and 
- * conditions:  
- * 
+ *
+ * This software is being provided to you, the LICENSEE, by the
+ * Massachusetts Institute of Technology (M.I.T.) under the following
+ * license.  By obtaining, using and/or copying this software, you agree
+ * that you have read, understood, and will comply with these terms and
+ * conditions:
+ *
  * 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 or 
- * royalty is hereby granted, provided that you agree to comply with the 
- * following copyright notice and statements, including the disclaimer, and 
- * that the same appear on ALL copies of the software and documentation, 
- * including modifications that you make for internal use or for 
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify and distribute
+ * this software and its documentation for any purpose and without fee or
+ * royalty is hereby granted, provided that you agree to comply with the
+ * following copyright notice and statements, including the disclaimer, and
+ * that the same appear on ALL copies of the software and documentation,
+ * including modifications that you make for internal use or for
  * distribution:
- * 
- * THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS 
- * OR WARRANTIES, EXPRESS OR IMPLIED.  By way of example, but not 
- * limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF 
- * MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF 
- * THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY 
- * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.   
- * 
- * The name of the Massachusetts Institute of Technology or M.I.T. may NOT 
- * be used in advertising or publicity pertaining to distribution of the 
- * software.  Title to copyright in this software and any associated 
- * documentation shall at all times remain with M.I.T., and USER agrees to 
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS
+ * OR WARRANTIES, EXPRESS OR IMPLIED.  By way of example, but not
+ * limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF
+ * MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF
+ * THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
+ * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+ *
+ * The name of the Massachusetts Institute of Technology or M.I.T. may NOT
+ * be used in advertising or publicity pertaining to distribution of the
+ * software.  Title to copyright in this software and any associated
+ * documentation shall at all times remain with M.I.T., and USER agrees to
  * preserve same.
  *
  * 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.  
+
  */
-
 /*
  * Copyright (C) 1998 by the FundsXpress, INC.
  *
@@ -2039,7 +2039,8 @@
     /* crypto stuff */
     const struct krb5_hash_provider *md5_hash_provider;
     const struct krb5_enc_provider *arcfour_enc_provider;
-    krb5_error_code (* krb5_hmac) (krb5_context context, const struct krb5_hash_provider *hash,
+	krb5_error_code (* krb5_hmac) (krb5_context,
+				   const struct krb5_hash_provider *hash,
                                    const krb5_keyblock *key,
                                    unsigned int icount, const krb5_data *input,
                                    krb5_data *output);
@@ -2290,6 +2291,7 @@
  * Use krb5_getuid() to select the mechanism to obtain the uid.
  */
 extern uid_t	krb5_getuid();
+
 /*
  * Referral definitions, debugging hooks, and subfunctions.
  */
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform.h	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform.h	Fri Sep 14 15:01:24 2007 -0700
@@ -430,4 +430,18 @@
     return ((UINT64_TYPE)load_32_le(p+4) << 32) | load_32_le(p);
 }
 
+
+/* Make the interfaces to getpwnam and getpwuid consistent.
+   Model the wrappers on the POSIX thread-safe versions, but
+   use the unsafe system versions if the safe ones don't exist
+   or we can't figure out their interfaces.  */
+/* SUNW15resync - just have Solaris relevant ones */
+
+#define k5_getpwnam_r(NAME, REC, BUF, BUFSIZE, OUT)  \
+         (*(OUT) = getpwnam_r(NAME,REC,BUF,BUFSIZE), *(OUT) == NULL ? -1 : 0)
+
+#define k5_getpwuid_r(UID, REC, BUF, BUFSIZE, OUT)  \
+        (*(OUT) = getpwuid_r(UID,REC,BUF,BUFSIZE), *(OUT) == NULL ? -1 : 0)
+
+
 #endif /* K5_PLATFORM_H */
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-thread.h	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-thread.h	Fri Sep 14 15:01:24 2007 -0700
@@ -37,9 +37,35 @@
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
-#ifndef _KERNEL   /* SUNW14resync, mimic k5-int.h ? */
+#ifdef _KERNEL
+
+#include <sys/ksynch.h>
+
+typedef kmutex_t k5_mutex_t;
+
+#define K5_MUTEX_PARTIAL_INITIALIZER {0}
+
+/* ARGSUSED */
+static void k5_mutex_assert_locked(k5_mutex_t *m) { }
+
+static int
+k5_mutex_lock(k5_mutex_t *m)
+{
+  mutex_enter(m);
+  return (0);
+}
+
+static int
+k5_mutex_unlock(k5_mutex_t *m)
+{
+  mutex_exit(m);
+  return(0);
+}
+
+
+#else /* _KERNEL */
+
 #include "autoconf.h"
-#endif
 
 #ifndef KRB5_CALLCONV
 # define KRB5_CALLCONV
@@ -789,4 +815,7 @@
 #define k5_mutex_unlock krb5int_mutex_unlock
 #endif
 
+#endif /* _KERNEL */
+
+
 #endif /* multiple inclusion? */
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5mech.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5mech.c	Fri Sep 14 15:01:24 2007 -0700
@@ -20,13 +20,57 @@
 #include <sys/debug.h>
 #include <k5-int.h>
 
-OM_uint32 krb5_gss_get_context(void ** context);
+/** mechglue wrappers **/
+
+static OM_uint32 k5glue_delete_sec_context
+    (void *, OM_uint32*,       /* minor_status */
+     gss_ctx_id_t*,    /* context_handle */
+     gss_buffer_t,     /* output_token */
+     OM_uint32);
+
+static OM_uint32 k5glue_sign
+    (void *, OM_uint32*,       /* minor_status */
+     gss_ctx_id_t,     /* context_handle */
+     int,              /* qop_req */
+     gss_buffer_t,     /* message_buffer */
+     gss_buffer_t,     /* message_token */
+     OM_uint32);
+
+static OM_uint32 k5glue_verify
+    (void *, OM_uint32*,       /* minor_status */
+     gss_ctx_id_t,     /* context_handle */
+     gss_buffer_t,     /* message_buffer */
+     gss_buffer_t,     /* token_buffer */
+     int*,              /* qop_state */
+     OM_uint32);
 
-extern krb5_error_code krb5_ser_context_init
-	(krb5_context);
+/* EXPORT DELETE START */
+static OM_uint32 k5glue_seal
+    (void *, OM_uint32*,       /* minor_status */
+     gss_ctx_id_t,     /* context_handle */
+     int,              /* conf_req_flag */
+     int,              /* qop_req */
+     gss_buffer_t,     /* input_message_buffer */
+     int*,             /* conf_state */
+     gss_buffer_t,     /* output_message_buffer */
+     OM_uint32);
 
-extern	krb5_error_code	krb5_ser_auth_context_init
-	(krb5_context);
+static OM_uint32 k5glue_unseal
+    (void *, OM_uint32*,       /* minor_status */
+     gss_ctx_id_t,     /* context_handle */
+     gss_buffer_t,     /* input_message_buffer */
+     gss_buffer_t,     /* output_message_buffer */
+     int*,             /* conf_state */
+     int*,             /* qop_state */
+     OM_uint32);
+/* EXPORT DELETE END */
+
+static OM_uint32 k5glue_import_sec_context
+    (void *, OM_uint32 *,		/* minor_status */
+     gss_buffer_t,		/* interprocess_token */
+     gss_ctx_id_t *);		/* context_handle */
+
+
 
 static	struct	gss_config krb5_mechanism =
 	{{9, "\052\206\110\206\367\022\001\002\002"},
@@ -34,31 +78,30 @@
 	NULL,	/* next */
 	TRUE,	/* uses_kmod */
 /* EXPORT DELETE START */ /* CRYPT DELETE START */
-	krb5_gss_unseal,
+	k5glue_unseal,
 /* EXPORT DELETE END */ /* CRYPT DELETE END */
-	krb5_gss_delete_sec_context,
+	k5glue_delete_sec_context,
 /* EXPORT DELETE START */ /* CRYPT DELETE START */
-	krb5_gss_seal,
+	k5glue_seal,
 /* EXPORT DELETE END */ /* CRYPT DELETE END */
-	krb5_gss_import_sec_context,
+	k5glue_import_sec_context,
 /* EXPORT DELETE START */
 /* CRYPT DELETE START */
 #if 0
 /* CRYPT DELETE END */
-	krb5_gss_seal,
-	krb5_gss_unseal,
+	k5glue_seal,
+	k5glue_unseal,
 /* CRYPT DELETE START */
 #endif
 /* CRYPT DELETE END */
 /* EXPORT DELETE END */
-	krb5_gss_sign,
-	krb5_gss_verify,
-};
+	k5glue_sign,
+	k5glue_verify,
+	};
 
 static gss_mechanism
 	gss_mech_initialize()
 {
-	(void) krb5_gss_get_context(&(krb5_mechanism.context));
 	return (&krb5_mechanism);
 }
 
@@ -134,38 +177,110 @@
 	return (mod_info(&modlinkage, modinfop));
 }
 
-OM_uint32
-krb5_gss_get_context(context)
-void **	context;
+/* ARGSUSED */
+static OM_uint32
+k5glue_delete_sec_context(ctx, minor_status, context_handle, output_token,
+	gssd_ctx_verifier)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_ctx_id_t *context_handle;
+     gss_buffer_t output_token;
+    OM_uint32 gssd_ctx_verifier;
 {
-	OM_uint32 major_status = 0;
+   return(krb5_gss_delete_sec_context(minor_status,
+				    context_handle, output_token,
+				    gssd_ctx_verifier));
+}
 
-	mutex_lock(&krb5_mutex);
-	if (context == NULL)
-	{
-		major_status = GSS_S_FAILURE;
-		goto unlock;
-	}
-	if (kg_context) {
-		*context = kg_context;
-		major_status = GSS_S_COMPLETE;
-		goto unlock;
-	}
+/* V2 */
+/* ARGSUSED */
+static OM_uint32
+k5glue_import_sec_context(ctx, minor_status, interprocess_token, context_handle)
+    void *ctx;
+     OM_uint32		 *minor_status;
+     gss_buffer_t	interprocess_token;
+     gss_ctx_id_t	 *context_handle;
+{
+   return(krb5_gss_import_sec_context(minor_status,
+				      interprocess_token,
+				    context_handle));
+}
+
+/* EXPORT DELETE START */
+/* V1 only */
+/* ARGSUSED */
+static OM_uint32
+k5glue_seal(ctx, minor_status, context_handle, conf_req_flag, qop_req,
+	    input_message_buffer, conf_state, output_message_buffer, gssd_ctx_verifier)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_ctx_id_t context_handle;
+     int conf_req_flag;
+     int qop_req;
+     gss_buffer_t input_message_buffer;
+     int *conf_state;
+     gss_buffer_t output_message_buffer;
+    OM_uint32 gssd_ctx_verifier;
+{
+   return(krb5_gss_seal(minor_status, context_handle,
+			conf_req_flag, qop_req, input_message_buffer,
+			conf_state, output_message_buffer, gssd_ctx_verifier));
+}
+/* EXPORT DELETE END */
 
-	if (krb5_init_context(&kg_context))
-	{
-		major_status = GSS_S_FAILURE;
-		goto unlock;
-	}
-	if (krb5_ser_auth_context_init(kg_context))
-	{
-		kg_context = 0;
-		major_status = GSS_S_FAILURE;
-		goto unlock;
-	}
+/* ARGSUSED */
+static OM_uint32
+k5glue_sign(ctx, minor_status, context_handle,
+	      qop_req, message_buffer, 
+	    message_token, gssd_ctx_verifier)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_ctx_id_t context_handle;
+     int qop_req;
+     gss_buffer_t message_buffer;
+     gss_buffer_t message_token;
+    OM_uint32 gssd_ctx_verifier;
+{
+   return(krb5_gss_sign(minor_status, context_handle,
+			qop_req, message_buffer, message_token, gssd_ctx_verifier));
+}
 
-	*context = kg_context;
-unlock:
-	mutex_unlock(&krb5_mutex);
-	return (major_status);
+/* EXPORT DELETE START */
+/* ARGSUSED */
+static OM_uint32
+k5glue_unseal(ctx, minor_status, context_handle, input_message_buffer,
+	    output_message_buffer, conf_state, qop_state, gssd_ctx_verifier)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_ctx_id_t context_handle;
+     gss_buffer_t input_message_buffer;
+     gss_buffer_t output_message_buffer;
+     int *conf_state;
+     int *qop_state;
+    OM_uint32 gssd_ctx_verifier;
+{
+   return(krb5_gss_unseal(minor_status, context_handle,
+			  input_message_buffer, output_message_buffer,
+			conf_state, qop_state, gssd_ctx_verifier));
 }
+/* EXPORT DELETE END */
+
+/* V1 only */
+/* ARGSUSED */
+static OM_uint32
+k5glue_verify(ctx, minor_status, context_handle, message_buffer,
+	    token_buffer, qop_state, gssd_ctx_verifier)
+    void *ctx;
+     OM_uint32 *minor_status;
+     gss_ctx_id_t context_handle;
+     gss_buffer_t message_buffer;
+     gss_buffer_t token_buffer;
+     int *qop_state;
+    OM_uint32 gssd_ctx_verifier;
+{
+   return(krb5_gss_verify(minor_status,
+			  context_handle,
+			  message_buffer,
+			  token_buffer,
+			qop_state, gssd_ctx_verifier));
+}
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/delete_sec_context.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/delete_sec_context.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -27,71 +27,104 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
+#include "mglueP.h"  /* SUNW15resync - for KGSS_ macros */
 
 /*
- * $Id: delete_sec_context.c,v 1.15 1998/10/30 02:54:17 marc Exp $
+ * $Id: delete_sec_context.c 16465 2004-06-16 02:37:23Z tlyu $
  */
 
+
+#ifdef	 _KERNEL
+/* SUNW15resync - todo - unify these kernel rel oid funcs with user spc ones */
+
+OM_uint32
+krb5_gss_internal_release_oid(minor_status, oid)
+    OM_uint32	*minor_status;
+    gss_OID	*oid;
+{
+    /*
+     * This function only knows how to release internal OIDs. It will
+     * return GSS_S_CONTINUE_NEEDED for any OIDs it does not recognize.
+     */
+   
+    if ((*oid != gss_mech_krb5) &&
+	(*oid != gss_mech_krb5_old) &&
+	(*oid != gss_mech_krb5_wrong) &&
+	(*oid != gss_nt_krb5_name) &&
+	(*oid != gss_nt_krb5_principal)) {
+	/* We don't know about this OID */
+	return(GSS_S_CONTINUE_NEEDED);
+    }
+    else {
+	*oid = GSS_C_NO_OID;
+	*minor_status = 0;
+	return(GSS_S_COMPLETE);
+    }
+}
+
 OM_uint32
-krb5_gss_delete_sec_context(ct,
-			minor_status,
-			context_handle,
-			output_token
-#ifdef	 _KERNEL
-		, gssd_ctx_verifier
-#endif
-			)
-    void *ct;
-    OM_uint32 *minor_status;
-    gss_ctx_id_t *context_handle;
-    gss_buffer_t output_token;
-#ifdef	 _KERNEL
-    OM_uint32 gssd_ctx_verifier;
+generic_gss_release_oid(minor_status, oid)
+    OM_uint32	*minor_status;
+    gss_OID	*oid;
+{
+    if (minor_status)
+	*minor_status = 0;
+
+    if (*oid == GSS_C_NO_OID)
+	return(GSS_S_COMPLETE);
+
+
+    if ((*oid != GSS_C_NT_USER_NAME) &&
+	(*oid != GSS_C_NT_MACHINE_UID_NAME) &&
+	(*oid != GSS_C_NT_STRING_UID_NAME) &&
+	(*oid != GSS_C_NT_HOSTBASED_SERVICE) &&
+	(*oid != GSS_C_NT_ANONYMOUS) &&
+	(*oid != GSS_C_NT_EXPORT_NAME) &&
+	(*oid != gss_nt_service_name)) {
+	FREE((*oid)->elements, (*oid)->length);
+	FREE(*oid, sizeof(gss_OID_desc));
+    }
+    *oid = GSS_C_NO_OID;
+    return(GSS_S_COMPLETE);
+}
+
+OM_uint32
+krb5_gss_release_oid(minor_status, oid)
+    OM_uint32	*minor_status;
+    gss_OID	*oid;
+{
+
+    if (krb5_gss_internal_release_oid(minor_status, oid) != GSS_S_COMPLETE) {
+	/* Pawn it off on the generic routine */
+	return(generic_gss_release_oid(minor_status, oid));
+    }
+    else {
+	*oid = GSS_C_NO_OID;
+	*minor_status = 0;
+	return(GSS_S_COMPLETE);
+    }
+}
 #endif
-{
-   OM_uint32 major_status = GSS_S_FAILURE;
-
-   mutex_lock(&krb5_mutex);
-
-   major_status = krb5_gss_delete_sec_context_no_lock(ct, minor_status,
-	   context_handle, output_token
-#ifdef   _KERNEL
-           , gssd_ctx_verifier
-#endif
-	   );
-   mutex_unlock(&krb5_mutex);
-   return(major_status);
-
-}
 
 /*ARGSUSED*/
 OM_uint32
-krb5_gss_delete_sec_context_no_lock(ct,
-			minor_status,
-			context_handle,
-			output_token
+krb5_gss_delete_sec_context(minor_status,
+			    context_handle,
+			    output_token
 #ifdef	 _KERNEL
-		, gssd_ctx_verifier
+			    , gssd_ctx_verifier
 #endif
-			)
-     void *ct;
+			    )
      OM_uint32 *minor_status;
      gss_ctx_id_t *context_handle;
      gss_buffer_t output_token;
 #ifdef	 _KERNEL
-	OM_uint32 gssd_ctx_verifier;
+     OM_uint32 gssd_ctx_verifier;
 #endif
 {
-   krb5_context context = ct;
+   krb5_context context;
    krb5_gss_ctx_id_rec *ctx;
-   OM_uint32 major_status = GSS_S_FAILURE;
-
-   /* Solaris Kerberos:  we use the global kg_context for MT safe */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, &context)))
-      return(GSS_S_FAILURE);
-#endif
 
    if (output_token) {
       output_token->length = 0;
@@ -101,28 +134,30 @@
    /*SUPPRESS 29*/
    if (*context_handle == GSS_C_NO_CONTEXT) {
       *minor_status = 0;
-      major_status = GSS_S_COMPLETE;
-      goto out;
+      return(GSS_S_COMPLETE);
    }
 
    /*SUPPRESS 29*/
    /* validate the context handle */
    if (! kg_validate_ctx_id(*context_handle)) {
       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
-      major_status = GSS_S_NO_CONTEXT;
-      goto out;
+      return(GSS_S_NO_CONTEXT);
    }
 
+   ctx = (krb5_gss_ctx_id_t) *context_handle;
+   context = ctx->k5_context;
+
    /* construct a delete context token if necessary */
 
    if (output_token) {
+      OM_uint32 major;
       gss_buffer_desc empty;
       empty.length = 0; empty.value = NULL;
 
-      if ((major_status = kg_seal(context, minor_status, *context_handle, 0,
+      if ((major = kg_seal(minor_status, *context_handle, 0,
 			   GSS_C_QOP_DEFAULT,
 			   &empty, NULL, output_token, KG_TOK_DEL_CTX)))
-	 goto out;
+	 return(major);
    }
 
    /* invalidate the context handle */
@@ -131,8 +166,6 @@
 
    /* free all the context state */
 
-   ctx = (krb5_gss_ctx_id_rec *) *context_handle;
-
    if (ctx->seqstate)
       g_order_free(&(ctx->seqstate));
 
@@ -149,25 +182,23 @@
    if (ctx->subkey)
       krb5_free_keyblock(context, ctx->subkey);
    if (ctx->acceptor_subkey)
-      krb5_free_keyblock(context, ctx->acceptor_subkey);
+       krb5_free_keyblock(context, ctx->acceptor_subkey);
 
-/* We never import the auth_context into the kernel */
+   /* We never import the auth_context into the kernel */
 #ifndef _KERNEL
    if (ctx->auth_context) {
-       (void)krb5_auth_con_setrcache(context, ctx->auth_context, NULL);
+       if (ctx->cred_rcache)
+	   (void)krb5_auth_con_setrcache(context, ctx->auth_context, NULL);
+
        krb5_auth_con_free(context, ctx->auth_context);
    }
 #endif
 
-  /* Solaris Kerberos:  the mech_used element of this structure
-   * is the actual gss_OID_desc type in gssapiP_krb5.h, and not 
-   * a gss_OID_desc * type, in particular, the gss_release_oid
-   * is not needed, as the oid is memset to zero below, then freed.
-   */
-  if (ctx->mech_used.length) {
-	xfree_wrap(ctx->mech_used.elements, ctx->mech_used.length);
-        /* gss_release_oid(minor_status, &(ctx->mech_used)); */
-  }	 
+   if (ctx->mech_used)
+       (void) KGSS_RELEASE_OID(minor_status, &ctx->mech_used);
+
+   if (ctx->k5_context)
+       krb5_free_context(ctx->k5_context);
 
    /* Zero out context */
    (void) memset(ctx, 0, sizeof(*ctx));
@@ -178,7 +209,5 @@
    *context_handle = GSS_C_NO_CONTEXT;
 
    *minor_status = 0;
-   major_status = GSS_S_COMPLETE;
-out:
-   return(major_status);
+   return(GSS_S_COMPLETE);
 }
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,17 +1,10 @@
 /*
- * Copyright 2001-2003 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
-/* 
- * Solaris Kerberos:  This is identical to MIT Release 1.2.1 except for 
- * changes to the call kg_get_context to get the context in release and 
- * getcred.  In order to be MT safe, we keep a global variable kg_context
- * and do not keep a defcred for default credentials.
- */
-
 /*
  * Copyright 1993 by OpenVision Technologies, Inc.
  * 
@@ -61,21 +54,24 @@
  */
 
 /*
- * $Id: gssapi_krb5.c,v 1.18 1999/03/26 03:51:42 tytso Exp $
+ * $Id: gssapi_krb5.c 18131 2006-06-14 22:27:54Z tlyu $
  */
 
-#include <gssapiP_krb5.h>
-#include <k5-int.h>
+
+/* For declaration of krb5_ser_context_init */
+#include "k5-int.h"
+#include "gssapiP_krb5.h"
 
 /*
+ * Solaris Kerberos
  * Kernel kgssd module debugging aid. The global variable "krb5_log" is a bit
- * mask which allows various types of log messages to be printed out.  
+ * mask which allows various types of log messages to be printed out.
  *
  * The log levels are defined in:
  * usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h
  *
- * Note, KRB5_LOG_LVL can be assigned via the make invocation.  See KRB5_DEFS in
- * the various Makefiles.
+ * Note, KRB5_LOG_LVL can be assigned via the make invocation.
+ * See KRB5_DEFS in the various Makefiles.
  */
 
 #ifdef KRB5_LOG_LVL
@@ -94,15 +90,12 @@
  * The OID of the draft krb5 mechanism, assigned by IETF, is:
  * 	iso(1) org(3) dod(5) internet(1) security(5)
  *	kerberosv5(2) = 1.3.5.1.5.2
- * The OID of the krb5_user_name type is:
- *      iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
- *      generic(1) user_name(1) = 1.2.840.113554.1.2.1.1
  * The OID of the krb5_name type is:
  * 	iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
  * 	krb5(2) krb5_name(1) = 1.2.840.113554.1.2.2.1
  * The OID of the krb5_principal type is:
- *      iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
- *      krb5(2) krb5_principal(2) = 1.2.840.113554.1.2.2.2
+ * 	iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
+ * 	krb5(2) krb5_principal(2) = 1.2.840.113554.1.2.2.2
  * The OID of the proposed standard krb5 mechanism is:
  * 	iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
  * 	krb5(2) = 1.2.840.113554.1.2.2
@@ -112,13 +105,6 @@
  *	
  */
 
-/* gss_mech_krb5 = 1.2.840.113554.1.2.2 
- * gss_mech_krb5_old = 1.3.5.1.5.2
- * gss_mech_krb5_v2 = 1.2.840.113554.1.2.3
- * gss_nt_krb5_name = 1.2.840.113554.1.2.2.1
- * gss_nt_krb5_principal = 1.2.840.113554.1.2.2.2
- */
-
 /*
  * Encoding rules: The first two values are encoded in one byte as 40
  * * value1 + value2.  Subsequent values are encoded base 128, most
@@ -126,59 +112,40 @@
  * except the last in each value's encoding.
  */
 
-/*  Global lock for krb5 mechanism  */
-#ifdef  _KERNEL
-kmutex_t	krb5_mutex;
-#else
-mutex_t		krb5_mutex;
-#endif
-
-/* krb5 mechanism oids */
-
 const gss_OID_desc krb5_gss_oid_array[] = {
    /* this is the official, rfc-specified OID */
-   {9, "\052\206\110\206\367\022\001\002\002"},
-   /* this is the unofficial, wrong OID */
-   {5, "\053\005\001\005\002"},   
+   {GSS_MECH_KRB5_OID_LENGTH, GSS_MECH_KRB5_OID},
+   /* this pre-RFC mech OID */
+   {GSS_MECH_KRB5_OLD_OID_LENGTH, GSS_MECH_KRB5_OLD_OID},
+   /* this is the unofficial, incorrect mech OID emitted by MS */
+   {GSS_MECH_KRB5_WRONG_OID_LENGTH, GSS_MECH_KRB5_WRONG_OID},
    /* this is the v2 assigned OID */
    {9, "\052\206\110\206\367\022\001\002\003"},
    /* these two are name type OID's */
+
+    /* 2.1.1. Kerberos Principal Name Form:  (rfc 1964)
+     * This name form shall be represented by the Object Identifier {iso(1)
+     * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+     * krb5(2) krb5_name(1)}.  The recommended symbolic name for this type
+     * is "GSS_KRB5_NT_PRINCIPAL_NAME". */
    {10, "\052\206\110\206\367\022\001\002\002\001"},
-   /* XXX this value isn't defined in an RFC */
+
+   /* gss_nt_krb5_principal.  Object identifier for a krb5_principal. Do not use. */
    {10, "\052\206\110\206\367\022\001\002\002\002"},
-   /* 
-    * Solaris Kerberos: the following element is the GSS_KRB5_NT_USER_NAME OID
-    * (1.2.840.113554.1.2.1.1, see RFC 1964) which is used for backward
-    * compatibility with earlier Solaris kerberos releases.
-    */
-   {10, "\052\206\110\206\367\022\001\002\001\001"},
    { 0, 0 }
 };
 
-const gss_OID_desc * const gss_mech_krb5 = krb5_gss_oid_array+0;
-const gss_OID_desc * const gss_mech_krb5_old = krb5_gss_oid_array+1;
-const gss_OID_desc * const gss_mech_krb5_v2 = krb5_gss_oid_array+2;
-
-/* 
- * Solaris Kerberos: gss_nt_krb5_name points to the GSS_KRB5_NT_USER_NAME OID
- * for backwards compat with earlier Solaris Kerberos releases.  In MIT this
- * points to the GSS_KRB5_NT_PRINCIPAL_NAME OID (1.2.840.113554.1.2.2.1).
- */
-
-const gss_OID_desc * const gss_nt_krb5_name = krb5_gss_oid_array+5;
-
-/* 
- * XXX gss_nt_krb5_principal points to an OID value that is specific to MIT
- * which is not described in any RFC at this point.  Be cautious about using
- * this.
- */ 
-
-const gss_OID_desc * const gss_nt_krb5_principal = krb5_gss_oid_array+4;
+const gss_OID_desc * const gss_mech_krb5              = krb5_gss_oid_array+0;
+const gss_OID_desc * const gss_mech_krb5_old          = krb5_gss_oid_array+1;
+const gss_OID_desc * const gss_mech_krb5_wrong        = krb5_gss_oid_array+2;
+const gss_OID_desc * const gss_nt_krb5_name           = krb5_gss_oid_array+4;
+const gss_OID_desc * const gss_nt_krb5_principal      = krb5_gss_oid_array+5;
+const gss_OID_desc * const GSS_KRB5_NT_PRINCIPAL_NAME = krb5_gss_oid_array+4;
 
 static const gss_OID_set_desc oidsets[] = {
    {1, (gss_OID) krb5_gss_oid_array+0},
    {1, (gss_OID) krb5_gss_oid_array+1},
-   {2, (gss_OID) krb5_gss_oid_array+0},
+   {3, (gss_OID) krb5_gss_oid_array+0},
    {1, (gss_OID) krb5_gss_oid_array+2},
    {3, (gss_OID) krb5_gss_oid_array+0},
 };
@@ -186,107 +153,132 @@
 const gss_OID_set_desc * const gss_mech_set_krb5 = oidsets+0;
 const gss_OID_set_desc * const gss_mech_set_krb5_old = oidsets+1;
 const gss_OID_set_desc * const gss_mech_set_krb5_both = oidsets+2;
-const gss_OID_set_desc * const gss_mech_set_krb5_v2 = oidsets+3;
-const gss_OID_set_desc * const gss_mech_set_krb5_v1v2 = oidsets+4;
 
-void *kg_vdb = NULL;
+g_set kg_vdb = G_SET_INIT;
 
 /** default credential support */
 
-/* default credentials */
+#ifndef  _KERNEL
 
 /*
- * Solaris Kerberos:
- * We no longer store the defcred in a global variable since this will
- * prevent us from assuming different user ids by gss daemon.
- * This also makes gss_release_defcred a no-op. 
+ * init_sec_context() will explicitly re-acquire default credentials,
+ * so handling the expiration/invalidation condition here isn't needed.
  */
-#if 0
-static gss_cred_id_t defcred = GSS_C_NO_CREDENTIAL;
-#endif
-
-krb5_context kg_context = NULL;
-
-/* XXX what happens when the default credentials expire or are invalidated? */
-
-#ifndef  _KERNEL
-
-/* Note, the krb5_mutex lock must be held prior to calling this function */
 OM_uint32
 kg_get_defcred(minor_status, cred)
      OM_uint32 *minor_status;
      gss_cred_id_t *cred;
 {
-OM_uint32 major;
-	
-   KRB5_LOG0(KRB5_INFO, "kg_get_defcred() start\n");
-
-   if (!kg_context && GSS_ERROR(kg_get_context(minor_status,&kg_context))){
-	 KRB5_LOG(KRB5_ERR, "kg_get_defcred() end, error, kg_get_context() "
-		 "minor_status=%d\n", *minor_status);
-      return GSS_S_FAILURE;
+    OM_uint32 major;
+    
+    if ((major = krb5_gss_acquire_cred(minor_status, 
+				      (gss_name_t) NULL, GSS_C_INDEFINITE, 
+				      GSS_C_NULL_OID_SET, GSS_C_INITIATE, 
+				      cred, NULL, NULL)) && GSS_ERROR(major)) {
+      return(major);
    }
-
-      major = krb5_gss_acquire_cred_no_lock(kg_context,minor_status, 
-	(gss_name_t) NULL, GSS_C_INDEFINITE, GSS_C_NULL_OID_SET, GSS_C_INITIATE, 
-	 cred, NULL, NULL);
-      if (major && GSS_ERROR(major)) {
-	 *cred = GSS_C_NO_CREDENTIAL;
-	 KRB5_LOG(KRB5_ERR, "kg_get_defcred() end, error major=%d\n", major);
-	 return(major);
-      }
-
    *minor_status = 0;
-   KRB5_LOG0(KRB5_INFO, "kg_get_defcred() end\n");
    return(GSS_S_COMPLETE);
 }
 
 OM_uint32
-kg_release_defcred(minor_status)
-     OM_uint32 *minor_status;
+kg_sync_ccache_name (krb5_context context, OM_uint32 *minor_status)
 {
-      *minor_status = 0;
-      return(GSS_S_COMPLETE);
+    OM_uint32 err = 0;
+    
+    /* 
+     * Sync up the context ccache name with the GSSAPI ccache name.
+     * If kg_ccache_name is NULL -- normal unless someone has called 
+     * gss_krb5_ccache_name() -- then the system default ccache will 
+     * be picked up and used by resetting the context default ccache.
+     * This is needed for platforms which support multiple ccaches.
+     */
+    
+    if (!err) {
+        /* if NULL, resets the context default ccache */
+        err = krb5_cc_set_default_name(context,
+				       (char *) k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME));
+    }
+    
+    *minor_status = err;
+    return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
 }
 
 OM_uint32
-kg_get_context(minor_status, context)
-   OM_uint32 *minor_status;
-   krb5_context *context;
+kg_get_ccache_name (OM_uint32 *minor_status, const char **out_name)
 {
-   /*
-    * Solaris Kerberos:  the following is a global variable declared 
-    * above and initialized here below
-    */
-   /* static krb5_context kg_context = NULL; */
-   krb5_error_code code;
+    const char *name = NULL;
+    OM_uint32 err = 0;
+    char *kg_ccache_name;
+
+    kg_ccache_name = k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME);
+    
+    if (kg_ccache_name != NULL) {
+	name = strdup(kg_ccache_name);
+	if (name == NULL)
+	    err = errno;
+    } else {
+	krb5_context context = NULL;
 
-   KRB5_LOG0(KRB5_INFO, "kg_get_context() start\n");
+	/* Reset the context default ccache (see text above), and then
+	   retrieve it.  */
+	err = krb5_gss_init_context(&context);
+	if (!err)
+	    err = krb5_cc_set_default_name (context, NULL);
+	if (!err) {
+	    name = krb5_cc_default_name(context);
+	    if (name) {
+		name = strdup(name);
+		if (name == NULL)
+		    err = errno;
+	    }
+	}
+	if (context)
+	    krb5_free_context(context);
+    }
 
-   if (!kg_context) {
-	   if ((code = krb5_init_context(&kg_context)))
-		   goto fail;
-	   if ((code = krb5_ser_context_init(kg_context)))
-		   goto fail;
-	   if ((code = krb5_ser_auth_context_init(kg_context)))
-		   goto fail;
-	   if ((code = krb5_ser_ccache_init(kg_context)))
-		   goto fail;
-	   if ((code = krb5_ser_rcache_init(kg_context)))
-		   goto fail;
-	   if ((code = krb5_ser_keytab_init(kg_context)))
-		   goto fail;
-	   if ((code = krb5_ser_auth_context_init(kg_context)))
-	       goto fail;
-   }
-   *context = kg_context;
-   *minor_status = 0;
-   KRB5_LOG0(KRB5_INFO, "kg_get_context() end\n");
-   return GSS_S_COMPLETE;
-   
-fail:
-   *minor_status = (OM_uint32) code;
-   KRB5_LOG(KRB5_ERR, "kg_get_context() end, error code=%d\n", code);
-   return GSS_S_FAILURE;
+    if (!err) {
+        if (out_name) {
+            *out_name = name;
+        }
+    }
+    
+    *minor_status = err;
+    return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
+}
+
+OM_uint32
+kg_set_ccache_name (OM_uint32 *minor_status, const char *name)
+{
+    char *new_name = NULL;
+    char *swap = NULL;
+    char *kg_ccache_name;
+    krb5_error_code kerr;
+
+    if (name) {
+	new_name = malloc(strlen(name) + 1);
+	if (new_name == NULL) {
+	    *minor_status = ENOMEM;
+	    return GSS_S_FAILURE;
+	}
+	strcpy(new_name, name);
+    }
+
+    kg_ccache_name = k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME);
+    swap = kg_ccache_name;
+    kg_ccache_name = new_name;
+    new_name = swap;
+    kerr = k5_setspecific(K5_KEY_GSS_KRB5_CCACHE_NAME, kg_ccache_name);
+    if (kerr != 0) {
+	/* Can't store, so free up the storage.  */
+	free(kg_ccache_name);
+	/* ??? free(new_name); */
+	*minor_status = kerr;
+	return GSS_S_FAILURE;
+    }
+
+    free (new_name);
+    *minor_status = 0;
+    return GSS_S_COMPLETE;
 }
 #endif
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/import_sec_context.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/import_sec_context.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -8,7 +8,7 @@
 /*
  * lib/gssapi/krb5/import_sec_context.c
  *
- * Copyright 1995 by the Massachusetts Institute of Technology.
+ * Copyright 1995,2004 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -35,21 +35,22 @@
 /*
  * import_sec_context.c	- Internalize the security context.
  */
-#include <gssapiP_krb5.h>
-#include <k5-int.h>
-#include <gssapi/gssapi.h>
+#include "gssapiP_krb5.h"
+/* for serialization initialization functions */
+#include "k5-int.h"
+#include "mglueP.h"  /* SUNW15resync - for KGSS_ macros */
+
+#ifdef	 _KERNEL
+extern OM_uint32 kgss_release_oid(OM_uint32 *, gss_OID *);
+#endif
+
 
 /*
  * Fix up the OID of the mechanism so that uses the static version of
  * the OID if possible.
- *
- * Solaris Kerberos: this is not necessary.  Our mech_used is allocated
- * as part of the context structure.  This function attempts to point to
- * the corresponding gss_OID in the array krb5_gss_oid_array.
  */
-#if 0
-gss_OID_desc krb5_gss_convert_static_mech_oid(oid)
-     gss_OID	FAR oid;
+gss_OID krb5_gss_convert_static_mech_oid(oid)
+     gss_OID	oid;
 {
 	const gss_OID_desc 	*p;
 	OM_uint32		minor_status;
@@ -57,17 +58,34 @@
 	for (p = krb5_gss_oid_array; p->length; p++) {
 		if ((oid->length == p->length) &&
 		    (memcmp(oid->elements, p->elements, p->length) == 0)) {
-			gss_release_oid(&minor_status, &oid);
-			return *p;
+		        (void) KGSS_RELEASE_OID(&minor_status, &oid);
+			return (gss_OID) p;
 		}
 	}
-	return *oid;
+	return oid;
 }
+
+krb5_error_code
+krb5_gss_ser_init (krb5_context context)
+{
+    krb5_error_code code;
+    static krb5_error_code (KRB5_CALLCONV *const fns[])(krb5_context) = {
+	krb5_ser_auth_context_init,
+#ifndef _KERNEL
+	krb5_ser_context_init,
+	krb5_ser_ccache_init, krb5_ser_rcache_init, krb5_ser_keytab_init,
 #endif
+    };
+    int i;
+
+    for (i = 0; i < sizeof(fns)/sizeof(fns[0]); i++)
+	if ((code = (fns[i])(context)) != 0)
+	    return code;
+    return 0;
+}
 
 OM_uint32
-krb5_gss_import_sec_context(ct, minor_status, interprocess_token, context_handle)
-    void		*ct;
+krb5_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;
@@ -78,16 +96,22 @@
     krb5_gss_ctx_id_t	ctx;
     krb5_octet		*ibp;
 
-   /* Solaris Kerberos:  we use the global kg_context for MT safe */
-#if 0
-    if (GSS_ERROR(kg_get_context(minor_status, &context)))
-       return(GSS_S_FAILURE);
-#endif
+    /* This is a bit screwy.  We create a krb5 context because we need
+       one when calling the serialization code.  However, one of the
+       objects we're unpacking is a krb5 context, so when we finish,
+       we can throw this one away.  */
+    kret = KGSS_INIT_CONTEXT(&context);
+    if (kret) {
+	*minor_status = kret;
+	return GSS_S_FAILURE;
+    }
 
-    KRB5_LOG0(KRB5_INFO, "krb5_gss_import_sec_context() start\n");
-
-    mutex_lock(&krb5_mutex);
-    context = ct;
+    kret = krb5_gss_ser_init(context);
+    if (kret) {
+	krb5_free_context(context);
+	*minor_status = kret;
+	return GSS_S_FAILURE;
+    }
 
     /* Assume a tragic failure */
     ctx = (krb5_gss_ctx_id_t) NULL;
@@ -96,56 +120,39 @@
     /* Internalize the context */
     ibp = (krb5_octet *) interprocess_token->value;
     blen = (size_t) interprocess_token->length;
-    if ((kret = kg_ctx_internalize(context,
-				   (krb5_pointer *) &ctx,
-				   &ibp, &blen))) {
+    kret = kg_ctx_internalize(context, (krb5_pointer *) &ctx, &ibp, &blen);
+    /*
+     * SUNW15resync
+     *
+     *    krb5_free_context(context);
+     * Previous versions of MIT(1.2ish)/Solaris did not serialize the
+     * k5_context but MIT 1.5 does.  But we don't need all the userspace
+     * junk in the kernel so we continue to not serialize it.
+     * So we keep this context live here (see it's use in kg_ctx_internalize)
+     * and it will get freed by delete_sec_context.
+     */
+    if (kret) {
+       krb5_free_context(context);
        *minor_status = (OM_uint32) kret;
-       mutex_unlock(&krb5_mutex);
-       
-       KRB5_LOG(KRB5_ERR, "krb5_gss_import_sec_context() end,"
-		"kg_ctx_internalize() error kret = %d\n", kret);
-
-       if (kret == ENOMEM)
-           return(GSS_S_FAILURE);
-       else
-           return(GSS_S_DEFECTIVE_TOKEN);
+       return(GSS_S_FAILURE);
     }
 
     /* intern the context handle */
     if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
-       (void)krb5_gss_delete_sec_context_no_lock(context, minor_status, 
+       (void)krb5_gss_delete_sec_context(minor_status, 
 					 (gss_ctx_id_t *) &ctx, NULL
 #ifdef _KERNEL
-					,0  /* gssd_ctx_verifier */
+ 					,0  /* gssd_ctx_verifier */
 #endif
 					);
        *minor_status = (OM_uint32) G_VALIDATE_FAILED;
-       mutex_unlock(&krb5_mutex);
-
-       KRB5_LOG0(KRB5_ERR, "krb5_gss_import_sec_context() end,"
-		"kg_save_ctx_id() error\n");
-
        return(GSS_S_FAILURE);
     }
-    if (! kg_validate_ctx_id((gss_ctx_id_t) ctx)) {
-       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
-        mutex_unlock(&krb5_mutex);
 
-	KRB5_LOG0(KRB5_ERR, "krb5_gss_import_sec_context() end,"
-		"kg_validate_ctx_id() error\n");
-
-        return(GSS_S_FAILURE);
-    }
-
-    /* Solaris Kerberos:  our mech_used is part of the ctx structure */
-    /* ctx->mech_used = krb5_gss_convert_static_mech_oid(&(ctx->mech_used)); */
-
+    ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used);
+    
     *context_handle = (gss_ctx_id_t) ctx;
 
     *minor_status = 0;
-    mutex_unlock(&krb5_mutex);
-
-    KRB5_LOG0(KRB5_INFO, "krb5_gss_import_sec_context() end\n");
-
     return (GSS_S_COMPLETE);
 }
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/k5seal.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/k5seal.c	Fri Sep 14 15:01:24 2007 -0700
@@ -57,7 +57,7 @@
 #include <k5-int.h>
 
 static krb5_error_code
-make_seal_token_v1 PROTOTYPE((krb5_context context,
+make_seal_token_v1 (krb5_context context,
 			      krb5_keyblock *enc,
 			      krb5_keyblock *seq,
 			      gssint_uint64 *seqnum,
@@ -70,7 +70,7 @@
 			      int encrypt,
 			      int toktype,
 			      int bigend,
-			      gss_OID oid));
+			      gss_OID oid);
 
 static krb5_error_code
 make_seal_token_v1(context, enc, seq, seqnum, direction, text, token,
@@ -398,9 +398,8 @@
    and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */
 
 OM_uint32
-kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req,
+kg_seal(minor_status, context_handle, conf_req_flag, qop_req,
 	input_message_buffer, conf_state, output_message_buffer, toktype)
-    krb5_context context;
     OM_uint32 *minor_status;
     gss_ctx_id_t context_handle;
     int conf_req_flag;
@@ -413,6 +412,7 @@
     krb5_gss_ctx_id_rec *ctx;
     krb5_error_code code;
     krb5_timestamp now;
+    krb5_context context;
 
     KRB5_LOG0(KRB5_INFO, "kg_seal() start");
 
@@ -446,6 +446,7 @@
 	return(GSS_S_NO_CONTEXT);
     }
 
+    context = ctx->k5_context;
     if ((code = krb5_timeofday(context, &now))) {
 	*minor_status = code;
 	KRB5_LOG(KRB5_ERR, "kg_seal() end, krb5_timeofday() error code=%d\n", code);
@@ -460,7 +461,7 @@
                                   input_message_buffer, output_message_buffer,
                                   ctx->signalg, ctx->cksum_size, ctx->sealalg,
                                   conf_req_flag, toktype, ctx->big_endian,
-                                  &ctx->mech_used);
+                                  ctx->mech_used);
 	break;
     case 1:
 	code = gss_krb5int_make_seal_token_v3(context, ctx,
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/k5sealv3.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/k5sealv3.c	Fri Sep 14 15:01:24 2007 -0700
@@ -91,6 +91,9 @@
     int key_usage;
     unsigned char acceptor_flag;
     const gss_buffer_desc *message2 = message;
+#ifdef CFX_EXERCISE
+    size_t rrc;
+#endif
     size_t ec;
     unsigned short tok_id;
     krb5_checksum sum;
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/k5unseal.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/k5unseal.c	Fri Sep 14 15:01:24 2007 -0700
@@ -394,7 +394,7 @@
 	}
 
 	if ((code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL,
-			       (g_OID_equal(&ctx->mech_used, gss_mech_krb5_old) ?
+			       (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ?
 				ctx->seq->contents : NULL),
 			       md5cksum.contents, md5cksum.contents, 16))) {
 	    xfree_wrap(md5cksum.contents, md5cksum.length);
@@ -638,9 +638,8 @@
    conf_state is only valid if SEAL. */
 
 OM_uint32
-kg_unseal(context, minor_status, context_handle, input_token_buffer,
+kg_unseal(minor_status, context_handle, input_token_buffer,
 	  message_buffer, conf_state, qop_state, toktype)
-    krb5_context context;
     OM_uint32 *minor_status;
     gss_ctx_id_t context_handle;
     gss_buffer_t input_token_buffer;
@@ -696,7 +695,7 @@
 	}
     else
         toktype2 = toktype;
-    err = g_verify_token_header(&ctx->mech_used,
+    err = g_verify_token_header(ctx->mech_used,
 				(uint32_t *)&bodysize, &ptr, toktype2,
 				input_token_buffer->length,
 				!ctx->proto);
@@ -708,12 +707,12 @@
 
 
     if (ctx->proto == 0) {
-	err = kg_unseal_v1(context, minor_status, ctx, ptr, bodysize,
+	err = kg_unseal_v1(ctx->k5_context, minor_status, ctx, ptr, bodysize,
 			    message_buffer, conf_state, qop_state,
 			    toktype);
 
     } else {
-	err = gss_krb5int_unseal_token_v3(context, minor_status, ctx,
+	err = gss_krb5int_unseal_token_v3(ctx->k5_context, minor_status, ctx,
                                            ptr, bodysize, message_buffer,
                                            conf_state, qop_state, toktype);
     }
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/seal.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/seal.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,7 +1,7 @@
 /* EXPORT DELETE START */
 
 /*
- * Copyright 2001-2003 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -29,21 +29,21 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
 
 /*
- * $Id: seal.c,v 1.11 1996/07/22 20:34:29 marc Exp $
+ * $Id: seal.c 16171 2004-03-15 17:45:01Z raeburn $
  */
+
 /*ARGSUSED*/
 OM_uint32
-krb5_gss_seal(ctx, minor_status, context_handle, conf_req_flag,
+krb5_gss_seal(minor_status, context_handle, conf_req_flag,
 	      qop_req, input_message_buffer, conf_state,
 	      output_message_buffer
 #ifdef	 _KERNEL
-		, gssd_ctx_verifier
+	    , gssd_ctx_verifier
 #endif
-)
-     void	*ctx;
+	    )
      OM_uint32 *minor_status;
      gss_ctx_id_t context_handle;
      int conf_req_flag;
@@ -52,56 +52,29 @@
      int *conf_state;
      gss_buffer_t output_message_buffer;
 #ifdef	 _KERNEL
-	OM_uint32 gssd_ctx_verifier;
+     OM_uint32 gssd_ctx_verifier;
 #endif
 {
-   krb5_context context;
-   OM_uint32    status;
-
 #ifdef	KRB5_NO_PRIVACY
-	/* 
-	 * conf_req_flag must be zero; 
-	 * encryption is disallowed 
- 	 * for global version
-	*/
-   if (conf_req_flag)	
-   	return (GSS_S_FAILURE);
-#endif
-
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, &context)))
-      return(GSS_S_FAILURE);
+ 	/*
+ 	 * conf_req_flag must be zero;
+ 	 * encryption is disallowed
+  	 * for global version
+ 	*/
+     if (conf_req_flag)
+       return (GSS_S_FAILURE);
 #endif
-
-   mutex_lock(&krb5_mutex);
-   context = ctx;
-   status = kg_seal(context, minor_status, context_handle, conf_req_flag,
+ 
+   return(kg_seal(minor_status, context_handle, conf_req_flag,
 		  qop_req, input_message_buffer, conf_state,
-		  output_message_buffer, KG_TOK_SEAL_MSG);
-   mutex_unlock(&krb5_mutex);
-#ifdef	KRB5_NO_PRIVACY
-	/*
-	 * Can't be paranoid enough;
-	 * if someone plugs in their version of kg_seal
-	 * that does encryption we want to 
-	 * disallow that too.
-	*/
-	if (conf_state && *conf_state) 
-   		return (GSS_S_FAILURE);
-
-#endif
-   return(status);
+		  output_message_buffer, KG_TOK_SEAL_MSG));
 }
 
 /* V2 interface */
-/*ARGSUSED*/
 OM_uint32
-krb5_gss_wrap(ctx, minor_status, context_handle, conf_req_flag,
+krb5_gss_wrap(minor_status, context_handle, conf_req_flag,
 	      qop_req, input_message_buffer, conf_state,
 	      output_message_buffer)
-    void		*ctx;
     OM_uint32		*minor_status;
     gss_ctx_id_t	context_handle;
     int			conf_req_flag;
@@ -111,25 +84,12 @@
     gss_buffer_t	output_message_buffer;
 {
 #ifdef	KRB5_NO_PRIVACY
-    return (GSS_S_FAILURE);
+     return (GSS_S_FAILURE);
 #else
-    krb5_context context;
-    OM_uint32    status;
-
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-    if (GSS_ERROR(kg_get_context(minor_status, &context)))
-       return(GSS_S_FAILURE);
-#endif
-
-    mutex_lock(&krb5_mutex);
-    context = ctx;
-    status = kg_seal(context, minor_status, context_handle, conf_req_flag,
+     return(kg_seal(minor_status, context_handle, conf_req_flag,
 		   (int) qop_req, input_message_buffer, conf_state,
-		   output_message_buffer, KG_TOK_WRAP_MSG);
-    mutex_unlock(&krb5_mutex);
-    return(status);
+		   output_message_buffer, KG_TOK_WRAP_MSG));
 #endif
 }
+
 /* EXPORT DELETE END */
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/ser_sctx.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/ser_sctx.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -8,7 +8,7 @@
 /*
  * lib/gssapi/krb5/ser_sctx.c
  *
- * Copyright 1995 by the Massachusetts Institute of Technology.
+ * Copyright 1995, 2004 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -35,12 +35,11 @@
 /*
  * ser_sctx.c - Handle [de]serialization of GSSAPI security context.
  */
-
-/* Solaris Kerberos:  order is important here.  include gssapiP_krb5.h
- * before all others, otherwise we get a LINT error from MALLOC macro
- * being redefined in mechglueP.h */
-#include <gssapiP_krb5.h>
-#include <k5-int.h>
+ /* Solaris Kerberos:  order is important here.  include gssapiP_krb5.h
+  * before all others, otherwise we get a LINT error from MALLOC macro
+  * being redefined in mechglueP.h */
+#include "gssapiP_krb5.h"
+#include "k5-int.h"
 
 /*
  * This module contains routines to [de]serialize 
@@ -64,18 +63,18 @@
 {
      gss_OID oid = (gss_OID) arg;
      krb5_error_code err;
-
+     
      err = krb5_ser_pack_int32(KV5M_GSS_OID, buffer, lenremain);
      if (err)
-        return err;
+	 return err;
      err = krb5_ser_pack_int32((krb5_int32) oid->length,
-                               buffer, lenremain);
+			       buffer, lenremain);
      if (err)
-        return err;
+	 return err;
      err = krb5_ser_pack_bytes((krb5_octet *) oid->elements,
-                               oid->length, buffer, lenremain);
+			       oid->length, buffer, lenremain);
      if (err)
-        return err;
+	 return err;
      err = krb5_ser_pack_int32(KV5M_GSS_OID, buffer, lenremain);
      return err;
 }
@@ -88,12 +87,7 @@
     krb5_octet		**buffer;
     size_t		*lenremain;
 {
-     /* Solaris Kerberos:  note that by copying the argp pointer directly here,
-      * we avoid doing all the MALLOC and FREE calls later.
-      * Don't forget that when argp is ctx->mech_used, then this memory was 
-      * already allocated.
-      */
-     gss_OID oid = (gss_OID)argp;
+     gss_OID oid;
      krb5_int32 ibuf;
      krb5_octet		*bp;
      size_t		remain;
@@ -107,48 +101,48 @@
 
      if (ibuf != KV5M_GSS_OID)
 	 return (EINVAL);
-/*   oid = (gss_OID) MALLOC(sizeof(gss_OID_desc));
+
+     oid = (gss_OID) MALLOC(sizeof(gss_OID_desc));
      if (oid == NULL)
 	  return ENOMEM;
-*/
-
      if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) {
-         return EINVAL;
+         FREE(oid, sizeof(gss_OID_desc));
+	 return EINVAL;
      }
      oid->length = ibuf;
      oid->elements = MALLOC(ibuf);
-     if (oid->elements == NULL) {
-             oid->length = 0;
-	     return (ENOMEM);
+     if (oid->elements == 0) {
+             FREE(oid, sizeof(gss_OID_desc));
+	     return ENOMEM;
      }
-
      if (krb5_ser_unpack_bytes((krb5_octet *) oid->elements,
-                               oid->length, &bp, &remain)) {
+			       oid->length, &bp, &remain)) {
          FREE(oid->elements, oid->length);
-         oid->length = 0;
-         return (EINVAL);
+         FREE(oid, sizeof(gss_OID_desc));
+	 return EINVAL;
      }
      
      /* Read in and check our trailing magic number */
      if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) {
-	FREE (oid->elements, oid->length);
-	oid->length = 0;
-	return (EINVAL);
+         FREE(oid->elements, oid->length);
+         FREE(oid, sizeof(gss_OID_desc));
+	 return (EINVAL);
      }
 
      if (ibuf != KV5M_GSS_OID) {
-	FREE (oid->elements, oid->length);
-	oid->length = 0;
-	return (EINVAL);
+         FREE(oid->elements, oid->length);
+         FREE(oid, sizeof(gss_OID_desc));
+	 return (EINVAL);
      }
 
      *buffer = bp;
      *lenremain = remain;
-     /* *argp = (krb5_pointer) oid; */
+     *argp = (krb5_pointer) oid;
      return 0;
 }
+
 /*ARGSUSED*/
-krb5_error_code
+static krb5_error_code
 kg_oid_size(kcontext, arg, sizep)
     krb5_context	kcontext;
     krb5_pointer	arg;
@@ -159,8 +153,8 @@
    size_t required;
 
    kret = EINVAL;
-   oid = (gss_OID) arg;
-   if (oid)  {
+   /*LINTED*/
+   if ((oid = (gss_OID) arg)) {
       required = 2*sizeof(krb5_int32); /* For the header and trailer */
       required += sizeof(krb5_int32);
       required += oid->length;
@@ -201,7 +195,7 @@
      krb5_int32 ibuf;
      krb5_octet		*bp;
      size_t		remain;
-     krb5_error_code    err;
+     krb5_error_code	err;
 
      bp = *buffer;
      remain = *lenremain;
@@ -215,21 +209,26 @@
 
      err = g_queue_internalize(argp, &bp, &remain);
      if (err)
-        return err;
+	  return err;
 
      /* Read in and check our trailing magic number */
-     if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
-	return (EINVAL);
+     if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) {
+	 g_order_free(argp);
+	 return (EINVAL);
+     }
 
-     if (ibuf != KV5M_GSS_QUEUE)
+     if (ibuf != KV5M_GSS_QUEUE) {
+	 g_order_free(argp);
 	 return (EINVAL);
+     }
 
      *buffer = bp;
      *lenremain = remain;
      return 0;
 }
+
 /*ARGSUSED*/
-krb5_error_code
+static krb5_error_code
 kg_queue_size(kcontext, arg, sizep)
     krb5_context	kcontext;
     krb5_pointer	arg;
@@ -262,44 +261,42 @@
     krb5_gss_ctx_id_rec	*ctx;
     size_t		required;
 
-    KRB5_LOG0(KRB5_INFO, "kg_ctx_size() start \n");
-
     /*
      * krb5_gss_ctx_id_rec requires:
-     *  krb5_int32      for KG_CONTEXT
-     *  krb5_int32      for initiate.
-     *  krb5_int32      for established.
-     *  krb5_int32      for big_endian.
-     *  krb5_int32      for have_acceptor_subkey.
-     *  krb5_int32      for seed_init.
-     *  krb5_int32      for gss_flags.
-     *  sizeof(seed)    for seed
-     *  krb5_int32      for signalg.
-     *  krb5_int32      for cksum_size.
-     *  krb5_int32      for sealalg.
-     *  krb5_int32      for endtime.
-     *  krb5_int32      for flags.
-     *  krb5_int64      for seq_send.
-     *  krb5_int64      for seq_recv.
-     *  ...             for mech_used
-     *  ...             for here
-     *  ...             for there
-     *  ...             for subkey
-     *  ...             for enc
-     *  ...             for seq
-     *  ...             for seqstate
-     *  ...             for auth_context
-     *  krb5_int32      for proto
-     *  krb5_int32      for cksumtype
-     *  ...             for acceptor_subkey
-     *  krb5_int32      for acceptor_key_cksumtype
-     *  krb5_int32      for trailer.
+     *	krb5_int32	for KG_CONTEXT
+     *	krb5_int32	for initiate.
+     *	krb5_int32	for established.
+     *	krb5_int32	for big_endian.
+     *	krb5_int32	for have_acceptor_subkey.
+     *	krb5_int32	for seed_init.
+     *	krb5_int32	for gss_flags.
+     *	sizeof(seed)	for seed
+     *	...		for here
+     *	...		for there
+     *	...		for subkey
+     *  krb5_int32	for signalg.
+     *  krb5_int32	for cksum_size.
+     *  krb5_int32	for sealalg.
+     *	...		for enc
+     *	...		for seq
+     *	krb5_int32	for endtime.
+     *	krb5_int32	for flags.
+     *	krb5_int64	for seq_send.
+     *	krb5_int64	for seq_recv.
+     *	...		for seqstate
+     *	...		for auth_context
+     *	...		for mech_used
+     *	krb5_int32	for proto
+     *	krb5_int32	for cksumtype
+     *	...		for acceptor_subkey
+     *	krb5_int32	for acceptor_key_cksumtype
+     *	krb5_int32	for cred_rcache
+     *	krb5_int32	for trailer.
      */
-
     kret = EINVAL;
-    ctx = (krb5_gss_ctx_id_rec *) arg;
-    if (ctx) { 
-	required = 16*sizeof(krb5_int32);
+    /*LINTED*/
+    if ((ctx = (krb5_gss_ctx_id_rec *) arg)) {
+	required = 17*sizeof(krb5_int32);
 	required += 2*sizeof(krb5_int64);
 	required += sizeof(ctx->seed);
 
@@ -336,28 +333,33 @@
 
 	if (!kret)
 	    kret = kg_oid_size(kcontext,
-			       (krb5_pointer) &ctx->mech_used,
+			       (krb5_pointer) ctx->mech_used,
 			       &required);
 
 	if (!kret && ctx->seqstate)
 	    kret = kg_queue_size(kcontext, ctx->seqstate, &required);
+
 #ifndef PROVIDE_KERNEL_IMPORT
 	if (!kret)
 	    kret = krb5_size_opaque(kcontext,
+				    KV5M_CONTEXT,
+				    (krb5_pointer) ctx->k5_context,
+				    &required);
+	if (!kret)
+	    kret = krb5_size_opaque(kcontext,
 				    KV5M_AUTH_CONTEXT,
 				    (krb5_pointer) ctx->auth_context,
 				    &required);
 #endif
+
 	if (!kret && ctx->acceptor_subkey)
-            kret = krb5_size_opaque(kcontext,
-                                    KV5M_KEYBLOCK,
-                                    (krb5_pointer) ctx->acceptor_subkey,
-                                    &required);
-
+	    kret = krb5_size_opaque(kcontext,
+				    KV5M_KEYBLOCK,
+				    (krb5_pointer) ctx->acceptor_subkey,
+				    &required);
 	if (!kret)
 	    *sizep += required;
     }
-    KRB5_LOG1(KRB5_INFO, "kg_ctx_size() end, kret = %d required = %lu\n", kret, required);
     return(kret);
 }
 
@@ -376,16 +378,20 @@
     size_t		required;
     krb5_octet		*bp;
     size_t		remain;
-    /* SOLARIS KERBEROS: do not use accessor */
+#ifndef _KERNEL
+    krb5int_access kaccess;
 
-    KRB5_LOG0(KRB5_INFO, "kg_ctx_externalize() start\n");
+    kret = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
+    if (kret) 
+        return(kret);
+#endif
 
     required = 0;
     bp = *buffer;
     remain = *lenremain;
     kret = EINVAL;
-    ctx = (krb5_gss_ctx_id_rec *) arg; 
-    if (ctx) {
+    /*LINTED*/
+    if ((ctx = (krb5_gss_ctx_id_rec *) arg)) {
 	kret = ENOMEM;
 	if (!kg_ctx_size(kcontext, arg, &required) &&
 	    (required <= remain)) {
@@ -393,21 +399,21 @@
 	    (void) krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain);
 
 	    /* Now static data */
-            (void) krb5_ser_pack_int32((krb5_int32) ctx->initiate,
-                                       &bp, &remain);
-            (void) krb5_ser_pack_int32((krb5_int32) ctx->established,
-                                       &bp, &remain);
-            (void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian,
-                                       &bp, &remain);
-            (void) krb5_ser_pack_int32((krb5_int32) ctx->have_acceptor_subkey,
-                                       &bp, &remain);
-            (void) krb5_ser_pack_int32((krb5_int32) ctx->seed_init,
-                                       &bp, &remain);
-            (void) krb5_ser_pack_int32((krb5_int32) ctx->gss_flags,
-                                       &bp, &remain);
-            (void) krb5_ser_pack_bytes((krb5_octet *) ctx->seed,
-                                       sizeof(ctx->seed),
-                                       &bp, &remain);
+	    (void) krb5_ser_pack_int32((krb5_int32) ctx->initiate,
+				       &bp, &remain);
+	    (void) krb5_ser_pack_int32((krb5_int32) ctx->established,
+				       &bp, &remain);
+	    (void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian,
+				       &bp, &remain);
+	    (void) krb5_ser_pack_int32((krb5_int32) ctx->have_acceptor_subkey,
+				       &bp, &remain);
+	    (void) krb5_ser_pack_int32((krb5_int32) ctx->seed_init,
+				       &bp, &remain);
+	    (void) krb5_ser_pack_int32((krb5_int32) ctx->gss_flags,
+				       &bp, &remain);
+	    (void) krb5_ser_pack_bytes((krb5_octet *) ctx->seed,
+				       sizeof(ctx->seed),
+				       &bp, &remain);
 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->signalg,
 				       &bp, &remain);
 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->cksum_size,
@@ -418,16 +424,23 @@
 				       &bp, &remain);
 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->krb_flags,
 				       &bp, &remain);
+#ifndef _KERNEL
+	    (void) (*kaccess.krb5_ser_pack_int64)((krb5_int64) ctx->seq_send,
+				       &bp, &remain);
+	    (void) (*kaccess.krb5_ser_pack_int64)((krb5_int64) ctx->seq_recv,
+				       &bp, &remain);
+#else
 	    (void) krb5_ser_pack_int64((krb5_int64) ctx->seq_send,
 				       &bp, &remain);
 	    (void) krb5_ser_pack_int64((krb5_int64) ctx->seq_recv,
 				       &bp, &remain);
+#endif
 
 	    /* Now dynamic data */
 	    kret = 0;
 
-	    if (!kret && &(ctx->mech_used))
-		 kret = kg_oid_externalize(kcontext, &(ctx->mech_used),
+	    if (!kret && ctx->mech_used)
+		 kret = kg_oid_externalize(kcontext, ctx->mech_used,
 					   &bp, &remain); 
 	    
 	    if (!kret && ctx->here)
@@ -467,34 +480,42 @@
 #ifndef PROVIDE_KERNEL_IMPORT
 	    if (!kret)
 		kret = krb5_externalize_opaque(kcontext,
+					       KV5M_CONTEXT,
+					       (krb5_pointer) ctx->k5_context,
+					       &bp, &remain);
+	    if (!kret)
+		kret = krb5_externalize_opaque(kcontext,
 					       KV5M_AUTH_CONTEXT,
 					       (krb5_pointer) ctx->auth_context,
 					       &bp, &remain);
 #endif
-            if (!kret)
+	    if (!kret)
 		kret = krb5_ser_pack_int32((krb5_int32) ctx->proto,
-                                           &bp, &remain);
-            if (!kret)
+					   &bp, &remain);
+	    if (!kret)
 		kret = krb5_ser_pack_int32((krb5_int32) ctx->cksumtype,
-                                           &bp, &remain);
-            if (!kret && ctx->acceptor_subkey)
+					   &bp, &remain);
+	    if (!kret && ctx->acceptor_subkey)
 		kret = krb5_externalize_opaque(kcontext,
-                                               KV5M_KEYBLOCK,
-                                               (krb5_pointer) ctx->acceptor_subkey,
-                                               &bp, &remain);
-            if (!kret)
+					       KV5M_KEYBLOCK,
+					       (krb5_pointer) ctx->acceptor_subkey,
+					       &bp, &remain);
+	    if (!kret)
 		kret = krb5_ser_pack_int32((krb5_int32) ctx->acceptor_subkey_cksumtype,
-                                           &bp, &remain);
+					   &bp, &remain);
 
 	    if (!kret)
-		(void) krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain);
+		kret = krb5_ser_pack_int32((krb5_int32) ctx->cred_rcache,
+					   &bp, &remain);
+	    /* trailer */
+	    if (!kret)
+		kret = krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain);
 	    if (!kret) {
 		*buffer = bp;
 		*lenremain = remain;
 	    }
 	}
     }
-    KRB5_LOG(KRB5_INFO, "kg_ctx_externalize() end, kret = %d\n", kret);
     return(kret);
 }
 
@@ -513,8 +534,13 @@
     krb5_int32		ibuf;
     krb5_octet		*bp;
     size_t		remain;
+#ifndef _KERNEL
+    krb5int_access kaccess;
 
-    KRB5_LOG0(KRB5_INFO, "kg_ctx_internalize() start\n");
+    kret = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
+    if (kret)
+        return(kret);
+#endif
 
     bp = *buffer;
     remain = *lenremain;
@@ -526,26 +552,28 @@
 	kret = ENOMEM;
 
 	/* Get a context */
-	if ((remain >= (16*sizeof(krb5_int32)
+	if ((remain >= (17*sizeof(krb5_int32)
 			+ 2*sizeof(krb5_int64)
 			+ sizeof(ctx->seed))) &&
 	    (ctx = (krb5_gss_ctx_id_rec *)
 	     xmalloc(sizeof(krb5_gss_ctx_id_rec)))) {
 	    (void) memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec));
 
+	    ctx->k5_context = kcontext;
+
 	    /* Get static data */
-            (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
-            ctx->initiate = (int) ibuf;
-            (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
-            ctx->established = (int) ibuf;
-            (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
-            ctx->big_endian = (int) ibuf;
-            (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
-            ctx->have_acceptor_subkey = (int) ibuf;
-            (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
-            ctx->seed_init = (int) ibuf;
-            (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
-            ctx->gss_flags = (int) ibuf;
+	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+	    ctx->initiate = (int) ibuf;
+	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+	    ctx->established = (int) ibuf;
+	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+	    ctx->big_endian = (int) ibuf;
+	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+	    ctx->have_acceptor_subkey = (int) ibuf;
+	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+	    ctx->seed_init = (int) ibuf;
+	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+	    ctx->gss_flags = (int) ibuf;
 	    (void) krb5_ser_unpack_bytes((krb5_octet *) ctx->seed,
 					 sizeof(ctx->seed),
 					 &bp, &remain);
@@ -559,11 +587,23 @@
 	    ctx->endtime = (krb5_timestamp) ibuf;
 	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
 	    ctx->krb_flags = (krb5_flags) ibuf;
-	    (void) krb5_ser_unpack_int64((krb5_int64 *) (&ctx->seq_send), &bp, &remain);
-	    (void) krb5_ser_unpack_int64((krb5_int64 *) (&ctx->seq_recv), &bp, &remain);
+#ifndef _KERNEL
+	    (void) (*kaccess.krb5_ser_unpack_int64)((krb5_int64 *)&ctx->seq_send, &bp, &remain);
+	    kret = (*kaccess.krb5_ser_unpack_int64)((krb5_int64 *)&ctx->seq_recv, &bp, &remain);
+#else
+	    (void) krb5_ser_unpack_int64((krb5_int64 *) (&ctx->seq_send),
+					&bp, &remain);
+	    kret = krb5_ser_unpack_int64((krb5_int64 *) (&ctx->seq_recv),
+					&bp, &remain);
+#endif
+	    if (kret) {
+		xfree_wrap(ctx, sizeof (krb5_gss_ctx_id_rec));
+		return kret;
+	    }
+
 	    if ((kret = kg_oid_internalize(kcontext,
-				(krb5_pointer)&ctx->mech_used, &bp,
-				&remain))) {
+					(krb5_pointer *) &ctx->mech_used, &bp,
+					   &remain))) {
 		 if (kret == EINVAL)
 		      kret = 0;
 	    }
@@ -614,8 +654,15 @@
 		if (kret == EINVAL)
 		    kret = 0;
 	    }
+
 #ifndef PROVIDE_KERNEL_IMPORT
-     	    if (!kret)
+	    if (!kret)
+		kret = krb5_internalize_opaque(kcontext,
+					       KV5M_CONTEXT,
+				       (krb5_pointer *) &ctx->k5_context,
+				       &bp, &remain);
+
+	    if (!kret)
 		kret = krb5_internalize_opaque(kcontext,
 					       KV5M_AUTH_CONTEXT,
 				       (krb5_pointer *) &ctx->auth_context,
@@ -633,26 +680,26 @@
 						(krb5_pointer *) &ctx->acceptor_subkey,
 						&bp, &remain))) {
 		if (kret == EINVAL)
-                    kret = 0;
-            }
-            if (!kret)
+		    kret = 0;
+	    }
+	    if (!kret)
+		kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+	    ctx->cred_rcache = ibuf;
+	    if (!kret)
 		kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
-            ctx->acceptor_subkey_cksumtype = ibuf;
-done:
+	    ctx->acceptor_subkey_cksumtype = ibuf;
+
 	    /* Get trailer */
-            if (!kret)
+	    if (!kret)
 		kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
-
-            if (!kret && ibuf != KG_CONTEXT)
+	    if (!kret && ibuf != KG_CONTEXT)
 		kret = EINVAL;
 
-            if (!kret) {
+	    if (!kret) {
 		*buffer = bp;
 		*lenremain = remain;
 		*argp = (krb5_pointer) ctx;
 	    } else {
-		if (!kret && (ibuf != KG_CONTEXT))
-		    kret = EINVAL;
 		if (ctx->seq)
 		    krb5_free_keyblock(kcontext, ctx->seq);
 		if (ctx->enc)
@@ -667,8 +714,5 @@
 	    }
 	}
     }
-
-    KRB5_LOG(KRB5_INFO, "kg_ctx_internalize() end kret = %d\n", kret);
-
     return(kret);
 }
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/sign.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/sign.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2002 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -27,79 +27,46 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
 
 /*
- * $Id: sign.c,v 1.11 1996/07/22 20:34:35 marc Exp $
+ * $Id: sign.c 16171 2004-03-15 17:45:01Z raeburn $
  */
+
 /*ARGSUSED*/
-
 OM_uint32
-krb5_gss_sign(ctx, minor_status, context_handle,
+krb5_gss_sign(minor_status, context_handle,
 	      qop_req, message_buffer, 
 	      message_token
 #ifdef	 _KERNEL
-		, gssd_ctx_verifier
+	    , gssd_ctx_verifier
 #endif
-	)
-     void      *ctx;
+	    )
      OM_uint32 *minor_status;
      gss_ctx_id_t context_handle;
      int qop_req;
      gss_buffer_t message_buffer;
      gss_buffer_t message_token;
 #ifdef	 _KERNEL
-	OM_uint32 gssd_ctx_verifier;
+     OM_uint32 gssd_ctx_verifier;
 #endif
 {
-   krb5_context context;
-   OM_uint32	status;
-
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, &context)))
-      return(GSS_S_FAILURE);
-#endif
-
-   mutex_lock(&krb5_mutex);
-
-   context = ctx;
-   status = kg_seal(context, minor_status, context_handle, 0,
+     return(kg_seal(minor_status, context_handle, 0,
 		  qop_req, message_buffer, NULL,
-		  message_token, KG_TOK_SIGN_MSG);
-   mutex_unlock(&krb5_mutex);
-   return(status);
+		  message_token, KG_TOK_SIGN_MSG));
 }
 
 /* V2 interface */
 OM_uint32
-krb5_gss_get_mic(ctx, minor_status, context_handle, qop_req,
+krb5_gss_get_mic(minor_status, context_handle, qop_req,
 		 message_buffer, message_token)
-    void                *ctx;
     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;
 {
-   krb5_context context;
-   OM_uint32	status;
-
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, &context)))
-      return(GSS_S_FAILURE);
-#endif
-
-   mutex_lock(&krb5_mutex);
-   
-   context = ctx;
-    
-   status = kg_seal(context, minor_status, context_handle, 0,
+     return(kg_seal(minor_status, context_handle, 0,
 		   (int) qop_req, message_buffer, NULL,
-		   message_token, KG_TOK_MIC_MSG);
-   mutex_unlock(&krb5_mutex);
-   return(status);
+		   message_token, KG_TOK_MIC_MSG));
 }
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/unseal.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/unseal.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,7 +1,7 @@
 /* EXPORT DELETE START */
 
 /*
- * Copyright 2001-2003 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -29,21 +29,21 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
 
 /*
- * $Id: unseal.c,v 1.10 1996/07/22 20:34:37 marc Exp $
+ * $Id: unseal.c 16171 2004-03-15 17:45:01Z raeburn $
  */
+
 /*ARGSUSED*/
 OM_uint32
-krb5_gss_unseal(ctx, minor_status, context_handle,
+krb5_gss_unseal(minor_status, context_handle,
 		input_message_buffer, output_message_buffer,
 		conf_state, qop_state
 #ifdef	 _KERNEL
-		, gssd_ctx_verifier
+ 		, gssd_ctx_verifier
 #endif
-	)
-     void	*ctx;
+		)
      OM_uint32 *minor_status;
      gss_ctx_id_t context_handle;
      gss_buffer_t input_message_buffer;
@@ -51,45 +51,19 @@
      int *conf_state;
      int *qop_state;
 #ifdef	 _KERNEL
-	OM_uint32 gssd_ctx_verifier;
+     OM_uint32 gssd_ctx_verifier;
 #endif
 {
-   krb5_context context;
-   OM_uint32	status;
-
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-   if (GSS_ERROR(kg_get_context(minor_status, &context)))
-      return(GSS_S_FAILURE);
-#endif
-
-   mutex_lock(&krb5_mutex);
-   context = ctx;
-   status  = kg_unseal(context, minor_status, context_handle,
+     return(kg_unseal(minor_status, context_handle,
 		    input_message_buffer, output_message_buffer,
-		    conf_state, qop_state, KG_TOK_SEAL_MSG);
-   mutex_unlock(&krb5_mutex);
-#ifdef	KRB5_NO_PRIVACY
-	/*
-	 * Can't be paranoid enough;
-	 * if someone plugs in their version of kg_unseal
-	 * that does decryption we want to 
-	 * disallow that too.
-	*/
-	if (conf_state && *conf_state) 
-   		return (GSS_S_FAILURE);
-#endif
-   return(status);
+		    conf_state, qop_state, KG_TOK_SEAL_MSG));
 }
 
 /* V2 interface */
-/*ARGSUSED*/
 OM_uint32
-krb5_gss_unwrap(ctx, minor_status, context_handle,
+krb5_gss_unwrap(minor_status, context_handle,
 		input_message_buffer, output_message_buffer,
 		conf_state, qop_state)
-    void		*ctx;
     OM_uint32		*minor_status;
     gss_ctx_id_t	context_handle;
     gss_buffer_t	input_message_buffer;
@@ -98,29 +72,18 @@
     gss_qop_t		*qop_state;
 {
 #ifdef	KRB5_NO_PRIVACY
-   return (GSS_S_FAILURE);
+    return (GSS_S_FAILURE);
 #else
-   OM_uint32		rstat;
-   int			qstate;
-   krb5_context context;
+    OM_uint32		rstat;
+    int			qstate;
 
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-    if (GSS_ERROR(kg_get_context(minor_status, &context)))
-       return(GSS_S_FAILURE);
-#endif
-
-   mutex_lock(&krb5_mutex);
-   context = ctx;
-
-   rstat = kg_unseal(context, minor_status, context_handle,
-		      input_message_buffer, output_message_buffer,
-		      conf_state, &qstate, KG_TOK_WRAP_MSG);
-   if (!rstat && qop_state)
+    rstat = kg_unseal(minor_status, context_handle,
+		    input_message_buffer, output_message_buffer,
+		    conf_state, &qstate, KG_TOK_WRAP_MSG);
+    if (!rstat && qop_state)
 	*qop_state = (gss_qop_t) qstate;
-   mutex_unlock(&krb5_mutex);
-   return(rstat);
+    return(rstat);
 #endif
 }
+
 /* EXPORT DELETE END */
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_crypt.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_crypt.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -122,7 +122,7 @@
      krb5_pointer iv;
      krb5_pointer in;
      krb5_pointer out;
-     int length;
+     unsigned int length;
 {
    krb5_error_code code;
    size_t blocksize;
@@ -169,7 +169,7 @@
      krb5_pointer iv;
      krb5_pointer in;
      krb5_pointer out;
-     int length;
+     unsigned int length;
 {
    krb5_error_code code;
    size_t blocksize;
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_ordering.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_ordering.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -32,6 +32,12 @@
  */
 
 /*
+ * SUNW15resync
+ * Left this alone (MIT version causes STC gss_verify_mic(6) test failure)
+ * as it has bug fixes that MIT does not yet.
+ */
+
+/*
  * functions to check sequence numbers for replay and sequencing
  */
 
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_seed.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_seed.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,4 +1,5 @@
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
+
 /*
  * Copyright 1993 by OpenVision Technologies, Inc.
  * 
@@ -21,11 +22,10 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_krb5.h>
-
-/*
- * $Id: util_seed.c,v 1.13.6.1 2000/05/31 17:17:39 raeburn Exp $
- */
+#include "gssapiP_krb5.h"
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
 
 static unsigned char zeros[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
 
@@ -39,7 +39,8 @@
    krb5_keyblock *tmpkey;
    int i;
 
-   if (code = krb5_copy_keyblock(context, key, &tmpkey))
+   code = krb5_copy_keyblock(context, key, &tmpkey);
+   if (code)
       return(code);
 
    /* reverse the key bytes, as per spec */
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_seqnum.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_seqnum.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,7 @@
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
+
 /*
+  * Copyright2001 by the Massachusetts Institute of Technology.
  * Copyright 1993 by OpenVision Technologies, Inc.
  * 
  * Permission to use, copy, modify, distribute, and sell this software
@@ -21,10 +23,11 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
+#include "k5-int.h"
 
 /*
- * $Id: util_seqnum.c,v 1.9.6.1 2000/05/31 17:17:39 raeburn Exp $
+ * $Id: util_seqnum.c 15007 2002-11-15 16:12:20Z epeisach $
  */
 
 krb5_error_code
@@ -38,22 +41,23 @@
 {
    unsigned char plain[8];
 
-   plain[4] = (unsigned char) direction;
-   plain[5] = (unsigned char) direction;
-   plain[6] = (unsigned char) direction;
-   plain[7] = (unsigned char) direction;
+   plain[4] = direction;
+   plain[5] = direction;
+   plain[6] = direction;
+   plain[7] = direction;
    if (key->enctype == ENCTYPE_ARCFOUR_HMAC ) {
-	/* Yes, Microsoft used big-endian sequence number.*/
-	plain[0] = (seqnum>>24) & 0xff;
-	plain[1] = (seqnum>>16) & 0xff;
-	plain[2] = (seqnum>>8) & 0xff;
-	plain[3] = seqnum & 0xff;
-	return kg_arcfour_docrypt (context, key, 0,
+     /* Yes, Microsoft used big-endian sequence number.*/
+     plain[0] = (seqnum>>24) & 0xff;
+     plain[1] = (seqnum>>16) & 0xff;
+     plain[2] = (seqnum>>8) & 0xff;
+     plain[3] = seqnum & 0xff;
+     return kg_arcfour_docrypt (context, key, 0, 
 				cksum, 8,
 				&plain[0], 8,
 				buf);
-
+     
    }
+     
    plain[0] = (unsigned char) (seqnum&0xff);
    plain[1] = (unsigned char) ((seqnum>>8)&0xff);
    plain[2] = (unsigned char) ((seqnum>>16)&0xff);
@@ -73,13 +77,16 @@
    krb5_error_code code;
    unsigned char plain[8];
 
-   if (key->enctype == ENCTYPE_ARCFOUR_HMAC)
-	code = kg_arcfour_docrypt (context, key, 0,
-			cksum, 8, buf, 8, plain);
-   else
-   	code = kg_decrypt(context, key, KG_USAGE_SEQ, cksum, buf, plain, 8);
+   if (key->enctype == ENCTYPE_ARCFOUR_HMAC) {
+     code = kg_arcfour_docrypt (context, key, 0,
+				cksum, 8,
+				buf, 8,
+				plain);
+   } else {
+     code = kg_decrypt(context, key, KG_USAGE_SEQ, cksum, buf, plain, 8);
+   }
    if (code)
-	return (code);
+      return(code);
 
    if ((plain[4] != plain[5]) ||
        (plain[4] != plain[6]) ||
@@ -87,14 +94,14 @@
       return((krb5_error_code) KG_BAD_SEQ);
 
    *direction = plain[4];
-
-   if (key->enctype == ENCTYPE_ARCFOUR_HMAC)
-	*seqnum = (plain[3]|(plain[2]<<8) | (plain[1]<<16)| (plain[0]<<24));
-   else
-        *seqnum = ((plain[0]) |
+   if (key->enctype == ENCTYPE_ARCFOUR_HMAC) {
+     *seqnum = (plain[3]|(plain[2]<<8) | (plain[1]<<16)| (plain[0]<<24));
+   } else {
+     *seqnum = ((plain[0]) |
 	      (plain[1]<<8) |
 	      (plain[2]<<16) |
 	      (plain[3]<<24));
+   }
 
    return(0);
 }
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_set.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_set.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,4 +1,10 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
+
 /*
  * Copyright 1995 by OpenVision Technologies, Inc.
  * 
@@ -22,26 +28,27 @@
  */
 
 /*
- * $Id: util_set.c,v 1.1 1996/04/12 00:39:41 marc Exp $
+ * $Id: util_set.c 16165 2004-03-14 05:31:43Z raeburn $
  */
 
-#include <mechglueP.h>
-#include <gssapiP_generic.h>
+#include <mechglueP.h>  /* SUNW15resync - for MALLOC/FREE */
+#include "gssapiP_generic.h"
 
-struct _g_set {
+struct _g_set_elt {
    void *key;
    void *value;
-   struct _g_set *next;
+   struct _g_set_elt *next;
 };
 
-int g_set_init(g_set *s)
+int g_set_init(g_set_elt *s)
 {
    *s = NULL;
 
    return(0);
 }
 
-int g_set_destroy(g_set *s)
+#if 0
+int g_set_destroy(g_set_elt *s)
 {
    g_set next;
 
@@ -53,12 +60,13 @@
 
    return(0);
 }
+#endif
 
-int g_set_entry_add(g_set *s, void *key, void *value)
+int g_set_entry_add(g_set_elt *s, void *key, void *value)
 {
-   g_set first;
+   g_set_elt first;
 
-   if ((first = (struct _g_set *) MALLOC(sizeof(struct _g_set))) == NULL)
+   if ((first = (struct _g_set_elt *) MALLOC(sizeof(struct _g_set_elt))) == NULL)
       return(ENOMEM);
 
    first->key = key;
@@ -70,14 +78,14 @@
    return(0);
 }
 
-int g_set_entry_delete(g_set *s, void *key)
+int g_set_entry_delete(g_set_elt *s, void *key)
 {
-   g_set *p;
+   g_set_elt *p;
 
    for (p=s; *p; p = &((*p)->next)) {
       if ((*p)->key == key) {
-	 g_set next = (*p)->next;
-	 FREE(*p, sizeof(struct _g_set));
+	 g_set_elt next = (*p)->next;
+	 FREE(*p, sizeof(struct _g_set_elt));
 	 *p = next;
 
 	 return(0);
@@ -87,9 +95,9 @@
    return(-1);
 }
 
-int g_set_entry_get(g_set *s, void *key, void **value)
+int g_set_entry_get(g_set_elt *s, void *key, void **value)
 {
-   g_set p;
+   g_set_elt p;
 
    for (p = *s; p; p = p->next) {
       if (p->key == key) {
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_token.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_token.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,4 +1,10 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
+
 /*
  * Copyright 1993 by OpenVision Technologies, Inc.
  * 
@@ -21,18 +27,21 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_generic.h>
+#include "gssapiP_generic.h"
+
+#ifdef _KERNEL
+#include <sys/systm.h>
+#else
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#include <limits.h>
+#include <string.h>
+#endif /* _KERNEL */
+
 
 /*
- * SUNW14resync
- * This is defed in autoconf but we don't grok it for kernel (why?).
- */
-#ifndef SIZEOF_INT
-#define SIZEOF_INT 4
-#endif
-
-/*
- * $Id: util_token.c,v 1.20.2.1 2003/12/16 02:56:16 tlyu Exp $
+ * $Id: util_token.c 17987 2006-05-09 11:31:02Z epeisach $
  */
 
 /* XXXX this code currently makes the assumption that a mech oid will
@@ -53,9 +62,9 @@
 					bytes 2,n are the token data
 
 Note that the token type field is a feature of RFC 1964 mechanisms and
-is not used by other GSSAPI mechanisms.	 As such, a token type of -1
+is not used by other GSSAPI mechanisms.  As such, a token type of -1
 is interpreted to mean that no token type should be expected or
-generated.
+generated. 
 
 For the purposes of this abstraction, the token "header" consists of
 the sequence tag and length octets, the mech OID DER encoding, and the
@@ -64,14 +73,14 @@
 
 */
 
-static int der_length_size(length)
+static unsigned int der_length_size(length)
      int length;
 {
    if (length < (1<<7))
       return(1);
    else if (length < (1<<8))
       return(2);
-#if (SIZEOF_INT == 2)
+#if INT_MAX == 0x7fff
    else
        return(3);
 #else
@@ -92,7 +101,7 @@
       *(*buf)++ = (unsigned char) length;
    } else {
       *(*buf)++ = (unsigned char) (der_length_size(length)+127);
-#if (SIZEOF_INT > 2)
+#if INT_MAX > 0x7fff
       if (length >= (1<<24))
 	 *(*buf)++ = (unsigned char) (length>>24);
       if (length >= (1<<16))
@@ -121,7 +130,7 @@
    if (sf & 0x80) {
       if ((sf &= 0x7f) > ((*bufsize)-1))
 	 return(-1);
-      if (sf > SIZEOF_INT)
+      if (sf > sizeof(int))
 	  return (-1);
       ret = 0;
       for (; sf; sf--) {
@@ -137,8 +146,8 @@
 
 /* returns the length of a token, given the mech oid and the body size */
 
-int g_token_size(mech, body_size)
-     gss_OID mech;
+unsigned int g_token_size(mech, body_size)
+     const gss_OID_desc * mech;
      unsigned int body_size;
 {
    /* set body_size to sequence contents size */
@@ -150,19 +159,20 @@
    be the right size.  buf is advanced past the token header */
 
 void g_make_token_header(mech, body_size, buf, tok_type)
-     gss_OID mech;
-     int body_size;
+     const gss_OID_desc * mech;
+     unsigned int body_size;
      unsigned char **buf;
      int tok_type;
 {
    *(*buf)++ = 0x60;
-   der_write_length(buf, (int) (4 + mech->length + body_size));
+   der_write_length(buf,
+       (tok_type == -1) ? 2 : (int) (4 + mech->length + body_size));
    *(*buf)++ = 0x06;
    *(*buf)++ = (unsigned char) mech->length;
-   TWRITE_STR(*buf, mech->elements, ((int) mech->length));
+   TWRITE_STR(*buf, mech->elements, mech->length);
    if (tok_type != -1) {
-	*(*buf)++ = (unsigned char) ((tok_type>>8)&0xff);
-	*(*buf)++ = (unsigned char) (tok_type&0xff);
+       *(*buf)++ = (unsigned char) ((tok_type>>8)&0xff);
+       *(*buf)++ = (unsigned char) (tok_type&0xff);
    }
 }
 
@@ -177,12 +187,12 @@
 
 gss_int32 g_verify_token_header(mech, body_size, buf_in, tok_type, toksize_in,
 				wrapper_required)
-	gss_OID mech;
-	unsigned int *body_size;
-	unsigned char **buf_in;
-	int tok_type;
-	unsigned int toksize_in;
-	int wrapper_required;
+     const gss_OID_desc * mech;
+     unsigned int *body_size;
+     unsigned char **buf_in;
+     int tok_type;
+     unsigned int toksize_in;
+     int wrapper_required;
 {
    unsigned char *buf = *buf_in;
    int seqsize;
@@ -190,43 +200,43 @@
    int toksize = toksize_in;
 
    if ((toksize-=1) < 0)
-	return(G_BAD_TOK_HEADER);
+      return(G_BAD_TOK_HEADER);
    if (*buf++ != 0x60) {
-	if (wrapper_required)
+       if (wrapper_required)
 	   return(G_BAD_TOK_HEADER);
-	buf--;
-	toksize++;
-	goto skip_wrapper;
+       buf--;
+       toksize++;
+       goto skip_wrapper;
    }
 
    if ((seqsize = der_read_length(&buf, &toksize)) < 0)
-	return(G_BAD_TOK_HEADER);
+      return(G_BAD_TOK_HEADER);
 
    if (seqsize != toksize)
-	return(G_BAD_TOK_HEADER);
+      return(G_BAD_TOK_HEADER);
 
    if ((toksize-=1) < 0)
-	return(G_BAD_TOK_HEADER);
+      return(G_BAD_TOK_HEADER);
    if (*buf++ != 0x06)
-	return(G_BAD_TOK_HEADER);
-
+      return(G_BAD_TOK_HEADER);
+ 
    if ((toksize-=1) < 0)
-	return(G_BAD_TOK_HEADER);
+      return(G_BAD_TOK_HEADER);
    toid.length = *buf++;
 
    if ((toksize-=toid.length) < 0)
-	return(G_BAD_TOK_HEADER);
+      return(G_BAD_TOK_HEADER);
    toid.elements = buf;
    buf+=toid.length;
 
-   if (! g_OID_equal(&toid, mech))
-	return  G_WRONG_MECH;
+   if (! g_OID_equal(&toid, mech)) 
+       return  G_WRONG_MECH;
 skip_wrapper:
    if (tok_type != -1) {
-	if ((toksize-=2) < 0)
+       if ((toksize-=2) < 0)
 	   return(G_BAD_TOK_HEADER);
 
-	if ((*buf++ != ((tok_type>>8)&0xff)) ||
+       if ((*buf++ != ((tok_type>>8)&0xff)) ||
 	   (*buf++ != (tok_type&0xff)))
 	   return(G_WRONG_TOKID);
    }
@@ -235,4 +245,3 @@
 
    return 0;
 }
-
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/util_validate.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/util_validate.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -28,14 +28,17 @@
  */
 
 /*
- * $Id: util_validate.c,v 1.8 1996/08/28 21:50:37 tytso Exp $
+ * $Id: util_validate.c 16475 2004-06-17 02:23:21Z raeburn $
  */
 
 /*
  * functions to validate name, credential, and context handles
  */
 
-#include <gssapiP_generic.h>
+#include "gssapiP_generic.h"
+#ifndef	_KERNEL
+#include "gss_libinit.h"
+#endif
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -48,10 +51,12 @@
 #include <limits.h>
 #endif
 
+
 #ifdef HAVE_BSD_DB
 #include <sys/file.h>
 #include <db.h>
 
+
 static const int one = 1;
 static const DBT dbtone = { (void *) &one, sizeof(one) };
 
@@ -64,19 +69,36 @@
 #define V_NAME		1
 #define V_CRED_ID	2
 #define V_CTX_ID	3
+#define V_LCTX_ID	4
+
+/* SUNW15resync
+   beware some of the uses below of type look dubious but seem
+   to have been working in Solaris for a long time */
 
 /* All these functions return 0 on failure, and non-zero on success */
 
 static int g_save(db, type, ptr)
-     void **db;
+     g_set *db;
      int type;
      void *ptr;
 {
+   int ret;
 #ifdef HAVE_BSD_DB
-   DB **vdb = (DB **) db;
+   DB **vdb;
    vkey vk;
    DBT key;
 
+#ifndef	_KERNEL
+   ret = gssint_initialize_library();
+   if (ret)
+       return 0;
+#endif
+   ret = k5_mutex_lock(&db->mutex);
+   if (ret)
+       return 0;
+
+   vdb = (DB **) &db->data;
+
    if (!*vdb)
       *vdb = dbopen(NULL, O_CREAT|O_RDWR, O_CREAT|O_RDWR, DB_HASH, NULL);
 
@@ -86,30 +108,57 @@
    key.data = &vk;
    key.size = sizeof(vk);
 
-   return((*((*vdb)->put))(*vdb, &key, &dbtone, 0) == 0);
+   ret = ((*((*vdb)->put))(*vdb, &key, &dbtone, 0) == 0);
+   (void) k5_mutex_unlock(&db->mutex);
+   return ret;
 #else
-   g_set *gs = (g_set *) db;
+   g_set_elt *gs;
+
+#ifndef _KERNEL
+   ret = gssint_initialize_library();
+   if (ret)
+       return 0;
+#endif
+   ret = k5_mutex_lock(&db->mutex);
+   if (ret)
+       return 0;
+
+   gs = (g_set_elt *) &db->data;
 
    if (!*gs)
-      if (g_set_init(gs))
+      if (g_set_init(gs)) {
+	 (void) k5_mutex_unlock(&db->mutex);
 	 return(0);
+      }
 
-   return(g_set_entry_add(gs, ptr, (void *)(intptr_t)type) == 0);
+   /* SUNW15resync */
+   ret = (g_set_entry_add(gs, ptr, (void *)(intptr_t)type) == 0);
+
+   (void) k5_mutex_unlock(&db->mutex);
+   return ret;
 #endif
 }
 
 static int g_validate(db, type, ptr)
-     void **db;
+     g_set *db;
      int type;
      void *ptr;
 {
+   int ret;
 #ifdef HAVE_BSD_DB
-   DB **vdb = (DB **) db;
+   DB **vdb;
    vkey vk;
    DBT key, value;
 
-   if (!*vdb)
+   ret = k5_mutex_lock(&db->mutex);
+   if (ret)
+       return 0;
+
+   vdb = (DB **) &db->data;
+   if (!*vdb) {
+      (void) k5_mutex_unlock(&db->mutex);
       return(0);
+   }
 
    vk.type = type;
    vk.ptr = ptr;
@@ -117,38 +166,58 @@
    key.data = &vk;
    key.size = sizeof(vk);
 
-   if ((*((*vdb)->get))(*vdb, &key, &value, 0))
+   if ((*((*vdb)->get))(*vdb, &key, &value, 0)) {
+      (void) k5_mutex_unlock(&db->mutex);
       return(0);
+   }
 
+   (void) k5_mutex_unlock(&db->mutex);
    return((value.size == sizeof(one)) &&
 	  (*((int *) value.data) == one));
 #else
-   g_set *gs = (g_set *) db;
+   g_set_elt *gs;
    void *value;
 
-   if (!*gs)
-      return(0);
+   ret = k5_mutex_lock(&db->mutex);
+   if (ret)
+       return 0;
 
-   if (g_set_entry_get(gs, ptr, (void **) &value))
+   gs = (g_set_elt *) &db->data;
+   if (!*gs) {
+      (void) k5_mutex_unlock(&db->mutex);
       return(0);
+   }
 
-   return((intptr_t)value == (intptr_t)type);
+   if (g_set_entry_get(gs, ptr, (void **) &value)) {
+      (void) k5_mutex_unlock(&db->mutex);
+      return(0);
+   }
+   (void) k5_mutex_unlock(&db->mutex);
+   return((intptr_t)value == (intptr_t)type); /* SUNW15resync */
 #endif
 }
 
 /*ARGSUSED*/
 static int g_delete(db, type, ptr)
-     void **db;
+     g_set *db;
      int type;
      void *ptr;
 {
+   int ret;
 #ifdef HAVE_BSD_DB
-   DB **vdb = (DB **) db;
+   DB **vdb;
    vkey vk;
    DBT key;
 
-   if (!*vdb)
+   ret = k5_mutex_lock(&db->mutex);
+   if (ret)
+       return 0;
+
+   vdb = (DB **) &db->data;
+   if (!*vdb) {
+      (void) k5_mutex_unlock(&db->mutex);
       return(0);
+   }
 
    vk.type = type;
    vk.ptr = ptr;
@@ -156,16 +225,27 @@
    key.data = &vk;
    key.size = sizeof(vk);
 
-   return((*((*vdb)->del))(*vdb, &key, 0) == 0);
+   ret = ((*((*vdb)->del))(*vdb, &key, 0) == 0);
+   (void) k5_mutex_unlock(&db->mutex);
+   return ret;
 #else
-   g_set *gs = (g_set *) db;
+   g_set_elt *gs;
+
+   ret = k5_mutex_lock(&db->mutex);
+   if (ret)
+       return 0;
 
-   if (!*gs)
+   gs = (g_set_elt *) &db->data;
+   if (!*gs) {
+      (void) k5_mutex_unlock(&db->mutex);
       return(0);
+   }
 
-   if (g_set_entry_delete(gs, ptr))
+   if (g_set_entry_delete(gs, ptr)) {
+      (void) k5_mutex_unlock(&db->mutex);
       return(0);
-
+   }
+   (void) k5_mutex_unlock(&db->mutex);
    return(1);
 #endif
 }
@@ -175,63 +255,82 @@
 /* save */
 
 int g_save_name(vdb, name)
-     void **vdb;
+     g_set *vdb;
      gss_name_t name;
 {
    return(g_save(vdb, V_NAME, (void *) name));
 }
 int g_save_cred_id(vdb, cred)
-     void **vdb;
+     g_set *vdb;
      gss_cred_id_t cred;
 {
    return(g_save(vdb, V_CRED_ID, (void *) cred));
 }
 int g_save_ctx_id(vdb, ctx)
-     void **vdb;
+     g_set *vdb;
      gss_ctx_id_t ctx;
 {
    return(g_save(vdb, V_CTX_ID, (void *) ctx));
 }
+int g_save_lucidctx_id(vdb, lctx)
+     g_set *vdb;
+     void *lctx;
+{
+   return(g_save(vdb, V_LCTX_ID, (void *) lctx));
+}
+
 
 /* validate */
 
 int g_validate_name(vdb, name)
-     void **vdb;
+     g_set *vdb;
      gss_name_t name;
 {
    return(g_validate(vdb, V_NAME, (void *) name));
 }
 int g_validate_cred_id(vdb, cred)
-     void **vdb;
+     g_set *vdb;
      gss_cred_id_t cred;
 {
    return(g_validate(vdb, V_CRED_ID, (void *) cred));
 }
 int g_validate_ctx_id(vdb, ctx)
-     void **vdb;
+     g_set *vdb;
      gss_ctx_id_t ctx;
 {
    return(g_validate(vdb, V_CTX_ID, (void *) ctx));
 }
+int g_validate_lucidctx_id(vdb, lctx)
+     g_set *vdb;
+     void *lctx;
+{
+   return(g_validate(vdb, V_LCTX_ID, (void *) lctx));
+}
 
 /* delete */
 
 int g_delete_name(vdb, name)
-     void **vdb;
+     g_set *vdb;
      gss_name_t name;
 {
    return(g_delete(vdb, V_NAME, (void *) name));
 }
 int g_delete_cred_id(vdb, cred)
-     void **vdb;
+     g_set *vdb;
      gss_cred_id_t cred;
 {
    return(g_delete(vdb, V_CRED_ID, (void *) cred));
 }
 int g_delete_ctx_id(vdb, ctx)
-     void **vdb;
+     g_set *vdb;
      gss_ctx_id_t ctx;
 {
    return(g_delete(vdb, V_CTX_ID, (void *) ctx));
 }
+int g_delete_lucidctx_id(vdb, lctx)
+     g_set *vdb;
+     void *lctx;
+{
+   return(g_delete(vdb, V_LCTX_ID, (void *) lctx));
+}
 
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/val_cred.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/val_cred.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,8 +1,3 @@
-/*
- * Copyright 2001-2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
@@ -30,72 +25,76 @@
  * 
  */
 
-#include <gssapiP_krb5.h>
-
-OM_uint32
-krb5_gss_validate_cred(ct, minor_status, cred_handle)
-     void *ct;
-     OM_uint32 *minor_status;
-     gss_cred_id_t cred_handle;
-{
-    OM_uint32 major_status; 
-
-    mutex_lock(&krb5_mutex);
-    major_status = krb5_gss_validate_cred_no_lock(ct, minor_status, 
-						  cred_handle);
-    mutex_unlock(&krb5_mutex);
-
-    return(major_status);
-}
+#include "gssapiP_krb5.h"
 
 /*
  * Check to see whether or not a GSSAPI krb5 credential is valid.  If
  * it is not, return an error.
  */
 
-/*ARGSUSED*/
 OM_uint32
-krb5_gss_validate_cred_no_lock(ct, minor_status, cred_handle)
-     void *ct;
-     OM_uint32 *minor_status;
-     gss_cred_id_t cred_handle;
+krb5_gss_validate_cred_1(OM_uint32 *minor_status, gss_cred_id_t cred_handle,
+			 krb5_context context)
 {
-    krb5_context context = ct;
     krb5_gss_cred_id_t cred;
     krb5_error_code code;
     krb5_principal princ;
-    OM_uint32 major_status = GSS_S_FAILURE;
-	
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-    if (GSS_ERROR(kg_get_context(minor_status, &context)))
-	return (major_status);
-#endif
 
     if (!kg_validate_cred_id(cred_handle)) {
 	*minor_status = (OM_uint32) G_VALIDATE_FAILED;
-	major_status = (GSS_S_CALL_BAD_STRUCTURE|GSS_S_DEFECTIVE_CREDENTIAL);
-	return (major_status);
+	return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_DEFECTIVE_CREDENTIAL);
     }
 
     cred = (krb5_gss_cred_id_t) cred_handle;
-	
+
+    code = k5_mutex_lock(&cred->lock);
+    if (code) {
+	*minor_status = code;
+	return GSS_S_FAILURE;
+    }
+
     if (cred->ccache) {
-	code = krb5_cc_get_principal(context, cred->ccache, &princ);
-	if (code) {
+	if ((code = krb5_cc_get_principal(context, cred->ccache, &princ))) {
+	    k5_mutex_unlock(&cred->lock);
 	    *minor_status = code;
-	    major_status = GSS_S_DEFECTIVE_CREDENTIAL;
-	    return (major_status);
+	    return(GSS_S_DEFECTIVE_CREDENTIAL);
 	}
 	if (!krb5_principal_compare(context, princ, cred->princ)) {
+	    k5_mutex_unlock(&cred->lock);
 	    *minor_status = KG_CCACHE_NOMATCH;
-	    major_status = GSS_S_DEFECTIVE_CREDENTIAL;
-	    return (major_status);
+	    return(GSS_S_DEFECTIVE_CREDENTIAL);
 	}
 	(void)krb5_free_principal(context, princ);
     }
     *minor_status = 0;
-    major_status = GSS_S_COMPLETE;
-    return (major_status);
+    return GSS_S_COMPLETE;
 }
+
+OM_uint32
+krb5_gss_validate_cred(minor_status, cred_handle)
+     OM_uint32 *minor_status;
+     gss_cred_id_t cred_handle;
+{
+    krb5_context context;
+    krb5_error_code code;
+    OM_uint32 maj;
+
+    code = krb5_gss_init_context(&context);
+    if (code) {
+	*minor_status = code;
+	return GSS_S_FAILURE;
+    }
+
+    maj = krb5_gss_validate_cred_1(minor_status, cred_handle, context);
+    if (maj == 0) {
+	krb5_gss_cred_id_t cred = (krb5_gss_cred_id_t) cred_handle;
+	k5_mutex_assert_locked(&cred->lock);
+	k5_mutex_unlock(&cred->lock);
+    }
+    krb5_free_context(context);
+    return maj;
+}
+
+		
+
+
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/verify.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/verify.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2002 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -27,81 +27,54 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <gssapiP_krb5.h>
+#include "gssapiP_krb5.h"
 
 /*
- * $Id: verify.c,v 1.11 1996/07/22 20:34:45 marc Exp $
+ * $Id: verify.c 16171 2004-03-15 17:45:01Z raeburn $
  */
+
 /*ARGSUSED*/
 OM_uint32
-krb5_gss_verify(ctx, minor_status, context_handle,
+krb5_gss_verify(minor_status, context_handle,
 		message_buffer, token_buffer,
 		qop_state
 #ifdef	 _KERNEL
 		, gssd_ctx_verifier
 #endif
 		)
-     void      *ctx;
      OM_uint32 *minor_status;
      gss_ctx_id_t context_handle;
      gss_buffer_t message_buffer;
      gss_buffer_t token_buffer;
      int *qop_state;
 #ifdef	 _KERNEL
-	OM_uint32 gssd_ctx_verifier;
+     OM_uint32 gssd_ctx_verifier;
 #endif
 {
-     krb5_context context;
-     OM_uint32	  status;
-
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-     if (GSS_ERROR(kg_get_context(minor_status, &context)))
-	return(GSS_S_FAILURE);
-#endif
-
-     mutex_lock(&krb5_mutex);
-     context = ctx;
-
-     status = kg_unseal(context, minor_status, context_handle,
+     return(kg_unseal(minor_status, context_handle,
 		      token_buffer, message_buffer,
-		      NULL, qop_state, KG_TOK_SIGN_MSG);
-     mutex_unlock(&krb5_mutex);
-     return(status);
+		      NULL, qop_state, KG_TOK_SIGN_MSG));
 }
 
 /* V2 interface */
 OM_uint32
-krb5_gss_verify_mic(ctx, minor_status, context_handle,
+krb5_gss_verify_mic(minor_status, context_handle,
 		    message_buffer, token_buffer,
 		    qop_state)
-    void		*ctx;
     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;
 {
-    krb5_context	context;
     OM_uint32		rstat;
     int			qstate;
 
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-    if (GSS_ERROR(kg_get_context(minor_status, &context)))
-       return(GSS_S_FAILURE);
-#endif
 
-    mutex_lock(&krb5_mutex);
-    context = ctx;
-
-    rstat = kg_unseal(context, minor_status, context_handle,
-		      token_buffer, message_buffer,
-		      NULL, &qstate, KG_TOK_MIC_MSG);
+    rstat = kg_unseal(minor_status, context_handle,
+		    token_buffer, message_buffer,
+		    NULL, &qstate, KG_TOK_MIC_MSG);
     if (!rstat && qop_state)
 	*qop_state = (gss_qop_t) qstate;
-    mutex_unlock(&krb5_mutex);
     return(rstat);
 }
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/wrap_size_limit.c	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/wrap_size_limit.c	Fri Sep 14 15:01:24 2007 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -77,19 +77,29 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#include <gssapiP_krb5.h>
-#include <k5-int.h>
+#include "gssapiP_krb5.h"
+
+size_t KRB5_CALLCONV krb5_encrypt_size(size_t, krb5_enctype);
 
-/*
- * $Id: wrap_size_limit.c,v 1.7.6.2 2000/04/19 00:33:42 raeburn Exp $
- */
+ /* SUNW15resync - XXX find new home for this func */
+#ifdef _KERNEL
+size_t KRB5_CALLCONV
+krb5_encrypt_size(size_t length, krb5_enctype crypto)
+{
+    size_t ret;
+
+    if (krb5_c_encrypt_length(/* XXX */ 0, crypto, length, &ret))
+	/*LINTED*/
+        return(-1); /* XXX */
+
+    return(ret);
+}
+#endif
 
 /* V2 interface */
- /*ARGSUSED*/
 OM_uint32
-krb5_gss_wrap_size_limit(ct, minor_status, context_handle, conf_req_flag,
+krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
 			 qop_req, req_output_size, max_input_size)
-    void		*ct;
     OM_uint32		*minor_status;
     gss_ctx_id_t	context_handle;
     int			conf_req_flag;
@@ -97,118 +107,93 @@
     OM_uint32		req_output_size;
     OM_uint32		*max_input_size;
 {
-    krb5_context	context;
     krb5_gss_ctx_id_rec	*ctx;
-    OM_uint32		conflen;
+    OM_uint32		data_size, conflen;
     OM_uint32		ohlen;
-    OM_uint32		data_size;
+    int			overhead;
 
-   /* Solaris Kerberos:  for MT safety, we avoid the use of a default
-    * context via kg_get_context() */
-#if 0
-    if (GSS_ERROR(kg_get_context(minor_status, &context)))
-       return(GSS_S_FAILURE);
-#endif
-
-    KRB5_LOG0(KRB5_INFO, "krb5_gss_wrap_size_limit() start\n");
-
-    /* check to make sure we aren't writing to a NULL pointer */
+    /* Solaris Kerb - check to make sure we aren't writing to a NULL pointer */
     if (!max_input_size)
-	return(GSS_S_CALL_INACCESSIBLE_WRITE);
-
-    mutex_lock(&krb5_mutex);
-    context = ct;
+ 	return(GSS_S_CALL_INACCESSIBLE_WRITE);
 
     /* only default qop is allowed */
+    /*
+     * SUNW15resync
+     * mit 1.2-6: if (qop_req != GSS_C_QOP_DEFAULT) {
+     * Go with Solaris version here, though not sure which is
+     * correct and RFC 2743 does not make it clear.
+     */
     if ((qop_req & GSS_KRB5_CONF_C_QOP_MASK) != GSS_C_QOP_DEFAULT) {
 	*minor_status = (OM_uint32) G_UNKNOWN_QOP;
-	mutex_unlock(&krb5_mutex); 
-	return(GSS_S_BAD_QOP);
+	/* SUNW15resync - RFC 2743 is clear here but 
+          this is still GSS_S_FAILURE in MIT */
+	return(GSS_S_BAD_QOP); 
     }
-
+    
     /* validate the context handle */
     if (! kg_validate_ctx_id(context_handle)) {
 	*minor_status = (OM_uint32) G_VALIDATE_FAILED;
-	mutex_unlock(&krb5_mutex);
 	return(GSS_S_NO_CONTEXT);
     }
-
+    
     ctx = (krb5_gss_ctx_id_rec *) context_handle;
     if (! ctx->established) {
 	*minor_status = KG_CTX_INCOMPLETE;
-	mutex_unlock(&krb5_mutex);
 	return(GSS_S_NO_CONTEXT);
     }
 
     if (ctx->proto == 1) {
-        /* No pseudo-ASN.1 wrapper overhead, so no sequence length and
-           OID.  */
-        OM_uint32 sz = req_output_size;
-        if (conf_req_flag) {
-	    size_t enclen;
-	    if ( (*minor_status = krb5_c_encrypt_length(context,
-				ctx->enc->enctype,
-				sz, &enclen))) {
-		mutex_unlock(&krb5_mutex);
-		return (GSS_S_FAILURE);
-	    }
-	    /*
-	     * The 16 byte token header is included 2 times,
-	     * once at the beginning of the token and once
-	     * encrypted with the plaintext data.
-	     */
-            while (sz > 0 && enclen + 32 > req_output_size) {
-                sz--;
-	        if ((*minor_status = krb5_c_encrypt_length(context,
-			ctx->enc->enctype, sz, &enclen))) {
-			mutex_unlock(&krb5_mutex);
-			return (GSS_S_FAILURE);
-		}
-	    }
-        } else {
-            if (sz < 16 + ctx->cksum_size)
-                sz = 0;
-            else
-                sz -= (16 + ctx->cksum_size);
-        }
+	/* No pseudo-ASN.1 wrapper overhead, so no sequence length and
+	   OID.  */
+	OM_uint32 sz = req_output_size;
+	/* Token header: 16 octets.  */
+	if (conf_req_flag) {
+	    while (sz > 0 && krb5_encrypt_size(sz, ctx->enc->enctype) + 16 > req_output_size)
+		sz--;
+	    /* Allow for encrypted copy of header.  */
+	    if (sz > 16)
+		sz -= 16;
+	    else
+		sz = 0;
+#ifdef CFX_EXERCISE
+	    /* Allow for EC padding.  In the MIT implementation, only
+	       added while testing.  */
+	    if (sz > 65535)
+		sz -= 65535;
+	    else
+		sz = 0;
+#endif
+	} else {
+	    /* Allow for token header and checksum.  */
+	    if (sz < 16 + ctx->cksum_size)
+		sz = 0;
+	    else
+		sz -= (16 + ctx->cksum_size);
+	}
 
-        *max_input_size = sz;
-        *minor_status = 0;
-	goto end;
+	*max_input_size = sz;
+	*minor_status = 0;
+	return GSS_S_COMPLETE;
     }
 
+    /* Calculate the token size and subtract that from the output size */
+    overhead = 7 + ctx->mech_used->length;
     data_size = req_output_size;
-
-    /* The confounder is always used */
-    conflen = kg_confounder_size(context, ctx->enc);
-    data_size = (conflen + data_size + 8) & (~7);
-
-    /*
-     * If we are encrypting, check the size, it may be larger than
-     * the input in some cases due to padding and byte-boundaries.
-     */
-    if (conf_req_flag) {
-	    data_size = kg_encrypt_size(context, ctx->enc, data_size);
-    }
+    conflen = kg_confounder_size(ctx->k5_context, ctx->enc);
+    data_size = (conflen + data_size + 8) & (~(OM_uint32)7);
+    ohlen = g_token_size(ctx->mech_used,
+			 (unsigned int) (data_size + ctx->cksum_size + 14))
+      - req_output_size;
 
-    /*
-     * Calculate the token size for a buffer that is 'req_output_size'
-     * long.
-     */
-    ohlen = g_token_size(&(ctx->mech_used),
-			(unsigned int)(data_size + ctx->cksum_size + 14)) -
-	    req_output_size;
-
-    KRB5_LOG1(KRB5_INFO, "ohlen = %u, req_output_size = %u.\n",
-	ohlen, req_output_size);
-
-    *max_input_size = (req_output_size > ohlen) ?
-	    ((req_output_size - ohlen) & (~7)) : 0;
+    if (ohlen+overhead < req_output_size)
+      /*
+       * Cannot have trailer length that will cause us to pad over our
+       * length.
+       */
+      *max_input_size = (req_output_size - ohlen - overhead) & (~(OM_uint32)7);
+    else
+      *max_input_size = 0;
 
     *minor_status = 0;
-end:
-    mutex_unlock(&krb5_mutex);
-    KRB5_LOG(KRB5_INFO, "krb5_gss_wrap_size_limit() end, "
-	"max_input_size = %u.\n", *max_input_size);
     return(GSS_S_COMPLETE);
 }
--- a/usr/src/xmod/cry_files	Fri Sep 14 14:36:45 2007 -0700
+++ b/usr/src/xmod/cry_files	Fri Sep 14 15:01:24 2007 -0700
@@ -25,7 +25,7 @@
 usr/src/lib/gss_mechs/mech_krb5/Makefile
 usr/src/lib/gss_mechs/mech_krb5/crypto/des/afsstring2key.c
 usr/src/lib/gss_mechs/mech_krb5/crypto/des/string2key.c
-usr/src/lib/gss_mechs/mech_krb5/mech/k5mech.c
+usr/src/lib/gss_mechs/mech_krb5/mech/krb5_gss_glue.c
 usr/src/lib/gss_mechs/mech_spnego/Makefile
 usr/src/lib/gss_mechs/mech_spnego/mech/spnego_mech.c
 usr/src/lib/libgss/Makefile