--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/krb5/patches/072-client-keytab-fix.patch Fri Jul 22 15:56:26 2016 -0500
@@ -0,0 +1,135 @@
+#
+# Patch to fix the issue where the token expansion for the default client
+# keytab path could fail and cause a core dump. Now the error is returned to
+# krb5_kt_client_default() but in order for acquire_init_cred() to function
+# properly it has to ignore the error returned by krb5_kt_client_default().
+# This in turn means that a NULL value in the client_keytab field of a cred
+# struct must be handled appropriately.
+#
+# I have submitted a pull request to MIT with these changes
+# https://github.com/krb5/krb5/pull/487
+# The final commit was
+# https://github.com/krb5/krb5/commit/bd2c2a02e22c609b3c7e9f92d6634e151d14e478
+#
+# Also note that the fix to src/lib/krb5/os/expand_path.c was handled by MIT
+# via ticket 8455 k5_expand_path_tokens_extra() always returns 0 even if
+# expand_token() fails which was integrated in MIT v1.14.3.
+#
+# Patch source: in-house
+#
+
+diff -ur krb5-1.14.2/src/include/k5-trace.h krb5-1.14.2-patched/src/include/k5-trace.h
+--- krb5-1.14.2/src/include/k5-trace.h
++++ krb5-1.14.2-patched/src/include/k5-trace.h
+@@ -180,6 +180,9 @@
+ #define TRACE_GIC_PWD_MASTER(c) \
+ TRACE(c, "Retrying AS request with master KDC")
+
++#define TRACE_GSS_CLIENT_KEYTAB_FAIL(c, ret) \
++ TRACE(c, "Unable to resolve default client keytab: {kerr}", ret)
++
+ #define TRACE_ENCTYPE_LIST_UNKNOWN(c, profvar, name) \
+ TRACE(c, "Unrecognized enctype name in {str}: {str}", profvar, name)
+
+diff -ur krb5-1.14.2/src/lib/gssapi/krb5/acquire_cred.c krb5-1.14.2-patched/src/lib/gssapi/krb5/acquire_cred.c
+--- krb5-1.14.2/src/lib/gssapi/krb5/acquire_cred.c
++++ krb5-1.14.2-patched/src/lib/gssapi/krb5/acquire_cred.c
+@@ -348,6 +348,9 @@
+ if (cred->password != NULL)
+ return TRUE;
+
++ if (cred->client_keytab == NULL)
++ return FALSE;
++
+ /* If we don't know the client principal yet, check for any keytab keys. */
+ if (cred->name == NULL)
+ return !krb5_kt_have_content(context, cred->client_keytab);
+@@ -522,6 +525,10 @@
+ krb5_principal princ;
+
+ assert(cred->name == NULL);
++
++ if (cred->client_keytab == NULL)
++ return KRB5_KT_NOTFOUND;
++
+ code = k5_kt_get_principal(context, cred->client_keytab, &princ);
+ if (code)
+ return code;
+@@ -601,9 +608,11 @@
+ code = krb5_get_init_creds_password(context, &creds, cred->name->princ,
+ cred->password, NULL, NULL, 0,
+ NULL, opt);
+- } else {
++ } else if (cred->client_keytab != NULL) {
+ code = krb5_get_init_creds_keytab(context, &creds, cred->name->princ,
+ cred->client_keytab, 0, NULL, opt);
++ } else {
++ code = KRB5_KT_NOTFOUND;
+ }
+ if (code)
+ goto cleanup;
+@@ -680,10 +689,18 @@
+ goto error;
+ }
+
+- if (client_keytab != NULL)
++ if (client_keytab != NULL) {
+ code = krb5_kt_dup(context, client_keytab, &cred->client_keytab);
+- else
++ } else {
+ code = krb5_kt_client_default(context, &cred->client_keytab);
++ if (code) {
++ /* Treat resolution failure similarly to a client keytab which
++ * resolves but doesn't exist or has no content. */
++ TRACE_GSS_CLIENT_KEYTAB_FAIL(context, code);
++ krb5_clear_error_message(context);
++ code = 0;
++ }
++ }
+ if (code)
+ goto error;
+
+diff -ur krb5-1.14.2/src/lib/gssapi/krb5/iakerb.c krb5-1.14.2-patched/src/lib/gssapi/krb5/iakerb.c
+--- krb5-1.14.2/src/lib/gssapi/krb5/iakerb.c
++++ krb5-1.14.2-patched/src/lib/gssapi/krb5/iakerb.c
+@@ -454,9 +454,11 @@
+ if (cred->password != NULL) {
+ code = krb5_init_creds_set_password(ctx->k5c, ctx->icc,
+ cred->password);
+- } else {
++ } else if (cred->client_keytab != NULL) {
+ code = krb5_init_creds_set_keytab(ctx->k5c, ctx->icc,
+ cred->client_keytab);
++ } else {
++ code = KRB5_KT_NOTFOUND;
+ }
+ if (code != 0)
+ goto cleanup;
+diff -ur krb5-1.14.2/src/lib/krb5/os/expand_path.c krb5-1.14.2-patched/src/lib/krb5/os/expand_path.c
+--- krb5-1.14.2/src/lib/krb5/os/expand_path.c
++++ krb5-1.14.2-patched/src/lib/krb5/os/expand_path.c
+@@ -537,5 +537,5 @@
+ cleanup:
+ k5_buf_free(&buf);
+ free_extra_tokens(extra_tokens);
+- return 0;
++ return ret;
+ }
+diff -ur krb5-1.14.2/src/tests/gssapi/t_client_keytab.py krb5-1.14.2-patched/src/tests/gssapi/t_client_keytab.py
+--- krb5-1.14.2/src/tests/gssapi/t_client_keytab.py
++++ krb5-1.14.2-patched/src/tests/gssapi/t_client_keytab.py
+@@ -141,4 +141,14 @@
+ fail('Expected error not seen')
+ realm.run([kdestroy, '-A'])
+
++# Test 16: default client keytab cannot be resolved, but valid
++# credentials exist in ccache.
++conf = {'libdefaults': {'default_client_keytab_name': '%{'}}
++bad_cktname = realm.special_env('bad_cktname', False, krb5_conf=conf)
++del bad_cktname['KRB5_CLIENT_KTNAME']
++realm.kinit(realm.user_princ, password('user'))
++out = realm.run(['./t_ccselect', phost], env=bad_cktname)
++if realm.user_princ not in out:
++ fail('Expected principal not seen for bad client keytab name')
++
+ success('Client keytab tests')