From cdd0b70d37d87026e8618ff44b8d636c0bf9cb6c Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Mon, 3 Jun 2019 14:36:36 +1000 Subject: [PATCH] kdc: don't misidentify constrained delegation requests as anonymous Earlier (pre-7.6) Heimdal clients would send both the request-anonymous and cname-in-addl-tkt flags for constrained delegation requests. A true anonymous TGS request will only have the former flag set. Do not treat TGS requests with both flags set as anonymous requests. --- kdc/kerberos5.c | 15 ++++++++------- kdc/krb5tgs.c | 22 ++++++++++++++++++++-- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/kdc/kerberos5.c b/kdc/kerberos5.c index f869038a9..a5c318f00 100644 --- a/kdc/kerberos5.c +++ b/kdc/kerberos5.c @@ -118,15 +118,16 @@ is_default_salt_p(const krb5_salt *default_salt, const Key *key) static krb5_boolean -is_anon_request_p(kdc_request_t r) +is_anon_as_request_p(kdc_request_t r) { KDC_REQ_BODY *b = &r->req.req_body; /* * Some versions of heimdal use bit 14 instead of 16 for * request_anonymous, as indicated in the anonymous draft prior to - * version 11. Bit 14 is assigned to S4U2Proxy, but all S4U2Proxy - * requests will have a second ticket; don't consider those anonymous + * version 11. Bit 14 is assigned to S4U2Proxy, but S4U2Proxy requests + * are only sent to the TGS and, in any case, would have an additional + * ticket present. */ return b->kdc_options.request_anonymous || (b->kdc_options.cname_in_addl_tkt && !b->additional_tickets); @@ -463,7 +464,7 @@ pa_enc_chal_validate(kdc_request_t r, const PA_DATA *pa) heim_assert(r->armor_crypto != NULL, "ENC-CHAL called for non FAST"); - if (is_anon_request_p(r)) { + if (is_anon_as_request_p(r)) { ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; kdc_log(r->context, r->config, 0, "ENC-CHALL doesn't support anon"); return ret; @@ -1794,7 +1795,7 @@ _kdc_as_rep(kdc_request_t r, */ if (_kdc_is_anonymous(context, r->client_princ) && - !is_anon_request_p(r)) { + !is_anon_as_request_p(r)) { kdc_log(context, config, 0, "Anonymous client w/o anonymous flag"); ret = KRB5KDC_ERR_BADOPTION; goto out; @@ -1968,7 +1969,7 @@ _kdc_as_rep(kdc_request_t r, * send requre preauth is its required or anon is requested, * anon is today only allowed via preauth mechanisms. */ - if (require_preauth_p(r) || is_anon_request_p(r)) { + if (require_preauth_p(r) || is_anon_as_request_p(r)) { ret = KRB5KDC_ERR_PREAUTH_REQUIRED; _kdc_set_e_text(r, "Need to use PA-ENC-TIMESTAMP/PA-PK-AS-REQ"); goto out; @@ -2001,7 +2002,7 @@ _kdc_as_rep(kdc_request_t r, if(ret) goto out; - if (is_anon_request_p(r)) { + if (is_anon_as_request_p(r)) { ret = _kdc_check_anon_policy(context, config, r->client, r->server); if (ret) { _kdc_set_e_text(r, "Anonymous ticket requests are disabled"); diff --git a/kdc/krb5tgs.c b/kdc/krb5tgs.c index 7ef05ecfa..3ba242037 100644 --- a/kdc/krb5tgs.c +++ b/kdc/krb5tgs.c @@ -366,6 +366,24 @@ check_PAC(krb5_context context, return 0; } +static krb5_boolean +is_anon_tgs_request_p(const KDC_REQ_BODY *b, + const EncTicketPart *tgt) +{ + KDCOptions f = b->kdc_options; + + /* + * Earlier (pre-7.6) versions of Heimdal would send both the + * request-anonymous and cname-in-addl-tkt flags for constrained + * delegation requests. A true anonymous TGS request will only + * have the request-anonymous flag set. (A corollary of this is + * that it is not possible to support anonymous constrained + * delegation requests, although they would be of limited utility.) + */ + return tgt->flags.anonymous || + (f.request_anonymous && !f.cname_in_addl_tkt && !b->additional_tickets); +} + /* * */ @@ -506,7 +524,7 @@ check_tgs_flags(krb5_context context, * anonymous KDC option SHOULD be set, but it is not required. * Treat an anonymous TGT as if the anonymous flag was set. */ - if (tgt->flags.anonymous || f.request_anonymous) + if (is_anon_tgs_request_p(b, tgt)) et->flags.anonymous = 1; return 0; @@ -2346,7 +2364,7 @@ server_lookup: } /* check local and per-principal anonymous ticket issuance policy */ - if (tgt->flags.anonymous || b->kdc_options.request_anonymous) { + if (is_anon_tgs_request_p(b, tgt)) { ret = _kdc_check_anon_policy(context, config, client, server); if (ret) goto out;