[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