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

Karolin Seeger kseeger at samba.org
Sat May 26 14:19:07 MDT 2012


The branch, v3-5-test has been updated
       via  b9d3f82 Fix the loop unrolling inside resolve_ads().
       via  6d5aae1 Protect all of the name resolution methods from returning null addrs. Ensure all returns go through remove_duplicate_addrs2().
       via  3226be5 Fix convert_ss2service() to filter out zero addresses.
       via  8e9db61 Fix remove_duplicate_addrs2 to do exactly what it says. Previously it could leave zero addresses in the list.
      from  991f83f Fix bug #8957 - Typo in pam_winbindd code MUST fix. (cherry picked from commit ee4ef9a535a2d9db11bd94987fb96ae8f8771e79)

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


- Log -----------------------------------------------------------------
commit b9d3f8258396873d6ec8b6ea9ad066e2f1f8e973
Author: Jeremy Allison <jra at samba.org>
Date:   Mon Apr 30 16:32:51 2012 -0700

    Fix the loop unrolling inside resolve_ads().
    
    If we don't get an IP list don't use interpret_string_addr(), as this only returns one address, use interpret_string_addr_internal() instead.
    
    The last 4 patches address bug #8910 (resolve_ads() code can return zero
    addresses and miss valid DC IP addresses).

commit 6d5aae1d9680657c7021af2974db9b0dc2336f13
Author: Jeremy Allison <jra at samba.org>
Date:   Mon Apr 30 16:29:19 2012 -0700

    Protect all of the name resolution methods from returning null addrs. Ensure all returns go through remove_duplicate_addrs2().

commit 3226be5b5ab771c8cdf98588c40713d36eae4702
Author: Jeremy Allison <jra at samba.org>
Date:   Mon Apr 30 16:24:27 2012 -0700

    Fix convert_ss2service() to filter out zero addresses.

commit 8e9db61b447d22bad84a8c9ae450a71d9c3e6d58
Author: Jeremy Allison <jra at samba.org>
Date:   Mon Apr 30 16:16:39 2012 -0700

    Fix remove_duplicate_addrs2 to do exactly what it says. Previously it could leave zero addresses in the list.

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

Summary of changes:
 source3/libsmb/namequery.c |  189 +++++++++++++++++++++++++++++---------------
 1 files changed, 126 insertions(+), 63 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 858330d..af76f3f 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -571,7 +571,7 @@ static int remove_duplicate_addrs2(struct ip_service *iplist, int count )
 	DEBUG(10,("remove_duplicate_addrs2: "
 			"looking for duplicate address/port pairs\n"));
 
-	/* one loop to remove duplicates */
+	/* One loop to set duplicates to a zero addr. */
 	for ( i=0; i<count; i++ ) {
 		if ( is_zero_addr((struct sockaddr *)&iplist[i].ss)) {
 			continue;
@@ -585,18 +585,17 @@ static int remove_duplicate_addrs2(struct ip_service *iplist, int count )
 		}
 	}
 
-	/* one loop to clean up any holes we left */
-	/* first ip should never be a zero_ip() */
-	for (i = 0; i<count; ) {
-		if (is_zero_addr((struct sockaddr *)&iplist[i].ss) ) {
-			if (i != count-1) {
-				memmove(&iplist[i], &iplist[i+1],
-					(count - i - 1)*sizeof(iplist[i]));
+	/* Now remove any addresses set to zero above. */
+	for (i = 0; i < count; i++) {
+		while (i < count &&
+				is_zero_addr((struct sockaddr *)&iplist[i].ss)) {
+			if (count-i-1>0) {
+				memmove(&iplist[i],
+					&iplist[i+1],
+					(count-i-1)*sizeof(struct ip_service));
 			}
 			count--;
-			continue;
 		}
-		i++;
 	}
 
 	return count;
@@ -849,32 +848,53 @@ struct sockaddr_storage *name_query(int fd,
 }
 
 /********************************************************
- convert an array if struct sockaddr_storage to struct ip_service
+ Convert an array if struct sockaddr_storage to struct ip_service
  return false on failure.  Port is set to PORT_NONE;
+ pcount is [in/out] - it is the length of ss_list on input,
+ and the length of return_iplist on output as we remove any
+ zero addresses from ss_list.
 *********************************************************/
 
 static bool convert_ss2service(struct ip_service **return_iplist,
 		const struct sockaddr_storage *ss_list,
-		int count)
+		int *pcount)
 {
 	int i;
+	int orig_count = *pcount;
+	int real_count = 0;
 
-	if ( count==0 || !ss_list )
+	if (orig_count==0 || !ss_list )
 		return False;
 
+	/* Filter out zero addrs. */
+	for ( i=0; i<orig_count; i++ ) {
+		if (is_zero_addr((struct sockaddr *)&ss_list[i])) {
+			continue;
+		}
+		real_count++;
+	}
+	if (real_count==0) {
+		return false;
+	}
+
 	/* copy the ip address; port will be PORT_NONE */
-	if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) ==
+	if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, real_count)) ==
 			NULL) {
 		DEBUG(0,("convert_ip2service: malloc failed "
-			"for %d enetries!\n", count ));
+			"for %d enetries!\n", real_count ));
 		return False;
 	}
 
