]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Do not always canonicalize enterprise principals
authorIsaac Boukris <iboukris@gmail.com>
Sat, 2 Nov 2019 12:32:32 +0000 (13:32 +0100)
committerGreg Hudson <ghudson@mit.edu>
Sat, 28 Dec 2019 06:02:03 +0000 (01:02 -0500)
When processing an AS request in the KDC, do not assume
KRB5_KDB_FLAG_CANONICALIZE for enterprise client names.  This change
allows the KDB module to only canonicalize enterprise client names if
the canonicalize flag was set on the request, as Windows does.  The
KDB module may check the principal type and apply canonicalization as
appropriate.

[ghudson@mit.edu: edited comments; rewrote commit message]

ticket: 8858 (new)

src/include/kdb.h
src/kdc/do_as_req.c
src/tests/t_kdb.py

index a632de9ad1ad7c2aa0bcb4b3986252ae14dc7862..fc9400b984c853bedfc2f0f2ff509ae3937fd08c 100644 (file)
@@ -1057,15 +1057,18 @@ typedef struct _kdb_vftabl {
      * in-realm alias, fill in a different value for entries->princ than the
      * one requested.
      *
-     * A module can return out-of-realm referrals if KRB5_KDB_FLAG_CANONICALIZE
-     * is set.  For AS request clients (KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY is
-     * also set), the module should do so by simply filling in an out-of-realm
-     * name in entries->princ and setting all other fields to NULL.  Otherwise,
-     * the module should return the entry for the cross-realm TGS of the
-     * referred-to realm.  For TGS referals, the module can also include
-     * tl-data of type KRB5_TL_SERVER_REFERRAL containing ASN.1-encoded Windows
-     * referral data as documented in draft-ietf-krb-wg-kerberos-referrals-11
-     * appendix A; this will be returned to the client as encrypted padata.
+     * A module can return a referral to another realm if
+     * KRB5_KDB_FLAG_CANONICALIZE is set, or if
+     * KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY is set and search_for->type is
+     * KRB5_NT_ENTERPRISE_PRINCIPAL.  If KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY is
+     * set, the module should return a referral by simply filling in an
+     * out-of-realm name in (*entry)->princ and setting all other fields to
+     * NULL.  Otherwise, the module should return the entry for the cross-realm
+     * TGS of the referred-to realm.  For TGS referals, the module can also
+     * include tl-data of type KRB5_TL_SERVER_REFERRAL containing ASN.1-encoded
+     * Windows referral data as documented in
+     * draft-ietf-krb-wg-kerberos-referrals-11 appendix A; this will be
+     * returned to the client as encrypted padata.
      */
     krb5_error_code (*get_principal)(krb5_context kcontext,
                                      krb5_const_principal search_for,
index 5da8abde14c3836ba2af541e18c0a306a44c1e0a..fcff99f5c4dab088d599ee94f7ca6580e61013d7 100644 (file)
@@ -596,15 +596,14 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
      * of cross realm TGS entries.
      */
     setflag(state->c_flags, KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY);
-    /*
-     * Note that according to the referrals draft we should
-     * always canonicalize enterprise principal names.
-     */
+    /* Enterprise principals are implicitly alias-ok. */
     if (isflagset(state->request->kdc_options, KDC_OPT_CANONICALIZE) ||
         state->request->client->type == KRB5_NT_ENTERPRISE_PRINCIPAL) {
-        setflag(state->c_flags, KRB5_KDB_FLAG_CANONICALIZE);
         setflag(state->c_flags, KRB5_KDB_FLAG_ALIAS_OK);
     }
+    if (isflagset(state->request->kdc_options, KDC_OPT_CANONICALIZE)) {
+        setflag(state->c_flags, KRB5_KDB_FLAG_CANONICALIZE);
+    }
     if (include_pac_p(kdc_context, state->request)) {
         setflag(state->c_flags, KRB5_KDB_FLAG_INCLUDE_PAC);
     }
index cc5d2fc3c81faae067b2ee7a92ac21001fa7782e..7271fcbbd30a6da3260c7b7ab6803506eae5de8a 100755 (executable)
@@ -340,11 +340,14 @@ ldap_modify('dn: krbPrincipalName=canon@KRBTEST.COM,cn=t1,cn=krb5\n'
             'changetype: modify\n'
             'add: krbPrincipalName\n'
             'krbPrincipalName: alias@KRBTEST.COM\n'
+            'krbPrincipalName: ent@abc@KRBTEST.COM\n'
             '-\n'
             'add: krbCanonicalName\n'
             'krbCanonicalName: canon@KRBTEST.COM\n')
 realm.run([kadminl, 'getprinc', 'alias'],
           expected_msg='Principal: canon@KRBTEST.COM\n')
+realm.run([kadminl, 'getprinc', 'ent\@abc'],
+          expected_msg='Principal: canon@KRBTEST.COM\n')
 realm.run([kadminl, 'getprinc', 'canon'],
           expected_msg='Principal: canon@KRBTEST.COM\n')
 realm.run([kvno, 'alias', 'canon'])
@@ -389,6 +392,15 @@ realm.run([kadminl, 'modprinc', '+requires_preauth', 'canon'])
 realm.kinit('canon', password('canon'))
 realm.kinit('alias', password('canon'), ['-C'])
 
+# Test enterprise alias with and without canonicalization.
+realm.kinit('ent@abc', password('canon'), ['-E', '-C'])
+realm.run([kvno, 'alias'])
+realm.klist('canon@KRBTEST.COM', 'alias@KRBTEST.COM')
+
+realm.kinit('ent@abc', password('canon'), ['-E'])
+realm.run([kvno, 'alias'])
+realm.klist('ent\@abc@KRBTEST.COM', 'alias@KRBTEST.COM')
+
 # Test client name canonicalization in non-krbtgt AS reply
 realm.kinit('alias', password('canon'), ['-C', '-S', 'kadmin/changepw'])