From: Greg Hudson Date: Wed, 14 Apr 2010 03:13:58 +0000 (+0000) Subject: Move the cache check from krb5_get_credentials() into the X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f0d26b5dd9ffcaeb845788c86c99f751ecb8af3c;p=thirdparty%2Fkrb5.git Move the cache check from krb5_get_credentials() into the krb5_tkt_creds functions. git-svn-id: svn://anonsvn.mit.edu/krb5/branches/iakerb@23893 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/lib/krb5/krb/gc_frm_kdc.c b/src/lib/krb5/krb/gc_frm_kdc.c index f23a2fb08f..ebda7b1296 100644 --- a/src/lib/krb5/krb/gc_frm_kdc.c +++ b/src/lib/krb5/krb/gc_frm_kdc.c @@ -870,11 +870,58 @@ begin_get_tgt(krb5_context context, krb5_tkt_creds_context ctx) /***** STATE_BEGIN *****/ +/* + * Look for the desired credentials in the cache, if possible. If we find + * them, put them in ctx->reply_creds and advance the state to STATE_COMPLETE. + * Return successfully even if creds are not found, unless the caller only + * wanted cached creds. + */ +static krb5_error_code +check_cache(krb5_context context, krb5_tkt_creds_context ctx) +{ + krb5_error_code code; + krb5_creds mcreds; + krb5_flags fields; + + /* For constrained delegation, the expected result is in second_ticket, so + * we can't really do a cache check here. */ + if (ctx->req_options & KRB5_GC_CONSTRAINED_DELEGATION) + return (ctx->req_options & KRB5_GC_CACHED) ? KRB5_CC_NOTFOUND : 0; + + /* Perform the cache lookup. */ + code = krb5int_construct_matching_creds(context, ctx->req_options, + ctx->in_creds, &mcreds, &fields); + if (code) + return code; + code = cache_get(context, ctx->ccache, fields, &mcreds, &ctx->reply_creds); + if (code == 0) { + ctx->state = STATE_COMPLETE; + return 0; + } + + /* Stop on unexpected cache errors. */ + if (code != KRB5_CC_NOTFOUND && code != KRB5_CC_NOT_KTYPE) + return code; + + /* Stop if the caller only wanted cached creds. */ + if (ctx->req_options & KRB5_GC_CACHED) + return code; + + /* Remember whether the cache lookup failed due to enctypes or not. */ + ctx->cache_code = code; + return 0; +} + +/* Decide where to begin the acquisition process. */ static krb5_error_code begin(krb5_context context, krb5_tkt_creds_context ctx) { krb5_error_code code; + code = check_cache(context, ctx); + if (code != 0 || ctx->state == STATE_COMPLETE) + return code; + /* If the server realm is unspecified, start with the client realm. */ if (krb5_is_referral_realm(&ctx->server->realm)) { krb5_free_data_contents(context, &ctx->server->realm); diff --git a/src/lib/krb5/krb/get_creds.c b/src/lib/krb5/krb/get_creds.c index 7f6e97cd46..3a28b1babd 100644 --- a/src/lib/krb5/krb/get_creds.c +++ b/src/lib/krb5/krb/get_creds.c @@ -138,9 +138,7 @@ krb5_get_credentials(krb5_context context, krb5_flags options, krb5_creds **out_creds) { krb5_error_code retval; - krb5_creds mcreds, *ncreds = NULL; - krb5_flags fields; - krb5_boolean not_ktype = FALSE; + krb5_creds *ncreds = NULL; *out_creds = NULL; @@ -148,34 +146,7 @@ krb5_get_credentials(krb5_context context, krb5_flags options, if (ncreds == NULL) goto cleanup; - /* - * See if we already have the ticket cached. To do this usefully - * for constrained delegation, we would need to look inside - * second_ticket, which we can't do. - */ - if ((options & KRB5_GC_CONSTRAINED_DELEGATION) == 0) { - retval = krb5int_construct_matching_creds(context, options, in_creds, - &mcreds, &fields); - - if (retval) - goto cleanup; - - retval = krb5_cc_retrieve_cred(context, ccache, fields, &mcreds, - ncreds); - if (retval == 0) { - *out_creds = ncreds; - return 0; - } - if ((retval != KRB5_CC_NOTFOUND && retval != KRB5_CC_NOT_KTYPE) - || options & KRB5_GC_CACHED) - goto cleanup; - not_ktype = (retval == KRB5_CC_NOT_KTYPE); - } else if (options & KRB5_GC_CACHED) { - retval = KRB5_CC_NOTFOUND; - goto cleanup; - } - - /* Get the credential from the KDC. */ + /* Get the credential. */ retval = get_tkt_creds(context, ccache, in_creds, options, ncreds); if (retval != 0) goto cleanup; @@ -191,18 +162,6 @@ krb5_get_credentials(krb5_context context, krb5_flags options, goto cleanup; } - /* - * Translate KRB5_CC_NOTFOUND if we previously got KRB5_CC_NOT_KTYPE from - * krb5_cc_retrieve_cred(), in order to handle the case where there is no - * TGT in the ccache and the input enctype didn't match. This handling is - * necessary because some callers, such as GSSAPI, iterate through enctypes - * and KRB5_CC_NOTFOUND passed through from get_tkt_creds() is semantically - * incorrect, since the actual failure was the non-existence of a ticket of - * the correct enctype rather than the missing TGT. - */ - if (retval == KRB5_CC_NOTFOUND && not_ktype) - retval = KRB5_CC_NOT_KTYPE; - *out_creds = ncreds; ncreds = NULL;