-	for ( i=0; i<count; i++ ) {
-		(*return_iplist)[i].ss   = ss_list[i];
-		(*return_iplist)[i].port = PORT_NONE;
+	for ( i=0, real_count = 0; i<orig_count; i++ ) {
+		if (is_zero_addr((struct sockaddr *)&ss_list[i])) {
+			continue;
+		}
+		(*return_iplist)[real_count].ss   = ss_list[i];
+		(*return_iplist)[real_count].port = PORT_NONE;
+		real_count++;
 	}
 
+	*pcount = real_count;
 	return true;
 }
 
@@ -947,7 +967,7 @@ NTSTATUS name_resolve_bcast(const char *name,
 success:
 
 	status = NT_STATUS_OK;
-	if (!convert_ss2service(return_iplist, ss_list, *return_count) )
+	if (!convert_ss2service(return_iplist, ss_list, return_count) )
 		status = NT_STATUS_INVALID_PARAMETER;
 
 	SAFE_FREE(ss_list);
@@ -1082,7 +1102,7 @@ NTSTATUS resolve_wins(const char *name,
 success:
 
 	status = NT_STATUS_OK;
-	if (!convert_ss2service(return_iplist, ss_list, *return_count))
+	if (!convert_ss2service(return_iplist, ss_list, return_count))
 		status = NT_STATUS_INVALID_PARAMETER;
 
 	SAFE_FREE(ss_list);
@@ -1230,6 +1250,10 @@ static NTSTATUS resolve_hosts(const char *name, int name_type,
 		ZERO_STRUCT(ss);
 		memcpy(&ss, res->ai_addr, res->ai_addrlen);
 
+		if (is_zero_addr((struct sockaddr *)&ss)) {
+			continue;
+		}
+
 		*return_count += 1;
 
 		*return_iplist = SMB_REALLOC_ARRAY(*return_iplist,
@@ -1263,7 +1287,7 @@ static NTSTATUS resolve_ads(const char *name,
 			    struct ip_service **return_iplist,
 			    int *return_count)
 {
-	int 			i, j;
+	int 			i;
 	NTSTATUS  		status;
 	TALLOC_CTX		*ctx;
 	struct dns_rr_srv	*dcs = NULL;
@@ -1312,7 +1336,11 @@ static NTSTATUS resolve_ads(const char *name,
 	}
 
 	for (i=0;i<numdcs;i++) {
-		numaddrs += MAX(dcs[i].num_ips,1);
+		if (!dcs[i].ss_s) {
+			numaddrs += 1;
+		} else {
+			numaddrs += dcs[i].num_ips;
+		}
 	}
 
 	if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) ==
@@ -1326,42 +1354,75 @@ static NTSTATUS resolve_ads(const char *name,
 	/* now unroll the list of IP addresses */
 
 	*return_count = 0;
-	i = 0;
-	j = 0;
-	while ( i < numdcs && (*return_count<numaddrs) ) {
-		struct ip_service *r = &(*return_iplist)[*return_count];
-
-		r->port = dcs[i].port;
-
-		/* If we don't have an IP list for a name, lookup it up */
 
+	for (i = 0; i < numdcs; i++) {
+		/* If we don't have an IP list for a name, look it up */
 		if (!dcs[i].ss_s) {
-			interpret_string_addr(&r->ss, dcs[i].hostname, 0);
-			i++;
-			j = 0;
-		} else {
-			/* use the IP addresses from the SRV sresponse */
-
-			if ( j >= dcs[i].num_ips ) {
-				i++;
-				j = 0;
+			/* We need to get all IP addresses here. */
+			struct addrinfo *res = NULL;
+			struct addrinfo *p;
+			int extra_addrs = 0;
+
+			if (!interpret_string_addr_internal(&res,
+						dcs[i].hostname,
+						0)) {
 				continue;
 			}
-
-			r->ss = dcs[i].ss_s[j];
-			j++;
-		}
-
-		/* make sure it is a valid IP.  I considered checking the
-		 * negative connection cache, but this is the wrong place
-		 * for it. Maybe only as a hack. After think about it, if
-		 * all of the IP addresses returned from DNS are dead, what
-		 * hope does a netbios name lookup have ? The standard reason
-		 * for falling back to netbios lookups is that our DNS server
-		 * doesn't know anything about the DC's   -- jerry */
-
-		if (!is_zero_addr((struct sockaddr *)&r->ss)) {
-			(*return_count)++;
+			/* Add in every IP from the lookup. How
+			   many is that ? */
+			for (p = res; p; p = p->ai_next) {
+				if (is_zero_addr((struct sockaddr *)p->ai_addr)) {
+					continue;
+				}
+				extra_addrs++;
+			}
+			if (extra_addrs > 1) {
+				/* We need to expand the return_iplist array
+				   as we only budgeted for one address. */
+				numaddrs += (extra_addrs-1);
+				*return_iplist = SMB_REALLOC_ARRAY(*return_iplist,
+						struct ip_service,
+						numaddrs);
+				if (*return_iplist == NULL) {
+					if (res) {
+						freeaddrinfo(res);
+					}
+					talloc_destroy(ctx);
+					return NT_STATUS_NO_MEMORY;
+				}
+			}
+			for (p = res; p; p = p->ai_next) {
+				(*return_iplist)[*return_count].port = dcs[i].port;
+				memcpy(&(*return_iplist)[*return_count].ss,
+						p->ai_addr,
+						p->ai_addrlen);
+				if (is_zero_addr((struct sockaddr *)&(*return_iplist)[*return_count].ss)) {
+					continue;
+				}
+				(*return_count)++;
+				/* Should never happen, but still... */
+				if (*return_count>=numaddrs) {
+					break;
+				}
+			}
+			if (res) {
+				freeaddrinfo(res);
+			}
+		} else {
+			/* use all the IP addresses from the SRV sresponse */
+			int j;
+			for (j = 0; j < dcs[i].num_ips; j++) {
+				(*return_iplist)[*return_count].port = dcs[i].port;
+				(*return_iplist)[*return_count].ss = dcs[i].ss_s[j];
+				if (is_zero_addr((struct sockaddr *)&(*return_iplist)[*return_count].ss)) {
+					continue;
+				}
+				(*return_count)++;
+				/* Should never happen, but still... */
+				if (*return_count>=numaddrs) {
+					break;
+				}
+			}
 		}
 	}
 
@@ -1418,6 +1479,10 @@ NTSTATUS internal_resolve_name(const char *name,
 			SAFE_FREE(*return_iplist);
 			return NT_STATUS_INVALID_PARAMETER;
 		}
+		if (is_zero_addr((struct sockaddr *)&(*return_iplist)->ss)) {
+			SAFE_FREE(*return_iplist);
+			return NT_STATUS_UNSUCCESSFUL;
+		}
 		*return_count = 1;
 		return NT_STATUS_OK;
 	}
@@ -1425,6 +1490,8 @@ NTSTATUS internal_resolve_name(const char *name,
 	/* Check name cache */
 
 	if (namecache_fetch(name, name_type, return_iplist, return_count)) {
+		*return_count = remove_duplicate_addrs2(*return_iplist,
+					*return_count );
 		/* This could be a negative response */
 		if (*return_count > 0) {
 			return NT_STATUS_OK;
@@ -1519,10 +1586,7 @@ NTSTATUS internal_resolve_name(const char *name,
 	controllers including the PDC in iplist[1..n].  Iterating over
 	the iplist when the PDC is down will cause two sets of timeouts. */
 
-	if ( *return_count ) {
-		*return_count = remove_duplicate_addrs2(*return_iplist,
-					*return_count );
-	}
+	*return_count = remove_duplicate_addrs2(*return_iplist, *return_count );
 
 	/* Save in name cache */
 	if ( DEBUGLEVEL >= 100 ) {
@@ -1538,7 +1602,9 @@ NTSTATUS internal_resolve_name(const char *name,
 		}
 	}
 
-	namecache_store(name, name_type, *return_count, *return_iplist);
+	if (*return_count) {
+		namecache_store(name, name_type, *return_count, *return_iplist);
+	}
 
 	/* Display some debugging info */
 
@@ -2001,10 +2067,7 @@ static NTSTATUS get_dc_list(const char *domain,
 	/* need to remove duplicates in the list if we have any
 	   explicit password servers */
 
-	if (local_count) {
-		local_count = remove_duplicate_addrs2(return_iplist,
-				local_count );
-	}
+	local_count = remove_duplicate_addrs2(return_iplist, local_count );
 
 	/* For DC's we always prioritize IPv4 due to W2K3 not
 	 * supporting LDAP, KRB5 or CLDAP over IPv6. */


-- 
Samba Shared Repository


More information about the samba-cvs mailing list