From 8952e72b9cf0f8a14d728feaeb2f5fe85ebbeae0 Mon Sep 17 00:00:00 2001
From: oracle <solaris@oracle.com>
Date: Mon, 3 Aug 2015 14:35:34 -0700
Subject: [PATCH 06/34] GSS store creds for Solaris

diff -wpruN --no-dereference '--exclude=*.orig' a~/configure.ac a/configure.ac
--- a~/configure.ac	1970-01-01 00:00:00
+++ a/configure.ac	1970-01-01 00:00:00
@@ -1170,6 +1170,9 @@ mips-sony-bsd|mips-sony-newsos4)
 		],
 	)
 	TEST_SHELL=$SHELL	# let configure find us a capable shell
+	AC_DEFINE([USE_GSS_STORE_CRED], [1], [Use the Solaris-style GSS cred store])
+	AC_DEFINE([GSSAPI_STORECREDS_NEEDS_RUID], [1], [GSSAPI storecreds needs ruid])
+	AC_DEFINE([HAVE_PAM_AUSER], [1], [pam_auser])
 	;;
 *-*-sunos4*)
 	CPPFLAGS="$CPPFLAGS -DSUNOS4"
diff -wpruN --no-dereference '--exclude=*.orig' a~/gss-serv-krb5.c a/gss-serv-krb5.c
--- a~/gss-serv-krb5.c	1970-01-01 00:00:00
+++ a/gss-serv-krb5.c	1970-01-01 00:00:00
@@ -109,7 +109,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client
 	return retval;
 }
 
-
+#ifndef USE_GSS_STORE_CRED
 /* This writes out any forwarded credentials from the structure populated
  * during userauth. Called after we have setuid to the user */
 
@@ -195,6 +195,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
 
 	return;
 }
+#endif /* #ifndef USE_GSS_STORE_CRED */
 
 ssh_gssapi_mech gssapi_kerberos_mech = {
 	"toWM5Slw5Ew8Mqkay+al2g==",
@@ -203,7 +204,11 @@ ssh_gssapi_mech gssapi_kerberos_mech = {
 	NULL,
 	&ssh_gssapi_krb5_userok,
 	NULL,
+#ifdef USE_GSS_STORE_CRED
+	NULL
+#else
 	&ssh_gssapi_krb5_storecreds
+#endif
 };
 
 #endif /* KRB5 */
diff -wpruN --no-dereference '--exclude=*.orig' a~/gss-serv.c a/gss-serv.c
--- a~/gss-serv.c	1970-01-01 00:00:00
+++ a/gss-serv.c	1970-01-01 00:00:00
@@ -44,6 +44,7 @@
 #include "session.h"
 #include "misc.h"
 #include "servconf.h"
+#include "sshbuf.h"
 
 #include "ssh-gss.h"
 
@@ -319,22 +320,66 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g
 void
 ssh_gssapi_cleanup_creds(void)
 {
+#ifdef USE_GSS_STORE_CRED
+	debug("removing gssapi cred file not implemented");
+#else
 	if (gssapi_client.store.filename != NULL) {
 		/* Unlink probably isn't sufficient */
 		debug("removing gssapi cred file\"%s\"",
 		    gssapi_client.store.filename);
 		unlink(gssapi_client.store.filename);
 	}
+#endif /* USE_GSS_STORE_CRED */
 }
 
 /* As user */
 void
 ssh_gssapi_storecreds(void)
 {
+#ifdef USE_GSS_STORE_CRED
+	OM_uint32 maj_status, min_status;
+
+	if (gssapi_client.creds == NULL) {
+		debug("No credentials stored");
+		return;
+	}
+
+	maj_status = gss_store_cred(&min_status, gssapi_client.creds,
+	    GSS_C_INITIATE, &gssapi_client.mech->oid, 1, 1, NULL, NULL);
+
+	if (GSS_ERROR(maj_status)) {
+		struct sshbuf *b;
+		gss_buffer_desc msg;
+		OM_uint32 lmin;
+		OM_uint32 more = 0;
+		if ((b = sshbuf_new()) == NULL) fatal("malloc");
+		/* GSS-API error */
+		do {
+			gss_display_status(&lmin, maj_status, GSS_C_GSS_CODE,
+			    GSS_C_NULL_OID, &more, &msg);
+			sshbuf_put(b, msg.value, msg.length);
+			sshbuf_put(b, "\n", 1);
+			gss_release_buffer(&lmin, &msg);
+		} while (more != 0);
+		/* Mechanism specific error */
+		do {
+			gss_display_status(&lmin, min_status, GSS_C_MECH_CODE,
+			    &gssapi_client.mech->oid, &more, &msg);
+			sshbuf_put(b, msg.value, msg.length);
+			sshbuf_put(b, "\n", 1);
+			gss_release_buffer(&lmin, &msg);
+		} while (more != 0);
+		sshbuf_put(b, "\0", 1);
+		error("GSS-API error while storing delegated credentials: %s",
+		    sshbuf_ptr(b));
+		sshbuf_free(b);
+	}
+#else	/* #ifdef USE_GSS_STORE_CRED */
 	if (gssapi_client.mech && gssapi_client.mech->storecreds) {
 		(*gssapi_client.mech->storecreds)(&gssapi_client);
 	} else
 		debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism");
+#endif	/* #ifdef USE_GSS_STORE_CRED */
 }
 
 /* This allows GSSAPI methods to do things to the child's environment based
diff -wpruN --no-dereference '--exclude=*.orig' a~/servconf.c a/servconf.c
--- a~/servconf.c	1970-01-01 00:00:00
+++ a/servconf.c	1970-01-01 00:00:00
@@ -653,7 +653,11 @@ static struct {
 	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
 #ifdef GSSAPI
 	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
+#ifdef USE_GSS_STORE_CRED
+	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
+#else /* USE_GSS_STORE_CRED */
 	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
+#endif /* USE_GSS_STORE_CRED */
 	{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
 #else
 	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
diff -wpruN --no-dereference '--exclude=*.orig' a~/sshd-session.c a/sshd-session.c
--- a~/sshd-session.c	1970-01-01 00:00:00
+++ a/sshd-session.c	1970-01-01 00:00:00
@@ -1353,9 +1353,23 @@ main(int ac, char **av)
 
 #ifdef GSSAPI
 	if (options.gss_authentication) {
+#ifdef GSSAPI_STORECREDS_NEEDS_RUID
+		if (setreuid(authctxt->pw->pw_uid, -1) != 0) {
+			debug("setreuid %u: %.100s",
+			    (u_int) authctxt->pw->pw_uid, strerror(errno));
+			goto bail_storecred;
+		}
+#endif
 		temporarily_use_uid(authctxt->pw);
 		ssh_gssapi_storecreds();
 		restore_uid();
+#ifdef GSSAPI_STORECREDS_NEEDS_RUID
+		if (setuid(geteuid()) != 0) {
+			fatal("setuid %u: %.100s", (u_int) geteuid(),
+			    strerror(errno));
+		}
+ bail_storecred: ;
+#endif
 	}
 #endif
 #ifdef USE_PAM
