From: Stefan Metzmacher Date: Fri, 9 May 2025 07:38:41 +0000 (+0200) Subject: s3:winbindd: avoid using any netlogon call to get a dc name X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f86a4bf6848ade2db7229d182576db3320c3ece7;p=thirdparty%2Fsamba.git 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 Reviewed-by: Guenther Deschner Reviewed-by: Andreas Schneider Reviewed-by: Ralph Boehme --- diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index cc0b47b0600..15a2f60c532 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -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; diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index b1809809b13..c48ca15dd2b 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -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)