bec1a9
From 334a4870cbbfefcd09c10f432a320ceaac29a14a Mon Sep 17 00:00:00 2001
bec1a9
From: Alexander Bokovoy <ab@samba.org>
bec1a9
Date: Fri, 3 Mar 2017 17:08:09 +0200
bec1a9
Subject: [PATCH 1/6] gssapi: check for gss_acquire_cred_from
bec1a9
bec1a9
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12611
bec1a9
bec1a9
Signed-off-by: Alexander Bokovoy <ab@samba.org>
bec1a9
Reviewed-by: Stefan Metzmacher <metze@samba.org>
bec1a9
(cherry picked from commit d630a364f9d74443e482934f76cd7107c331e108)
bec1a9
---
bec1a9
 wscript_configure_system_mitkrb5 | 1 +
bec1a9
 1 file changed, 1 insertion(+)
bec1a9
bec1a9
diff --git a/wscript_configure_system_mitkrb5 b/wscript_configure_system_mitkrb5
bec1a9
index 06a9821..d3e8ebf 100644
bec1a9
--- a/wscript_configure_system_mitkrb5
bec1a9
+++ b/wscript_configure_system_mitkrb5
bec1a9
@@ -92,6 +92,7 @@ conf.CHECK_FUNCS_IN('''
bec1a9
        gsskrb5_extract_authz_data_from_sec_context
bec1a9
        gss_krb5_export_lucid_sec_context
bec1a9
        gss_import_cred gss_export_cred
bec1a9
+       gss_acquire_cred_from
bec1a9
        ''', 'gssapi gssapi_krb5')
bec1a9
 conf.CHECK_VARIABLE('GSS_KRB5_CRED_NO_CI_FLAGS_X', headers=possible_gssapi_headers)
bec1a9
 conf.CHECK_FUNCS_IN('krb5_mk_req_extended krb5_kt_compare', 'krb5')
bec1a9
-- 
bec1a9
2.9.3
bec1a9
bec1a9
bec1a9
From 4b4a95436a56ee91e6bef8e905656c387ce2f62c Mon Sep 17 00:00:00 2001
bec1a9
From: Alexander Bokovoy <ab@samba.org>
bec1a9
Date: Fri, 3 Mar 2017 16:14:57 +0200
bec1a9
Subject: [PATCH 2/6] lib/krb5_wrap: add smb_gss_krb5_import_cred wrapper
bec1a9
bec1a9
Wrap gss_krb5_import_cred() to allow re-implementing it with
bec1a9
gss_acquire_cred_from() for newer MIT versions. gss_acquire_cred_from()
bec1a9
works fine with GSSAPI interposer (GSS-proxy) while
bec1a9
gss_krb5_import_cred() is not interposed yet.
bec1a9
bec1a9
The wrapper has additional parameter, krb5_context handle, to facilitate
bec1a9
with credentials cache name discovery. All our callers to
bec1a9
gss_krb5_import_cred() already have krb5 context handy.
bec1a9
bec1a9
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12611
bec1a9
bec1a9
Signed-off-by: Alexander Bokovoy <ab@samba.org>
bec1a9
Reviewed-by: Stefan Metzmacher <metze@samba.org>
bec1a9
(cherry picked from commit 0e6e8dd2600c699a7a02e3d11fed21b5bc49858d)
bec1a9
---
bec1a9
 lib/krb5_wrap/gss_samba.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++
bec1a9
 lib/krb5_wrap/gss_samba.h |  13 +++++
bec1a9
 2 files changed, 134 insertions(+)
bec1a9
bec1a9
diff --git a/lib/krb5_wrap/gss_samba.c b/lib/krb5_wrap/gss_samba.c
bec1a9
index b444633..757ffc5 100644
bec1a9
--- a/lib/krb5_wrap/gss_samba.c
bec1a9
+++ b/lib/krb5_wrap/gss_samba.c
bec1a9
@@ -48,4 +48,125 @@ int smb_gss_oid_equal(const gss_OID first_oid, const gss_OID second_oid)
bec1a9
 }
bec1a9
 #endif /* !HAVE_GSS_OID_EQUAL */
bec1a9
 
