diff options
author | Nate Rosenblum <nater@maginatics.com> | 2013-12-23 13:21:44 -0800 |
---|---|---|
committer | Tom Yu <tlyu@mit.edu> | 2015-02-06 16:55:11 -0500 |
commit | 6dda4d7acd4565f983784b484baae32f930cc810 (patch) | |
tree | a9c53ad818b8ca10ba82d752cefe74aabddff832 | |
parent | 5a1bd1d9c4e6f46ff03bd1c0957d803ea8671360 (diff) | |
download | krb5-6dda4d7acd4565f983784b484baae32f930cc810.zip krb5-6dda4d7acd4565f983784b484baae32f930cc810.tar.gz krb5-6dda4d7acd4565f983784b484baae32f930cc810.tar.bz2 |
Support referrals from Windows Server 2003
Although RFC 6806 Section 7 requires servers to indicate a client
referral in a WRONG_REALM message, Microsoft Windows Server 2003
returns this information in a message with error code
PRINCIPAL_UNKNOWN. Failure to follow the referral in these messages
prevents referral chasing in Windows Server 2003 forests. Detect
referral messages of this type by checking for a non-empty
client.realm field in the response, and activate the referral logic in
these cases.
[tlyu@mit.edu: style, comments, and commit message]
(back ported from 3093b92734adfe2deb9ad6bad5a221acc967fd8b)
ticket: 8083 (new)
version_fixed: 1.11.6
status: resolved
-rw-r--r-- | src/lib/krb5/krb/get_in_tkt.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c index 6cf64bd..98851d8 100644 --- a/src/lib/krb5/krb/get_in_tkt.c +++ b/src/lib/krb5/krb/get_in_tkt.c @@ -1421,6 +1421,35 @@ note_req_timestamp(krb5_context kcontext, krb5_clpreauth_rock rock, AUTH_OFFSET : UNAUTH_OFFSET; } +/* Determine whether the client realm in a KRB-ERROR is empty. */ +static krb5_boolean +is_empty_crealm(krb5_error *err) +{ + + return (err->client == NULL || err->client->realm.length == 0); +} + +/* + * Determine whether a KRB-ERROR is a referral to another realm. + * + * RFC 6806 Section 7 requires that KDCs return the referral realm in + * an error type WRONG_REALM, but Microsoft Windows Server 2003 (and + * possibly others) return the realm in a PRINCIPAL_UNKNOWN message. + * Detect this case by looking for a non-empty client.realm field in + * such responses. + */ +static krb5_boolean +is_referral(krb5_init_creds_context ctx) +{ + krb5_error *err = ctx->err_reply; + + if (err->error == KDC_ERR_WRONG_REALM) + return TRUE; + if (err->error != KDC_ERR_C_PRINCIPAL_UNKNOWN) + return FALSE; + return !is_empty_crealm(err); +} + static krb5_error_code init_creds_step_reply(krb5_context context, krb5_init_creds_context ctx, @@ -1478,9 +1507,9 @@ init_creds_step_reply(krb5_context context, ctx->preauth_to_use); ctx->preauth_required = TRUE; - } else if (canon_flag && ctx->err_reply->error == KDC_ERR_WRONG_REALM) { - if (ctx->err_reply->client == NULL || - !krb5_princ_realm(context, ctx->err_reply->client)->length) { + } else if (canon_flag && is_referral(ctx)) { + if (is_empty_crealm(ctx->err_reply)) { + /* Only WRONG_REALM referral types can reach this. */ code = KRB5KDC_ERR_WRONG_REALM; goto cleanup; } |