diff options
Diffstat (limited to 'source3/libsmb')
-rw-r--r-- | source3/libsmb/libsmb_dir.c | 6 | ||||
-rw-r--r-- | source3/libsmb/namequery.c | 63 | ||||
-rw-r--r-- | source3/libsmb/passchange.c | 2 |
3 files changed, 62 insertions, 9 deletions
diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index a3f63f204d..7a6632ae4e 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -615,8 +615,8 @@ SMBC_opendir_ctx(SMBCCTX *context, */ if (!srv && !is_ipaddress(server) && - (resolve_name(server, &rem_ss, 0x1d) || /* LMB */ - resolve_name(server, &rem_ss, 0x1b) )) { /* DMB */ + (resolve_name(server, &rem_ss, 0x1d, false) || /* LMB */ + resolve_name(server, &rem_ss, 0x1b, false) )) { /* DMB */ fstring buserver; @@ -675,7 +675,7 @@ SMBC_opendir_ctx(SMBCCTX *context, return NULL; } } else if (srv || - (resolve_name(server, &rem_ss, 0x20))) { + (resolve_name(server, &rem_ss, 0x20, false))) { /* * If we hadn't found the server, get one now diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 05143270b9..1a641ac791 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -439,12 +439,12 @@ static int addr_compare(const struct sockaddr *ss1, int num_interfaces = iface_count(); int i; - /* Sort IPv6 addresses first. */ + /* Sort IPv4 addresses first. */ if (ss1->sa_family != ss2->sa_family) { if (ss2->sa_family == AF_INET) { - return -1; - } else { return 1; + } else { + return -1; } } @@ -601,6 +601,38 @@ static int remove_duplicate_addrs2(struct ip_service *iplist, int count ) return count; } +static bool prioritize_ipv4_list(struct ip_service *iplist, int count) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct ip_service *iplist_new = TALLOC_ARRAY(frame, struct ip_service, count); + int i, j; + + if (iplist_new == NULL) { + TALLOC_FREE(frame); + return false; + } + + j = 0; + + /* Copy IPv4 first. */ + for (i = 0; i < count; i++) { + if (iplist[i].ss.ss_family == AF_INET) { + iplist_new[j++] = iplist[i]; + } + } + + /* Copy IPv6. */ + for (i = 0; i < count; i++) { + if (iplist[i].ss.ss_family != AF_INET) { + iplist_new[j++] = iplist[i]; + } + } + + memcpy(iplist, iplist_new, sizeof(struct ip_service)*count); + TALLOC_FREE(frame); + return true; +} + /**************************************************************************** Do a netbios name query to find someones IP. Returns an array of IP addresses or NULL if none. @@ -1664,7 +1696,8 @@ NTSTATUS internal_resolve_name(const char *name, bool resolve_name(const char *name, struct sockaddr_storage *return_ss, - int name_type) + int name_type, + bool prefer_ipv4) { struct ip_service *ss_list = NULL; char *sitename = NULL; @@ -1681,6 +1714,19 @@ bool resolve_name(const char *name, lp_name_resolve_order()))) { int i; + if (prefer_ipv4) { + for (i=0; i<count; i++) { + if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) && + !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss) && + (ss_list[i].ss.ss_family == AF_INET)) { + *return_ss = ss_list[i].ss; + SAFE_FREE(ss_list); + SAFE_FREE(sitename); + return True; + } + } + } + /* only return valid addresses for TCP connections */ for (i=0; i<count; i++) { if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) && @@ -2056,7 +2102,7 @@ static NTSTATUS get_dc_list(const char *domain, /* explicit lookup; resolve_name() will * handle names & IP addresses */ - if (resolve_name( name, &name_ss, 0x20 )) { + if (resolve_name( name, &name_ss, 0x20, true )) { char addr[INET6_ADDRSTRLEN]; print_sockaddr(addr, sizeof(addr), @@ -2086,6 +2132,13 @@ static NTSTATUS get_dc_list(const char *domain, local_count ); } + /* For DC's we always prioritize IPv4 due to W2K3 not + * supporting LDAP, KRB5 or CLDAP over IPv6. */ + + if (local_count && return_iplist) { + prioritize_ipv4_list(return_iplist, local_count); + } + if ( DEBUGLEVEL >= 4 ) { DEBUG(4,("get_dc_list: returning %d ip addresses " "in an %sordered list\n", diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 7f0389f132..bb70386990 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -37,7 +37,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam *err_str = NULL; - if(!resolve_name( remote_machine, &ss, 0x20)) { + if(!resolve_name( remote_machine, &ss, 0x20, false)) { if (asprintf(err_str, "Unable to find an IP address for machine " "%s.\n", remote_machine) == -1) { *err_str = NULL; |