From: Joseph Sutton Date: Fri, 16 Jun 2023 02:24:50 +0000 (+1200) Subject: s4:kdc: Check authentication policy server restrictions X-Git-Tag: talloc-2.4.1~182 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3240ac4ebef75c3e955259ad32054380996ae7cf;p=thirdparty%2Fsamba.git s4:kdc: Check authentication policy server restrictions 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 Reviewed-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher --- diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc index 9b4e9f7fb34..48a274ab243 100644 --- a/selftest/knownfail_heimdal_kdc +++ b/selftest/knownfail_heimdal_kdc @@ -78,61 +78,11 @@ # 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 diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c index 56f4588b9ab..33ece51eab8 100644 --- a/source4/kdc/mit_samba.c +++ b/source4/kdc/mit_samba.c @@ -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, diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c index b128bca4578..f85051dd062 100644 --- a/source4/kdc/pac-glue.c +++ b/source4/kdc/pac-glue.c @@ -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; } diff --git a/source4/kdc/pac-glue.h b/source4/kdc/pac-glue.h index bb343233ae1..d966eb256b2 100644 --- a/source4/kdc/pac-glue.h +++ b/source4/kdc/pac-glue.h @@ -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, diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c index 9e72337e9ee..5ae2bd1e1a9 100644 --- a/source4/kdc/wdc-samba4.c +++ b/source4/kdc/wdc-samba4.c @@ -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,