diff options
Diffstat (limited to 'contrib/bind/lib/irs')
-rw-r--r-- | contrib/bind/lib/irs/dns_gr.c | 4 | ||||
-rw-r--r-- | contrib/bind/lib/irs/dns_ho.c | 598 | ||||
-rw-r--r-- | contrib/bind/lib/irs/dns_nw.c | 21 | ||||
-rw-r--r-- | contrib/bind/lib/irs/gen_gr.c | 17 | ||||
-rw-r--r-- | contrib/bind/lib/irs/getaddrinfo.c | 63 | ||||
-rw-r--r-- | contrib/bind/lib/irs/gethostent.c | 59 | ||||
-rw-r--r-- | contrib/bind/lib/irs/getnameinfo.c | 1 | ||||
-rw-r--r-- | contrib/bind/lib/irs/getnetgrent.c | 27 | ||||
-rw-r--r-- | contrib/bind/lib/irs/getnetgrent_r.c | 14 | ||||
-rw-r--r-- | contrib/bind/lib/irs/hesiod.c | 26 | ||||
-rw-r--r-- | contrib/bind/lib/irs/irp_p.h | 4 | ||||
-rw-r--r-- | contrib/bind/lib/irs/irs_data.c | 25 | ||||
-rw-r--r-- | contrib/bind/lib/irs/nis_gr.c | 4 | ||||
-rw-r--r-- | contrib/bind/lib/irs/nis_ho.c | 107 |
14 files changed, 325 insertions, 645 deletions
diff --git a/contrib/bind/lib/irs/dns_gr.c b/contrib/bind/lib/irs/dns_gr.c index a622345..b314f11 100644 --- a/contrib/bind/lib/irs/dns_gr.c +++ b/contrib/bind/lib/irs/dns_gr.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: dns_gr.c,v 1.20 2001/05/29 05:48:27 marka Exp $"; +static const char rcsid[] = "$Id: dns_gr.c,v 1.21 2002/07/08 06:26:09 marka Exp $"; #endif /* @@ -226,7 +226,7 @@ get_hes_group(struct irs_gr *this, const char *name, const char *type) { goto cleanup; *cp++ = '\0'; - errno = -1; + errno = 0; t = strtoul(cp, NULL, 10); if (errno == ERANGE) goto cleanup; diff --git a/contrib/bind/lib/irs/dns_ho.c b/contrib/bind/lib/irs/dns_ho.c index 6c0a6e7..1b37e3d 100644 --- a/contrib/bind/lib/irs/dns_ho.c +++ b/contrib/bind/lib/irs/dns_ho.c @@ -52,7 +52,7 @@ /* BIND Id: gethnamaddr.c,v 8.15 1996/05/22 04:56:30 vixie Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: dns_ho.c,v 1.39 2002/06/27 03:56:32 marka Exp $"; +static const char rcsid[] = "$Id: dns_ho.c,v 1.42.6.1 2003/06/02 09:24:40 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports. */ @@ -95,7 +95,7 @@ static const char rcsid[] = "$Id: dns_ho.c,v 1.39 2002/06/27 03:56:32 marka Exp #define MAXALIASES 35 #define MAXADDRS 35 -#define MAXPACKET (1024*64) +#define MAXPACKET (65535) /* Maximum TCP message size */ #define BOUNDS_CHECK(ptr, count) \ if ((ptr) + (count) > eom) { \ @@ -172,15 +172,6 @@ static struct hostent * gethostans(struct irs_ho *this, const struct addrinfo *pai); static int add_hostent(struct pvt *pvt, char *bp, char **hap, struct addrinfo *ai); -static const u_char * ar_head(const u_char *, int, const u_char *, - const u_char *, struct pvt *, - int (*)(const char *)); -static struct addrinfo * a6_expand(const u_char *, const u_char *, int, - const u_char *, const u_char *, - const struct in6_addr *, int, - const struct addrinfo *, - struct pvt *, int (*)(const char *), int *); -static const char *dname_subst(const char *, const char *, const char *); static int init(struct irs_ho *this); /* Exports. */ @@ -257,21 +248,19 @@ ho_byname2(struct irs_ho *this, const char *name, int af) char tmp[NS_MAXDNAME]; const char *cp; struct addrinfo ai; - struct dns_res_target *q, *q2, *p; + struct dns_res_target *q, *p; int querystate = RESQRY_FAIL; if (init(this) == -1) return (NULL); q = memget(sizeof(*q)); - q2 = memget(sizeof(*q2)); - if (q == NULL || q2 == NULL) { + if (q == NULL) { RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); errno = ENOMEM; goto cleanup; } memset(q, 0, sizeof(q)); - memset(q2, 0, sizeof(q2)); switch (af) { case AF_INET: @@ -285,21 +274,10 @@ ho_byname2(struct irs_ho *this, const char *name, int af) case AF_INET6: size = IN6ADDRSZ; q->qclass = C_IN; - q->qtype = ns_t_a6; + q->qtype = T_AAAA; q->answer = q->qbuf.buf; q->anslen = sizeof(q->qbuf); - q->next = q2; -#ifdef RES_USE_A6 - if ((pvt->res->options & RES_USE_A6) == 0) - q->action = RESTGT_IGNORE; - else -#endif - q->action = RESTGT_DOALWAYS; - q2->qclass = C_IN; - q2->qtype = T_AAAA; - q2->answer = q2->qbuf.buf; - q2->anslen = sizeof(q2->qbuf); - q2->action = RESTGT_AFTERFAILURE; + q->action = RESTGT_DOALWAYS; break; default: RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); @@ -349,8 +327,6 @@ ho_byname2(struct irs_ho *this, const char *name, int af) cleanup: if (q != NULL) memput(q, sizeof(*q)); - if (q2 != NULL) - memput(q2, sizeof(*q2)); return(hp); } @@ -363,7 +339,7 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) struct hostent *hp = NULL; struct addrinfo ai; struct dns_res_target *q, *q2, *p; - int n, size; + int n, size, i; int querystate = RESQRY_FAIL; if (init(this) == -1) @@ -440,20 +416,36 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) if (q->action != RESTGT_IGNORE) { qp = q->qname; for (n = IN6ADDRSZ - 1; n >= 0; n--) { - qp += SPRINTF((qp, "%x.%x.", + i = SPRINTF((qp, "%x.%x.", uaddr[n] & 0xf, (uaddr[n] >> 4) & 0xf)); + if (i < 0) + abort(); + qp += i; } +#ifdef HAVE_STRLCAT + strlcat(q->qname, res_get_nibblesuffix(pvt->res), + sizeof(q->qname)); +#else strcpy(qp, res_get_nibblesuffix(pvt->res)); +#endif } if (q2->action != RESTGT_IGNORE) { qp = q2->qname; for (n = IN6ADDRSZ - 1; n >= 0; n--) { - qp += SPRINTF((qp, "%x.%x.", + i = SPRINTF((qp, "%x.%x.", uaddr[n] & 0xf, (uaddr[n] >> 4) & 0xf)); + if (i < 0) + abort(); + qp += i; } +#ifdef HAVE_STRLCAT + strlcat(q->qname, res_get_nibblesuffix2(pvt->res), + sizeof(q->qname)); +#else strcpy(qp, res_get_nibblesuffix2(pvt->res)); +#endif } break; default: @@ -563,7 +555,7 @@ ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai) int n; char tmp[NS_MAXDNAME]; const char *cp; - struct dns_res_target *q, *q2, *q3, *p; + struct dns_res_target *q, *q2, *p; struct addrinfo sentinel, *cur; int querystate = RESQRY_FAIL; @@ -575,42 +567,28 @@ ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai) q = memget(sizeof(*q)); q2 = memget(sizeof(*q2)); - q3 = memget(sizeof(*q3)); - if (q == NULL || q2 == NULL || q3 == NULL) { + if (q == NULL || q2 == NULL) { RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); errno = ENOMEM; goto cleanup; } memset(q, 0, sizeof(q2)); memset(q2, 0, sizeof(q2)); - memset(q3, 0, sizeof(q3)); switch (pai->ai_family) { case AF_UNSPEC: /* prefer IPv6 */ q->qclass = C_IN; - q->qtype = ns_t_a6; + q->qtype = T_AAAA; q->answer = q->qbuf.buf; q->anslen = sizeof(q->qbuf); q->next = q2; -#ifdef RES_USE_A6 - if ((pvt->res->options & RES_USE_A6) == 0) - q->action = RESTGT_IGNORE; - else -#endif - q->action = RESTGT_DOALWAYS; + q->action = RESTGT_DOALWAYS; q2->qclass = C_IN; - q2->qtype = T_AAAA; + q2->qtype = T_A; q2->answer = q2->qbuf.buf; q2->anslen = sizeof(q2->qbuf); - q2->next = q3; - /* try AAAA only when A6 query fails */ - q2->action = RESTGT_AFTERFAILURE; - q3->qclass = C_IN; - q3->qtype = T_A; - q3->answer = q3->qbuf.buf; - q3->anslen = sizeof(q3->qbuf); - q3->action = RESTGT_DOALWAYS; + q2->action = RESTGT_DOALWAYS; break; case AF_INET: q->qclass = C_IN; @@ -621,21 +599,10 @@ ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai) break; case AF_INET6: q->qclass = C_IN; - q->qtype = ns_t_a6; + q->qtype = T_AAAA; q->answer = q->qbuf.buf; q->anslen = sizeof(q->qbuf); - q->next = q2; -#ifdef RES_USE_A6 - if ((pvt->res->options & RES_USE_A6) == 0) - q->action = RESTGT_IGNORE; - else -#endif - q->action = RESTGT_DOALWAYS; - q2->qclass = C_IN; - q2->qtype = T_AAAA; - q2->answer = q2->qbuf.buf; - q2->anslen = sizeof(q2->qbuf); - q2->action = RESTGT_AFTERFAILURE; + q->action = RESTGT_DOALWAYS; break; default: RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); /* better error? */ @@ -688,375 +655,9 @@ ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai) memput(q, sizeof(*q)); if (q2 != NULL) memput(q2, sizeof(*q2)); - if (q3 != NULL) - memput(q3, sizeof(*q3)); return(sentinel.ai_next); } -static const u_char * -ar_head(cp, count, msg, eom, pvt, name_ok) - const u_char *cp, *msg, *eom; - int count; - struct pvt *pvt; - int (*name_ok)(const char *); -{ - int n; - char buf[1024]; /* XXX */ - - while (count-- > 0 && cp < eom) { - n = dn_expand(msg, eom, cp, buf, sizeof(buf)); - if (n < 0 || !maybe_ok(pvt->res, buf, name_ok)) - goto end; - cp += n; /* name */ - if (cp + 3 * INT16SZ + INT32SZ >= eom) - goto end; - cp += INT16SZ; /* type */ - cp += INT16SZ + INT32SZ; /* class, TTL */ - n = ns_get16(cp); - cp += n + INT16SZ; /* len */ - } - return(cp); - - end: - return(eom); /* XXX */ -} - -/* XXX: too many arguments */ -static struct addrinfo * -a6_expand(const u_char *ansbuf, const u_char *a6p, - int a6len, const u_char *arp, const u_char *eom, - const struct in6_addr *in6, int plen, const struct addrinfo *pai, - struct pvt *pvt, int (*name_ok)(const char *), int *errorp) -{ - struct in6_addr a; - int n, pbyte, plen1, pbyte1, error = 0; - const u_char *cp; - struct addrinfo sentinel, *cur; - char pname[1024], buf[1024]; /* XXX */ - - *errorp = NETDB_SUCCESS; - memset(&sentinel, 0, sizeof(sentinel)); - cur = &sentinel; - - /* - * Validate A6 parameters. - */ - if (a6len == 0) { /* an A6 record must contain at least 1 byte. */ - error = NO_RECOVERY; - goto bad; - } - /* prefix length check. */ - if ((plen1 = *a6p) > 128) { - error = NO_RECOVERY; - goto bad; - } - if (plen1 > plen) { - /* - * New length must not be greater than old one. - * Ignore the record as specified in RFC 2874 - * Section 3.1.2. - */ - return(NULL); /* just ignore. */ - } - /* boundary check for new plen and prefix addr */ - pbyte1 = (plen1 & ~7) / 8; - if ((int)sizeof(struct in6_addr) - pbyte1 > a6len - 1) { - error = NO_RECOVERY; - goto bad; - } - - /* - * merge the new prefix portion. - * <--- plen(bits) ---> - * <--- pbyte ---><-b-> - * 000000000000000pppppxxxxxxxxxxx(= in6, 0: unknown, x: known, p: pad) - * PP++++++++(+ should be merged. P: padding, must be 0) - * <-- plen1--> - * <-pbyte1-> - * ^a6p+1 - * The result should be: - * 0000000000PP++++++++xxxxxxxxxxx(= a) - */ - pbyte = (plen & ~7) / 8; - a = *in6; - if (pbyte > pbyte1) { - /* N.B. the case of "pbyte1 == 128" is implicitly excluded. */ - int b = plen % 8; /* = the length of "pp..." above */ - u_char c_hi, c_lo; - - memcpy(&a.s6_addr[pbyte1], a6p + 1, pbyte - pbyte1); - if (b > 0) { - c_hi = a6p[pbyte - pbyte1 + 1]; - c_lo = in6->s6_addr[pbyte]; - a.s6_addr[pbyte] = - (c_hi & (0xff << (8 - b))) | - ((0x00ff >> b) & c_lo); - } - } - -#if 0 /* for debug */ - if ((pvt->res->options & RES_DEBUG) != 0) { - u_char ntopbuf[INET6_ADDRSTRLEN]; - - inet_ntop(AF_INET6, &a, ntopbuf, sizeof(ntopbuf)); - printf("a6_expand: %s\\%d\n", ntopbuf, plen1); - } -#endif - - if (plen1 == 0) { - /* Here is the end of A6 chain. make addrinfo, then return. */ - return(addr2addrinfo(pai, (const char *)&a)); - } - - /* - * Expand the new prefix name. Since the prefix name must not be - * compressed (RFC 2874 Section 3.1.1), we could use ns_name_ntop() - * here if it had a stricter boundary check. - */ - cp = a6p + 1 + (sizeof(*in6) - pbyte1); - n = dn_expand(ansbuf, eom, cp, pname, sizeof(pname)); - if (n < 0 || !maybe_ok(pvt->res, pname, name_ok)) { - error = NO_RECOVERY; - goto bad; - } - if (cp + n != a6p + a6len) { /* length mismatch */ - error = NO_RECOVERY; - goto bad; - } - - /* - * we need (more) additional section records, but no one is - * available, which possibly means a malformed answer. - */ - if (arp == NULL) { - error = NO_RECOVERY; /* we can't resolve the chain. */ - goto bad; - } - - /* - * Loop thru the rest of the buffer, searching for the next A6 record - * that has the same owner name as the prefix name. If found, then - * recursively call this function to expand the whole A6 chain. - */ - plen = plen1; - for (cp = arp; cp != NULL && cp < eom; cp += n) { - int class, type; - - n = dn_expand(ansbuf, eom, cp, buf, sizeof(buf)); - if (n < 0 || !maybe_ok(pvt->res, buf, name_ok)) { - error = NO_RECOVERY; - goto bad; - } - cp += n; /* name */ - if (cp + 3 * INT16SZ + INT32SZ > eom) { - error = NO_RECOVERY; - goto bad; - } - type = ns_get16(cp); - cp += INT16SZ; /* type */ - class = ns_get16(cp); - cp += INT16SZ + INT32SZ; /* class, TTL */ - n = ns_get16(cp); - cp += INT16SZ; /* len */ - if (cp + n > eom) { - error = NO_RECOVERY; - goto bad; - } - if (class != C_IN || type != ns_t_a6) { - /* we are only interested in A6 records. skip others */ - continue; - } - - if (ns_samename(buf, pname) != 1) { - continue; - } - - /* Proceed to the next record in the chain. */ - cur->ai_next = a6_expand(ansbuf, cp, n, cp + n, eom, - (const struct in6_addr *)&a, - plen, pai, pvt, name_ok, &error); - if (error != NETDB_SUCCESS) - goto bad; - while (cur && cur->ai_next) - cur = cur->ai_next; - } - - return(sentinel.ai_next); - - bad: - *errorp = error; - if (sentinel.ai_next) - freeaddrinfo(sentinel.ai_next); - return(NULL); -} - -static const char * -dname_subst(const char *qname0, const char *owner0, const char *target) { - char owner[MAXDNAME]; - static char qname[MAXDNAME]; - const char blabelhead[] = "\\[x"; /* we can assume hex strings */ - int qlen, olen; - int bufsiz = sizeof(qname); - - /* make local copies, which are canonicalized. */ - if (ns_makecanon(qname0, qname, sizeof(qname)) < 0 || - ns_makecanon(owner0, owner, sizeof(owner)) < 0) - return(NULL); - qlen = strlen(qname); - olen = strlen(owner); - /* from now on, do not refer to qname0 nor owner0. */ - - /* - * check if QNAME is a subdomain of OWNER. - * XXX: currently, we only handle the following two cases: - * (A) none of the labels are bitlabels, or - * (B) both of the head labels are bitlabels (and the following - * labels are NOT bitlabels). - * If we pass the check, then subtract the remaining part from QNAME. - * ex. (A) qname=www.foo.com,owner=foo.com => new qname=www. - * (B) qname=\[x3ffe0501/32].foo.com,owner=\[x3ffe/16].foo.com - * => new qname=\[x0501/16]. - */ - if (ns_samedomain(qname, owner)) { /* check (A) */ - /* at this point, qlen must not be smaller than olen */ - qname[qlen - olen] = 0; - bufsiz -= (qlen - olen); - } else { /* check (B) */ - char *parent0, *parent1; - /* the following 3 have enough size to store 1 bitlabel */ - u_char qlabel[64], olabel[64], newlabel[64]; - int qlabellen, olabellen; - - if (strncmp(qname, blabelhead, 3) != 0 || - strncmp(owner, blabelhead, 3) != 0) - return(NULL); - /* - * Both two begin with bitlabels. The succeeding parts - * must exact match. - */ - if ((parent0 = strchr(qname, '.')) == NULL || - (parent1 = strchr(owner, '.')) == NULL) - return(NULL); - - /* ns_samename allows names to begin with '.' */ - if (ns_samename(parent0, parent1) != 1) - return(NULL); - - /* cut the upper domain parts off. */ - *(parent0 + 1) = 0; - *(parent1 + 1) = 0; - /* convert the textual form into binary one. */ - if (ns_name_pton(qname, qlabel, sizeof(qlabel)) < 0 || - ns_name_pton(owner, olabel, sizeof(olabel)) < 0) - return(NULL); - if ((qlabellen = *(qlabel + 1)) == 0) - qlabellen = 256; - if ((olabellen = *(olabel + 1)) == 0) - olabellen = 256; - if (olabellen > qlabellen) - return(NULL); /* owner does not contain qname. */ - else { - int qplen = (qlabellen + 7) / 8; - int oplen = (olabellen + 7) / 8; - int sft = olabellen % 8; - int nllen, n; - u_char *qp, *op, *np; - - /* skip ELT and Count. */ - qp = qlabel + 2; - op = olabel + 2; - - /* check if olabel is a "subdomain" of qlabel. */ - if (memcmp(qp, op, oplen - 1) != 0) - return(NULL); - if (sft > 0) { - /* compare trailing bits (between 1 and 7) */ - if ((qp[qplen - 1] & (0xff << sft)) != - op[qplen - 1]) - return(NULL); - } - - /* OK, get remaining bits from qlabel. */ - np = newlabel; - if (olabellen == qlabellen) { - /* - * Two names (including bitlabels) are exactly - * same. Discard the whole names. - * XXX: ns_samename() above should exclude - * this case... - */ - qname[0] = 0; - goto maketarget; - } - *np++ = 0x41; /* XXX hardcoding */ - *np++ = nllen = (qlabellen - olabellen); - if (sft == 0) { - /* - * No alignment issue. can just use memcpy. - * Note that the "else" part below contains - * this case. We separate the two cases just - * for efficiency. - * We assume that ns_name_pton above ensures - * QP does not contain trailing garbages. - */ - memcpy(np, qp + oplen, qplen - oplen); - np += qplen - oplen; - *np = 0; - } else { - /* - * copy the lower (8-SFT) bits of QP to the - * upper (8-SFT) bits of NP, then copy the - * upper SFT bits of QP+1 to the lower SFT bits - * of NP, and so on... - * if QP is xxxyyyyy zzzwww..., then - * NP would be yyyyyzzz ... - * Again, we assume QP does not contain - * trailing garbages. - */ - qp += (oplen - 1); - while (nllen > 0) { - *np = (*qp << sft) & 0xff; - if ((nllen -= (8 - sft)) <= 0) - break; /* done */ - qp++; - *np |= ((*qp >> sft) & 0xff); - np++; - nllen -= sft; - } - *++np = 0; - } - - /* - * make a new bitlabel with the remaining bits. - * Note that there's no buffer boundary issue, since - * qlabel, olabel, and newlabel all have the same size. - * ns_name_ntop() must not return 0, since we have - * a non-empty bitlabel. - */ - if ((n = ns_name_ntop(newlabel, qname, sizeof(qname))) - <= 0) - return(NULL); - bufsiz -= n; - if (qname[n - 1] != '.') { /* XXX no trailing dot */ - qname[n - 1] = '.'; - qname[n] = 0; - bufsiz--; - } - - } - } - - maketarget: - /* - * Finally, append the remaining part (maybe empty) to the new target. - */ - if (bufsiz < (int)strlen(target)) /* bufsiz takes care of the \0. */ - return(NULL); - strcat(qname, target); - - return((const char *)qname); -} - static void ho_res_set(struct irs_ho *this, struct __res_state *res, void (*free_res)(void *)) { @@ -1092,7 +693,6 @@ gethostans(struct irs_ho *this, char *bp, *ep, **ap, **hap; char tbuf[MAXDNAME+1]; struct addrinfo sentinel, *cur, ai; - const u_char *arp = NULL; if (pai == NULL) abort(); if (ret_aip != NULL) @@ -1103,7 +703,6 @@ gethostans(struct irs_ho *this, tname = qname; eom = ansbuf + anslen; switch (qtype) { - case ns_t_a6: case T_A: case T_AAAA: case T_ANY: /* use T_ANY only for T_A/T_AAAA lookup */ @@ -1148,8 +747,7 @@ gethostans(struct irs_ho *this, RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); return (NULL); } - if (qtype == T_A || qtype == T_AAAA || - qtype == ns_t_a6 || qtype == T_ANY) { + if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) { /* res_nsend() has already verified that the query name is the * same as the one we sent; this just gets the expanded name * (i.e., with the succeeding search-domain tacked on). @@ -1193,8 +791,8 @@ gethostans(struct irs_ho *this, continue; } eor = cp + n; - if ((qtype == T_A || qtype == T_AAAA || qtype == ns_t_a6 || - qtype == T_ANY) && type == T_CNAME) { + if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) && + type == T_CNAME) { if (haveanswer) { int level = LOG_CRIT; #ifdef LOG_SECURITY @@ -1222,58 +820,16 @@ gethostans(struct irs_ho *this, had_error++; continue; } +#ifdef HAVE_STRLCPY + strlcpy(bp, tbuf, ep - bp); +#else strcpy(bp, tbuf); +#endif pvt->host.h_name = bp; hname = bp; bp += n; continue; } - if (type == ns_t_dname) { - const char *t0, *t; - - /* - * just replace the query target; do not update the - * alias list. (Or should we?) - */ - t0 = (qtype == T_PTR) ? tname : hname; - - n = dn_expand(ansbuf, eor, cp, tbuf, sizeof(tbuf)); - if (n < 0 || !maybe_dnok(pvt->res, tbuf)) { - had_error++; - continue; - } -#ifdef RES_USE_DNAME - if ((pvt ->res->options & RES_USE_DNAME) == 0) { - cp += n; - continue; - } -#endif - if ((t = dname_subst(t0, bp, tbuf)) == NULL) { - cp += n; - continue; - } -#if 0 /* for debug */ - if ((pvt->res->options & RES_DEBUG) != 0) { - printf("DNAME owner=%s, target=%s, next=%s\n", - bp, tbuf, t); - } -#endif - cp += n; - - n = strlen(t) + 1; /* for the \0 */ - if (n > (ep - bp)) { - had_error++; - continue; - } - strcpy(bp, t); - if (qtype == T_PTR) - tname = bp; - else - hname = bp; - bp += n; - - continue; - } if (qtype == T_PTR && type == T_CNAME) { n = dn_expand(ansbuf, eor, cp, tbuf, sizeof tbuf); if (n < 0 || !maybe_dnok(pvt->res, tbuf)) { @@ -1300,14 +856,17 @@ gethostans(struct irs_ho *this, had_error++; continue; } +#ifdef HAVE_STRLCPY + strlcpy(bp, tbuf, ep - bp); +#else strcpy(bp, tbuf); +#endif tname = bp; bp += n; continue; } if (qtype == T_ANY) { - if (!(type == T_A || type == T_AAAA || - type == ns_t_a6)) { + if (!(type == T_A || type == T_AAAA)) { cp += n; continue; } @@ -1346,66 +905,6 @@ gethostans(struct irs_ho *this, bp += n; } break; - case ns_t_a6: { - struct in6_addr in6; - struct addrinfo ai; - -#ifdef RES_USE_A6 - if ((pvt->res->options & RES_USE_A6) == 0) { - cp += n; - continue; - } -#endif - - if (ns_samename(hname, bp) != 1) { - cp += n; - continue; - } - - /* - * search for the top of the additional section. - * once found, keep it for the case where we have - * more than one A6 record. - * XXX: however, we may not need this part. - */ - if (arp == NULL && arcount > 0) { - int nscount = ntohs(hp->nscount); - - arp = ar_head(cp + n, nscount + ancount - 1, - ansbuf, eom, pvt, name_ok); - } - - /* recursively collect the whole A6 chain */ - ai = *pai; /* XXX: we can't override constant pai */ - ai.ai_family = AF_INET6; - memset(&in6, 0, sizeof(in6)); /* just for safety */ - cur->ai_next = a6_expand(ansbuf, cp, n, arp, eom, - &in6, 128, - (const struct addrinfo *)&ai, - pvt, name_ok, &error); - if (error != NETDB_SUCCESS) { -#ifdef DEBUG - /* in this case, cur->ai_next must be NULL. */ - if (cur->ai_next != NULL) - abort(); -#endif - had_error++; - continue; - } - - /* - * We don't bother even if cur->ai_next is NULL unless - * the expansion failed by a fatal error. The list - * can be NULL if the given A6 is incomplete, but we - * may have another complete A6 chain in this answer. - * See the last paragraph of RFC 2874 Section 3.1.4. - */ - if (cur->ai_next == NULL) { - cp += n; - continue; /* no error, no answer */ - } - goto convertinfo; - } /* FALLTHROUGH */ case T_A: case T_AAAA: if (ns_samename(hname, bp) != 1) { @@ -1430,7 +929,6 @@ gethostans(struct irs_ho *this, if (cur->ai_next == NULL) had_error++; - convertinfo: /* convert addrinfo into hostent form */ if (!haveanswer) { int nn; @@ -1471,7 +969,7 @@ gethostans(struct irs_ho *this, continue; if (hap < &pvt->h_addr_ptrs[MAXADDRS-1]) hap++; - + *hap = NULL; bp += m; } @@ -1498,7 +996,11 @@ gethostans(struct irs_ho *this, n = strlen(qname) + 1; /* for the \0 */ if (n > (ep - bp) || n >= MAXHOSTNAMELEN) goto no_recovery; +#ifdef HAVE_STRLCPY + strlcpy(bp, qname, ep - bp); +#else strcpy(bp, qname); +#endif pvt->host.h_name = bp; bp += n; } diff --git a/contrib/bind/lib/irs/dns_nw.c b/contrib/bind/lib/irs/dns_nw.c index f39a59a..a322f449 100644 --- a/contrib/bind/lib/irs/dns_nw.c +++ b/contrib/bind/lib/irs/dns_nw.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: dns_nw.c,v 1.23 2002/06/26 07:42:06 marka Exp $"; +static const char rcsid[] = "$Id: dns_nw.c,v 1.25 2002/07/18 02:07:43 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports. */ @@ -349,7 +349,12 @@ get1101answer(struct irs_nw *this, RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); return (NULL); } +#ifdef HAVE_STRLCPY + strlcpy(bp, name, ep - bp); + pvt->net.n_name = bp; +#else pvt->net.n_name = strcpy(bp, name); +#endif bp += n; } break; @@ -522,37 +527,37 @@ get1101mask(struct irs_nw *this, struct nwent *nwent) { static int make1101inaddr(const u_char *net, int bits, char *name, int size) { int n, m; + char *ep; + + ep = name + size; /* Zero fill any whole bytes left out of the prefix. */ for (n = (32 - bits) / 8; n > 0; n--) { - if (size < (int)(sizeof "0.")) + if (ep - name < (int)(sizeof "0.")) goto emsgsize; m = SPRINTF((name, "0.")); name += m; - size -= m; } /* Format the partial byte, if any, within the prefix. */ if ((n = bits % 8) != 0) { - if (size < (int)(sizeof "255.")) + if (ep - name < (int)(sizeof "255.")) goto emsgsize; m = SPRINTF((name, "%u.", net[bits / 8] & ~((1 << (8 - n)) - 1))); name += m; - size -= m; } /* Format the whole bytes within the prefix. */ for (n = bits / 8; n > 0; n--) { - if (size < (int)(sizeof "255.")) + if (ep - name < (int)(sizeof "255.")) goto emsgsize; m = SPRINTF((name, "%u.", net[n - 1])); name += m; - size -= m; } /* Add the static text. */ - if (size < (int)(sizeof "in-addr.arpa")) + if (ep - name < (int)(sizeof "in-addr.arpa")) goto emsgsize; (void) SPRINTF((name, "in-addr.arpa")); return (0); diff --git a/contrib/bind/lib/irs/gen_gr.c b/contrib/bind/lib/irs/gen_gr.c index 4b1b282..9a7af3d 100644 --- a/contrib/bind/lib/irs/gen_gr.c +++ b/contrib/bind/lib/irs/gen_gr.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: gen_gr.c,v 1.25 2001/06/07 02:12:26 marka Exp $"; +static const char rcsid[] = "$Id: gen_gr.c,v 1.26 2002/07/18 02:07:44 marka Exp $"; #endif /* Imports */ @@ -324,7 +324,7 @@ gr_res_set(struct irs_gr *this, struct __res_state *res, static void grmerge(struct irs_gr *this, const struct group *src, int preserve) { struct pvt *pvt = (struct pvt *)this->private; - char *cp, **m, **p, *oldmembuf; + char *cp, **m, **p, *oldmembuf, *ep; int n, ndst, nnew; size_t used; @@ -379,6 +379,7 @@ grmerge(struct irs_gr *this, const struct group *src, int preserve) { /* No harm done, no work done. */ return; } + ep = cp + used + n; if (used != 0) memcpy(cp, pvt->membuf, used); oldmembuf = pvt->membuf; @@ -400,7 +401,11 @@ grmerge(struct irs_gr *this, const struct group *src, int preserve) { if (isnew(pvt->group.gr_mem, *m)) { *p++ = cp; *p = NULL; +#ifdef HAVE_STRLCPY + strlcpy(cp, *m, ep - cp); +#else strcpy(cp, *m); +#endif cp += strlen(cp) + 1; } if (preserve) { @@ -410,10 +415,18 @@ grmerge(struct irs_gr *this, const struct group *src, int preserve) { (pvt->group.gr_passwd - oldmembuf); } else { pvt->group.gr_name = cp; +#ifdef HAVE_STRLCPY + strlcpy(cp, src->gr_name, ep - cp); +#else strcpy(cp, src->gr_name); +#endif cp += strlen(src->gr_name) + 1; pvt->group.gr_passwd = cp; +#ifdef HAVE_STRLCPY + strlcpy(cp, src->gr_passwd, ep - cp); +#else strcpy(cp, src->gr_passwd); +#endif cp += strlen(src->gr_passwd) + 1; } if (oldmembuf != NULL) diff --git a/contrib/bind/lib/irs/getaddrinfo.c b/contrib/bind/lib/irs/getaddrinfo.c index 243f106..89db519 100644 --- a/contrib/bind/lib/irs/getaddrinfo.c +++ b/contrib/bind/lib/irs/getaddrinfo.c @@ -101,17 +101,12 @@ #include <stdarg.h> #include <irs.h> +#include <isc/assertions.h> #include "port_after.h" #include "irs_data.h" -/* - * if we enable it, we will see duplicated addrinfo entries on reply if both - * AAAA and A6 records are found. disable it for default installation. - */ -#undef T_A6 - #define SUCCESS 0 #define ANY 0 #define YES 1 @@ -192,7 +187,8 @@ static int get_portmatch __P((const struct addrinfo *, const char *)); static int get_port __P((const struct addrinfo *, const char *, int)); static const struct afd *find_afd __P((int)); static int addrconfig __P((int)); -static int ip6_str2scopeid __P((char *, struct sockaddr_in6 *)); +static int ip6_str2scopeid __P((char *, struct sockaddr_in6 *, + u_int32_t *scopeidp)); static struct net_data *init __P((void)); struct addrinfo *hostent2addrinfo __P((struct hostent *, @@ -297,8 +293,9 @@ str_isnumber(p) if (*p == '\0') return NO; ep = NULL; + errno = 0; (void)strtoul(p, &ep, 10); - if (ep && *ep == '\0') + if (errno == 0 && ep && *ep == '\0') return YES; else return NO; @@ -595,7 +592,7 @@ explore_fqdn(pai, hostname, servname, res) char tmp[NS_MAXDNAME]; const char *cp; - result = NULL; + INSIST(res != NULL && *res == NULL); /* * if the servname does not match socktype/protocol, ignore it. @@ -854,13 +851,13 @@ explore_numeric_scope(pai, hostname, servname, res) error = explore_numeric(pai, addr, servname, res); if (error == 0) { - int scopeid; + u_int32_t scopeid = 0; for (cur = *res; cur; cur = cur->ai_next) { if (cur->ai_family != AF_INET6) continue; sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr; - if ((scopeid = ip6_str2scopeid(scope, sin6)) == -1) { + if (!ip6_str2scopeid(scope, sin6, &scopeid)) { free(hostname2); return(EAI_NONAME); /* XXX: is return OK? */ } @@ -990,7 +987,17 @@ get_port(const struct addrinfo *ai, const char *servname, int matchonly) { allownumeric = 1; break; case ANY: - allownumeric = 0; + switch (ai->ai_family) { + case AF_INET: +#ifdef AF_INET6 + case AF_INET6: +#endif + allownumeric = 1; + break; + default: + allownumeric = 0; + break; + } break; default: return EAI_SOCKTYPE; @@ -999,9 +1006,10 @@ get_port(const struct addrinfo *ai, const char *servname, int matchonly) { if (str_isnumber(servname)) { if (!allownumeric) return EAI_SERVICE; - port = htons(atoi(servname)); + port = atoi(servname); if (port < 0 || port > 65535) return EAI_SERVICE; + port = htons(port); } else { switch (ai->ai_socktype) { case SOCK_DGRAM: @@ -1075,17 +1083,17 @@ addrconfig(af) /* convert a string to a scope identifier. XXX: IPv6 specific */ static int -ip6_str2scopeid(scope, sin6) - char *scope; - struct sockaddr_in6 *sin6; +ip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6, + u_int32_t *scopeidp) { - int scopeid; + u_int32_t scopeid; + u_long lscopeid; struct in6_addr *a6 = &sin6->sin6_addr; char *ep; - + /* empty scopeid portion is invalid */ if (*scope == '\0') - return -1; + return (0); #ifdef USE_IFNAMELINKID if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) { @@ -1096,8 +1104,8 @@ ip6_str2scopeid(scope, sin6) */ scopeid = if_nametoindex(scope); if (scopeid == 0) - goto trynumeric; - return(scopeid); + *scopeidp = scopeid; + return (1); } #endif @@ -1111,11 +1119,14 @@ ip6_str2scopeid(scope, sin6) /* try to convert to a numeric id as a last resort */ trynumeric: - scopeid = (int)strtoul(scope, &ep, 10); - if (*ep == '\0') - return scopeid; - else - return -1; + errno = 0; + lscopeid = strtoul(scope, &ep, 10); + scopeid = lscopeid & 0xffffffff; + if (errno == 0 && ep && *ep == '\0' && scopeid == lscopeid) { + *scopeidp = scopeid; + return (1); + } else + return (0); } struct addrinfo * diff --git a/contrib/bind/lib/irs/gethostent.c b/contrib/bind/lib/irs/gethostent.c index 8e7e717..3964b5f 100644 --- a/contrib/bind/lib/irs/gethostent.c +++ b/contrib/bind/lib/irs/gethostent.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: gethostent.c,v 1.32 2002/05/27 06:50:55 marka Exp $"; +static const char rcsid[] = "$Id: gethostent.c,v 1.32.10.2 2003/06/04 01:09:43 marka Exp $"; #endif /* Imports */ @@ -482,7 +482,7 @@ freehostent(struct hostent *he) { #define LIFREQ lifreq #endif -static int +static void scan_interfaces6(int *have_v4, int *have_v6) { struct LIFCONF lifc; struct LIFREQ lifreq; @@ -492,12 +492,9 @@ scan_interfaces6(int *have_v4, int *have_v6) { static unsigned int bufsiz = 4095; int s, cpsize, n; - /* Set to zero. Used as loop terminators below. */ - *have_v4 = *have_v6 = 0; - /* Get interface list from system. */ if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) == -1) - goto err_ret; + goto cleanup; /* * Grow buffer until large enough to contain all interface @@ -506,7 +503,7 @@ scan_interfaces6(int *have_v4, int *have_v6) { for (;;) { buf = memget(bufsiz); if (buf == NULL) - goto err_ret; + goto cleanup; #ifdef SETFAMILYFLAGS lifc.lifc_family = AF_UNSPEC; /* request all families */ lifc.lifc_flags = 0; @@ -526,10 +523,10 @@ scan_interfaces6(int *have_v4, int *have_v6) { break; } if ((n == -1) && errno != EINVAL) - goto err_ret; + goto cleanup; if (bufsiz > 1000000) - goto err_ret; + goto cleanup; memput(buf, bufsiz); bufsiz += 4096; @@ -600,16 +597,42 @@ scan_interfaces6(int *have_v4, int *have_v6) { memput(buf, bufsiz); close(s); /* printf("scan interface -> 4=%d 6=%d\n", *have_v4, *have_v6); */ - return (0); - err_ret: + return; + cleanup: if (buf != NULL) memput(buf, bufsiz); if (s != -1) close(s); /* printf("scan interface -> 4=%d 6=%d\n", *have_v4, *have_v6); */ - return (-1); + return; } +#endif +#ifdef __linux +#ifndef IF_NAMESIZE +# ifdef IFNAMSIZ +# define IF_NAMESIZE IFNAMSIZ +# else +# define IF_NAMESIZE 16 +# endif +#endif +static void +scan_linux6(int *have_v6) { + FILE *proc = NULL; + char address[33]; + char name[IF_NAMESIZE+1]; + int ifindex, prefix, flag3, flag4; + + proc = fopen("/proc/net/if_inet6", "r"); + if (proc == NULL) + return; + + if (fscanf(proc, "%32[a-f0-9] %x %x %x %x %16s\n", + address, &ifindex, &prefix, &flag3, &flag4, name) == 6) + *have_v6 = 1; + fclose(proc); + return; +} #endif static int @@ -626,17 +649,21 @@ scan_interfaces(int *have_v4, int *have_v6) { int s, n; size_t cpsize; + /* Set to zero. Used as loop terminators below. */ + *have_v4 = *have_v6 = 0; + #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \ !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF) /* * Try to scan the interfaces using IPv6 ioctls(). */ - if (!scan_interfaces6(have_v4, have_v6)) + scan_interfaces6(have_v4, have_v6); + if (*have_v4 != 0 && *have_v6 != 0) return (0); #endif - - /* Set to zero. Used as loop terminators below. */ - *have_v4 = *have_v6 = 0; +#ifdef __linux + scan_linux6(have_v6); +#endif /* Get interface list from system. */ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) diff --git a/contrib/bind/lib/irs/getnameinfo.c b/contrib/bind/lib/irs/getnameinfo.c index 9b26c64..702b932 100644 --- a/contrib/bind/lib/irs/getnameinfo.c +++ b/contrib/bind/lib/irs/getnameinfo.c @@ -44,6 +44,7 @@ #include <netinet/in.h> #include <arpa/nameser.h> #include <arpa/inet.h> +#include <net/if.h> #include <netdb.h> #include <resolv.h> diff --git a/contrib/bind/lib/irs/getnetgrent.c b/contrib/bind/lib/irs/getnetgrent.c index e966ea6..9c13b01 100644 --- a/contrib/bind/lib/irs/getnetgrent.c +++ b/contrib/bind/lib/irs/getnetgrent.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: getnetgrent.c,v 1.15 2001/05/29 05:48:49 marka Exp $"; +static const char rcsid[] = "$Id: getnetgrent.c,v 1.16.6.1 2003/06/02 06:06:58 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports */ @@ -47,8 +47,11 @@ static struct net_data *init(void); /* Public */ +#ifndef SETNETGRENT_ARGS +#define SETNETGRENT_ARGS const char *netgroup +#endif void -setnetgrent(const char *netgroup) { +setnetgrent(SETNETGRENT_ARGS) { struct net_data *net_data = init(); setnetgrent_p(netgroup, net_data); @@ -61,19 +64,31 @@ endnetgrent(void) { endnetgrent_p(net_data); } +#ifndef INNETGR_ARGS +#define INNETGR_ARGS const char *netgroup, const char *host, \ + const char *user, const char *domain +#endif int -innetgr(const char *netgroup, const char *host, - const char *user, const char *domain) { +innetgr(INNETGR_ARGS) { struct net_data *net_data = init(); return (innetgr_p(netgroup, host, user, domain, net_data)); } int -getnetgrent(const char **host, const char **user, const char **domain) { +getnetgrent(char **host, char **user, char **domain) { struct net_data *net_data = init(); + const char *ch, *cu, *cd; + int ret; - return (getnetgrent_p(host, user, domain, net_data)); + ret = getnetgrent_p(&ch, &cu, &cd, net_data); + if (ret != 1) + return (ret); + + DE_CONST(ch, *host); + DE_CONST(cu, *user); + DE_CONST(cd, *domain); + return (ret); } /* Shared private. */ diff --git a/contrib/bind/lib/irs/getnetgrent_r.c b/contrib/bind/lib/irs/getnetgrent_r.c index adae817..0a88ea4 100644 --- a/contrib/bind/lib/irs/getnetgrent_r.c +++ b/contrib/bind/lib/irs/getnetgrent_r.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: getnetgrent_r.c,v 8.6 2001/11/01 08:02:12 marka Exp $"; +static const char rcsid[] = "$Id: getnetgrent_r.c,v 8.6.10.1 2003/06/02 06:06:58 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include <port_before.h> @@ -41,9 +41,15 @@ copy_protoent(char **, char **, char **, const char *, const char *, NGR_R_RETURN innetgr_r(const char *netgroup, const char *host, const char *user, - const char *domain) { + const char *domain) { + char *ng, *ho, *us, *dom; - return (innetgr(netgroup, host, user, domain)); + DE_CONST(netgroup, ng); + DE_CONST(host, ho); + DE_CONST(user, us); + DE_CONST(domain, dom); + + return (innetgr(ng, ho, us, dom)); } /* @@ -54,7 +60,7 @@ innetgr_r(const char *netgroup, const char *host, const char *user, NGR_R_RETURN getnetgrent_r(char **machinep, char **userp, char **domainp, NGR_R_ARGS) { - const char *mp, *up, *dp; + char *mp, *up, *dp; int res = getnetgrent(&mp, &up, &dp); if (res != 1) diff --git a/contrib/bind/lib/irs/hesiod.c b/contrib/bind/lib/irs/hesiod.c index 2b08911..5afe661 100644 --- a/contrib/bind/lib/irs/hesiod.c +++ b/contrib/bind/lib/irs/hesiod.c @@ -1,5 +1,5 @@ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: hesiod.c,v 1.22 2001/05/29 05:48:55 marka Exp $"; +static const char rcsid[] = "$Id: hesiod.c,v 1.23 2002/07/18 02:07:45 marka Exp $"; #endif /* @@ -98,8 +98,13 @@ hesiod_init(void **context) { errno = ENOMEM; goto cleanup; } +#ifdef HAVE_STRLCPY + strlcpy(ctx->LHS, DEF_LHS, strlen(DEF_LHS) + 1); + strlcpy(ctx->RHS, DEF_RHS, strlen(DEF_RHS) + 1); +#else strcpy(ctx->LHS, DEF_LHS); strcpy(ctx->RHS, DEF_RHS); +#endif #else goto cleanup; #endif @@ -109,18 +114,31 @@ hesiod_init(void **context) { * variable. */ if ((cp = getenv("HES_DOMAIN")) != NULL) { + size_t RHSlen = strlen(cp) + 2; if (ctx->RHS) free(ctx->RHS); - ctx->RHS = malloc(strlen(cp)+2); + ctx->RHS = malloc(RHSlen); if (!ctx->RHS) { errno = ENOMEM; goto cleanup; } - if (cp[0] == '.') + if (cp[0] == '.') { +#ifdef HAVE_STRLCPY + strlcpy(ctx->RHS, cp, RHSlen); +#else strcpy(ctx->RHS, cp); - else { +#endif + } else { +#ifdef HAVE_STRLCPY + strlcpy(ctx->RHS, ".", RHSlen); +#else strcpy(ctx->RHS, "."); +#endif +#ifdef HAVE_STRLCAT + strlcat(ctx->RHS, cp, RHSlen); +#else strcat(ctx->RHS, cp); +#endif } } diff --git a/contrib/bind/lib/irs/irp_p.h b/contrib/bind/lib/irs/irp_p.h index 0f68b28..8a02b1b 100644 --- a/contrib/bind/lib/irs/irp_p.h +++ b/contrib/bind/lib/irs/irp_p.h @@ -16,7 +16,7 @@ */ /* - * $Id: irp_p.h,v 8.2 2001/08/10 02:40:52 marka Exp $ + * $Id: irp_p.h,v 8.2.10.1 2003/06/02 05:55:14 marka Exp $ */ #ifndef _IRP_P_H_INCLUDED @@ -53,8 +53,6 @@ char *irs_irp_read_body(struct irp_p *pvt, size_t *size); int irs_irp_get_full_response(struct irp_p *pvt, int *code, char *text, size_t textlen, char **body, size_t *bodylen); -int irs_irp_send_command(struct irp_p *pvt, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3); - extern int irp_log_errors; diff --git a/contrib/bind/lib/irs/irs_data.c b/contrib/bind/lib/irs/irs_data.c index 000da0c..f69a6b4 100644 --- a/contrib/bind/lib/irs/irs_data.c +++ b/contrib/bind/lib/irs/irs_data.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: irs_data.c,v 1.19 2001/08/20 07:08:41 marka Exp $"; +static const char rcsid[] = "$Id: irs_data.c,v 1.20.2.1 2003/06/02 10:09:48 marka Exp $"; #endif #include "port_before.h" @@ -38,6 +38,7 @@ static const char rcsid[] = "$Id: irs_data.c,v 1.19 2001/08/20 07:08:41 marka Ex #endif #include <irs.h> +#include <stdlib.h> #include "port_after.h" @@ -97,6 +98,14 @@ net_data_destroy(void *p) { (*net_data->ng->close)(net_data->ng); net_data->ng = NULL; } + if (net_data->ho_data != NULL) { + free(net_data->ho_data); + net_data->ho_data = NULL; + } + if (net_data->nw_data != NULL) { + free(net_data->nw_data); + net_data->nw_data = NULL; + } (*net_data->irs->close)(net_data->irs); memput(net_data, sizeof *net_data); @@ -143,19 +152,27 @@ net_data_create(const char *conf_file) { return (NULL); memset(net_data, 0, sizeof (struct net_data)); - if ((net_data->irs = irs_gen_acc("", conf_file)) == NULL) + if ((net_data->irs = irs_gen_acc("", conf_file)) == NULL) { + memput(net_data, sizeof (struct net_data)); return (NULL); + } #ifndef DO_PTHREADS (*net_data->irs->res_set)(net_data->irs, &_res, NULL); #endif net_data->res = (*net_data->irs->res_get)(net_data->irs); - if (net_data->res == NULL) + if (net_data->res == NULL) { + (*net_data->irs->close)(net_data->irs); + memput(net_data, sizeof (struct net_data)); return (NULL); + } if ((net_data->res->options & RES_INIT) == 0 && - res_ninit(net_data->res) == -1) + res_ninit(net_data->res) == -1) { + (*net_data->irs->close)(net_data->irs); + memput(net_data, sizeof (struct net_data)); return (NULL); + } return (net_data); } diff --git a/contrib/bind/lib/irs/nis_gr.c b/contrib/bind/lib/irs/nis_gr.c index b4e0945..0ea50f5 100644 --- a/contrib/bind/lib/irs/nis_gr.c +++ b/contrib/bind/lib/irs/nis_gr.c @@ -49,7 +49,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: nis_gr.c,v 1.21 2001/05/29 05:49:12 marka Exp $"; +static const char rcsid[] = "$Id: nis_gr.c,v 1.22 2002/07/08 06:26:11 marka Exp $"; /* from getgrent.c 8.2 (Berkeley) 3/21/94"; */ /* from BSDI Id: getgrent.c,v 2.8 1996/05/28 18:15:14 bostic Exp $ */ #endif /* LIBC_SCCS and not lint */ @@ -286,7 +286,7 @@ makegroupent(struct irs_gr *this) { goto cleanup; *cp++ = '\0'; - errno = -1; + errno = 0; t = strtoul(cp, NULL, 10); if (errno == ERANGE) goto cleanup; diff --git a/contrib/bind/lib/irs/nis_ho.c b/contrib/bind/lib/irs/nis_ho.c index 72a8d17..7158f4c 100644 --- a/contrib/bind/lib/irs/nis_ho.c +++ b/contrib/bind/lib/irs/nis_ho.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: nis_ho.c,v 1.18 2001/06/18 14:44:00 marka Exp $"; +static const char rcsid[] = "$Id: nis_ho.c,v 1.18.10.1 2003/06/02 05:50:57 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports */ @@ -87,6 +87,9 @@ static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; static /*const*/ char hosts_byname[] = "hosts.byname"; static /*const*/ char hosts_byaddr[] = "hosts.byaddr"; +static /*const*/ char ipnode_byname[] = "ipnode.byname"; +static /*const*/ char ipnode_byaddr[] = "ipnode.byaddr"; +static /*const*/ char yp_multi[] = "YP_MULTI_"; /* Forwards */ @@ -186,10 +189,33 @@ ho_byname2(struct irs_ho *this, const char *name, int af) { return (NULL); nisfree(pvt, do_val); - DE_CONST(name, tmp); - r = yp_match(pvt->nis_domain, hosts_byname, tmp, + + strcpy(pvt->hostbuf, yp_multi); + strncat(pvt->hostbuf, name, sizeof(pvt->hostbuf) - sizeof(yp_multi)); + pvt->hostbuf[sizeof(pvt->hostbuf) - 1] = '\0'; + for (r = sizeof(yp_multi) - 1; pvt->hostbuf[r] != '\0'; r++) + if (isupper((unsigned char)pvt->hostbuf[r])) + tolower(pvt->hostbuf[r]); + + tmp = pvt->hostbuf; + r = yp_match(pvt->nis_domain, ipnode_byname, tmp, strlen(tmp), &pvt->curval_data, &pvt->curval_len); if (r != 0) { + tmp = pvt->hostbuf + sizeof(yp_multi) - 1; + r = yp_match(pvt->nis_domain, ipnode_byname, tmp, + strlen(tmp), &pvt->curval_data, &pvt->curval_len); + } + if (r != 0) { + tmp = pvt->hostbuf; + r = yp_match(pvt->nis_domain, hosts_byname, tmp, + strlen(tmp), &pvt->curval_data, &pvt->curval_len); + } + if (r != 0) { + tmp = pvt->hostbuf + sizeof(yp_multi) - 1; + r = yp_match(pvt->nis_domain, hosts_byname, tmp, + strlen(tmp), &pvt->curval_data, &pvt->curval_len); + } + if (r != 0) { RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND); return (NULL); } @@ -220,8 +246,11 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) { return (NULL); } nisfree(pvt, do_val); - r = yp_match(pvt->nis_domain, hosts_byaddr, tmp, strlen(tmp), + r = yp_match(pvt->nis_domain, ipnode_byaddr, tmp, strlen(tmp), &pvt->curval_data, &pvt->curval_len); + if (r != 0) + r = yp_match(pvt->nis_domain, hosts_byaddr, tmp, strlen(tmp), + &pvt->curval_data, &pvt->curval_len); if (r != 0) { RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND); return (NULL); @@ -382,12 +411,35 @@ ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai) /* Private */ +/* +ipnodes: +::1 localhost +127.0.0.1 localhost +1.2.3.4 FOO bar +1.2.6.4 FOO bar +1.2.6.5 host + +ipnodes.byname: +YP_MULTI_localhost ::1,127.0.0.1 localhost +YP_MULTI_foo 1.2.3.4,1.2.6.4 FOO bar +YP_MULTI_bar 1.2.3.4,1.2.6.4 FOO bar +host 1.2.6.5 host + +hosts.byname: +localhost 127.0.0.1 localhost +host 1.2.6.5 host +YP_MULTI_foo 1.2.3.4,1.2.6.4 FOO bar +YP_MULTI_bar 1.2.3.4,1.2.6.4 FOO bar +*/ + static struct hostent * makehostent(struct irs_ho *this) { struct pvt *pvt = (struct pvt *)this->private; static const char spaces[] = " \t"; - char *cp, **q, *p; - int af, len; + char *cp, **q, *p, *comma, *ap; + int af = 0, len = 0; + int multi = 0; + int addr = 0; p = pvt->curval_data; if ((cp = strpbrk(p, "#\n")) != NULL) @@ -395,25 +447,40 @@ makehostent(struct irs_ho *this) { if (!(cp = strpbrk(p, spaces))) return (NULL); *cp++ = '\0'; - if ((pvt->res->options & RES_USE_INET6) && - inet_pton(AF_INET6, p, pvt->host_addr) > 0) { - af = AF_INET6; - len = IN6ADDRSZ; - } else if (inet_pton(AF_INET, p, pvt->host_addr) > 0) { - if (pvt->res->options & RES_USE_INET6) { - map_v4v6_address((char*)pvt->host_addr, - (char*)pvt->host_addr); + ap = pvt->hostbuf; + do { + if ((comma = strchr(p, ',')) != NULL) { + *comma++ = '\0'; + multi = 1; + } + if ((ap + IN6ADDRSZ) > (pvt->hostbuf + sizeof(pvt->hostbuf))) + break; + if ((pvt->res->options & RES_USE_INET6) && + inet_pton(AF_INET6, p, ap) > 0) { af = AF_INET6; len = IN6ADDRSZ; + } else if (inet_pton(AF_INET, p, pvt->host_addr) > 0) { + if (pvt->res->options & RES_USE_INET6) { + map_v4v6_address((char*)pvt->host_addr, ap); + af = AF_INET6; + len = IN6ADDRSZ; + } else { + af = AF_INET; + len = INADDRSZ; + } } else { - af = AF_INET; - len = INADDRSZ; + if (!multi) + return (NULL); + continue; + } + if (addr < MAXADDRS) { + pvt->h_addr_ptrs[addr++] = ap; + pvt->h_addr_ptrs[addr] = NULL; + ap += len; } - } else { + } while ((p = comma) != NULL); + if (ap == pvt->hostbuf) return (NULL); - } - pvt->h_addr_ptrs[0] = (char *)pvt->host_addr; - pvt->h_addr_ptrs[1] = NULL; pvt->host.h_addr_list = pvt->h_addr_ptrs; pvt->host.h_length = len; pvt->host.h_addrtype = af; |