diff options
author | Jason Downs <downsj@cvs.openbsd.org> | 1997-03-12 10:42:55 +0000 |
---|---|---|
committer | Jason Downs <downsj@cvs.openbsd.org> | 1997-03-12 10:42:55 +0000 |
commit | 6072bd74192e6df1e3ed3f3afe32edfe7d99d2cb (patch) | |
tree | 21877bf94332fd37f010aeb1c31f888b63bcd85a /usr.sbin/named/named-xfer/named-xfer.c | |
parent | f1d001e6fcd8bdb74d98ca1547b99958b9d90102 (diff) |
BIND 4.9.5-P1.
libresolv and include are required until the new resolver gets integrated
into libc.
Diffstat (limited to 'usr.sbin/named/named-xfer/named-xfer.c')
-rw-r--r-- | usr.sbin/named/named-xfer/named-xfer.c | 378 |
1 files changed, 332 insertions, 46 deletions
diff --git a/usr.sbin/named/named-xfer/named-xfer.c b/usr.sbin/named/named-xfer/named-xfer.c index d8e981df9c3..047f2a6a8d8 100644 --- a/usr.sbin/named/named-xfer/named-xfer.c +++ b/usr.sbin/named/named-xfer/named-xfer.c @@ -1,4 +1,4 @@ -/* $NetBSD: named-xfer.c,v 1.2 1996/03/21 18:24:16 jtc Exp $ */ +/* $OpenBSD: named-xfer.c,v 1.4 1997/03/12 10:42:43 downsj Exp $ */ /* * The original version of xfer by Kevin Dunlap. @@ -60,6 +60,28 @@ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. * --Copyright-- */ @@ -71,10 +93,15 @@ char copyright[] = #endif /* not lint */ #if !defined(lint) && !defined(SABER) +#if 0 static char sccsid[] = "@(#)named-xfer.c 4.18 (Berkeley) 3/7/91"; -static char rcsid[] = "$Id: named-xfer.c,v 8.10 1995/12/06 20:34:38 vixie Exp "; +static char rcsid[] = "$From: named-xfer.c,v 8.22 1996/12/02 09:17:21 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: named-xfer.c,v 1.4 1997/03/12 10:42:43 downsj Exp $"; +#endif #endif /* not lint */ +#include <sys/types.h> #include <sys/param.h> #include <sys/file.h> #include <sys/stat.h> @@ -139,7 +166,7 @@ static const char *soa_zinfo __P((struct zoneinfo *, u_char *, u_char*)); extern char *optarg; extern int optind, getopt(); -int +void main(argc, argv) int argc; char *argv[]; @@ -181,9 +208,9 @@ main(argc, argv) openlog(ProgName, LOG_PID); #endif #ifdef STUBS - while ((c = getopt(argc, argv, "C:d:l:s:t:z:f:p:P:qS")) != -1) + while ((c = getopt(argc, argv, "C:d:l:s:t:z:f:p:P:qS")) != EOF) #else - while ((c = getopt(argc, argv, "C:d:l:s:t:z:f:p:P:q")) != -1) + while ((c = getopt(argc, argv, "C:d:l:s:t:z:f:p:P:q")) != EOF) #endif switch (c) { #ifdef GEN_AXFR @@ -348,8 +375,7 @@ main(argc, argv) (void) signal(SIGFPE, SIG_IGN); #endif /* SIGUSR1&&SIGUSR2 */ - dprintf(1, (ddt, - "domain `%s'; file `%s'; serial %lu; closed %d\n", + dprintf(1, (ddt, "domain `%s'; file `%s'; serial %lu; closed %d\n", domain, dbfile, (u_long)serial_no, closed)); buildservicelist(); @@ -426,20 +452,16 @@ main(argc, argv) (void) unlink(tmpname); exit(XFER_UPTODATE); + default: + result = XFER_FAIL; + /* fall through */ case XFER_TIMEOUT: -#ifdef DEBUG - if (!debug) -#endif - (void) unlink(tmpname); - exit(XFER_TIMEOUT); /* servers not reachable exit */ - case XFER_FAIL: - default: #ifdef DEBUG if (!debug) #endif (void) unlink(tmpname); - exit(XFER_FAIL); /* yuck exit */ + exit(result); /* error or timeout */ } /*NOTREACHED*/ } @@ -664,6 +686,7 @@ getzone(zp, serial_no, port) goto tryagain; } #endif +#ifndef ultrix syslog(LOG_NOTICE, "[%s] %s for %s, SOA query got rcode %d, aa %d, ancount %d, aucount %d", inet_ntoa(sin.sin_addr), @@ -672,6 +695,7 @@ getzone(zp, serial_no, port) : "not authoritative"), zp->z_origin[0] != '\0' ? zp->z_origin : ".", hp->rcode, hp->aa, ancount, aucount); +#endif error++; (void) my_close(s); continue; @@ -712,13 +736,40 @@ getzone(zp, serial_no, port) (void) my_close(s); continue; } - /* ... Answer Section. */ - n = dn_expand(buf, eom, tmp, name2, sizeof name2); - if (n < 0) { - badsoa_msg = "aname error"; - goto badsoa; - } - tmp += n; + /* ... Answer Section. + * We may have to loop a little, to bypass SIG SOA's in + * the response. + */ + do { + u_char *cp4; + u_short type, class, dlen; + u_long ttl; + + n = dn_expand(buf, eom, tmp, name2, sizeof name2); + if (n < 0) { + badsoa_msg = "aname error"; + goto badsoa; + } + tmp += n; + + /* Are type, class, and ttl OK? */ + cp4 = tmp; /* Leave tmp pointing to type field */ + if (eom - cp4 < 3 * INT16SZ + INT32SZ) { + badsoa_msg = "zinfo too short"; + goto badsoa; + } + GETSHORT(type, cp4); + GETSHORT(class, cp4); + GETLONG(ttl, cp4); + GETSHORT(dlen, cp4); + if (type == T_SOA) + break; + /* Skip to next record, if any. */ + dprintf (1, (ddt, "skipping %s %s RR in response\n", + name2, p_type (type))); + tmp = cp4 + dlen; + } while (1); + if (strcasecmp(zp->z_origin, name2) != 0) { syslog(LOG_INFO, "wrong answer in resp from [%s], zone %s: [%s %s %s]\n", @@ -861,24 +912,34 @@ getzone(zp, serial_no, port) #ifdef STUBS if (zp->z_type == Z_STUB) { ancount = ntohs(hp->ancount); - for (cnt = 0 ; cnt < ancount ; cnt++) { - + for (n = cnt = 0 ; cnt < ancount ; cnt++) { n = print_output(buf, bufsize, cp); + if (n < 0) + break; cp += n; } - if (hp->nscount) { + if (n >= 0 && hp->nscount) { /* we should not get here */ ancount = ntohs(hp->nscount); for (cnt = 0 ; cnt < ancount ; cnt++) { n = print_output(buf, bufsize, cp); - cp += n; + if (n < 0) + break; + cp += n; } } ancount = ntohs(hp->arcount); - for (cnt = 0 ; cnt < ancount ; cnt ++) { + for (cnt = 0 ; n >= 0 && cnt < ancount ; cnt++) { n = print_output(buf, bufsize, cp); cp += n; } + if (n < 0) { + syslog(LOG_INFO, + "print_output: unparseable answer (%d), zone %s", + hp->rcode, zp->z_origin); + error++; + break; + } if (cp != eom) { syslog(LOG_INFO, "print_output: short answer (%d, %d), zone %s", @@ -889,11 +950,25 @@ getzone(zp, serial_no, port) } else { #endif /*STUBS*/ - n = print_output(buf, bufsize, cp); - if (cp + n != eom) { + ancount = ntohs(hp->ancount); + for (n = cnt = 0; cnt < ancount; cnt++) { + n = print_output(buf, bufsize, cp); + if (n < 0) + break; + cp += n; + } + if (n < 0) { + syslog(LOG_INFO, + "print_output: unparseable answer (%d), zone %s", + hp->rcode, zp->z_origin); + error++; + break; + } + if (cp != eom) { syslog(LOG_INFO, "print_output: short answer (%d, %d), zone %s", - cp - buf, n, zp->z_origin); + cp - buf, eom - buf, + zp->z_origin); error++; break; } @@ -1025,7 +1100,7 @@ getzone(zp, serial_no, port) #else (void) sigvec(SIGALRM, &osv, (struct sigvec *)0); #endif - if (error) + if (!error) return (XFER_TIMEOUT); return (XFER_FAIL); } @@ -1158,7 +1233,8 @@ print_output(msg, msglen, rrp) int i, j, tab, result, class, type, dlen, n1, n; char data[BUFSIZ]; u_char *cp1, *cp2, *temp_ptr; - char *cdata, *origin, *proto, dname[MAXDNAME]; + u_char *cdata; + char *origin, *proto, dname[MAXDNAME]; char *ignore = ""; cp = rrp; @@ -1183,6 +1259,11 @@ print_output(msg, msglen, rrp) dname, type, class, ttl)); /* * Convert the resource record data into the internal database format. + * CP points to the raw resource record. + * After this switch: + * CP has been updated to point past the RR. + * CP1 points to the internal database version. + * N is the length of the internal database version. */ switch (type) { case T_A: @@ -1194,8 +1275,10 @@ print_output(msg, msglen, rrp) case T_ISDN: case T_LOC: case T_NSAP: + case T_AAAA: case T_UID: case T_GID: + case T_KEY: cp1 = cp; n = dlen; cp += n; @@ -1250,14 +1333,59 @@ print_output(msg, msglen, rrp) cp1 = (u_char *)data; break; + case T_NAPTR: + /* Grab weight and port. */ + bcopy(cp, data, INT16SZ*2); + cp1 = (u_char *) (data + INT16SZ*2); + cp += INT16SZ*2; + + /* Flags */ + n = *cp++; + *cp1++ = n; + bcopy(cp, cp1, n); + cp += n; cp1 += n; + + /* Service */ + n = *cp++; + *cp1++ = n; + bcopy(cp, cp1, n); + cp += n; cp1 += n; + + /* Regexp */ + n = *cp++; + *cp1++ = n; + bcopy(cp, cp1, n); + cp += n; cp1 += n; + + /* Replacement */ + n = dn_expand(msg, msg + msglen, cp, (char *)cp1, + sizeof data - ((char *)cp1 - data)); + if (n < 0) + return (-1); + cp += n; + + /* compute end of data */ + cp1 += strlen((char *)cp1) + 1; + /* compute size of data */ + n = cp1 - (u_char *)data; + cp1 = (u_char *)data; + break; + case T_MX: case T_AFSDB: case T_RT: + case T_SRV: /* grab preference */ bcopy((char *)cp, data, INT16SZ); cp1 = (u_char *)data + INT16SZ; cp += INT16SZ; + if (type == T_SRV) { + bcopy((char *)cp, data, INT16SZ*2); + cp1 += INT16SZ*2; + cp += INT16SZ*2; + } + /* get name */ n = dn_expand(msg, msg + msglen, cp, (char *)cp1, sizeof data - INT16SZ); @@ -1291,18 +1419,52 @@ print_output(msg, msglen, rrp) n = dn_expand(msg, msg + msglen, cp, (char *)cp1, n1); if (n < 0) return (-1); - + cp += n; cp1 += strlen((char *) cp1) + 1; n = cp1 - (u_char *)data; cp1 = (u_char *)data; break; + case T_SIG: + /* CP is the raw resource record as it arrived. + * CP1, after this switch, points to the internal database version. */ + cp1 = (u_char *)data; + + /* first just copy over the type_covered, algorithm, */ + /* labels, orig ttl, two timestamps, and the footprint */ + bcopy( cp, cp1, 18 ); + cp += 18; + cp1 += 18; + + /* then the signer's name */ + n = dn_expand(msg, msg + msglen, cp, + (char *)cp1, (sizeof data) - 18); + if (n < 0) + return (-1); + cp += n; + cp1 += strlen((char*)cp1)+1; + + /* finally, we copy over the variable-length signature. + Its size is the total data length, minus what we copied. */ + n = dlen - (18 + n); + if (n > (sizeof data) - (cp1 - (u_char *)data)) + return (-1); /* out of room! */ + bcopy(cp, cp1, n); + cp += n; + cp1 += n; + + /* compute size of data */ + n = cp1 - (u_char *)data; + cp1 = (u_char *)data; + break; + default: syslog(LOG_INFO, "\"%s %s %s\" - unknown type (%d)", dname, p_class(class), p_type(type), type); hp->rcode = NOTIMP; return (-1); } + if (n > MAXDATA) { dprintf(1, (ddt, "update type %d: %d bytes is too much data\n", @@ -1310,7 +1472,7 @@ print_output(msg, msglen, rrp) hp->rcode = FORMERR; return (-1); } - cdata = (char *) cp1; + cdata = cp1; result = cp - rrp; /* @@ -1419,7 +1581,7 @@ print_output(msg, msglen, rrp) (void) putc('\t', dbfp); (void) fprintf(dbfp, "%s\t%s\t", p_class(class), p_type(type)); - cp = (u_char *) cdata; + cp = cdata; /* * Print type specific data @@ -1450,7 +1612,7 @@ print_output(msg, msglen, rrp) break; case T_NS: - cp = (u_char *) cdata; + cp = cdata; if (cp[0] == '\0') (void) fprintf(dbfp, ".\t"); else @@ -1475,9 +1637,8 @@ print_output(msg, msglen, rrp) cp = cp1; break; } - if ((*cp == '\n') || (*cp == '"')) { + if (strchr("\n\"\\", *cp)) (void) putc('\\', dbfp); - } (void) putc(*cp++, dbfp); j++; } @@ -1524,34 +1685,90 @@ print_output(msg, msglen, rrp) case T_TXT: case T_X25: cp1 = cp + n; - (void) putc('"', dbfp); while (cp < cp1) { + (void) putc('"', dbfp); if (i = *cp++) { - for (j = i ; j > 0 && cp < cp1 ; j--) { - if ((*cp == '\n') || (*cp == '"')) { + for (j = i; j > 0 && cp < cp1; j--) { + if (strchr("\n\"\\", *cp)) (void) putc('\\', dbfp); - } (void) putc(*cp++, dbfp); } } + (void) putc('"', dbfp); + if (cp < cp1) + (void) putc(' ', dbfp); } - (void) fputs("\"\n", dbfp); + (void) putc('\n', dbfp); break; case T_NSAP: fprintf(dbfp, "%s\n", inet_nsap_ntoa(n, cp, NULL)); break; + case T_AAAA: { + char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; + + fprintf(dbfp, "%s\n", inet_ntop(AF_INET6, cp, t, sizeof t)); + break; + } case T_UINFO: (void) fprintf(dbfp, "\"%s\"\n", cp); break; #ifdef LOC_RR - case T_LOC: - (void) fprintf(dbfp, "%s\n", loc_ntoa(cp, NULL)); + case T_LOC: { + char t[255]; + + (void) fprintf(dbfp, "%s\n", loc_ntoa(cp, t)); break; + } #endif /* LOC_RR */ + case T_NAPTR: { + u_int order, preference; + + /* Order */ + GETSHORT(order, cp); + fprintf(dbfp, "%lu", (u_long)order); + + /* Preference */ + GETSHORT(preference, cp); + fprintf(dbfp, " %lu", (u_long)preference); + + /* Flags */ + if (n = *cp++) { + fprintf(dbfp, " \"%.*s\"", (int)n, cp); + cp += n; + } + + /* Service */ + if (n = *cp++) { + fprintf(dbfp, " \"%.*s\"", (int)n, cp); + cp += n; + } + + /* Regexp */ + if (n = *cp++) { + fprintf(dbfp, " \"%.*s\"", (int)n, cp); + cp += n; + } + + /* Replacement */ + fprintf(dbfp, " %s.\n", cp); + + break; + } + case T_SRV: { + u_int priority, weight, port; + + GETSHORT(priority, cp); + GETSHORT(weight, cp); + GETSHORT(port, cp); + fprintf(dbfp, "\t%u %u %u %s.\n", + priority, weight, port, cp); + break; + } + case T_UID: case T_GID: if (n == INT32SZ) { @@ -1569,7 +1786,7 @@ print_output(msg, msglen, rrp) cp += sizeof(char); (void) fprintf(dbfp, "%s ", proto); i = 0; - while (cp < (u_char *) cdata + n) { + while (cp < cdata + n) { j = *cp++; do { if (j & 0200) @@ -1588,7 +1805,76 @@ print_output(msg, msglen, rrp) (void) fprintf(dbfp, " %s.\n", cp); break; + case T_KEY: { + char databuf[16+MAX_KEY_BASE64]; /* 16 for slop */ + u_int16_t keyflags; + + /* get & format key flags */ + keyflags = _getshort(cp); + (void) fprintf(dbfp, "0x%04x ", keyflags); + cp += INT16SZ; + + /* protocol id */ + (void) fprintf(dbfp, " %u", *cp++); + + /* algorithm id */ + (void) fprintf(dbfp, " %u ", *cp++); + + /* key itself (which may have zero length) */ + n = b64_ntop(cp, (cp1 + n) - cp, databuf, sizeof databuf); + if (n < 0) + fprintf(dbfp, "; BAD BASE64\n"); + else + fprintf(dbfp, "%s\n", databuf); + break; + } + + case T_SIG: { + char databuf[16+MAX_KEY_BASE64]; /* 16 for slop */ + + /* get & format rr type which signature covers */ + (void) fprintf(dbfp,"%s", p_type(_getshort((u_char*)cp))); + cp += INT16SZ; + + /* algorithm id */ + (void) fprintf(dbfp," %d",*cp++); + + /* labels (# of labels in name) - skip in textual record */ + cp++; + + /* orig time to live (TTL)) */ + (void) fprintf(dbfp," %d", _getlong((u_char*)cp)); + cp += INT32SZ; + + /* expiration time */ + (void) fprintf(dbfp," %s", p_secstodate(_getlong((u_char*)cp))); + cp += INT32SZ; + + /* time signed */ + (void) fprintf(dbfp," %s", p_secstodate(_getlong((u_char*)cp))); + cp += INT32SZ; + + /* Key footprint */ + (void) fprintf(dbfp," %d", _getshort((u_char*)cp)); + cp += INT16SZ; + + /* signer's name */ + (void) fprintf(dbfp, " %s. ", cp); + cp += strlen((char *) cp) + 1; + + /* signature itself */ + n = b64_ntop(cp, (cdata + n) - cp, databuf, sizeof databuf); + if (n < 0) + fprintf (dbfp, "; BAD BASE64\n"); + else + fprintf (dbfp, "%s\n", databuf); + break; + } + default: + cp1 = cp + n; + while (cp < cp1) + fprintf(dbfp, "0x%02.2X ", *cp++ & 0xFF); (void) fprintf(dbfp, "???\n"); } if (ferror(dbfp)) { |