]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:winbindd: avoid using any netlogon call to get a dc name
authorStefan Metzmacher <metze@samba.org>
Fri, 9 May 2025 07:38:41 +0000 (09:38 +0200)
committerRalph Boehme <slow@samba.org>
Mon, 7 Jul 2025 09:40:30 +0000 (09:40 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15876

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/winbindd/winbindd_cm.c
source3/winbindd/winbindd_dual_srv.c

index cc0b47b0600c4e3835773394aa66970f99caa383..15a2f60c532191eabaac1b200c02a5a1b80bb9aa 100644 (file)
@@ -477,140 +477,6 @@ static bool cm_is_ipc_credentials(struct cli_credentials *creds)
        return ret;
 }
 
-static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
-                                    fstring dcname,
-                                    struct sockaddr_storage *dc_ss,
-                                    uint32_t request_flags)
-{
-       struct winbindd_domain *our_domain = NULL;
-       struct rpc_pipe_client *netlogon_pipe = NULL;
-       NTSTATUS result;
-       WERROR werr;
-       TALLOC_CTX *mem_ctx;
-       unsigned int orig_timeout;
-       const char *tmp = NULL;
-       const char *p;
-       struct dcerpc_binding_handle *b;
-
-       /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
-        * moment.... */
-
-       if (IS_DC) {
-               return False;
-       }
-
-       if (domain->primary) {
-               return False;
-       }
-
-       our_domain = find_our_domain();
-
-       if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
-               return False;
-       }
-
-       result = cm_connect_netlogon(our_domain, &netlogon_pipe);
-       if (!NT_STATUS_IS_OK(result)) {
-               talloc_destroy(mem_ctx);
-               return False;
-       }
-
-       b = netlogon_pipe->binding_handle;
-
-       /* This call can take a long time - allow the server to time out.
-          35 seconds should do it. */
-
-       orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
-
-       if (our_domain->active_directory) {
-               struct netr_DsRGetDCNameInfo *domain_info = NULL;
-
-               /*
-                * TODO request flags are not respected in the server
-                * (and in some cases, like REQUIRE_PDC, causes an error)
-                */
-               result = dcerpc_netr_DsRGetDCName(b,
-                                                 mem_ctx,
-                                                 our_domain->dcname,
-                                                 domain->name,
-                                                 NULL,
-                                                 NULL,
-                                                 request_flags|DS_RETURN_DNS_NAME,
-                                                 &domain_info,
-                                                 &werr);
-               if (NT_STATUS_IS_OK(result) && W_ERROR_IS_OK(werr)) {
-                       tmp = talloc_strdup(
-                               mem_ctx, domain_info->dc_unc);
-                       if (tmp == NULL) {
-                               DBG_ERR("talloc_strdup failed for dc_unc[%s]\n",
-                                       domain_info->dc_unc);
-                               talloc_destroy(mem_ctx);
-                               return false;
-                       }
-                       if (domain->alt_name == NULL) {
-                               domain->alt_name = talloc_strdup(domain,
-                                                                domain_info->domain_name);
-                               if (domain->alt_name == NULL) {
-                                       DBG_ERR("talloc_strdup failed for "
-                                               "domain_info->domain_name[%s]\n",
-                                               domain_info->domain_name);
-                                       talloc_destroy(mem_ctx);
-                                       return false;
-                               }
-                       }
-                       if (domain->forest_name == NULL) {
-                               domain->forest_name = talloc_strdup(domain,
-                                                                   domain_info->forest_name);
-                               if (domain->forest_name == NULL) {
-                                       DBG_ERR("talloc_strdup failed for "
-                                               "domain_info->forest_name[%s]\n",
-                                               domain_info->forest_name);
-                                       talloc_destroy(mem_ctx);
-                                       return false;
-                               }
-                       }
-               }
-       } else {
-               result = dcerpc_netr_GetAnyDCName(b, mem_ctx,
-                                                 our_domain->dcname,
-                                                 domain->name,
-                                                 &tmp,
-                                                 &werr);
-       }
-
-       /* And restore our original timeout. */
-       rpccli_set_timeout(netlogon_pipe, orig_timeout);
-
-       if (!NT_STATUS_IS_OK(result)) {
-               DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
-                       nt_errstr(result)));
-               talloc_destroy(mem_ctx);
-               return false;
-       }
-
-       if (!W_ERROR_IS_OK(werr)) {
-               DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
-                          win_errstr(werr)));
-               talloc_destroy(mem_ctx);
-               return false;
-       }
-
-       /* dcerpc_netr_GetAnyDCName gives us a name with \\ */
-       p = strip_hostname(tmp);
-
-       fstrcpy(dcname, p);
-
-       talloc_destroy(mem_ctx);
-
-       DEBUG(10,("dcerpc_netr_GetAnyDCName returned %s\n", dcname));
-
-       if (!resolve_name(dcname, dc_ss, 0x20, true)) {
-               return False;
-       }
-
-       return True;
-}
-
 /**
  * Helper function to assemble trust password and account name
  */
