s4:kdc: redirect pre-authentication failured to an RWDC
authorStefan Metzmacher <metze@samba.org>
Fri, 18 Feb 2022 16:17:02 +0000 (17:17 +0100)
committerStefan Metzmacher <metze@samba.org>
Fri, 18 Mar 2022 11:55:11 +0000 (11:55 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14865

Signed-off-by: Stefan Metzmacher <metze@samba.org>
(similar to commit 0f5d7ff1a9fd14fd412b09883d413d1d660fa7be)

Autobuild-User(v4-14-test): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(v4-14-test): Fri Mar 18 11:55:11 UTC 2022 on sn-devel-184

selftest/knownfail
source4/dsdb/tests/python/rodc_rwdc.py
source4/kdc/hdb-samba4.c

index 2701fe4c5b326d517e6e5a3745a44225d43b6e91..c4c050403d0da3fb505083f3fce7e712bf3a8064 100644 (file)
 ^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\)
index 21b7c05fcbeae10254de3089460090344e8279d2..6cd0e50e47b60d436855e344a177c32c26e0e305 100644 (file)
@@ -1166,8 +1166,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):
index 2ed7a5e0623d06b44f9d31102997d8079a61e5b1..43e836f8360d2e68e1eb1ebdc0a6b82e64b24fb2 100644 (file)
@@ -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,
@@ -395,8 +341,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:
@@ -446,6 +392,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,
@@ -462,18 +409,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,
@@ -499,6 +448,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,
@@ -510,7 +461,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,