From: Isaac Boukris Date: Sat, 2 Nov 2019 12:32:32 +0000 (+0100) Subject: Do not always canonicalize enterprise principals X-Git-Tag: krb5-1.18-beta1~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3f5955631a2056f8ec4d1ce73d9681fa7da061c2;p=thirdparty%2Fkrb5.git Do not always canonicalize enterprise principals 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) --- diff --git a/src/include/kdb.h b/src/include/kdb.h index a632de9ad1..fc9400b984 100644 --- a/src/include/kdb.h +++ b/src/include/kdb.h @@ -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, diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c index 5da8abde14..fcff99f5c4 100644 --- a/src/kdc/do_as_req.c +++ b/src/kdc/do_as_req.c @@ -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); } diff --git a/src/tests/t_kdb.py b/src/tests/t_kdb.py index cc5d2fc3c8..7271fcbbd3 100755 --- a/src/tests/t_kdb.py +++ b/src/tests/t_kdb.py @@ -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'])