The branch, master has been updated
via 85dd55a5fef libads: change netlogon_pings() behaviour wrt to
min_servers parameter
via 6643d1fb337 libads: reverse termination condition in
netlogon_pings_done()
via 4d69ec473b7 idmap_ad: add and use ldap_timeout and fix LDAP server
failover
via 4e79fe13325 tldap: use tevent_req_set_endtime() to terminate LDAP
searches
via 9ad2e59a464 winbindd: use find_domain_from_name_noinit() in
find_dns_domain_name()
via 23f100f67c0 libads: fix get_kdc_ip_string()
from 37c7952a2e5 s4:torture/smb2: Fix torture test case
smb2.acls.ACCESS_BASED
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 85dd55a5fef0049660126bdcd48abfa1c48da259
Author: Ralph Boehme <[email protected]>
Date: Thu Jul 24 12:59:30 2025 +0200
libads: change netlogon_pings() behaviour wrt to min_servers parameter
Currently if a caller passes min_servers=X with X>1, netlogon_pings() will
fail
if it can't contact X DCs. This is not really what we want. What we want
is: we
want at least one DC, and up to X.
Change implemenentation in that sense and rename the min_servers argument to
wanted_servers to express this behaviour change.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15844
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Guenther Deschner <[email protected]>
Autobuild-User(master): Günther Deschner <[email protected]>
Autobuild-Date(master): Wed Aug 13 19:31:10 UTC 2025 on atb-devel-224
commit 6643d1fb3375903e2857e5bff33b39a4562c5a4d
Author: Ralph Boehme <[email protected]>
Date: Thu Jul 24 12:55:30 2025 +0200
libads: reverse termination condition in netlogon_pings_done()
No change in behaviour, prepares for upcoming change and minimizes its diff.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15844
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Guenther Deschner <[email protected]>
commit 4d69ec473b7be763399c9787eda8e659a1582184
Author: Ralph Boehme <[email protected]>
Date: Thu Jul 24 15:49:19 2025 +0200
idmap_ad: add and use ldap_timeout and fix LDAP server failover
The key parts are:
1. If an LDAP search fails with the hardcoded fatal error, remove the
retry. That would only retry the query against the same server, taken
from the DCINFO cache key. Instead, force a DC rediscovery.
2. Set a default ldap_timeout and pass it to tldap_search(). This
avoids tldap_search() hanging forever on a stale TCP connection.
3. The LDAP server idmap_ad is using is not necessarily the same DC
we're using for RPC, so in case we learn about a dead DC, put it in
the negative-conn-cache.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15844
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Guenther Deschner <[email protected]>
commit 4e79fe13325385ef4fe37baeec8656c9b332de19
Author: Ralph Boehme <[email protected]>
Date: Mon Jul 21 06:44:22 2025 +0200
tldap: use tevent_req_set_endtime() to terminate LDAP searches
Needed to detect unresponsive LDAP servers, otherwise we might be sitting
up to
924.6 seconds after sending a request before the kernel notifies us of a
broken
connection.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15844
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Guenther Deschner <[email protected]>
commit 9ad2e59a464bb472da2071c61a254547b6497625
Author: Ralph Boehme <[email protected]>
Date: Tue Jul 22 19:16:14 2025 +0200
winbindd: use find_domain_from_name_noinit() in find_dns_domain_name()
Avoid triggering a connection to a DC of a trusted domain.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15876
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Guenther Deschner <[email protected]>
commit 23f100f67c0586a940e91e9e1e6f42b804401322
Author: Ralph Boehme <[email protected]>
Date: Tue Jul 22 19:22:31 2025 +0200
libads: fix get_kdc_ip_string()
Correctly handle the interaction between optionally passed in DC via
pss and DC lookup.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15876
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Guenther Deschner <[email protected]>
-----------------------------------------------------------------------
Summary of changes:
source3/lib/tldap.c | 5 ++++
source3/libads/cldap.c | 2 +-
source3/libads/kerberos.c | 18 ++++++++++----
source3/libads/ldap.c | 2 +-
source3/libads/netlogon_ping.c | 32 ++++++++++++++----------
source3/libads/netlogon_ping.h | 4 +--
source3/libsmb/dsgetdcname.c | 2 +-
source3/winbindd/idmap_ad.c | 33 ++++++++++++++++++-------
source3/winbindd/wb_queryuser.c | 10 +++++++-
source3/winbindd/wb_sids2xids.c | 12 ++++++++-
source3/winbindd/wb_xids2sids.c | 10 +++++++-
source3/winbindd/winbindd_cm.c | 52 +++++++++++++++++++++++++++++++++++++++
source3/winbindd/winbindd_proto.h | 1 +
source3/winbindd/winbindd_util.c | 2 +-
source4/libnet/libnet_site.c | 2 +-
source4/torture/rpc/lsa.c | 2 +-
16 files changed, 151 insertions(+), 38 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c
index f89306d2acd..7b1d04064e2 100644
--- a/source3/lib/tldap.c
+++ b/source3/lib/tldap.c
@@ -1905,6 +1905,11 @@ struct tevent_req *tldap_search_send(TALLOC_CTX *mem_ctx,
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
+ if (timelimit != 0) {
+ struct timeval end;
+ end = timeval_current_ofs(timelimit * 1.5F, 0);
+ tevent_req_set_endtime(subreq, ev, end);
+ }
tevent_req_set_callback(subreq, tldap_search_done, req);
return req;
diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c
index 96d602d9feb..fdb78454141 100644
--- a/source3/libads/cldap.c
+++ b/source3/libads/cldap.c
@@ -69,7 +69,7 @@ static bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx,
.acct_ctrl = -1,
.required_flags = required_flags,
},
- 1, /* min_servers */
+ 1, /* wanted_servers */
timeval_current_ofs(MAX(3, lp_ldap_timeout() / 2), 0),
&responses);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
index c1f3f3ce356..d8325201b2f 100644
--- a/source3/libads/kerberos.c
+++ b/source3/libads/kerberos.c
@@ -1180,10 +1180,12 @@ static char *get_kdc_ip_string(char *mem_ctx,
DBG_DEBUG("%zu additional KDCs to test\n", num_dcs);
if (num_dcs == 0) {
/*
- * We do not have additional KDCs, but we have the one passed
- * in via `pss`. So just use that one and leave.
+ * We do not have additional KDCs, but if we have one passed
+ * in via `pss` just use that one, otherwise fail
*/
- result = talloc_move(mem_ctx, &kdc_str);
+ if (pss != NULL) {
+ result = talloc_move(mem_ctx, &kdc_str);
+ }
goto out;
}
@@ -1223,14 +1225,20 @@ static char *get_kdc_ip_string(char *mem_ctx,
.acct_ctrl = -1,
.required_flags = DS_KDC_REQUIRED,
},
- MIN(num_dcs, 3), /* min_servers */
+ MIN(num_dcs, 3), /* wanted_servers */
timeval_current_ofs(3, 0), /* timeout */
&responses);
TALLOC_FREE(dc_addrs2);
if (!NT_STATUS_IS_OK(status)) {
DBG_DEBUG("netlogon_pings failed: %s\n", nt_errstr(status));
- result = talloc_move(mem_ctx, &kdc_str);
+ /*
+ * netlogon_pings() failed, but if we have one passed
+ * in via `pss` just just use that one, otherwise fail
+ */
+ if (pss != NULL) {
+ result = talloc_move(mem_ctx, &kdc_str);
+ }
goto out;
}
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index af467cfe390..49fa1d47298 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -501,7 +501,7 @@ again:
.required_flags = ads->config.flags |
DS_ONLY_LDAP_NEEDED,
},
- 1, /* min_servers */
+ 1, /* wanted_servers */
endtime, /* timeout */
&responses);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/libads/netlogon_ping.c b/source3/libads/netlogon_ping.c
index 22f5a56b395..c65244dd876 100644
--- a/source3/libads/netlogon_ping.c
+++ b/source3/libads/netlogon_ping.c
@@ -588,7 +588,7 @@ struct netlogon_pings_state {
struct tsocket_address **servers;
size_t num_servers;
- size_t min_servers;
+ size_t wanted_servers;
struct timeval timeout;
enum client_netlogon_ping_protocol proto;
uint32_t required_flags;
@@ -610,7 +610,7 @@ struct tevent_req *netlogon_pings_send(TALLOC_CTX *mem_ctx,
struct tsocket_address **servers,
size_t num_servers,
struct netlogon_ping_filter filter,
- size_t min_servers,
+ size_t wanted_servers,
struct timeval timeout)
{
struct tevent_req *req = NULL;
@@ -626,7 +626,7 @@ struct tevent_req *netlogon_pings_send(TALLOC_CTX *mem_ctx,
state->proto = proto;
state->servers = servers;
state->num_servers = num_servers;
- state->min_servers = min_servers;
+ state->wanted_servers = wanted_servers;
state->timeout = timeout;
state->required_flags = filter.required_flags;
@@ -685,7 +685,7 @@ struct tevent_req *netlogon_pings_send(TALLOC_CTX *mem_ctx,
}
state->filter = filter_str;
- for (i = 0; i < min_servers; i++) {
+ for (i = 0; i < wanted_servers; i++) {
state->reqs[i] = netlogon_ping_send(state->reqs,
state->ev,
state->servers[i],
@@ -699,7 +699,7 @@ struct tevent_req *netlogon_pings_send(TALLOC_CTX *mem_ctx,
netlogon_pings_done,
req);
}
- state->num_sent = min_servers;
+ state->num_sent = wanted_servers;
if (state->num_sent < state->num_servers) {
/*
* After 100 milliseconds fire the next one
@@ -818,21 +818,27 @@ static void netlogon_pings_done(struct tevent_req *subreq)
}
}
- if (state->num_good_received >= state->min_servers) {
+ if (state->num_good_received >= state->wanted_servers) {
tevent_req_done(req);
return;
}
- if (state->num_received == state->num_servers) {
+ if (state->num_received < state->num_servers) {
/*
- * Everybody replied, but we did not get enough good
- * answers (see above)
+ * Wait for more answers
*/
- tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
+ return;
+ }
+ if (state->num_good_received == 1) {
+ /* We require at least one DC */
+ tevent_req_done(req);
return;
}
/*
- * Wait for more answers
+ * Everybody replied, but we did not get a single good
+ * answers (see above)
*/
+ tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
+ return;
}
NTSTATUS netlogon_pings_recv(struct tevent_req *req,
@@ -856,7 +862,7 @@ NTSTATUS netlogon_pings(TALLOC_CTX *mem_ctx,
struct tsocket_address **servers,
int num_servers,
struct netlogon_ping_filter filter,
- int min_servers,
+ int wanted_servers,
struct timeval timeout,
struct netlogon_samlogon_response ***responses)
{
@@ -875,7 +881,7 @@ NTSTATUS netlogon_pings(TALLOC_CTX *mem_ctx,
servers,
num_servers,
filter,
- min_servers,
+ wanted_servers,
timeout);
if (req == NULL) {
goto fail;
diff --git a/source3/libads/netlogon_ping.h b/source3/libads/netlogon_ping.h
index d50c0a47936..6063c4e8a28 100644
--- a/source3/libads/netlogon_ping.h
+++ b/source3/libads/netlogon_ping.h
@@ -45,7 +45,7 @@ struct tevent_req *netlogon_pings_send(TALLOC_CTX *mem_ctx,
struct tsocket_address **servers,
size_t num_servers,
struct netlogon_ping_filter filter,
- size_t min_servers,
+ size_t wanted_servers,
struct timeval timeout);
NTSTATUS netlogon_pings_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
@@ -55,7 +55,7 @@ NTSTATUS netlogon_pings(TALLOC_CTX *mem_ctx,
struct tsocket_address **servers,
int num_servers,
struct netlogon_ping_filter filter,
- int min_servers,
+ int wanted_servers,
struct timeval timeout,
struct netlogon_samlogon_response ***responses);
diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c
index 695f0c38d85..97633317903 100644
--- a/source3/libsmb/dsgetdcname.c
+++ b/source3/libsmb/dsgetdcname.c
@@ -871,7 +871,7 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx,
.domain = domain_name,
.required_flags = flags,
},
- 1, /* min_servers */
+ 1, /* wanted_servers */
timeval_current_ofs(MAX(3, lp_ldap_timeout() / 2), 0),
&responses);
diff --git a/source3/winbindd/idmap_ad.c b/source3/winbindd/idmap_ad.c
index 38e902b8292..0644b844df1 100644
--- a/source3/winbindd/idmap_ad.c
+++ b/source3/winbindd/idmap_ad.c
@@ -50,6 +50,7 @@ struct idmap_ad_context {
bool unix_primary_group;
bool unix_nss_info;
+ int ldap_timeout;
struct ldb_context *ldb;
struct ldb_dn **deny_ous;
@@ -576,6 +577,8 @@ static NTSTATUS idmap_ad_context_create(TALLOC_CTX *mem_ctx,
domname, "unix_primary_group", false);
ctx->unix_nss_info = idmap_config_bool(
domname, "unix_nss_info", false);
+ ctx->ldap_timeout = idmap_config_int(
+ domname, "ldap_timeout", 10);
schema_mode = idmap_config_const_string(
domname, "schema_mode", "rfc2307");
@@ -742,7 +745,7 @@ static NTSTATUS idmap_ad_query_user(struct idmap_domain
*domain,
rc = tldap_search(ctx->ld, ctx->default_nc, TLDAP_SCOPE_SUB, filter,
attrs, ARRAY_SIZE(attrs), 0, NULL, 0, NULL, 0,
- 0, 0, 0, talloc_tos(), &msgs);
+ ctx->ldap_timeout, 0, 0, talloc_tos(), &msgs);
if (!TLDAP_RC_IS_SUCCESS(rc)) {
return NT_STATUS_LDAP(TLDAP_RC_V(rc));
}
@@ -815,13 +818,17 @@ static NTSTATUS idmap_ad_query_user_retry(struct
idmap_domain *domain,
{
const NTSTATUS status_server_down =
NT_STATUS_LDAP(TLDAP_RC_V(TLDAP_SERVER_DOWN));
+ const NTSTATUS status_timeout =
+ NT_STATUS_LDAP(TLDAP_RC_V(TLDAP_TIMEOUT));
NTSTATUS status;
status = idmap_ad_query_user(domain, info);
- if (NT_STATUS_EQUAL(status, status_server_down)) {
+ if (NT_STATUS_EQUAL(status, status_server_down) ||
+ NT_STATUS_EQUAL(status, status_timeout))
+ {
TALLOC_FREE(domain->private_data);
- status = idmap_ad_query_user(domain, info);
+ return NT_STATUS_HOST_UNREACHABLE;
}
return status;
@@ -978,7 +985,7 @@ static NTSTATUS idmap_ad_unixids_to_sids(struct
idmap_domain *dom,
rc = tldap_search(ctx->ld, ctx->default_nc, TLDAP_SCOPE_SUB, filter,
attrs, ARRAY_SIZE(attrs), 0, NULL, 0, NULL, 0,
- 0, 0, 0, talloc_tos(), &msgs);
+ ctx->ldap_timeout, 0, 0, talloc_tos(), &msgs);
if (!TLDAP_RC_IS_SUCCESS(rc)) {
return NT_STATUS_LDAP(TLDAP_RC_V(rc));
}
@@ -1142,7 +1149,7 @@ static NTSTATUS idmap_ad_sids_to_unixids(struct
idmap_domain *dom,
rc = tldap_search(ctx->ld, ctx->default_nc, TLDAP_SCOPE_SUB, filter,
attrs, ARRAY_SIZE(attrs), 0, NULL, 0, NULL, 0,
- 0, 0, 0, talloc_tos(), &msgs);
+ ctx->ldap_timeout, 0, 0, talloc_tos(), &msgs);
if (!TLDAP_RC_IS_SUCCESS(rc)) {
return NT_STATUS_LDAP(TLDAP_RC_V(rc));
}
@@ -1249,13 +1256,17 @@ static NTSTATUS idmap_ad_unixids_to_sids_retry(struct
idmap_domain *dom,
{
const NTSTATUS status_server_down =
NT_STATUS_LDAP(TLDAP_RC_V(TLDAP_SERVER_DOWN));
+ const NTSTATUS status_timeout =
+ NT_STATUS_LDAP(TLDAP_RC_V(TLDAP_TIMEOUT));
NTSTATUS status;
status = idmap_ad_unixids_to_sids(dom, ids);
- if (NT_STATUS_EQUAL(status, status_server_down)) {
+ if (NT_STATUS_EQUAL(status, status_server_down) ||
+ NT_STATUS_EQUAL(status, status_timeout))
+ {
TALLOC_FREE(dom->private_data);
- status = idmap_ad_unixids_to_sids(dom, ids);
+ return NT_STATUS_HOST_UNREACHABLE;
}
return status;
@@ -1266,13 +1277,17 @@ static NTSTATUS idmap_ad_sids_to_unixids_retry(struct
idmap_domain *dom,
{
const NTSTATUS status_server_down =
NT_STATUS_LDAP(TLDAP_RC_V(TLDAP_SERVER_DOWN));
+ const NTSTATUS status_timeout =
+ NT_STATUS_LDAP(TLDAP_RC_V(TLDAP_TIMEOUT));
NTSTATUS status;
status = idmap_ad_sids_to_unixids(dom, ids);
- if (NT_STATUS_EQUAL(status, status_server_down)) {
+ if (NT_STATUS_EQUAL(status, status_server_down) ||
+ NT_STATUS_EQUAL(status, status_timeout))
+ {
TALLOC_FREE(dom->private_data);
- status = idmap_ad_sids_to_unixids(dom, ids);
+ return NT_STATUS_HOST_UNREACHABLE;
}
return status;
diff --git a/source3/winbindd/wb_queryuser.c b/source3/winbindd/wb_queryuser.c
index db8e946ba71..0f318f8b631 100644
--- a/source3/winbindd/wb_queryuser.c
+++ b/source3/winbindd/wb_queryuser.c
@@ -279,6 +279,7 @@ static void wb_queryuser_done(struct tevent_req *subreq)
NTSTATUS status, result;
bool need_group_name = false;
const char *tmpl = NULL;
+ uint32_t dsgetdcname_flags = DS_RETURN_DNS_NAME;
status = dcerpc_wbint_GetNssInfo_recv(subreq, info, &result);
TALLOC_FREE(subreq);
@@ -287,6 +288,13 @@ static void wb_queryuser_done(struct tevent_req *subreq)
return;
}
+ if (NT_STATUS_EQUAL(result, NT_STATUS_HOST_UNREACHABLE)) {
+ winbind_idmap_add_failed_connection_entry(info->domain_name);
+ /* Trigger DC lookup and reconnect below */
+ result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
+ dsgetdcname_flags |= DS_FORCE_REDISCOVERY;
+ }
+
if (NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) &&
!state->tried_dclookup) {
const char *domain_name = find_dns_domain_name(
@@ -301,7 +309,7 @@ static void wb_queryuser_done(struct tevent_req *subreq)
domain_name,
NULL,
NULL,
- DS_RETURN_DNS_NAME);
+ dsgetdcname_flags);
if (tevent_req_nomem(subreq, req)) {
return;
}
diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c
index 03e5e7e0258..f5ff9223034 100644
--- a/source3/winbindd/wb_sids2xids.c
+++ b/source3/winbindd/wb_sids2xids.c
@@ -598,6 +598,7 @@ static void wb_sids2xids_done(struct tevent_req *subreq)
NTSTATUS status, result;
const struct wbint_TransIDArray *src = NULL;
struct wbint_TransIDArray *dst = NULL;
+ uint32_t dsgetdcname_flags = DS_RETURN_DNS_NAME;
uint32_t si;
status = dcerpc_wbint_Sids2UnixIDs_recv(subreq, state, &result);
@@ -608,6 +609,15 @@ static void wb_sids2xids_done(struct tevent_req *subreq)
return;
}
+ if (NT_STATUS_EQUAL(result, NT_STATUS_HOST_UNREACHABLE)) {
+ struct lsa_DomainInfo *d =
+ &state->idmap_doms.domains[state->dom_index];
+ winbind_idmap_add_failed_connection_entry(d->name.string);
+ /* Trigger DC lookup and reconnect below */
+ result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
+ dsgetdcname_flags |= DS_FORCE_REDISCOVERY;
+ }
+
if (NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) &&
!state->tried_dclookup) {
@@ -627,7 +637,7 @@ static void wb_sids2xids_done(struct tevent_req *subreq)
domain_name,
NULL,
NULL,
- DS_RETURN_DNS_NAME);
+ dsgetdcname_flags);
if (tevent_req_nomem(subreq, req)) {
return;
}
diff --git a/source3/winbindd/wb_xids2sids.c b/source3/winbindd/wb_xids2sids.c
index 6fcf524d94f..0384740d17d 100644
--- a/source3/winbindd/wb_xids2sids.c
+++ b/source3/winbindd/wb_xids2sids.c
@@ -130,6 +130,7 @@ static void wb_xids2sids_dom_done(struct tevent_req *subreq)
struct wb_xids2sids_dom_state *state = tevent_req_data(
req, struct wb_xids2sids_dom_state);
const struct wb_parent_idmap_config_dom *dom_map = state->dom_map;
+ uint32_t dsgetdcname_flags = DS_RETURN_DNS_NAME;
NTSTATUS status, result;
size_t i;
size_t dom_sid_idx;
@@ -140,6 +141,13 @@ static void wb_xids2sids_dom_done(struct tevent_req
*subreq)
return;
}
+ if (NT_STATUS_EQUAL(result, NT_STATUS_HOST_UNREACHABLE)) {
+ winbind_idmap_add_failed_connection_entry(dom_map->name);
+ /* Trigger DC lookup and reconnect below */
+ result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
+ dsgetdcname_flags |= DS_FORCE_REDISCOVERY;
+ }
+
if (NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) &&
!state->tried_dclookup) {
@@ -151,7 +159,7 @@ static void wb_xids2sids_dom_done(struct tevent_req *subreq)
domain_name,
NULL,
NULL,
- DS_RETURN_DNS_NAME);
+ dsgetdcname_flags);
if (tevent_req_nomem(subreq, req)) {
return;
}
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index f45bb6cda99..3963881ca45 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -90,6 +90,8 @@
#include "lib/global_contexts.h"
#include "librpc/gen_ndr/ndr_winbind_c.h"
#include "libsmb/smbsock_connect.h"
+#include "source3/libsmb/namequery.h"
+#include "source3/libsmb/dsgetdcname.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
@@ -338,6 +340,56 @@ void winbind_add_failed_connection_entry(
winbindd_unset_locator_kdc_env(domain);
}
+void winbind_idmap_add_failed_connection_entry(const char *_domain_name)
+{
+ struct netr_DsRGetDCNameInfo *dcinfo = NULL;
+ const char *dc_unc = NULL;
+ const char *dc_address = NULL;
+ char *domain_name = NULL;
+ struct winbindd_domain *domain = NULL;
+ NTSTATUS failed_status = NT_STATUS_HOST_UNREACHABLE;
+ NTSTATUS status;
+
+ domain_name = talloc_strdup_upper(talloc_tos(), _domain_name);
+ if (domain_name == NULL) {
+ DBG_ERR("talloc_strdup_upper failed\n");
+ return;
+ }
+
+ status = wb_dsgetdcname_gencache_get(talloc_tos(), domain_name,
&dcinfo);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_DEBUG("Missing DC cache for domain '%s'\n", domain_name);
+ goto done;
+ }
+
+ dc_unc = dcinfo->dc_unc;
+ while (dc_unc[0] == '\\') {
+ dc_unc++;
+ }
+ dc_address = dcinfo->dc_address;
+ while (dc_address[0] == '\\') {
+ dc_address++;
+ }
+
+ add_failed_connection_entry(domain_name, dc_unc, failed_status);
+ add_failed_connection_entry(domain_name, dc_address, failed_status);
+
+ domain = find_domain_from_name_noinit(domain_name);
+ if (domain == NULL) {
+ goto done;
+ }
+ if (domain->alt_name == NULL) {
+ goto done;
+ }
+
+ add_failed_connection_entry(domain->alt_name, dc_unc, failed_status);
+ add_failed_connection_entry(domain->alt_name, dc_address,
failed_status);
+
+done:
+ TALLOC_FREE(domain_name);
--
Samba Shared Repository