aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNate Rosenblum <nater@maginatics.com>2013-12-23 13:21:44 -0800
committerTom Yu <tlyu@mit.edu>2015-02-06 16:55:11 -0500
commit6dda4d7acd4565f983784b484baae32f930cc810 (patch)
treea9c53ad818b8ca10ba82d752cefe74aabddff832
parent5a1bd1d9c4e6f46ff03bd1c0957d803ea8671360 (diff)
downloadkrb5-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.c35
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;
}