[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Mon Jun 15 20:17:04 MDT 2015


The branch, master has been updated
       via  95fc7fb lib: ldap: Properly check talloc error returns.
       via  28f51b9 libads: further split resolve_and_ping into dns and netbios implementations
       via  4d8241e libads: Fix fallback logic when finding a domain controller
       via  625550c namequery: remove dead code
       via  dcdf2d6 libads: Keep 'good' server at the head of custom KDC list
       via  2f1b847 namequery: correctly merge kdc ip address list
       via  183b799 kerberos: Move DEFAULT_KRB5_PORT to a header file
       via  5078178 namequery: fix get_kdc_list() to look for _kerberos records
       via  a9325f1 libads: fix indentation in generated krb5.conf
      from  69e1f3d net: Fix messaging_init for clustering

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 95fc7fbe8270894d41404499ac79d699be0fb75c
Author: Jeremy Allison <jra at samba.org>
Date:   Mon Jun 15 15:49:07 2015 -0700

    lib: ldap: Properly check talloc error returns.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Tue Jun 16 04:16:13 CEST 2015 on sn-devel-104

commit 28f51b915947061555ee12f8fbe0e5fab91f4194
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Thu Jun 11 14:24:36 2015 +0300

    libads: further split resolve_and_ping into dns and netbios implementations
    
    split the resolve_and_ping function, which does name lookup followed by
    cldap ping, into two variants:
    - resolve_and_ping_dns() which uses AD name resolution
    - resolve_and_ping_netbios() which uses pre-AD name resolution
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 4d8241e017da534a933e28a0fd26e862ffae8038
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Tue Jun 9 14:30:14 2015 +0300

    libads: Fix fallback logic when finding a domain controller
    
    This is a patch to fix bug 11321.
    
    When finding a domain controller, the method is to resolve
    the IP address of candidate servers, and then do an ldap ping until a
    suitable server answers.
    
    In case of failure, there's fallback from DNS lookup to netbios lookup
    (if netbios is enabled) and then back to site-less DNS lookup. The two
    problems here are:
    1. It makes more sense to try site-less DNS before NetBIOS because the
    fallback to NetBIOS is not likely to give better results.
    2. The NetBIOS fallback screws the site-less fallback (I suppose the
    "goto considered harmful fellows are sometimes right after all...).
    
    This fix extracts the core code that does name resolving+ldap ping
    into a separate function and then activates this function in up to
    three modes - site-aware, site-less, and netbios, in that order.
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 625550c32a2ff3fcfcfd4e95a13315bf04462d8e
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Mon Jun 8 08:42:58 2015 +0300

    namequery: remove dead code
    
    When composing the list of servers out of the server affinity cache
    and "password server" parameter, there's fallback to DNS-SRV-record-
    based search if the "password server" + session affinity yield an empty
    list. However:
    1. The way the code is written, it never gets executed because the empty list
       is not an empty string (it contains a comma)
    2. This fallback is doe in any case just a few lines down the function
    
    Therefore this patch simply removes this fallback code.
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit dcdf2d6f275f4e9ed5fa062ffc173956d2aba4dc
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Mon May 18 13:36:46 2015 +0300

    libads: Keep 'good' server at the head of custom KDC list
    
    When creating a custom krb.conf file for a domain, make sure
    that the DC which already answered the ldap ping is not queried
    again, and is always first in the custom KDC list. This has two
    advantages:
    1. Avoid re-sending an ldap ping to this server
    2. The generated list is made up of the servers that answered
       first. Since the DC which already answered an LDAP ping
       is typically the "last good server", this change keeps it
       out of the contest and guarantees that we keep using last
       good server as long as it works.
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 2f1b84719914f6e0966708da6cc8f4150f7c2608
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Thu May 21 10:38:42 2015 +0300

    namequery: correctly merge kdc ip address list
    
    When finding DCs, there are three sources of addresses:
    1. "Last good server"
    2. Configured password server
    3. SRV DNS queries
    
    Since those different sources may return the same addresses, the
    IP list is checked for duplicates, e.g. in order to save on
    the LDAP ping that usually follows. Both IP address and port are
    compared.
    
    This change fixes the address duplicate removal for the case of KDC
    search, where the "last good server" or configured password server
    also appears in the DNS SRV query response.
    
    An (undocumented?) assumption is that the "password server" parameter
    is applicable to KDCs as well, but if a port is specified (e.g.
    dc1.example.com:390), then this is the ldap port.
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 183b799103d250985807f187fe60a03deb2145cc
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Thu Jun 4 22:10:55 2015 +0300

    kerberos: Move DEFAULT_KRB5_PORT to a header file
    
    Move the kerberos port number definition to a header file, so that
    it can be used by DNS code.
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 507817881c734706b0287a9eaa9c10d7b61ff7cb
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Wed Jun 3 13:50:25 2015 +0300

    namequery: fix get_kdc_list() to look for _kerberos records
    
    get_kdc_list() should look for _kerberos.xxx SRV records rather
    than _ldap.xxx records. This has significance in two cases:
    - Non-default DNS configurations
    - When building a custom krb5.conf file for a domain, an attempt is
      made to get site-specific as well as site-less records, but the
      search for _ldap records yields a cached site-specific result even
      for the site-less query.
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit a9325f185c6894f723c278898b3f6738ecf9d6f9
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Thu May 21 08:40:24 2015 +0300

    libads: fix indentation in generated krb5.conf
    
    In case of multiple KDCs, the automatically-generated
    domain-specific kerberos configuration file lists all the
    KDCs it can find, but the indentation of additional KDCs
    is not aligned with that of the first KDC.
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

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

Summary of changes:
 libcli/ldap/ldap_message.c      |  11 +-
 source3/libads/kerberos.c       |  59 +++++----
 source3/libads/kerberos_proto.h |   2 +
 source3/libads/ldap.c           | 261 +++++++++++++++++++++++++---------------
 source3/libsmb/namequery.c      |  32 ++---
 5 files changed, 229 insertions(+), 136 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c
index ba94f4c..0c664b7 100644
--- a/libcli/ldap/ldap_message.c
+++ b/libcli/ldap/ldap_message.c
@@ -706,6 +706,9 @@ static const char *blob2string_talloc(TALLOC_CTX *mem_ctx,
 				      DATA_BLOB blob)
 {
 	char *result = talloc_array(mem_ctx, char, blob.length+1);
+	if (result == NULL) {
+		return NULL;
+	}
 	memcpy(result, blob.data, blob.length);
 	result[blob.length] = '\0';
 	return result;
@@ -720,7 +723,7 @@ bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
 		return false;
 	*result = blob2string_talloc(mem_ctx, string);
 	data_blob_free(&string);
-	return true;
+	return *result ? true : false;
 }
 
 static bool ldap_decode_response(TALLOC_CTX *mem_ctx,
@@ -868,6 +871,9 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
 
 		ret->operation = LDB_OP_SUBSTRING;
 		ret->u.substring.attr = talloc_strndup(ret, (char *)attr.data, attr.length);
+		if (ret->u.substring.attr == NULL) {
+			goto failed;
+		}
 		ret->u.substring.chunks = NULL;
 		ret->u.substring.start_with_wildcard = 1;
 		ret->u.substring.end_with_wildcard = 1;
@@ -1073,6 +1079,9 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
 				ret->u.extended.attr = talloc_steal(ret, attr);
 			} else {
 				ret->u.extended.attr = talloc_strdup(ret, "*");
+				if (ret->u.extended.attr == NULL) {
+					goto failed;
+				}
 			}
 			ret->u.extended.rule_id      = talloc_steal(ret, oid);
 			ret->u.extended.value.data   = (uint8_t *)talloc_steal(ret, value);
diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
index d5d8e2a..1c2d8a2 100644
--- a/source3/libads/kerberos.c
+++ b/source3/libads/kerberos.c
@@ -32,8 +32,6 @@
 
 #ifdef HAVE_KRB5
 
-#define DEFAULT_KRB5_PORT 88
-
 #define LIBADS_CCACHE_NAME "MEMORY:libads"
 
 /*
@@ -663,7 +661,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
 	char *result = NULL;
 	struct netlogon_samlogon_response **responses = NULL;
 	NTSTATUS status;
-	char *kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", "",
+	char *kdc_str = talloc_asprintf(mem_ctx, "%s\t\tkdc = %s\n", "",
 					print_canonical_sockaddr_with_port(mem_ctx, pss));
 
 	if (kdc_str == NULL) {
@@ -678,34 +676,51 @@ static char *get_kdc_ip_string(char *mem_ctx,
 
 	if (sitename) {
 		get_kdc_list(realm, sitename, &ip_srv_site, &count_site);
+		DEBUG(10, ("got %d addresses from site %s search\n", count_site,
+			   sitename));
 	}
 
 	/* Get all KDC's. */
 
 	get_kdc_list(realm, NULL, &ip_srv_nonsite, &count_nonsite);
+	DEBUG(10, ("got %d addresses from site-less search\n", count_nonsite));
 
 	dc_addrs = talloc_array(talloc_tos(), struct sockaddr_storage,
-				1 + count_site + count_nonsite);
+				count_site + count_nonsite);
 	if (dc_addrs == NULL) {
-		goto fail;
+		goto out;
 	}
 
-	dc_addrs[0] = *pss;
-	num_dcs = 1;
+	num_dcs = 0;
 
-	for (i=0; i<count_site; i++) {
-		add_sockaddr_unique(dc_addrs, &num_dcs, &ip_srv_site[i].ss);
+	for (i = 0; i < count_site; i++) {
+		if (!sockaddr_equal(
+			(const struct sockaddr *)pss,
+			(const struct sockaddr *)&ip_srv_site[i].ss)) {
+			add_sockaddr_unique(dc_addrs, &num_dcs,
+					    &ip_srv_site[i].ss);
+		}
 	}
 
-	for (i=0; i<count_nonsite; i++) {
-		add_sockaddr_unique(dc_addrs, &num_dcs, &ip_srv_nonsite[i].ss);
+	for (i = 0; i < count_nonsite; i++) {
+		if (!sockaddr_equal(
+			(const struct sockaddr *)pss,
+			(const struct sockaddr *)&ip_srv_nonsite[i].ss)) {
+			add_sockaddr_unique(dc_addrs, &num_dcs,
+					    &ip_srv_nonsite[i].ss);
+		}
 	}
 
 	dc_addrs2 = talloc_zero_array(talloc_tos(),
 				      struct tsocket_address *,
 				      num_dcs);
+
+	DEBUG(10, ("%d additional KDCs to test\n", num_dcs));
+	if (num_dcs == 0) {
+		goto out;
+	}
 	if (dc_addrs2 == NULL) {
-		goto fail;
+		goto out;
 	}
 
 	for (i=0; i<num_dcs; i++) {
@@ -721,7 +736,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
 			status = map_nt_error_from_unix(errno);
 			DEBUG(2,("Failed to create tsocket_address for %s - %s\n",
 				 addr, nt_errstr(status)));
-			goto fail;
+			goto out;
 		}
 	}
 
@@ -738,12 +753,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(10,("get_kdc_ip_string: cldap_multi_netlogon failed: "
 			  "%s\n", nt_errstr(status)));
-		goto fail;
-	}
-
-	kdc_str = talloc_strdup(mem_ctx, "");
-	if (kdc_str == NULL) {
-		goto fail;
+		goto out;
 	}
 
 	for (i=0; i<num_dcs; i++) {
@@ -754,21 +764,20 @@ static char *get_kdc_ip_string(char *mem_ctx,
 		}
 
 		/* Append to the string - inefficient but not done often. */
-		new_kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
+		new_kdc_str = talloc_asprintf(mem_ctx, "%s\t\tkdc = %s\n",
 					      kdc_str,
 					      print_canonical_sockaddr_with_port(mem_ctx, &dc_addrs[i]));
 		if (new_kdc_str == NULL) {
-			goto fail;
+			goto out;
 		}
 		TALLOC_FREE(kdc_str);
 		kdc_str = new_kdc_str;
 	}
 
-	DEBUG(10,("get_kdc_ip_string: Returning %s\n",
-		kdc_str ));
+out:
+	DEBUG(10, ("get_kdc_ip_string: Returning %s\n", kdc_str));
 
 	result = kdc_str;
-fail:
 	SAFE_FREE(ip_srv_site);
 	SAFE_FREE(ip_srv_nonsite);
 	TALLOC_FREE(frame);
@@ -872,7 +881,7 @@ bool create_local_private_krb5_conf_for_domain(const char *realm,
 					"\tdefault_tkt_enctypes = %s RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n"
 					"\tpreferred_enctypes = %s RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n\n"
 					"[realms]\n\t%s = {\n"
-					"\t%s\t}\n",
+					"%s\t}\n",
 					realm_upper, aes_enctypes, aes_enctypes, aes_enctypes,
 					realm_upper, kdc_ip_string);
 
diff --git a/source3/libads/kerberos_proto.h b/source3/libads/kerberos_proto.h
index 3d0ad4b..8a6e00d 100644
--- a/source3/libads/kerberos_proto.h
+++ b/source3/libads/kerberos_proto.h
@@ -39,6 +39,8 @@ struct PAC_DATA_CTR {
 	struct PAC_DATA *pac_data;
 };
 
+#define DEFAULT_KRB5_PORT 88
+
 #include "libads/ads_status.h"
 
 /* The following definitions come from libads/kerberos.c  */
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 1c0375d..5c53c63 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -313,22 +313,125 @@ static bool ads_try_connect(ADS_STRUCT *ads, bool gc,
 }
 
 /**********************************************************************
+ send a cldap ping to list of servers, one at a time, until one of
+ them answers it's an ldap server. Record success in the ADS_STRUCT.
+ Take note of and update negative connection cache.
+**********************************************************************/
+
+static NTSTATUS cldap_ping_list(ADS_STRUCT *ads,const char *domain,
+				struct ip_service *ip_list, int count)
+{
+	int i;
+	bool ok;
+
+	for (i = 0; i < count; i++) {
+		char server[INET6_ADDRSTRLEN];
+
+		print_sockaddr(server, sizeof(server), &ip_list[i].ss);
+
+		if (!NT_STATUS_IS_OK(
+			check_negative_conn_cache(domain, server)))
+			continue;
+
+		ok = ads_try_connect(ads, false, &ip_list[i].ss);
+		if (ok) {
+			return NT_STATUS_OK;
+		}
+
+		/* keep track of failures */
+		add_failed_connection_entry(domain, server,
+					    NT_STATUS_UNSUCCESSFUL);
+	}
+
+	return NT_STATUS_NO_LOGON_SERVERS;
+}
+
+/***************************************************************************
+ resolve a name and perform an "ldap ping" using NetBIOS and related methods
+****************************************************************************/
+
+static NTSTATUS resolve_and_ping_netbios(ADS_STRUCT *ads,
+					 const char *domain, const char *realm)
+{
+	int count, i;
+	struct ip_service *ip_list;
+	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+
+	DEBUG(6, ("resolve_and_ping_netbios: (cldap) looking for domain '%s'\n",
+		  domain));
+
+	status = get_sorted_dc_list(domain, NULL, &ip_list, &count,
+				    false);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	/* remove servers which are known to be dead based on
+	   the corresponding DNS method */
+	if (*realm) {
+		for (i = 0; i < count; ++i) {
+			char server[INET6_ADDRSTRLEN];
+
+			print_sockaddr(server, sizeof(server), &ip_list[i].ss);
+
+			if(!NT_STATUS_IS_OK(
+				check_negative_conn_cache(realm, server))) {
+				/* Ensure we add the workgroup name for this
+				   IP address as negative too. */
+				add_failed_connection_entry(
+				    domain, server,
+				    NT_STATUS_UNSUCCESSFUL);
+			}
+		}
+	}
+
+	status = cldap_ping_list(ads, domain, ip_list, count);
+
+	SAFE_FREE(ip_list);
+
+	return status;
+}
+
+
+/**********************************************************************
+ resolve a name and perform an "ldap ping" using DNS
+**********************************************************************/
+
+static NTSTATUS resolve_and_ping_dns(ADS_STRUCT *ads, const char *sitename,
+				     const char *realm)
+{
+	int count;
+	struct ip_service *ip_list;
+	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+
+	DEBUG(6, ("resolve_and_ping_dns: (cldap) looking for realm '%s'\n",
+		  realm));
+
+	status = get_sorted_dc_list(realm, sitename, &ip_list, &count,
+				    true);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	status = cldap_ping_list(ads, realm, ip_list, count);
+
+	SAFE_FREE(ip_list);
+
+	return status;
+}
+
+/**********************************************************************
  Try to find an AD dc using our internal name resolution routines
- Try the realm first and then then workgroup name if netbios is not 
+ Try the realm first and then then workgroup name if netbios is not
  disabled
 **********************************************************************/
 
 static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
 {
-	const char *c_domain;
+	const char *c_domain = "";
 	const char *c_realm;
-	int count, i=0;
-	struct ip_service *ip_list;
-	const char *realm;
-	const char *domain;
-	bool got_realm = False;
 	bool use_own_domain = False;
-	char *sitename;
+	char *sitename = NULL;
 	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
 	bool ok = false;
 
@@ -337,7 +440,10 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
 	/* realm */
 	c_realm = ads->server.realm;
 
-	if ( !c_realm || !*c_realm ) {
+	if (c_realm == NULL)
+		c_realm = "";
+
+	if (!*c_realm) {
 		/* special case where no realm and no workgroup means our own */
 		if ( !ads->server.workgroup || !*ads->server.workgroup ) {
 			use_own_domain = True;
@@ -345,35 +451,27 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
 		}
 	}
 
-	if (c_realm && *c_realm)
-		got_realm = True;
-
-	/* we need to try once with the realm name and fallback to the
-	   netbios domain name if we fail (if netbios has not been disabled */
+	if (!lp_disable_netbios()) {
+		if (use_own_domain) {
+			c_domain = lp_workgroup();
+		} else {
+			c_domain = ads->server.workgroup;
+			if (!*c_realm && (!c_domain || !*c_domain)) {
+				c_domain = lp_workgroup();
+			}
+		}
 
-	if ( !got_realm	&& !lp_disable_netbios() ) {
-		c_realm = ads->server.workgroup;
-		if (!c_realm || !*c_realm) {
-			if ( use_own_domain )
-				c_realm = lp_workgroup();
+		if (!c_domain) {
+			c_domain = "";
 		}
 	}
 
-	if ( !c_realm || !*c_realm ) {
+	if (!*c_realm && !*c_domain) {
 		DEBUG(1, ("ads_find_dc: no realm or workgroup!  Don't know "
 			  "what to do\n"));
 		return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */
 	}
 
-	if ( use_own_domain ) {
-		c_domain = lp_workgroup();
-	} else {
-		c_domain = ads->server.workgroup;
-	}
-
-	realm = c_realm;
-	domain = c_domain;
-
 	/*
 	 * In case of LDAP we use get_dc_name() as that
 	 * creates the custom krb5.conf file
@@ -382,10 +480,11 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
 		fstring srv_name;
 		struct sockaddr_storage ip_out;
 
-		DEBUG(6,("ads_find_dc: (ldap) looking for %s '%s'\n",
-			(got_realm ? "realm" : "domain"), realm));
+		DEBUG(6, ("ads_find_dc: (ldap) looking for realm '%s'"
+			  " and falling back to domain '%s'\n",
+			  c_realm, c_domain));
 
-		ok = get_dc_name(domain, realm, srv_name, &ip_out);
+		ok = get_dc_name(c_domain, c_realm, srv_name, &ip_out);
 		if (ok) {
 			/*
 			 * we call ads_try_connect() to fill in the
@@ -400,80 +499,52 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
 		return NT_STATUS_NO_LOGON_SERVERS;
 	}
 
-	sitename = sitename_fetch(talloc_tos(), realm);
-
- again:
+	if (*c_realm) {
+		sitename = sitename_fetch(talloc_tos(), c_realm);
+		status = resolve_and_ping_dns(ads, sitename, c_realm);
 
-	DEBUG(6,("ads_find_dc: (cldap) looking for %s '%s'\n",
-		(got_realm ? "realm" : "domain"), realm));
-
-	status = get_sorted_dc_list(realm, sitename, &ip_list, &count, got_realm);
-	if (!NT_STATUS_IS_OK(status)) {
-		/* fall back to netbios if we can */
-		if ( got_realm && !lp_disable_netbios() ) {
-			got_realm = False;
-			goto again;
+		if (NT_STATUS_IS_OK(status)) {
+			TALLOC_FREE(sitename);
+			return status;
 		}
 
-		TALLOC_FREE(sitename);
-		return status;
-	}
-
-	/* if we fail this loop, then giveup since all the IP addresses returned were dead */
-	for ( i=0; i<count; i++ ) {
-		char server[INET6_ADDRSTRLEN];
-
-		print_sockaddr(server, sizeof(server), &ip_list[i].ss);
-
-		if ( !NT_STATUS_IS_OK(check_negative_conn_cache(realm, server)) )
-			continue;
-
-		if (!got_realm) {
-			/* realm in this case is a workgroup name. We need
-			   to ignore any IP addresses in the negative connection
-			   cache that match ip addresses returned in the ad realm
-			   case. It sucks that I have to reproduce the logic above... */
-			c_realm = ads->server.realm;
-			if ( !c_realm || !*c_realm ) {
-				if ( !ads->server.workgroup || !*ads->server.workgroup ) {
-					c_realm = lp_realm();
-				}
-			}
-			if (c_realm && *c_realm &&
-					!NT_STATUS_IS_OK(check_negative_conn_cache(c_realm, server))) {
-				/* Ensure we add the workgroup name for this
-				   IP address as negative too. */
-				add_failed_connection_entry( realm, server, NT_STATUS_UNSUCCESSFUL );
-				continue;
+		/* In case we failed to contact one of our closest DC on our
+		 * site we
+		 * need to try to find another DC, retry with a site-less SRV
+		 * DNS query
+		 * - Guenther */
+
+		if (sitename) {
+			DEBUG(1, ("ads_find_dc: failed to find a valid DC on "
+				  "our site (%s), "
+				  "trying to find another DC\n",
+				  sitename));
+			namecache_delete(c_realm, 0x1C);
+			status =
+			    resolve_and_ping_dns(ads, NULL, c_realm);
+
+			if (NT_STATUS_IS_OK(status)) {
+				TALLOC_FREE(sitename);
+				return status;
 			}
 		}
 
-		ok = ads_try_connect(ads, false, &ip_list[i].ss);
-		if (ok) {
-			SAFE_FREE(ip_list);
-			TALLOC_FREE(sitename);
-			return NT_STATUS_OK;
-		}
-
-		/* keep track of failures */
-		add_failed_connection_entry( realm, server, NT_STATUS_UNSUCCESSFUL );
+		TALLOC_FREE(sitename);
 	}
 
-	SAFE_FREE(ip_list);
-


-- 
Samba Shared Repository


More information about the samba-cvs mailing list