Some fixes for password-server conf option and IPv6

Isaac Boukris iboukris at gmail.com
Mon Jan 15 13:51:14 UTC 2018


On Sat, Jan 13, 2018 at 5:30 PM, Isaac Boukris <iboukris at gmail.com> wrote:
> Hello all,
>
> Find attached two patches.

Hi, I fixed the comment in the second patch, reattaching both.

btw, I wonder if the logic to prefer IPv4 address over IPv6 when an
FQDN resolves to both still make sense nowdays.
Otherwise, the code around could use a good cleanup, see:
https://buildfarm.opencsw.org/source/xref/samba/source3/libsmb/namequery.c#3293

Thanks.
-------------- next part --------------
From f40fb47d19fcd7f2e6b053df3ca9c5f27538f5d6 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris at gmail.com>
Date: Wed, 3 Jan 2018 13:51:14 +0200
Subject: [PATCH 1/2] libsmb: Fix password-server conf option using IPv6

Signed-off-by: Isaac Boukris <iboukris at gmail.com>
---
 source3/libsmb/namequery.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 7eb5dff..b3f2076 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -3245,7 +3245,24 @@ static NTSTATUS get_dc_list(const char *domain,
 		port = (lookup_type == DC_ADS_ONLY) ? LDAP_PORT :
 			((lookup_type == DC_KDC_ONLY) ? DEFAULT_KRB5_PORT :
 			 PORT_NONE);
-		if ((port_str=strchr(name, ':')) != NULL) {
+
+		/* handle IPv6 literal and port within square brackets */
+		port_str = strchr(name, ']');
+		if (*name == '[' && port_str) {
+			name++;
+			*port_str = '\0';
+
+			/* port delimiter must follow enclosing bracket */
+			port_str++;
+			if (*port_str != ':') {
+				port_str = NULL;
+			}
+		}
+		else {
+			port_str = strchr(name, ':');
+		}
+		/* if more than one colon, it is likely an IPv6 literal */
+		if (port_str && !strchr(port_str, ':')) {
 			*port_str = '\0';
 			if (lookup_type != DC_KDC_ONLY) {
 				port_str++;
-- 
2.1.0

-------------- next part --------------
From b881777ca09371d2070033eab605a29b6208370e Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris at gmail.com>
Date: Sat, 13 Jan 2018 15:06:57 +0000
Subject: [PATCH 2/2] libsmb: Fix password-server conf option with IPv6 only
 reachable DCs

Currently, if an FQDN is defined in password-server resolves to
both IPv4 and IPv6 addresses, when the DC is not reachable over
IPv4 we save it in negative conn cache and IPv6 addresses are not
being tried at all.
Fix this by iterating over resolved IPs and check each in cache
before giving up on a specified host.

Signed-off-by: Isaac Boukris <iboukris at gmail.com>
---
 source3/libsmb/namequery.c | 69 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 53 insertions(+), 16 deletions(-)

diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index b3f2076..ec49d80 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -2977,6 +2977,56 @@ NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
 	return NT_STATUS_OK;
 }
 
+static bool resolve_reachable_host(const char *name,
+				const char *domain,
+				struct sockaddr_storage *return_ss,
+				int name_type,
+				bool prefer_ipv4)
+{
+	struct sockaddr_storage *addrs;
+	unsigned i, num_addrs;
+
+	if (NT_STATUS_IS_OK(resolve_name_list(talloc_tos(), name, name_type,
+						&addrs, &num_addrs))) {
+		char addr[INET6_ADDRSTRLEN];
+
+		if (prefer_ipv4) {
+			for (i = 0; i < num_addrs; i++) {
+				if (addrs[i].ss_family != AF_INET) {
+					continue;
+				}
+
+				/* Check and don't copy known bad DC IP's */
+				print_sockaddr(addr, sizeof(addr), &addrs[i]);
+				if(!NT_STATUS_IS_OK(check_negative_conn_cache(
+							domain, addr))) {
+					DEBUG(5,("skipping negative entry %s ",
+								addr));
+					continue;
+				}
+
+				*return_ss = addrs[i];
+				return true;
+			}
+		}
+
+		for (i = 0; i < num_addrs; i++) {
+			/* Check and don't copy known bad DC IP's */
+			print_sockaddr(addr, sizeof(addr), &addrs[i]);
+			if(!NT_STATUS_IS_OK(check_negative_conn_cache(
+							domain, addr))) {
+				DEBUG(5,("skipping negative entry %s ", addr));
+				continue;
+			}
+
+			*return_ss = addrs[i];
+			return true;
+		}
+	}
+
+	return false;
+}
+
 /********************************************************
  Find the IP address of the master browser or DMB for a workgroup.
 *********************************************************/
@@ -3270,23 +3320,10 @@ static NTSTATUS get_dc_list(const char *domain,
 			}
 		}
 
-		/* explicit lookup; resolve_name() will
+		/* explicit lookup; resolve_reachable_host() will
 		 * handle names & IP addresses */
-		if (resolve_name( name, &name_ss, 0x20, true )) {
-			char addr[INET6_ADDRSTRLEN];
-			print_sockaddr(addr,
-					sizeof(addr),
-					&name_ss);
-
-			/* Check for and don't copy any known bad DC IP's. */
-			if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain,
-							addr)) ) {
-				DEBUG(5,("get_dc_list: negative entry %s "
-					"removed from DC list\n",
-					name ));
-				continue;
-			}
-
+		if (resolve_reachable_host(name, domain, &name_ss, 0x20, true))
+		{
 			return_iplist[local_count].ss = name_ss;
 			return_iplist[local_count].port = port;
 			local_count++;
-- 
2.1.0



More information about the samba-technical mailing list