bec1a9
+
bec1a9
+/* wrapper around gss_krb5_import_cred() that prefers to use gss_acquire_cred_from()
bec1a9
+ * if this GSSAPI extension is available. gss_acquire_cred_from() is properly
bec1a9
+ * interposed by GSSPROXY while gss_krb5_import_cred() is not.
bec1a9
+ *
bec1a9
+ * This wrapper requires a proper krb5_context to resolve ccache name.
bec1a9
+ * All gss_krb5_import_cred() callers in Samba already have krb5_context available. */
bec1a9
+uint32_t smb_gss_krb5_import_cred(uint32_t *minor_status, krb5_context ctx,
bec1a9
+				  krb5_ccache id, krb5_principal keytab_principal,
bec1a9
+				  krb5_keytab keytab, gss_cred_id_t *cred)
bec1a9
+{
bec1a9
+	uint32_t major_status = 0;
bec1a9
+
bec1a9
+#if HAVE_GSS_ACQUIRE_CRED_FROM
bec1a9
+	uint32_t minor = 0;
bec1a9
+	gss_key_value_element_desc ccache_element = {
bec1a9
+		.key = "ccache",
bec1a9
+		.value = NULL,
bec1a9
+	};
bec1a9
+
bec1a9
+	gss_key_value_element_desc keytab_element = {
bec1a9
+		.key = "keytab",
bec1a9
+		.value = NULL,
bec1a9
+	};
bec1a9
+
bec1a9
+	gss_key_value_element_desc elements[2];
bec1a9
+
bec1a9
+	gss_key_value_set_desc cred_store = {
bec1a9
+		.elements = &ccache_element,
bec1a9
+		.count = 1,
bec1a9
+	};
bec1a9
+
bec1a9
+	gss_OID_set mech_set = GSS_C_NO_OID_SET;
bec1a9
+	gss_cred_usage_t cred_usage = GSS_C_INITIATE;
bec1a9
+	gss_name_t name = NULL;
bec1a9
+	gss_buffer_desc pr_name = {
bec1a9
+		.value = NULL,
bec1a9
+		.length = 0,
bec1a9
+	};
bec1a9
+
bec1a9
+	if (id != NULL) {
bec1a9
+		major_status = krb5_cc_get_full_name(ctx,
bec1a9
+						     id,
bec1a9
+						     discard_const(&ccache_element.value));
bec1a9
+		if (major_status != 0) {
bec1a9
+			return major_status;
bec1a9
+		}
bec1a9
+	}
bec1a9
+
bec1a9
+	if (keytab != NULL) {
bec1a9
+		keytab_element.value = malloc(4096);
bec1a9
+		if (!keytab_element.value) {
bec1a9
+			return ENOMEM;
bec1a9
+		}
bec1a9
+		major_status = krb5_kt_get_name(ctx,
bec1a9
+						keytab,
bec1a9
+						discard_const(keytab_element.value), 4096);
bec1a9
+		if (major_status != 0) {
bec1a9
+			free(discard_const(keytab_element.value));
bec1a9
+			return major_status;
bec1a9
+		}
bec1a9
+		cred_usage = GSS_C_ACCEPT;
bec1a9
+		cred_store.elements = &keytab_element;
bec1a9
+
bec1a9
+		if (keytab_principal != NULL) {
bec1a9
+			major_status = krb5_unparse_name(ctx, keytab_principal, (char**)&pr_name.value);
bec1a9
+			if (major_status != 0) {
bec1a9
+				free(discard_const(keytab_element.value));
bec1a9
+				return major_status;
bec1a9
+			}
bec1a9
+			pr_name.length = strlen(pr_name.value);
bec1a9
+
bec1a9
+			major_status = gss_import_name(minor_status,
bec1a9
+						       &pr_name,
bec1a9
+						       discard_const(GSS_KRB5_NT_PRINCIPAL_NAME),
bec1a9
+						       &name);
bec1a9
+			if (major_status != 0) {
bec1a9
+				krb5_free_unparsed_name(ctx, pr_name.value);
bec1a9
+				free(discard_const(keytab_element.value));
bec1a9
+				return major_status;
bec1a9
+			}
bec1a9
+		}
bec1a9
+	}
bec1a9
+
bec1a9
+	if (id != NULL && keytab != NULL) {
bec1a9
+		elements[0] = ccache_element;
bec1a9
+		elements[1] = keytab_element;
bec1a9
+
bec1a9
+		cred_store.elements = elements;
bec1a9
+		cred_store.count = 2;
bec1a9
+		cred_usage = GSS_C_BOTH;
bec1a9
+	}
bec1a9
+
bec1a9
+	major_status = gss_acquire_cred_from(minor_status,
bec1a9
+					     name,
bec1a9
+					     0,
bec1a9
+					     mech_set,
bec1a9
+					     cred_usage,
bec1a9
+					     &cred_store,
bec1a9
+					     cred,
bec1a9
+					     NULL,
bec1a9
+					     NULL);
bec1a9
+
bec1a9
+	if (pr_name.value != NULL) {
bec1a9
+		(void)gss_release_name(&minor, &name);
bec1a9
+		krb5_free_unparsed_name(ctx, pr_name.value);
bec1a9
+	}
bec1a9
+	if (keytab_element.value != NULL) {
bec1a9
+		free(discard_const(keytab_element.value));
bec1a9
+	}
bec1a9
+	krb5_free_string(ctx, discard_const(ccache_element.value));
bec1a9
+#else
bec1a9
+	major_status = gss_krb5_import_cred(minor_status,
bec1a9
+					id,
bec1a9
+					keytab_principal,
bec1a9
+					keytab, cred);
bec1a9
+#endif
bec1a9
+	return major_status;
bec1a9
+}
bec1a9
+
bec1a9
+
bec1a9
 #endif /* HAVE_GSSAPI */