@@ -1297,24 +1163,8 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
        struct  samba_sockaddr *sa_list = NULL;
        size_t     salist_size = 0;
        size_t     i;
-       bool    is_our_domain;
        enum security_types sec = (enum security_types)lp_security();
 
-       is_our_domain = strequal(domain->name, lp_workgroup());
-
-       /* If not our domain, get the preferred DC, by asking our primary DC */
-       if ( !is_our_domain
-               && get_dc_name_via_netlogon(domain, dcname, &ss, request_flags)
-               && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs,
-                      num_dcs) )
-       {
-               char addr[INET6_ADDRSTRLEN];
-               print_sockaddr(addr, sizeof(addr), &ss);
-               DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
-                          dcname, addr));
-               return True;
-       }
-
        if ((sec == SEC_ADS) && (domain->alt_name != NULL)) {
                char *sitename = NULL;
 
index b1809809b13eaa046d7b109f06167b5d18b919e2..c48ca15dd2b25c8461e07a2545b55e0862cb73f6 100644 (file)
@@ -661,106 +661,11 @@ NTSTATUS _wbint_QueryUserRidList(struct pipes_struct *p,
 
 NTSTATUS _wbint_DsGetDcName(struct pipes_struct *p, struct wbint_DsGetDcName *r)
 {
-       struct winbindd_domain *domain = wb_child_domain();
-       struct rpc_pipe_client *netlogon_pipe;
-       struct netr_DsRGetDCNameInfo *dc_info;
-       NTSTATUS status;
-       WERROR werr;
-       unsigned int orig_timeout;
-       struct dcerpc_binding_handle *b;
-       bool retry = false;
-       bool try_dsrgetdcname = false;
-
-       if (domain == NULL) {
-               return dsgetdcname(p->mem_ctx, global_messaging_context(),
-                                  r->in.domain_name, r->in.domain_guid,
-                                  r->in.site_name ? r->in.site_name : "",
-                                  r->in.flags,
-                                  r->out.dc_info);
-       }
-
-       if (domain->active_directory) {
-               try_dsrgetdcname = true;
-       }
-
-reconnect:
-       status = cm_connect_netlogon(domain, &netlogon_pipe);
-
-       reset_cm_connection_on_error(domain, NULL, status);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(10, ("Can't contact the NETLOGON pipe\n"));
-               return status;
-       }
-
-       b = netlogon_pipe->binding_handle;
-
-       /* This call can take a long time - allow the server to time out.
-          35 seconds should do it. */
-
-       orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
-
-       if (try_dsrgetdcname) {
-               status = dcerpc_netr_DsRGetDCName(b,
-                       p->mem_ctx, domain->dcname,
-                       r->in.domain_name, NULL, r->in.domain_guid,
-                       r->in.flags, r->out.dc_info, &werr);
-               if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(werr)) {
-                       goto done;
-               }
-               if (!retry &&
-                   reset_cm_connection_on_error(domain, NULL, status))
-               {
-                       retry = true;
-                       goto reconnect;
-               }
-               try_dsrgetdcname = false;
-               retry = false;
-       }
-
-       /*
-        * Fallback to less capable methods
-        */
-
-       dc_info = talloc_zero(r->out.dc_info, struct netr_DsRGetDCNameInfo);
-       if (dc_info == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto done;
-       }
-
-       if (r->in.flags & DS_PDC_REQUIRED) {
-               status = dcerpc_netr_GetDcName(b,
-                       p->mem_ctx, domain->dcname,
-                       r->in.domain_name, &dc_info->dc_unc, &werr);
-       } else {
-               status = dcerpc_netr_GetAnyDCName(b,
-                       p->mem_ctx, domain->dcname,
-                       r->in.domain_name, &dc_info->dc_unc, &werr);
-       }
-
-       if (!retry && reset_cm_connection_on_error(domain, b, status)) {
-               retry = true;
-               goto reconnect;
-       }
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(10, ("dcerpc_netr_Get[Any]DCName failed: %s\n",
-                          nt_errstr(status)));
-               goto done;
-       }
-       if (!W_ERROR_IS_OK(werr)) {
-               DEBUG(10, ("dcerpc_netr_Get[Any]DCName failed: %s\n",
-                          win_errstr(werr)));
-               status = werror_to_ntstatus(werr);
-               goto done;
-       }
-
-       *r->out.dc_info = dc_info;
-       status = NT_STATUS_OK;
-
-done:
-       /* And restore our original timeout. */
-       rpccli_set_timeout(netlogon_pipe, orig_timeout);
-
-       return status;
+       return dsgetdcname(p->mem_ctx, global_messaging_context(),
+                          r->in.domain_name, r->in.domain_guid,
+                          r->in.site_name ? r->in.site_name : "",
+                          r->in.flags,
+                          r->out.dc_info);
 }
 
 NTSTATUS _wbint_LookupRids(struct pipes_struct *p, struct wbint_LookupRids *r)