From 3f83b2963e3f1302f6507d3968aa3bfc93d7472d Mon Sep 17 00:00:00 2001 From: asmodai Date: Fri, 26 May 2000 07:17:19 +0000 Subject: Virgin import of BIND v8.2.3-T5B --- contrib/bind/bin/dig/dig.c | 70 ++-- contrib/bind/bin/host/host.c | 6 +- contrib/bind/bin/irpd/Makefile | 4 +- contrib/bind/bin/irpd/irpd.c | 23 +- contrib/bind/bin/named-xfer/named-xfer.c | 612 ++++++++++++++++++++++--------- contrib/bind/bin/named/Makefile | 6 +- contrib/bind/bin/named/db_defs.h | 8 +- contrib/bind/bin/named/db_dump.c | 22 +- contrib/bind/bin/named/db_func.h | 8 +- contrib/bind/bin/named/db_glob.h | 5 +- contrib/bind/bin/named/db_glue.c | 4 +- contrib/bind/bin/named/db_ixfr.c | 216 +++++++---- contrib/bind/bin/named/db_load.c | 30 +- contrib/bind/bin/named/db_lookup.c | 18 +- contrib/bind/bin/named/db_save.c | 4 +- contrib/bind/bin/named/db_sec.c | 4 +- contrib/bind/bin/named/db_tsig.c | 4 +- contrib/bind/bin/named/db_update.c | 12 +- contrib/bind/bin/named/named.h | 5 +- contrib/bind/bin/named/ns_config.c | 138 +++++-- contrib/bind/bin/named/ns_ctl.c | 87 ++++- contrib/bind/bin/named/ns_defs.h | 49 ++- contrib/bind/bin/named/ns_forw.c | 99 ++--- contrib/bind/bin/named/ns_func.h | 15 +- contrib/bind/bin/named/ns_glob.h | 14 +- contrib/bind/bin/named/ns_glue.c | 37 +- contrib/bind/bin/named/ns_init.c | 21 +- contrib/bind/bin/named/ns_ixfr.c | 375 +++++++++++-------- contrib/bind/bin/named/ns_lexer.c | 4 +- contrib/bind/bin/named/ns_lexer.h | 2 +- contrib/bind/bin/named/ns_main.c | 70 ++-- contrib/bind/bin/named/ns_maint.c | 235 ++++++++++-- contrib/bind/bin/named/ns_ncache.c | 4 +- contrib/bind/bin/named/ns_notify.c | 63 +++- contrib/bind/bin/named/ns_parser.y | 10 +- contrib/bind/bin/named/ns_parseutil.c | 2 +- contrib/bind/bin/named/ns_parseutil.h | 2 +- contrib/bind/bin/named/ns_req.c | 154 +++++--- contrib/bind/bin/named/ns_resp.c | 132 ++++--- contrib/bind/bin/named/ns_signal.c | 4 +- contrib/bind/bin/named/ns_sort.c | 4 +- contrib/bind/bin/named/ns_stats.c | 12 +- contrib/bind/bin/named/ns_udp.c | 4 +- contrib/bind/bin/named/ns_update.c | 139 +++---- contrib/bind/bin/named/ns_xfr.c | 120 +++--- contrib/bind/bin/named/pathtemplate.h | 8 +- contrib/bind/bin/ndc/ndc.c | 25 +- contrib/bind/bin/nslookup/commands.l | 6 +- contrib/bind/bin/nslookup/list.c | 65 +--- contrib/bind/bin/nslookup/main.c | 4 +- contrib/bind/bin/nslookup/nslookup.help | 3 +- contrib/bind/bin/nsupdate/nsupdate.c | 8 +- 52 files changed, 1973 insertions(+), 1003 deletions(-) (limited to 'contrib/bind/bin') diff --git a/contrib/bind/bin/dig/dig.c b/contrib/bind/bin/dig/dig.c index 4e75c13..8d5f5be 100644 --- a/contrib/bind/bin/dig/dig.c +++ b/contrib/bind/bin/dig/dig.c @@ -1,5 +1,5 @@ #ifndef lint -static const char rcsid[] = "$Id: dig.c,v 8.36 1999/11/05 05:05:14 vixie Exp $"; +static const char rcsid[] = "$Id: dig.c,v 8.41 2000/04/20 07:36:04 vixie Exp $"; #endif /* @@ -184,8 +184,8 @@ static const char rcsid[] = "$Id: dig.c,v 8.36 1999/11/05 05:05:14 vixie Exp $"; /* Global. */ -#define VERSION 82 -#define VSTRING "8.2" +#define VERSION 83 +#define VSTRING "8.3" #define PRF_DEF 0x2ff9 #define PRF_MIN 0xA930 @@ -270,14 +270,14 @@ main(int argc, char **argv) { ns_type xfr = ns_t_invalid; int bytes_out, bytes_in; - char cmd[256]; + char cmd[512]; char domain[MAXDNAME]; char msg[120], *msgptr; char **vtmp; char *args[DIG_MAXARGS]; char **ax; int once = 1, dofile = 0; /* batch -vs- interactive control */ - char fileq[100]; + char fileq[384]; int fp; int wait=0, delay; int envset=0, envsave=0; @@ -357,8 +357,10 @@ main(int argc, char **argv) { while ((dofile && fgets(fileq, sizeof fileq, qfp) != NULL) || (!dofile && once--)) { - if (*fileq == '\n' || *fileq == '#' || *fileq==';') - continue; /* ignore blank lines & comments */ + if (*fileq == '\n' || *fileq == '#' || *fileq==';') { + printf("%s", fileq); /* echo but otherwise ignore */ + continue; /* blank lines and comments */ + } /* * "Sticky" requests that before current parsing args @@ -512,7 +514,8 @@ main(int argc, char **argv) { ";; bad -b addr\n"); exit(1); } - } + } + break; case 'k': /* -k keydir:keyname */ @@ -946,7 +949,7 @@ where: server,\n\ fputs("\ notes: defname and search don't work; use fully-qualified names.\n\ this is DiG version " VSTRING "\n\ - $Id: dig.c,v 8.36 1999/11/05 05:05:14 vixie Exp $\n\ + $Id: dig.c,v 8.41 2000/04/20 07:36:04 vixie Exp $\n\ ", stderr); } @@ -1104,6 +1107,7 @@ res_re_init() { static char localdomain[] = "LOCALDOMAIN"; u_long pfcode = res.pfcode, options = res.options; unsigned ndots = res.ndots; + int retrans = res.retrans, retry = res.retry; char *buf; /* @@ -1116,6 +1120,8 @@ res_re_init() { res.pfcode = pfcode; res.options = options; res.ndots = ndots; + res.retrans = retrans; + res.retry = retry; } /* @@ -1185,7 +1191,7 @@ printZone(ns_type xfr, const char *zone, const struct sockaddr_in *sin, u_char *newmsg; int newmsglen; ns_tcp_tsig_state tsig_state; - int tsig_ret; + int tsig_ret, tsig_required, tsig_present; switch (xfr) { case ns_t_axfr: @@ -1403,18 +1409,6 @@ printZone(ns_type xfr, const char *zone, const struct sockaddr_in *sin, break; } - /* - * Verify the TSIG - */ - - if (key) { - tsig_ret = ns_verify_tcp(answer, &len, &tsig_state, 1); - if (tsig_ret == 0) - printf("; TSIG ok\n"); - else - printf("; TSIG invalid\n"); - } - result = print_axfr(stdout, answer, len); if (result != 0) { error = ERR_PRINTING; @@ -1475,6 +1469,30 @@ printZone(ns_type xfr, const char *zone, const struct sockaddr_in *sin, break; } } + + /* + * Verify the TSIG + */ + + if (key) { + if (ns_find_tsig(answer, answer + len) != NULL) + tsig_present = 1; + else + tsig_present = 0; + if (numAnswers == 1 || soacnt > 1) + tsig_required = 1; + else + tsig_required = 0; + tsig_ret = ns_verify_tcp(answer, &len, &tsig_state, + tsig_required); + if (tsig_ret == 0) { + if (tsig_present) + printf("; TSIG ok\n"); + } + else + printf("; TSIG invalid\n"); + } + } printf(";; Received %d answer%s (%d record%s).\n", @@ -1570,8 +1588,12 @@ print_axfr(FILE *file, const u_char *msg, size_t msglen) { } name = ns_rr_name(rr); if (origin[0] == '\0' && name[0] != '\0') { - fprintf(file, "$ORIGIN %s.\n", name); - strcpy(origin, name); + if (strcmp(name, ".") != 0) + strcpy(origin, name); + fprintf(file, "$ORIGIN %s.\n", origin); + if (strcmp(name, ".") == 0) + strcpy(origin, name); + strcpy(name_ctx, "@"); } if (ns_sprintrr(&handle, &rr, name_ctx, origin, buf, sizeof buf) < 0) { diff --git a/contrib/bind/bin/host/host.c b/contrib/bind/bin/host/host.c index bcfbe02..1a66b8b 100644 --- a/contrib/bind/bin/host/host.c +++ b/contrib/bind/bin/host/host.c @@ -1,5 +1,5 @@ #ifndef lint -static const char rcsid[] = "$Id: host.c,v 8.34 1999/11/11 19:39:10 cyarnell Exp $"; +static const char rcsid[] = "$Id: host.c,v 8.36 2000/01/25 00:20:21 cyarnell Exp $"; #endif /* not lint */ /* @@ -171,7 +171,7 @@ static char *cname = NULL; static const char *progname = "amnesia"; static int getclass = ns_c_in, verbose = 0, list = 0; static int server_specified = 0; -static int gettype; +static int gettype = 0; static char getdomain[NS_MAXDNAME]; /* Forward. */ @@ -270,7 +270,7 @@ main(int argc, char **argv) { /*NOTREACHED*/ } } - if (gettype == 0) { + if ((gettype == 0) && (sigchase)) { if (verbose) printf ("Forcing `-t a' for signature trace.\n"); gettype = ns_t_a; diff --git a/contrib/bind/bin/irpd/Makefile b/contrib/bind/bin/irpd/Makefile index 6f94d63..4d2c0fc 100644 --- a/contrib/bind/bin/irpd/Makefile +++ b/contrib/bind/bin/irpd/Makefile @@ -13,7 +13,7 @@ ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ## SOFTWARE. -# $Id: Makefile,v 1.3 1999/02/22 02:47:55 vixie Exp $ +# $Id: Makefile,v 1.4 2000/05/09 07:02:22 vixie Exp $ DESTDIR= CC= cc @@ -68,7 +68,7 @@ tmp_version.c: version.c Makefile ../Makefile ${SRCS} ${HDRS} (u=$${USER-root} d=`pwd` h=`${HOSTNAMECMD}` t=`date`; \ sed -e "s|%WHEN%|$${t}|" -e "s|%VERSION%|"${VER}"|" \ -e "s|%WHOANDWHERE%|$${u}@$${h}:$${d}|" \ - < version.c > tmp_version.c) + < version.c > tmp_version.c); sleep 1 distclean: clean diff --git a/contrib/bind/bin/irpd/irpd.c b/contrib/bind/bin/irpd/irpd.c index a2b13cb..4a94d2c 100644 --- a/contrib/bind/bin/irpd/irpd.c +++ b/contrib/bind/bin/irpd/irpd.c @@ -37,7 +37,7 @@ seem to be so for getnetbyaddr #endif #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: irpd.c,v 1.7 1999/10/13 16:26:23 vixie Exp $"; +static const char rcsid[] = "$Id: irpd.c,v 1.8 2000/02/04 08:28:27 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports. */ @@ -329,7 +329,9 @@ int main(int argc, char **argv) { struct ctl_sctx *ctx; struct sockaddr *addr; +#ifndef NO_SOCKADDR_UN struct sockaddr_un uaddr; +#endif struct sockaddr_in iaddr; log_channel chan; short port = IRPD_PORT; @@ -358,11 +360,13 @@ main(int argc, char **argv) { } break; +#ifndef NO_SOCKADDR_UN case 'u': sockname = optarg; addr = (struct sockaddr *)&uaddr; socksize = sizeof uaddr; break; +#endif case 'h': case '?': @@ -374,7 +378,6 @@ main(int argc, char **argv) { argc -= optind; argv += optind; - memset(&uaddr, 0, sizeof uaddr); memset(&iaddr, 0, sizeof iaddr); #ifdef HAVE_SA_LEN @@ -384,17 +387,21 @@ main(int argc, char **argv) { iaddr.sin_port = htons(IRPD_PORT); iaddr.sin_addr.s_addr = htonl(INADDR_ANY); - uaddr.sun_family = AF_UNIX; - strncpy(uaddr.sun_path, sockname, sizeof uaddr.sun_path); +#ifndef NO_SOCKADDR_UN + memset(&uaddr, 0, sizeof uaddr); + if (addr == (struct sockaddr *)&uaddr) { + uaddr.sun_family = AF_UNIX; + strncpy(uaddr.sun_path, sockname, sizeof uaddr.sun_path); #ifdef HAVE_SA_LEN - uaddr.sun_len = SUN_LEN(&uaddr); + uaddr.sun_len = SUN_LEN(&uaddr); #endif - if (addr == (struct sockaddr *)&uaddr) socksize = SUN_LEN(&uaddr); - /* XXX what if this file is not currently a socket? */ - unlink(sockname); + /* XXX what if this file is not currently a socket? */ + unlink(sockname); + } +#endif evCreate(&ev); diff --git a/contrib/bind/bin/named-xfer/named-xfer.c b/contrib/bind/bin/named-xfer/named-xfer.c index 50c299e..59fff9f 100644 --- a/contrib/bind/bin/named-xfer/named-xfer.c +++ b/contrib/bind/bin/named-xfer/named-xfer.c @@ -130,7 +130,7 @@ char copyright[] = #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)named-xfer.c 4.18 (Berkeley) 3/7/91"; -static const char rcsid[] = "$Id: named-xfer.c,v 8.89 1999/11/09 20:36:54 marka Exp $"; +static const char rcsid[] = "$Id: named-xfer.c,v 8.93 2000/04/20 07:33:47 vixie Exp $"; #endif /* not lint */ #include "port_before.h" @@ -178,7 +178,7 @@ static const char rcsid[] = "$Id: named-xfer.c,v 8.89 1999/11/09 20:36:54 marka #define MAX_XFER_RESTARTS 2 -#define ENABLE_IXFR 0 +#define ENABLE_IXFR 1 # ifdef SHORT_FNAMES extern long pathconf __P((const char *path, int name)); /* XXX */ @@ -191,7 +191,7 @@ static char *ddtfilename = NULL, *ddtfile = NULL; static char *tmpname = NULL, - *tmpiname = NULL, /* temporary file name for ixfr transaction file */ + *tmpiname = NULL, /* temporary file name for ixfr transaction file */ *domain; /* domain being xfered */ static int quiet = 0, @@ -209,12 +209,12 @@ static void usage(const char *), tsig_init(const char *); static int getzone(struct zoneinfo *, u_int32_t, int), print_output(struct zoneinfo *, u_int32_t, - u_char *, int, u_char *), + u_char *, int, u_char *, int), netread(int, char *, int, int), writemsg(int, const u_char *, int); -static void ixfr_log(const u_char *msg, int len, int *delete, +static int ixfr_log(const u_char *msg, int len, int *delete, FILE *file, struct sockaddr_in *sin, - char *domain, u_int32_t serial_no, int *); + char *domain, u_int32_t *serial_no, int *); static SIG_FN read_alarm(void); static SIG_FN term_handler(void); static const char *soa_zinfo(struct zoneinfo *, u_char *, u_char*), @@ -225,7 +225,6 @@ struct zoneinfo zp_start, zp_finish; static int restarts = 0; static int check_serial = 0; static int xfr_qtype = T_AXFR; -static u_int32_t old_serial; FILE *ddt = NULL; int servermethode[NSMAX]; @@ -692,8 +691,8 @@ main(int argc, char *argv[]) { if (movefile(tmpname, ixfrfile) == -1) { perror("movefile"); #ifdef DEBUG - if (debug) - (void) unlink(ddtfile); + if (debug) + (void) unlink(ddtfile); #endif if (!quiet) syslog(LOG_ERR, @@ -833,7 +832,6 @@ int soa_cnt = 0, scdsoa = 0, methode = ISNOTIXFR; int delete_soa = 1; u_int32_t final_serial = 0; int ixfr_soa = 0; -int firstsoa = 1; int ns_cnt = 0; int query_type = 0; int prev_comment = 0; /* was previous record a comment? */ @@ -852,6 +850,7 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { u_int cnt; u_char *cp, *nmp, *eom, *tmp ; u_char *buf = NULL, *cpp = NULL; + u_char *bp; u_int bufsize = 0; char name[MAXDNAME], name2[MAXDNAME]; struct sockaddr_in sin; @@ -863,6 +862,7 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { struct sigvec sv, osv; #endif int qdcount, ancount, aucount, arcount, class, type; + int first_serial; const char *badsoa_msg = "Nil"; struct sockaddr_in my_addr; char my_addr_text[30]; @@ -873,7 +873,9 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { u_char sig[64]; int siglen; int ixfr_first = 1; + int loop_cnt = 0; time_t timesigned; + u_int32_t query_serial = serial_no; #ifdef DEBUG if (debug) { @@ -982,7 +984,7 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { (void) my_close(s); continue; } - if (methode == ISIXFR) { + if (methode == ISIXFR && was_ixfr == 0) { hp = (HEADER *) buf; cpp = buf; n = res_nmkquery(&res, QUERY, zp->z_origin, curclass, @@ -1069,9 +1071,10 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { * Get out your butterfly net and catch the SOA */ - if (netread(s, (char *)buf, INT16SZ, XFER_TIMER) < 0) { - error++; + if (netread(s, (char *)buf, INT16SZ, + (soa_cnt == 0) ?400 :XFER_TIMER) < 0) { (void) my_close(s); + error++; continue; } if ((len = ns_get16(buf)) == 0) { @@ -1117,16 +1120,10 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { res_pquery(&res, buf, len, ddt); } #endif - if ((methode == ISIXFR) && (ixfp == NULL)) { + if (((methode == ISIXFR) && (ixfp == NULL)) && was_ixfr == 0) { delete_soa = 1; - firstsoa = 1; ixfr_soa = 0; - old_serial = serial_no; - if (ixfp != NULL) { - fflush(ixfp); - /* XXX error */ - ftruncate(fileno(ixfp), 0); - } else if ((ixfp = fopen(tmpiname, "w+")) == NULL) { + if ((ixfp = fopen(tmpiname, "w+")) == NULL) { perror(tmpiname); if (!quiet) syslog(LOG_ERR, @@ -1141,7 +1138,6 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { ancount = ntohs(hp->ancount); aucount = ntohs(hp->nscount); arcount = ntohs(hp->arcount); - /* * close socket if any of these apply: * 1) rcode != NOERROR @@ -1151,7 +1147,7 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { */ if (hp->rcode != NOERROR || !hp->aa || qdcount != 1 || (ancount < 1 && aucount < 1)) { -#ifndef ultrix /*XXX*/ +#ifndef SYSLOG_42BSD syslog(LOG_NOTICE, "[%s] %s for %s, SOA query got rcode %d, aa %d, ancount %d, aucount %d", inet_ntoa(sin.sin_addr), @@ -1183,6 +1179,12 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { tmp = buf + HFIXEDSZ; eom = buf + len; /* Query Section. */ + if (qdcount > 1) { + badsoa_msg = "question error"; + goto badsoa; + } + if (qdcount < 1) + goto no_question; n = dn_expand(buf, eom, tmp, name2, sizeof name2); if (n < 0) { badsoa_msg = "qname error"; @@ -1195,8 +1197,10 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { } NS_GET16(type, tmp); NS_GET16(class, tmp); - if (class != curclass || ((type != T_SOA) && type != T_IXFR) || - ns_samename(zp->z_origin, name2) != 1) { + if (class != curclass || + ((type != T_SOA) && (type != T_IXFR) && (type != T_AXFR)) || + ns_samename(zp->z_origin, name2) != 1) + { syslog(LOG_INFO, "wrong query in resp from [%s], zone %s: [%s %s %s]\n", inet_ntoa(sin.sin_addr), zp->z_origin, @@ -1205,15 +1209,16 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { (void) my_close(s); continue; } + no_question: /* ... Answer Section. * We may have to loop a little, to bypass SIG SOA's in * the response. */ + loop_cnt = 0; do { u_char *cp4; u_short type, class, dlen; u_int32_t ttl; - n = dn_expand(buf, eom, tmp, name2, sizeof name2); if (n < 0) { badsoa_msg = "aname error"; @@ -1235,12 +1240,53 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { badsoa_msg = "zinfo dlen too big"; goto badsoa; } - if (type == T_SOA) + if (type == T_SOA) { + if (was_ixfr) { + methode = ISNOTIXFR; + break; + } + if ((methode == ISIXFR) && (loop_cnt == 0)) { + bp = tmp; + soa_cnt++; + badsoa_msg = soa_zinfo(&zp_finish, tmp, eom); + if (badsoa_msg) + goto badsoa; + if (ixfp) + if (ixfr_log(buf, len, &delete_soa, ixfp, + &sin, domain, &serial_no, + &ixfr_first) < 0) { + error++; + break; + } + } else { + if (methode == ISIXFR) { + check_serial = 0; + soa_cnt++; + break; + } + break; + } + } + if ((loop_cnt >= 1) && (soa_cnt < 2)) { + dprintf(1, + "server %s %d rejected IXFR and responded with AXFR\n", + inet_ntoa(sin.sin_addr), soa_cnt); + methode = ISNOTIXFR; + check_serial = 0; + was_ixfr++; + tmp = bp; break; + } /* Skip to next record, if any. */ dprintf(1, "skipping %s %s RR in response\n", name2, p_type(type)); tmp = cp4 + dlen; + loop_cnt++; + if (loop_cnt >= ancount) { + tmp = bp; + check_serial = 0; + break; + } } while (1); if (ns_samename(zp->z_origin, name2) != 1) { @@ -1255,28 +1301,17 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { badsoa_msg = soa_zinfo(&zp_start, tmp, eom); if (badsoa_msg) goto badsoa; + if (methode == ISNOTIXFR) { if (SEQ_GT(zp_start.z_serial, serial_no) || !check_serial) { const char *l, *nl, *t; + if (soa_cnt) { + goto axfr_response; + } dprintf(1, "need update, serial %u\n", zp_start.z_serial); + soa_cnt = 0; hp = (HEADER *) buf; - if ((methode == ISIXFR) && (soa_cnt == 0)) { - if (type == T_IXFR) { - if (ixfp) - ixfr_log(buf, len, &delete_soa, ixfp, - &sin, domain, serial_no, - &ixfr_first); - soa_cnt = 2; - } else { - dprintf(1, - "server %s rejected IXFR and responded with AXFR\n", - inet_ntoa(sin.sin_addr)); - methode = ISNOTIXFR; - was_ixfr++; - soa_cnt++; - } - } ns_cnt = 0; gettime(&tt); locallen = sizeof local; @@ -1393,7 +1428,7 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { } } /*XXX ZXFR*/ - if (methode == ISNOTIXFR && !was_ixfr) { +receive: /* * Receive length & response */ @@ -1425,7 +1460,6 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { error++; break; } - } #ifdef DEBUG if (debug >= 3) { (void)fprintf(ddt,"len = %d\n", len); @@ -1455,8 +1489,7 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { } } if (len < HFIXEDSZ) { - - badrec: + badrec: error++; alen = sizeof my_addr; if (getsockname(s, (struct sockaddr *) @@ -1486,6 +1519,7 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { } break; } +axfr_response: if (query_type == T_IXFR) if (hp->rcode != NOERROR) { dprintf(1, @@ -1507,156 +1541,360 @@ getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { ((n + QFIXEDSZ) >= (eom - cp))) goto badrec; cp += n + QFIXEDSZ; - } else { - if (methode == ISIXFR && ixfp) - ixfr_log(buf, len, &delete_soa, ixfp, - &sin, domain, serial_no, - &ixfr_first); - } nmp = cp; if ((n = dn_skipname(cp, eom)) == -1) goto badrec; tmp = cp + n; - if (zp->z_type == Z_STUB) { - ancount = ntohs(hp->ancount); - n = 0; - for (cnt = 0; cnt < (u_int)ancount; cnt++) { - n = print_output(zp, serial_no, buf, - len, cp); - if (n < 0) + if (zp->z_type == Z_STUB) { + ancount = ntohs(hp->ancount); + n = 0; + for (cnt = 0; + cnt < (u_int)ancount; + cnt++) { + n = print_output(zp, + serial_no, + buf, len, cp, + was_ixfr); + if (n < 0) + break; + cp += n; + } + /* + * If we've processed the answer + * section and didn't get any useful + * answers, bail out. + */ + if (query_type == T_SOA && + soa_cnt == 0) { + syslog(LOG_ERR, + "stubs: no SOA in answer"); + error++; break; - cp += n; - } - /* - * If we've processed the answer section and - * didn't get any useful answers, bail out. - */ - if (query_type == T_SOA && soa_cnt == 0) { - syslog(LOG_ERR, - "stubs: no SOA in answer"); - error++; - break; - } - if (query_type == T_NS && ns_cnt == 0) { - syslog(LOG_ERR, - "stubs: no NS in answer"); - error++; - break; - } - if (n >= 0 && hp->nscount) { - ancount = ntohs(hp->nscount); + } + if (query_type == T_NS && + ns_cnt == 0) { + syslog(LOG_ERR, + "stubs: no NS in answer"); + error++; + break; + } + if (n >= 0 && hp->nscount) { + ancount = ntohs(hp->nscount); + for (cnt = 0; + cnt < (u_int)ancount; + cnt++) { + n = print_output(zp, + serial_no, + buf, + len, + cp, + was_ixfr); + if (n < 0) + break; + cp += n; + } + } + ancount = ntohs(hp->arcount); for (cnt = 0; + n > 0 && cnt < (u_int)ancount; + cnt++) { + n = print_output(zp, serial_no, + buf, len, cp, + was_ixfr); + 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, eom - buf, + zp->z_origin); + error++; + break; + } + } else { + ancount = ntohs(hp->ancount); + if (query_type == T_IXFR && + methode == ISIXFR) { + if (ixfr_log(buf, len, + &delete_soa, ixfp, + &sin, domain, + &serial_no, + &ixfr_first) < 0){ + error++; + break; + } + } + for (n = cnt = 0; cnt < (u_int)ancount; cnt++) { n = print_output(zp, serial_no, - buf, len, - cp); + buf, len, cp, + was_ixfr); if (n < 0) break; cp += n; } - } - ancount = ntohs(hp->arcount); - for (cnt = 0; - n > 0 && cnt < (u_int)ancount; - cnt++) { - n = print_output(zp, serial_no, buf, - len, 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, + 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, eom - buf, - zp->z_origin); - error++; - break; - } - } else { - ancount = ntohs(hp->ancount); - for (n = cnt = 0; cnt < (u_int)ancount; cnt++) { - n = print_output(zp, serial_no, buf, - len, cp); - if (n < 0) + cp - buf, eom - buf, + zp->z_origin); + error++; break; - cp += n; + } } - if (n < 0) { - syslog(LOG_INFO, - "print_output: unparseable answer (%d), zone %s", - hp->rcode, zp->z_origin); - error++; + if ((soa_cnt >= 2) && (methode == ISNOTIXFR)) break; - } - if (cp != eom) { - syslog(LOG_INFO, - "print_output: short answer (%d, %d), zone %s", - cp - buf, eom - buf, - zp->z_origin); - error++; + if ((soa_cnt == -1) && (methode == ISIXFR)) break; - } } - - if ((soa_cnt >= 2) && (methode == ISNOTIXFR)) - break; - if ((soa_cnt == -1) && (methode == ISIXFR)) - break; - } - (void) my_close(s); - if (error == 0) { + (void) my_close(s); + if (error == 0) { #ifdef POSIX_SIGNALS - (void) sigaction(SIGALRM, &osv, - (struct sigaction *)0); + (void) sigaction(SIGALRM, &osv, + (struct sigaction *)0); #else - (void) sigvec(SIGALRM, &osv, (struct sigvec *)0); + (void) sigvec(SIGALRM, &osv, + (struct sigvec *)0); #endif - if (methode == ISIXFR) { - fprintf(ixfp, "update:\t{add} "); - if (soa_buf) - fputs(soa_buf, ixfp); - fprintf(ixfp, "[END_DELTA]\n"); - (void) my_close(s); - return (XFER_SUCCESSIXFR); - } else { if (ixfp) { (void) fclose(ixfp); ixfp = NULL; } return (XFER_SUCCESSAXFR); } - } - if (ixfp) { - (void) fclose(ixfp); - ixfp = NULL; - } - dprintf(2, "error receiving zone transfer\n"); - } else if (zp_start.z_serial == serial_no) { + if (ixfp) { + (void) fclose(ixfp); + ixfp = NULL; + } + dprintf(2, "error receiving zone transfer\n"); + } else if (zp_start.z_serial == serial_no) { (void) my_close(s); - dprintf(1, "zone up-to-date, serial %u\n", zp_start.z_serial); + dprintf(1, "zone up-to-date, serial %u\n", + zp_start.z_serial); if (ixfp) { (void) unlink (tmpiname); (void) fclose(ixfp); ixfp = NULL; } return (XFER_UPTODATE); - } else { + } else { (void) my_close(s); if (!quiet) - syslog(LOG_NOTICE, + syslog(LOG_NOTICE, "serial from [%s], zone %s: %u lower than current: %u\n", - inet_ntoa(sin.sin_addr), zp->z_origin, - zp_start.z_serial, serial_no); + inet_ntoa(sin.sin_addr), zp->z_origin, + zp_start.z_serial, serial_no); return (XFER_FAIL); - } + } + } else { + if (zp_finish.z_serial == query_serial) { + (void) my_close(s); + dprintf(1, "zone up-to-date, serial %u\n", + zp_start.z_serial); + if (ixfp) { + (void) unlink (tmpiname); + (void) fclose(ixfp); + ixfp = NULL; + } + return (XFER_UPTODATE); + } + if (SEQ_GT(query_serial, zp_finish.z_serial)) { + if (!quiet) + syslog(LOG_NOTICE, + "serial from [%s], zone %s: %u lower than current: %u\n", + inet_ntoa(sin.sin_addr), zp->z_origin, + zp_finish.z_serial, query_serial); + dprintf(1, + "serial from [%s], zone %s: %u lower than current: %u\n", + inet_ntoa(sin.sin_addr), zp->z_origin, + zp_finish.z_serial, query_serial); + if (ixfp) { + (void) fclose(ixfp); + ixfp = NULL; + (void) unlink (tmpiname); + } + if (was_ixfr == 0) { + was_ixfr++; + n = res_nmkquery(&res, QUERY, + zp->z_origin, + curclass, T_AXFR, + NULL, 0, + NULL, buf, bufsize); + if (n < 0) { + if (!quiet) + syslog(LOG_INFO, + "zone %s: res_nmkquery T_SOA failed", + zp->z_origin); + (void) my_close(s); +#ifdef POSIX_SIGNALS + (void) sigaction(SIGALRM, &osv, + (struct sigaction *)0); +#else + (void) sigvec(SIGALRM, &osv, + (struct sigvec *)0); +#endif + return (XFER_FAIL); + } + /* + * Append TSIG to SOA query if desired + */ + tsig_key = tsig_key_from_addr(sin.sin_addr); + if (tsig_key != NULL) { + siglen = sizeof(sig); + ret = ns_sign(buf, &n, bufsize, + NOERROR, + tsig_key, NULL, + 0, sig, &siglen, + timesigned); + if (ret == 0) + tsig_signed = 1; + } + + /* + * Send length & message for AXFR query + */ + if (writemsg(s, buf, n) < 0) + syslog(LOG_INFO, + "writemsg: %m"); + else { + methode = ISNOTIXFR; + check_serial = 0; + soa_cnt = 0; + was_ixfr = 0; + goto receive; + } + } + (void) my_close(s); + return (XFER_FAIL); + } + if (ancount == 1) { + methode = ISNOTIXFR; + check_serial = 0; + soa_cnt = 0; + goto axfr_response; + } + dprintf(1, "We have an IXFR\n"); + while (SEQ_GT(zp_finish.z_serial, serial_no)) { + /* + * Receive length & response + */ + if (netread(s, (char *)buf, INT16SZ, + (soa_cnt == 0) ?300 :XFER_TIMER) + < 0) { + error++; + break; + } + if ((len = ns_get16(buf)) == 0) + break; + if (len > bufsize) { + buf = (u_char *)realloc(buf, len); + if (buf == NULL) { + syslog(LOG_INFO, + "malloc(%u) failed for packet from server [%s], zone %s\n", + len, + inet_ntoa(sin.sin_addr), + zp->z_origin); + error++; + break; + } + bufsize = len; + } + hp = (HEADER *)buf; + eom = buf + len; + if (netread(s, (char *)buf, len, XFER_TIMER) + < 0) { + error++; + break; + } +#ifdef DEBUG + if (debug >= 3) { + (void)fprintf(ddt,"len = %d\n", len); + res_pquery(&res, buf, len, ddt); + } + if (fp) + res_pquery(&res, buf, len, fp); +#endif + /* + * Verify the TSIG if expected + */ + if (tsig_signed != 0) { + tsig_req = (soa_cnt == 0); + ret = ns_verify_tcp(buf, (int *)&len, + &tsig_state, + tsig_req); + eom = buf + len; + + if (ret != 0) { + syslog(LOG_NOTICE, + "TSIG verification from server [%s], zone %s: %s (%d)\n", + inet_ntoa(sin.sin_addr), + zp->z_origin, + tsig_rcode(ret), ret); + error++; + break; + } + } + if (len < HFIXEDSZ) { + error++; + alen = sizeof my_addr; + if (getsockname(s, (struct sockaddr *) + &my_addr, &alen) < 0) + sprintf(my_addr_text, "[errno %d]", errno); + else + sprintf(my_addr_text, "[%s].%u", + inet_ntoa(my_addr. sin_addr), + ntohs(my_addr.sin_port)); + if ((hp->rcode == REFUSED) && + (len >= HFIXEDSZ)) { + syslog(LOG_INFO, + "[%s] transfer refused from [%s], zone %s\n", + my_addr_text, + inet_ntoa(sin.sin_addr), + zp->z_origin); + } else { + syslog(LOG_INFO, + "[%s] record too short from [%s], zone %s\n", + my_addr_text, + inet_ntoa(sin.sin_addr), + zp->z_origin); + } + break; + } + if (ixfp) + if (ixfr_log(buf, len, &delete_soa, ixfp, + &sin, domain, &serial_no, + &ixfr_first) < 0) { + error++; + break; + } + } + (void) my_close(s); + if (!error) { + fprintf(ixfp, "update:\t{add} "); + if (soa_buf) + fputs(soa_buf, ixfp); + fprintf(ixfp, "[END_DELTA]\n"); + return (XFER_SUCCESSIXFR); + } + } } #ifdef POSIX_SIGNALS (void) sigaction(SIGALRM, &osv, (struct sigaction *)0); @@ -1702,10 +1940,12 @@ netread(int fd, char *buf, int len, int timeout) { ival = zeroival; ival.it_value.tv_sec = timeout; while (len > 0) { +#ifndef WINNT if (setitimer(ITIMER_REAL, &ival, NULL) < 0) { syslog(LOG_INFO, setitimerStr); return (-1); } +#endif errno = 0; salen = sizeof sa; n = recvfrom(fd, buf, len, 0, (struct sockaddr *)&sa, &salen); @@ -1742,10 +1982,12 @@ netread(int fd, char *buf, int len, int timeout) { buf += n; len -= n; } +#ifndef WINNT if (setitimer(ITIMER_REAL, &zeroival, NULL) < 0) { syslog(LOG_INFO, setitimerStr); return (-1); } +#endif return (0); } @@ -1825,7 +2067,7 @@ soa_zinfo(struct zoneinfo *zp, u_char *cp, u_char *eom) { */ static int print_output(struct zoneinfo *zp, u_int32_t serial_no, u_char *msg, - int msglen, u_char *rrp) { + int msglen, u_char *rrp, int was_ixfr) { u_char *cp; HEADER *hp = (HEADER *) msg; u_int32_t addr, ttl, tmpnum; @@ -2195,9 +2437,8 @@ print_output(struct zoneinfo *zp, u_int32_t serial_no, u_char *msg, zp->z_origin, zp_finish.z_serial); } soa_cnt++; - if ((methode == ISIXFR) || (soa_cnt >= 2)) { + if (methode == ISIXFR) return (result); - } } else { badsoa_msg = soa_zinfo(&zp_finish, rr_type_ptr, eom); if (badsoa_msg) { @@ -2255,6 +2496,9 @@ print_output(struct zoneinfo *zp, u_int32_t serial_no, u_char *msg, return (result); } } + if ((soa_cnt == 2) && (was_ixfr == 0)) + return (result); + } if (zp->z_type == Z_STUB) { @@ -2757,7 +3001,7 @@ tsig_key_from_addr(struct in_addr addr) { return NULL; } -static void +static u_int32_t do_section(ns_msg *handle, ns_sect section, int pflag, FILE *file, int *delete) { int n, sflag, rrnum; char buf[2048]; /* XXX need to malloc */ @@ -2775,19 +3019,21 @@ do_section(ns_msg *handle, ns_sect section, int pflag, FILE *file, int *delete) */ sflag = (_res.pfcode & pflag); if (_res.pfcode && !sflag) - return; + return (-1); opcode = (ns_opcode)ns_msg_getflag(*handle, ns_f_opcode); rrnum = 0; + serial = -1; for (;;) { if (ns_parserr(handle, section, rrnum, &rr)) { - if (errno != ENODEV) + if (errno != ENODEV) { fprintf(file, ";; ns_parserr: %s\n", strerror(errno)); - else if (rrnum > 0 && sflag != 0 && + return (-1); + } else if (rrnum > 0 && sflag != 0 && (_res.pfcode & RES_PRF_HEAD1)) putc('\n', file); - return; + return (serial); } if (rrnum == 0 && sflag != 0 && (_res.pfcode & RES_PRF_HEAD1)) fprintf(file, ";; %s SECTION:\n", @@ -2815,24 +3061,21 @@ do_section(ns_msg *handle, ns_sect section, int pflag, FILE *file, int *delete) } cp += n; NS_GET32(serial, cp); - if (*delete && serial != old_serial) - /*XXX*/; - old_serial = serial; switch (++ixfr_soa) { case 1: final_serial = serial; if (soa_buf == NULL) { if ((soa_buf = (char *)malloc(2 * PACKETSZ)) == NULL) { syslog(LOG_INFO, "malloc(%u) failed", 2 * PACKETSZ); - return; + return(-1); } n = ns_sprintrr(handle, &rr, NULL, NULL, soa_buf, 2*PACKETSZ); if (n < 0) { fprintf(file, ";; ns_sprintrr: %s\n", strerror(errno)); - return; - } + return (-1); + } } print_record = 0; break; @@ -2861,7 +3104,7 @@ do_section(ns_msg *handle, ns_sect section, int pflag, FILE *file, int *delete) if (n < 0) { fprintf(file, ";; ns_sprintrr: %s\n", strerror(errno)); - return; + return(-1); } fputs(buf, file); fputc('\n', file); @@ -2871,11 +3114,12 @@ do_section(ns_msg *handle, ns_sect section, int pflag, FILE *file, int *delete) } rrnum++; } + return (serial); } -static void +static int ixfr_log(const u_char *msg, int len, int *delete, FILE *file, - struct sockaddr_in *sin, char *domain, u_int32_t serial_no, + struct sockaddr_in *sin, char *domain, u_int32_t *serial_no, int *first_rr) { ns_msg handle; @@ -2884,17 +3128,20 @@ ixfr_log(const u_char *msg, int len, int *delete, FILE *file, ns_opcode opcode; ns_rcode rcode; u_int id, n; - char time[25]; + char time[25]; ns_rr rr; char *cp; HEADER *hp; - if ((_res.options & RES_INIT) == 0 && res_init() == -1) - return; + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + dprintf(1, "ixfr_log() failed\n"); + return (-1); + } if (ns_initparse(msg, len, &handle) < 0) { fprintf(file, ";; ns_initparse: %s\n", strerror(errno)); - return; + dprintf(1, "ixfr_log() failed\n"); + return (-1); } opcode = (ns_opcode) ns_msg_getflag(handle, ns_f_opcode); rcode = (ns_rcode) ns_msg_getflag(handle, ns_f_rcode); @@ -2904,7 +3151,8 @@ ixfr_log(const u_char *msg, int len, int *delete, FILE *file, { (void) fprintf(file,"ns_parserr() failed"); - return; + dprintf(1, "ixfr_log() failed\n"); + return (-1); } type = (ns_type)rr.type; class = (ns_class)rr.rr_class; @@ -2914,12 +3162,13 @@ ixfr_log(const u_char *msg, int len, int *delete, FILE *file, (void) fprintf(file,"%s", LogSignature); sprintf(time, "at %lu", (u_long)tt.tv_sec); fprintf(file, - "[IXFR_UPDATE] id %u from [%s].%d %s (named-xfr pid %ld):\n", + "[IXFR_UPDATE] id %u from [%s].%d %s (named-xfer pid %ld):\n", id, inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), time, (long)getpid()); (*first_rr)++; } - do_section(&handle, ns_s_an, RES_PRF_ANS, file, delete); + *serial_no = do_section(&handle, ns_s_an, RES_PRF_ANS, file, delete); + return (1); } static const char * @@ -2943,3 +3192,4 @@ tsig_rcode(int rcode) { } return ("FORMERR"); } + diff --git a/contrib/bind/bin/named/Makefile b/contrib/bind/bin/named/Makefile index 6eac2b1..03f533d 100644 --- a/contrib/bind/bin/named/Makefile +++ b/contrib/bind/bin/named/Makefile @@ -1,4 +1,4 @@ -## Copyright (c) 1996-1999 by Internet Software Consortium +## Copyright (c) 1996-2000 by Internet Software Consortium ## ## Permission to use, copy, modify, and distribute this software for any ## purpose with or without fee is hereby granted, provided that the above @@ -13,7 +13,7 @@ ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ## SOFTWARE. -# $Id: Makefile,v 8.47 1999/08/26 18:42:31 vixie Exp $ +# $Id: Makefile,v 8.49 2000/05/09 07:02:22 vixie Exp $ DESTDIR= CC= cc @@ -86,7 +86,7 @@ tmp_version.c: version.c Makefile ../Makefile ${SRCS} ${HDRS} (u=$${USER-root} d=`pwd` h=`${HOSTNAMECMD}` t=`date`; \ sed -e "s|%WHEN%|$${t}|" -e "s|%VERSION%|"${VER}"|" \ -e "s|%WHOANDWHERE%|$${u}@$${h}:$${d}|" \ - < version.c > tmp_version.c) + < version.c > tmp_version.c); sleep 1 pathnames.h: ${TOP}/.settings Makefile pathtemplate.h rm -f pathnames.h diff --git a/contrib/bind/bin/named/db_defs.h b/contrib/bind/bin/named/db_defs.h index 9fe2021..6fad285 100644 --- a/contrib/bind/bin/named/db_defs.h +++ b/contrib/bind/bin/named/db_defs.h @@ -1,6 +1,6 @@ /* * from db.h 4.16 (Berkeley) 6/1/90 - * $Id: db_defs.h,v 8.36 1999/08/26 18:42:32 vixie Exp $ + * $Id: db_defs.h,v 8.38 2000/04/21 06:54:01 vixie Exp $ */ /* @@ -57,7 +57,7 @@ */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -307,3 +307,7 @@ struct db_rrset { if (((x)->d_rcnt)-- == 0) \ ns_panic(ns_log_db, 1, "d_rcnt-- == 0"); \ } while (0) + +#define ISVALIDGLUE(xdp) ((xdp)->d_type == T_NS || (xdp)->d_type == T_A \ + || (xdp)->d_type == T_AAAA || (xdp)->d_type == ns_t_a6) + diff --git a/contrib/bind/bin/named/db_dump.c b/contrib/bind/bin/named/db_dump.c index 75a59b7..10acb8c 100644 --- a/contrib/bind/bin/named/db_dump.c +++ b/contrib/bind/bin/named/db_dump.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)db_dump.c 4.33 (Berkeley) 3/3/91"; -static const char rcsid[] = "$Id: db_dump.c,v 8.40 1999/10/13 16:39:01 vixie Exp $"; +static const char rcsid[] = "$Id: db_dump.c,v 8.43 2000/04/21 06:54:01 vixie Exp $"; #endif /* not lint */ /* @@ -82,7 +82,7 @@ static const char rcsid[] = "$Id: db_dump.c,v 8.40 1999/10/13 16:39:01 vixie Exp */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -144,6 +144,8 @@ doadump() fprintf(fp, "; Dumped at %s", ctimel(tt.tv_sec)); if (zones != NULL && nzones != 0) zt_dump(fp); + if (fwddata != NULL && fwddata_count != 0) + fwd_dump(fp); fputs( "; Note: Cr=(auth,answer,addtnl,cache) tag only shown for non-auth RR's\n", fp); @@ -202,6 +204,18 @@ zt_dump(FILE *fp) { fprintf(fp, ";; --zone table--\n"); return (0); } +int +fwd_dump(FILE *fp) { + int i; + fprintf(fp, ";; ++forwarders table++\n"); + for (i=0;ifwdaddr.sin_addr), + fwddata[i]->nsdata->d_nstime); + } + fprintf(fp, ";; --forwarders table--\n"); + return (0); +} int db_dump(struct hashbuf *htp, FILE *fp, int zone, char *origin) { @@ -276,9 +290,9 @@ db_dump(struct hashbuf *htp, FILE *fp, int zone, char *origin) { fprintf(fp, "%d\t", (int)(dp->d_ttl - tt.tv_sec)); } else if (dp->d_ttl != USE_MINIMUM) - fprintf(fp, "%d\t", (int)dp->d_ttl); + fprintf(fp, "%u\t", dp->d_ttl); else - fprintf(fp, "%d\t", + fprintf(fp, "%u\t", zones[dp->d_zone].z_minimum); fprintf(fp, "%s\t%s\t", p_class(dp->d_class), diff --git a/contrib/bind/bin/named/db_func.h b/contrib/bind/bin/named/db_func.h index 9ba5299..cb83beb 100644 --- a/contrib/bind/bin/named/db_func.h +++ b/contrib/bind/bin/named/db_func.h @@ -52,7 +52,7 @@ */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -90,7 +90,7 @@ /* db_proc.h - prototypes for functions in db_*.c * - * $Id: db_func.h,v 8.40 1999/10/07 08:24:06 vixie Exp $ + * $Id: db_func.h,v 8.42 2000/04/21 06:54:02 vixie Exp $ */ /* ++from db_update.c++ */ @@ -101,7 +101,7 @@ extern int db_update(const char *name, int flags, struct hashbuf *htp, struct sockaddr_in from), - db_cmp(const struct databuf *, const struct databuf *), + db_cmp(const struct databuf *, const struct databuf *), findMyZone(struct namebuf *np, int class); void fixttl(struct databuf *dp); /* --from db_update.c-- */ @@ -187,7 +187,7 @@ extern int match(struct databuf *, int, int), /* --from db_lookup.c-- */ /* ++from db_ixfr.c++ */ -struct ns_updrec * ixfr_get_change_list(struct zoneinfo *, u_int32_t, +extern ns_deltalist * ixfr_get_change_list(struct zoneinfo *, u_int32_t, u_int32_t); int ixfr_have_log(struct zoneinfo *, u_int32_t, u_int32_t); diff --git a/contrib/bind/bin/named/db_glob.h b/contrib/bind/bin/named/db_glob.h index 3d11739..cfd7abb 100644 --- a/contrib/bind/bin/named/db_glob.h +++ b/contrib/bind/bin/named/db_glob.h @@ -1,6 +1,6 @@ /* * from db.h 4.16 (Berkeley) 6/1/90 - * $Id: db_glob.h,v 8.12 1999/08/08 21:10:01 vixie Exp $ + * $Id: db_glob.h,v 8.14 2000/04/21 06:54:02 vixie Exp $ */ /* @@ -57,7 +57,7 @@ */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -95,6 +95,7 @@ DECL struct hashbuf *fcachetab INIT(NULL); /* state of ns_reload() and ns_reconfig(). */ DECL int reloading INIT(0); DECL int reconfiging INIT(0); +DECL int noexpired INIT(0); DECL const int hashsizes[] #ifdef MAIN_PROGRAM diff --git a/contrib/bind/bin/named/db_glue.c b/contrib/bind/bin/named/db_glue.c index f1fae69..8c48465 100644 --- a/contrib/bind/bin/named/db_glue.c +++ b/contrib/bind/bin/named/db_glue.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)db_glue.c 4.4 (Berkeley) 6/1/90"; -static const char rcsid[] = "$Id: db_glue.c,v 8.39 1999/10/15 19:48:57 vixie Exp $"; +static const char rcsid[] = "$Id: db_glue.c,v 8.40 2000/04/21 06:54:02 vixie Exp $"; #endif /* not lint */ /* @@ -57,7 +57,7 @@ static const char rcsid[] = "$Id: db_glue.c,v 8.39 1999/10/15 19:48:57 vixie Exp */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/contrib/bind/bin/named/db_ixfr.c b/contrib/bind/bin/named/db_ixfr.c index a009f4d..7a50618 100644 --- a/contrib/bind/bin/named/db_ixfr.c +++ b/contrib/bind/bin/named/db_ixfr.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) -static char rcsid[] = "$Id: db_ixfr.c,v 8.18 1999/10/15 19:48:57 vixie Exp $"; -#endif /* not lint */ +static char rcsid[] = "$Id: db_ixfr.c,v 8.20 2000/02/29 05:15:03 vixie Exp $"; +#endif /* * Portions Copyright (c) 1999 by Check Point Software Technologies, Inc. @@ -51,81 +51,137 @@ static char rcsid[] = "$Id: db_ixfr.c,v 8.18 1999/10/15 19:48:57 vixie Exp $ #include #include +#include #include "port_after.h" #include "named.h" -#define DBIXFR_ERROR -1 -#define DBIXFR_FOUND_RR 2 -#define DBIXFR_END 3 +#define DBIXFR_ERROR (-1) +#define DBIXFR_FOUND_RR 2 +#define DBIXFR_END 3 -static int ixfr_getrr(struct zoneinfo *, FILE *, const char *, char *, - ns_updrec **, u_int32_t *, u_int32_t *); +static int ixfr_getdelta(struct zoneinfo *, FILE *, const char *, char *, + ns_updque *, u_int32_t *, u_int32_t *); -ns_updrec * +ns_deltalist * ixfr_get_change_list(struct zoneinfo *zp, u_int32_t from_serial, u_int32_t to_serial) { - FILE * fp; + FILE * fp = NULL; u_int32_t old_serial, new_serial; char origin[MAXDNAME]; - struct namebuf *np, *listnp, *finlistnp; - LIST(ns_updrec) listuprec; - int ret, mode; + ns_deltalist *dlhead = NULL; + int ret; ns_updrec *uprec; + ns_delta *dl; if (SEQ_GT(from_serial, to_serial)) return (NULL); - listnp = finlistnp = NULL; - INIT_LIST(listuprec); + + dlhead = memget(sizeof(*dlhead)); + if (dlhead == NULL) + return (NULL); + INIT_LIST(*dlhead); + if ((fp = fopen(zp->z_ixfr_base, "r")) == NULL) { ns_warning(ns_log_db, "%s: %s", zp->z_ixfr_base, strerror(errno)); - return (NULL); + goto cleanup; } strcpy(origin, zp->z_origin); lineno = 1; - np = NULL; - mode = 0; old_serial = new_serial = 0; + for (;;) { - ret = ixfr_getrr(zp, fp, zp->z_ixfr_base, origin, &uprec, - &old_serial, &new_serial); + dl = memget(sizeof *dl); + if (dl == NULL) { + ns_warning(ns_log_db, + "ixfr_get_change_list: out of memory"); + goto cleanup; + } + INIT_LINK(dl, d_link); + INIT_LIST(dl->d_changes); + ret = ixfr_getdelta(zp, fp, zp->z_ixfr_base, origin, &dl->d_changes, + &old_serial, &new_serial); switch (ret) { case DBIXFR_ERROR: - (void) my_fclose(fp); - ns_warning(ns_log_db, "Logical error in %s line %d", - zp->z_ixfr_base, lineno); - return (NULL); + ns_warning(ns_log_db, "Logical error in %s: unlinking", + zp->z_ixfr_base); + unlink(zp->z_ixfr_base); + goto cleanup; + case DBIXFR_FOUND_RR: - if (EMPTY(listuprec)) { + ns_debug(ns_log_default, 4, "ixfr_getdelta DBIXFR_FOUND_RR (%s)", + zp->z_origin); + if (EMPTY(*dlhead)) { /* skip updates prior to the one we want */ - if (uprec->r_zone != from_serial) { - while (uprec != NULL) { - ns_updrec *prev; + uprec = HEAD(dl->d_changes); + INSIST(uprec != NULL); + if ((uprec->r_zone < from_serial) || + (uprec->r_zone > to_serial)) + { + while ((uprec = HEAD(dl->d_changes)) != NULL) { + UNLINK(dl->d_changes, uprec, r_link); if (uprec->r_dp != NULL) - db_freedata(uprec->r_dp); + db_freedata(uprec->r_dp); uprec->r_dp = NULL; - prev = PREV(uprec, r_link); res_freeupdrec(uprec); - uprec = prev; } + memput(dl, sizeof *dl); break; } + else if (uprec->r_zone > from_serial) { + /* missed the boat */ + ns_debug(ns_log_default, 3, + "ixfr_getdelta first SOA is %d, asked for %d (%s)", + uprec->r_zone, + from_serial, + zp->z_origin); + goto cleanup; + } } - APPEND(listuprec, uprec, r_link); - /* continue; */ + ns_debug(ns_log_default, 4, + "adding to change list (%s)", + zp->z_origin); + APPEND(*dlhead, dl, d_link); break; + case DBIXFR_END: + ns_debug(ns_log_default, 4, + "ixfr_getdelta DBIXFR_END (%s)", + zp->z_origin); (void) my_fclose(fp); - return (HEAD(listuprec)); + memput(dl, sizeof *dl); + return (dlhead); + default: (void) my_fclose(fp); + if (dl != NULL) + memput(dl, sizeof *dl); return (NULL); } } + + cleanup: + if (fp != NULL) + (void) my_fclose(fp); + + while ((dl = HEAD(*dlhead)) != NULL) { + UNLINK(*dlhead, dl, d_link); + while ((uprec = HEAD(dl->d_changes)) != NULL) { + UNLINK(dl->d_changes, uprec, r_link); + + if (uprec->r_dp != NULL) + db_freedata(uprec->r_dp); + uprec->r_dp = NULL; + res_freeupdrec(uprec); + } + memput(dl, sizeof *dl); + } + memput(dlhead, sizeof *dlhead); + return (NULL); } /* @@ -137,7 +193,7 @@ ixfr_get_change_list(struct zoneinfo *zp, * * returns: * 0 = serial number is up to date - * 1 = transision is possible + * 1 = transmission is possible * -1 = error while opening the ixfr transaction log * -2 = error in parameters * -3 = logical error in the history file @@ -147,14 +203,17 @@ ixfr_have_log(struct zoneinfo *zp, u_int32_t from_serial, u_int32_t to_serial) { FILE *fp; u_int32_t old_serial = 0, new_serial = 0; + u_int32_t last_serial = 0; + u_int32_t first_serial = 0; char buf[BUFSIZ]; char *cp; struct stat st; int nonempty_lineno = -1, prev_pktdone = 0, cont = 0, inside_next = 0; int err; + int first = 0; + int rval = 0; int id, rcode = NOERROR; - if (SEQ_GT(from_serial, to_serial)) return (-2); if (from_serial == to_serial) @@ -162,6 +221,10 @@ ixfr_have_log(struct zoneinfo *zp, u_int32_t from_serial, u_int32_t to_serial) /* If there is no log file, just return. */ if (zp->z_ixfr_base == NULL || zp->z_updatelog == NULL) return (-1); + if (zp->z_serial_ixfr_start > 0) { + if (from_serial >= zp->z_serial_ixfr_start) + return (1); + } if (stat(zp->z_ixfr_base, &st) < 0) { if (errno != ENOENT) ns_error(ns_log_db, @@ -176,17 +239,18 @@ ixfr_have_log(struct zoneinfo *zp, u_int32_t from_serial, u_int32_t to_serial) } if (fgets(buf, sizeof(buf), fp) == NULL) { ns_error(ns_log_update, "fgets() from %s failed: %s", - zp->z_updatelog, strerror(errno)); + zp->z_ixfr_base, strerror(errno)); fclose(fp); return (-1); } if (strcmp(buf, LogSignature) != 0) { ns_error(ns_log_update, "invalid log file %s", - zp->z_updatelog); + zp->z_ixfr_base); fclose(fp); return (-3); } lineno = 1; + first = 1; for (;;) { if (getword(buf, sizeof buf, fp, 0)) { nonempty_lineno = lineno; @@ -214,12 +278,13 @@ ixfr_have_log(struct zoneinfo *zp, u_int32_t from_serial, u_int32_t to_serial) if (cp != NULL) lineno++; if (sscanf((char *) cp, "%u", &old_serial)) { + if (first == 1) { + first = 0; + first_serial = old_serial; + } + last_serial = old_serial; if (from_serial >= old_serial) { - fclose(fp); - return (1); - } else { - fclose(fp); - return (-1); + rval = 1; } } prev_pktdone = 1; @@ -232,14 +297,16 @@ ixfr_have_log(struct zoneinfo *zp, u_int32_t from_serial, u_int32_t to_serial) if (cp == NULL || sscanf((char *) cp, "from %u to %u", &old_serial, &new_serial) != 2) { - fclose(fp); - return (-3); + rval = -3; + break; } else if (from_serial >= old_serial) { - fclose(fp); - return (1); + if (first == 1) { + first = 0; + first_serial = old_serial; + } + last_serial = old_serial; + rval = 1; } - fclose(fp); - return (-1); } if (prev_pktdone) { prev_pktdone = 0; @@ -248,7 +315,19 @@ ixfr_have_log(struct zoneinfo *zp, u_int32_t from_serial, u_int32_t to_serial) } } fclose(fp); - return (0); + if (last_serial +1 < zp->z_serial) { + ns_warning(ns_log_db, + "%s: File Deleted. Found gap between serial:" + " %d and current serial: %d", + zp->z_ixfr_base, last_serial, zp->z_serial); + (void) unlink(zp->z_ixfr_base); + rval = -3; + } + if (from_serial < first_serial || from_serial > last_serial) + rval = -3; + if (rval == 1) + zp->z_serial_ixfr_start = first_serial; + return (rval); } /* from db_load.c */ @@ -278,12 +357,7 @@ static struct map m_opcode[] = { #define M_TYPE_CNT m_type_cnt /* - * int - * ixfr_getrr(struct zoneinfo *zp, FILE *fp, - * const char *filename, char *origin, struct namebuf **np, - * u_int32_t *old_serial, u_int32_t *new_serial) - * - * read a line from the historic of a zone. + * read a line from the history of a zone. * * returns: * @@ -292,8 +366,8 @@ static struct map m_opcode[] = { * DBIXFR_END = end of file */ static int -ixfr_getrr(struct zoneinfo *zp, FILE *fp, const char *filename, char *origin, - ns_updrec **uprec, u_int32_t *old_serial, +ixfr_getdelta(struct zoneinfo *zp, FILE *fp, const char *filename, char *origin, + ns_updque *listuprec, u_int32_t *old_serial, u_int32_t *new_serial) { static int read_soa, read_ns, rrcount; @@ -305,7 +379,7 @@ ixfr_getrr(struct zoneinfo *zp, FILE *fp, const char *filename, char *origin, u_int32_t serial, ttl; int nonempty_lineno = -1, prev_pktdone = 0, cont = 0, inside_next = 0; - int id, rcode = NOERROR; + int id; int i, c, section, opcode, matches, zonenum, err, multiline; int type, class; u_int32_t n; @@ -316,7 +390,6 @@ ixfr_getrr(struct zoneinfo *zp, FILE *fp, const char *filename, char *origin, struct in_addr ina; struct sockaddr_in empty_from; int datasize; - ns_updque listuprec; ns_updrec * rrecp; u_long l; @@ -325,7 +398,6 @@ ixfr_getrr(struct zoneinfo *zp, FILE *fp, const char *filename, char *origin, err = 0; transport = primary_trans; lineno = 1; - INIT_LIST(listuprec); for (;;) { if (!getword(buf, sizeof buf, fp, 0)) { if (lineno == (nonempty_lineno + 1) && !(feof(fp))) { @@ -337,11 +409,10 @@ ixfr_getrr(struct zoneinfo *zp, FILE *fp, const char *filename, char *origin, } /* * Empty line or EOF. - * - * Marks completion of current update packet. */ + if (feof(fp)) + break; inside_next = 0; - prev_pktdone = 1; cont = 1; } else { nonempty_lineno = lineno; @@ -349,15 +420,12 @@ ixfr_getrr(struct zoneinfo *zp, FILE *fp, const char *filename, char *origin, if (!strcasecmp(buf, "[DYNAMIC_UPDATE]") || !strcasecmp(buf, "[IXFR_UPDATE]")) { - err = 0; - rcode = NOERROR; cp = fgets(buf, sizeof buf, fp); if (cp != NULL) lineno++; if (cp == NULL || !sscanf((char *) cp, "id %d", &id)) id = -1; inside_next = 1; - prev_pktdone = 1; cont = 1; } else if (!strcasecmp(buf, "[INCR_SERIAL]")) { /* XXXRTH not enough error checking here */ @@ -380,14 +448,11 @@ ixfr_getrr(struct zoneinfo *zp, FILE *fp, const char *filename, char *origin, lineno++; } if (prev_pktdone) { - if (!EMPTY(listuprec)) { + if (!EMPTY(*listuprec)) { n++; - *uprec = TAIL(listuprec); return (DBIXFR_FOUND_RR); } prev_pktdone = 0; - if (feof(fp)) - break; } if (cont) { cont = 0; @@ -800,9 +865,7 @@ ixfr_getrr(struct zoneinfo *zp, FILE *fp, const char *filename, char *origin, ns_debug(ns_log_update, 1, "merge of update id %d failed due to error at line %d", id, lineno); - memset(&empty_from, 0, sizeof empty_from); - free_rrecp(&listuprec, rcode, empty_from); - continue; + return (DBIXFR_ERROR); } rrecp = res_mkupdrec(section, dname, class, type, ttl); if (section != S_ZONE) { @@ -822,7 +885,7 @@ ixfr_getrr(struct zoneinfo *zp, FILE *fp, const char *filename, char *origin, ns_updrec *arp; int foundmatch; - arp = TAIL(listuprec); + arp = TAIL(*listuprec); foundmatch = 0; while (arp) { if (arp->r_section == S_UPDATE && @@ -837,7 +900,7 @@ ixfr_getrr(struct zoneinfo *zp, FILE *fp, const char *filename, char *origin, db_cmp(arp->r_dp, dp) == 0) { db_freedata(dp); db_freedata(arp->r_dp); - UNLINK(listuprec, arp, r_link); + UNLINK(*listuprec, arp, r_link); res_freeupdrec(arp); res_freeupdrec(rrecp); foundmatch = 1; @@ -849,7 +912,7 @@ ixfr_getrr(struct zoneinfo *zp, FILE *fp, const char *filename, char *origin, continue; } - APPEND(listuprec, rrecp, r_link); + APPEND(*listuprec, rrecp, r_link); /* Override zone number with current zone serial number */ rrecp->r_zone = serial; } @@ -859,3 +922,4 @@ ixfr_getrr(struct zoneinfo *zp, FILE *fp, const char *filename, char *origin, return (DBIXFR_END); } + diff --git a/contrib/bind/bin/named/db_load.c b/contrib/bind/bin/named/db_load.c index 9b6fedb..2d6a6e5 100644 --- a/contrib/bind/bin/named/db_load.c +++ b/contrib/bind/bin/named/db_load.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)db_load.c 4.38 (Berkeley) 3/2/91"; -static const char rcsid[] = "$Id: db_load.c,v 8.97 1999/10/30 03:21:35 vixie Exp $"; +static const char rcsid[] = "$Id: db_load.c,v 8.103 2000/04/21 06:54:02 vixie Exp $"; #endif /* not lint */ /* @@ -82,7 +82,7 @@ static const char rcsid[] = "$Id: db_load.c,v 8.97 1999/10/30 03:21:35 vixie Exp */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -267,6 +267,8 @@ db_load(const char *filename, const char *in_origin, switch (zp->z_type) { case Z_PRIMARY: + /* Any updates should be saved before we attempt to reload. */ + INSIST((zp->z_flags & (Z_NEED_DUMP|Z_NEED_SOAUPDATE)) == 0); case Z_HINT: transport = primary_trans; break; @@ -292,6 +294,7 @@ db_load(const char *filename, const char *in_origin, default_warn = 1; clev = nlabels(in_origin); filenames = NULL; + zp->z_minimum = USE_MINIMUM; } ttl = default_ttl; @@ -358,7 +361,8 @@ db_load(const char *filename, const char *in_origin, endline(fp); } didinclude = 1; - errs += db_load(buf, tmporigin, zp, domain, ISNOTIXFR); + i = db_load(buf, tmporigin, zp, domain, ISNOTIXFR); + errs += (i == -1) ? 1 : i; continue; case ORIGIN: @@ -742,7 +746,7 @@ db_load(const char *filename, const char *in_origin, zp->z_minimum = 0; } else zp->z_minimum = n; - if (default_ttl == USE_MINIMUM) + if (ttl == USE_MINIMUM) ttl = n; n = cp - (char *)data; if (multiline) { @@ -750,6 +754,7 @@ db_load(const char *filename, const char *in_origin, buf[1] = '\0'; if (buf[0] != ')') ERRTO("SOA \")\""); + multiline = 0; endline(fp); } read_soa++; @@ -971,7 +976,10 @@ db_load(const char *filename, const char *in_origin, case ns_t_cert: case ns_t_sig: { char *errmsg = NULL; - int ret = parse_sec_rdata(buf, sizeof(buf), 0, + int ret; + if (ttl == USE_MINIMUM) /* no ttl set */ + ttl = 0; + ret = parse_sec_rdata(buf, sizeof(buf), 0, data, sizeof(data), fp, zp, domain, ttl, type, domain_ctx, @@ -1022,6 +1030,8 @@ db_load(const char *filename, const char *in_origin, zp->z_origin); continue; } + if (ttl == USE_MINIMUM) /* no ttl set */ + ttl = 0; dp = savedata(class, type, (u_int32_t)ttl, (u_char *)data, (int)n); dp->d_zone = zp - zones; @@ -1083,6 +1093,9 @@ db_load(const char *filename, const char *in_origin, zp->z_origin, filename, msg); } } + errs += purge_nonglue(zp->z_origin, + (dataflags & DB_F_HINT) ? fcachetab : + hashtab, zp->z_class); while (filenames) { fn = filenames; filenames = filenames->next; @@ -1115,8 +1128,8 @@ db_load(const char *filename, const char *in_origin, void db_err(int err, char *domain, int type, const char *filename, int lineno) { if (filename != NULL && err == CNAMEANDOTHER) - ns_notice(ns_log_load, "%s:%d:%s: CNAME and OTHER data error", - filename, lineno, domain); + ns_warning(ns_log_load, "%s:%d:%s: CNAME and OTHER data error", + filename, lineno, domain); if (err != DATAEXISTS) ns_debug(ns_log_load, 1, "update failed %s %d", domain, type); @@ -2078,7 +2091,8 @@ parse_sig_rr(char *buf, int buf_len, u_char *data, int data_size, if (!getmlword(buf, my_buf_size, fp, 0)) ERRTO("Missing label count"); la = wordtouint32(buf); - if (0 == la || wordtouint32_error || 255 <= la) + if (wordtouint32_error || 255 <= la || + (0 == la && *domain != '\0')) ERRTO("Bad label count number"); data[i] = (u_char) la; i++; diff --git a/contrib/bind/bin/named/db_lookup.c b/contrib/bind/bin/named/db_lookup.c index 400523e..00b3d8d 100644 --- a/contrib/bind/bin/named/db_lookup.c +++ b/contrib/bind/bin/named/db_lookup.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)db_lookup.c 4.18 (Berkeley) 3/21/91"; -static const char rcsid[] = "$Id: db_lookup.c,v 8.24 1999/10/15 19:48:58 vixie Exp $"; +static const char rcsid[] = "$Id: db_lookup.c,v 8.26 2000/04/21 06:54:03 vixie Exp $"; #endif /* not lint */ /* @@ -57,7 +57,7 @@ static const char rcsid[] = "$Id: db_lookup.c,v 8.24 1999/10/15 19:48:58 vixie E */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -291,8 +291,18 @@ nxtlower(const char *name, struct databuf *dp) { int nxtmatch(const char *name, struct databuf *dp1, struct databuf *dp2) { int dp1_lower, dp2_lower; - - if (dp1->d_type != ns_t_nxt || dp2->d_type != ns_t_nxt) + int type1, type2; + + if (dp1->d_type == ns_t_sig) + type1 = SIG_COVERS(dp1); + else + type1 = dp1->d_type; + if (dp2->d_type == ns_t_sig) + type2 = SIG_COVERS(dp2); + else + type2 = dp2->d_type; + + if (type1 != ns_t_nxt || type2 != ns_t_nxt) return (0); dp1_lower = nxtlower(name, dp1); dp2_lower = nxtlower(name, dp2); diff --git a/contrib/bind/bin/named/db_save.c b/contrib/bind/bin/named/db_save.c index c4db46a..1fe0e73 100644 --- a/contrib/bind/bin/named/db_save.c +++ b/contrib/bind/bin/named/db_save.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)db_save.c 4.16 (Berkeley) 3/21/91"; -static const char rcsid[] = "$Id: db_save.c,v 8.26 1999/10/13 16:39:02 vixie Exp $"; +static const char rcsid[] = "$Id: db_save.c,v 8.27 2000/04/21 06:54:03 vixie Exp $"; #endif /* not lint */ /* @@ -57,7 +57,7 @@ static const char rcsid[] = "$Id: db_save.c,v 8.26 1999/10/13 16:39:02 vixie Exp */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/contrib/bind/bin/named/db_sec.c b/contrib/bind/bin/named/db_sec.c index bb31fae..2ed4a4c 100644 --- a/contrib/bind/bin/named/db_sec.c +++ b/contrib/bind/bin/named/db_sec.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: db_sec.c,v 8.30 1999/10/15 21:06:49 vixie Exp $"; +static const char rcsid[] = "$Id: db_sec.c,v 8.31 2000/04/21 06:54:04 vixie Exp $"; #endif /* not lint */ /* @@ -57,7 +57,7 @@ static const char rcsid[] = "$Id: db_sec.c,v 8.30 1999/10/15 21:06:49 vixie Exp */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/contrib/bind/bin/named/db_tsig.c b/contrib/bind/bin/named/db_tsig.c index d95031d..e8e81f9 100644 --- a/contrib/bind/bin/named/db_tsig.c +++ b/contrib/bind/bin/named/db_tsig.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: db_tsig.c,v 8.5 1999/10/15 19:48:59 vixie Exp $"; +static const char rcsid[] = "$Id: db_tsig.c,v 8.6 2000/04/21 06:54:04 vixie Exp $"; #endif /* not lint */ /* @@ -57,7 +57,7 @@ static const char rcsid[] = "$Id: db_tsig.c,v 8.5 1999/10/15 19:48:59 vixie Exp */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/contrib/bind/bin/named/db_update.c b/contrib/bind/bin/named/db_update.c index ea0176e..3bd9838 100644 --- a/contrib/bind/bin/named/db_update.c +++ b/contrib/bind/bin/named/db_update.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)db_update.c 4.28 (Berkeley) 3/21/91"; -static const char rcsid[] = "$Id: db_update.c,v 8.39 1999/10/15 19:48:59 vixie Exp $"; +static const char rcsid[] = "$Id: db_update.c,v 8.42 2000/04/21 06:54:04 vixie Exp $"; #endif /* not lint */ /* @@ -57,7 +57,7 @@ static const char rcsid[] = "$Id: db_update.c,v 8.39 1999/10/15 19:48:59 vixie E */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -169,10 +169,6 @@ findMyZone(struct namebuf *np, int class) { return (DB_Z_CACHE); } - -#define ISVALIDGLUE(xdp) ((xdp)->d_type == T_NS || (xdp)->d_type == T_A \ - || (xdp)->d_type == T_AAAA) - /* int * db_update(name, odp, newdp, savedpp, flags, htp, from) * update data base node at `name'. `flags' controls the action. @@ -591,9 +587,9 @@ db_update(const char *name, if ((flags & DB_REPLACE) == 0 && zones[dp->d_zone].z_type == Z_PRIMARY) { - ns_info(ns_log_db, + ns_warning(ns_log_db, "%s has multiple CNAMES", - name); + name); return (CNAMEANDOTHER); } else goto delete; diff --git a/contrib/bind/bin/named/named.h b/contrib/bind/bin/named/named.h index 18f4ac4..e9e95fa 100644 --- a/contrib/bind/bin/named/named.h +++ b/contrib/bind/bin/named/named.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996-1999 by Internet Software Consortium. + * Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -16,7 +16,7 @@ */ /* - * $Id: named.h,v 8.25 1999/10/13 18:00:19 vixie Exp $ + * $Id: named.h,v 8.27 2000/04/21 06:54:04 vixie Exp $ */ /* Options. Change them at your peril. */ @@ -30,7 +30,6 @@ #define QRYLOG #define YPKLUDGE #define RENICE -#define SLAVE_FORWARD #define BIND_IXFR #define BIND_NOTIFY #define BIND_UPDATE diff --git a/contrib/bind/bin/named/ns_config.c b/contrib/bind/bin/named/ns_config.c index 67bffbd..670e288 100644 --- a/contrib/bind/bin/named/ns_config.c +++ b/contrib/bind/bin/named/ns_config.c @@ -1,9 +1,9 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_config.c,v 8.104 1999/11/08 23:09:42 vixie Exp $"; +static const char rcsid[] = "$Id: ns_config.c,v 8.114 2000/04/23 02:18:58 vixie Exp $"; #endif /* not lint */ /* - * Copyright (c) 1996-1999 by Internet Software Consortium. + * Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -431,7 +431,6 @@ begin_zone(char *name, int class) { zp->z_origin = name; zp->z_class = class; zp->z_checknames = not_set; - zp->z_log_size_ixfr = 0; if (server_options->flags & OPTION_MAINTAIN_IXFR_BASE) zp->z_maintain_ixfr_base = 1; else @@ -478,7 +477,6 @@ update_zone_info(struct zoneinfo *zp, struct zoneinfo *new_zp) { new_zp->z_origin = NULL; zp->z_maintain_ixfr_base = new_zp->z_maintain_ixfr_base; zp->z_max_log_size_ixfr = new_zp->z_max_log_size_ixfr; - zp->z_log_size_ixfr = new_zp->z_log_size_ixfr; zp->z_class = new_zp->z_class; zp->z_type = new_zp->z_type; zp->z_checknames = new_zp->z_checknames; @@ -557,6 +555,7 @@ update_zone_info(struct zoneinfo *zp, struct zoneinfo *new_zp) { /* File has changed, or hasn't been loaded yet. */ if (zp->z_source) { freestr(zp->z_source); + ns_stopxfrs(zp); purge_zone(zp->z_origin, fcachetab, zp->z_class); } zp->z_source = new_zp->z_source; @@ -684,7 +683,8 @@ update_zone_info(struct zoneinfo *zp, struct zoneinfo *new_zp) { zp->z_ixfr_tmp = new_zp->z_ixfr_tmp; new_zp->z_ixfr_tmp = NULL; - if ((zp->z_flags & Z_AUTH) == 0) + if ((!noexpired || ((zp->z_flags & Z_EXPIRED) == 0)) && + ((zp->z_flags & Z_AUTH) == 0)) zoneinit(zp); else { /* @@ -833,7 +833,7 @@ set_zone_ixfr_file(zone_config zh, char *filename) { return (0); zp->z_ixfr_base = filename; if (zp->z_ixfr_tmp == NULL) { - int len = strlen(zp->z_ixfr_base) + (sizeof ".tmp" - 1); + int len = strlen(zp->z_ixfr_base) + (sizeof ".tmp"); char *str = (char *) memget(len); sprintf(str, "%s.tmp", zp->z_ixfr_base); @@ -1450,6 +1450,7 @@ write_open(char *filename) { S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); if (fd < 0) return (NULL); + (void) fchown(fd, user_id, group_id); stream = fdopen(fd, "w"); if (stream == NULL) (void)close(fd); @@ -2067,7 +2068,7 @@ ip_match_addr_or_key(ip_match_list iml, struct in_addr address, if (indirect) { ret = ip_match_addr_or_key(ime->u.indirect.list, address, key); - if (ret >= 0) { + if (ret > 0) { if (ime->flags & IP_MATCH_NEGATE) ret = (ret) ? 0 : 1; return (ret); @@ -2246,7 +2247,79 @@ ip_match_is_none(ip_match_list iml) { return (0); } +/* + * find_forwarder finds the fwddata structure for an address, + * allocating one if we can't find one already existing. + */ + +static struct fwddata * +find_forwarder(struct in_addr address) +{ + struct fwddata *fdp; + struct databuf *ns, *nsdata; + register int i; + + for (i=0;ifwdaddr.sin_addr,&address,sizeof(address))==0) { + fdp->ref_count++; + return fdp; + } + } + fdp = (struct fwddata *)memget(sizeof(struct fwddata)); + if (!fdp) + panic("memget failed in find_forwarder", NULL); + fdp->fwdaddr.sin_family = AF_INET; + fdp->fwdaddr.sin_addr = address; + fdp->fwdaddr.sin_port = ns_port; + ns = fdp->ns = (struct databuf *)memget(sizeof(*ns)); + if (!ns) + panic("memget failed in find_forwarder", NULL); + memset(ns,0,sizeof(*ns)); + nsdata = fdp->nsdata = (struct databuf *)memget(sizeof(*nsdata)); + if (!nsdata) + panic("memget failed in find_forwarder", NULL); + memset(nsdata,0,sizeof(*nsdata)); + ns->d_type = T_NS; + ns->d_class = C_IN; + ns->d_rcnt=1; + nsdata->d_type = T_A; + nsdata->d_class = C_IN; + nsdata->d_nstime = 1 + (int)(25.0*rand()/(RAND_MAX + 1.0)); + nsdata->d_rcnt=1; + fdp->ref_count=1; + + i=0; + if (fwddata == NULL) { + fwddata = memget(sizeof *fwddata); + if (fwddata == NULL) + i = 1; + } else { + register size_t size; + register struct fwddata **an_tmp; + size = fwddata_count * sizeof *fwddata; + an_tmp = memget(size + sizeof *fwddata); + if (an_tmp == NULL) { + i = 1; + } else { + memcpy(an_tmp, fwddata, size); + memput(fwddata, size); + fwddata = an_tmp; + } + } + + if (i == 0) { + fwddata[fwddata_count] = fdp; + fwddata_count++; + } else { + ns_warning(ns_log_config, + "forwarder add failed (memget) [%s]", + inet_ntoa(address)); + } + + return fdp; +} /* * Forwarder glue * @@ -2257,25 +2330,25 @@ ip_match_is_none(ip_match_list iml) { static void add_forwarder(struct fwdinfo **fipp, struct in_addr address) { struct fwdinfo *fip = *fipp, *ftp = NULL; + struct fwddata *fdp; + +#ifdef FWD_LOOP + if (aIsUs(address)) { + ns_error(ns_log_config, "forwarder '%s' ignored, my address", + inet_ntoa(address)); + return; + } +#endif /* FWD_LOOP */ /* On multiple forwarder lines, move to end of the list. */ while (fip != NULL && fip->next != NULL) fip = fip->next; + fdp = find_forwarder(address); ftp = (struct fwdinfo *)memget(sizeof(struct fwdinfo)); if (!ftp) panic("memget failed in add_forwarder", NULL); - ftp->fwdaddr.sin_family = AF_INET; - ftp->fwdaddr.sin_addr = address; - ftp->fwdaddr.sin_port = ns_port; -#ifdef FWD_LOOP - if (aIsUs(ftp->fwdaddr.sin_addr)) { - ns_error(ns_log_config, "forwarder '%s' ignored, my address", - inet_ntoa(address)); - memput(ftp, sizeof *ftp); - return; - } -#endif /* FWD_LOOP */ + ftp->fwddata = fdp; ftp->next = NULL; if (fip == NULL) *fipp = ftp; /* First time only */ @@ -2346,10 +2419,6 @@ add_global_also_notify(options op, struct in_addr address) { void add_global_forwarder(options op, struct in_addr address) { -#ifdef SLAVE_FORWARD - struct fwdinfo *fip; - int forward_count; -#endif INSIST(op != NULL); @@ -2357,20 +2426,6 @@ add_global_forwarder(options op, struct in_addr address) { inet_ntoa(address)); add_forwarder(&op->fwdtab, address); - -#ifdef SLAVE_FORWARD - /* - ** Set the slave retry time to 60 seconds total divided - ** between each forwarder - */ - for (forward_count = 0, fip = op->fwdtab; fip != NULL; fip = fip->next) - forward_count++; - if (forward_count != 0) { - slave_retry = (int) (60 / forward_count); - if(slave_retry <= 0) - slave_retry = 1; - } -#endif } void @@ -2405,6 +2460,12 @@ free_forwarders(struct fwdinfo *fwdtab) { for (ftp = fwdtab; ftp != NULL; ftp = fnext) { fnext = ftp->next; + if (!--ftp->fwddata->ref_count) { + memput(ftp->fwddata->ns, sizeof *ftp->fwddata->ns); + memput(ftp->fwddata->nsdata, + sizeof *ftp->fwddata->nsdata); + memput(ftp->fwddata,sizeof *ftp->fwddata); + } memput(ftp, sizeof *ftp); } fwdtab = NULL; @@ -2911,16 +2972,19 @@ init_default_log_channels() { 0, ULONG_MAX); if (debug_channel == NULL || log_inc_references(debug_channel) < 0) ns_panic(ns_log_config, 0, "couldn't create debug_channel"); + log_set_file_owner(debug_channel, user_id, group_id); stderr_channel = log_new_file_channel(0, log_info, NULL, stderr, 0, ULONG_MAX); if (stderr_channel == NULL || log_inc_references(stderr_channel) < 0) ns_panic(ns_log_config, 0, "couldn't create stderr_channel"); + log_set_file_owner(stderr_channel, user_id, group_id); null_channel = log_new_file_channel(LOG_CHANNEL_OFF, log_info, _PATH_DEVNULL, NULL, 0, ULONG_MAX); if (null_channel == NULL || log_inc_references(null_channel) < 0) ns_panic(ns_log_config, 0, "couldn't create null_channel"); + log_set_file_owner(null_channel, user_id, group_id); } static void @@ -3057,4 +3121,6 @@ load_configuration(const char *filename) { initial_configuration = 0; loading = 0; + /* release queued notifies */ + notify_afterload(); } diff --git a/contrib/bind/bin/named/ns_ctl.c b/contrib/bind/bin/named/ns_ctl.c index 259093b..66cb862 100644 --- a/contrib/bind/bin/named/ns_ctl.c +++ b/contrib/bind/bin/named/ns_ctl.c @@ -1,9 +1,9 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_ctl.c,v 8.28 1999/10/13 16:39:04 vixie Exp $"; +static const char rcsid[] = "$Id: ns_ctl.c,v 8.34 2000/04/21 06:54:05 vixie Exp $"; #endif /* not lint */ /* - * Copyright (c) 1997-1999 by Internet Software Consortium. + * Copyright (c) 1997-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -68,12 +68,14 @@ struct control { struct sockaddr_in in; ip_match_list allow; } v_inet; +#ifndef NO_SOCKADDR_UN struct { struct sockaddr_un un; mode_t mode; uid_t owner; gid_t group; } v_unix; +#endif } var; }; @@ -150,7 +152,7 @@ static struct ctl_verb verbs[] = { { "stop", verb_stop, "stop"}, { "exec", verb_exec, "exec"}, { "reload", verb_reload, "reload [zone] ..."}, - { "reconfig", verb_reconfig, "reconfig (just sees new/gone zones)"}, + { "reconfig", verb_reconfig, "reconfig [-noexpired] (just sees new/gone zones)"}, { "dumpdb", verb_dumpdb, "dumpdb"}, { "stats", verb_stats, "stats"}, { "trace", verb_trace, "trace [level]"}, @@ -177,7 +179,29 @@ ns_ctl_shutdown(void) { void ns_ctl_defaults(controls *list) { +#ifdef NO_SOCKADDR_UN + struct in_addr saddr; + ip_match_list iml; + ip_match_element ime; + + /* + * If the operating system does not support local domain sockets, + * connect with ndc on 127.0.0.1, port 101, and only allow + * connections from 127.0.0.1. + */ + saddr.s_addr = htonl (INADDR_LOOPBACK); + iml = new_ip_match_list(); + ime = new_ip_match_pattern(saddr, 32); + add_to_ip_match_list(iml, ime); + + ns_ctl_add(list, ns_ctl_new_inet(saddr, htons (101), iml)); +#else +#ifdef NEED_SECURE_DIRECTORY + ns_ctl_add(list, ns_ctl_new_unix(_PATH_NDCSOCK, 0700, 0, 0)); +#else ns_ctl_add(list, ns_ctl_new_unix(_PATH_NDCSOCK, 0600, 0, 0)); +#endif +#endif /*NO_SOCKADDR_UN*/ } void @@ -200,6 +224,7 @@ ns_ctl_new_inet(struct in_addr saddr, u_int sport, ip_match_list allow) { return (new); } +#ifndef NO_SOCKADDR_UN control ns_ctl_new_unix(char *path, mode_t mode, uid_t owner, gid_t group) { control new = new_control(); @@ -215,6 +240,7 @@ ns_ctl_new_unix(char *path, mode_t mode, uid_t owner, gid_t group) { new->var.v_unix.group = group; return (new); } +#endif void ns_ctl_install(controls *new) { @@ -288,6 +314,7 @@ free_control(controls *list, control this) { this->var.v_inet.allow = NULL; } break; +#ifndef NO_SOCKADDR_UN case t_unix: /* XXX Race condition. */ if (was_live && @@ -297,6 +324,7 @@ free_control(controls *list, control this) { unlink(this->var.v_unix.un.sun_path); } break; +#endif default: panic("impossible type in free_control", NULL); /* NOTREACHED */ @@ -333,6 +361,7 @@ match_control(control l, control r) { r->var.v_inet.in.sin_addr.s_addr) match = 0; break; +#ifndef NO_SOCKADDR_UN case t_unix: if (l->var.v_unix.un.sun_family != r->var.v_unix.un.sun_family || @@ -340,6 +369,7 @@ match_control(control l, control r) { r->var.v_unix.un.sun_path) != 0) match = 0; break; +#endif default: panic("impossible type in match_control", NULL); /* NOTREACHED */ @@ -370,6 +400,7 @@ propagate_changes(const control diff, control base) { diff->var.v_inet.allow = NULL; need_install++; break; +#ifndef NO_SOCKADDR_UN case t_unix: if (base->var.v_unix.mode != diff->var.v_unix.mode) { base->var.v_unix.mode = diff->var.v_unix.mode; @@ -384,6 +415,7 @@ propagate_changes(const control diff, control base) { need_install++; } break; +#endif default: panic("impossible type in ns_ctl::propagate_changes", NULL); /* NOTREACHED */ @@ -398,9 +430,11 @@ install(control ctl) { case t_inet: install_inet(ctl); break; +#ifndef NO_SOCKADDR_UN case t_unix: install_unix(ctl); break; +#endif default: panic("impossible type in ns_ctl::install", NULL); /* NOTREACHED */ @@ -416,6 +450,7 @@ install_inet(control ctl) { } } +#ifndef NO_SOCKADDR_UN /* * Unattach an old unix domain socket if it exists. */ @@ -478,6 +513,35 @@ unattach(control ctl) { static void install_unix(control ctl) { + char *path; +#ifdef NEED_SECURE_DIRECTORY + char *slash; + + path = savestr(ctl->var.v_unix.un.sun_path, 1); + + slash = strrchr(path, '/'); + if (slash != NULL) { + if (slash != path) + *slash = '\0'; + else { + freestr(path); + path = savestr("/", 1); + } + } else { + freestr(path); + path = savestr(".", 1); + } + if (mkdir(path, ctl->var.v_unix.mode) < 0) { + if (errno != EEXIST) { + ns_warning(ns_log_config, + "unix control \"%s\" mkdir failed: %s", + path, strerror(errno)); + } + } +#else + path = ctl->var.v_unix.un.sun_path; +#endif + if (ctl->sctx == NULL) { unattach(ctl); ctl->sctx = mksrvr(ctl, @@ -486,15 +550,13 @@ install_unix(control ctl) { } if (ctl->sctx != NULL) { /* XXX Race condition. */ - if (chmod(ctl->var.v_unix.un.sun_path, - ctl->var.v_unix.mode) < 0) { + if (chmod(path, ctl->var.v_unix.mode) < 0) { ns_warning(ns_log_config, "chmod(\"%s\", 0%03o): %s", ctl->var.v_unix.un.sun_path, ctl->var.v_unix.mode, strerror(errno)); } - if (chown(ctl->var.v_unix.un.sun_path, - ctl->var.v_unix.owner, + if (chown(path, ctl->var.v_unix.owner, ctl->var.v_unix.group) < 0) { ns_warning(ns_log_config, "chown(\"%s\", %d, %d): %s", ctl->var.v_unix.un.sun_path, @@ -503,7 +565,11 @@ install_unix(control ctl) { strerror(errno)); } } +#ifdef NEED_SECURE_DIRECTORY + freestr(path); +#endif } +#endif static void logger(enum ctl_severity ctlsev, const char *format, ...) { @@ -747,6 +813,8 @@ verb_reload(struct ctl_sctx *ctl, struct ctl_sess *sess, case z_slave: case z_stub: ns_stopxfrs(zp); + if (zonefile_changed_p(zp)) + zp->z_serial = 0; /* force xfer */ addxfer(zp); code = 251; msg = "Slave transfer queued."; @@ -770,7 +838,10 @@ verb_reconfig(struct ctl_sctx *ctl, struct ctl_sess *sess, const struct ctl_verb *verb, const char *rest, u_int respflags, void *respctx, void *uctx) { - ns_need(main_need_reconfig); + if (strcmp(rest, "-noexpired") != 0) + ns_need(main_need_reconfig); + else + ns_need(main_need_noexpired); ctl_response(sess, 250, "Reconfig initiated.", 0, NULL, NULL, NULL, NULL, 0); } diff --git a/contrib/bind/bin/named/ns_defs.h b/contrib/bind/bin/named/ns_defs.h index 801e5a9..56b50fe 100644 --- a/contrib/bind/bin/named/ns_defs.h +++ b/contrib/bind/bin/named/ns_defs.h @@ -1,6 +1,6 @@ /* * from ns.h 4.33 (Berkeley) 8/23/90 - * $Id: ns_defs.h,v 8.89 1999/10/07 08:24:08 vixie Exp $ + * $Id: ns_defs.h,v 8.96 2000/04/21 06:54:06 vixie Exp $ */ /* @@ -57,7 +57,7 @@ */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -165,7 +165,9 @@ typedef enum need { main_need_debug, /* use_desired_debug() needed. */ main_need_restart, /* exec() needed. */ main_need_reap, /* need to reap dead children */ - main_need_num /* number of needs, used for array bound. */ + main_need_noexpired, /* ns_reconfig() needed w/ noexpired set */ + main_need_num, /* number of needs, used for array bound. */ + main_need_tick /* tick every second to poll for cleanup (NT)*/ } main_need; /* What global options are set? */ @@ -181,13 +183,13 @@ typedef enum need { * CNAME RRs */ #define OPTION_HOSTSTATS 0x0080 /* Maintain per-host statistics? */ #define OPTION_DEALLOC_ON_EXIT 0x0100 /* Deallocate everything on exit? */ -#define OPTION_USE_IXFR 0x0110 /* Use by delault ixfr in zone transfer */ -#define OPTION_MAINTAIN_IXFR_BASE 0x0120 #define OPTION_NODIALUP 0x0200 /* Turn off dialup support */ #define OPTION_NORFC2308_TYPE1 0x0400 /* Prevent type1 respones (RFC 2308) * to cached negative respones */ #define OPTION_USE_ID_POOL 0x0800 /* Use the memory hogging query ID */ #define OPTION_TREAT_CR_AS_SPACE 0x1000 /* Treat CR in zone files as space */ +#define OPTION_USE_IXFR 0x2000 /* Use by delault ixfr in zone transfer */ +#define OPTION_MAINTAIN_IXFR_BASE 0x4000 /* Part of IXFR file name logic. */ #define DEFAULT_OPTION_FLAGS (OPTION_NODIALUP|OPTION_NONAUTH_NXDOMAIN|\ OPTION_USE_ID_POOL|OPTION_NORFC2308_TYPE1) @@ -306,7 +308,8 @@ typedef struct ztimer_info { int type; } *ztimer_info; -/* these fields are ordered to maintain word-alignment; +/* + * These fields are ordered to maintain word-alignment; * be careful about changing them. */ struct zoneinfo { @@ -359,9 +362,9 @@ struct zoneinfo { enum zdialup z_dialup; /* secondaries over a dialup link */ char *z_ixfr_base; /* where to find the history of the zone */ char *z_ixfr_tmp; /* tmp file for the ixfr */ - int z_maintain_ixfr_base; - int z_log_size_ixfr; - int z_max_log_size_ixfr; + int z_maintain_ixfr_base; + long z_max_log_size_ixfr; + u_int32_t z_serial_ixfr_start; evTimerID z_timer; /* maintenance timer */ ztimer_info z_timerinfo; /* UAP associated with timer */ time_t z_nextmaint; /* time of next maintenance */ @@ -410,6 +413,7 @@ enum zonetype { z_nil, z_master, z_slave, z_hint, z_stub, z_forward, #define Z_NEED_QSERIAL 0x00020000 /* we need to re-call qserial() */ #define Z_PARENT_RELOAD 0x00040000 /* we need to reload this as parent */ #define Z_FORWARD_SET 0x00080000 /* has forwarders been set */ +#define Z_EXPIRED 0x00100000 /* expire timer has gone off */ /* named_xfer exit codes */ #define XFER_UPTODATE 0 /* zone is up-to-date */ @@ -507,6 +511,14 @@ struct fdlist { }; #endif + +typedef struct ns_delta { + LINK(struct ns_delta) d_link; + ns_updque d_changes; +} ns_delta; + +typedef LIST(ns_delta) ns_deltalist; + typedef struct _interface { int dfd, /* Datagram file descriptor */ sfd; /* Stream file descriptor. */ @@ -570,7 +582,7 @@ struct qstream { u_int zone; /* zone being XFR'd. */ union { struct namebuf *axfr; /* top np of an AXFR. */ - struct ns_updrec *ixfr; /* top udp of an IXFR. */ + ns_deltalist *ixfr; /* top udp of an IXFR. */ } top; int ixfr_zone; u_int32_t serial; /* serial number requested in IXFR */ @@ -602,16 +614,23 @@ struct qstream { #define STREAM_CONNECT_EV 0x08 #define STREAM_DONE_CLOSE 0x10 #define STREAM_AXFR 0x20 -#define STREAM_AXFRIXFR 0x22 +#define STREAM_AXFRIXFR 0x40 #define ALLOW_NETS 0x0001 #define ALLOW_HOSTS 0x0002 #define ALLOW_ALL (ALLOW_NETS | ALLOW_HOSTS) +struct fwddata { + struct sockaddr_in + fwdaddr; /* address of NS */ + struct databuf *ns; /* databuf for NS record */ + struct databuf *nsdata; /* databuf for server address */ + int ref_count; /* how many users of this */ +}; + struct fwdinfo { struct fwdinfo *next; - struct sockaddr_in - fwdaddr; + struct fwddata *fwddata; }; enum nameserStats { nssRcvdR, /* sent us an answer */ @@ -639,6 +658,10 @@ enum nameserStats { nssRcvdR, /* sent us an answer */ nssSentFErr, /* sent them a FORMERR */ nssSentNaAns, /* sent them a non autoritative answer */ nssSentNXD, /* sent them a negative response */ + nssRcvdUQ, /* sent us an unapproved query */ + nssRcvdURQ, /* sent us an unapproved recursive query */ + nssRcvdUXFR, /* sent us an unapproved AXFR or IXFR */ + nssRcvdUUpd, /* sent us an unapproved update */ nssLast }; struct nameser { diff --git a/contrib/bind/bin/named/ns_forw.c b/contrib/bind/bin/named/ns_forw.c index 3a4e488..beb919c 100644 --- a/contrib/bind/bin/named/ns_forw.c +++ b/contrib/bind/bin/named/ns_forw.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)ns_forw.c 4.32 (Berkeley) 3/3/91"; -static const char rcsid[] = "$Id: ns_forw.c,v 8.68 1999/10/13 16:39:07 vixie Exp $"; +static const char rcsid[] = "$Id: ns_forw.c,v 8.75 2000/05/09 07:12:58 vixie Exp $"; #endif /* not lint */ /* @@ -57,7 +57,7 @@ static const char rcsid[] = "$Id: ns_forw.c,v 8.68 1999/10/13 16:39:07 vixie Exp */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -160,7 +160,7 @@ ns_forw(struct databuf *nsp[], u_char *msg, int msglen, } } - qp = qnew(dname, class, type); + qp = qnew(dname, class, type, 1); getname(np, tmpdomain, sizeof tmpdomain); qp->q_domain = savestr(tmpdomain, 1); qp->q_from = from; /* nslookup wants to know this */ @@ -208,11 +208,6 @@ ns_forw(struct databuf *nsp[], u_char *msg, int msglen, hp->rd = (qp->q_addr[0].forwarder ? 1 : 0); qp->q_addr[0].stime = tt; -#ifdef SLAVE_FORWARD - if (NS_ZOPTION_P(qp->q_fzone, OPTION_FORWARD_ONLY)) - schedretry(qp, (time_t)slave_retry); - else -#endif /* SLAVE_FORWARD */ schedretry(qp, retrytime(qp)); nsa = Q_NEXTADDR(qp, 0); @@ -288,8 +283,7 @@ ns_forw(struct databuf *nsp[], u_char *msg, int msglen, hp = (HEADER *) qp->q_msg; } - if (NS_OPTION_P(OPTION_HOSTSTATS)) - nameserIncr(from.sin_addr, nssRcvdFwdQ); + nameserIncr(from.sin_addr, nssRcvdFwdQ); nameserIncr(nsa->sin_addr, nssSentFwdQ); if (qpp) *qpp = qp; @@ -470,7 +464,7 @@ nslookup(struct databuf *nsp[], struct qinfo *qp, lame_ns = potential_ns = 0; naddr = n = qp->q_naddr; curtime = (u_long) tt.tv_sec; - while ((nsdp = *nsp++) != NULL) { + while ((nsdp = *nsp++) != NULL && n < NSMAX) { class = nsdp->d_class; dname = (char *)nsdp->d_data; ns_debug(ns_log_default, 3, @@ -668,7 +662,7 @@ nslookup(struct databuf *nsp[], struct qinfo *qp, n++; if (n >= NSMAX) - goto out; + break; skipaddr: (void)NULL; } @@ -703,8 +697,11 @@ nslookup(struct databuf *nsp[], struct qinfo *qp, DRCNTINC(qp->q_addr[i].nsdata); DRCNTINC(qp->q_addr[i].ns); } - if (n > 1) { - qsort((char *)qp->q_addr, n, sizeof(struct qserv), + /* Just sort the NS RR's we added, since the forwarders may + * be ahead of us (naddr > 0) + */ + if (n > naddr) { + qsort((char *)(qp->q_addr+naddr), n-naddr, sizeof(struct qserv), (int (*)(const void *, const void *))qcomp); } return (n - naddr); @@ -761,51 +758,51 @@ nslookup(struct databuf *nsp[], struct qinfo *qp, * RTT delta deemed to be significant, in milliseconds. With the current * definition of RTTROUND it must be a power of 2. */ -#define NOISE 128 /* milliseconds; 0.128 seconds */ +#define NOISE 64 -#define sign(x) (((x) < 0) ? -1 : ((x) > 0) ? 1 : 0) #define RTTROUND(rtt) (((rtt) + (NOISE >> 1)) & ~(NOISE - 1)) int qcomp(struct qserv *qs1, struct qserv *qs2) { - int pos1, pos2, pdiff; - u_long rtt1, rtt2; - long tdiff; + u_int rtt1, rtt2, rttr1, rttr2; - if ((!qs1->nsdata) || (!qs2->nsdata)) - return 0; - rtt1 = qs1->nsdata->d_nstime; - rtt2 = qs2->nsdata->d_nstime; + if (qs1->nsdata == NULL || qs2->nsdata == NULL) { + rtt1 = 0; + rttr1 = 0; + rtt2 = 0; + rttr2 = 0; + } else { + rtt1 = qs1->nsdata->d_nstime; + rttr1 = RTTROUND(rtt1); + rtt2 = qs2->nsdata->d_nstime; + rttr2 = RTTROUND(rtt2); + } #ifdef DEBUG if (debug >= 10) { - char a1[sizeof "255.255.255.255"], - a2[sizeof "255.255.255.255"]; + char t[sizeof "255.255.255.255"]; - strcpy(a1, inet_ntoa(qs1->ns_addr.sin_addr)); - strcpy(a2, inet_ntoa(qs2->ns_addr.sin_addr)); + strcpy(t, inet_ntoa(qs1->ns_addr.sin_addr)); ns_debug(ns_log_default, 10, "qcomp(%s, %s) %lu (%lu) - %lu (%lu) = %lu", - a1, a2, - rtt1, RTTROUND(rtt1), - rtt2, RTTROUND(rtt2), - rtt1 - rtt2); + t, inet_ntoa(qs2->ns_addr.sin_addr), + rtt1, rttr1, rtt2, rttr2, rtt1 - rtt2); } #endif - if (RTTROUND(rtt1) == RTTROUND(rtt2)) { + if (rttr1 == rttr2) { + int pos1, pos2, pdiff; + pos1 = distance_of_address(server_options->topology, qs1->ns_addr.sin_addr); pos2 = distance_of_address(server_options->topology, qs2->ns_addr.sin_addr); pdiff = pos1 - pos2; ns_debug(ns_log_default, 10, "\tpos1=%d, pos2=%d", pos1, pos2); - if (pdiff) + if (pdiff != 0) return (pdiff); } - tdiff = rtt1 - rtt2; - return (sign(tdiff)); + return (rtt1 - rtt2); } -#undef sign #undef RTTROUND /* @@ -1076,11 +1073,6 @@ retry(struct qinfo *qp) { schedretry(qp, (time_t) 0); return; } -#ifdef SLAVE_FORWARD - if (NS_ZOPTION_P(qp->q_fzone, OPTION_FORWARD_ONLY)) - schedretry(qp, (time_t)slave_retry); - else -#endif /* SLAVE_FORWARD */ schedretry(qp, retrytime(qp)); } @@ -1140,7 +1132,7 @@ qfindid(u_int16_t id) { } struct qinfo * -qnew(const char *name, int class, int type) { +qnew(const char *name, int class, int type, int forward) { struct qinfo *qp; const char *s; int escape = 0; @@ -1160,7 +1152,8 @@ qnew(const char *name, int class, int type) { qp->q_type = (u_int16_t)type; qp->q_flags = 0; s = name; - for (;;) { /* find forwarding zone, if any */ + qp->q_fzone = NULL; + for (;forward;) { /* find forwarding zone, if any */ if ((qp->q_fzone = find_zone(s, class)) != NULL && (qp->q_fzone->z_flags & Z_FORWARD_SET) != 0) break; @@ -1250,15 +1243,15 @@ nsfwdadd(struct qinfo *qp, struct fwdinfo *fwd) { struct qserv *qs; n = qp->q_naddr; - while (fwd != NULL && n < MAXNS) { + while (fwd != NULL && n < NSMAX) { qs = qp->q_addr; for (i = 0; i < (u_int)n; i++, qs++) if (ina_equal(qs->ns_addr.sin_addr, - fwd->fwdaddr.sin_addr)) + fwd->fwddata->fwdaddr.sin_addr)) goto nextfwd; - qs->ns_addr = fwd->fwdaddr; - qs->ns = NULL; - qs->nsdata = NULL; + qs->ns_addr = fwd->fwddata->fwdaddr; + qs->ns = fwd->fwddata->ns; + qs->nsdata = fwd->fwddata->nsdata; qs->forwarder = 1; qs->nretry = 0; n++; @@ -1266,4 +1259,14 @@ nsfwdadd(struct qinfo *qp, struct fwdinfo *fwd) { fwd = fwd->next; } qp->q_naddr = n; + + /* Update the refcounts before the sort. */ + for (i = 0; i < (u_int)n; i++) { + DRCNTINC(qp->q_addr[i].nsdata); + DRCNTINC(qp->q_addr[i].ns); + } + if (n > 1) { + qsort((char *)qp->q_addr, n, sizeof(struct qserv), + (int (*)(const void *, const void *))qcomp); + } } diff --git a/contrib/bind/bin/named/ns_func.h b/contrib/bind/bin/named/ns_func.h index 88c181ca..760266d 100644 --- a/contrib/bind/bin/named/ns_func.h +++ b/contrib/bind/bin/named/ns_func.h @@ -52,7 +52,7 @@ */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -90,7 +90,7 @@ /* ns_func.h - declarations for ns_*.c's externally visible functions * - * $Id: ns_func.h,v 8.90 1999/10/11 18:22:20 vixie Exp $ + * $Id: ns_func.h,v 8.96 2000/04/21 06:54:06 vixie Exp $ */ /* ++from ns_glue.c++ */ @@ -146,7 +146,9 @@ int movefile(const char *, const char *); /* ++from ns_notify.c++ */ #ifdef BIND_NOTIFY void ns_notify(const char *, ns_class, ns_type); +void notify_afterload(void); void ns_unnotify(void); +void ns_stopnotify(const char *, ns_class); #endif /* --from ns_notify.c-- */ @@ -254,7 +256,7 @@ extern void schedretry(struct qinfo *, time_t), freeComplaints(void), nsfwdadd(struct qinfo *, struct fwdinfo *); extern struct qinfo *qfindid(u_int16_t), - *qnew(const char *, int, int); + *qnew(const char *, int, int, int); /* --from ns_forw.c-- */ /* ++from ns_main.c++ */ @@ -302,7 +304,8 @@ extern void zone_maint(struct zoneinfo *), addxfer(struct zoneinfo *), ns_zreload(void), ns_reload(void), - ns_reconfig(void); + ns_reconfig(void), + ns_noexpired(void); #if 0 extern int reload_all_unsafe(void); #endif @@ -318,6 +321,8 @@ extern void ns_heartbeat(evContext ctx, void *uap, extern void make_new_zones(void); extern void free_zone(struct zoneinfo *); extern struct zoneinfo *find_auth_zone(const char *, ns_class); +extern int purge_nonglue(const char *dname, struct hashbuf *htp, + int class); /* --from ns_maint.c-- */ /* ++from ns_sort.c++ */ @@ -416,7 +421,7 @@ void free_rrset_order_list(rrset_order_list); void set_global_boolean_option(options, int, int); listen_info_list new_listen_info_list(void); void free_listen_info_list(listen_info_list); -void add_listen_on(options, u_int16_t, ip_match_list); +void add_listen_on(options, u_short, ip_match_list); FILE * write_open(char *filename); void update_pid_file(void); void set_options(options, int); diff --git a/contrib/bind/bin/named/ns_glob.h b/contrib/bind/bin/named/ns_glob.h index b977f7b..af0ea30 100644 --- a/contrib/bind/bin/named/ns_glob.h +++ b/contrib/bind/bin/named/ns_glob.h @@ -1,6 +1,6 @@ /* * from ns.h 4.33 (Berkeley) 8/23/90 - * $Id: ns_glob.h,v 8.51 1999/10/15 21:53:32 vixie Exp $ + * $Id: ns_glob.h,v 8.54 2000/04/21 06:54:07 vixie Exp $ */ /* @@ -57,7 +57,7 @@ */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -156,17 +156,17 @@ DECL u_char *dnptrs[40]; DECL u_char **dnptrs_end INIT(dnptrs + sizeof dnptrs / sizeof(u_char*)); + /* data about all forwarders */ +DECL struct fwddata **fwddata; + /* how many forwarders are there in fwddata? */ +DECL int fwddata_count; + /* number of names in addinfo */ DECL int addcount; /* name of cache file */ DECL const char *cache_file; -#ifdef SLAVE_FORWARD - /* retry time when a slave */ -DECL int slave_retry INIT(4); -#endif - #ifdef BIND_UPDATE DECL const char * LogSignature INIT(";BIND LOG V8\n"); DECL const char * DumpSignature INIT(";BIND DUMP V8\n"); diff --git a/contrib/bind/bin/named/ns_glue.c b/contrib/bind/bin/named/ns_glue.c index 4b7972c..9c40dde 100644 --- a/contrib/bind/bin/named/ns_glue.c +++ b/contrib/bind/bin/named/ns_glue.c @@ -1,9 +1,9 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_glue.c,v 8.14 1999/10/19 02:06:26 gson Exp $"; +static const char rcsid[] = "$Id: ns_glue.c,v 8.16 2000/04/21 06:50:18 vixie Exp $"; #endif /* not lint */ /* - * Copyright (c) 1996-1999 by Internet Software Consortium. + * Copyright (c) 1996-2000 by Internet Software Consortium, Inc. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -73,15 +73,13 @@ ina_put(struct in_addr ina, u_char *data) { } /* - * XXX: sin_ntoa() should probably be in libc. + * IP address to presentation format. */ const char * sin_ntoa(struct sockaddr_in sin) { static char ret[sizeof "[111.222.333.444].55555"]; - sprintf(ret, "[%s].%u", - inet_ntoa(sin.sin_addr), - ntohs(sin.sin_port)); + sprintf(ret, "[%s].%u", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); return (ret); } @@ -180,7 +178,7 @@ ns_assertion_failed(char *file, int line, assertion_type type, char *cond, } /* - * XXX This is for compatibility and will eventually be removed. + * XXX This is for compatibility and should eventually be removed. */ void panic(const char *msg, const void *arg) { @@ -192,7 +190,7 @@ panic(const char *msg, const void *arg) { * Note: the root label is not included in the count. */ int -nlabels (const char *dname) { +nlabels(const char *dname) { int count, i, found, escaped; const char *tmpdname, *end_tmpdname; int tmpdnamelen, c; @@ -215,9 +213,8 @@ nlabels (const char *dname) { escaped = 0; else escaped = 1; - } else { + } else break; - } if (!escaped) tmpdnamelen--; } @@ -244,8 +241,7 @@ nlabels (const char *dname) { } } - ns_debug(ns_log_default, 12, "nlabels of \"%s\" -> %d", dname, - count); + ns_debug(ns_log_default, 12, "nlabels of \"%s\" -> %d", dname, count); return (count); } @@ -448,3 +444,20 @@ movefile(const char *oldname, const char *newname) { return (rename(oldname, newname)); } #endif + +#ifdef ultrix +/* + * Some library routines in libc need to be able to see the res_send + * and res_close symbols with out __ prefix otherwise we get multiply + * defined symbol errors when linking named. + */ + +#undef res_send +int res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) { + return __res_send(buf, buflen, ans, anssiz); +} +#undef _res_close +void _res_close(void) { + __res_close(); +} +#endif diff --git a/contrib/bind/bin/named/ns_init.c b/contrib/bind/bin/named/ns_init.c index cc95ce6..66242a4 100644 --- a/contrib/bind/bin/named/ns_init.c +++ b/contrib/bind/bin/named/ns_init.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)ns_init.c 4.38 (Berkeley) 3/21/91"; -static const char rcsid[] = "$Id: ns_init.c,v 8.63 1999/10/15 19:49:04 vixie Exp $"; +static const char rcsid[] = "$Id: ns_init.c,v 8.68 2000/04/21 06:54:07 vixie Exp $"; #endif /* not lint */ /* @@ -57,7 +57,7 @@ static const char rcsid[] = "$Id: ns_init.c,v 8.63 1999/10/15 19:49:04 vixie Exp */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -245,7 +245,7 @@ zoneinit(struct zoneinfo *zp) { } } else { zp->z_flags |= Z_AUTH; - zp->z_flags &= ~Z_NEED_RELOAD; + zp->z_flags &= ~(Z_NEED_RELOAD|Z_EXPIRED); ns_refreshtime(zp, tt.tv_sec); sched_zone_maint(zp); } @@ -285,6 +285,7 @@ do_reload(const char *domain, int type, int class, int mark) { /* * Clean up any leftover data. */ + ns_stopxfrs(zp); purge_zone(domain, hashtab, class); /* @@ -328,6 +329,20 @@ do_reload(const char *domain, int type, int class, int mark) { void purgeandload(struct zoneinfo *zp) { + +#ifdef BIND_UPDATE + /* + * A dynamic zone might have changed, so we + * need to dump it before removing it. + */ + if (zp->z_type == Z_PRIMARY && + (zp->z_flags & Z_DYNAMIC) != 0 && + ((zp->z_flags & Z_NEED_SOAUPDATE) != 0 || + (zp->z_flags & Z_NEED_DUMP) != 0)) + (void) zonedump(zp, ISNOTIXFR); +#endif + ns_stopxfrs(zp); + if (zp->z_type == Z_HINT) purge_zone(zp->z_origin, fcachetab, zp->z_class); else diff --git a/contrib/bind/bin/named/ns_ixfr.c b/contrib/bind/bin/named/ns_ixfr.c index 76dbe6e..693dc6f 100644 --- a/contrib/bind/bin/named/ns_ixfr.c +++ b/contrib/bind/bin/named/ns_ixfr.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_ixfr.c,v 8.17 1999/11/05 04:48:28 vixie Exp $"; +static const char rcsid[] = "$Id: ns_ixfr.c,v 8.19 2000/04/18 20:47:27 vixie Exp $"; #endif /* not lint */ /* @@ -58,7 +58,6 @@ static int sx_flush(struct qstream * qsp), sx_addrr(struct qstream * qsp, const char *dname, struct databuf * dp); -extern void sx_sendsoa(struct qstream * qsp); /* * u_char * sx_new_ixfrmsg(msg) init the header of a message, reset the @@ -68,7 +67,6 @@ extern void sx_sendsoa(struct qstream * qsp); static void sx_new_ixfrmsg(struct qstream *qsp) { HEADER * hp = (HEADER *) qsp->xfr.msg; - ns_updrec * up; memset(hp, 0, HFIXEDSZ); hp->id = htons(qsp->xfr.id); @@ -94,7 +92,6 @@ sx_new_ixfrmsg(struct qstream *qsp) { qsp->xfr.ixfr_zone = qsp->xfr.zone; zp = &zones[qsp->xfr.zone]; - up = qsp->xfr.top.ixfr; n = dn_comp(zp->z_origin, qsp->xfr.cp, XFER_BUFSIZE - (qsp->xfr.cp - qsp->xfr.msg), NULL, NULL); qsp->xfr.cp += n; @@ -114,8 +111,11 @@ sx_new_ixfrmsg(struct qstream *qsp) { } /* - * int sx_flush(qsp) flush the intermediate buffer out to the stream IO - * system. return: passed through from sq_write(). + * int + * sx_flush(qsp) + * flush the intermediate buffer out to the stream IO system. + * return: + * passed through from sq_write(). */ static int sx_flush(struct qstream *qsp) { @@ -126,12 +126,34 @@ sx_flush(struct qstream *qsp) { fp_nquery(qsp->xfr.msg, qsp->xfr.cp - qsp->xfr.msg, log_get_stream(packet_channel)); #endif - ret = sq_write(qsp, qsp->xfr.msg, qsp->xfr.cp - qsp->xfr.msg); - if (ret >= 0) + if (qsp->xfr.tsig_state != NULL && qsp->xfr.tsig_skip == 0) { + int msglen = qsp->xfr.cp - qsp->xfr.msg; + + ns_sign_tcp(qsp->xfr.msg, &msglen, qsp->xfr.eom - qsp->xfr.msg, + NOERROR, qsp->xfr.tsig_state, + qsp->xfr.state == s_x_done); + + if (qsp->xfr.state == s_x_done) { + memput(qsp->xfr.tsig_state, sizeof(ns_tcp_tsig_state)); + qsp->xfr.tsig_state = NULL; + } + qsp->xfr.cp = qsp->xfr.msg + msglen; + + } + if (qsp->xfr.cp - qsp->xfr.msg > 0) + ret = sq_write(qsp, qsp->xfr.msg, qsp->xfr.cp - qsp->xfr.msg); + else { + ns_debug(ns_log_default, 3, " Flush negative number *********"); + ret = -1; + } + if (ret >= 0) { qsp->xfr.cp = NULL; + qsp->xfr.tsig_skip = 0; + } + else + qsp->xfr.tsig_skip = 1; return (ret); } - /* * int sx_addrr(qsp, name, dp) add name/dp's RR to the current assembly * message. if it won't fit, write current message out, renew the message, @@ -176,8 +198,9 @@ sx_send_ixfr(struct qstream *qsp) { struct zoneinfo *zp = NULL; struct databuf *soa_dp; struct databuf *old_soadp; - ns_updrec * rp; - ns_updrec * trp; + ns_delta *dp; + ns_updrec *rp; + ns_updrec *trp; int foundsoa; zp = &zones[qsp->xfr.zone]; @@ -193,6 +216,8 @@ sx_send_ixfr(struct qstream *qsp) { again: switch (qsp->xfr.state) { case s_x_firstsoa: + ns_debug(ns_log_default, 3, + "IXFR: s_x_firstsoa (%s)", zp->z_origin); /* * The current SOA has been emited already. * It would be cleaner if the first one was emited here... @@ -203,11 +228,15 @@ sx_send_ixfr(struct qstream *qsp) { qsp->xfr.state = s_x_deletesoa; /* FALLTHROUGH */ case s_x_deletesoa: - if (qsp->xfr.top.ixfr) { + ns_debug(ns_log_default, 3, + "IXFR: s_x_deletesoa (%s)", zp->z_origin); + dp = NULL; + if (qsp->xfr.top.ixfr != NULL && !EMPTY(*qsp->xfr.top.ixfr)) + dp = HEAD(*qsp->xfr.top.ixfr); + if (dp != NULL) { foundsoa = 0; - rp = qsp->xfr.top.ixfr; - while (PREV(rp, r_link) != NULL) - rp = PREV(rp, r_link); + + rp = HEAD(dp->d_changes); while (rp != NULL) { if (rp->r_opcode == DELETE && rp->r_dp != NULL && @@ -220,13 +249,12 @@ sx_send_ixfr(struct qstream *qsp) { foundsoa = 1; break; } - trp = rp; rp = NEXT(rp, r_link); } if (!foundsoa) { cp = (char *)findsoaserial(old_soadp->d_data); - PUTLONG(qsp->xfr.top.ixfr->r_zone, cp); + PUTLONG(HEAD(dp->d_changes)->r_zone, cp); if (sx_addrr(qsp, zp->z_origin, old_soadp) < 0) goto cleanup; @@ -235,15 +263,13 @@ sx_send_ixfr(struct qstream *qsp) { qsp->xfr.state = s_x_deleting; /* FALLTHROUGH */ case s_x_deleting: - if (qsp->xfr.top.ixfr) { - /* - * The order s important here. - * Go to start of this update via PREV(r_link) - * then extract all deletions. - */ - rp = qsp->xfr.top.ixfr; - while (PREV(rp, r_link) != NULL) - rp = PREV(rp, r_link); + ns_debug(ns_log_default, 3, + "IXFR: s_x_deleting (%s)", zp->z_origin); + dp = NULL; + if (qsp->xfr.top.ixfr != NULL && !EMPTY(*qsp->xfr.top.ixfr)) + dp = HEAD(*qsp->xfr.top.ixfr); + if (dp != NULL) { + rp = HEAD(dp->d_changes); while (rp != NULL) { if (rp->r_opcode == DELETE && rp->r_dp != NULL) { @@ -257,18 +283,20 @@ sx_send_ixfr(struct qstream *qsp) { db_freedata(rp->r_dp); rp->r_dp = NULL; } - trp = rp; rp = NEXT(rp, r_link); } } qsp->xfr.state = s_x_addsoa; /* FALLTHROUGH */ case s_x_addsoa: - if (qsp->xfr.top.ixfr) { + ns_debug(ns_log_default, 3, + "IXFR: s_x_addsoa (%s)", zp->z_origin); + dp = NULL; + if (qsp->xfr.top.ixfr != NULL && !EMPTY(*qsp->xfr.top.ixfr)) + dp = HEAD(*qsp->xfr.top.ixfr); + if (dp != NULL) { foundsoa = 0; - rp = qsp->xfr.top.ixfr; - while (PREV(rp, r_link) != NULL) - rp = PREV(rp, r_link); + rp = HEAD(dp->d_changes); while (rp != NULL) { if (rp->r_opcode == ADD && rp->r_dp != NULL && @@ -281,15 +309,13 @@ sx_send_ixfr(struct qstream *qsp) { foundsoa = 1; break; } - trp = rp; rp = NEXT(rp, r_link); } if (!foundsoa) { cp = (char *)findsoaserial(old_soadp->d_data); - if (NEXT(qsp->xfr.top.ixfr, r_link) != NULL) { - trp = qsp->xfr.top.ixfr; - PUTLONG(NEXT(trp, r_link)->r_zone, cp); + if (NEXT(dp, d_link) != NULL) { + PUTLONG(HEAD(dp->d_changes)->r_zone, cp); if (sx_addrr(qsp, zp->z_origin, old_soadp) < 0) goto cleanup; @@ -303,52 +329,77 @@ sx_send_ixfr(struct qstream *qsp) { qsp->xfr.state = s_x_adding; /* FALLTHROUGH */ case s_x_adding: - if (qsp->xfr.top.ixfr) { - /* see s_x_deleting */ - rp = qsp->xfr.top.ixfr; - while (PREV(rp, r_link) != NULL) - rp = PREV(rp, r_link); - while (rp != NULL) { - if (rp->r_opcode == ADD && - rp->r_dp != NULL && - rp->r_dp->d_type != T_SOA) { - if (sx_addrr(qsp, rp->r_dname, - rp->r_dp) < 0) - goto cleanup; - db_freedata(rp->r_dp); - rp->r_dp = NULL; + ns_debug(ns_log_default, 3, + "IXFR: s_x_adding (%s)", zp->z_origin); + dp = NULL; + if (qsp->xfr.top.ixfr != NULL && !EMPTY(*qsp->xfr.top.ixfr)) { + dp = HEAD(*qsp->xfr.top.ixfr); + if (dp != NULL) { + /* see s_x_deleting */ + rp = HEAD(dp->d_changes); + while (rp != NULL) { + if (rp->r_opcode == ADD && + rp->r_dp != NULL && + rp->r_dp->d_type != T_SOA) { + if (sx_addrr(qsp, rp->r_dname, + rp->r_dp) < 0) + goto cleanup; + db_freedata(rp->r_dp); + rp->r_dp = NULL; + } + rp = NEXT(rp, r_link); } - trp = rp; - rp = NEXT(rp, r_link); - } - /* move to next update */ - rp = qsp->xfr.top.ixfr; - qsp->xfr.top.ixfr = NEXT(rp, r_link); - PREV(rp, r_link) = NULL; - /* clean up old update */ - while (rp != NULL) { - trp = PREV(rp, r_link); - if (rp->r_dp != NULL) { - db_freedata(rp->r_dp); - rp->r_dp = NULL; + /* move to next update */ + UNLINK(*qsp->xfr.top.ixfr, dp, d_link); + + /* clean up old update */ + while ((rp = HEAD(dp->d_changes)) != NULL) { + UNLINK(dp->d_changes, rp, r_link); + if (rp->r_dp != NULL) { + db_freedata(rp->r_dp); + rp->r_dp = NULL; + } + res_freeupdrec(rp); + } + memput(dp, sizeof (*dp)); + if (HEAD(*qsp->xfr.top.ixfr) != NULL) { + qsp->xfr.state = s_x_deletesoa; + goto again; } - res_freeupdrec(rp); - rp = trp; } } qsp->xfr.state = s_x_lastsoa; /* FALLTHROUGH */ case s_x_lastsoa: - if (qsp->xfr.ixfr_zone != 0) { + ns_debug(ns_log_default, 3, + "IXFR: s_x_lastsoa (%s)", zp->z_origin); + if (qsp->xfr.ixfr_zone != 0) sx_addrr(qsp, zp->z_origin, soa_dp); - } break; } + ns_debug(ns_log_default, 3, "IXFR: flushing %s", zp->z_origin); qsp->xfr.state = s_x_done; sx_flush(qsp); sq_writeh(qsp, sq_flushw); cleanup: + if (qsp->xfr.top.ixfr != NULL) { + if(!EMPTY(*qsp->xfr.top.ixfr)) { + while ((dp = HEAD(*qsp->xfr.top.ixfr)) != NULL) { + UNLINK(*qsp->xfr.top.ixfr, dp, d_link); + while ((rp = HEAD(dp->d_changes)) != NULL) { + UNLINK(dp->d_changes, rp, r_link); + if (rp->r_dp != NULL) + db_freedata(rp->r_dp); + rp->r_dp = NULL; + res_freeupdrec(rp); + } + memput(dp, sizeof *dp); + } + } + memput(qsp->xfr.top.ixfr, sizeof *qsp->xfr.top.ixfr); + qsp->xfr.top.ixfr = NULL; + } memput(old_soadp, DATASIZE(old_soadp->d_size)); } @@ -358,9 +409,19 @@ sx_send_ixfr(struct qstream *qsp) { #endif -int ixfr_log_maint(struct zoneinfo *zp) { - int fd, rcount, wcount, rval; - int found = 0, seek = 0; +/* + * int ixfr_log_maint(struct zoneinfo *zp, int fast_trim) + * + * zp - pointer to the zone information + * fast_trim - is used to denote that this is not called on the regular + * maintaince cycle. + * + */ +int ixfr_log_maint(struct zoneinfo *zp, int fast_trim) { + int fd, rcount, wcount; + int found = 0; + int error = 0; + long seek = 0; FILE *to_fp, *from_fp, *db_fp; static char *tmpname; struct stat db_sb; @@ -369,50 +430,16 @@ int ixfr_log_maint(struct zoneinfo *zp) { ns_debug(ns_log_default, 3, "ixfr_log_maint(%s)", zp->z_origin); - tmpname = memget(strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1); - if (!tmpname) { - ns_warning(ns_log_default, "memget failed"); - return (-1); - } -#ifdef SHORT_FNAMES - filenamecpy(tmpname, zp->z_ixfr_base); -#else - (void) strcpy(tmpname, zp->z_ixfr_base); -#endif /* SHORT_FNAMES */ - - (void) strcat(tmpname, ".XXXXXX"); - if ((fd = mkstemp(tmpname)) == -1) { - ns_warning(ns_log_db, "can't make tmpfile (%s): %s", - strerror(errno)); - memput(tmpname, (strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1)); - return (-1); - } - if ((to_fp = fdopen(fd, "r+")) == NULL) { - ns_warning(ns_log_db, "%s: %s", - tmpname, strerror(errno)); - (void) unlink(tmpname); - memput(tmpname, (strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1)); - (void) close(fd); - return (-1); - } /* find out how big the zone db file is */ if ((db_fp = fopen(zp->z_source, "r")) == NULL) { ns_warning(ns_log_db, "%s: %s", zp->z_source, strerror(errno)); - (void) unlink(tmpname); - memput(tmpname, (strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1)); - (void) my_fclose(to_fp); - (void) close(fd); return (-1); } if (fstat(fileno(db_fp), &db_sb) < 0) { ns_warning(ns_log_db, "%s: %s", zp->z_source, strerror(errno)); - (void) my_fclose(to_fp); (void) my_fclose(db_fp); - (void) close(fd); - (void) unlink(tmpname); - memput(tmpname, (strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1)); return (-1); } (void) my_fclose(db_fp); @@ -421,39 +448,32 @@ int ixfr_log_maint(struct zoneinfo *zp) { db_sb.st_size); /* open up the zone ixfr log */ - if ((from_fp = fopen(zp->z_ixfr_base, "r")) == NULL) { + if ((from_fp = fopen(zp->z_ixfr_base, "r")) == NULL) { ns_warning(ns_log_db, "%s: %s", zp->z_ixfr_base, strerror(errno)); - (void) my_fclose(to_fp); - (void) close(fd); - (void) unlink(tmpname); - memput(tmpname, (strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1)); return (-1); } if (fstat(fileno(from_fp), &sb) < 0) { ns_warning(ns_log_db, "%s: %s", zp->z_ixfr_base, strerror(errno)); - (void) my_fclose(to_fp); - (void) close(fd); - (void) unlink(tmpname); (void) my_fclose(from_fp); - memput(tmpname, (strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1)); return (-1); } - ns_debug(ns_log_default, 3, "%s, size %d log_s %d max %d\n", + ns_debug(ns_log_default, 3, "%s, size %d max %d\n", zp->z_ixfr_base, sb.st_size, - zp->z_log_size_ixfr, zp->z_max_log_size_ixfr); if (zp->z_max_log_size_ixfr) { if (sb.st_size > zp->z_max_log_size_ixfr) - seek = sb.st_size - (zp->z_max_log_size_ixfr + (zp->z_max_log_size_ixfr *.10)); + seek = (signed)sb.st_size - + (signed)(zp->z_max_log_size_ixfr + + (zp->z_max_log_size_ixfr * .10) ); else seek = 0; } else { if (sb.st_size > (db_sb.st_size * .50)) - seek = sb.st_size - ((db_sb.st_size * .50) + seek = (signed)sb.st_size - (signed)((db_sb.st_size * .50) + ((db_sb.st_size * zp->z_max_log_size_ixfr) *.10)); else seek = 0; @@ -463,43 +483,58 @@ int ixfr_log_maint(struct zoneinfo *zp) { { ns_debug(ns_log_default, 3, "%s does not need to be reduced", zp->z_ixfr_base); - (void) my_fclose(to_fp); - (void) close(fd); - (void) unlink(tmpname); (void) my_fclose(from_fp); - memput(tmpname, (strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1)); return (-1); } + if ((fast_trim) && seek < (zp->z_max_log_size_ixfr + 100000)) { + (void) my_fclose(from_fp); + return (0); + } + + tmpname = memget(strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1); + if (!tmpname) { + ns_warning(ns_log_default, "memget failed"); + return (-1); + } +#ifdef SHORT_FNAMES + filenamecpy(tmpname, zp->z_ixfr_base); +#else + (void) strcpy(tmpname, zp->z_ixfr_base); +#endif /* SHORT_FNAMES */ + + (void) strcat(tmpname, ".XXXXXX"); + if ((fd = mkstemp(tmpname)) == -1) { + ns_warning(ns_log_db, "can't make tmpfile (%s): %s", + strerror(errno)); + memput(tmpname, (strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1)); + return (-1); + } + if ((to_fp = fdopen(fd, "r+")) == NULL) { + ns_warning(ns_log_db, "%s: %s", + tmpname, strerror(errno)); + (void) unlink(tmpname); + memput(tmpname, (strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1)); + (void) close(fd); + return (-1); + } if (fgets(buf, sizeof(buf), from_fp) == NULL) { ns_error(ns_log_update, "fgets() from %s failed: %s", zp->z_ixfr_base, strerror(errno)); - (void) my_fclose(from_fp); - (void) my_fclose(to_fp); - (void) close(fd); - (void) unlink(tmpname); - memput(tmpname, (strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1)); - return (-1); + error++; + goto clean_up; } if (strcmp(buf, LogSignature) != 0) { ns_error(ns_log_update, "invalid log file %s", zp->z_ixfr_base); - (void) my_fclose(from_fp); - (void) my_fclose(to_fp); - (void) close(fd); - (void) unlink(tmpname); - memput(tmpname, (strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1)); - return (-3); + error++; + goto clean_up; } - if (fseek( from_fp, seek, 0) < 0) { - (void) my_fclose(from_fp); - (void) my_fclose(to_fp); - (void) close(fd); - (void) unlink(tmpname); - memput(tmpname, (strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1)); - return (-1); + if (fseek( from_fp, seek, 0) < 0) { + error++; + goto clean_up; } found = 0; @@ -517,47 +552,61 @@ int ixfr_log_maint(struct zoneinfo *zp) { if (found) { ns_debug(ns_log_default, 1, "ixfr_log_maint(): found [END_DELTA]"); + fprintf(to_fp, "%s", LogSignature); + while ((rcount = fread(buf, sizeof(char), MAXBSIZE, from_fp)) > 0) { wcount = fwrite(buf, sizeof(char), rcount, to_fp); if (rcount != wcount || wcount == -1) { ns_warning(ns_log_default, "ixfr_log_maint: error in writting copy"); - rval = 1; break; } - } - if (rcount < 0) { - ns_warning(ns_log_default, "ixfr_log_maint: error in reading copy"); - rval = 1; } + if (rcount < 0) + ns_warning(ns_log_default, + "ixfr_log_maint: error in reading copy"); } + clean_up: (void) my_fclose(to_fp); (void) close(fd); (void) my_fclose(from_fp); - if (rename(tmpname, zp->z_ixfr_base) == -1) { - ns_warning(ns_log_default, "can not rename %s to %s :%s", - tmpname, zp->z_ixfr_base, strerror(errno)); + if (error == 0) { + if (rename(tmpname, zp->z_ixfr_base) == -1) { + ns_warning(ns_log_default, "can not rename %s to %s :%s", + tmpname, zp->z_ixfr_base, strerror(errno)); + } + if ((from_fp = fopen(zp->z_ixfr_base, "r")) == NULL) { + ns_warning(ns_log_db, "%s: %s", + zp->z_ixfr_base, strerror(errno)); + return (-1); + } + if (fstat(fileno(from_fp), &sb) < 0) { + ns_warning(ns_log_db, "%s: %s", + zp->z_ixfr_base, strerror(errno)); + (void) my_fclose(from_fp); + return (-1); + } + if (sb.st_size <= 0) + (void) unlink(zp->z_ixfr_base); + else if (chmod(zp->z_ixfr_base, 0644) < 0) + ns_error(ns_log_update, + "chmod(%s,%o) failed, pressing on: %s", + zp->z_source, sb.st_mode, + strerror(errno)); } (void) unlink(tmpname); memput(tmpname, (strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1)); - if ((from_fp = fopen(zp->z_ixfr_base, "r")) == NULL) { - ns_warning(ns_log_db, "%s: %s", - zp->z_ixfr_base, strerror(errno)); - return (-1); - } - if (fstat(fileno(from_fp), &sb) < 0) { - ns_warning(ns_log_db, "%s: %s", - zp->z_ixfr_base, strerror(errno)); - (void) my_fclose(from_fp); - return (-1); - } - if (sb.st_size <= 0) - (void) unlink(zp->z_ixfr_base); (void) my_fclose(from_fp); - ns_debug(ns_log_default, 3, "%s, size %d log_s %d max %d\n", + zp->z_serial_ixfr_start = 0; /* signal to read for lowest serial number */ + + ns_debug(ns_log_default, 3, "%s, size %d max %d\n", zp->z_ixfr_base, sb.st_size, - zp->z_log_size_ixfr, zp->z_max_log_size_ixfr); - return (0); + + if (error) + return(-1); + else + return (0); } + diff --git a/contrib/bind/bin/named/ns_lexer.c b/contrib/bind/bin/named/ns_lexer.c index 244d5f6..7110fe4 100644 --- a/contrib/bind/bin/named/ns_lexer.c +++ b/contrib/bind/bin/named/ns_lexer.c @@ -1,9 +1,9 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_lexer.c,v 8.19 1999/10/13 16:39:08 vixie Exp $"; +static const char rcsid[] = "$Id: ns_lexer.c,v 8.20 2000/04/21 06:54:07 vixie Exp $"; #endif /* not lint */ /* - * Copyright (c) 1996-1999 by Internet Software Consortium. + * Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/contrib/bind/bin/named/ns_lexer.h b/contrib/bind/bin/named/ns_lexer.h index 66c19f2..7a22b8e 100644 --- a/contrib/bind/bin/named/ns_lexer.h +++ b/contrib/bind/bin/named/ns_lexer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996-1999 by Internet Software Consortium. + * Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/contrib/bind/bin/named/ns_main.c b/contrib/bind/bin/named/ns_main.c index 1377098..199190f 100644 --- a/contrib/bind/bin/named/ns_main.c +++ b/contrib/bind/bin/named/ns_main.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)ns_main.c 4.55 (Berkeley) 7/1/91"; -static const char rcsid[] = "$Id: ns_main.c,v 8.117 1999/11/08 23:01:38 vixie Exp $"; +static const char rcsid[] = "$Id: ns_main.c,v 8.125 2000/04/21 06:54:08 vixie Exp $"; #endif /* not lint */ /* @@ -57,7 +57,7 @@ static const char rcsid[] = "$Id: ns_main.c,v 8.117 1999/11/08 23:01:38 vixie Ex */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -146,7 +146,11 @@ static int iflist_dont_rescan = 0; static const int drbufsize = 32 * 1024, /* UDP rcv buf size */ dsbufsize = 48 * 1024, /* UDP snd buf size */ sbufsize = 16 * 1024, /* TCP snd buf size */ +#ifdef BROKEN_RECVFROM + nudptrans = 1, +#else nudptrans = 20, /* #/udps per select */ +#endif listenmax = 50; static u_int16_t nsid_state; @@ -318,8 +322,8 @@ main(int argc, char *argv[], char *envp[]) { break; case 'v': - fprintf(stderr, "%s\n", Version); - exit(1); + fprintf(stdout, "%s\n", Version); + exit(0); #ifdef CAN_CHANGE_ID case 'u': @@ -754,6 +758,10 @@ tcp_send(struct qinfo *qp) { sq_remove(sp); return (SERVFAIL); } + if (fcntl(sp->s_rfd, F_SETFD, 1) < 0) { + sq_remove(sp); + return (SERVFAIL); + } if (sq_openw(sp, qp->q_msglen + INT16SZ) == -1) { sq_remove(sp); return (SERVFAIL); @@ -785,7 +793,7 @@ tcp_send(struct qinfo *qp) { static void stream_send(evContext lev, void *uap, int fd, const void *la, int lalen, - const void *ra, int ralen) { + const void *ra, int ralen) { struct qstream *sp = uap; ns_debug(ns_log_default, 1, "stream_send"); @@ -890,7 +898,8 @@ stream_getlen(evContext lev, void *uap, int fd, int bytes) { } } - iov = evConsIovec(sp->s_buf, sp->s_size); + iov = evConsIovec(sp->s_buf, (sp->s_size <= sp->s_bufsize) ? + sp->s_size : sp->s_bufsize); if (evRead(lev, sp->s_rfd, &iov, 1, stream_getmsg, sp, &sp->evID_r) == -1) ns_panic(ns_log_default, 1, "evRead(fd %d): %s", @@ -1127,13 +1136,13 @@ getnetconf(int periodic_scan) { ifc.ifc_len = bufsiz; ifc.ifc_buf = buf; #ifdef IRIX_EMUL_IOCTL_SIOCGIFCONF - /* - * This is a fix for IRIX OS in which the call to ioctl with - * the flag SIOCGIFCONF may not return an entry for all the - * interfaces like most flavors of Unix. - */ - if (emul_ioctl(&ifc) >= 0) - break; + /* + * This is a fix for IRIX OS in which the call to ioctl with + * the flag SIOCGIFCONF may not return an entry for all the + * interfaces like most flavors of Unix. + */ + if (emul_ioctl(&ifc) >= 0) + break; #else if ((n = ioctl(s, SIOCGIFCONF, (char *)&ifc)) != -1) { /* @@ -1431,6 +1440,11 @@ opensocket_d(interface *ifp) { ns_notice(ns_log_default, "fcntl(dfd, F_DUPFD, 20): %s", strerror(errno)); #endif + if (fcntl(ifp->dfd, F_SETFD, 1) < 0) { + ns_error(ns_log_default, "F_SETFD: %s", strerror(errno)); + close(ifp->dfd); + return (-1); + } ns_debug(ns_log_default, 1, "ifp->addr %s d_dfd %d", sin_ntoa(nsa), ifp->dfd); if (setsockopt(ifp->dfd, SOL_SOCKET, SO_REUSEADDR, @@ -1516,6 +1530,11 @@ opensocket_s(interface *ifp) { ns_notice(ns_log_default, "fcntl(sfd, F_DUPFD, 20): %s", strerror(errno)); #endif + if (fcntl(ifp->sfd, F_SETFD, 1) < 0) { + ns_error(ns_log_default, "F_SETFD: %s", strerror(errno)); + close(ifp->sfd); + return (-1); + } if (setsockopt(ifp->sfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof on) != 0) { ns_notice(ns_log_default, "setsockopt(REUSEADDR): %s", @@ -1617,6 +1636,8 @@ opensocket_f() { strerror(errno)); if (ds > evHighestFD(ev)) ns_panic(ns_log_default, 1, "socket too high: %d", ds); + if (fcntl(ds, F_SETFD, 1) < 0) + ns_panic(ns_log_default, 1, "F_SETFD: %s", strerror(errno)); if (setsockopt(ds, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof on) != 0) { ns_notice(ns_log_default, "setsockopt(REUSEADDR): %s", @@ -1719,7 +1740,7 @@ sq_remove(struct qstream *qp) { INSIST_ERR(evDeselectFD(ev, qp->evID_w) != -1); if (qp->flags & STREAM_CONNECT_EV) INSIST_ERR(evCancelConn(ev, qp->evID_c) != -1); - if (qp->flags & STREAM_AXFR) + if (qp->flags & STREAM_AXFR || qp->flags & STREAM_AXFRIXFR) ns_freexfr(qp); (void) close(qp->s_rfd); if (qp == streamq) @@ -1945,7 +1966,7 @@ sq_done(struct qstream *sp) { sp->s_wbuf_send = sp->s_wbuf_free = NULL; sp->s_wbuf_end = sp->s_wbuf = NULL; } - if (sp->flags & STREAM_AXFR) + if (sp->flags & STREAM_AXFR || sp->flags & STREAM_AXFRIXFR) ns_freexfr(sp); sp->s_refcnt = 0; sp->s_time = tt.tv_sec; @@ -2340,7 +2361,7 @@ static const u_int16_t nsid_multiplier_table[] = { 10853, 1453, 18069, 21693, 30573, 36261, 37421, 42533 }; #define NSID_MULT_TABLE_SIZE \ - ((sizeof nsid_multiplier_table)/(sizeof nsid_multiplier_table[0])) + ((sizeof nsid_multiplier_table)/(sizeof nsid_multiplier_table[0])) void nsid_init(void) { @@ -2623,6 +2644,7 @@ init_needs(void) { handlers[main_need_debug] = use_desired_debug; handlers[main_need_restart] = ns_restart; handlers[main_need_reap] = reapchild; + handlers[main_need_noexpired] = ns_noexpired; } static void @@ -2703,18 +2725,18 @@ meminit(size_t init_max_size, size_t target_size) { void * memget_debug(size_t size, const char *file, int line) { - void *ptr; - ptr = __memget(size); - fprintf(stderr, "%s:%d: memget(%lu) -> %p\n", file, line, - (u_long)size, ptr); - return (ptr); + void *ptr; + ptr = __memget(size); + fprintf(stderr, "%s:%d: memget(%lu) -> %p\n", file, line, + (u_long)size, ptr); + return (ptr); } void memput_debug(void *ptr, size_t size, const char *file, int line) { - fprintf(stderr, "%s:%d: memput(%p, %lu)\n", file, line, ptr, - (u_long)size); - __memput(ptr, size); + fprintf(stderr, "%s:%d: memput(%p, %lu)\n", file, line, ptr, + (u_long)size); + __memput(ptr, size); } void diff --git a/contrib/bind/bin/named/ns_maint.c b/contrib/bind/bin/named/ns_maint.c index 69a8fc3..9b9e16e 100644 --- a/contrib/bind/bin/named/ns_maint.c +++ b/contrib/bind/bin/named/ns_maint.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)ns_maint.c 4.39 (Berkeley) 3/2/91"; -static const char rcsid[] = "$Id: ns_maint.c,v 8.95 1999/10/13 16:39:09 vixie Exp $"; +static const char rcsid[] = "$Id: ns_maint.c,v 8.103 2000/04/23 02:18:58 vixie Exp $"; #endif /* not lint */ /* @@ -57,7 +57,7 @@ static const char rcsid[] = "$Id: ns_maint.c,v 8.95 1999/10/13 16:39:09 vixie Ex */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -134,6 +134,8 @@ static void startxfer(struct zoneinfo *), abortxfer(struct zoneinfo *), tryxfer(void), purge_z_2(struct hashbuf *, int); +static int purge_nonglue_2(const char *, struct hashbuf *, + int, int); #ifndef HAVE_SPAWNXFER static pid_t spawnxfer(char **, struct zoneinfo *); @@ -178,10 +180,19 @@ zone_maint(struct zoneinfo *zp) { #endif if (zp->z_serial != 0 && ((zp->z_lastupdate+zp->z_expire) < (u_int32_t)tt.tv_sec)) { + if ((zp->z_flags & Z_NOTIFY) != 0) + ns_stopnotify(zp->z_origin, zp->z_class); /* calls purge_zone */ do_reload(zp->z_origin, zp->z_type, zp->z_class, 0); /* reset zone state */ + if (!haveComplained((u_long)zp, (u_long)stale)) { + ns_notice(ns_log_default, + "%s zone \"%s\" expired", + zoneTypeString(zp->z_type), + zp->z_origin); + } zp->z_flags &= ~Z_AUTH; + zp->z_flags |= Z_EXPIRED; zp->z_refresh = INIT_REFRESH; zp->z_retry = INIT_REFRESH; zp->z_serial = 0; @@ -247,9 +258,9 @@ zone_maint(struct zoneinfo *zp) { zp->z_dumptime = 0; (void)schedule_dump(zp); } - if (zp->z_maintain_ixfr_base) - ixfr_log_maint(zp); } + if (zp->z_maintain_ixfr_base) + ixfr_log_maint(zp); break; #endif /* BIND_UPDATE */ @@ -402,7 +413,7 @@ ns_cleancache(evContext ctx, void *uap, void ns_heartbeat(evContext ctx, void *uap, struct timespec due, - struct timespec inter) + struct timespec inter) { struct zoneinfo *zp; @@ -417,12 +428,9 @@ ns_heartbeat(evContext ctx, void *uap, struct timespec due, (zp->z_dialup == zdialup_use_default && NS_OPTION_P(OPTION_NODIALUP))) continue; -#ifdef BIND_NOTIFY - if ((zp->z_notify == znotify_no) || - ((zp->z_notify == znotify_use_default) && - NS_OPTION_P(OPTION_NONOTIFY))) - continue; -#endif + /* + * Perform the refresh query that was suppressed. + */ if ((zt == z_slave || zt == z_stub) && (zp->z_flags & (Z_NEED_RELOAD|Z_NEED_XFER|Z_QSERIAL|Z_XFER_RUNNING) @@ -432,6 +440,18 @@ ns_heartbeat(evContext ctx, void *uap, struct timespec due, *(zp->z_origin) ? zp->z_origin : "."); qserial_query(zp); } +#ifdef BIND_NOTIFY + /* + * Trigger a refresh query while the link is up by + * sending a notify. + */ + if (((zp->z_notify == znotify_yes) || + ((zp->z_notify == znotify_use_default) && + !NS_OPTION_P(OPTION_NONOTIFY))) && + (zt == z_master || zt == z_slave) && !loading && + ((zp->z_flags & Z_AUTH) != 0)) + ns_notify(zp->z_origin, zp->z_class, ns_t_soa); +#endif } } @@ -453,8 +473,10 @@ markUpToDate(struct zoneinfo *zp) { * but only if there were no errors * in the zone file. */ - if ((zp->z_flags & Z_DB_BAD) == 0) + if ((zp->z_flags & Z_DB_BAD) == 0) { zp->z_flags |= Z_AUTH; + zp->z_flags &= ~Z_EXPIRED; + } if (zp->z_source) { struct timeval t[2]; @@ -642,6 +664,7 @@ write_tsig_info(struct in_addr addr, char *name, int *fd, int creat_failed) { name); return(-1); } + (void) fchown(tsig_fd, user_id, group_id); } if (creat_failed != 0) return(-1); @@ -796,7 +819,7 @@ startxfer(struct zoneinfo *zp) { } *curr = '\0'; ns_debug(ns_log_xfer_in, 1, buffer); - } + } #endif /* DEBUG */ gettime(&tt); @@ -1066,6 +1089,8 @@ remove_zone(struct zoneinfo *zp, const char *verb) { (zp->z_flags & Z_NEED_DUMP) != 0)) (void) zonedump(zp, ISNOTIXFR); #endif + if ((zp->z_flags & Z_NOTIFY) != 0) + ns_stopnotify(zp->z_origin, zp->z_class); ns_stopxfrs(zp); do_reload(zp->z_origin, zp->z_type, zp->z_class, 1); ns_notice(ns_log_config, "%s zone \"%s\" (%s) %s", @@ -1078,6 +1103,145 @@ remove_zone(struct zoneinfo *zp, const char *verb) { free_zone(zp); } +int +purge_nonglue(const char *dname, struct hashbuf *htp, int class) { + const char *fname; + struct namebuf *np; + struct hashbuf *phtp = htp; + int root_zone = 0; + int errs = 0; + + ns_debug(ns_log_default, 1, "purge_zone(%s,%d)", dname, class); + if ((np = nlookup(dname, &phtp, &fname, 0)) && dname == fname && + !ns_wildcard(NAME(*np))) { + + if (*dname == '\0') + root_zone = 1; + + if (np->n_hash != NULL || root_zone) { + struct hashbuf *h; + + if (root_zone) + h = htp; + else + h = np->n_hash; + errs += purge_nonglue_2(dname, h, class, 0); + if (h->h_cnt == 0 && !root_zone) { + rm_hash(np->n_hash); + np->n_hash = NULL; + } + } + } + return (errs); +} + +static int +valid_glue(struct databuf *dp, char *name, int belowcut) { + + /* NS records are only valid glue at the zone cut */ + if (belowcut && dp->d_type == T_NS) + return(0); + + if (ISVALIDGLUE(dp)) /* T_NS/T_A/T_AAAA/T_A6 */ + return (1); + + if (belowcut) + return (0); + + /* Parent NXT record? */ + if (dp->d_type == T_NXT && !ns_samedomain((char*)dp->d_data, name) && + ns_samedomain((char*)dp->d_data, zones[dp->d_zone].z_origin)) + return (1); + + /* NOKEY is in parent zone otherwise child zone */ + if (dp->d_type == T_KEY && dp->d_size == 4 && + (dp->d_data[0] & 0xc6) == 0xc2) + return (1); + + /* NXT & KEY records may be signed */ + if (!belowcut && dp->d_type == T_SIG && + (SIG_COVERS(dp) == T_NXT || SIG_COVERS(dp) == T_KEY)) + return (1); + return (0); +} + +static int +purge_nonglue_2(const char *dname, struct hashbuf *htp, int class, + int belowcut) +{ + struct databuf *dp, *pdp; + struct namebuf *np, *pnp, *npn; + struct namebuf **npp, **nppend; + int errs = 0; + int zonecut; + char name[MAXDNAME]; + + nppend = htp->h_tab + htp->h_size; + for (npp = htp->h_tab; npp < nppend; npp++) { + for (pnp = NULL, np = *npp; np != NULL; np = npn) { + if (!bottom_of_zone(np->n_data, class)) { + zonecut = belowcut; + for (dp = np->n_data; dp != NULL; + dp = dp->d_next) { + if (match(dp, class, ns_t_ns)) { + zonecut = 1; + break; + } + } + getname(np, name, sizeof name); + for (pdp = NULL, dp = np->n_data; + dp != NULL; + (void)NULL) { + if (dp->d_class == class && + zonecut && + !valid_glue(dp, name, belowcut)) { + ns_error(ns_log_db, + "zone: %s/%s: non-glue record %s bottom of zone: %s/%s", + *dname ? dname : ".", + p_class(dp->d_class), + belowcut ? "below" : + "at", + *name ? name : ".", + p_type(dp->d_type)); + dp = rm_datum(dp, np, pdp, + NULL); + errs++; + } else { + pdp = dp; + dp = dp->d_next; + } + } + if (np->n_hash) { + /* + * call recursively to clean + * subdomains + */ + errs += purge_nonglue_2(dname, + np->n_hash, + class, + zonecut || + belowcut); + + /* if now empty, free it */ + if (np->n_hash->h_cnt == 0) { + rm_hash(np->n_hash); + np->n_hash = NULL; + } + } + } + + if (np->n_hash == NULL && np->n_data == NULL) { + npn = rm_name(np, npp, pnp); + htp->h_cnt--; + } else { + npn = np->n_next; + pnp = np; + } + } + } + return (errs); +} + void purge_zone(const char *dname, struct hashbuf *htp, int class) { const char *fname; @@ -1186,7 +1350,7 @@ bottom_of_zone(struct databuf *dp, int class) { ns_debug(ns_log_default, 3, "bottom_of_zone() == %d", ret); return (ret); } - + /* * Handle XFER limit for a nameserver. */ @@ -1295,7 +1459,7 @@ reapchild(void) { */ void endxfer() { - struct zoneinfo *zp; + struct zoneinfo *zp; int exitstatus, i; pid_t pid; WAIT_T status; @@ -1324,8 +1488,8 @@ endxfer() { if (WIFSIGNALED(status)) { if (WTERMSIG(status) != SIGKILL) { ns_notice(ns_log_default, - "named-xfer \"%s\" exited with signal %d", - zp->z_origin[0]?zp->z_origin:".", + "named-xfer \"%s\" exited with signal %d", + zp->z_origin[0]?zp->z_origin:".", WTERMSIG(status)); } ns_retrytime(zp, tt.tv_sec); @@ -1351,8 +1515,8 @@ endxfer() { break; case XFER_SUCCESSIXFR: + zp->z_flags |= Z_XFER_RUNNING; zp->z_xferpid = XFER_ISIXFR; - zp->z_log_size_ixfr++; ns_notice(ns_log_default, "IXFR Success %s", zp->z_ixfr_tmp); @@ -1374,6 +1538,8 @@ endxfer() { ns_notice(ns_log_default, "IXFR Merge failed %s", zp->z_ixfr_tmp); + zp->z_flags &= + ~(Z_XFER_RUNNING|Z_XFER_ABORTED|Z_XFER_GONE); break; case XFER_TIMEOUT: @@ -1436,7 +1602,7 @@ tryxfer() { zp = zones; } lastnzones = nzones; - + if (zp == zones) stopzp = &zones[nzones-1]; else @@ -1482,7 +1648,7 @@ tryxfer() { */ void loadxfer(void) { - struct zoneinfo *zp; + struct zoneinfo *zp; u_int32_t old_serial,new_serial; char *tmpnom; int isixfr; @@ -1512,11 +1678,12 @@ loadxfer(void) { if (!db_load(tmpnom, zp->z_origin, zp, NULL, isixfr)) { zp->z_flags |= Z_AUTH; + zp->z_flags &= ~Z_EXPIRED; if (isixfr == ISIXFR) { new_serial= zp ->z_serial; ns_warning(ns_log_db, "ISIXFR"); ns_warning(ns_log_db, "error in updating ixfr data base file %s from %s", zp -> z_ixfr_base, zp ->z_ixfr_tmp); - if (zonedump(zp,ISIXFR)<0) + if (zonedump(zp,ISIXFR)<0) ns_warning(ns_log_db, "error in write ixfr updates to zone file %s", zp ->z_source); } @@ -1578,6 +1745,16 @@ reload_master(struct zoneinfo *zp) { zp->z_flags &= ~Z_AUTH; ns_stopxfrs(zp); /* XXX what about parent zones? */ +#ifdef BIND_UPDATE + /* + * A dynamic zone might have changed, so we + * need to dump it before reloading it. + */ + if ((zp->z_flags & Z_DYNAMIC) != 0 && + ((zp->z_flags & Z_NEED_SOAUPDATE) != 0 || + (zp->z_flags & Z_NEED_DUMP) != 0)) + (void) zonedump(zp, ISNOTIXFR); +#endif purge_zone(zp->z_origin, hashtab, zp->z_class); ns_debug(ns_log_config, 1, "reloading zone"); #ifdef BIND_UPDATE @@ -1640,7 +1817,9 @@ ns_zreload(void) { */ void ns_reload(void) { - ns_notice(ns_log_default, "reloading nameserver"); + ns_notice(ns_log_default, "%s %snameserver", + (reconfiging != 0) ? "reconfiguring" : "reloading", + (noexpired == 1) ? "(-noexpired) " : ""); INSIST(reloading == 0); qflush(); @@ -1653,6 +1832,18 @@ ns_reload(void) { } /* + * Reload configuration, look for new or deleted zones, not changed ones + * also ignore expired zones. + */ +void +ns_noexpired(void) { + INSIST(noexpired == 0); + noexpired++; /* To ignore zones which are expired */ + ns_reconfig(); + noexpired--; +} + +/* * Reload configuration, look for new or deleted zones, not changed ones. */ void diff --git a/contrib/bind/bin/named/ns_ncache.c b/contrib/bind/bin/named/ns_ncache.c index 437072c..2b8bb6b 100644 --- a/contrib/bind/bin/named/ns_ncache.c +++ b/contrib/bind/bin/named/ns_ncache.c @@ -1,9 +1,9 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_ncache.c,v 8.26 1999/10/13 16:39:10 vixie Exp $"; +static const char rcsid[] = "$Id: ns_ncache.c,v 8.27 2000/04/21 06:54:09 vixie Exp $"; #endif /* not lint */ /* - * Copyright (c) 1996-1999 by Internet Software Consortium. + * Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/contrib/bind/bin/named/ns_notify.c b/contrib/bind/bin/named/ns_notify.c index ac03732e..0cf1e0a 100644 --- a/contrib/bind/bin/named/ns_notify.c +++ b/contrib/bind/bin/named/ns_notify.c @@ -1,9 +1,9 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_notify.c,v 8.4 1999/10/15 19:49:04 vixie Exp $"; +static const char rcsid[] = "$Id: ns_notify.c,v 8.10 2000/04/21 06:54:09 vixie Exp $"; #endif /* not lint */ /* - * Copyright (c) 1994-1999 by Internet Software Consortium. + * Copyright (c) 1994-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -78,6 +78,7 @@ static void notify_timer(evContext, void *, /* Local. */ static LIST(struct notify) pending_notifies; +static LIST(struct notify) loading_notifies; /* Public. */ @@ -100,6 +101,13 @@ ns_notify(const char *dname, ns_class class, ns_type type) { p_class(class), p_type(type)); return; } + if (ns_samename(dname, zp->z_origin) != 1) { + ns_warning(ns_log_notify, + "notify not called with top of zone (\"%s\" %s %s)", + (dname && *dname) ? dname : ".", + p_class(class), p_type(type)); + return; + } if ((zp->z_flags & Z_NOTIFY) != 0) { ns_info(ns_log_notify, "suppressing duplicate notify (\"%s\" %s %s)", @@ -123,6 +131,11 @@ ns_notify(const char *dname, ns_class class, ns_type type) { ni->type = type; evInitID(&ni->timer); + if (loading != 0) { + APPEND(loading_notifies, ni, link); + return; + } + /* Delay notification for from five seconds up to fifteen minutes. */ max_delay = MIN(nzones/5, 895); max_delay = MAX(max_delay, 25); @@ -146,6 +159,19 @@ ns_notify(const char *dname, ns_class class, ns_type type) { ni, zp, delay); } +void +notify_afterload() { + struct notify *ni; + + INSIST(loading == 0); + while ((ni = HEAD(loading_notifies)) != NULL) { + UNLINK(loading_notifies, ni, link); + ns_notify(ni->name, ni->class, ni->type); + freestr(ni->name); + memput(ni, sizeof *ni); + } +} + /* * ns_unnotify() * call this when all pending notifies are now considered junque. @@ -161,6 +187,25 @@ ns_unnotify(void) { } } +/* + * ns_stopnotify(const char *dname, ns_class class) + * stop notifies for this particular zone. + */ +void +ns_stopnotify(const char *dname, ns_class class) { + struct notify *ni; + + ni = HEAD(pending_notifies); + while (ni != NULL && + (ni->class != class || ns_samename(ni->name, dname) != 1)) + ni = NEXT(ni, link); + + if (ni != NULL) { + UNLINK(pending_notifies, ni, link); + free_notify(ni); + } +} + /* Private. */ /* @@ -171,6 +216,7 @@ ns_unnotify(void) { static void sysnotify(const char *dname, ns_class class, ns_type type) { const char *zname, *fname; + u_int32_t zserial; int nns, na, i; struct zoneinfo *zp; struct in_addr *also_addr; @@ -198,10 +244,9 @@ sysnotify(const char *dname, ns_class class, ns_type type) { return; } zname = zp->z_origin; + zserial = zp->z_serial; nns = na = 0; - if (zp->z_type == z_master) - sysnotify_slaves(dname, zname, class, type, - zp - zones, &nns, &na); + sysnotify_slaves(dname, zname, class, type, zp - zones, &nns, &na); /* * Handle any global or zone-specific also-notify clauses @@ -239,8 +284,8 @@ sysnotify(const char *dname, ns_class class, ns_type type) { if (nns != 0 || na != 0) ns_info(ns_log_notify, - "Sent NOTIFY for \"%s %s %s\" (%s); %d NS, %d A", - dname, p_class(class), p_type(type), zname, nns, na); + "Sent NOTIFY for \"%s %s %s %u\" (%s); %d NS, %d A", + dname, p_class(class), p_type(type), zserial, zname, nns, na); } static void @@ -328,7 +373,7 @@ sysnotify_ns(const char *dname, const char *aname, nss[nsc++] = ina; } /*next A*/ if (nsc == 0) { - if (!is_us) { + if (!is_us && !NS_OPTION_P(OPTION_NOFETCHGLUE)) { struct qinfo *qp; qp = sysquery(aname, class, ns_t_a, 0, 0, ns_port, @@ -349,7 +394,7 @@ free_notify(struct notify *ni) { INSIST(!LINKED(ni, link)); zp = find_auth_zone(ni->name, ni->class); - if (zp != NULL) { + if (zp != NULL && ns_samename(ni->name, zp->z_origin) == 1) { INSIST((zp->z_flags & Z_NOTIFY) != 0); zp->z_flags &= ~Z_NOTIFY; } diff --git a/contrib/bind/bin/named/ns_parser.y b/contrib/bind/bin/named/ns_parser.y index b381083..c987e2b 100644 --- a/contrib/bind/bin/named/ns_parser.y +++ b/contrib/bind/bin/named/ns_parser.y @@ -1,10 +1,10 @@ %{ #if !defined(lint) && !defined(SABER) -static char rcsid[] = "$Id: ns_parser.y,v 8.51 1999/11/12 05:29:18 vixie Exp $"; +static char rcsid[] = "$Id: ns_parser.y,v 8.55 2000/04/23 02:18:59 vixie Exp $"; #endif /* not lint */ /* - * Copyright (c) 1996-1999 by Internet Software Consortium. + * Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -376,8 +376,6 @@ option: /* Empty */ | T_HAS_OLD_CLIENTS yea_or_nay { set_global_boolean_option(current_options, - OPTION_MAINTAIN_IXFR_BASE, $2); - set_global_boolean_option(current_options, OPTION_NORFC2308_TYPE1, $2); set_global_boolean_option(current_options, OPTION_NONAUTH_NXDOMAIN, !$2); @@ -589,7 +587,9 @@ control: /* Empty */ } | T_UNIX L_QSTRING T_PERM L_NUMBER T_OWNER L_NUMBER T_GROUP L_NUMBER { +#ifndef NO_SOCKADDR_UN ns_ctl_add(¤t_controls, ns_ctl_new_unix($2, $4, $6, $8)); +#endif } | error ; @@ -960,6 +960,8 @@ logging_opt: T_CATEGORY category chan_name, NULL, chan_versions, chan_max_size); + log_set_file_owner(current_channel, + user_id, group_id); freestr(chan_name); chan_name = NULL; break; diff --git a/contrib/bind/bin/named/ns_parseutil.c b/contrib/bind/bin/named/ns_parseutil.c index 60b189a..4a26337 100644 --- a/contrib/bind/bin/named/ns_parseutil.c +++ b/contrib/bind/bin/named/ns_parseutil.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996-1999 by Internet Software Consortium. + * Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/contrib/bind/bin/named/ns_parseutil.h b/contrib/bind/bin/named/ns_parseutil.h index 78356f8..77fc878 100644 --- a/contrib/bind/bin/named/ns_parseutil.h +++ b/contrib/bind/bin/named/ns_parseutil.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996-1999 by Internet Software Consortium. + * Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/contrib/bind/bin/named/ns_req.c b/contrib/bind/bin/named/ns_req.c index d7ee0b5..5e1459c 100644 --- a/contrib/bind/bin/named/ns_req.c +++ b/contrib/bind/bin/named/ns_req.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)ns_req.c 4.47 (Berkeley) 7/1/91"; -static const char rcsid[] = "$Id: ns_req.c,v 8.104 1999/10/15 19:49:04 vixie Exp $"; +static const char rcsid[] = "$Id: ns_req.c,v 8.113 2000/04/21 06:54:11 vixie Exp $"; #endif /* not lint */ /* @@ -82,7 +82,7 @@ static const char rcsid[] = "$Id: ns_req.c,v 8.104 1999/10/15 19:49:04 vixie Exp */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -138,6 +138,7 @@ struct addinfo { u_int16_t a_class; /* class for data */ }; + #ifndef BIND_UPDATE enum req_action { Finish, Refuse, Return }; #endif @@ -184,7 +185,7 @@ ns_req(u_char *msg, int msglen, int buflen, struct qstream *qsp, #ifdef DEBUG if (debug > 3) { ns_debug(ns_log_packet, 3, "ns_req(from %s)", sin_ntoa(from)); - res_pquery(&res, msg, msglen, log_get_stream(packet_channel)); + fp_nquery(msg, msglen, log_get_stream(packet_channel)); } #endif msglen_orig = msglen; @@ -197,7 +198,13 @@ ns_req(u_char *msg, int msglen, int buflen, struct qstream *qsp, char buf[MAXDNAME]; has_tsig = 1; - ns_name_ntop(tsigstart, buf, sizeof(buf)); + n = dn_expand(msg, msg + msglen, tsigstart, buf, sizeof(buf)); + if (n < 0) { + ns_debug(ns_log_default, 1, + "ns_req: bad TSIG key name", + buf); + key = NULL; + } key = find_key(buf, NULL); if (key == NULL) { error = ns_r_badkey; @@ -515,7 +522,7 @@ req_notify(HEADER *hp, u_char **cpp, u_char *eom, u_char *msg, goto refuse; } if (findZonePri(zp, from) == -1) { - ns_info(ns_log_notify, + ns_debug(ns_log_notify, 1, "NOTIFY(SOA) from non-master server (zone %s), from %s", zp->z_origin, sin_ntoa(from)); goto refuse; @@ -556,6 +563,7 @@ req_notify(HEADER *hp, u_char **cpp, u_char *eom, u_char *msg, } #endif /*BIND_NOTIFY*/ + static enum req_action req_query(HEADER *hp, u_char **cpp, u_char *eom, struct qstream *qsp, int *buflenp, int *msglenp, u_char *msg, int dfd, int *ra, @@ -579,6 +587,9 @@ req_query(HEADER *hp, u_char **cpp, u_char *eom, struct qstream *qsp, struct databuf *dp; DST_KEY *in_key = (in_tsig != NULL) ? in_tsig->key : NULL; + + + nameserIncr(from.sin_addr, nssRcvdQ); nsp[0] = NULL; @@ -633,7 +644,7 @@ req_query(HEADER *hp, u_char **cpp, u_char *eom, struct qstream *qsp, } if (((ntohs(hp->nscount) != 0) && (type != ns_t_ixfr)) || - ((ntohs(hp->nscount) != 1) && (type == ns_t_ixfr))) + ((ntohs(hp->nscount) != 1) && (type == ns_t_ixfr))) { ns_debug(ns_log_default, 1, "FORMERR Query nscount wrong"); hp->rcode = ns_r_formerr; @@ -647,6 +658,8 @@ req_query(HEADER *hp, u_char **cpp, u_char *eom, struct qstream *qsp, * Process query. */ if (type == ns_t_ixfr) { + ns_info(ns_log_security, "Request %s from %s", + p_type(type), sin_ntoa(from)); hp->nscount = htons(0); hp->rd = 0; /* Force IXFR queries to be non recursive. */ n = dn_expand(msg, eom, *cpp, dnbuf2, sizeof dnbuf2); @@ -741,6 +754,11 @@ req_query(HEADER *hp, u_char **cpp, u_char *eom, struct qstream *qsp, np == NULL ? "missed" : "found", dname, fname, cname); + + ns_debug(ns_log_default, 1, "req: %s '%s' as '%s' (cname=%d)", + np == NULL ? "missed" : "found", + dname, fname, cname); + #ifdef YPKLUDGE /* Some braindamaged resolver software will not recognize internet addresses in dot notation and @@ -803,17 +821,21 @@ req_query(HEADER *hp, u_char **cpp, u_char *eom, struct qstream *qsp, if (SEQ_GT(serial_ixfr, zp->z_serial)) ixfr_found = 0; else { - ixfr_error = ixfr_have_log(zp, serial_ixfr, zp->z_serial); - if (ixfr_error < 0) { - ns_debug(ns_log_default, - 1, "ixfr_have_log(%d %d) failed %d", - serial_ixfr, zp->z_serial, ixfr_error); - ixfr_found = 0; - /* Refuse IXFR and send AXFR */ - type = ns_t_axfr; - } else - ixfr_found = 1; - } + ixfr_error = ixfr_have_log(zp, serial_ixfr, + zp->z_serial); + if (ixfr_error < 0) { + ns_info(ns_log_security, "No %s log from %d for \"%s\"", + p_type(type), serial_ixfr, *dname ? dname : "."); + ns_debug(ns_log_default, + 1, "ixfr_have_log(%d %d) failed %d", + serial_ixfr, zp->z_serial, ixfr_error); + ixfr_found = 0; /* Refuse IXFR and send AXFR */ + } else if (ixfr_error == 1) { + ixfr_found = 1; + } + } + ns_debug(ns_log_default, 1, "IXFR log lowest serial: %d", + zp->z_serial_ixfr_start); } /* * If recursion is turned on, we need to check recursion ACL @@ -889,8 +911,9 @@ req_query(HEADER *hp, u_char **cpp, u_char *eom, struct qstream *qsp, } } ns_notice(ns_log_security, - "unapproved query from %s for \"%s\"", + "denied query from %s for \"%s\"", sin_ntoa(from), *dname ? dname : "."); + nameserIncr(from.sin_addr, nssRcvdUQ); return (Refuse); } } else { @@ -908,9 +931,10 @@ req_query(HEADER *hp, u_char **cpp, u_char *eom, struct qstream *qsp, in_key)) { ns_notice(ns_log_security, - "unapproved %s from %s for \"%s\" (acl)", + "denied %s from %s for \"%s\" (acl)", p_type(type), sin_ntoa(from), *dname ? dname : "."); + nameserIncr(from.sin_addr, nssRcvdUXFR); return (Refuse); } @@ -918,9 +942,10 @@ req_query(HEADER *hp, u_char **cpp, u_char *eom, struct qstream *qsp, if (zp->z_type != z_master && zp->z_type != z_slave) { ns_notice(ns_log_security, - "unapproved %s from %s for \"%s\" (not master/slave)", + "denied %s from %s for \"%s\" (not master/slave)", p_type(type), sin_ntoa(from), *dname ? dname : "."); + nameserIncr(from.sin_addr, nssRcvdUXFR); return (Refuse); } @@ -928,9 +953,10 @@ req_query(HEADER *hp, u_char **cpp, u_char *eom, struct qstream *qsp, if ((zp->z_flags & Z_AUTH) == 0) { ns_notice(ns_log_security, - "unapproved %s from %s for \"%s\" (not authoritative)", + "denied %s from %s for \"%s\" (not authoritative)", p_type(type), sin_ntoa(from), *dname ? dname : "."); + nameserIncr(from.sin_addr, nssRcvdUXFR); return (Refuse); } @@ -938,14 +964,20 @@ req_query(HEADER *hp, u_char **cpp, u_char *eom, struct qstream *qsp, if (ns_samename(zp->z_origin, dname) != 1) { ns_notice(ns_log_security, - "unapproved %s from %s for \"%s\" (not zone top)", + "denied %s from %s for \"%s\" (not zone top)", p_type(type), sin_ntoa(from), *dname ? dname : "."); + nameserIncr(from.sin_addr, nssRcvdUXFR); return (Refuse); } - ns_info(ns_log_security, "approved %s from %s for \"%s\"", - p_type(type), sin_ntoa(from), *dname ? dname : "."); + if (type == ns_t_ixfr) { + ns_info(ns_log_security, "approved %s from %s for \"%s\"", + (ixfr_found) ? p_type(type) : "IXFR/AXFR", + sin_ntoa(from), *dname ? dname : "."); + } else + ns_info(ns_log_security, "approved %s from %s for \"%s\"", + p_type(type), sin_ntoa(from), *dname ? dname : "."); } /* @@ -1102,8 +1134,9 @@ req_query(HEADER *hp, u_char **cpp, u_char *eom, struct qstream *qsp, if (type == ns_t_ixfr) { hp->aa = 1; if ((SEQ_GT(serial_ixfr, zp->z_serial) || - serial_ixfr == zp->z_serial)) + serial_ixfr == zp->z_serial)) { return (Finish); + } } /* @@ -1204,8 +1237,9 @@ req_query(HEADER *hp, u_char **cpp, u_char *eom, struct qstream *qsp, if (!founddata && hp->rd && recursion_blocked_by_acl) { ns_notice(ns_log_security, - "unapproved recursive query from %s for %s", + "denied recursion for query from %s for %s", sin_ntoa(from), *dname ? dname : "."); + nameserIncr(from.sin_addr, nssRcvdURQ); } /* @@ -1591,11 +1625,11 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, } #endif if ((n = dn_comp(name, buf, buflen, comp_ptrs, edp)) < 0) - return (-1); + goto cleanup; cp = buf + n; buflen -= n; if (buflen < 0) - return (-1); + goto cleanup; PUTSHORT((u_int16_t)type, cp); PUTSHORT((u_int16_t)dp->d_class, cp); PUTLONG(ttl, cp); @@ -1608,7 +1642,7 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, case T_PTR: n = dn_comp((char *)dp->d_data, cp, buflen, comp_ptrs, edp); if (n < 0) - return (-1); + goto cleanup; PUTSHORT((u_int16_t)n, sp); cp += n; break; @@ -1618,7 +1652,7 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, /* Store domain name in answer */ n = dn_comp((char *)dp->d_data, cp, buflen, comp_ptrs, edp); if (n < 0) - return (-1); + goto cleanup; PUTSHORT((u_int16_t)n, sp); cp += n; if (doadd) { @@ -1634,15 +1668,15 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, cp1 = dp->d_data; n = dn_comp((char *)cp1, cp, buflen, comp_ptrs, edp); if (n < 0) - return (-1); + goto cleanup; cp += n; buflen -= type == T_SOA ? n + 5 * INT32SZ : n; if (buflen < 0) - return (-1); + goto cleanup; cp1 += strlen((char *)cp1) + 1; n = dn_comp((char *)cp1, cp, buflen, comp_ptrs, edp); if (n < 0) - return (-1); + goto cleanup; cp += n; if (type == T_SOA) { cp1 += strlen((char *)cp1) + 1; @@ -1670,7 +1704,7 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, /* copy order */ buflen -= INT16SZ; if (buflen < 0) - return (-1); + goto cleanup; memcpy(cp, cp1, INT16SZ); cp += INT16SZ; cp1 += INT16SZ; @@ -1680,7 +1714,7 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, /* copy preference */ buflen -= INT16SZ; if (buflen < 0) - return (-1); + goto cleanup; memcpy(cp, cp1, INT16SZ); cp += INT16SZ; cp1 += INT16SZ; @@ -1692,7 +1726,7 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, ns_debug(ns_log_default, 1, "size of n at flags = %d", n); buflen -= n + 1; if (buflen < 0) - return (-1); + goto cleanup; *cp++ = n; memcpy(cp, cp1, n); cp += n; @@ -1704,7 +1738,7 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, n = *cp1++; buflen -= n + 1; if (buflen < 0) - return (-1); + goto cleanup; *cp++ = n; memcpy(cp, cp1, n); cp += n; @@ -1716,7 +1750,7 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, n = *cp1++; buflen -= n + 1; if (buflen < 0) - return (-1); + goto cleanup; *cp++ = n; memcpy(cp, cp1, n); cp += n; @@ -1729,7 +1763,7 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, n = dn_comp((char *)cp1, cp, buflen, dnptrs, edp); ns_debug(ns_log_default, 1, "dn_comp's n = %u", n); if (n < 0) - return (-1); + goto cleanup; cp += n; /* save data length */ @@ -1747,7 +1781,7 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, cp1 = dp->d_data; if ((buflen -= INT16SZ) < 0) - return (-1); + goto cleanup; /* copy preference */ memcpy(cp, cp1, INT16SZ); @@ -1757,7 +1791,7 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, if (type == T_SRV) { buflen -= INT16SZ*2; if (buflen < 0) - return (-1); + goto cleanup; memcpy(cp, cp1, INT16SZ*2); cp += INT16SZ*2; cp1 += INT16SZ*2; @@ -1767,7 +1801,7 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, (type == ns_t_mx) ? comp_ptrs : NULL, (type == ns_t_mx) ? edp : NULL); if (n < 0) - return (-1); + goto cleanup; cp += n; /* save data length */ @@ -1781,7 +1815,7 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, cp1 = dp->d_data; if ((buflen -= INT16SZ) < 0) - return (-1); + goto cleanup; /* copy preference */ memcpy(cp, cp1, INT16SZ); @@ -1790,13 +1824,13 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, n = dn_comp((char *)cp1, cp, buflen, comp_ptrs, edp); if (n < 0) - return (-1); + goto cleanup; cp += n; buflen -= n; cp1 += strlen((char *)cp1) + 1; n = dn_comp((char *)cp1, cp, buflen, comp_ptrs, edp); if (n < 0) - return (-1); + goto cleanup; cp += n; /* save data length */ @@ -1811,7 +1845,7 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, /* first just copy over the type_covered, algorithm, */ /* labels, orig ttl, two timestamps, and the footprint */ if ((dp->d_size - 18) > buflen) - return (-1); /* out of room! */ + goto cleanup; /* out of room! */ memcpy(cp, cp1, 18); cp += 18; cp1 += 18; @@ -1820,7 +1854,7 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, /* then the signer's name */ n = dn_comp((char *)cp1, cp, buflen, NULL, NULL); if (n < 0) - return (-1); + goto cleanup; cp += n; buflen -= n; cp1 += strlen((char*)cp1)+1; @@ -1828,20 +1862,20 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, /* finally, we copy over the variable-length signature */ n = dp->d_size - (u_int16_t)((cp1 - dp->d_data)); if (n > buflen) - return (-1); /* out of room! */ + goto cleanup; /* out of room! */ memcpy(cp, cp1, n); cp += n; - /* save data length & return */ + /* save data length & return */ n = (u_int16_t)((cp - sp) - INT16SZ); - PUTSHORT((u_int16_t)n, sp); + PUTSHORT((u_int16_t)n, sp); break; case T_NXT: cp1 = dp->d_data; n = dn_comp((char *)cp1, cp, buflen, NULL, NULL); if (n < 0) - return (-1); + goto cleanup; cp += n; buflen -=n; @@ -1850,7 +1884,7 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, /* copy nxt bit map */ n = dp->d_size - (u_int16_t)((cp1 - dp->d_data)); if (n > buflen) - return (-1); /* out of room! */ + goto cleanup; /* out of room! */ memcpy(cp, cp1, n); cp += n; buflen -= n; @@ -1864,12 +1898,18 @@ make_rr(const char *name, struct databuf *dp, u_char *buf, if ((type == T_A || type == T_AAAA) && doadd) addname(name, name, type, T_KEY, dp->d_class); if (dp->d_size > buflen) - return (-1); + goto cleanup; memcpy(cp, dp->d_data, dp->d_size); PUTSHORT((u_int16_t)dp->d_size, sp); cp += dp->d_size; } return (cp - buf); + + cleanup: + /* Rollback RR. */ + ns_name_rollback(buf, (const u_char **)comp_ptrs, + (const u_char **)edp); + return (-1); } static void @@ -1965,7 +2005,9 @@ loop: !match(dp, (int)ap->a_class, T_A) && !match(dp, C_IN, T_A) && !match(dp, (int)ap->a_class, T_AAAA) && - !match(dp, C_IN, T_AAAA)) { + !match(dp, C_IN, T_AAAA) && + !match(dp, (int)ap->a_class, ns_t_a6) && + !match(dp, C_IN, ns_t_a6)) { continue; } if (ap->a_type == T_KEY && @@ -1993,6 +2035,10 @@ loop: ns_debug(ns_log_default, 5, "addinfo: not enough room, remaining msglen = %d", save_msglen); + /* Rollback RRset. */ + ns_name_rollback(save_cp, + (const u_char **)dnptrs, + (const u_char **)dnptrs_end); cp = save_cp; msglen = save_msglen; count = save_count; diff --git a/contrib/bind/bin/named/ns_resp.c b/contrib/bind/bin/named/ns_resp.c index d20b1ef..0646618 100644 --- a/contrib/bind/bin/named/ns_resp.c +++ b/contrib/bind/bin/named/ns_resp.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)ns_resp.c 4.65 (Berkeley) 3/3/91"; -static const char rcsid[] = "$Id: ns_resp.c,v 8.133 1999/11/05 04:40:57 vixie Exp $"; +static const char rcsid[] = "$Id: ns_resp.c,v 8.143 2000/05/09 07:38:38 vixie Exp $"; #endif /* not lint */ /* @@ -82,7 +82,7 @@ static const char rcsid[] = "$Id: ns_resp.c,v 8.133 1999/11/05 04:40:57 vixie Ex */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -148,7 +148,8 @@ static const char skipnameFailedAnswer[] = "skipname failed in answer", outofDataAFinal[] = "out of data after final pass", badNameFound[] = "found an invalid domain name", wrongQuestion[] = "answer to wrong question", - danglingCname[] = "dangling CNAME pointer"; + danglingCname[] = "dangling CNAME pointer", + nonRecursiveForwarder[]= "non-recursive forwarder"; struct db_list { struct db_list *db_next; @@ -463,20 +464,14 @@ ns_resp(u_char *msg, int msglen, struct sockaddr_in from, struct qstream *qsp) * XXX - should put this in STATS somewhere. */ for (fwd = NS_ZFWDTAB(qp->q_fzone); fwd; fwd = fwd->next) - if (ina_equal(fwd->fwdaddr.sin_addr, from.sin_addr)) + if (ina_equal(fwd->fwddata->fwdaddr.sin_addr, from.sin_addr)) break; /* - * XXX: note bad ambiguity here. if one of our forwarders is also - * a delegated server for some domain, then we will not update - * the RTT information on any replies we get from those servers. - * Workaround: disable recursion on authoritative servers so that - * the ambiguity does not arise. - */ /* - * If we weren't using a forwarder, find the qinfo pointer and update + * find the qinfo pointer and update * the rtt and fact that we have called on this server before. */ - if (fwd == NULL) { + { struct timeval *stp; for (n = 0, qs = qp->q_addr; (u_int)n < qp->q_naddr; n++, qs++) @@ -706,13 +701,15 @@ ns_resp(u_char *msg, int msglen, struct sockaddr_in from, struct qstream *qsp) /* * Non-authoritative, no answer, no error, with referral. */ - if (hp->rcode == NOERROR && !hp->aa && ancount == 0 && aucount > 0 + if (hp->rcode == NOERROR && !hp->tc && !hp->aa && + ancount == 0 && aucount > 0 #ifdef BIND_NOTIFY && hp->opcode != NS_NOTIFY_OP #endif ) { u_char *tp; - int type, class; + int type, class, dlen; + int foundns, foundsoa; #ifdef DEBUG if (debug > 0) res_pquery(&res, msg, msglen, @@ -723,23 +720,40 @@ ns_resp(u_char *msg, int msglen, struct sockaddr_in from, struct qstream *qsp) * we must be pointing at the authority section (aucount > 0). */ tp = cp; - n = dn_expand(msg, eom, tp, name, sizeof name); - if (n < 0) { - formerrmsg = expandFailedAuth; - goto formerr; - } - tp += n; - if (tp + 2 * INT16SZ > eom) { - formerrmsg = outofDataAuth; - goto formerr; - } - GETSHORT(type, tp); - GETSHORT(class, tp); - if (!ns_nameok(qp, name, class, NULL, response_trans, - ns_ownercontext(type, response_trans), - name, from.sin_addr)) { - formerrmsg = badNameFound; - goto refused; + foundns = foundsoa = 0; + for (i = 0 ; i < aucount ; i++) { + n = dn_expand(msg, eom, tp, name, sizeof name); + if (n < 0) { + formerrmsg = expandFailedAuth; + goto formerr; + } + tp += n; + if (tp + 3 * INT16SZ + INT32SZ > eom) { + formerrmsg = outofDataAuth; + goto formerr; + } + GETSHORT(type, tp); + GETSHORT(class, tp); + tp += INT32SZ; /* ttl */ + GETSHORT(dlen, tp); + if (!ns_nameok(qp, name, class, NULL, response_trans, + ns_ownercontext(type, response_trans), + name, from.sin_addr)) { + formerrmsg = badNameFound; + goto refused; + } + /* skip rest of record */ + if (tp + dlen > eom) { + formerrmsg = outofDataAuth; + goto formerr; + } + tp += dlen; + if (type == T_NS) { + strcpy(aname, name); + foundns = 1; + } + if (type == T_SOA) + foundsoa = 1; } /* @@ -751,11 +765,14 @@ ns_resp(u_char *msg, int msglen, struct sockaddr_in from, struct qstream *qsp) * classes tend to not have good strong delegation graphs). */ - if (type == T_NS && ns_samedomain(qp->q_domain, name)) { - nameserIncr(from.sin_addr, nssRcvdLDel); - mark_lame(qp, from); + if (foundns && !foundsoa && + ns_samedomain(qp->q_domain, aname)) { + if (fwd == NULL) { + nameserIncr(from.sin_addr, nssRcvdLDel); + mark_lame(qp, from); + } mark_bad(qp, from); - if (class == C_IN && + if (class == C_IN && fwd == NULL && !haveComplained(ina_ulong(from.sin_addr), nhash(qp->q_domain))) { char *learnt_from = learntFrom(qp, &from); @@ -768,6 +785,12 @@ ns_resp(u_char *msg, int msglen, struct sockaddr_in from, struct qstream *qsp) learnt_from); if (learnt_from != NULL) freestr(learnt_from); + } else if (fwd != NULL) { + if (!haveComplained(ina_ulong(from.sin_addr), + (u_long)nonRecursiveForwarder)) + ns_warning(ns_log_default, "%s: %s", + nonRecursiveForwarder, + sin_ntoa(from)); } fast_retry(qp, from); @@ -788,7 +811,7 @@ ns_resp(u_char *msg, int msglen, struct sockaddr_in from, struct qstream *qsp) /* -ve $ing non-existence of record, must handle non-authoritative * NOERRORs with c == 0. */ - if (!hp->aa && hp->rcode == NOERROR && c == 0) + if (!hp->aa && !hp->tc && hp->rcode == NOERROR && c == 0) goto return_msg; if (qp->q_flags & Q_SYSTEM) @@ -979,19 +1002,22 @@ tcp_retry: case T_SOA: if (!ns_samedomain(aname, name)) { ns_info(ns_log_resp_checks, - "bad referral (%s !< %s)", + "bad referral (%s !< %s) from %s", aname[0] ? aname : ".", - name[0] ? name : "."); + name[0] ? name : ".", + sin_ntoa(from)); db_freedata(dp); continue; - } else if (!ns_samedomain(name, + } else if (fwd == NULL && + !ns_samedomain(name, qp->q_domain)) { if (!externalcname) ns_info(ns_log_resp_checks, - "bad referral (%s !< %s)", + "bad referral (%s !< %s) from %s", name[0] ? name : ".", qp->q_domain[0] ? - qp->q_domain : "."); + qp->q_domain : ".", + sin_ntoa(from)); db_freedata(dp); continue; } @@ -1182,17 +1208,11 @@ tcp_retry: founddata = 0; dname = name; /* - * If restart==0 and ancount > 0, we should - * have some valid data because because the data in the answer - * section is owned by the query name and that passes the - * validation test by definition - * * XXX - the restart stuff doesn't work if any of the answer RRs * is not cacheable (TTL==0 or unknown RR type), since all of the * answer must pass through the cache and be re-assembled. */ - if ((forcecmsg && qp->q_cmsglen) || - ((!restart || !cname) && qp->q_cmsglen && ancount)) { + if (qp->q_cmsglen != 0) { ns_debug(ns_log_default, 1, "Cname second pass"); newmsglen = MIN(PACKETSZ, qp->q_cmsglen); memcpy(newmsg, qp->q_cmsg, newmsglen); @@ -1461,8 +1481,7 @@ tcp_retry: } else hp = (HEADER *) qp->q_msg; hp->id = qp->q_nsid = htons(nsid_next()); - if (qp->q_addr[0].forwarder) - hp->rd = 1; + hp->rd = (qp->q_addr[0].forwarder ? 1 : 0); unsched(qp); schedretry(qp, retrytime(qp)); nsa = Q_NEXTADDR(qp, 0); @@ -1560,6 +1579,11 @@ tcp_retry: return_msg: nameserIncr(from.sin_addr, nssRcvdFwdR); nameserIncr(qp->q_from.sin_addr, nssSentFwdR); + nameserIncr(qp->q_from.sin_addr, nssSentAns); + if (!hp->aa) + nameserIncr(qp->q_from.sin_addr, nssSentNaAns); + if (hp->rcode == NXDOMAIN) + nameserIncr(qp->q_from.sin_addr, nssSentNXD); /* The "standard" return code */ hp->qr = 1; hp->id = qp->q_id; @@ -2093,6 +2117,7 @@ rrextract(u_char *msg, int msglen, u_char *rrp, struct databuf **dpp, } memcpy(cp1, cp, n2); cp += n2; + cp1 += n2; /* compute size of data */ n = cp1 - (u_char *)data; @@ -2279,7 +2304,7 @@ sysquery(const char *dname, int class, int type, nsp[0] = NULL; ns_debug(ns_log_default, 3, "sysquery(%s, %d, %d, %#x, %d, %d)", dname, class, type, nss, nsc, ntohs(port)); - qp = qnew(dname, class, type); + qp = qnew(dname, class, type, (nss != NULL && nsc != 0) ? 0 : 1); if (nss != NULL && nsc != 0) np = NULL; @@ -3106,7 +3131,10 @@ finddata(struct namebuf *np, int class, int type, case cyclic_order: /* first we do the non-SIG records */ - choice = ((u_int)rand()>>3) % non_sig_count; + if (non_sig_count > 0) + choice = ((u_int)rand()>>3) % non_sig_count; + else + choice = 0; for (i = 0; i < non_sig_count ; i++) { dp = found[(i + choice) % non_sig_count]; if (foundcname != 0 && dp->d_type == T_CNAME) diff --git a/contrib/bind/bin/named/ns_signal.c b/contrib/bind/bin/named/ns_signal.c index 4c7c48a..8cc715b 100644 --- a/contrib/bind/bin/named/ns_signal.c +++ b/contrib/bind/bin/named/ns_signal.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)ns_main.c 4.55 (Berkeley) 7/1/91"; -static const char rcsid[] = "$Id: ns_signal.c,v 8.11 1999/10/13 16:39:12 vixie Exp $"; +static const char rcsid[] = "$Id: ns_signal.c,v 8.12 2000/04/21 06:54:12 vixie Exp $"; #endif /* not lint */ /* @@ -57,7 +57,7 @@ static const char rcsid[] = "$Id: ns_signal.c,v 8.11 1999/10/13 16:39:12 vixie E */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/contrib/bind/bin/named/ns_sort.c b/contrib/bind/bin/named/ns_sort.c index 25c74eb..3b3f31e 100644 --- a/contrib/bind/bin/named/ns_sort.c +++ b/contrib/bind/bin/named/ns_sort.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)ns_sort.c 4.10 (Berkeley) 3/3/91"; -static const char rcsid[] = "$Id: ns_sort.c,v 8.5 1999/10/13 16:39:12 vixie Exp $"; +static const char rcsid[] = "$Id: ns_sort.c,v 8.6 2000/04/21 06:54:13 vixie Exp $"; #endif /* not lint */ /* @@ -57,7 +57,7 @@ static const char rcsid[] = "$Id: ns_sort.c,v 8.5 1999/10/13 16:39:12 vixie Exp */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/contrib/bind/bin/named/ns_stats.c b/contrib/bind/bin/named/ns_stats.c index 44552ed..f04790b 100644 --- a/contrib/bind/bin/named/ns_stats.c +++ b/contrib/bind/bin/named/ns_stats.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)ns_stats.c 4.10 (Berkeley) 6/27/90"; -static const char rcsid[] = "$Id: ns_stats.c,v 8.27 1999/10/13 16:39:12 vixie Exp $"; +static const char rcsid[] = "$Id: ns_stats.c,v 8.30 2000/04/23 02:18:59 vixie Exp $"; #endif /* not lint */ /* @@ -57,7 +57,7 @@ static const char rcsid[] = "$Id: ns_stats.c,v 8.27 1999/10/13 16:39:12 vixie Ex */ /* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * Portions Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -122,6 +122,7 @@ ns_stats() { server_options->stats_filename); return; } + (void) fchown(fileno(f), user_id, group_id); fprintf(f, "+++ Statistics Dump +++ (%ld) %s", (long)timenow, checked_ctime(&timenow)); @@ -144,10 +145,11 @@ ns_stats() { /* Now do the memory statistics file */ if (!(f = fopen(server_options->memstats_filename, "a"))) { - ns_notice(ns_log_statistics, "cannot open memstat file, \"%s\"", + ns_notice(ns_log_statistics, "cannot open memstat file, \"%s\"", server_options->memstats_filename); return; } + (void) fchown(fileno(f), user_id, group_id); fprintf(f, "+++ Memory Statistics Dump +++ (%ld) %s", (long)timenow, checked_ctime(&timenow)); @@ -207,6 +209,10 @@ static const char *statNames[nssLast] = { "SFErr", /* sent them a FORMERR */ "SNaAns", /* sent them a non autoritative answer */ "SNXD", /* sent them a negative response */ + "RUQ", /* sent us an unapproved query */ + "RURQ", /* sent us an unapproved recursive query */ + "RUXFR", /* sent us an unapproved AXFR or IXFR */ + "RUUpd", /* sent us an unapproved update */ }; /* diff --git a/contrib/bind/bin/named/ns_udp.c b/contrib/bind/bin/named/ns_udp.c index 95f0438..23f4377 100644 --- a/contrib/bind/bin/named/ns_udp.c +++ b/contrib/bind/bin/named/ns_udp.c @@ -1,9 +1,9 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_udp.c,v 8.8 1999/10/13 16:39:13 vixie Exp $"; +static const char rcsid[] = "$Id: ns_udp.c,v 8.9 2000/04/21 06:54:13 vixie Exp $"; #endif /* not lint */ /* - * Copyright (c) 1996-1999 by Internet Software Consortium. + * Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/contrib/bind/bin/named/ns_update.c b/contrib/bind/bin/named/ns_update.c index 4f9817f..c7d8ad3 100644 --- a/contrib/bind/bin/named/ns_update.c +++ b/contrib/bind/bin/named/ns_update.c @@ -1,9 +1,9 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_update.c,v 8.68 1999/11/05 04:40:58 vixie Exp $"; +static const char rcsid[] = "$Id: ns_update.c,v 8.78 2000/04/23 02:19:00 vixie Exp $"; #endif /* not lint */ /* - * Copyright (c) 1996-1999 by Internet Software Consortium. + * Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -140,30 +140,45 @@ static int rdata_expand(const u_char *, const u_char *, const u_char *, static FILE * open_transaction_log(struct zoneinfo *zp) { - FILE *fp; - - fp = fopen(zp->z_updatelog, "a+"); + FILE *fp = fopen(zp->z_updatelog, "a+"); + if (fp == NULL) { ns_error(ns_log_update, "can't open %s: %s", zp->z_updatelog, strerror(errno)); return (NULL); } + (void) fchown(fileno(fp), user_id, group_id); + if (fseek(fp, 0L, SEEK_END) != 0) { + ns_error(ns_log_update, "can't fseek(%s, 0, SEEK_END)", + zp->z_updatelog); + fclose(fp); + return (NULL); + } if (ftell(fp) == 0L) { fprintf(fp, "%s", LogSignature); + zp->z_serial_ixfr_start = get_serial(zp); } + else + zp->z_serial_ixfr_start = 0; return (fp); } static FILE * open_ixfr_log(struct zoneinfo *zp) { - FILE *fp; - - fp = fopen(zp->z_ixfr_base, "a+"); + FILE *fp = fopen(zp->z_ixfr_base, "a+"); + if (fp == NULL) { ns_error(ns_log_update, "can't open %s: %s", zp->z_ixfr_base, strerror(errno)); return (NULL); } + (void) fchown(fileno(fp), user_id, group_id); + if (fseek(fp, 0L, SEEK_END) != 0) { + ns_error(ns_log_update, "can't fseek(%s, 0, SEEK_END)", + zp->z_ixfr_base); + fclose(fp); + return (NULL); + } if (ftell(fp) == 0L) { fprintf(fp, "%s", LogSignature); } @@ -425,16 +440,10 @@ schedule_soa_update(struct zoneinfo *zp, int numupdated) { */ zp->z_updatecnt += numupdated; if (zp->z_updatecnt >= zp->z_deferupdcnt) { - if (incr_serial(zp) < 0) { - ns_error(ns_log_update, - "error updating serial number for %s from %d", - zp->z_origin, zp->z_serial); - } else - return (0); - /* - * Note we continue scheduling if for some reason - * incr_serial fails. - */ + if (zp->z_soaincrtime > tt.tv_sec) { + zp->z_soaincrtime = tt.tv_sec; + return (1); + } } if (zp->z_soaincrintvl > 0) { @@ -655,8 +664,6 @@ process_prereq(ns_updrec *ur, int *rcodep, u_int16_t zclass) { *rcodep = FORMERR; return (0); } - htp = hashtab; - np = nlookup(dname, &htp, &fname, 0); if (np == NULL || fname != dname) { *rcodep = NXRRSET; return (0); @@ -880,6 +887,12 @@ prescan_update(ns_updrec *ur, int *rcodep, u_int16_t zclass) { *rcodep = FORMERR; return (0); } + if (ttl > MAXIMUM_TTL) { + ns_debug(ns_log_update, 1, + "prescan_update: invalid ttl (%u)", ttl); + *rcodep = FORMERR; + return (0); + } } else if (class == C_ANY) { if (ttl != 0 || rdp->d_size || (!ns_t_rr_p(type) && type != T_ANY)) @@ -1189,8 +1202,9 @@ req_update_private(HEADER *hp, u_char *cp, u_char *eom, u_char *msg, */ if (!ip_addr_or_key_allowed(zp->z_update_acl, from.sin_addr, in_key)) { - ns_notice(ns_log_security, "unapproved update from %s for %s", + ns_notice(ns_log_security, "denied update from %s for %s", sin_ntoa(from), *dname ? dname : "."); + nameserIncr(from.sin_addr, nssRcvdUUpd); return (Refuse); } @@ -1210,10 +1224,11 @@ req_update_private(HEADER *hp, u_char *cp, u_char *eom, u_char *msg, if (zp->z_type == Z_SECONDARY) { /* * XXX The code below is broken. - * Until fixed, we just refuse. + * Until fixed, we just return NOTIMPL. */ #if 1 - return (Refuse); + hp->rcode = ns_r_notimpl; + return (Finish); #else /* We are a slave for this zone, forward it to the master. */ for (cnt = 0; cnt < zp->z_addrcnt; cnt++) @@ -1236,12 +1251,12 @@ req_update_private(HEADER *hp, u_char *cp, u_char *eom, u_char *msg, eom -= tsig_len; free_nsp(nsp); switch (n) { - case FW_OK: - case FW_DUP: + case FW_OK: + case FW_DUP: return (Return); - case FW_NOSERVER: + case FW_NOSERVER: /* should not happen */ - case FW_SERVFAIL: + case FW_SERVFAIL: hp->rcode = SERVFAIL; return (Finish); } @@ -1324,7 +1339,7 @@ req_update_private(HEADER *hp, u_char *cp, u_char *eom, u_char *msg, rrecp->r_dp = dp; /* Append the current record to the end of list of records. */ APPEND(curupd, rrecp, r_link); - if (cp > eom) { + if (cp > eom) { ns_info(ns_log_update, "Malformed response from %s (overrun)", inet_ntoa(from.sin_addr)); @@ -2635,21 +2650,21 @@ merge_logs(struct zoneinfo *zp, char *logname) { } } else { /* section == S_UPDATE */ if (opcode == DELETE) { - ttl = 0; + ttl = 0; if (n == 0) { class = C_ANY; if (type == -1) type = T_ANY; - /* WTF? C_NONE or C_ANY _must_ be the case if - * we really are to delete this. If - * C_NONE is used, according to process_updates(), - * the class is gotten from the zone's class. - * This still isn't perfect, but it will at least - * work. - * - * Question: What is so special about the class - * of the update while we are deleting?? - */ + /* WTF? C_NONE or C_ANY _must_ be the case if + * we really are to delete this. If + * C_NONE is used, according to process_updates(), + * the class is gotten from the zone's class. + * This still isn't perfect, but it will at least + * work. + * + * Question: What is so special about the class + * of the update while we are deleting?? + */ } else /* if (zp->z_xferpid != XFER_ISIXFR) */ { class = C_NONE; } @@ -2794,22 +2809,22 @@ zonedump(struct zoneinfo *zp, int mode) { } if (mode == ISIXFR) { - if (movefile(tmp_name, zp->z_ixfr_tmp) < 0) { - ns_error(ns_log_update, "movefile(%s,%s) failed: %s :2", - tmp_name, zp->z_ixfr_tmp, strerror(errno)); - return (-1); - } + if (movefile(tmp_name, zp->z_ixfr_tmp) < 0) { + ns_error(ns_log_update, "movefile(%s,%s) failed: %s :2", + tmp_name, zp->z_ixfr_tmp, strerror(errno)); + return (-1); + } if (chmod(zp->z_source, 0644) < 0) ns_error(ns_log_update, "chmod(%s,%o) failed, pressing on: %s", zp->z_source, st.st_mode, strerror(errno)); - if (movefile(zp->z_ixfr_tmp, zp->z_source) < 0) { - ns_error(ns_log_update, "movefile(%s,%s) failed: %s :3", - zp->z_ixfr_tmp, zp->z_source, - strerror(errno)); - return (-1); - } + if (movefile(zp->z_ixfr_tmp, zp->z_source) < 0) { + ns_error(ns_log_update, "movefile(%s,%s) failed: %s :3", + zp->z_ixfr_tmp, zp->z_source, + strerror(errno)); + return (-1); + } st.st_mode &= ~WRITEABLE_MASK; if (chmod(zp->z_source, st.st_mode) < 0) ns_error(ns_log_update, @@ -2830,9 +2845,9 @@ zonedump(struct zoneinfo *zp, int mode) { } } else { if (movefile(tmp_name, zp->z_source) < 0) { - ns_error(ns_log_update, "movefile(%s,%s) failed: % s :6", tmp_name, zp->z_source, strerror(errno)); - return (-1); - } + ns_error(ns_log_update, "movefile(%s,%s) failed: % s :6", tmp_name, zp->z_source, strerror(errno)); + return (-1); + } } } else ns_debug(ns_log_update, 1, "zonedump: no zone to dump"); @@ -2844,15 +2859,15 @@ zonedump(struct zoneinfo *zp, int mode) { struct databuf * findzonesoa(struct zoneinfo *zp) { - struct hashbuf *htp; - struct namebuf *np; - struct databuf *dp; - const char *fname; + struct hashbuf *htp; + struct namebuf *np; + struct databuf *dp; + const char *fname; htp = hashtab; - np = nlookup(zp->z_origin, &htp, &fname, 0); - if (np == NULL || fname != zp->z_origin) - return (NULL); + np = nlookup(zp->z_origin, &htp, &fname, 0); + if (np == NULL || fname != zp->z_origin) + return (NULL); foreach_rr(dp, np, T_SOA, zp->z_class, zp - zones) return (dp); return (NULL); @@ -2933,7 +2948,7 @@ incr_serial(struct zoneinfo *zp) { unsigned char *cp; old_serial = get_serial(zp); - serial = old_serial + 1; + serial = old_serial + 1; if (serial == 0) serial = 1; set_serial(zp, serial); @@ -2991,7 +3006,7 @@ incr_serial(struct zoneinfo *zp) { void dynamic_about_to_exit(void) { - struct zoneinfo *zp; + struct zoneinfo *zp; ns_debug(ns_log_update, 1, "shutting down; dumping zones that need it"); diff --git a/contrib/bind/bin/named/ns_xfr.c b/contrib/bind/bin/named/ns_xfr.c index e25a536..f5cbdfa 100644 --- a/contrib/bind/bin/named/ns_xfr.c +++ b/contrib/bind/bin/named/ns_xfr.c @@ -1,9 +1,9 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_xfr.c,v 8.55 1999/10/13 16:39:13 vixie Exp $"; +static const char rcsid[] = "$Id: ns_xfr.c,v 8.62 2000/04/24 05:20:51 vixie Exp $"; #endif /* not lint */ /* - * Copyright (c) 1996-1999 by Internet Software Consortium. + * Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -79,7 +79,7 @@ ns_xfr(struct qstream *qsp, struct namebuf *znp, #ifdef SO_SNDLOWAT static const int sndlowat = XFER_BUFSIZE; #endif - ns_updrec *changes; + ns_deltalist *changes; switch (type) { case ns_t_axfr: /*FALLTHROUGH*/ @@ -123,6 +123,8 @@ ns_xfr(struct qstream *qsp, struct namebuf *znp, qsp->xfr.top.axfr = znp; qsp->xfr.zone = zone; qsp->xfr.class = class; + if (qsp->flags & STREAM_AXFRIXFR) + type = ns_t_axfr; qsp->xfr.type = type; qsp->xfr.id = id; qsp->xfr.opcode = opcode; @@ -186,25 +188,32 @@ ns_xfr(struct qstream *qsp, struct namebuf *znp, if (type == ns_t_ixfr) { changes = ixfr_get_change_list(&zones[zone], serial_ixfr, zones[zone].z_serial); - if (changes != NULL) - { + ixfr_log_maint(&zones[zone], 1); + if (changes != NULL) { qsp->xfr.serial = serial_ixfr; qsp->xfr.top.ixfr = changes; } - else - type = ns_t_axfr; - } + else { + qsp->xfr.top.ixfr = NULL; + goto abort; + } + } else { if (sx_pushlev(qsp, znp) < 0) { abort: (void) shutdown(qsp->s_rfd, 2); sq_remove(qsp); return; } - if (type != ns_t_ixfr) + } + if (type != ns_t_ixfr) { + ns_debug(ns_log_default, 3, "sq_writeh sx_sendsoa (%s)", + zones[zone].z_origin); (void) sq_writeh(qsp, sx_sendsoa); - else + } else { + ns_debug(ns_log_default, 3, "sq_writeh sx_send_ixfr (%s)", + zones[zone].z_origin); (void) sq_writeh(qsp, sx_send_ixfr); - + } } /* @@ -217,6 +226,8 @@ ns_stopxfrs(struct zoneinfo *zp) { struct qstream *this, *next; u_int zone = (u_int)(zp - zones); + ns_debug(ns_log_default, 3, "ns_stopxfrs (%s)", zp->z_origin); + for (this = streamq; this; this = next) { next = this->s_next; if (this->xfr.zone == zone) { @@ -234,19 +245,37 @@ ns_stopxfrs(struct zoneinfo *zp) { */ void ns_freexfr(struct qstream *qsp) { + ns_delta *dp; + ns_updrec *rp; + if (qsp->xfr.msg != NULL) { memput(qsp->xfr.msg, XFER_BUFSIZE); qsp->xfr.msg = NULL; } + if (qsp->xfr.type == ns_t_ixfr && qsp->xfr.top.ixfr != NULL) { + while ((dp = HEAD(*qsp->xfr.top.ixfr)) != NULL) { + UNLINK(*qsp->xfr.top.ixfr, dp, d_link); + while ((rp = HEAD(dp->d_changes)) != NULL) { + UNLINK(dp->d_changes, rp, r_link); + if (rp->r_dp != NULL) + db_freedata(rp->r_dp); + rp->r_dp = NULL; + res_freeupdrec(rp); + } + memput(dp, sizeof *dp); + } + memput(qsp->xfr.top.ixfr, sizeof *qsp->xfr.top.ixfr); + qsp->xfr.top.ixfr = NULL; + } while (qsp->xfr.lev) qsp->xfr.lev = sx_freelev(qsp->xfr.lev); zones[qsp->xfr.zone].z_numxfrs--; - qsp->flags &= ~STREAM_AXFR; + qsp->flags &= ~(STREAM_AXFR | STREAM_AXFRIXFR); } /* * u_char * - * renew_msg(msg) + * sx_newmsg(msg) * init the header of a message, reset the compression pointers, and * reset the write pointer to the first byte following the header. */ @@ -315,7 +344,7 @@ sx_flush(struct qstream *qsp) { * int * sx_addrr(qsp, name, dp) * add name/dp's RR to the current assembly message. if it won't fit, - * write current message out, renew the message, and then RR should fit. + * write current message out, renew the message, and then RR *must* fit. * return: * -1 = the sx_flush() failed so we could not queue the full message. * 0 = one way or another, everything is fine. @@ -339,18 +368,20 @@ sx_addrr(struct qstream *qsp, const char *dname, struct databuf *dp) { /* * Add question to first answer. */ - if (qsp->xfr.state == s_x_firstsoa && dp->d_type == T_SOA ) { - if ((qsp->xfr.type == ns_t_ixfr) || (qsp->flags & STREAM_AXFRIXFR)) { - n = dn_comp(dname, qsp->xfr.cp, qsp->xfr.eom - qsp->xfr.cp, - qsp->xfr.ptrs, edp); - if (n > 0 && (qsp->xfr.cp + n + INT16SZ * 2) <= qsp->xfr.eom) { - qsp->xfr.cp += n; - type = (qsp->xfr.type == ns_t_zxfr) ? - ns_t_axfr : qsp->xfr.type; - PUTSHORT((u_int16_t) type, qsp->xfr.cp); - PUTSHORT((u_int16_t) qsp->xfr.class, qsp->xfr.cp); - hp->qdcount = htons(ntohs(hp->qdcount) + 1); - } + if (qsp->xfr.state == s_x_firstsoa && dp->d_type == T_SOA) { + n = dn_comp(dname, qsp->xfr.cp, qsp->xfr.eom - qsp->xfr.cp, + qsp->xfr.ptrs, edp); + if (n > 0 && (qsp->xfr.cp + n + INT16SZ * 2) <= qsp->xfr.eom) { + qsp->xfr.cp += n; + if (qsp->xfr.type == ns_t_zxfr) + type = ns_t_axfr; + else if ((qsp->flags & STREAM_AXFRIXFR) != 0) + type = ns_t_ixfr; + else + type = qsp->xfr.type; + PUTSHORT((u_int16_t) type, qsp->xfr.cp); + PUTSHORT((u_int16_t) qsp->xfr.class, qsp->xfr.cp); + hp->qdcount = htons(ntohs(hp->qdcount) + 1); } } @@ -416,11 +447,9 @@ sx_soarr(struct qstream *qsp) { /* * int * sx_nsrrs(qsp) - * add the NS RR's at the current level's current np, - * to the assembly message - * This function also adds the SIG(NS), KEY, SIG(KEY), NXT, SIG(NXT) - * the reason for this these records are part of the delegation. - * + * add the NS RR's at the current level's current np to the assembly msg. + * This function also adds the SIG(NS), KEY, SIG(KEY), NXT, SIG(NXT), + * since these records are also part of the delegation (see DNSSEC). * return: * >1 = number of NS RRs added, note that there may be more * 0 = success, there are no more NS RRs at this level @@ -438,15 +467,13 @@ sx_nsrrs(struct qstream *qsp) { struct namebuf *gnp, *tnp, *top; struct hashbuf *htp; const char *fname; - int rrcount, class; + int class; class = qsp->xfr.class; top = qsp->xfr.top.axfr; - rrcount = 0; for ((void)NULL; (dp = qsp->xfr.lev->dp) != NULL; qsp->xfr.lev->dp = db_next(dp)) { - /* XYZZY foreach_rr? */ if (dp->d_class != class && class != C_ANY) continue; if (dp->d_rcode) @@ -475,7 +502,9 @@ sx_nsrrs(struct qstream *qsp) { } if (dp->d_type != T_NS) /* no glue processing */ continue; - rrcount++; /* only count NS records */ + /* Remember we have found a zone cut */ + if (qsp->xfr.top.axfr != qsp->xfr.lev->np) + qsp->xfr.lev->flags |= SXL_ZONECUT; } /* @@ -528,9 +557,17 @@ sx_nsrrs(struct qstream *qsp) { */ return (-1); } + foreach_rr(gdp, gnp, ns_t_a6, class, DB_Z_CACHE) + if (sx_addrr(qsp, fname, gdp) < 0) { + /* + * Rats. We already sent the NS RR, too. + * Note that SXL_GLUING is being left on. + */ + return (-1); + } qsp->xfr.lev->flags &= ~SXL_GLUING; } - return (rrcount); + return (0); } /* @@ -565,7 +602,6 @@ sx_allrrs(struct qstream *qsp) { for ((void)NULL; (dp = qsp->xfr.lev->dp) != NULL; qsp->xfr.lev->dp = db_next(dp)) { - /* XYZZY foreach_rr? */ if (dp->d_class != class && class != C_ANY) continue; if (dp->d_rcode) @@ -605,7 +641,6 @@ sx_allrrs(struct qstream *qsp) { void sx_sendlev(struct qstream *qsp) { struct qs_x_lev *lev; - int rrcount; again: lev = qsp->xfr.lev; @@ -618,16 +653,9 @@ sx_sendlev(struct qstream *qsp) { sq_remove(qsp); return; } - rrcount = sx_nsrrs(qsp); /* If we can't pack this one in, come back later. */ - if (rrcount < 0) + if (sx_nsrrs(qsp) < 0) return; - /* - * NS RRs other than those at the - * zone top are zone cuts. - */ - if (rrcount > 0 && qsp->xfr.top.axfr != lev->np) - lev->flags |= SXL_ZONECUT; } /* No more DP's for the NS RR pass on this NP. */ if (lev->flags & SXL_ZONECUT) { diff --git a/contrib/bind/bin/named/pathtemplate.h b/contrib/bind/bin/named/pathtemplate.h index 65056b6..3011713 100644 --- a/contrib/bind/bin/named/pathtemplate.h +++ b/contrib/bind/bin/named/pathtemplate.h @@ -1,9 +1,9 @@ /* - * $Id: pathtemplate.h,v 8.4 1999/01/08 19:28:30 vixie Exp $ + * $Id: pathtemplate.h,v 8.6 2000/04/21 06:54:15 vixie Exp $ */ /* - * Copyright (c) 1996-1999 by Internet Software Consortium. + * Copyright (c) 1996-2000 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -42,8 +42,12 @@ #endif #ifndef _PATH_NDCSOCK +#ifdef NEED_SECURE_DIRECTORY +#define _PATH_NDCSOCK "%DESTRUN%/ndc.d/ndc" +#else #define _PATH_NDCSOCK "%DESTRUN%/ndc" #endif +#endif #ifndef _PATH_STATS #define _PATH_STATS "named.stats" diff --git a/contrib/bind/bin/ndc/ndc.c b/contrib/bind/bin/ndc/ndc.c index 764d05b..7235586 100644 --- a/contrib/bind/bin/ndc/ndc.c +++ b/contrib/bind/bin/ndc/ndc.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ndc.c,v 1.13 1999/10/13 16:39:16 vixie Exp $"; +static const char rcsid[] = "$Id: ndc.c,v 1.14 2000/02/04 08:28:32 vixie Exp $"; #endif /* not lint */ /* @@ -47,7 +47,9 @@ static const char rcsid[] = "$Id: ndc.c,v 1.13 1999/10/13 16:39:16 vixie Exp $"; typedef union { struct sockaddr_in in; +#ifndef NO_SOCKADDR_UN struct sockaddr_un un; +#endif } sockaddr_t; typedef void (*closure)(void *, const char *, int); @@ -603,22 +605,29 @@ static int get_sockaddr(char *name, sockaddr_t *addr) { char *slash; +#ifndef NO_SOCKADDR_UN if (name[0] == '/') { memset(&addr->un, '\0', sizeof addr->un); addr->un.sun_family = AF_UNIX; strncpy(addr->un.sun_path, name, sizeof addr->un.sun_path - 1); addr->un.sun_path[sizeof addr->un.sun_path - 1] = '\0'; - } else if ((slash = strrchr(name, '/')) != NULL) { - *slash = '\0'; + } else +#endif + if ((slash = strrchr(name, '/')) != NULL) { + char *ibuf = malloc(slash - name + 1); + if (!ibuf) + usage("no memory for IP address (%s)", name); + memcpy(ibuf, name, slash - name); + ibuf[slash - name] = '\0'; memset(&addr->in, '\0', sizeof addr->in); - if (!inet_pton(AF_INET, name, &addr->in.sin_addr)) + if (!inet_pton(AF_INET, ibuf, &addr->in.sin_addr)) usage("bad ip address (%s)", name); if ((addr->in.sin_port = htons(atoi(slash+1))) == 0) usage("bad ip port (%s)", slash+1); addr->in.sin_family = AF_INET; - *slash = ':'; - } else { - return (0); + free (ibuf); + } else { + return (0); } return (1); } @@ -630,8 +639,10 @@ impute_addrlen(const struct sockaddr *sa) { switch (sa->sa_family) { case AF_INET: return (sizeof(struct sockaddr_in)); +#ifndef NO_SOCKADDR_UN case AF_UNIX: return (sizeof(struct sockaddr_un)); +#endif default: abort(); } diff --git a/contrib/bind/bin/nslookup/commands.l b/contrib/bind/bin/nslookup/commands.l index 286ae95..19cf062 100644 --- a/contrib/bind/bin/nslookup/commands.l +++ b/contrib/bind/bin/nslookup/commands.l @@ -105,7 +105,7 @@ extern void ViewList(char *); %} WS [ \t] FLET [A-Za-z0-9.*\\_] -LET [A-Za-z0-9.*] +LET [A-Za-z0-9.*_] NAME [A-Za-z0-9.*=_/-] %% ^{WS}*server{WS}+{LET}{NAME}*{WS}*$ { @@ -142,10 +142,6 @@ NAME [A-Za-z0-9.*=_/-] Finger(yytext, 0); return(1); } -^{WS}*view{WS}+{NAME}+{WS}*$ { - ViewList((char *)yytext); - return(1); - } ^{WS}*ls{WS}+(("-a"|"-d"|"-h"|"-m"|"-s"){WS}+)?{LET}{NAME}*{WS}+>>?{WS}+{NAME}+{WS}*$ { /* * 2nd arg. diff --git a/contrib/bind/bin/nslookup/list.c b/contrib/bind/bin/nslookup/list.c index 1b7f452..db46d7f 100644 --- a/contrib/bind/bin/nslookup/list.c +++ b/contrib/bind/bin/nslookup/list.c @@ -53,7 +53,7 @@ #ifndef lint static const char sccsid[] = "@(#)list.c 5.23 (Berkeley) 3/21/91"; -static const char rcsid[] = "$Id: list.c,v 8.21 1999/10/15 19:49:08 vixie Exp $"; +static const char rcsid[] = "$Id: list.c,v 8.23 2000/03/30 23:25:34 vixie Exp $"; #endif /* not lint */ /* @@ -135,7 +135,6 @@ int ListSubr(); * * To see all types of information sorted by name, do the following: * ls -d domain.edu > file - * view file * * Results: * SUCCESS the listing was successful. @@ -422,8 +421,12 @@ ListSubr(int qtype, char *domain, char *cmd) { } name = ns_rr_name(rr); if (origin[0] == '\0' && name[0] != '\0') { - fprintf(filePtr, "$ORIGIN %s.\n", name); - strcpy(origin, name); + if (strcmp(name, ".") != 0) + strcpy(origin, name); + fprintf(filePtr, "$ORIGIN %s.\n", origin); + if (strcmp(name, ".") == 0) + strcpy(origin, name); + strcpy(name_ctx, "@"); } if (qtype == T_ANY || ns_rr_type(rr) == qtype) { if (ns_sprintrr(&handle, &rr, name_ctx, origin, @@ -496,60 +499,6 @@ ListSubr(int qtype, char *domain, char *cmd) { return (ERROR); } } - -/* - ******************************************************************************* - * - * ViewList -- - * - * A hack to view the output of the ls command in sorted - * order using more. - * - ******************************************************************************* - */ - -void -ViewList(char *string) { - char file[PATH_MAX]; - char command[PATH_MAX]; - int i, j; - char soafile[PATH_MAX]; - - /* sscanf(string, " view %s", file); */ - i = matchString(" view ", string); - if (i > 0) { - j = pickString(string + i, file, sizeof file); - if (j == 0) { - fprintf(stderr, "*** invalid file name: %s\n", string + i); - return ; - } - } - - if ( !mktemp(strcpy(soafile,"/var/tmp/nslookup_tmpXXXXXX"))) { - fprintf(stderr, "*** cannot create temp file\n"); - return ; - } - (void)sprintf(command, "sed '\ -/^$/,${\ -/@/,$d\ -}\ -/^[^ ]/{\ -h\ -s/^\\([^ ]* *\\).*/\\1/\ -x\ -}\ -1,/^$/{\ -w %s\ -d\ -}\ -/^ /{\ -G\ -s/^ *//\ -s/^\\(.*\\)\\n\\(.*\\)$/\\2\\1/\ -}' %s | sort | (cat %s -; rm %s) | %s", - soafile, file, soafile, soafile, pager); - system(command); -} /* ******************************************************************************* diff --git a/contrib/bind/bin/nslookup/main.c b/contrib/bind/bin/nslookup/main.c index d36c0f4..f78d927 100644 --- a/contrib/bind/bin/nslookup/main.c +++ b/contrib/bind/bin/nslookup/main.c @@ -77,7 +77,7 @@ char copyright[] = #ifndef lint static const char sccsid[] = "@(#)main.c 5.42 (Berkeley) 3/3/91"; -static const char rcsid[] = "$Id: main.c,v 8.13 1999/10/13 16:39:19 vixie Exp $"; +static const char rcsid[] = "$Id: main.c,v 8.14 2000/03/30 23:25:34 vixie Exp $"; #endif /* not lint */ /* @@ -171,7 +171,7 @@ jmp_buf env; /* - * Browser command for help and view. + * Browser command for help. */ char *pager; diff --git a/contrib/bind/bin/nslookup/nslookup.help b/contrib/bind/bin/nslookup/nslookup.help index 015bdc2..31a6634 100644 --- a/contrib/bind/bin/nslookup/nslookup.help +++ b/contrib/bind/bin/nslookup/nslookup.help @@ -1,4 +1,4 @@ -$Id: nslookup.help,v 8.4 1996/10/25 18:09:41 vixie Exp $ +$Id: nslookup.help,v 8.5 2000/03/30 23:25:35 vixie Exp $ Commands: (identifiers are shown in uppercase, [] means optional) NAME - print info about the host/domain NAME using default server @@ -30,5 +30,4 @@ ls [opt] DOMAIN [> FILE] - list addresses in DOMAIN (optional: output to FILE) -s - list well-known services -d - list all records -t TYPE - list records of the given type (e.g., A,CNAME,MX, etc.) -view FILE - sort an 'ls' output file and view it with more exit - exit the program, ^D also exits diff --git a/contrib/bind/bin/nsupdate/nsupdate.c b/contrib/bind/bin/nsupdate/nsupdate.c index a02d0ad..31496b3 100644 --- a/contrib/bind/bin/nsupdate/nsupdate.c +++ b/contrib/bind/bin/nsupdate/nsupdate.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: nsupdate.c,v 8.21 1999/10/19 22:22:59 cyarnell Exp $"; +static const char rcsid[] = "$Id: nsupdate.c,v 8.23 2000/02/04 07:51:04 vixie Exp $"; #endif /* not lint */ /* @@ -204,6 +204,8 @@ main(argc, argv) } } + INIT_LIST(listuprec); + if (keyfile) { #ifdef PARSE_KEYFILE if ((fp=fopen(keyfile, "r"))==NULL) { @@ -397,7 +399,7 @@ main(argc, argv) exit (1); } r_dname = dnbuf; - r_ttl = 0; + r_ttl = (r_opcode == ADD) ? -1 : 0; r_type = -1; r_class = C_IN; /* default to IN */ r_size = 0; @@ -500,7 +502,7 @@ main(argc, argv) r_size = endp - cp + 1; break; case ADD: - if (r_ttl == 0) { + if (r_ttl == -1) { fprintf (stderr, "ttl must be specified for record to be added: %s\n", buf); exit (1); -- cgit v1.1