bec1a9
diff --git a/lib/krb5_wrap/gss_samba.h b/lib/krb5_wrap/gss_samba.h
bec1a9
index 5319932..89aee34 100644
bec1a9
--- a/lib/krb5_wrap/gss_samba.h
bec1a9
+++ b/lib/krb5_wrap/gss_samba.h
bec1a9
@@ -25,6 +25,7 @@
bec1a9
 #ifdef HAVE_GSSAPI
bec1a9
 
bec1a9
 #include "system/gssapi.h"
bec1a9
+#include "krb5_samba.h"
bec1a9
 
bec1a9
 #if defined(HAVE_GSS_OID_EQUAL)
bec1a9
 #define smb_gss_oid_equal gss_oid_equal
bec1a9
@@ -32,5 +33,17 @@
bec1a9
 int smb_gss_oid_equal(const gss_OID first_oid, const gss_OID second_oid);
bec1a9
 #endif /* HAVE_GSS_OID_EQUAL */
bec1a9
 
bec1a9
+/* wrapper around gss_krb5_import_cred() that prefers to use gss_acquire_cred_from()
bec1a9
+ * if this GSSAPI extension is available. gss_acquire_cred_from() is properly
bec1a9
+ * interposed by GSS-proxy while gss_krb5_import_cred() is not.
bec1a9
+ *
bec1a9
+ * This wrapper requires a proper krb5_context to resolve the ccache name for
bec1a9
+ * gss_acquire_cred_from().
bec1a9
+ *
bec1a9
+ * All gss_krb5_import_cred() callers in Samba already have krb5_context available. */
bec1a9
+uint32_t smb_gss_krb5_import_cred(OM_uint32 *minor_status, krb5_context ctx,
bec1a9
+				  krb5_ccache id, krb5_principal keytab_principal,
bec1a9
+				  krb5_keytab keytab, gss_cred_id_t *cred);
bec1a9
+
bec1a9
 #endif /* HAVE_GSSAPI */
bec1a9
 #endif /* _GSS_SAMBA_H */
bec1a9
-- 
bec1a9
2.9.3
bec1a9
bec1a9
bec1a9
From f06fafce32a27acf4028ab573297c64189b62e30 Mon Sep 17 00:00:00 2001
bec1a9
From: Alexander Bokovoy <ab@samba.org>
bec1a9
Date: Fri, 3 Mar 2017 16:57:13 +0200
bec1a9
Subject: [PATCH 3/6] credentials_krb5: convert to use smb_gss_krb5_import_cred
bec1a9
bec1a9
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12611
bec1a9
bec1a9
Signed-off-by: Alexander Bokovoy <ab@samba.org>
bec1a9
Reviewed-by: Stefan Metzmacher <metze@samba.org>
bec1a9
(cherry picked from commit ca8fd793930173b4e625d3f286739de214155bc1)
bec1a9
---
bec1a9
 auth/credentials/credentials_krb5.c | 22 +++++++++++++---------
bec1a9
 1 file changed, 13 insertions(+), 9 deletions(-)
