]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s4:kdc: Check authentication policy server restrictions
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Fri, 16 Jun 2023 02:24:50 +0000 (14:24 +1200)
committerStefan Metzmacher <metze@samba.org>
Mon, 26 Jun 2023 11:10:31 +0000 (11:10 +0000)
For a constrained delegation request, we need to pass ‘delegated_proxy’
(and the delegated proxy PAC, if one was provided) into
samba_kdc_update_pac() so that we can verify that the delegating server
is allowed to authenticate to the target server.

The ‘const’ is entirely unnecessary in a function declaration, but we
add it just to be consistent.

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
selftest/knownfail_heimdal_kdc
source4/kdc/mit_samba.c
source4/kdc/pac-glue.c
source4/kdc/pac-glue.h
source4/kdc/wdc-samba4.c

index 9b4e9f7fb341c95d7e7967932322fc46432f8d67..48a274ab243102862f96a48fb11ff10032176634 100644 (file)
 # Authentication policy tests
 #
 ^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_from_empty.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_no_fast.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow_asserted_identity.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow_asserted_identity_from_rodc.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow_authenticated_users.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow_authenticated_users_from_rodc.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow_but_deny_mach.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow_claims_valid.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow_claims_valid_from_rodc.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow_compounded_auth.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow_compounded_authn_from_rodc.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow_from_rodc.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow_mach.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow_ntlm_authn.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow_ntlm_authn_from_rodc.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow_to_self.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow_to_self_with_self.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_allow_user2user.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_deny.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_deny_from_rodc.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_deny_to_self.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_deny_to_self_with_self.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_deny_user2user.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_computer_derived_class_allow.ad_dc
 ^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_empty.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_no_owner.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_no_owner_unenforced.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_owner_anon.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_owner_self.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_service_allow.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_service_allow_from_rodc.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_service_deny.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_service_deny_from_rodc.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_service_derived_class_allow.ad_dc
-^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_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
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_allow_group_member.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_allow_group_member_from_rodc.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_allow_group_not_a_member.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_allow_group_not_a_member_from_rodc.ad_dc
 ^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_allow_rbcd.ad_dc
 ^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_allow_rbcd_to_self.ad_dc
 ^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_allow_rbcd_wrong_sname.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_deny.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_deny_constrained_delegation.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_deny_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_deny_from_rodc.ad_dc
 ^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_deny_rbcd.ad_dc
 ^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_deny_rbcd_to_self.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_deny_s4u2self_constrained_delegation.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_derived_class_allow.ad_dc
 ^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_allowed_to_user_not_allowed_rbcd_to_self.ad_dc
-^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_denied_no_fast.ad_dc
 ^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_rbcd_not_allowed_from.ad_dc
index 56f4588b9ab36c4325896c5d6ad0fb486a6fc789..33ece51eab8335cc940d1a0fa0fa3d0238087502 100644 (file)
@@ -628,6 +628,7 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx,
        struct samba_kdc_entry *client_skdc_entry = NULL;
        struct samba_kdc_entry *krbtgt_skdc_entry = NULL;
        struct samba_kdc_entry *server_skdc_entry = NULL;
+       struct samba_kdc_entry *delegated_proxy_entry = NULL;
        krb5_principal delegated_proxy_principal = NULL;
        krb5_pac new_pac = NULL;
        bool is_in_db = false;
@@ -685,6 +686,7 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx,
 
        if (kdc_flags & KRB5_KDB_FLAG_CONSTRAINED_DELEGATION) {
                flags |= SAMBA_KDC_FLAG_CONSTRAINED_DELEGATION;
+               delegated_proxy_entry = client_skdc_entry;
                delegated_proxy_principal = discard_const(client_principal);
        }
 
