]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
libsmb: Use netlogon_pings() in dsgetdcname
authorVolker Lendecke <vl@samba.org>
Mon, 28 Oct 2024 11:06:05 +0000 (12:06 +0100)
committerVolker Lendecke <vl@samba.org>
Mon, 11 Nov 2024 14:03:04 +0000 (14:03 +0000)
Use parallel requests and req_flags filtering provided by
netlogon_pings()

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
source3/libsmb/dsgetdcname.c

index 654893c172c63de647e5eaf18cb328ac6ebde6a1..9053ee5c8b05f3fcf7ca1d65f22f208dc8027b17 100644 (file)
 #include "libads/sitename_cache.h"
 #include "../librpc/gen_ndr/ndr_netlogon.h"
 #include "libads/cldap.h"
+#include "libads/netlogon_ping.h"
 #include "lib/addns/dnsquery_srv.h"
 #include "libsmb/clidgram.h"
 #include "lib/gencache.h"
 #include "lib/util/util_net.h"
+#include "lib/tsocket/tsocket.h"
 
 /* 15 minutes */
 #define DSGETDCNAME_CACHE_TTL  60*15
@@ -257,56 +259,6 @@ static NTSTATUS store_cldap_reply(TALLOC_CTX *mem_ctx,
 /****************************************************************
 ****************************************************************/
 
-static uint32_t get_cldap_reply_server_flags(struct netlogon_samlogon_response *r,
-                                            uint32_t nt_version)
-{
-       switch (nt_version & 0x0000001f) {
-               case 0:
-               case 1:
-               case 16:
-               case 17:
-                       return 0;
-               case 2:
-               case 3:
-               case 18:
-               case 19:
-                       return r->data.nt5.server_type;
-               case 4:
-               case 5:
-               case 6:
-               case 7:
-                       return r->data.nt5_ex.server_type;
-               case 8:
-               case 9:
-               case 10:
-               case 11:
-               case 12:
-               case 13:
-               case 14:
-               case 15:
-                       return r->data.nt5_ex.server_type;
-               case 20:
-               case 21:
-               case 22:
-               case 23:
-               case 24:
-               case 25:
-               case 26:
-               case 27:
-               case 28:
-                       return r->data.nt5_ex.server_type;
-               case 29:
-               case 30:
-               case 31:
-                       return r->data.nt5_ex.server_type;
-               default:
-                       return 0;
-       }
-}
-
-/****************************************************************
-****************************************************************/
-
 static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx,
                                        const char *domain_name,
                                        const struct GUID *domain_guid,
@@ -870,50 +822,74 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx,
                               struct netr_DsRGetDCNameInfo **info)
 {
        size_t i = 0;
-       bool valid_dc = false;
-       struct netlogon_samlogon_response *r = NULL;
-       uint32_t nt_version = NETLOGON_NT_VERSION_5 |
-                             NETLOGON_NT_VERSION_5EX;
-       uint32_t ret_flags = 0;
+       struct tsocket_address **addrs = NULL;
+       struct netlogon_samlogon_response **responses = NULL;
+       const uint32_t nt_version = NETLOGON_NT_VERSION_5 |
+                                   NETLOGON_NT_VERSION_5EX;
        NTSTATUS status;
 
-       nt_version |= map_ds_flags_to_nt_version(flags);
+       addrs = talloc_array(mem_ctx, struct tsocket_address *, num_dcs);
+       if (addrs == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
        for (i=0; i<num_dcs; i++) {
-               char addr[INET6_ADDRSTRLEN];
-
-               print_sockaddr(addr, sizeof(addr), &dclist[i].sa.u.ss);
-
-               DEBUG(10,("LDAP ping to %s (%s)\n", dclist[i].hostname, addr));
-
-               if (ads_cldap_netlogon(mem_ctx, &dclist[i].sa.u.ss,
-                                       domain_name,
-                                       nt_version,
-                                       &r))
-               {
-                       nt_version = r->ntver;
-                       ret_flags = get_cldap_reply_server_flags(r, nt_version);
-
-                       if (check_cldap_reply_required_flags(ret_flags, flags)) {
-                               valid_dc = true;
-                               break;
-                       }
+               int ret = tsocket_address_bsd_from_samba_sockaddr(
+                       addrs, &dclist[i].sa, &addrs[i]);
+               if (ret != 0) {
+                       status = map_nt_error_from_unix(errno);
+                       goto done;
                }
-
-               continue;
        }
 
-       if (!valid_dc) {
-               return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
+       status = netlogon_pings(
+               addrs,                              /* mem_ctx */
+               lp_client_netlogon_ping_protocol(), /* proto */
+               addrs,                              /* servers */
+               num_dcs,                            /* num_servers */
+               (struct netlogon_ping_filter){
+                       .ntversion = nt_version,
+                       .acct_ctrl = -1,
+                       .domain = domain_name,
+                       .required_flags = flags,
+               },
+               1, /* min_servers */
+               timeval_current_ofs(MAX(3, lp_ldap_timeout() / 2), 0),
+               &responses);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
+               goto done;
        }
 
-       status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].sa,
-                                              &r->data.nt5_ex, info);
-       if (NT_STATUS_IS_OK(status)) {
-               return store_cldap_reply(mem_ctx, flags, &dclist[i].sa,
-                                        nt_version, &r->data.nt5_ex);
+       for (i = 0; i < num_dcs; i++) {
+               struct netlogon_samlogon_response *r = responses[i];
+
+               if (r == NULL) {
+                       continue;
+               }
+               if (r->ntver != NETLOGON_NT_VERSION_5EX) {
+                       continue;
+               }
+               status = make_dc_info_from_cldap_reply(
+                       mem_ctx, flags, &dclist[i].sa, &r->data.nt5_ex, info);
+               if (!NT_STATUS_IS_OK(status)) {
+                       continue;
+               }
+               status = store_cldap_reply(mem_ctx,
+                                          flags,
+                                          &dclist[i].sa,
+                                          nt_version,
+                                          &r->data.nt5_ex);
+               if (!NT_STATUS_IS_OK(status)) {
+                       continue;
+               }
+               goto done;
        }
 
+       status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
+done:
+       TALLOC_FREE(addrs);
        return status;
 }