]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2119. [compat] libbind: allow res_init() to succeed enough to
authorMark Andrews <marka@isc.org>
Mon, 11 Dec 2006 04:45:19 +0000 (04:45 +0000)
committerMark Andrews <marka@isc.org>
Mon, 11 Dec 2006 04:45:19 +0000 (04:45 +0000)
                        return the default domain even if it was unable
                        to allocate memory.

CHANGES
lib/bind/resolv/res_init.c

diff --git a/CHANGES b/CHANGES
index c2e7313186d8d72d9a62954a377d077a41ceb63d..ad7e76155f11240ecc6840677bd29c3c48f8b22b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+2119.  [compat]        libbind: allow res_init() to succeed enough to
+                       return the default domain even if it was unable
+                       to allocate memory.
+
 2118.  [bug]           Handle response with long chains of domain name
                        compression pointers which point to other compression
                        pointers. [RT #16427]
index d3bb71f545880dab5277b742b7bd0ded99f583fc..f0c6489edc6d8531a370ab925ce9384d64b93ee3 100644 (file)
@@ -70,7 +70,7 @@
 
 #if defined(LIBC_SCCS) && !defined(lint)
 static const char sccsid[] = "@(#)res_init.c   8.1 (Berkeley) 6/7/93";
-static const char rcsid[] = "$Id: res_init.c,v 1.9.2.11 2006/08/30 23:23:14 marka Exp $";
+static const char rcsid[] = "$Id: res_init.c,v 1.9.2.12 2006/12/11 04:45:19 marka Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include "port_before.h"
@@ -166,7 +166,9 @@ __res_vinit(res_state statp, int preinit) {
 #endif
        int dots;
        union res_sockaddr_union u[2];
+       int maxns = MAXNS;
 
+       h_errno = 0;
        if (statp->_u._ext.ext != NULL)
                res_ndestroy(statp);
 
@@ -216,8 +218,22 @@ __res_vinit(res_state statp, int preinit) {
                statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr;
                strcpy(statp->_u._ext.ext->nsuffix, "ip6.arpa");
                strcpy(statp->_u._ext.ext->nsuffix2, "ip6.int");
-       } else
-               return (-1);
+       } else {
+               /*
+                * Historically res_init() rarely, if at all, failed.
+                * Examples and applications exist which do not check
+                * our return code.  Furthermore several applications
+                * simply call us to get the systems domainname.  So
+                * rather then immediately fail here we store the
+                * failure, which is returned later, in h_errno.  And
+                * prevent the collection of 'nameserver' information
+                * by setting maxns to 0.  Thus applications that fail
+                * to check our return code wont be able to make
+                * queries anyhow.
+                */
+               h_errno = statp->res_h_errno = NETDB_INTERNAL;
+               maxns = 0;
+       }
 #ifdef RESOLVSORT
        statp->nsort = 0;
 #endif
@@ -238,9 +254,9 @@ __res_vinit(res_state statp, int preinit) {
                                buf[0] = '.';
                        cp = strchr(buf, '.');
                        cp = (cp == NULL) ? buf : (cp + 1);
-                       if (strlen(cp) >= sizeof(statp->defdname))
-                               goto freedata; 
-                       strcpy(statp->defdname, cp);
+                       strncpy(statp->defdname, cp,
+                               sizeof(statp->defdname) - 1);
+                       statp->defdname[sizeof(statp->defdname) - 1] = '\0';
                }
        }
 #endif /* SOLARIS2 */
@@ -346,7 +362,7 @@ __res_vinit(res_state statp, int preinit) {
                    continue;
                }
                /* read nameservers to query */
-               if (MATCH(buf, "nameserver") && nserv < MAXNS) {
+               if (MATCH(buf, "nameserver") && nserv < maxns) {
                    struct addrinfo hints, *ai;
                    char sbuf[NI_MAXSERV];
                    const size_t minsiz =
@@ -482,16 +498,7 @@ __res_vinit(res_state statp, int preinit) {
        if ((cp = getenv("RES_OPTIONS")) != NULL)
                res_setoptions(statp, cp, "env");
        statp->options |= RES_INIT;
-       return (0);
-
-#ifdef SOLARIS2
- freedata:
-       if (statp->_u._ext.ext != NULL) {
-               free(statp->_u._ext.ext);
-               statp->_u._ext.ext = NULL;
-       }
-       return (-1);
-#endif
+       return (h_errno);
 }
 
 static void