bec1a9
bec1a9
diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c
bec1a9
index e974df9..0e68012 100644
bec1a9
--- a/auth/credentials/credentials_krb5.c
bec1a9
+++ b/auth/credentials/credentials_krb5.c
bec1a9
@@ -579,8 +579,9 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
bec1a9
 		return ENOMEM;
bec1a9
 	}
bec1a9
 
bec1a9
-	maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL, 
bec1a9
-					&gcc->creds);
bec1a9
+	maj_stat = smb_gss_krb5_import_cred(&min_stat, ccache->smb_krb5_context->krb5_context,
bec1a9
+					    ccache->ccache, NULL, NULL,
bec1a9
+					    &gcc->creds);
bec1a9
 	if ((maj_stat == GSS_S_FAILURE) &&
bec1a9
 	    (min_stat == (OM_uint32)KRB5_CC_END ||
bec1a9
 	     min_stat == (OM_uint32)KRB5_CC_NOTFOUND ||
bec1a9
@@ -597,8 +598,9 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
bec1a9
 			return ret;
bec1a9
 		}
bec1a9
 
bec1a9
-		maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL,
bec1a9
-						&gcc->creds);
bec1a9
+		maj_stat = smb_gss_krb5_import_cred(&min_stat, ccache->smb_krb5_context->krb5_context,
bec1a9
+						    ccache->ccache, NULL, NULL,
bec1a9
+						    &gcc->creds);
bec1a9
 
bec1a9
 	}
bec1a9
 
bec1a9
@@ -609,7 +611,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
bec1a9
 		} else {
bec1a9
 			ret = EINVAL;
bec1a9
 		}
bec1a9
-		(*error_string) = talloc_asprintf(cred, "gss_krb5_import_cred failed: %s", error_message(ret));
bec1a9
+		(*error_string) = talloc_asprintf(cred, "smb_gss_krb5_import_cred failed: %s", error_message(ret));
bec1a9
 		return ret;
bec1a9
 	}
bec1a9
 
bec1a9
@@ -1076,12 +1078,14 @@ _PUBLIC_ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred,
bec1a9
 
bec1a9
 	if (ktc->password_based || obtained < CRED_SPECIFIED) {
bec1a9
 		/* This creates a GSSAPI cred_id_t for match-by-key with only the keytab set */
bec1a9
-		maj_stat = gss_krb5_import_cred(&min_stat, NULL, NULL, ktc->keytab,
bec1a9
-						&gcc->creds);
bec1a9
+		maj_stat = smb_gss_krb5_import_cred(&min_stat, smb_krb5_context->krb5_context,
bec1a9
+						    NULL, NULL, ktc->keytab,
bec1a9
+						    &gcc->creds);
bec1a9
 	} else {
bec1a9
 		/* This creates a GSSAPI cred_id_t with the principal and keytab set, matching by name */
bec1a9
-		maj_stat = gss_krb5_import_cred(&min_stat, NULL, princ, ktc->keytab,
bec1a9
-						&gcc->creds);
bec1a9
+		maj_stat = smb_gss_krb5_import_cred(&min_stat, smb_krb5_context->krb5_context,
bec1a9
+						    NULL, princ, ktc->keytab,
bec1a9
+						    &gcc->creds);
bec1a9
 	}
