summaryrefslogtreecommitdiff
path: root/usr.sbin/named/named-xfer/named-xfer.c
diff options
context:
space:
mode:
authorJason Downs <downsj@cvs.openbsd.org>1997-03-12 10:42:55 +0000
committerJason Downs <downsj@cvs.openbsd.org>1997-03-12 10:42:55 +0000
commit6072bd74192e6df1e3ed3f3afe32edfe7d99d2cb (patch)
tree21877bf94332fd37f010aeb1c31f888b63bcd85a /usr.sbin/named/named-xfer/named-xfer.c
parentf1d001e6fcd8bdb74d98ca1547b99958b9d90102 (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.c378
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)) {