@@ -709,11 +711,14 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx,
        code = samba_kdc_update_pac(tmp_ctx,
                                    context,
                                    krbtgt_skdc_entry->kdc_db_ctx->samdb,
+                                   krbtgt_skdc_entry->kdc_db_ctx->lp_ctx,
                                    flags,
                                    client_skdc_entry,
                                    server->princ,
                                    server_skdc_entry,
                                    delegated_proxy_principal,
+                                   delegated_proxy_entry,
+                                   NULL /* delegated_proxy_pac */,
                                    NULL /* device */,
                                    NULL /* device_pac */,
                                    *pac,
@@ -825,11 +830,14 @@ krb5_error_code mit_samba_update_pac(struct mit_samba_context *ctx,
        code = samba_kdc_update_pac(tmp_ctx,
                                    context,
                                    krbtgt_skdc_entry->kdc_db_ctx->samdb,
+                                   krbtgt_skdc_entry->kdc_db_ctx->lp_ctx,
                                    flags,
                                    client_skdc_entry,
                                    server->princ,
                                    server_skdc_entry,
                                    NULL /* delegated_proxy_principal */,
+                                   NULL /* delegated_proxy */,
+                                   NULL /* delegated_proxy_pac */,
                                    NULL /* device */,
                                    NULL /* device_pac */,
                                    old_pac,
index b128bca4578c8a682ab18c983c9255a411a78aee..f85051dd062d7de7cdefb3e14550414a6fdb64ba 100644 (file)
@@ -2298,6 +2298,8 @@ done:
  *
  * @param samdb     An open samdb connection.
  *
+ * @param lp_ctx    A loadparm context.
+ *
  * @param flags     Bitwise OR'ed flags
  *
  * @param device_pac_is_trusted Whether the device's PAC was issued by a trusted server,
@@ -2313,6 +2315,12 @@ done:
  *                                  updating the constrained delegation PAC
  *                                  buffer.
 
+ * @param delegated_proxy   The delegated proxy kdc entry.
+
+ * @param delegated_proxy_pac       The PAC from the primary TGT (i.e., that of
+ *                                  the delegating service) during a constrained
+ *                                  delegation request.
+
  * @param device    The computer's samba kdc entry; used for compound
  *                  authentication.
 
@@ -2329,11 +2337,14 @@ done:
 krb5_error_code samba_kdc_update_pac(TALLOC_CTX *mem_ctx,
                                     krb5_context context,
                                     struct ldb_context *samdb,
+                                    struct loadparm_context *lp_ctx,
                                     uint32_t flags,
                                     struct samba_kdc_entry *client,
                                     const krb5_const_principal server_principal,
                                     const struct samba_kdc_entry *server,
                                     const krb5_const_principal delegated_proxy_principal,
+                                    struct samba_kdc_entry *delegated_proxy,
+                                    const krb5_const_pac delegated_proxy_pac,
                                     struct samba_kdc_entry *device,
                                     const krb5_const_pac device_pac,
                                     const krb5_const_pac old_pac,
@@ -2350,6 +2361,7 @@ krb5_error_code samba_kdc_update_pac(TALLOC_CTX *mem_ctx,
        DATA_BLOB *client_claims_blob = NULL;
        bool client_pac_is_trusted = flags & SAMBA_KDC_FLAG_KRBTGT_IS_TRUSTED;
        bool device_pac_is_trusted = flags & SAMBA_KDC_FLAG_DEVICE_KRBTGT_IS_TRUSTED;
+       bool delegated_proxy_pac_is_trusted = flags & SAMBA_KDC_FLAG_DELEGATED_PROXY_IS_TRUSTED;
        DATA_BLOB *device_claims_blob = NULL;
        DATA_BLOB *device_info_blob = NULL;
        int is_tgs = false;
@@ -2493,6 +2505,50 @@ krb5_error_code samba_kdc_update_pac(TALLOC_CTX *mem_ctx,
                goto done;
        }
 
+       /*
+        * Enforce the AllowedToAuthenticateTo part of an authentication policy,
+        * if one is present.
+        */
+       if (authn_policy_restrictions_present(server->server_policy)) {
+               const struct samba_kdc_entry *auth_entry = NULL;
+               struct auth_user_info_dc *auth_user_info_dc = NULL;
+
+               if (delegated_proxy != NULL) {
+                       auth_entry = delegated_proxy;
+
+                       code = samba_kdc_obtain_user_info_dc(mem_ctx,
+                                                            context,
+                                                            samdb,
+                                                            AUTH_INCLUDE_RESOURCE_GROUPS,
+                                                            delegated_proxy,
+                                                            delegated_proxy_pac,
+                                                            delegated_proxy_pac_is_trusted,
+                                                            &auth_user_info_dc,
+                                                            NULL);
+                       if (code) {
+                               goto done;
+                       }
+               } else {
+                       auth_entry = client;
+                       auth_user_info_dc = user_info_dc;
+               }
+
+               code = samba_kdc_allowed_to_authenticate_to(mem_ctx,
+                                                           samdb,
+                                                           lp_ctx,
+                                                           auth_entry,
+                                                           auth_user_info_dc,
+                                                           server,
+                                                           server_audit_info_out,
+                                                           status_out);
+               if (auth_user_info_dc != user_info_dc) {
+                       talloc_unlink(mem_ctx, auth_user_info_dc);
+               }
+               if (code) {
+                       goto done;
+               }
+       }
+
        nt_status = samba_add_compounded_auth(compounded_auth,
                                              user_info_dc);
        if (!NT_STATUS_IS_OK(nt_status)) {
@@ -2770,7 +2826,10 @@ done:
        TALLOC_FREE(pac_blob);
        TALLOC_FREE(upn_blob);
        TALLOC_FREE(deleg_blob);
-       /* Release our handle to user_info_dc. */
+       /*
+        * Release our handle to user_info_dc. ‘server_audit_info_out’, if
+        * non-NULL, becomes the new parent.
+        */
        talloc_unlink(mem_ctx, user_info_dc);
        return code;
 }
index bb343233ae1cc08a08ee23ad13a5ab94fad58cdf..d966eb256b21d60b74002f0a55ff84d5ad8dccef 100644 (file)
@@ -55,6 +55,7 @@ enum {
        SAMBA_KDC_FLAG_KRBTGT_IS_TRUSTED      = 0x00000008,
        SAMBA_KDC_FLAG_SKIP_PAC_BUFFER        = 0x00000010,
        SAMBA_KDC_FLAG_DEVICE_KRBTGT_IS_TRUSTED = 0x00000020,
+       SAMBA_KDC_FLAG_DELEGATED_PROXY_IS_TRUSTED = 0x00000040,
 };
 
 krb5_error_code samba_kdc_encrypt_pac_credentials(krb5_context context,
@@ -132,11 +133,14 @@ struct authn_audit_info;
 krb5_error_code samba_kdc_update_pac(TALLOC_CTX *mem_ctx,
                                     krb5_context context,
                                     struct ldb_context *samdb,
+                                    struct loadparm_context *lp_ctx,
                                     uint32_t flags,
                                     struct samba_kdc_entry *client,
                                     const krb5_const_principal server_principal,
                                     const struct samba_kdc_entry *server,
                                     const krb5_const_principal delegated_proxy_principal,
+                                    struct samba_kdc_entry *delegated_proxy,
+                                    const krb5_const_pac delegated_proxy_pac,
                                     struct samba_kdc_entry *device,
                                     const krb5_const_pac device_pac,
                                     const krb5_const_pac old_pac,
index 9e72337e9eedb686935b5ffc22c8cd6503872f86..5ae2bd1e1a99f0138386c37ef0645c2ec0d44900 100644 (file)
@@ -384,6 +384,7 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, astgs_request_t r,
        krb5_context context = kdc_request_get_context((kdc_request_t)r);
        const hdb_entry *device = kdc_request_get_explicit_armor_client(r);
        const krb5_const_pac device_pac = kdc_request_get_explicit_armor_pac(r);
+       struct samba_kdc_entry *delegated_proxy_skdc_entry = NULL;
        krb5_const_principal delegated_proxy_principal = NULL;
        struct samba_kdc_entry *client_skdc_entry = NULL;
        struct samba_kdc_entry *device_skdc_entry = NULL;
@@ -404,6 +405,8 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, astgs_request_t r,
        }
 
        if (delegated_proxy != NULL) {
+               delegated_proxy_skdc_entry = talloc_get_type_abort(delegated_proxy->context,
+                                                                  struct samba_kdc_entry);
                delegated_proxy_principal = delegated_proxy->principal;
        }
 
@@ -429,15 +432,21 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, astgs_request_t r,
        if (device_pac != NULL && krb5_pac_is_trusted(device_pac)) {
                flags |= SAMBA_KDC_FLAG_DEVICE_KRBTGT_IS_TRUSTED;
        }
+       if (delegated_proxy_pac != NULL && krb5_pac_is_trusted(delegated_proxy_pac)) {
+               flags |= SAMBA_KDC_FLAG_DELEGATED_PROXY_IS_TRUSTED;
+       }
 
        ret = samba_kdc_update_pac(mem_ctx,
                                   context,
                                   krbtgt_skdc_entry->kdc_db_ctx->samdb,
+                                  krbtgt_skdc_entry->kdc_db_ctx->lp_ctx,
                                   flags,
                                   client_skdc_entry,
                                   server->principal,
                                   server_skdc_entry,
                                   delegated_proxy_principal,
+                                  delegated_proxy_skdc_entry,
+                                  delegated_proxy_pac,
                                   device_skdc_entry,
                                   device_pac,
                                   *pac,