From: Will Fiveash Date: Wed, 20 Jul 2016 00:20:51 +0000 (-0500) Subject: Better handle failures to resolve client keytab X-Git-Tag: krb5-1.15-beta1~141 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bd2c2a02e22c609b3c7e9f92d6634e151d14e478;p=thirdparty%2Fkrb5.git Better handle failures to resolve client keytab In krb5_gss_acquire_cred(), treat failure to resolve the client keytab similarly to a client keytab which resolves but does not exist or has no entries. The client keytab could fail to resolve if its name contains %{username} and the current process is acting on behalf of the NSS system. [ghudson@mit.edu: rewrote commit message; changed tracing call to use a macro; cleared error message when ignoring krb5_kt_client_default() error; added test case] ticket: 8462 (new) --- diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h index a0aa85aacc..045f102657 100644 --- a/src/include/k5-trace.h +++ b/src/include/k5-trace.h @@ -180,6 +180,9 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); #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 --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c index 6e83fb9ea1..2247c497f3 100644 --- a/src/lib/gssapi/krb5/acquire_cred.c +++ b/src/lib/gssapi/krb5/acquire_cred.c @@ -348,6 +348,9 @@ can_get_initial_creds(krb5_context context, krb5_gss_cred_id_rec *cred) 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 @@ get_name_from_client_keytab(krb5_context context, krb5_gss_cred_id_rec *cred) 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 @@ get_initial_cred(krb5_context context, krb5_gss_cred_id_rec *cred) 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 @@ acquire_init_cred(krb5_context context, 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 --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c index 32a341ec58..2dc4d0c1a4 100644 --- a/src/lib/gssapi/krb5/iakerb.c +++ b/src/lib/gssapi/krb5/iakerb.c @@ -454,9 +454,11 @@ iakerb_init_creds_ctx(iakerb_ctx_id_t ctx, 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 --git a/src/tests/gssapi/t_client_keytab.py b/src/tests/gssapi/t_client_keytab.py index ef27d5e599..4c8747a506 100755 --- a/src/tests/gssapi/t_client_keytab.py +++ b/src/tests/gssapi/t_client_keytab.py @@ -139,4 +139,14 @@ if 'No credentials cache found' not in out: 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')