[SCM] Samba Shared Repository - branch v3-5-test updated

Karolin Seeger kseeger at samba.org
Wed Apr 20 12:45:30 MDT 2011


The branch, v3-5-test has been updated
       via  80078cb Fix is_myname_or_ipaddr() to be robust against strange DNS setups.
      from  2167ac2 s3: Fix bug 8099 - setpwent() actually does endpwent() on FreeBSD

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-5-test


- Log -----------------------------------------------------------------
commit 80078cb6ef2e6976cb5ab25a86157bca22c836a2
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Mar 24 11:55:38 2011 -0700

    Fix is_myname_or_ipaddr() to be robust against strange DNS setups.
    
    If IPv6 DNS names are turned on, but Samba isn't configured to
    listen on an IPv6 interface, then is_myname_or_ipaddr() can return
    false on a valid DNS name that it should detect is our own. If the
    IPv6 addr is returned by preference, then looking at the first addr
    only causes is_myname_or_ipaddr() to fail. We need to look at all the
    addresses returned by the DNS lookup and check all of them against
    our interface list. This is an order N^2 lookup, but there shouldn't
    be enough addresses to make this a practical problem.
    
    Jeremy.
    
    Fix bug #8038 - Connecting to a printer can return INVALID_PARAMETER when IPv6
    DNS names are turned on.

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

Summary of changes:
 source3/lib/util_sock.c |   88 ++++++++++++++++++++++++++++++----------------
 1 files changed, 57 insertions(+), 31 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index 7a573ad..1441560 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -1839,13 +1839,46 @@ const char *get_mydnsfullname(void)
 }
 
 /************************************************************
+ Is this my ip address ?
+************************************************************/
+
+static bool is_my_ipaddr(const char *ipaddr_str)
+{
+	struct sockaddr_storage ss;
+	struct iface_struct *nics;
+	int i, n;
+
+	if (!interpret_string_addr(&ss, ipaddr_str, AI_NUMERICHOST)) {
+		return false;
+	}
+
+	if (ismyaddr((struct sockaddr *)&ss)) {
+		return true;
+	}
+
+	if (is_zero_addr((struct sockaddr *)&ss) ||
+		is_loopback_addr((struct sockaddr *)&ss)) {
+		return false;
+	}
+
+	n = get_interfaces(talloc_tos(), &nics);
+	for (i=0; i<n; i++) {
+		if (sockaddr_equal((struct sockaddr *)&nics[i].ip, (struct sockaddr *)&ss)) {
+			TALLOC_FREE(nics);
+			return true;
+		}
+	}
+	TALLOC_FREE(nics);
+	return false;
+}
+
+/************************************************************
  Is this my name ?
 ************************************************************/
 
 bool is_myname_or_ipaddr(const char *s)
 {
 	TALLOC_CTX *ctx = talloc_tos();
-	char addr[INET6_ADDRSTRLEN];
 	char *name = NULL;
 	const char *dnsname;
 	char *servername = NULL;
@@ -1893,45 +1926,38 @@ bool is_myname_or_ipaddr(const char *s)
 		return true;
 	}
 
-	/* Handle possible CNAME records - convert to an IP addr. */
+	/* Handle possible CNAME records - convert to an IP addr. list. */
 	if (!is_ipaddress(servername)) {
-		/* Use DNS to resolve the name, but only the first address */
-		struct sockaddr_storage ss;
-		if (interpret_string_addr(&ss, servername, 0)) {
-			print_sockaddr(addr,
-					sizeof(addr),
-					&ss);
-			servername = addr;
-		}
-	}
+		/* Use DNS to resolve the name, check all addresses. */
+		struct addrinfo *p = NULL;
+		struct addrinfo *res = NULL;
 
-	/* Maybe its an IP address? */
-	if (is_ipaddress(servername)) {
-		struct sockaddr_storage ss;
-		struct iface_struct *nics;
-		int i, n;
-
-		if (!interpret_string_addr(&ss, servername, AI_NUMERICHOST)) {
+		if (!interpret_string_addr_internal(&res,
+				servername,
+				AI_ADDRCONFIG)) {
 			return false;
 		}
 
-		if (ismyaddr((struct sockaddr *)&ss)) {
-			return true;
-		}
-
-		if (is_zero_addr((struct sockaddr *)&ss) || 
-			is_loopback_addr((struct sockaddr *)&ss)) {
-			return false;
-		}
+		for (p = res; p; p = p->ai_next) {
+			char addr[INET6_ADDRSTRLEN];
+			struct sockaddr_storage ss;
 
-		n = get_interfaces(talloc_tos(), &nics);
-		for (i=0; i<n; i++) {
-			if (sockaddr_equal((struct sockaddr *)&nics[i].ip, (struct sockaddr *)&ss)) {
-				TALLOC_FREE(nics);
+			ZERO_STRUCT(ss);
+			memcpy(&ss, p->ai_addr, p->ai_addrlen);
+			print_sockaddr(addr,
+					sizeof(addr),
+					&ss);
+			if (is_my_ipaddr(addr)) {
+				freeaddrinfo(res);
 				return true;
 			}
 		}
-		TALLOC_FREE(nics);
+		freeaddrinfo(res);
+	}
+
+	/* Maybe its an IP address? */
+	if (is_ipaddress(servername)) {
+		return is_my_ipaddr(servername);
 	}
 
 	/* No match */


-- 
Samba Shared Repository


More information about the samba-cvs mailing list