]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Support referrals from Windows Server 2003
authorNate Rosenblum <nater@maginatics.com>
Mon, 23 Dec 2013 21:21:44 +0000 (13:21 -0800)
committerTom Yu <tlyu@mit.edu>
Tue, 18 Feb 2014 20:20:15 +0000 (15:20 -0500)
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]

ticket: 7856 (new)
target_version: 1.12.2
tags: pullup

src/lib/krb5/krb/get_in_tkt.c

index f8f38014b62890bc2d9e5d25fcf138b300cbf18c..d7b2bd9ebd39009b51512ce6995de05a574894fe 100644 (file)
@@ -1396,6 +1396,35 @@ note_req_timestamp(krb5_context context, krb5_init_creds_context ctx,
         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,
@@ -1454,9 +1483,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 ||
-                !ctx->err_reply->client->realm.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;
             }