(Hopefully) fix the problem Kai reported with
authorJeremy Allison <jra@samba.org>
Wed, 29 Jul 2009 01:02:10 +0000 (18:02 -0700)
committerJeremy Allison <jra@samba.org>
Wed, 29 Jul 2009 01:02:10 +0000 (18:02 -0700)
net ads leave and IPv6. Ensure all DC lookups
prefer IPv4.
Jeremy.

source3/include/proto.h
source3/lib/util_sock.c
source3/libads/cldap.c
source3/libsmb/dsgetdcname.c

index fc009145f08a60280d453edc69d749d8202f4e28..697051ceea7e052c95b2fa2e3787480f95ad3233 100644 (file)
@@ -1333,6 +1333,9 @@ bool is_broadcast_addr(const struct sockaddr *pss);
 bool interpret_string_addr(struct sockaddr_storage *pss,
                const char *str,
                int flags);
+bool interpret_string_addr_prefer_ipv4(struct sockaddr_storage *pss,
+               const char *str,
+               int flags);
 bool is_loopback_ip_v4(struct in_addr ip);
 bool is_loopback_addr(const struct sockaddr *pss);
 bool is_zero_addr(const struct sockaddr *pss);
index af64f370baf18e33e60a78a1956e642b13b2444d..ec88b6046a4010c76ed1537ad133229c97a7b128 100644 (file)
 
 /*******************************************************************
  Map a text hostname or IP address (IPv4 or IPv6) into a
- struct sockaddr_storage.
+ struct sockaddr_storage. Takes a flag which allows it to
+ prefer an IPv4 address (needed for DC's).
 ******************************************************************/
 
-bool interpret_string_addr(struct sockaddr_storage *pss,
+static bool interpret_string_addr_pref(struct sockaddr_storage *pss,
                const char *str,
-               int flags)
+               int flags,
+               bool prefer_ipv4)
 {
        struct addrinfo *res = NULL;
 #if defined(HAVE_IPV6)
@@ -60,8 +62,24 @@ bool interpret_string_addr(struct sockaddr_storage *pss,
        if (!res) {
                return false;
        }
-       /* Copy the first sockaddr. */
-       memcpy(pss, res->ai_addr, res->ai_addrlen);
+
+       if (prefer_ipv4) {
+               struct addrinfo *p;
+
+               for (p = res; p; p = p->ai_next) {
+                       if (p->ai_family == AF_INET) {
+                               memcpy(pss, p->ai_addr, p->ai_addrlen);
+                               break;
+                       }
+               }
+               if (p == NULL) {
+                       /* Copy the first sockaddr. */
+                       memcpy(pss, res->ai_addr, res->ai_addrlen);
+               }
+       } else {
+               /* Copy the first sockaddr. */
+               memcpy(pss, res->ai_addr, res->ai_addrlen);
+       }
 
 #if defined(HAVE_IPV6)
        if (pss->ss_family == AF_INET6 && scope_id) {
@@ -77,6 +95,36 @@ bool interpret_string_addr(struct sockaddr_storage *pss,
        return true;
 }
 
+/*******************************************************************
+ Map a text hostname or IP address (IPv4 or IPv6) into a
+ struct sockaddr_storage. Address agnostic version.
+******************************************************************/
+
+bool interpret_string_addr(struct sockaddr_storage *pss,
+               const char *str,
+               int flags)
+{
+       return interpret_string_addr_pref(pss,
+                                       str,
+                                       flags,
+                                       false);
+}
+
+/*******************************************************************
+ Map a text hostname or IP address (IPv4 or IPv6) into a
+ struct sockaddr_storage. Version that prefers IPv4.
+******************************************************************/
+
+bool interpret_string_addr_prefer_ipv4(struct sockaddr_storage *pss,
+               const char *str,
+               int flags)
+{
+       return interpret_string_addr_pref(pss,
+                                       str,
+                                       flags,
+                                       true);
+}
+
 /*******************************************************************
  Set an address to INADDR_ANY.
 ******************************************************************/
index 523020797b097d6187a76b6016c2bb521dc50c5c..5cefd6ccc1b69941b5b1bed879df18719f987f0c 100644 (file)
@@ -44,7 +44,7 @@ bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx,
        int ret;
        struct tsocket_address *dest_addr;
 
-       if (!interpret_string_addr(&ss, server, 0)) {
+       if (!interpret_string_addr_prefer_ipv4(&ss, server, 0)) {
                DEBUG(2,("Failed to resolve[%s] into an address for cldap\n",
                        server));
                return false;
index 3e0f4977aa250e444edb149c916a546316feac10..de020d4791e753420f68b763ef9472516bbef4e2 100644 (file)
@@ -613,7 +613,8 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx,
                /* If we don't have an IP list for a name, lookup it up */
 
                if (!dcs[i].ss_s) {
-                       interpret_string_addr(&r->ss, dcs[i].hostname, 0);
+                       interpret_string_addr_prefer_ipv4(&r->ss,
+                                               dcs[i].hostname, 0);
                        i++;
                        j = 0;
                } else {
@@ -973,7 +974,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx,
                ip_list.ss = dclist[i].ss;
                ip_list.port = 0;
 
-               if (!interpret_string_addr(&ss, dclist[i].hostname, AI_NUMERICHOST)) {
+               if (!interpret_string_addr_prefer_ipv4(&ss, dclist[i].hostname, AI_NUMERICHOST)) {
                        return NT_STATUS_UNSUCCESSFUL;
                }