diff --git a/CHANGES b/CHANGES index db01d74e22..523cc98b74 100644 --- 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] diff --git a/lib/bind/resolv/res_init.c b/lib/bind/resolv/res_init.c index fd82e87203..5424e4f139 100644 --- a/lib/bind/resolv/res_init.c +++ b/lib/bind/resolv/res_init.c @@ -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.5.4.6 2006/08/30 23:23:01 marka Exp $"; +static const char rcsid[] = "$Id: res_init.c,v 1.9.2.5.4.7 2006/12/11 04:46:54 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