third_party/heimdal: Import lorikeet-heimdal-202306192129 (commit 0096f9c1dc105d8ac9f...
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Mon, 19 Jun 2023 22:52:01 +0000 (10:52 +1200)
committerStefan Metzmacher <metze@samba.org>
Mon, 26 Jun 2023 11:10:31 +0000 (11:10 +0000)
NOTE: THIS COMMIT WON’T COMPILE/WORK ON ITS OWN!

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
18 files changed:
selftest/knownfail_heimdal_kdc
third_party/heimdal/kdc/fast.c
third_party/heimdal/kdc/kdc-accessors.h
third_party/heimdal/kdc/kdc-audit.h
third_party/heimdal/kdc/kdc-plugin.c
third_party/heimdal/kdc/kdc-plugin.h
third_party/heimdal/kdc/kdc_locl.h
third_party/heimdal/kdc/kerberos5.c
third_party/heimdal/kdc/krb5tgs.c
third_party/heimdal/kdc/libkdc-exports.def
third_party/heimdal/kdc/mssfu.c
third_party/heimdal/kdc/pkinit.c
third_party/heimdal/kdc/version-script.map
third_party/heimdal/lib/base/dict.c
third_party/heimdal/lib/krb5/changepw.c
third_party/heimdal/lib/krb5/crypto.c
third_party/heimdal/lib/krb5/deprecated.c
third_party/heimdal/lib/krb5/init_creds.c

index 2fbf7f72284ad3abccceb3109e515f6d9d22a921..095234514e9cb7b97c9615ff82adc3c5def2477a 100644 (file)
@@ -3,11 +3,6 @@
 # kerberos
 ^samba.tests.krb5.compatability_tests.samba.tests.krb5.compatability_tests.SimpleKerberosTests.test_mit_
 #
-# AS-REQ tests
-#
-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_logon_hours_wrong_password.fl2003dc
-^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_logon_hours_wrong_password.fl2008r2dc
-#
 # Heimdal currently fails the following MS-KILE client principal lookup
 # tests
 ^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_enterprise_principal_step_6_a
@@ -39,7 +34,7 @@
 ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_forwardable
 ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_s4u2self_not_trusted_empty_allowed
 #
-^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_auth_data_required
+^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_constrained_delegation_no_client_pac_no_auth_data_required
 ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd\(
 ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_auth_data_required
 ^samba.tests.krb5.s4u_tests.samba.tests.krb5.s4u_tests.S4UKerberosTests.test_rbcd_no_client_pac_no_auth_data_required_a
 ^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_allow.ad_dc
 ^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_allow_constrained_delegation.ad_dc
 ^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_allow_constrained_delegation_to_self.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_allow_constrained_delegation_wrong_sname.ad_dc
 ^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_allow_domain_local_group.ad_dc
 ^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_allow_domain_local_group_from_rodc.ad_dc
 ^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_allow_from_rodc.ad_dc
index 1352a10fe01c6b237879321d052ac65fdb779392..b63d0b16a9d143714b9cd0dbe3185aa3f9761b57 100644 (file)
@@ -877,8 +877,10 @@ _kdc_fast_strengthen_reply_key(astgs_request_t r)
 
        ret = krb5_generate_random_keyblock(r->context, r->reply_key.keytype,
                                            &r->strengthen_key);
-       if (ret)
-           krb5_abortx(r->context, "random generator fail");
+       if (ret) {
+           kdc_log(r->context, r->config, 0, "failed to prepare random keyblock");
+           return ret;
+       }
 
        ret = _krb5_fast_cf2(r->context,
                             &r->strengthen_key, "strengthenkey",
@@ -969,16 +971,14 @@ _kdc_fast_check_armor_pac(astgs_request_t r, int flags)
        goto out;
     }
 
-    if (r->explicit_armor_present) {
-       r->explicit_armor_clientdb = armor_db;
-       armor_db = NULL;
+    r->armor_clientdb = armor_db;
+    armor_db = NULL;
 
-       r->explicit_armor_client = armor_client;
-       armor_client = NULL;
+    r->armor_client = armor_client;
+    armor_client = NULL;
 
-       r->explicit_armor_pac = mspac;
-       mspac = NULL;
-    }
+    r->armor_pac = mspac;
+    mspac = NULL;
 
 out:
     krb5_xfree(armor_client_principal_name);
index 911b83d7576fae892dd58b0168ac73e8ed247e37..c00fd49d60b27a3cecfed57dd477f3ece5cede2d 100644 (file)
@@ -346,24 +346,49 @@ ASTGS_REQUEST_GET_ACCESSOR(uint64_t, pac_attributes)
 
 ASTGS_REQUEST_SET_ACCESSOR(uint64_t, pac_attributes)
 
+KDC_LIB_FUNCTION const HDB * KDC_LIB_CALL
+kdc_request_get_explicit_armor_clientdb(astgs_request_t);
+
+KDC_LIB_FUNCTION const hdb_entry * KDC_LIB_CALL
+kdc_request_get_explicit_armor_client(astgs_request_t);
+
+KDC_LIB_FUNCTION const hdb_entry * KDC_LIB_CALL
+kdc_request_get_explicit_armor_server(astgs_request_t);
+
+KDC_LIB_FUNCTION krb5_const_pac KDC_LIB_CALL
+kdc_request_get_explicit_armor_pac(astgs_request_t);
+
 /*
  * const HDB *
- * kdc_request_get_explicit_armor_clientdb(astgs_request_t);
+ * kdc_request_get_armor_clientdb(astgs_request_t);
  */
 
-ASTGS_REQUEST_GET_ACCESSOR_PTR(HDB *, explicit_armor_clientdb)
+ASTGS_REQUEST_GET_ACCESSOR_PTR(HDB *, armor_clientdb)
+
+/*
+ * const hdb_entry *
+ * kdc_request_get_armor_client(astgs_request_t);
+ */
+ASTGS_REQUEST_GET_ACCESSOR_PTR(hdb_entry *, armor_client);
 
 /*
  * const hdb_entry *
- * kdc_request_get_explicit_armor_client(astgs_request_t);
+ * kdc_request_get_armor_server(astgs_request_t);
  */
-ASTGS_REQUEST_GET_ACCESSOR_PTR(hdb_entry *, explicit_armor_client);
+ASTGS_REQUEST_GET_ACCESSOR_PTR(hdb_entry *, armor_server);
 
 /*
  * krb5_const_pac
- * kdc_request_get_explicit_armor_pac(astgs_request_t);
+ * kdc_request_get_armor_pac(astgs_request_t);
+ */
+
+ASTGS_REQUEST_GET_ACCESSOR_PTR(struct krb5_pac_data *, armor_pac);
+
+/*
+ * krb5_boolean
+ * kdc_request_get_explicit_armor_present(astgs_request_t);
  */
 
-ASTGS_REQUEST_GET_ACCESSOR_PTR(struct krb5_pac_data *, explicit_armor_pac);
+ASTGS_REQUEST_GET_ACCESSOR_PTR(krb5_boolean, explicit_armor_present);
 
 #endif /* HEIMDAL_KDC_KDC_ACCESSORS_H */
index df5362031f5ae72128eb35c963e8af2dc1d73821..4097c48b761937ed7e8075c42645c0d5c5fba81d 100644 (file)
@@ -52,6 +52,7 @@
 #define KDC_AUTH_EVENT_PREAUTH_FAILED          8   /* generic PA failure */
 #define KDC_AUTH_EVENT_PREAUTH_SUCCEEDED       9   /* generic (non-long term key) PA success */
 #define KDC_AUTH_EVENT_HISTORIC_LONG_TERM_KEY  10  /* PA failed to validate current long term key, but historic */
+#define KDC_AUTH_EVENT_CLIENT_FOUND            11  /* the client was successfully looked up */
 
 /*
  * Audit keys to be queried using kdc_audit_getkv(). There are other keys
index cbb61b51fc2c1a7e8e9909019e69897d73a3a228..f1d9a1f7579bd85e3053623f0be871ef86d1b1b1 100644 (file)
@@ -140,8 +140,8 @@ _kdc_pac_generate(astgs_request_t r,
 
 struct verify_uc {
     astgs_request_t r;
-    krb5_principal client_principal;
-    krb5_principal delegated_proxy_principal;
+    krb5_const_principal client_principal;
+    hdb_entry *delegated_proxy;
     hdb_entry *client;
     hdb_entry *server;
     hdb_entry *krbtgt;
@@ -163,7 +163,7 @@ verify(krb5_context context, const void *plug, void *plugctx, void *userctx)
     ret = ft->pac_verify((void *)plug,
                         uc->r,
                         uc->client_principal,
-                        uc->delegated_proxy_principal,
+                        uc->delegated_proxy,
                         uc->client, uc->server, uc->krbtgt,
                         uc->ticket, uc->pac,
                         uc->is_trusted);
@@ -172,8 +172,8 @@ verify(krb5_context context, const void *plug, void *plugctx, void *userctx)
 
 krb5_error_code
 _kdc_pac_verify(astgs_request_t r,
-               const krb5_principal client_principal,
-               const krb5_principal delegated_proxy_principal,
+               krb5_const_principal client_principal,
+               hdb_entry *delegated_proxy,
                hdb_entry *client,
                hdb_entry *server,
                hdb_entry *krbtgt,
@@ -188,7 +188,7 @@ _kdc_pac_verify(astgs_request_t r,
 
     uc.r = r;
     uc.client_principal = client_principal;
-    uc.delegated_proxy_principal = delegated_proxy_principal;
+    uc.delegated_proxy = delegated_proxy;
     uc.client = client;
     uc.server = server;
     uc.krbtgt = krbtgt;
@@ -202,8 +202,9 @@ _kdc_pac_verify(astgs_request_t r,
 
 struct update_uc {
     astgs_request_t r;
-    krb5_principal client_principal;
-    krb5_principal delegated_proxy_principal;
+    krb5_const_principal client_principal;
+    hdb_entry *delegated_proxy;
+    krb5_const_pac delegated_proxy_pac;
     hdb_entry *client;
     hdb_entry *server;
     hdb_entry *krbtgt;
@@ -223,15 +224,17 @@ update(krb5_context context, const void *plug, void *plugctx, void *userctx)
     ret = ft->pac_update((void *)plug,
                         uc->r,
                         uc->client_principal,
-                        uc->delegated_proxy_principal,
+                        uc->delegated_proxy,
+                        uc->delegated_proxy_pac,
                         uc->client, uc->server, uc->krbtgt, uc->pac);
     return ret;
 }
 
 krb5_error_code
 _kdc_pac_update(astgs_request_t r,
-               const krb5_principal client_principal,
-               const krb5_principal delegated_proxy_principal,
+               krb5_const_principal client_principal,
+               hdb_entry *delegated_proxy,
+               krb5_const_pac delegated_proxy_pac,
                hdb_entry *client,
                hdb_entry *server,
                hdb_entry *krbtgt,
@@ -244,7 +247,8 @@ _kdc_pac_update(astgs_request_t r,
 
     uc.r = r;
     uc.client_principal = client_principal;
-    uc.delegated_proxy_principal = delegated_proxy_principal;
+    uc.delegated_proxy = delegated_proxy;
+    uc.delegated_proxy_pac = delegated_proxy_pac;
     uc.client = client;
     uc.server = server;
     uc.krbtgt = krbtgt;
@@ -714,3 +718,27 @@ free_keyblock(EncryptionKey *key)
 
 #undef HEIMDAL_KDC_KDC_ACCESSORS_H
 #include "kdc-accessors.h"
+
+KDC_LIB_FUNCTION const HDB * KDC_LIB_CALL
+kdc_request_get_explicit_armor_clientdb(astgs_request_t r)
+{
+    return r->explicit_armor_present ? r->armor_clientdb : NULL;
+}
+
+KDC_LIB_FUNCTION const hdb_entry * KDC_LIB_CALL
+kdc_request_get_explicit_armor_client(astgs_request_t r)
+{
+    return r->explicit_armor_present ? r->armor_client : NULL;
+}
+
+KDC_LIB_FUNCTION const hdb_entry * KDC_LIB_CALL
+kdc_request_get_explicit_armor_server(astgs_request_t r)
+{
+    return r->explicit_armor_present ? r->armor_server : NULL;
+}
+
+KDC_LIB_FUNCTION krb5_const_pac KDC_LIB_CALL
+kdc_request_get_explicit_armor_pac(astgs_request_t r)
+{
+    return r->explicit_armor_present ? r->armor_pac : NULL;
+}
index 2e26d90137e654a58325d09701c16e7df159f60f..7d44f0a52437627468fe366c68a97225928b8fe5 100644 (file)
@@ -65,8 +65,8 @@ typedef krb5_error_code
 typedef krb5_error_code
 (KRB5_CALLCONV *krb5plugin_kdc_pac_verify)(void *,
                                           astgs_request_t,
-                                          const krb5_principal, /* new ticket client */
-                                          const krb5_principal, /* delegation proxy */
+                                          krb5_const_principal, /* new ticket client */
+                                          hdb_entry *, /* delegation proxy */
                                           hdb_entry *,/* client */
                                           hdb_entry *,/* server */
                                           hdb_entry *,/* krbtgt */
@@ -84,8 +84,9 @@ typedef krb5_error_code
 typedef krb5_error_code
 (KRB5_CALLCONV *krb5plugin_kdc_pac_update)(void *,
                                           astgs_request_t,
-                                          const krb5_principal, /* new ticket client */
-                                          const krb5_principal, /* delegation proxy */
+                                          krb5_const_principal, /* new ticket client */
+                                          hdb_entry *, /* delegation proxy */
+                                          krb5_const_pac, /* delegation proxy pac */
                                           hdb_entry *,/* client */
                                           hdb_entry *,/* server */
                                           hdb_entry *,/* krbtgt */
index bf9a0bc55e9c4e050d5d4b47e141f9463bfd06a4..5fe9ce620ada433534175e66ef5c9cb6d384e55e 100644 (file)
@@ -176,9 +176,9 @@ struct astgs_request_desc {
     krb5_ticket *armor_ticket;
     Key *armor_key;
 
-    hdb_entry *explicit_armor_client;
-    HDB *explicit_armor_clientdb;
-    krb5_pac explicit_armor_pac;
+    hdb_entry *armor_client;
+    HDB *armor_clientdb;
+    krb5_pac armor_pac;
 
     KDCFastState fast;
 };
index 6d4887a44a6e1a57fe834bfaed978a9c0560cccb..463ee3691170f97fa4a7e1fbffe52afcc06c91dd 100644 (file)
@@ -1275,7 +1275,7 @@ pa_enc_ts_validate(astgs_request_t r, const PA_DATA *pa)
 
 struct kdc_patypes {
     int type;
-    char *name;
+    const char *name;
     unsigned int flags;
 #define PA_ANNOUNCE    1
 #define PA_REQ_FAST    2 /* only use inside fast */
@@ -2199,7 +2199,7 @@ generate_pac(astgs_request_t r, const Key *skey, const Key *tkey,
                         rodc_id,
                         NULL, /* UPN */
                         canon_princ,
-                        false, /* add_full_sig */
+                        FALSE, /* add_full_sig */
                         is_tgs ? &r->pac_attributes : NULL,
                         &data);
     krb5_free_principal(r->context, client);
@@ -2384,6 +2384,13 @@ _kdc_as_rep(astgs_request_t r)
        goto out;
     }
 
+    /* Validate armor TGT, and initialize the armor client and PAC */
+    if (r->armor_ticket) {
+       ret = _kdc_fast_check_armor_pac(r, HDB_F_FOR_AS_REQ);
+       if (ret)
+           goto out;
+    }
+
     b = &req->req_body;
     f = b->kdc_options;
 
@@ -2476,6 +2483,10 @@ _kdc_as_rep(astgs_request_t r)
        goto out;
     }
     }
+
+    kdc_audit_setkv_number((kdc_request_t)r, KDC_REQUEST_KV_AUTH_EVENT,
+                          KDC_AUTH_EVENT_CLIENT_FOUND);
+
     ret = _kdc_db_fetch(r->context, config, r->server_princ,
                        HDB_F_GET_SERVER | HDB_F_DELAY_NEW_KEYS |
                        flags | (is_tgs ? HDB_F_GET_KRBTGT : 0),
@@ -2495,6 +2506,10 @@ _kdc_as_rep(astgs_request_t r)
        goto out;
     }
 
+    ret = _kdc_check_access(r);
+    if(ret)
+       goto out;
+
     /*
      * This has to be here (not later), because we need to have r->sessionetype
      * set prior to calling pa_pkinit_validate(), which in turn calls
@@ -2662,15 +2677,6 @@ _kdc_as_rep(astgs_request_t r)
 
     r->canon_client_princ = r->client->principal;
 
-    /*
-     * Verify flags after the user been required to prove its identity
-     * with in a preauth mech.
-     */
-
-    ret = _kdc_check_access(r);
-    if(ret)
-       goto out;
-
     if (_kdc_is_anon_request(&r->req)) {
        ret = _kdc_check_anon_policy(r);
        if (ret) {
@@ -3058,7 +3064,10 @@ _kdc_as_rep(astgs_request_t r)
     }
 
 out:
-    r->error_code = ret;
+    if (ret) {
+       /* Overwrite ‘error_code’ only if we have an actual error. */
+       r->error_code = ret;
+    }
     {
        krb5_error_code ret2 = _kdc_audit_request(r);
        if (ret2) {
@@ -3076,7 +3085,7 @@ out:
                                 r->rep.padata,
                                 r->armor_crypto,
                                 &req->req_body,
-                                r->error_code,
+                                r->error_code ? r->error_code : ret,
                                 r->client_princ,
                                 r->server_princ,
                                 NULL, NULL,
index b01aa52628363f5a0c00ca6a47208f0a335323a7..79dbe6622f46e703d5c520e0843b201ada4ea918 100644 (file)
@@ -78,7 +78,7 @@ _kdc_synthetic_princ_used_p(krb5_context context, krb5_ticket *ticket)
 krb5_error_code
 _kdc_check_pac(astgs_request_t r,
               const krb5_principal client_principal,
-              const krb5_principal delegated_proxy_principal,
+              hdb_entry *delegated_proxy,
               hdb_entry *client,
               hdb_entry *server,
               hdb_entry *krbtgt,
@@ -125,11 +125,11 @@ _kdc_check_pac(astgs_request_t r,
 
     /* Verify the KDC signatures. */
     ret = _kdc_pac_verify(r,
-                         client_principal, delegated_proxy_principal,
+                         client_principal, delegated_proxy,
                          client, server, krbtgt, tkt, pac, &is_trusted);
     if (ret == 0) {
        if (is_trusted) {
-           krb5_pac_set_trusted(pac, true);
+           krb5_pac_set_trusted(pac, TRUE);
        }
 
        if (pac_canon_name) {
@@ -1383,6 +1383,9 @@ tgs_build_reply(astgs_request_t priv,
 
     int result;
 
+    const PA_DATA *for_user = NULL;
+    int for_user_idx = 0;
+
     memset(&sessionkey, 0, sizeof(sessionkey));
     memset(&adtkt, 0, sizeof(adtkt));
 
@@ -1592,7 +1595,7 @@ server_lookup:
        ret = krb5_unparse_name(context, priv->krbtgt->principal, &ktpn);
        kdc_log(context, config, 4,
                "No such principal %s (needed for authz-data signature keys) "
-               "while processing TGS-REQ for service %s with krbtg %s",
+               "while processing TGS-REQ for service %s with krbtgt %s",
                krbtgt_out_n, spn, (ret == 0) ? ktpn : "<unknown>");
        free(ktpn);
        ret = KRB5KRB_AP_ERR_NOT_US;
@@ -1892,8 +1895,35 @@ server_lookup:
        goto out;
     }
 
-    if (priv->pac != NULL) {
-       ret = _kdc_pac_update(priv, priv->client_princ, NULL,
+    /*
+     * Process request
+     */
+
+    /*
+     * Services for User: protocol transition and constrained delegation
+     */
+
+    if (priv->client != NULL &&
+       (for_user = _kdc_find_padata(&priv->req,
+                                    &for_user_idx,
+                                    KRB5_PADATA_FOR_USER)) != NULL)
+    {
+       /* Process an S4U2Self request. */
+       ret = _kdc_validate_protocol_transition(priv, for_user);
+       if (ret)
+           goto out;
+    } else if (priv->client != NULL
+              && b->additional_tickets != NULL
+              && b->additional_tickets->len != 0
+              && b->kdc_options.cname_in_addl_tkt
+              && b->kdc_options.enc_tkt_in_skey == 0)
+    {
+       /* Process an S4U2Proxy request. */
+       ret = _kdc_validate_constrained_delegation(priv);
+       if (ret)
+           goto out;
+    } else if (priv->pac != NULL) {
+       ret = _kdc_pac_update(priv, priv->client_princ, NULL, NULL,
                              priv->client, priv->server, priv->krbtgt,
                              &priv->pac);
        if (ret == KRB5_PLUGIN_NO_HANDLE) {
@@ -1915,18 +1945,6 @@ server_lookup:
        }
     }
 
-    /*
-     * Process request
-     */
-
-    /*
-     * Services for User: protocol transition and constrained delegation
-     */
-
-    ret = _kdc_validate_services_for_user(priv);
-    if (ret)
-       goto out;
-
     if (b->enc_authorization_data) {
        unsigned auth_data_usage;
        krb5_crypto crypto;
@@ -2206,7 +2224,10 @@ _kdc_tgs_rep(astgs_request_t r)
     }
 
 out:
-    r->error_code = ret;
+    if (ret) {
+       /* Overwrite ‘error_code’ only if we have an actual error. */
+       r->error_code = ret;
+    }
     {
        krb5_error_code ret2 = _kdc_audit_request(r);
        if (ret2) {
@@ -2223,7 +2244,7 @@ out:
                                 &error_method,
                                 r->armor_crypto,
                                 &req->req_body,
-                                r->error_code,
+                                r->error_code ? r->error_code : ret,
                                 r->client_princ ? r->client_princ :(r->ticket != NULL ? r->ticket->client : NULL),
                                 r->server_princ ? r->server_princ :(r->ticket != NULL ? r->ticket->server : NULL),
                                 csec, cusec,
@@ -2260,12 +2281,12 @@ out:
        krb5_free_ticket(r->context, r->armor_ticket);
     if (r->armor_server)
        _kdc_free_ent(r->context, r->armor_serverdb, r->armor_server);
-    if (r->explicit_armor_client)
+    if (r->armor_client)
        _kdc_free_ent(r->context,
-                     r->explicit_armor_clientdb,
-                     r->explicit_armor_client);
-    if (r->explicit_armor_pac)
-       krb5_pac_free(r->context, r->explicit_armor_pac);
+                     r->armor_clientdb,
+                     r->armor_client);
+    if (r->armor_pac)
+       krb5_pac_free(r->context, r->armor_pac);
     krb5_free_keyblock_contents(r->context, &r->reply_key);
     krb5_free_keyblock_contents(r->context, &r->enc_ad_key);
     krb5_free_keyblock_contents(r->context, &r->strengthen_key);
index d7c5a0de1abb3fcb601f79f3f48e51513527a19c..a6aaf94d3fc8cd8ee11e373c48ac8232e7dc6d09 100644 (file)
@@ -26,6 +26,10 @@ EXPORTS
        kdc_request_add_pac_buffer
        kdc_request_add_reply_padata
        kdc_request_get_addr
+       kdc_request_get_armor_client
+       kdc_request_get_armor_clientdb
+       kdc_request_get_armor_pac
+       kdc_request_get_armor_server
        kdc_request_get_canon_client_princ
        kdc_request_get_client
        kdc_request_get_clientdb
@@ -37,6 +41,8 @@ EXPORTS
        kdc_request_get_explicit_armor_pac
        kdc_request_get_explicit_armor_clientdb
        kdc_request_get_explicit_armor_client
+       kdc_request_get_explicit_armor_present
+       kdc_request_get_explicit_armor_server
        kdc_request_get_from
        kdc_request_get_krbtgt
        kdc_request_get_krbtgtdb
index 6145fc8e8e1da3f4bc0a2377ff073bc0468865c3..c583c9b667dace32d8c98aa88748233756aef7a9 100644 (file)
@@ -97,13 +97,13 @@ check_constrained_delegation(krb5_context context,
 }
 
 /*
- * Validate a protocol transition (S4U2Self) request. If present and
- * successfully validated then the client in the request structure
- * will be replaced with the impersonated client.
+ * Validate a protocol transition (S4U2Self) request. If successfully
+ * validated then the client in the request structure will be replaced
+ * with the impersonated client.
  */
 
-static krb5_error_code
-validate_protocol_transition(astgs_request_t r)
+krb5_error_code
+_kdc_validate_protocol_transition(astgs_request_t r, const PA_DATA *for_user)
 {
     krb5_error_code ret;
     KDC_REQ_BODY *b = &r->req.req_body;
@@ -113,28 +113,21 @@ validate_protocol_transition(astgs_request_t r)
     int flags = HDB_F_FOR_TGS_REQ;
     krb5_principal s4u_client_name = NULL, s4u_canon_client_name = NULL;
     krb5_pac s4u_pac = NULL;
-    const PA_DATA *sdata;
     char *s4ucname = NULL;
-    int i = 0;
     krb5_crypto crypto;
     krb5_data datack;
     PA_S4U2Self self;
     const char *str;
 
-    if (r->client == NULL)
-       return 0;
-
-    sdata = _kdc_find_padata(&r->req, &i, KRB5_PADATA_FOR_USER);
-    if (sdata == NULL)
-       return 0;
+    heim_assert(r->client != NULL, "client must be non-NULL");
 
     memset(&self, 0, sizeof(self));
 
     if (b->kdc_options.canonicalize)
        flags |= HDB_F_CANON;
 
-    ret = decode_PA_S4U2Self(sdata->padata_value.data,
-                            sdata->padata_value.length,
+    ret = decode_PA_S4U2Self(for_user->padata_value.data,
+                            for_user->padata_value.length,
                             &self, NULL);
     if (ret) {
        kdc_audit_addreason((kdc_request_t)r,
@@ -293,13 +286,13 @@ validate_protocol_transition(astgs_request_t r)
      */
     if (r->client->flags.trusted_for_delegation &&
        s4u_client->flags.forwardable) {
-       str = "[forwardable]";
+       str = " [forwardable]";
     } else {
        b->kdc_options.forwardable = 0;
        str = "";
     }
     kdc_log(r->context, r->config, 4, "s4u2self %s impersonating %s to "
-           "service %s %s", r->cname, s4ucname, r->sname, str);
+           "service %s%s", r->cname, s4ucname, r->sname, str);
 
     /*
      * Replace all client information in the request with the
@@ -332,13 +325,13 @@ out:
 }
 
 /*
- * Validate a constrained delegation (S4U2Proxy) request. If present
- * and successfully validated then the client in the request structure
- * will be replaced with the client from the evidence ticket.
+ * Validate a constrained delegation (S4U2Proxy) request. If
+ * successfully validated then the client in the request structure will
+ * be replaced with the client from the evidence ticket.
  */
 
-static krb5_error_code
-validate_constrained_delegation(astgs_request_t r)
+krb5_error_code
+_kdc_validate_constrained_delegation(astgs_request_t r)
 {
     krb5_error_code ret;
     KDC_REQ_BODY *b = &r->req.req_body;
@@ -351,18 +344,13 @@ validate_constrained_delegation(astgs_request_t r)
     EncTicketPart evidence_tkt;
     HDB *s4u_clientdb;
     hdb_entry *s4u_client = NULL;
+    HDB *s4u_serverdb = NULL;
+    hdb_entry *s4u_server = NULL;
     krb5_boolean ad_kdc_issued = FALSE;
     Key *clientkey;
     Ticket *t;
     krb5_const_realm local_realm;
 
-    if (r->client == NULL
-       || b->additional_tickets == NULL
-       || b->additional_tickets->len == 0
-       || b->kdc_options.cname_in_addl_tkt == 0
-       || b->kdc_options.enc_tkt_in_skey)
-       return 0;
-
     memset(&evidence_tkt, 0, sizeof(evidence_tkt));
     local_realm =
            krb5_principal_get_comp_string(r->context, r->krbtgt->principal, 1);
@@ -382,6 +370,49 @@ validate_constrained_delegation(astgs_request_t r)
 
     t = &b->additional_tickets->val[0];
 
+    ret = _krb5_principalname2krb5_principal(r->context,
+                                            &s4u_server_name,
+                                            t->sname,
+                                            t->realm);
+    if (ret)
+       goto out;
+
+    ret = krb5_unparse_name(r->context, s4u_server_name, &s4usname);
+    if (ret)
+       goto out;
+
+    /*
+     * Look up the name given in the ticket in the database. We don’t ask for
+     * canonicalisation, so that we get back the same principal that was
+     * specified in the ticket.
+     */
+    ret = _kdc_db_fetch(r->context, r->config, s4u_server_name,
+                       HDB_F_GET_SERVER | HDB_F_DELAY_NEW_KEYS | flags,
+                       NULL, &s4u_serverdb, &s4u_server);
+    if (ret == HDB_ERR_NOENTRY)
+       ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
+    if (ret) {
+       kdc_audit_addreason((kdc_request_t)r,
+                           "Constrained delegation service principal unknown");
+       goto out;
+    }
+
+    /*
+     * Check that the delegating server (r->client) is the same one as specified
+     * in the ticket. This is to make sure that the server hasn’t forged the
+     * sname, which is in the unencrypted part of the ticket.
+     */
+    ret = _kdc_check_client_matches_target_service(r->context,
+                                                  r->config,
+                                                  s4u_serverdb,
+                                                  s4u_server,
+                                                  r->client,
+                                                  r->client_princ);
+    if (ret == KRB5KRB_AP_ERR_BADMATCH)
+       ret = KRB5KDC_ERR_BADOPTION;
+    if (ret)
+       goto out;
+
     ret = hdb_enctype2key(r->context, r->client,
                          hdb_kvno2keys(r->context, r->client,
                                        t->enc_part.kvno ? * t->enc_part.kvno : 0),
@@ -397,7 +428,7 @@ validate_constrained_delegation(astgs_request_t r)
                            "Failed to decrypt constrained delegation ticket");
        kdc_log(r->context, r->config, 4,
                "failed to decrypt ticket for "
-               "constrained delegation from %s to %s ", r->cname, r->sname);
+               "constrained delegation from %s to %s", r->cname, r->sname);
        goto out;
     }
 
@@ -414,17 +445,6 @@ validate_constrained_delegation(astgs_request_t r)
 
     kdc_audit_addkv((kdc_request_t)r, 0, "impersonatee", "%s", s4ucname);
 
-    ret = _krb5_principalname2krb5_principal(r->context,
-                                            &s4u_server_name,
-                                            t->sname,
-                                            t->realm);
-    if (ret)
-       goto out;
-
-    ret = krb5_unparse_name(r->context, s4u_server_name, &s4usname);
-    if (ret)
-       goto out;
-
        /* check that ticket is valid */
     if (evidence_tkt.flags.forwardable == 0) {
        kdc_audit_addreason((kdc_request_t)r,
@@ -472,7 +492,7 @@ validate_constrained_delegation(astgs_request_t r)
      * TODO: pass in t->sname and t->realm and build
      * a S4U_DELEGATION_INFO blob to the PAC.
      */
-    ret = _kdc_check_pac(r, s4u_client_name, s4u_server_name,
+    ret = _kdc_check_pac(r, s4u_client_name, s4u_server,
                         s4u_client, r->server, r->krbtgt, r->client,
                         &clientkey->key, &r->ticket_key->key, &evidence_tkt,
                         &ad_kdc_issued, &s4u_pac,
@@ -482,7 +502,7 @@ validate_constrained_delegation(astgs_request_t r)
         kdc_audit_addreason((kdc_request_t)r,
                            "Constrained delegation ticket PAC check failed");
        kdc_log(r->context, r->config, 4,
-               "Verify delegated PAC failed to %s for client"
+               "Verify delegated PAC failed to %s for client "
                "%s (%s) as %s from %s with %s",
                r->sname, r->cname, s4usname, s4ucname, r->from, msg);
        krb5_free_error_message(r->context, msg);
@@ -503,7 +523,7 @@ validate_constrained_delegation(astgs_request_t r)
 
     heim_assert(s4u_pac != NULL, "ad_kdc_issued implies the PAC is non-NULL");
 
-    ret = _kdc_pac_update(r, s4u_client_name, s4u_server_name,
+    ret = _kdc_pac_update(r, s4u_client_name, s4u_server, r->pac,
                          s4u_client, r->server, r->krbtgt,
                          &s4u_pac);
     if (ret == KRB5_PLUGIN_NO_HANDLE) {
@@ -514,7 +534,7 @@ validate_constrained_delegation(astgs_request_t r)
         kdc_audit_addreason((kdc_request_t)r,
                            "Constrained delegation ticket PAC update failed");
        kdc_log(r->context, r->config, 4,
-               "Update delegated PAC failed to %s for client"
+               "Update delegated PAC failed to %s for client "
                "%s (%s) as %s from %s with %s",
                r->sname, r->cname, s4usname, s4ucname, r->from, msg);
        krb5_free_error_message(r->context, msg);
@@ -569,6 +589,8 @@ validate_constrained_delegation(astgs_request_t r)
 out:
     if (s4u_client)
        _kdc_free_ent(r->context, s4u_clientdb, s4u_client);
+    if (s4u_server)
+       _kdc_free_ent(r->context, s4u_serverdb, s4u_server);
     krb5_free_principal(r->context, s4u_client_name);
     krb5_xfree(s4ucname);
     krb5_free_principal(r->context, s4u_server_name);
@@ -580,19 +602,3 @@ out:
 
     return ret;
 }
-
-/*
- *
- */
-
-krb5_error_code
-_kdc_validate_services_for_user(astgs_request_t r)
-{
-    krb5_error_code ret;
-
-    ret = validate_protocol_transition(r);
-    if (ret == 0)
-       ret = validate_constrained_delegation(r);
-
-    return ret;
-}
index f01178983f3c826333c989b682ea4bbb2241268c..d06fc32cfbdb77332141fed8fad9d2a75723e397 100644 (file)
@@ -1988,7 +1988,7 @@ krb5_kdc_pk_initialize(krb5_context context,
                ret = hx509_cert_get_subject(cert, &name);
                if (ret == 0) {
                    hx509_name_to_string(name, &str);
-                   krb5_warnx(context, "WARNING Found KDC certificate (%s)"
+                   krb5_warnx(context, "WARNING Found KDC certificate (%s) "
                               "is missing the PKINIT KDC EKU, this is bad for "
                               "interoperability.", str);
                    hx509_name_free(&name);
index 3028789cb6076f3c6e2c4613ed325bfdaf5792b9..415526c007c608bb98521164089b5e388695ace7 100644 (file)
@@ -29,6 +29,10 @@ HEIMDAL_KDC_1.0 {
                kdc_request_add_pac_buffer;
                kdc_request_add_reply_padata;
                kdc_request_get_addr;
+               kdc_request_get_armor_client;
+               kdc_request_get_armor_clientdb;
+               kdc_request_get_armor_pac;
+               kdc_request_get_armor_server;
                kdc_request_get_canon_client_princ;
                kdc_request_get_client;
                kdc_request_get_clientdb;
@@ -40,6 +44,8 @@ HEIMDAL_KDC_1.0 {
                kdc_request_get_explicit_armor_pac;
                kdc_request_get_explicit_armor_clientdb;
                kdc_request_get_explicit_armor_client;
+               kdc_request_get_explicit_armor_present;
+               kdc_request_get_explicit_armor_server;
                kdc_request_get_from;
                kdc_request_get_krbtgt;
                kdc_request_get_krbtgtdb;
index 86be109ffc5e7a273b21588e476a1ea408b76983..de924f48036733cdb3a057e11a906d75bff419b1 100644 (file)
@@ -52,8 +52,10 @@ dict_dealloc(void *ptr)
 {
     heim_dict_t dict = ptr;
     struct hashentry **h, *g, *i;
+    size_t j;
 
-    for (h = dict->tab; h < &dict->tab[dict->size]; ++h) {
+    for (j = 0; j < dict->size; ++j) {
+       h = &dict->tab[j];
        for (g = h[0]; g; g = i) {
            i = g->next;
            heim_release(g->key);
index 1982925bf0653ad578b36df8ad76dd49617b3dba..4336cddc37c15bb5c2507dbdd9b26901ed0889fe 100644 (file)
@@ -695,7 +695,7 @@ krb5_change_password (krb5_context  context,
                      int               *result_code,
                      krb5_data         *result_code_string,
                      krb5_data         *result_string)
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_set_password instead")
 {
     struct kpwd_proc *p = find_chpw_proto("change password");
 
index 699d227d696d9219f269b63959ece187ca42e65d..ce1faad72d6c463fa8050357d7abd326cc44eb08 100644 (file)
@@ -612,7 +612,7 @@ verify_checksum_iov(krb5_context context,
            return ret;
     } else if ((flags & KRB5_CRYPTO_FLAG_ALLOW_UNKEYED_CHECKSUM) == 0) {
        krb5_clear_error_message (context);
-       krb5_set_error_message(context, KRB5KRB_AP_ERR_BAD_INTEGRITY,
+       krb5_set_error_message(context, KRB5KRB_AP_ERR_INAPP_CKSUM,
                               N_("Unkeyed checksum type %s provided where keyed "
                                  "checksum was expected", ""), ct->name);
 
index 0efa162702cbc93fe8206295e47a32845326d177..172f089175cc9937f1737e29af8703d141c5beb2 100644 (file)
@@ -57,7 +57,7 @@
 
 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
 krb5_free_data_contents(krb5_context context, krb5_data *data)
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_data_free instead")
 {
     krb5_data_free(data);
 }
@@ -120,7 +120,7 @@ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
 krb5_keytype_to_string(krb5_context context,
                       krb5_keytype keytype,
                       char **string)
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_enctype_to_string instead")
 {
     const char *name = NULL;
     int i;
@@ -154,7 +154,7 @@ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
 krb5_string_to_keytype(krb5_context context,
                       const char *string,
                       krb5_keytype *keytype)
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_string_to_enctype instead")
 {
     char *end;
     int i;
@@ -386,7 +386,7 @@ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
 krb5_cc_gen_new(krb5_context context,
                const krb5_cc_ops *ops,
                krb5_ccache *id)
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_cc_new_unique instead")
 {
     return krb5_cc_new_unique(context, ops->prefix, NULL, id);
 }
@@ -400,7 +400,7 @@ krb5_cc_gen_new(krb5_context context,
 KRB5_LIB_FUNCTION krb5_realm * KRB5_LIB_CALL
 krb5_princ_realm(krb5_context context,
                 krb5_principal principal)
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_principal_get_realm instead")
 {
     return &principal->realm;
 }
@@ -416,7 +416,7 @@ KRB5_LIB_FUNCTION void KRB5_LIB_CALL
 krb5_princ_set_realm(krb5_context context,
                     krb5_principal principal,
                     krb5_realm *realm)
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_principal_set_realm instead")
 {
     principal->realm = *realm;
 }
@@ -430,7 +430,7 @@ krb5_princ_set_realm(krb5_context context,
 /* keep this for compatibility with older code */
 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
 krb5_free_creds_contents (krb5_context context, krb5_creds *c)
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_free_cred_contents instead")
 {
     return krb5_free_cred_contents (context, c);
 }
@@ -448,7 +448,7 @@ krb5_free_creds_contents (krb5_context context, krb5_creds *c)
 
 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
 krb5_free_error_string(krb5_context context, char *str)
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_free_error_message instead")
 {
     krb5_free_error_message(context, str);
 }
@@ -456,7 +456,7 @@ krb5_free_error_string(krb5_context context, char *str)
 /**
  * Set the error message returned by krb5_get_error_string().
  *
- * Deprecated: use krb5_get_error_message()
+ * Deprecated: use krb5_set_error_message()
  *
  * @param context Kerberos context
  * @param fmt error message to free
@@ -469,7 +469,7 @@ krb5_free_error_string(krb5_context context, char *str)
 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
 krb5_set_error_string(krb5_context context, const char *fmt, ...)
     __attribute__ ((__format__ (__printf__, 2, 3)))
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_set_error_message instead")
 {
     va_list ap;
 
@@ -480,8 +480,7 @@ krb5_set_error_string(krb5_context context, const char *fmt, ...)
 }
 
 /**
- * Set the error message returned by krb5_get_error_string(),
- * deprecated, use krb5_set_error_message().
+ * Set the error message returned by krb5_get_error_string().
  *
  * Deprecated: use krb5_vset_error_message()
  *
@@ -497,7 +496,7 @@ krb5_set_error_string(krb5_context context, const char *fmt, ...)
 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
 krb5_vset_error_string(krb5_context context, const char *fmt, va_list args)
     __attribute__ ((__format__ (__printf__, 2, 0)))
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_vset_error_message instead")
 {
     krb5_vset_error_message(context, 0, fmt, args);
     return 0;
@@ -515,7 +514,7 @@ krb5_vset_error_string(krb5_context context, const char *fmt, va_list args)
 
 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
 krb5_clear_error_string(krb5_context context)
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_clear_error_message instead")
 {
     krb5_clear_error_message(context);
 }
@@ -533,7 +532,7 @@ krb5_get_cred_from_kdc_opt(krb5_context context,
                           krb5_creds **out_creds,
                           krb5_creds ***ret_tgts,
                           krb5_flags flags)
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_get_credentials_with_flags instead")
 {
     krb5_kdc_flags f;
     f.i = flags;
@@ -554,7 +553,7 @@ krb5_get_cred_from_kdc(krb5_context context,
                       krb5_creds *in_creds,
                       krb5_creds **out_creds,
                       krb5_creds ***ret_tgts)
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_get_credentials_with_flags instead")
 {
     return krb5_get_cred_from_kdc_opt(context, ccache,
                                      in_creds, out_creds, ret_tgts, 0);
@@ -568,7 +567,7 @@ krb5_get_cred_from_kdc(krb5_context context,
 
 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
 krb5_free_unparsed_name(krb5_context context, char *str)
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_xfree instead")
 {
     krb5_xfree(str);
 }
@@ -583,7 +582,7 @@ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
 krb5_generate_subkey(krb5_context context,
                     const krb5_keyblock *key,
                     krb5_keyblock **subkey)
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_generate_subkey_extended instead")
 {
     return krb5_generate_subkey_extended(context, key, ETYPE_NULL, subkey);
 }
@@ -598,7 +597,7 @@ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
 krb5_auth_getremoteseqnumber(krb5_context context,
                             krb5_auth_context auth_context,
                             int32_t *seqnumber)
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_auth_con_getremoteseqnumber instead")
 {
   *seqnumber = auth_context->remote_seqnumber;
   return 0;
index b34e3eb325c81ed41d85ec7065431ab16f26c764..b2d0d39a3dc3f190ba853247f37c34aa52e4337f 100644 (file)
@@ -408,7 +408,7 @@ krb5_get_init_creds_opt_set_process_last_req(krb5_context context,
 
 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
 krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt)
-    KRB5_DEPRECATED_FUNCTION("Use X instead")
+    KRB5_DEPRECATED_FUNCTION("Use krb5_get_init_creds_opt_alloc instead")
 {
     memset (opt, 0, sizeof(*opt));
 }