The branch, v4-21-test has been updated
       via  1967ce81998 s3-winbindd: Fix internal winbind dsgetdcname calls 
w.r.t. domain name
       via  fc13e0918fd s3:winbindd: avoid using any netlogon call to get a dc 
name
      from  3490e76342a lib:util: Disable logging to syslog for startup messages

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-21-test


- Log -----------------------------------------------------------------
commit 1967ce819985be2e223c258284d5153713549108
Author: Günther Deschner <g...@samba.org>
Date:   Wed Jul 2 21:59:48 2025 +0200

    s3-winbindd: Fix internal winbind dsgetdcname calls w.r.t. domain name
    
    when winbind calls to dsgetdcname internally, make sure to
    prefer the DNS domain name if we have it. Makes DNS lookups much more
    likely to succeed.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15876
    
    Guenther
    
    Signed-off-by: Guenther Deschner <g...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>
    
    Autobuild-User(master): Ralph Böhme <s...@samba.org>
    Autobuild-Date(master): Mon Jul  7 10:44:37 UTC 2025 on atb-devel-224
    
    (cherry picked from commit 2560c9b3224816ffd371a62103f65b3aca301ad5)
    
    Autobuild-User(v4-21-test): Jule Anger <jan...@samba.org>
    Autobuild-Date(v4-21-test): Mon Jul  7 15:42:19 UTC 2025 on atb-devel-224

commit fc13e0918fddac18800790926a71a9e60f8b95df
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri May 9 09:38:41 2025 +0200

    s3:winbindd: avoid using any netlogon call to get a dc name
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15876
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Guenther Deschner <g...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>
    (cherry picked from commit f86a4bf6848ade2db7229d182576db3320c3ece7)

-----------------------------------------------------------------------

Summary of changes:
 source3/winbindd/wb_queryuser.c      |  17 +++-
 source3/winbindd/wb_sids2xids.c      |  17 +++-
 source3/winbindd/wb_xids2sids.c      |  12 ++-
 source3/winbindd/winbindd_cm.c       | 150 -----------------------------------
 source3/winbindd/winbindd_dual.c     |   6 +-
 source3/winbindd/winbindd_dual_srv.c | 105 ++----------------------
 source3/winbindd/winbindd_proto.h    |   1 +
 source3/winbindd/winbindd_util.c     |  19 +++++
 8 files changed, 65 insertions(+), 262 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/winbindd/wb_queryuser.c b/source3/winbindd/wb_queryuser.c
