From 274464a6faaee694c30ae4d1412a8ab516b1a982 Mon Sep 17 00:00:00 2001 From: Julien Rische Date: Wed, 20 Sep 2023 16:22:06 +0200 Subject: [PATCH] [downstream] Allow to make AD-SIGNEDPATH optional MIT krb5 1.20 and newer KDCs do generate a minimal PAC instead of AD-SIGNEDPATH. As a consequence, an evidence ticket generated by an older KDC would fail to be processed by a newer KDC for a constrained delegation request. This commit modifies this behavior to check the AD-SIGNEDPATH whenever it is present in a TGS-REQ, but do not require it in case a PAC is provided AND the KDB plugin supports its verification. This is done regardless to the fact the constrained delegation request is from a local realm or a cross-realm. To enable this mechanism, the KDB plugin must set the "optional_ab_signedpath" string attribute to "true" for the local TGS principal. --- src/include/kdb.h | 1 + src/kdc/kdc_authdata.c | 65 +++++++++++++++++++++++++++++++++--------- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/include/kdb.h b/src/include/kdb.h index c56947ab81..95d07d0195 100644 --- a/src/include/kdb.h +++ b/src/include/kdb.h @@ -136,6 +136,7 @@ /* String attribute names recognized by krb5 */ #define KRB5_KDB_SK_SESSION_ENCTYPES "session_enctypes" #define KRB5_KDB_SK_REQUIRE_AUTH "require_auth" +#define KRB5_KDB_SK_OPTIONAL_AD_SIGNEDPATH "optional_ad_signedpath" #if !defined(_WIN32) diff --git a/src/kdc/kdc_authdata.c b/src/kdc/kdc_authdata.c index 1ebe872467..c0fcccdf21 100644 --- a/src/kdc/kdc_authdata.c +++ b/src/kdc/kdc_authdata.c @@ -668,6 +668,13 @@ has_pac(krb5_context context, krb5_authdata **authdata) return has_kdc_issued_authdata(context, authdata, KRB5_AUTHDATA_WIN2K_PAC); } +/* Return true if the AD-SIGNEDPATH is present in authorization data. */ +static krb5_boolean +has_ad_signedpath(krb5_context context, krb5_authdata **authdata) +{ + return has_kdc_issued_authdata(context, authdata, KRB5_AUTHDATA_SIGNTICKET); +} + /* Verify AD-SIGNTICKET authdata if we need to, and insert an AD-SIGNEDPATH * element if we should. */ static krb5_error_code @@ -680,24 +687,54 @@ handle_signticket(krb5_context context, unsigned int flags, { krb5_error_code ret = 0; krb5_principal *deleg_path = NULL; - krb5_boolean signed_path = FALSE; - krb5_boolean s4u2proxy; + krb5_boolean s4u2proxy, adsp_present, adsp_optional, adsp_valid = FALSE; + char *str; s4u2proxy = isflagset(flags, KRB5_KDB_FLAG_CONSTRAINED_DELEGATION); - /* For cross-realm the Windows PAC must have been verified, and it - * fulfills the same role as the signed path. */ - if (req->msg_type == KRB5_TGS_REQ && - (!isflagset(flags, KRB5_KDB_FLAG_CROSS_REALM) || - !has_pac(context, enc_tkt_req->authorization_data))) { - ret = verify_signedpath(context, local_tgt, local_tgt_key, enc_tkt_req, - &deleg_path, &signed_path); - if (ret) - goto cleanup; + if (req->msg_type == KRB5_TGS_REQ) { + adsp_present = has_ad_signedpath(context, + enc_tkt_req->authorization_data); + + /* In case of constained delegation, based on the value of the + * "optional_ad_signedpath" string attribute of the local TGS principal: + * - "true": in case AD-SIGNEDPATH is absent, the PAC must be present + * - "false" or undefined: AD-SIGNEDPATH must be present + */ + if (s4u2proxy && !adsp_present) { + ret = krb5_dbe_get_string(context, local_tgt, + KRB5_KDB_SK_OPTIONAL_AD_SIGNEDPATH, + &str); + /* TODO: should be using _krb5_conf_boolean(), but os-proto.h is not + * available here. + */ + adsp_optional = !ret && str && (strncasecmp(str, "true", 4) == 0 + || strncasecmp(str, "t", 1) == 0 + || strncasecmp(str, "yes", 3) == 0 + || strncasecmp(str, "y", 1) == 0 + || strncasecmp(str, "1", 1) == 0 + || strncasecmp(str, "on", 2) == 0); + + if (!adsp_optional || + !has_pac(context, enc_tkt_req->authorization_data)) { + ret = KRB5KDC_ERR_BADOPTION; + goto cleanup; + } + } - if (s4u2proxy && signed_path == FALSE) { - ret = KRB5KDC_ERR_BADOPTION; - goto cleanup; + /* If AD-SIGNEDPATH is present, verify it */ + if (adsp_present) { + ret = verify_signedpath(context, local_tgt, local_tgt_key, + enc_tkt_req, &deleg_path, &adsp_valid); + if (ret) + goto cleanup; + + /* In case of contrained delegation, if AD-SIGNEDPATH is present, it + * has to be valid */ + if (s4u2proxy && !adsp_valid) { + ret = KRB5KDC_ERR_BADOPTION; + goto cleanup; + } } } -- 2.41.0