heimdal Fix DNS name qualification to not mangle IP addresses
authorAndrew Bartlett <abartlet@samba.org>
Tue, 28 Sep 2010 17:59:15 +0000 (03:59 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 28 Sep 2010 18:23:07 +0000 (04:23 +1000)
If the host running this code used IPv6 forms for IPv4 addreses
then the check for '.' would not be sufficient to determine that this
isn't a name we should mangle.  Instead, check if it can be parsed
as a numeric address first, and only then mangle.

Andrew Bartlett

source4/heimdal/lib/krb5/krbhst.c

index 4da3af2e828be0d4145abea8c81bf54f17e068d3..ec0c8b738e68fd03627aa8cbb2ae97335e19c37b 100644 (file)
@@ -370,11 +370,27 @@ krb5_krbhst_get_addrinfo(krb5_context context, krb5_krbhst_info *host,
     int ret;
 
     if (host->ai == NULL) {
-       char *hostname_dot = NULL;
        make_hints(&hints, host->proto);
+       hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
        snprintf (portstr, sizeof(portstr), "%d", host->port);
-       if (strchr(host->hostname, '.') && 
+
+       /* First try this as an IP address - the flags we have set
+        * will prevent it from looking up a name */
+       ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai);
+       if (ret == 0) {
+               *ai = host->ai;
+               return 0;
+       }
+
+       hints.ai_flags &= ~AI_NUMERICHOST;
+
+       /* Now that we know it's not an IP, we can manipulate
+          it as a dotted-name, to add a final . if we think
+          it's a fully qualified DNS name */
+       if (strchr(host->hostname, '.') &&
            host->hostname[strlen(host->hostname)-1] != '.') {
+               char *hostname_dot = NULL;
+
                /* avoid expansion of search domains from resolv.conf
                   - these can be very slow if the DNS server is not up
                   for the searched domain */
@@ -384,10 +400,12 @@ krb5_krbhst_get_addrinfo(krb5_context context, krb5_krbhst_info *host,
                        hostname_dot[strlen(host->hostname)] = '.';
                        hostname_dot[strlen(host->hostname)+1] = 0;
                }
+               ret = getaddrinfo(hostname_dot?hostname_dot:host->hostname, portstr, &hints, &host->ai);
+               if (hostname_dot)
+                       free(hostname_dot);
+       } else {
+               ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai);
        }
-       ret = getaddrinfo(hostname_dot?hostname_dot:host->hostname, portstr, &hints, &host->ai);
-       if (hostname_dot) 
-               free(hostname_dot);
        if (ret)
            return krb5_eai_to_heim_errno(ret, errno);
     }