index c2758f1b76a..db8e946ba71 100644
--- a/source3/winbindd/wb_queryuser.c
+++ b/source3/winbindd/wb_queryuser.c
@@ -289,10 +289,19 @@ static void wb_queryuser_done(struct tevent_req *subreq)
 
        if (NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) &&
            !state->tried_dclookup) {
-               D_DEBUG("GetNssInfo got DOMAIN_CONTROLLER_NOT_FOUND, calling 
wb_dsgetdcname_send()\n");
-               subreq = wb_dsgetdcname_send(
-                       state, state->ev, state->info->domain_name, NULL, NULL,
-                       DS_RETURN_DNS_NAME);
+               const char *domain_name = find_dns_domain_name(
+                       state->info->domain_name);
+
+               D_DEBUG("GetNssInfo got DOMAIN_CONTROLLER_NOT_FOUND, calling "
+                       "wb_dsgetdcname_send(%s)\n",
+                       domain_name);
+
+               subreq = wb_dsgetdcname_send(state,
+                                            state->ev,
+                                            domain_name,
+                                            NULL,
+                                            NULL,
+                                            DS_RETURN_DNS_NAME);
                if (tevent_req_nomem(subreq, req)) {
                        return;
                }
diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c
index f0f6c23fc20..03e5e7e0258 100644
--- a/source3/winbindd/wb_sids2xids.c
+++ b/source3/winbindd/wb_sids2xids.c
@@ -612,13 +612,22 @@ static void wb_sids2xids_done(struct tevent_req *subreq)
            !state->tried_dclookup) {
 
                struct lsa_DomainInfo *d;
+               const char *domain_name = NULL;
 
-               D_DEBUG("Domain controller not found. Calling 
wb_dsgetdcname_send() to get it.\n");
                d = &state->idmap_doms.domains[state->dom_index];
 
-               subreq = wb_dsgetdcname_send(
-                       state, state->ev, d->name.string, NULL, NULL,
-                       DS_RETURN_DNS_NAME);
+               domain_name = find_dns_domain_name(d->name.string);
+
+               D_DEBUG("Domain controller not found. Calling "
+                       "wb_dsgetdcname_send(%s) to get it.\n",
+                       domain_name);
+
+               subreq = wb_dsgetdcname_send(state,
+                                            state->ev,
+                                            domain_name,
+                                            NULL,
+                                            NULL,
+                                            DS_RETURN_DNS_NAME);
                if (tevent_req_nomem(subreq, req)) {
                        return;
                }
diff --git a/source3/winbindd/wb_xids2sids.c b/source3/winbindd/wb_xids2sids.c
index 86bd7f9deab..6fcf524d94f 100644
--- a/source3/winbindd/wb_xids2sids.c
+++ b/source3/winbindd/wb_xids2sids.c
@@ -143,9 +143,15 @@ static void wb_xids2sids_dom_done(struct tevent_req 
*subreq)
        if (NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) &&
            !state->tried_dclookup) {
 
-               subreq = wb_dsgetdcname_send(
-                       state, state->ev, state->dom_map->name, NULL, NULL,
-                       DS_RETURN_DNS_NAME);
+               const char *domain_name = find_dns_domain_name(
+                       state->dom_map->name);
+
+               subreq = wb_dsgetdcname_send(state,
+                                            state->ev,
+                                            domain_name,
+                                            NULL,
+                                            NULL,
+                                            DS_RETURN_DNS_NAME);
                if (tevent_req_nomem(subreq, req)) {
                        return;
                }
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index 24616980af3..9e51ee2acfe 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -475,140 +475,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
  */
@@ -1298,24 +1164,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;
 
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index c27fa2653f2..6570c3dec23 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -532,6 +532,7 @@ static void wb_domain_request_trigger(struct tevent_req 
*req,
        struct wb_domain_request_state *state = tevent_req_data(
                req, struct wb_domain_request_state);
        struct winbindd_domain *domain = state->domain;
+       const char *domain_name = NULL;
        struct tevent_req *subreq = NULL;
        size_t shortest_queue_length;
 
@@ -604,8 +605,11 @@ static void wb_domain_request_trigger(struct tevent_req 
*req,
         * which is indicated by DS_RETURN_DNS_NAME.
         * For NT4 domains we still get the netbios name.
         */
+
+       domain_name = find_dns_domain_name(state->domain->name);
+
        subreq = wb_dsgetdcname_send(state, state->ev,
-                                    state->domain->name,
+                                    domain_name,
                                     NULL, /* domain_guid */
                                     NULL, /* site_name */
                                     DS_RETURN_DNS_NAME); /* flags */
diff --git a/source3/winbindd/winbindd_dual_srv.c 
b/source3/winbindd/winbindd_dual_srv.c
index 0c7e9dd5491..4f855d424e5 100644
--- a/source3/winbindd/winbindd_dual_srv.c
+++ b/source3/winbindd/winbindd_dual_srv.c
@@ -662,106 +662,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)
diff --git a/source3/winbindd/winbindd_proto.h 
b/source3/winbindd/winbindd_proto.h
index 5b90a7a731f..e318911d192 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -610,6 +610,7 @@ bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
                   struct dom_sid **sids, uint32_t *num_sids);
 bool parse_xidlist(TALLOC_CTX *mem_ctx, const char *xidstr,
                   struct unixid **pxids, uint32_t *pnum_xids);
+const char *find_dns_domain_name(const char *domain_name);
 
 /* The following definitions come from winbindd/winbindd_wins.c  */
 
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index 2234efeed54..c94d313e9fd 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -2241,3 +2241,22 @@ fail:
        TALLOC_FREE(xids);
        return false;
 }
+
+/**
+ * Helper to extract the DNS Domain Name from a struct winbindd_domain
+ */
+const char *find_dns_domain_name(const char *domain_name)
+{
+       struct winbindd_domain *wbdom = NULL;
+
+       wbdom = find_domain_from_name(domain_name);
+       if (wbdom == NULL) {
+               return domain_name;
+       }
+
+       if (wbdom->active_directory && wbdom->alt_name != NULL) {
+               return wbdom->alt_name;
+       }
+
+       return wbdom->name;
+}


-- 
Samba Shared Repository

Reply via email to