From: Tom Yu Date: Mon, 5 Dec 2011 19:01:49 +0000 (+0000) Subject: Handle TGS referrals to the same realm X-Git-Tag: krb5-1.10-alpha2~21 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=0acf70150b7a2cf66954627db5572f735c75f4ba;p=krb5.git Handle TGS referrals to the same realm pull up r25472 from trunk ------------------------------------------------------------------------ r25472 | ghudson | 2011-11-14 13:02:52 -0500 (Mon, 14 Nov 2011) | 12 lines ticket: 7016 subject: Handle TGS referrals to the same realm target_version: 1.9.3 tags: pullup krb5 1.6 through 1.8 contained a workaround for the Active Directory behavior of returning a TGS referral to the same realm as the request. 1.9 responds to this behavior by caching the returned TGT, trying again, and detecting a referral loop. This is a partial regression of ticket #4955. Detect this case and fall back to a non-referreal request. ticket: 7039 version_fixed: 1.10 status: resolved git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-10@25507 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h index 2d3457486..926c523bc 100644 --- a/src/include/k5-trace.h +++ b/src/include/k5-trace.h @@ -357,6 +357,9 @@ TRACE(c, (c, "TGS request result: {kerr}", code)) #define TRACE_TKT_CREDS_RETRY_TCP(c) \ TRACE(c, (c, "Request or response is too big for UDP; retrying with TCP")) +#define TRACE_TKT_CREDS_SAME_REALM_TGT(c, realm) \ + TRACE(c, (c, "Received TGT referral back to same realm ({data}); trying " \ + "again without referrals", realm)) #define TRACE_TKT_CREDS_SERVICE_REQ(c, princ, referral) \ TRACE(c, (c, "Requesting tickets for {princ}, referrals {str}", princ, \ (referral) ? "on" : "off")) diff --git a/src/lib/krb5/krb/get_creds.c b/src/lib/krb5/krb/get_creds.c index f229ba1c3..780e6568b 100644 --- a/src/lib/krb5/krb/get_creds.c +++ b/src/lib/krb5/krb/get_creds.c @@ -557,6 +557,14 @@ step_referrals(krb5_context context, krb5_tkt_creds_context ctx) return begin_non_referral(context, ctx); } + /* Active Directory may return a TGT to the local realm. Try a + * non-referral query if we see this. */ + referral_realm = &ctx->reply_creds->server->data[1]; + if (data_eq(*referral_realm, ctx->cur_tgt->server->data[1])) { + TRACE_TKT_CREDS_SAME_REALM_TGT(context, referral_realm); + return begin_non_referral(context, ctx); + } + if (ctx->referral_count == 1) { /* Cache the referral TGT only if it's from the local realm. * Make sure to note the associated authdata, if any. */ @@ -577,7 +585,6 @@ step_referrals(krb5_context context, krb5_tkt_creds_context ctx) return KRB5_KDC_UNREACH; /* Check for referral loops. */ - referral_realm = &ctx->reply_creds->server->data[1]; if (seen_realm_before(context, ctx, referral_realm)) return KRB5_KDC_UNREACH; code = remember_realm(context, ctx, referral_realm);