From 3ce6d0fd582846d22e27c2ed4ad3bf1fd0acc81f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Feb 2022 17:17:02 +0100 Subject: [PATCH 1/2] HEIMDAL: allow HDB_AUTH_WRONG_PASSWORD to result in HDB_ERR_NOT_FOUND_HERE On an RODC we need to redirect failing preauthentication to an RWDC. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14865 Signed-off-by: Stefan Metzmacher (similar to commit heimdal commit df655cecd12712e7f7df5128b123eee0066a8216) --- source4/heimdal/kdc/kerberos5.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c index b8fec62333db..9fec8bfd9d8a 100644 --- a/source4/heimdal/kdc/kerberos5.c +++ b/source4/heimdal/kdc/kerberos5.c @@ -1358,13 +1358,18 @@ _kdc_as_rep(krb5_context context, free_EncryptedData(&enc_data); - if (clientdb->hdb_auth_status) - (clientdb->hdb_auth_status)(context, clientdb, client, + if (clientdb->hdb_auth_status) { + ret = (clientdb->hdb_auth_status)(context, clientdb, client, from_addr, &_kdc_now, client_name, str ? str : "unknown enctype", HDB_AUTH_WRONG_PASSWORD); + if (ret == HDB_ERR_NOT_FOUND_HERE) { + kdc_log(context, config, 5, "client %s HDB_AUTH_WRONG_PASSWORD at this KDC, forward to proxy", client_name); + goto out; + } + } free(str); -- 2.25.1 From 963a359ea9caa3786d751e71cadfc422d1bd29e8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Feb 2022 17:17:02 +0100 Subject: [PATCH 2/2] s4:kdc: redirect pre-authentication failured to an RWDC BUG: https://bugzilla.samba.org/show_bug.cgi?id=14865 Signed-off-by: Stefan Metzmacher (similar to commit 0f5d7ff1a9fd14fd412b09883d413d1d660fa7be) --- selftest/knownfail | 1 - source4/dsdb/tests/python/rodc_rwdc.py | 3 +- source4/kdc/hdb-samba4.c | 79 +++++--------------------- 3 files changed, 16 insertions(+), 67 deletions(-) diff --git a/selftest/knownfail b/selftest/knownfail index 9f362c02b470..b5e52753968f 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -365,7 +365,6 @@ ^samba.tests.auth_log_pass_change.samba.tests.auth_log_pass_change.AuthLogPassChangeTests.test_rap_change_password\(ad_dc_ntvfs\) # We currently don't send referrals for LDAP modify of non-replicated attrs ^samba4.ldap.rodc.python\(rodc\).__main__.RodcTests.test_modify_nonreplicated.* -^samba4.ldap.rodc_rwdc.python.*.__main__.RodcRwdcTests.test_change_password_reveal_on_demand_kerberos # NETLOGON is disabled in any non-DC environments ^samba.tests.netlogonsvc.python\(ad_member\) ^samba.tests.netlogonsvc.python\(simpleserver\) diff --git a/source4/dsdb/tests/python/rodc_rwdc.py b/source4/dsdb/tests/python/rodc_rwdc.py index 74e0773abc37..beea26e8e1ae 100644 --- a/source4/dsdb/tests/python/rodc_rwdc.py +++ b/source4/dsdb/tests/python/rodc_rwdc.py @@ -1146,8 +1146,7 @@ class RodcRwdcTests(password_lockout_base.BasePasswordTestCase): creds2 = make_creds(username, password) self.try_ldap_logon(RWDC, creds2) - # We can forward WRONG_PASSWORD over NTLM. - # This SHOULD succeed. + # The RODC forward WRONG_PASSWORD to the RWDC self.try_ldap_logon(RODC, creds2) def test_change_password_reveal_on_demand_ntlm(self): diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c index f0939193ad78..0bd31ea19a63 100644 --- a/source4/kdc/hdb-samba4.c +++ b/source4/kdc/hdb-samba4.c @@ -311,60 +311,6 @@ static void reset_bad_password_netlogon(TALLOC_CTX *mem_ctx, irpc_handle, &req); } -static void send_bad_password_netlogon(TALLOC_CTX *mem_ctx, - struct samba_kdc_db_context *kdc_db_ctx, - struct auth_usersupplied_info *user_info) -{ - struct dcerpc_binding_handle *irpc_handle; - struct winbind_SamLogon req; - struct netr_IdentityInfo *identity_info; - struct netr_NetworkInfo *network_info; - - irpc_handle = irpc_binding_handle_by_name(mem_ctx, kdc_db_ctx->msg_ctx, - "winbind_server", - &ndr_table_winbind); - if (irpc_handle == NULL) { - DEBUG(0, ("Winbind forwarding for [%s]\\[%s] failed, " - "no winbind_server running!\n", - user_info->mapped.domain_name, user_info->mapped.account_name)); - return; - } - - network_info = talloc_zero(mem_ctx, struct netr_NetworkInfo); - if (network_info == NULL) { - DEBUG(0, ("Winbind forwarding failed: No memory\n")); - return; - } - - identity_info = &network_info->identity_info; - req.in.logon_level = 2; - req.in.logon.network = network_info; - - identity_info->domain_name.string = user_info->mapped.domain_name; - identity_info->parameter_control = user_info->logon_parameters; /* TODO */ - identity_info->logon_id = user_info->logon_id; - identity_info->account_name.string = user_info->mapped.account_name; - identity_info->workstation.string - = talloc_asprintf(identity_info, "krb5-bad-pw on RODC from %s", - tsocket_address_string(user_info->remote_host, - identity_info)); - if (identity_info->workstation.string == NULL) { - DEBUG(0, ("Winbind forwarding failed: No memory allocating workstation string\n")); - return; - } - - req.in.validation_level = 3; - - /* - * The memory in identity_info and user_info only needs to be - * valid until the end of this function call, as it will be - * pushed to NDR during this call - */ - - dcerpc_winbind_SamLogon_r_send(mem_ctx, kdc_db_ctx->ev_ctx, - irpc_handle, &req); -} - static krb5_error_code hdb_samba4_auth_status(krb5_context context, HDB *db, hdb_entry_ex *entry, struct sockaddr *from_addr, @@ -396,8 +342,8 @@ static krb5_error_code hdb_samba4_auth_status(krb5_context context, HDB *db, .password_type = auth_type, .logon_id = logon_id }; - size_t sa_socklen = 0; + int final_ret = 0; switch (from_addr->sa_family) { case AF_INET: @@ -447,6 +393,7 @@ static krb5_error_code hdb_samba4_auth_status(krb5_context context, HDB *db, struct tsocket_address *remote_host; NTSTATUS status; int ret; + bool rwdc_fallback = false; ret = tsocket_address_bsd_from_sockaddr(frame, from_addr, sa_socklen, @@ -463,18 +410,20 @@ static krb5_error_code hdb_samba4_auth_status(krb5_context context, HDB *db, if (hdb_auth_status == HDB_AUTH_WRONG_PASSWORD) { authsam_update_bad_pwd_count(kdc_db_ctx->samdb, p->msg, domain_dn); status = NT_STATUS_WRONG_PASSWORD; - /* - * TODO We currently send a bad password via NETLOGON, - * however, it should probably forward the ticket to - * another KDC to allow login after password changes. - */ - if (kdc_db_ctx->rodc) { - send_bad_password_netlogon(frame, kdc_db_ctx, &ui); - } + rwdc_fallback = kdc_db_ctx->rodc; } else { status = NT_STATUS_OK; } + if (rwdc_fallback) { + /* + * Forward the request to an RWDC in order + * to give an authoritative answer to the client. + */ + ui.password_type = "Forwarding to RWDC"; + final_ret = HDB_ERR_NOT_FOUND_HERE; + } + log_authentication_event(kdc_db_ctx->msg_ctx, kdc_db_ctx->lp_ctx, start_time, @@ -500,6 +449,8 @@ static krb5_error_code hdb_samba4_auth_status(krb5_context context, HDB *db, ui.remote_host = remote_host; } + /* Note this is not forwarded to an RWDC */ + log_authentication_event(kdc_db_ctx->msg_ctx, kdc_db_ctx->lp_ctx, start_time, @@ -511,7 +462,7 @@ static krb5_error_code hdb_samba4_auth_status(krb5_context context, HDB *db, break; } } - return 0; + return final_ret; } /* This interface is to be called by the KDC and libnet_keytab_dump, -- 2.25.1