bec1a9
 	if (maj_stat) {
bec1a9
 		if (min_stat) {
bec1a9
-- 
bec1a9
2.9.3
bec1a9
bec1a9
bec1a9
From 5305bffd4c72a85cc6c3148222ef7e346cbe3d87 Mon Sep 17 00:00:00 2001
bec1a9
From: Alexander Bokovoy <ab@samba.org>
bec1a9
Date: Fri, 3 Mar 2017 16:57:50 +0200
bec1a9
Subject: [PATCH 4/6] libads: convert to use smb_gss_krb5_import_cred
bec1a9
bec1a9
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12611
bec1a9
bec1a9
Signed-off-by: Alexander Bokovoy <ab@samba.org>
bec1a9
Reviewed-by: Stefan Metzmacher <metze@samba.org>
bec1a9
(cherry picked from commit 520167992bd2477bc11920d2dc9ec87f2cb339c9)
bec1a9
---
bec1a9
 source3/libads/sasl.c | 2 +-
bec1a9
 1 file changed, 1 insertion(+), 1 deletion(-)
bec1a9
bec1a9
diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
bec1a9
index 8570788..30127fa 100644
bec1a9
--- a/source3/libads/sasl.c
bec1a9
+++ b/source3/libads/sasl.c
bec1a9
@@ -372,7 +372,7 @@ static ADS_STATUS ads_init_gssapi_cred(ADS_STRUCT *ads, gss_cred_id_t *cred)
bec1a9
 		goto done;
bec1a9
 	}
bec1a9
 
bec1a9
-	maj = gss_krb5_import_cred(&min, kccache, NULL, NULL, cred);
bec1a9
+	maj = smb_gss_krb5_import_cred(&min, kctx, kccache, NULL, NULL, cred);
bec1a9
 	if (maj != GSS_S_COMPLETE) {
bec1a9
 		status = ADS_ERROR_GSS(maj, min);
bec1a9
 		goto done;
bec1a9
-- 
bec1a9
2.9.3
bec1a9
bec1a9
bec1a9
From 1dbc68f9bee19a9c26825cc5be7d81951dcac710 Mon Sep 17 00:00:00 2001
bec1a9
From: Alexander Bokovoy <ab@samba.org>
bec1a9
Date: Fri, 3 Mar 2017 16:58:14 +0200
bec1a9
Subject: [PATCH 5/6] s3-gse: convert to use smb_gss_krb5_import_cred
bec1a9
bec1a9
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12611
bec1a9
bec1a9
Signed-off-by: Alexander Bokovoy <ab@samba.org>
bec1a9
Reviewed-by: Stefan Metzmacher <metze@samba.org>
bec1a9
(cherry picked from commit 3d733d5791a6d82edda13ac39790bd8ba893f3d7)
bec1a9
---
bec1a9
 source3/librpc/crypto/gse.c | 20 +++++++++++---------
bec1a9
 1 file changed, 11 insertions(+), 9 deletions(-)
bec1a9
bec1a9
diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c
bec1a9
index abf20bc..f4238f3 100644
bec1a9
--- a/source3/librpc/crypto/gse.c
bec1a9
+++ b/source3/librpc/crypto/gse.c
bec1a9
@@ -252,11 +252,12 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx,
bec1a9
 	/* TODO: get krb5 ticket using username/password, if no valid
bec1a9
 	 * one already available in ccache */
bec1a9
 
bec1a9
-	gss_maj = gss_krb5_import_cred(&gss_min,
bec1a9
-				       gse_ctx->ccache,
bec1a9
-				       NULL, /* keytab_principal */
bec1a9
-				       NULL, /* keytab */
bec1a9
-				       &gse_ctx->creds);
bec1a9
+	gss_maj = smb_gss_krb5_import_cred(&gss_min,
bec1a9
+					   gse_ctx->k5ctx,
bec1a9
+					   gse_ctx->ccache,
bec1a9
+					   NULL, /* keytab_principal */
bec1a9
+					   NULL, /* keytab */
bec1a9
+					   &gse_ctx->creds);
bec1a9
 	if (gss_maj) {
bec1a9
 		char *ccache = NULL;
bec1a9
 		int kret;
bec1a9
@@ -268,7 +269,7 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx,
bec1a9
 			ccache = NULL;
bec1a9
 		}
bec1a9
 
bec1a9
-		DEBUG(5, ("gss_krb5_import_cred ccache[%s] failed with [%s] -"
bec1a9
+		DEBUG(5, ("smb_gss_krb5_import_cred ccache[%s] failed with [%s] -"
bec1a9
 			  "the caller may retry after a kinit.\n",
bec1a9
 			  ccache, gse_errstr(gse_ctx, gss_maj, gss_min)));
bec1a9
 		SAFE_FREE(ccache);
bec1a9
@@ -430,12 +431,13 @@ static NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx,
bec1a9
 	}
bec1a9
 
bec1a9
 	/* This creates a GSSAPI cred_id_t with the keytab set */
bec1a9
-	gss_maj = gss_krb5_import_cred(&gss_min, NULL, NULL, gse_ctx->keytab, 
bec1a9
-				       &gse_ctx->creds);
bec1a9
+	gss_maj = smb_gss_krb5_import_cred(&gss_min, gse_ctx->k5ctx,
bec1a9
+					   NULL, NULL, gse_ctx->keytab,
bec1a9
+					   &gse_ctx->creds);
bec1a9
 
bec1a9
 	if (gss_maj != 0
bec1a9
 	    && gss_maj != (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME)) {
bec1a9
-		DEBUG(0, ("gss_krb5_import_cred failed with [%s]\n",
bec1a9
+		DEBUG(0, ("smb_gss_krb5_import_cred failed with [%s]\n",
bec1a9
 			  gse_errstr(gse_ctx, gss_maj, gss_min)));
bec1a9
 		status = NT_STATUS_INTERNAL_ERROR;
bec1a9
 		goto done;
bec1a9
-- 
bec1a9
2.9.3
bec1a9
bec1a9
bec1a9
From 3c9390d26cf12e483d98f005b43da7b10348753d Mon Sep 17 00:00:00 2001
bec1a9
From: Alexander Bokovoy <ab@samba.org>
bec1a9
Date: Wed, 8 Mar 2017 12:38:49 +0200
bec1a9
Subject: [PATCH 6/6] s3-gse: move krb5 fallback to smb_gss_krb5_import_cred
bec1a9
 wrapper
bec1a9
bec1a9
MIT krb5 1.9 version of gss_krb5_import_cred() may fail when importing
bec1a9
credentials from a keytab without specifying actual principal.
bec1a9
This was fixed in MIT krb5 1.9.2 (see commit
bec1a9
71c3be093db577aa52f6b9a9a3a9f442ca0d8f20 in MIT krb5-1.9 branch, git
bec1a9
master's version is bd18687a705a8a6cdcb7c140764d1a7c6a3381b5).
bec1a9
bec1a9
Move fallback code to the smb_gss_krb5_import_cred wrapper. We only
bec1a9
expect this fallback to happen with krb5 GSSAPI mechanism, thus hard
bec1a9
code use of krb5 mech when calling to gss_acquire_cred.
bec1a9
bec1a9
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12611
bec1a9
bec1a9
Signed-off-by: Alexander Bokovoy <ab@samba.org>
bec1a9
Reviewed-by: Stefan Metzmacher <metze@samba.org>
bec1a9
bec1a9
Autobuild-User(master): Alexander Bokovoy <ab@samba.org>
bec1a9
Autobuild-Date(master): Wed Mar  8 22:00:24 CET 2017 on sn-devel-144
bec1a9
bec1a9
(cherry picked from commit 57286d57732d49fdb8b8e21f584787cdbc917c32)
bec1a9
---
bec1a9
 lib/krb5_wrap/gss_samba.c   | 46 +++++++++++++++++++++++++++++++++++++++---
bec1a9
 source3/librpc/crypto/gse.c | 49 +--------------------------------------------
bec1a9
 2 files changed, 44 insertions(+), 51 deletions(-)
bec1a9
bec1a9
diff --git a/lib/krb5_wrap/gss_samba.c b/lib/krb5_wrap/gss_samba.c
bec1a9
index 757ffc5..9e5ad4a 100644
bec1a9
--- a/lib/krb5_wrap/gss_samba.c
bec1a9
+++ b/lib/krb5_wrap/gss_samba.c
bec1a9
@@ -161,9 +161,49 @@ uint32_t smb_gss_krb5_import_cred(uint32_t *minor_status, krb5_context ctx,
bec1a9
 	krb5_free_string(ctx, discard_const(ccache_element.value));
bec1a9
 #else
bec1a9
 	major_status = gss_krb5_import_cred(minor_status,
bec1a9
-					id,
bec1a9
-					keytab_principal,
bec1a9
-					keytab, cred);
bec1a9
+					    id,
bec1a9
+					    keytab_principal,
bec1a9
+					    keytab, cred);
bec1a9
+
bec1a9
+	if (major_status == (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME)) {
bec1a9
+		if ((keytab_principal == NULL) && (keytab != NULL)) {
bec1a9
+			/* No principal was specified and MIT krb5 1.9 version failed.
bec1a9
+			 * We have to fall back to set global acceptor identity */
bec1a9
+			gss_OID_set_desc mech_set;
bec1a9
+			char *kt_name = NULL;
bec1a9
+
bec1a9
+			kt_name = malloc(4096);
bec1a9
+			if (!kt_name) {
bec1a9
+				return ENOMEM;
bec1a9
+			}
bec1a9
+
bec1a9
+			major_status = krb5_kt_get_name(ctx,
bec1a9
+							keytab,
bec1a9
+							kt_name, 4096);
bec1a9
+			if (major_status != 0) {
bec1a9
+				free(kt_name);
bec1a9
+				return major_status;
bec1a9
+			}
bec1a9
+
bec1a9
+			major_status = gsskrb5_register_acceptor_identity(kt_name);
bec1a9
+			if (major_status) {
bec1a9
+				free(kt_name);
bec1a9
+				return major_status;
bec1a9
+			}
bec1a9
+
bec1a9
+			/* We are dealing with krb5 GSSAPI mech in this fallback */
bec1a9
+			mech_set.count = 1;
bec1a9
+			mech_set.elements = gss_mech_krb5;
bec1a9
+			major_status = gss_acquire_cred(minor_status,
bec1a9
+							GSS_C_NO_NAME,
bec1a9
+							GSS_C_INDEFINITE,
bec1a9
+							&mech_set,
bec1a9
+							GSS_C_ACCEPT,
bec1a9
+							cred,
bec1a9
+							NULL, NULL);
bec1a9
+			free(kt_name);
bec1a9
+		}
bec1a9
+	}
bec1a9
 #endif
bec1a9
 	return major_status;
bec1a9
 }
bec1a9
diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c
bec1a9
index f4238f3..a111320 100644
bec1a9
--- a/source3/librpc/crypto/gse.c
bec1a9
+++ b/source3/librpc/crypto/gse.c
bec1a9
@@ -435,58 +435,11 @@ static NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx,
bec1a9
 					   NULL, NULL, gse_ctx->keytab,
bec1a9
 					   &gse_ctx->creds);
bec1a9
 
bec1a9
-	if (gss_maj != 0
bec1a9
-	    && gss_maj != (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME)) {
bec1a9
+	if (gss_maj != 0) {
bec1a9
 		DEBUG(0, ("smb_gss_krb5_import_cred failed with [%s]\n",
bec1a9
 			  gse_errstr(gse_ctx, gss_maj, gss_min)));
bec1a9
 		status = NT_STATUS_INTERNAL_ERROR;
bec1a9
 		goto done;
bec1a9
-
bec1a9
-		/* This is the error the MIT krb5 1.9 gives when it
bec1a9
-		 * implements the function, but we do not specify the
bec1a9
-		 * principal.  However, when we specify the principal
bec1a9
-		 * as host$@REALM the GSS acceptor fails with 'wrong
bec1a9
-		 * principal in request'.  Work around the issue by
bec1a9
-		 * falling back to the alternate approach below. */
bec1a9
-	} else if (gss_maj == (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME))
bec1a9
-	/* FIXME!!!
bec1a9
-	 * This call sets the default keytab for the whole server, not
bec1a9
-	 * just for this context. Need to find a way that does not alter
bec1a9
-	 * the state of the whole server ... */
bec1a9
-	{
bec1a9
-		const char *ktname;
bec1a9
-		gss_OID_set_desc mech_set;
bec1a9
-
bec1a9
-		ret = smb_krb5_kt_get_name(gse_ctx, gse_ctx->k5ctx,
bec1a9
-				   gse_ctx->keytab, &ktname);
bec1a9
-		if (ret) {
bec1a9
-			status = NT_STATUS_INTERNAL_ERROR;
bec1a9
-			goto done;
bec1a9
-		}
bec1a9
-
bec1a9
-		ret = gsskrb5_register_acceptor_identity(ktname);
bec1a9
-		if (ret) {
bec1a9
-			status = NT_STATUS_INTERNAL_ERROR;
bec1a9
-			goto done;
bec1a9
-		}
bec1a9
-
bec1a9
-		mech_set.count = 1;
bec1a9
-		mech_set.elements = &gse_ctx->gss_mech;
bec1a9
-
bec1a9
-		gss_maj = gss_acquire_cred(&gss_min,
bec1a9
-				   GSS_C_NO_NAME,
bec1a9
-				   GSS_C_INDEFINITE,
bec1a9
-				   &mech_set,
bec1a9
-				   GSS_C_ACCEPT,
bec1a9
-				   &gse_ctx->creds,
bec1a9
-				   NULL, NULL);
bec1a9
-
bec1a9
-		if (gss_maj) {
bec1a9
-			DEBUG(0, ("gss_acquire_creds failed with [%s]\n",
bec1a9
-				  gse_errstr(gse_ctx, gss_maj, gss_min)));
bec1a9
-			status = NT_STATUS_INTERNAL_ERROR;
bec1a9
-			goto done;
bec1a9
-		}
bec1a9
 	}
bec1a9
 
bec1a9
 	status = NT_STATUS_OK;
bec1a9
-- 
bec1a9
2.9.3
bec1a9