summaryrefslogtreecommitdiffstats
path: root/contrib/bind/bin/named-xfer/named-xfer.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind/bin/named-xfer/named-xfer.c')
-rw-r--r--contrib/bind/bin/named-xfer/named-xfer.c3256
1 files changed, 0 insertions, 3256 deletions
diff --git a/contrib/bind/bin/named-xfer/named-xfer.c b/contrib/bind/bin/named-xfer/named-xfer.c
deleted file mode 100644
index bbc1898..0000000
--- a/contrib/bind/bin/named-xfer/named-xfer.c
+++ /dev/null
@@ -1,3256 +0,0 @@
-/* $FreeBSD$ */
-/*
- * The original version of named-xfer by Kevin Dunlap.
- * Completed and integrated with named by David Waitzman
- * (dwaitzman@bbn.com) 3/14/88.
- * Modified by M. Karels and O. Kure 10-88.
- * Modified extensively since then by just about everybody.
- */
-
-/*
- * Copyright (c) 1988, 1990
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-/*
- * Portions Copyright (c) 1995 by International Business Machines, Inc.
- *
- * International Business Machines, Inc. (hereinafter called IBM) grants
- * permission under its copyrights to use, copy, modify, and distribute this
- * Software with or without fee, provided that the above copyright notice and
- * all paragraphs of this notice appear in all copies, and that the name of IBM
- * not be used in connection with the marketing of any product incorporating
- * the Software or modifications thereof, without specific, written prior
- * permission.
- *
- * To the extent it has a right to do so, IBM grants an immunity from suit
- * under its patents, if any, for the use, sale or manufacture of products to
- * the extent that such products are used for performing Domain Name System
- * dynamic updates in TCP/IP networks by means of the Software. No immunity is
- * granted for any product per se or for any other function of any product.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
- * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
- * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
- */
-
-/*
- * Portions Copyright (c) 1996-1999 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
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-/*
- * Portions Copyright (c) 1998 by MetaInfo, Incorporated.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of MetaInfo Incorporated not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND METAINFO INCORPORATED DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL METAINFO INCORPRATED
- * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR
- * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#if !defined(lint) && !defined(SABER)
-char copyright[] =
-"@(#) Copyright (c) 1988, 1990 The Regents of the University of California.\n\
- portions Copyright (c) 1993 Digital Equipment Corporation\n\
- portions Copyright (c) 1998 MetaInfo, Inc.\n\
- portions Copyright (c) 1995, 1996 Internet Software Consorium\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-#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.122.8.2 2003/06/02 05:59:56 marka Exp $";
-#endif /* not lint */
-
-#include "port_before.h"
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <netinet/in.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-
-#include <limits.h>
-#include <ctype.h>
-#include <errno.h>
-#include <math.h>
-#include <resolv.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-#include <stdarg.h>
-
-#include <isc/eventlib.h>
-#include <isc/list.h>
-#include <isc/logging.h>
-#include <isc/memcluster.h>
-#include <isc/dst.h>
-#include <isc/misc.h>
-
-#include "port_after.h"
-
-
-#ifndef PATH_SEP
-#define PATH_SEP '/'
-#endif
-
-#define MAIN_PROGRAM
-#include "../named/named.h"
-#undef MAIN_PROGRAM
-
-#define MAX_XFER_RESTARTS 2
-
-#define ENABLE_IXFR 1
-
-# ifdef SHORT_FNAMES
-extern long pathconf __P((const char *path, int name)); /* XXX */
-# endif
-
-
-static struct zoneinfo zone; /* zone information */
-
-static char *ddtfilename = NULL,
- *ddtfile = NULL;
-
-static char *tmpname = NULL,
- *tmpiname = NULL, /* temporary file name for ixfr transaction file */
- *domain; /* domain being xfered */
-
-static int quiet = 0,
- read_interrupted = 0,
- curclass,
- domain_len; /* strlen(domain) */
-
-static FILE *fp = NULL,
- *dbfp = NULL,
- *ixfp = NULL;
-
-static char *ProgName;
-
-static void usage(const char *);
-static int 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 *, int),
- netread(int, char *, int, int),
- writemsg(int, const u_char *, int);
-static int ixfr_log(const u_char *msg, int len, int *delete,
- FILE *file, struct sockaddr_in *sin,
- 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*),
- *tsig_rcode(int);
-
-struct zoneinfo zp_start, zp_finish;
-
-static int restarts = 0;
-static int check_serial = 0;
-static int xfr_qtype = T_AXFR;
-
-FILE *ddt = NULL;
-int servermethode[NSMAX];
-char *soa_buf;
-
-typedef struct _tsig_node {
- struct in_addr addr;
- DST_KEY *dst_key;
- LINK(struct _tsig_node) link;
-} tsig_node;
-
-LIST(tsig_node) tsig_list;
-
-/*
- * Debugging printf.
- */
-static void lprintf(int level, const char *format, ...) ISC_FORMAT_PRINTF(2, 3);
-static void
-lprintf(int level, const char *format, ...) {
- va_list ap;
-
- va_start(ap, format);
- if (ddt != NULL && debug >= level)
- (void) vfprintf(ddt, format, ap);
- va_end(ap);
-}
-
-static int
-init_xfer_logging() {
- log_channel chan;
-
- if (log_new_context(ns_log_max_category, NULL, &log_ctx) < 0) {
- perror("log_new_context");
- return (0);
- }
- log_option(log_ctx, LOG_OPTION_DEBUG, debug);
- log_option(log_ctx, LOG_OPTION_LEVEL, debug);
-
- log_ctx_valid = 1;
-
- chan = log_new_syslog_channel(0, 0, ISC_FACILITY);
- if (chan == NULL)
- return (0);
- if (log_add_channel(log_ctx, ns_log_default, chan) < 0) {
- perror("log_add_channel syslog");
- return (0);
- }
-
- if (debug) {
- unsigned int flags = LOG_USE_CONTEXT_LEVEL|LOG_REQUIRE_DEBUG;
-
- chan = log_new_file_channel(flags, 0, NULL, ddt, 0, ULONG_MAX);
- if (chan == NULL)
- return (0);
- if (log_add_channel(log_ctx, ns_log_default, chan) < 0) {
- perror("log_add_channel debug");
- return (0);
- }
- }
-
- return (1);
-}
-
-static void
-cleanup_for_exit(void) {
-#ifdef DEBUG
- if (!debug)
-#endif
- {
- (void) unlink(tmpname);
- if (tmpiname != NULL)
- (void) unlink(tmpiname);
- }
- if(tmpiname)
- free(tmpiname);
- tmpiname = NULL;
- if (ddtfilename != NULL) {
- free(ddtfilename);
- if (ddtfilename == ddtfile)
- ddtfile = NULL;
- ddtfilename = NULL;
- }
- if(tmpname)
- free(tmpname);
- tmpname = NULL;
- if(ddtfile)
- free(ddtfile);
- ddtfile = NULL;
-}
-
-
-int
-main(int argc, char *argv[]) {
- struct zoneinfo *zp;
- struct hostent *hp;
- struct in_addr axfr_src;
- char *dbfile = NULL, *tracefile = NULL, *tm = NULL, *tsigfile = NULL;
- char *ixfrfile = NULL;
- int dbfd, ddtd, result, c, ixfd = -1;
- u_int32_t serial_no = 0;
- u_int port = htons(NAMESERVER_PORT);
- struct stat statbuf;
- int stub_only = 0;
- int class = C_IN;
- int n;
-
-#ifdef _AUX_SOURCE
- set42sig();
-#endif
- memset(&axfr_src, 0, sizeof axfr_src);
- ProgName = strrchr(argv[0], PATH_SEP);
- if (ProgName != NULL)
- ProgName++;
- else
- ProgName = argv[0];
-
- (void) umask(022);
-
- ddtfilename = (char *)malloc(strlen(_PATH_TMPXFER) + 1);
- strcpy(ddtfilename, _PATH_TMPXFER);
- ddtfile = ddtfilename;
-
-#ifdef RENICE
- nice(-40); /* this is the recommended procedure to */
- nice(20); /* reset the priority of the current process */
- nice(0); /* to "normal" (== 0) - see nice(3) */
-#endif
-
- n = LOG_PID;
-#ifdef LOG_PERROR
- n |= LOG_PERROR;
-#endif
-#if defined(LOG_CONS) && defined(USE_LOG_CONS)
- n |= LOG_CONS;
-#endif
-#ifdef SYSLOG_42BSD
- openlog(ProgName, n);
-#else
- openlog(ProgName, n, ISC_FACILITY);
-#endif
- while ((c = getopt(argc, argv, "C:d:l:s:t:z:f:i:p:P:qx:ST:Z")) != -1)
- switch (c) {
- case 'C':
- class = get_class(optarg);
- break;
- case 'd':
-#ifdef DEBUG
- debug = atoi(optarg);
-#endif
- break;
- case 'l':
- ddtfile = (char *)malloc(strlen(optarg) +
- sizeof(".XXXXXX") + 1);
- if (!ddtfile)
- panic("malloc(ddtfile)", NULL);
-#ifdef SHORT_FNAMES
- filenamecpy(ddtfile, optarg);
-#else
- (void) strcpy(ddtfile, optarg);
-#endif /* SHORT_FNAMES */
- (void) strcat(ddtfile, ".XXXXXX");
- break;
- case 's':
- serial_no = strtoul(optarg, (char **)NULL, 10);
- check_serial++;
- break;
- case 't':
- tracefile = optarg;
- break;
- case 'z': /* zone == domain */
- domain = optarg;
- domain_len = strlen(domain);
- while ((domain_len > 0) &&
- (domain[domain_len-1] == '.'))
- domain[--domain_len] = '\0';
- break;
- case 'f':
- dbfile = optarg;
- tmpname = (char *)malloc((unsigned)strlen(optarg) +
- sizeof(".XXXXXX") + 1);
- if (!tmpname)
- panic("malloc(tmpname)", NULL);
-#ifdef SHORT_FNAMES
- filenamecpy(tmpname, optarg);
-#else
- (void) strcpy(tmpname, optarg);
-#endif /* SHORT_FNAMES */
- break;
- case 'i':
-#if ENABLE_IXFR
- ixfrfile = optarg;
- tmpiname = (char *) malloc(strlen(optarg) +
- sizeof(".XXXXXX") + 1);
- if (!tmpiname)
- panic("malloc(tmpiname)", NULL);
-#ifdef SHORT_FNAMES
- filenamecpy(tmpiname, optarg);
-#else
- (void) strcpy(tmpiname, optarg);
-#endif /* SHORT_FNAMES */
-#endif /* ENABLE_IXFR */
- break;
- case 'p':
- port = htons((u_int16_t)atoi(optarg));
- break;
- case 'P':
- port = (u_int16_t)atoi(optarg);
- break;
- case 'S':
- stub_only = 1;
- break;
- case 'q':
- quiet++;
- break;
- case 'x':
- if (!inet_aton(optarg, &axfr_src))
- panic("bad -x addr: %s", optarg);
- break;
- case 'T':
- tsigfile = optarg;
- break;
- case 'Z':
- xfr_qtype = ns_t_zxfr;
- break;
- case '?':
- default:
- usage("unrecognized argument");
- /* NOTREACHED */
- }
- if (!domain || ((!dbfile) && (!ixfrfile)) || optind >= argc) {
- if (!domain)
- usage("no domain");
- if (!dbfile)
- usage("no dbfile");
- if (optind >= argc)
- usage("not enough arguments");
- /* NOTREACHED */
- }
- if (stat(dbfile, &statbuf) != -1 &&
- !S_ISREG(statbuf.st_mode) &&
- !S_ISFIFO(statbuf.st_mode))
- usage("dbfile must be a regular file or FIFO");
- if (ixfrfile && (stat(ixfrfile, &statbuf) != -1 &&
- !S_ISREG(statbuf.st_mode) &&
- !S_ISFIFO(statbuf.st_mode)))
- usage("ixfrfile must be a regular file or FIFO");
- if (tsigfile && stat(tsigfile, &statbuf) != -1 &&
- !S_ISREG(statbuf.st_mode) &&
- !S_ISFIFO(statbuf.st_mode))
- usage("tsigfile must be a regular file or FIFO");
- if (tracefile && (fp = fopen(tracefile, "w")) == NULL)
- perror(tracefile);
- (void) strcat(tmpname, ".XXXXXX");
- /* tmpname is now something like "/etc/named/named.bu.db.XXXXXX" */
- if ((dbfd = mkstemp(tmpname)) == -1) {
- perror(tmpname);
- if (!quiet)
- syslog(LOG_ERR, "can't make tmpfile (%s): %s\n",
- tmpname, strerror(errno));
- exit(XFER_FAIL);
- }
-#ifdef HAVE_FCHMOD /* XXX */
- if (fchmod(dbfd, 0644) == -1)
-#else
- if (chmod(tmpname, 0644) == -1)
-#endif
- {
- perror(tmpname);
- if (!quiet)
- syslog(LOG_ERR, "can't [f]chmod tmpfile (%s): %s\n",
- tmpname, strerror(errno));
- close(dbfd);
- unlink(tmpname);
- exit(XFER_FAIL);
- }
- if ((dbfp = fdopen(dbfd, "r+")) == NULL) {
- perror(tmpname);
- if (!quiet)
- syslog(LOG_ERR, "can't fdopen tmpfile (%s)", tmpname);
- close(dbfd);
- unlink(tmpname);
- exit(XFER_FAIL);
- }
- if (ixfrfile) {
- (void) strcat(tmpiname, ".XXXXXX");
- if ((ixfd = mkstemp(tmpiname)) == -1) {
- perror(tmpiname);
- if (!quiet)
- syslog(LOG_ERR,
- "can't make tmpifile (%s): %s\n",
- tmpiname, strerror(errno));
- (void) fclose(dbfp);
- (void) close(dbfd);
- exit(XFER_FAIL);
- }
-#ifdef HAVE_FCHMOD /* XXX */
- if (fchmod(ixfd, 0644) == -1)
-#else
- if (chmod(tmpiname, 0644) == -1)
-#endif
- {
- perror(tmpiname);
- if (!quiet)
- syslog(LOG_ERR,
- "can't [f]chmod tmpifile (%s): %s\n",
- tmpiname, strerror(errno));
- (void) fclose(dbfp);
- (void) close(dbfd);
- (void) close(ixfd);
- exit(XFER_FAIL);
- }
- close(ixfd);
- }
-#ifdef DEBUG
- if (debug) {
- /* ddtfile is now something like "/usr/tmp/xfer.ddt.XXXXXX" */
- if ((ddtd = mkstemp(ddtfile)) == -1) {
- perror(ddtfile);
- debug = 0;
- }
-#ifdef HAVE_FCHMOD
- else if (fchmod(ddtd, 0644) == -1)
-#else
- else if (chmod(ddtfile, 0644) == -1)
-#endif
- {
- perror(ddtfile);
- close(ddtd);
- unlink(ddtfile);
- debug = 0;
- } else if ((ddt = fdopen(ddtd, "w")) == NULL) {
- perror(ddtfile);
- close(ddtd);
- unlink(ddtfile);
- debug = 0;
- } else
- setvbuf(ddt, NULL, _IOLBF, 0);
- }
-#endif
- if (!init_xfer_logging()) {
- cleanup_for_exit();
- perror("init_xfer_logging");
- }
-
- /*
- * Ignore many types of signals that named (assumed to be our parent)
- * considers important- if not, the user controlling named with
- * signals usually kills us.
- */
- (void) signal(SIGHUP, SIG_IGN);
-#ifdef SIGSYS
- (void) signal(SIGSYS, SIG_IGN);
-#endif
-#ifdef DEBUG
- if (debug == 0)
-#endif
- {
- (void) signal(SIGINT, SIG_IGN);
- (void) signal(SIGQUIT, SIG_IGN);
- }
- (void) signal(SIGILL, SIG_IGN);
-
-#if defined(SIGUSR1) && defined(SIGUSR2)
- (void) signal(SIGUSR1, SIG_IGN);
- (void) signal(SIGUSR2, SIG_IGN);
-#else /* SIGUSR1&&SIGUSR2 */
- (void) signal(SIGEMT, SIG_IGN);
- (void) signal(SIGFPE, SIG_IGN);
-#endif /* SIGUSR1&&SIGUSR2 */
-
- if (dbfile)
- lprintf(1, "domain `%s'; file `%s'; serial %u\n",
- domain, dbfile, serial_no);
-
- if (ixfrfile)
- lprintf(1, "domain `%s'; ixfrfile `%s'; serial %u\n",
- domain, ixfrfile, serial_no);
-
- if (tsigfile)
- lprintf(1, "tsigfile `%s'\n", tsigfile);
-
- buildservicelist();
- buildprotolist();
-
- if (tsig_init(tsigfile) == -1) {
- cleanup_for_exit();
- return (XFER_FAIL);
- }
-
- /* init zone data */
-
- zp = &zone;
- if (stub_only)
- zp->z_type = Z_STUB;
- else
- zp->z_type = Z_SECONDARY;
- zp->z_class = class;
- zp->z_origin = domain;
- zp->z_source = dbfile;
- zp->z_axfr_src = axfr_src;
- zp->z_addrcnt = 0;
- lprintf(1, "zone found (%d): \"%s\", source = %s\n",
- zp->z_type,
- (zp->z_origin[0] == '\0') ? "." : zp->z_origin,
- zp->z_source);
-
- for (; optind != argc; optind++) {
- int tmpsupportixfr;
-
- tm = argv[optind];
- tmpsupportixfr = ISNOTIXFR;
- if ((optind+1) != argc) {
- if (strcasecmp("ixfr", argv[optind+1]) == 0) {
-#if ENABLE_IXFR
- tmpsupportixfr = ISIXFR;
- servermethode[zp->z_addrcnt] = tmpsupportixfr;
-#endif
- optind++;
- } else if (strcasecmp("axfr", argv[optind+1]) == 0) {
- tmpsupportixfr = ISNOTIXFR;
- optind++;
- }
- }
- if (!inet_aton(tm, &zp->z_addr[zp->z_addrcnt])) {
- if (strcmp("-ixfr",tm)==0) {
-#if ENABLE_IXFR
- tmpsupportixfr = ISIXFR;
- servermethode[zp->z_addrcnt-1] = tmpsupportixfr;
-#endif
- continue;
- } else
- if (strcmp("-axfr",tm)==0) {
- tmpsupportixfr = ISNOTIXFR;
- continue;
- }
- hp = gethostbyname(tm);
- if (hp == NULL) {
- syslog(LOG_NOTICE,
- "uninterpretable server (%s) for %s\n",
- tm, zp->z_origin);
- continue;
- }
- memcpy(&zp->z_addr[zp->z_addrcnt],
- hp->h_addr,
- INADDRSZ);
- lprintf(1, "Arg: \"%s\" %s\n", tm,((tmpsupportixfr) ? "IXFR":"AXFR"));
- }
- if (++zp->z_addrcnt >= NSMAX) {
- zp->z_addrcnt = NSMAX;
- lprintf(1, "NSMAX reached\n");
- break;
- }
- }
- lprintf(1, "addrcnt = %d\n", zp->z_addrcnt);
-
- res_ninit(&res);
- res.options &= ~(RES_DEFNAMES | RES_DNSRCH | RES_RECURSE);
- result = getzone(zp, serial_no, port);
- (void) fclose(dbfp);
- (void) close(dbfd);
-
- if (ixfp)
- (void) my_fclose(ixfp);
- else
- close(ixfd);
-
- switch (result) {
-
- case XFER_SUCCESSAXFR: /* ok exit */
- if (tmpiname != NULL)
- unlink(tmpiname);
- if (ixfrfile) {
- /*
- * An IXFR was requested but we performed an
- * AXFR. Rename the temporary file to the IXFR
- * name, named will rename it again to the dbname.
- */
- if (isc_movefile(tmpname, ixfrfile) == -1) {
- perror("isc_movefile");
-#ifdef DEBUG
- if (debug)
- (void) unlink(ddtfile);
-#endif
- if (!quiet)
- syslog(LOG_ERR,
- "rename %s to %s: %s",
- tmpname, ixfrfile, strerror(errno));
- cleanup_for_exit();
- exit(XFER_FAIL);
- };
- exit(XFER_SUCCESSAXFRIXFRFILE);
- }
- if (isc_movefile(tmpname, dbfile) == -1) {
- perror("isc_movefile");
- if (!quiet)
- syslog(LOG_ERR, "isc_movefile %s to %s: %m",
- tmpname, dbfile);
- cleanup_for_exit();
- exit(XFER_FAIL);
- }
- exit(XFER_SUCCESSAXFR);
-
- case XFER_SUCCESSIXFR:
- unlink(tmpname);
- if (isc_movefile(tmpiname, ixfrfile) == -1) {
- perror("isc_movefile");
- if (!quiet)
- syslog(LOG_ERR, "isc_movefile %s to %s: %m",
- tmpiname, ixfrfile);
- cleanup_for_exit();
- exit(XFER_FAIL);
- }
- cleanup_for_exit();
- exit(XFER_SUCCESSIXFR);
-
- case XFER_UPTODATE: /* the zone was already uptodate */
- (void) unlink(tmpname);
- if (tmpiname != NULL)
- (void) unlink(tmpiname);
- cleanup_for_exit();
- exit(XFER_UPTODATE);
-
- default:
- result = XFER_FAIL;
- /* fall through */
- case XFER_REFUSED:
- case XFER_TIMEOUT:
- case XFER_FAIL:
- (void) unlink(tmpname);
- cleanup_for_exit();
- exit(result); /* error or timeout */
- }
- /*NOTREACHED*/
- return (0); /* Make gcc happy. */
-}
-
-static const char *UsageText[] = {
- "\t-z zone_to_transfer\n",
- "\t-f db_file\n",
- "\t[-i ixfr_file]\n",
- "\t[-s serial_no]\n",
- "\t[-d debug_level]\n",
- "\t[-l debug_log_file]\n",
- "\t[-t trace_file]\n",
- "\t[-p port]\n",
- "\t[-S] [-Z]\n",
- "\t[-C class]\n",
- "\t[-x axfr-src]\n",
- "\t[-T tsig_info_file]\n",
- "\tservers [-ixfr|-axfr]...\n",
- NULL
-};
-
-static void
-usage(const char *msg) {
- const char **line;
-
- fprintf(stderr, "Usage error: %s\n", msg);
- fprintf(stderr, "Usage: %s\n", ProgName);
- for (line = UsageText; *line; line++)
- fputs(*line, stderr);
- exit(XFER_FAIL);
-}
-
-static int
-tsig_init(const char *file) {
- char buf[1024];
- FILE *fp;
- char *s;
-
- if (file == NULL)
- return (0);
- fp = fopen(file, "r");
- if (fp == NULL)
- return (-1);
- dst_init();
- INIT_LIST(tsig_list);
- while (1) {
- tsig_node *n = malloc(sizeof(tsig_node));
- int alg, secret_len;
- char *cp;
- u_char secret[128];
- char *name;
-
- if (n == NULL)
- return (-1);
-
- s = fgets(buf, sizeof(buf), fp);
- if (s == NULL)
- break;
- buf[strlen(buf)-1] = 0;
- inet_aton(buf, &n->addr);
-
- fgets(buf, sizeof(buf), fp);
- buf[strlen(buf)-1] = 0;
- name = strdup(buf);
-
- if (name == NULL)
- return (-1);
-
- fscanf(fp, "%d", &alg);
- fgets(buf, sizeof(buf), fp);
-
- fgets(buf, sizeof(buf), fp);
- buf[strlen(buf)-1] = 0;
- cp = buf;
- while (isspace(*cp))
- cp++;
-
- secret_len = b64_pton(cp, secret, sizeof(secret));
- n->dst_key = dst_buffer_to_key(name, alg, 0, 0,
- secret, secret_len);
-
- free(name);
- INIT_LINK(n, link);
- APPEND(tsig_list, n, link);
- }
- fclose(fp);
- unlink(file);
- return (0);
-}
-
-#define DEF_DNAME '\001' /* '\0' means the root domain */
-/* XXX: The following variables should probably all be "static" */
-u_int32_t minimum_ttl = 0;
-int soa_cnt = 0, scdsoa = 0, methode = ISNOTIXFR;
-int delete_soa = 1;
-int ixfr_single_answer_mode = 0;
-u_int32_t final_serial = 0;
-int ixfr_soa = 0;
-int ns_cnt = 0;
-int query_type = 0;
-int prev_comment = 0; /* was previous record a comment? */
-char zone_top[MAXDNAME]; /* the top of the zone */
-char prev_origin[MAXDNAME]; /* from most recent $ORIGIN line */
-char prev_dname[MAXDNAME] = { DEF_DNAME }; /* from previous record */
-char prev_ns_dname[MAXDNAME] = { DEF_DNAME }; /* from most recent NS record */
-
-/*
- * TSIG state
- */
-static int tsig_signed;
-static ns_tcp_tsig_state tsig_state;
-
-static int
-make_query(int fd, struct zoneinfo *zp, int type, u_int32_t serial_no,
- DST_KEY *tsig_key, u_char *buf, u_int bufsize)
-{
- HEADER *hp;
- u_char *cp;
- int n, ret;
- time_t timesigned = 0;
-
- n = res_nmkquery(&res, QUERY, zp->z_origin, curclass,
- type, NULL, 0, NULL, buf, bufsize);
- if (n < 0) {
- if (!quiet)
- syslog(LOG_INFO, "zone %s: res_nmkquery %s failed",
- p_type(query_type), zp->z_origin);
- return (n);
- }
-
- if (type == T_IXFR) {
- hp = (HEADER *) buf;
- cp = buf;
- lprintf(1, "len = %d\n", n);
- hp->nscount = htons(1+ntohs(hp->nscount));
- cp += n;
- n = dn_comp(zp->z_origin, cp, bufsize - (cp - buf), NULL, NULL);
- if (n < 0)
- return (n);
- cp += n;
- if (cp + 3 * INT16SZ + 6 * INT32SZ + 2 > buf + bufsize)
- return (-1);
- PUTSHORT(T_SOA, cp); /* type */
- PUTSHORT(C_IN, cp); /* class */
- PUTLONG(0, cp); /* ttl */
- PUTSHORT(22, cp); /* dlen */
- *cp++ = 0; /* mname */
- *cp++ = 0; /* rname */
- PUTLONG(serial_no, cp);
- PUTLONG(0xDEAD, cp); /* Refresh */
- PUTLONG(0xBEEF, cp); /* Retry */
- PUTLONG(0xABCD, cp); /* Expire */
- PUTLONG(0x1776, cp); /* Min TTL */
- n = cp - buf;
- lprintf(1, "len = %d\n", cp-buf);
- }
-
- tsig_signed = 0;
- if (tsig_key != NULL) {
- int siglen;
- u_char sig[64];
-
- siglen = sizeof(sig);
- ret = ns_sign(buf, &n, bufsize, NOERROR, tsig_key,
- NULL, 0, sig, &siglen, timesigned);
- if (ret == 0) {
- tsig_signed = 1;
- ns_verify_tcp_init(tsig_key, sig, siglen, &tsig_state);
- }
- }
-
- if (debug)
- res_pquery(&res, buf, n, ddt);
-
- if (writemsg(fd, buf, n) < 0) {
- syslog(LOG_INFO, "writemsg: %m");
- return (-1);
- }
-
- return (n);
-}
-
-static u_int
-readandverify(int fd, u_char **bufp, u_int *bufsizep,
- struct sockaddr_in *sin, char *z_origin, int sig_req)
-{
- u_char *buf = *bufp;
- u_char *newbuf;
- u_int bufsize = *bufsizep;
- u_int len;
-
- if (netread(fd, (char *)buf, INT16SZ, XFER_TIMER) < 0)
- return (0);
-
- if ((len = ns_get16(buf)) == 0)
- return (0);
-
- if (len > bufsize) {
- newbuf = realloc(buf, len);
- if (newbuf == NULL) {
- syslog(LOG_INFO, "realloc(%u) failed\n", len);
- return (0);
- }
- *bufp = buf = newbuf;
- *bufsizep = bufsize = len;
- }
-
- if (netread(fd, (char *)buf, len, XFER_TIMER) < 0)
- return (0);
-
-#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
-
- if (tsig_signed) {
- int ret;
-
- ret = ns_verify_tcp(buf, (int *)&len, &tsig_state, sig_req);
- if (ret != 0) {
- syslog(LOG_NOTICE, "%s [%s] %s %s: %s (%d)\n",
- "TSIG verification from server",
- inet_ntoa(sin->sin_addr), "zone", z_origin,
- tsig_rcode(ret), ret);
- return (0);
- }
- }
-
- return (len);
-}
-
-static void
-print_comment(int s, struct sockaddr_in *sin, int check_serial,
- u_int32_t serial_no, DST_KEY *tsig_key)
-{
- struct sockaddr_in local;
- ISC_SOCKLEN_T locallen;
- const char *l, *nl;
-
- gettime(&tt);
- locallen = sizeof local;
- if (getsockname(s, (struct sockaddr *)&local, &locallen) < 0)
- memset(&local, 0, sizeof local);
-
- for (l = Version; l; l = nl) {
- size_t len;
- if ((nl = strchr(l, '\n')) != NULL) {
- len = nl - l;
- nl = nl + 1;
- } else {
- len = strlen(l);
- nl = NULL;
- }
- while (isspace((unsigned char) *l))
- l++;
- if (*l)
- fprintf(dbfp, "; BIND version %.*s\n", (int)len, l);
- }
-
- fprintf(dbfp, check_serial ?
- "; zone '%s' last serial %u\n" :
- "; zone '%s' first transfer\n",
- domain, serial_no);
- fprintf(dbfp, "; from %s:%d",
- inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
- fprintf(dbfp, " (local %s) using %s at %s",
- inet_ntoa(local.sin_addr), (methode == ISIXFR) ? "IXFR":"AXFR",
- ctimel(tt.tv_sec));
- if (tsig_signed != 0)
- fprintf(dbfp, "; TSIG verified: key %s.\n",
- tsig_key->dk_key_name);
- else
- fprintf(dbfp, "; NOT TSIG verified\n");
-}
-
-static int
-getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) {
- HEADER *hp;
- u_int len;
- int s, n, l, error = 0;
- int was_ixfr = 0;
- u_int cnt;
- u_char *cp, *nmp, *eom, *tmp ;
- u_char *buf = NULL;
- u_char *bp;
- u_int bufsize = 0;
- u_char *buf2 = NULL;
- u_int buf2size = 0;
- char name2[MAXDNAME];
- struct sockaddr_in sin;
-#ifdef POSIX_SIGNALS
- struct sigaction sv, osv;
-#else
- struct sigvec sv, osv;
-#endif
- int qdcount, ancount, aucount, arcount, class = 0, type = 0;
- const char *badsoa_msg = "Nil";
- struct sockaddr_in my_addr;
- char my_addr_text[30];
- ISC_SOCKLEN_T alen;
- int tsig_req;
- DST_KEY *tsig_key;
- int ixfr_first = 1;
- int loop_cnt = 0;
- u_int32_t query_serial = serial_no;
- int first_soa_printed;
- struct in_addr z_axfr_src;
- int refused = 0;
-
-#ifdef DEBUG
- if (debug) {
- (void)fprintf(ddt,"getzone() %s ", zp->z_origin);
- switch (zp->z_type) {
- case Z_STUB:
- fprintf(ddt, "stub\n");
- break;
- case Z_SECONDARY:
- fprintf(ddt, "slave\n");
- break;
- default:
- fprintf(ddt, "unknown type\n");
- }
- }
-#endif
-#ifdef POSIX_SIGNALS
- memset(&sv, 0, sizeof sv);
- sv.sa_handler = (SIG_FN (*)()) read_alarm;
- /* SA_ONSTACK isn't recommended for strict POSIX code */
- /* is it absolutely necessary? */
- /* sv.sa_flags = SA_ONSTACK; */
- sigfillset(&sv.sa_mask);
- (void) sigaction(SIGALRM, &sv, &osv);
- memset(&sv, 0, sizeof sv);
- sv.sa_handler = (SIG_FN (*)()) term_handler;
- sigfillset(&sv.sa_mask);
- (void) sigaction(SIGTERM, &sv, &osv);
-#else
- memset(&sv, 0, sizeof sv);
- sv.sv_handler = read_alarm;
- sv.sv_mask = ~0;
- (void) sigvec(SIGALRM, &sv, &osv);
- memset(&sv, 0, sizeof sv);
- sv.sv_handler = term_handler;
- sv.sv_mask = ~0;
- (void) sigvec(SIGTERM, &sv, &osv);
-#endif
-
- strcpy(zone_top, zp->z_origin);
- if ((l = strlen(zone_top)) != 0 && zone_top[l - 1] == '.')
- zone_top[l - 1] = '\0';
- strcpy(prev_origin, zone_top);
-
- for (cnt = 0; cnt < zp->z_addrcnt; cnt++) {
- methode = servermethode[cnt];
- sin.sin_addr = zp->z_addr[cnt];
- lprintf(3, "address [%s] %s\n",
- inet_ntoa(sin.sin_addr),
- (methode == ISIXFR) ? "IXFR":"AXFR");
- }
-
- for (cnt = 0; cnt < zp->z_addrcnt; cnt++) {
- methode = ISNOTIXFR;
- curclass = zp->z_class;
- /*
- * If we have been given a serial number and a ixfr log
- * file name then set methode.
- */
- if (check_serial && tmpiname != NULL)
- methode = servermethode[cnt];
- error = 0;
- tsig_signed = 0;
- z_axfr_src = zp->z_axfr_src;
- if (buf == NULL) {
- if ((buf = (u_char *)malloc(2 * PACKETSZ)) == NULL) {
- syslog(LOG_INFO, "malloc(%u) failed",
- 2 * PACKETSZ);
- error++;
- break;
- }
- bufsize = 2 * PACKETSZ;
- }
- tsig_key = tsig_key_from_addr(sin.sin_addr);
-
- try_again:
- first_soa_printed = 0;
- if ((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
- syslog(LOG_INFO, "socket: %m");
- error++;
- break;
- }
- if (z_axfr_src.s_addr != 0) {
- memset(&sin, 0, sizeof sin);
- sin.sin_family = AF_INET;
- sin.sin_port = 0; /* "ANY" */
- sin.sin_addr = z_axfr_src;
- lprintf(2, "binding to address [%s]\n",
- inet_ntoa(sin.sin_addr));
- if (bind(s, (struct sockaddr *)&sin, sizeof sin) < 0)
- syslog(LOG_INFO, "warning: bind(%s) failed",
- inet_ntoa(zp->z_axfr_src));
- }
- memset(&sin, 0, sizeof sin);
- sin.sin_family = AF_INET;
- sin.sin_port = port;
- sin.sin_addr = zp->z_addr[cnt];
- lprintf(2, "connecting to server #%d [%s].%d\n",
- cnt + 1, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
- if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
- if (z_axfr_src.s_addr != 0) {
- lprintf(2, "connect failed, trying w/o -x");
- z_axfr_src.s_addr = 0;
- (void) my_close(s);
- goto try_again;
- }
- if (!quiet)
- syslog(LOG_INFO,
- "connect(%s) for zone %s failed: %s",
- inet_ntoa(sin.sin_addr), zp->z_origin,
- strerror(errno));
- error++;
- (void) my_close(s);
- continue;
- }
-
- query_type = (methode == ISIXFR && was_ixfr == 0) ?
- T_IXFR : T_SOA;
-
- n = make_query(s, zp, query_type, serial_no, tsig_key,
- buf, bufsize);
-
- if (n < 0) {
- (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);
- }
-
- /*
- * Get out your butterfly net and catch the answer.
- */
- len = readandverify(s, &buf, &bufsize, &sin, zp->z_origin, 1);
- if (len == 0) {
- my_close(s);
- error++;
- continue;
- }
-
- if (query_type == T_IXFR && ixfp == NULL) {
- delete_soa = 1;
- ixfr_soa = 0;
- if ((ixfp = fopen(tmpiname, "w+")) == NULL) {
- perror(tmpiname);
- if (!quiet)
- syslog(LOG_ERR,
- "can't fopen ixfr log (%s)",
- tmpname);
- exit(XFER_FAIL);
- }
- }
-
- hp = (HEADER *) buf;
- qdcount = ntohs(hp->qdcount);
- ancount = ntohs(hp->ancount);
- aucount = ntohs(hp->nscount);
- arcount = ntohs(hp->arcount);
- /*
- * close socket if any of these apply:
- * 1) rcode != NOERROR
- * 2) not an authority response
- * 3) not an answer to our question
- * 4) both the number of answers and authority count < 1)
- */
- if (hp->rcode != NOERROR ||
- (query_type == T_SOA && (!hp->aa || qdcount != 1)) ||
- (ancount < 1 && aucount < 1)) {
-#ifndef SYSLOG_42BSD
- syslog(LOG_NOTICE,
- "[%s] %s for %s, %s query got rcode %d, aa %d, ancount %d, aucount %d",
- inet_ntoa(sin.sin_addr),
- (hp->aa
- ? (qdcount==1 ?"no SOA found" :"bad response")
- : "not authoritative"),
- zp->z_origin[0] != '\0' ? zp->z_origin : ".",
- p_type(query_type),
- hp->rcode, hp->aa, ancount, aucount);
-#endif
- error++;
- (void) my_close(s);
- continue;
- }
- zp_start = *zp;
- if ((int)len < HFIXEDSZ + QFIXEDSZ) {
- badsoa_msg = "too short";
- badsoa:
- syslog(LOG_INFO,
- "malformed %s from [%s], zone %s: %s",
- p_type(query_type), inet_ntoa(sin.sin_addr),
- zp->z_origin, badsoa_msg);
- error++;
- (void) my_close(s);
- continue;
- }
- /*
- * Step through response.
- */
- 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";
- goto badsoa;
- }
- tmp += n;
- if (tmp + 2 * INT16SZ > eom) {
- badsoa_msg = "query error";
- goto badsoa;
- }
- NS_GET16(type, tmp);
- NS_GET16(class, tmp);
- 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,
- name2, p_class(class), p_type(type));
- error++;
- (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;
- bp = NULL;
- do {
- u_char *cp4, *ocp = tmp;
- u_short type, class, dlen, olen = len;
- u_int32_t ttl;
-
- n = dn_expand(buf, eom, tmp, name2, sizeof name2);
- if (n < 0) {
- badsoa_msg = "aname error";
- goto badsoa;
- }
- tmp += n;
-
- if (loop_cnt == 0)
- bp = tmp;
-
- /* Are type, class, and ttl OK? */
- cp4 = tmp; /* Leave tmp pointing to type field */
- if (eom - cp4 < 3 * INT16SZ + INT32SZ) {
- badsoa_msg = "zinfo too short";
- goto badsoa;
- }
- NS_GET16(type, cp4);
- NS_GET16(class, cp4);
- NS_GET32(ttl, cp4);
- NS_GET16(dlen, cp4);
- if (cp4 + dlen > eom) {
- badsoa_msg = "zinfo dlen too big";
- goto badsoa;
- }
- if (type == T_SOA) {
- if (was_ixfr) {
- methode = ISNOTIXFR;
- break;
- }
- if ((methode == ISIXFR) && (loop_cnt == 0)) {
- soa_cnt++;
- badsoa_msg = soa_zinfo(&zp_finish, tmp,
- eom);
- if (badsoa_msg)
- goto badsoa;
- if (ixfp && ixfr_log(buf, len,
- &delete_soa,
- ixfp, &sin,
- &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)) {
- lprintf(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. */
- lprintf(1, "skipping %s %s RR in response\n",
- name2, p_type(type));
- tmp = cp4 + dlen;
- loop_cnt++;
- if (loop_cnt == 1) {
-
- badsoa_msg = soa_zinfo(&zp_start, bp, eom);
- if (badsoa_msg)
- goto badsoa;
- if (check_serial &&
- !SEQ_GT(zp_start.z_serial, query_serial)) {
- (void) my_close(s);
- lprintf(1,
- "zone up-to-date, serial %u\n",
- zp_start.z_serial);
- if (ixfp) {
- (void) fclose(ixfp);
- (void) unlink (tmpiname);
- ixfp = NULL;
- }
- return (XFER_UPTODATE);
- }
- }
- if (ancount == 1 && loop_cnt == 1) {
- if (buf2 == NULL) {
- if ((buf2 = (u_char *)malloc(2 * PACKETSZ)) == NULL) {
- syslog(LOG_INFO,
- "malloc(%u) failed",
- 2 * PACKETSZ);
- error++;
- break;
- }
- buf2size = 2 * PACKETSZ;
- }
- len = readandverify(s, &buf2, &buf2size, &sin,
- zp->z_origin, 0);
- if (len == 0) {
- error++;
- tmp = bp;
- check_serial = 0;
- break;
- }
-
- hp = (HEADER *) buf2;
- qdcount = ntohs(hp->qdcount);
- ancount = ntohs(hp->ancount);
- aucount = ntohs(hp->nscount);
- arcount = ntohs(hp->arcount);
-
- tmp = buf2 + HFIXEDSZ;
- eom = buf2 + len;
- /* Query Section. */
- if (qdcount > 1) {
- badsoa_msg = "question error";
- goto badsoa;
- } else if (qdcount == 1) {
- n = dn_skipname(tmp, eom);
- if (n < 0) {
- badsoa_msg = "qname error";
- goto badsoa;
- }
- tmp += n;
- if (tmp + 2 * INT16SZ > eom) {
- badsoa_msg = "query error";
- goto badsoa;
- }
- tmp += 2 * INT16SZ;
- }
- /* answer section */
- if (ancount < 1) {
- badsoa_msg = "empty answer";
- goto badsoa;
- }
- n = dn_expand(buf2, eom, tmp, name2,
- sizeof name2);
- if (n < 0) {
- badsoa_msg = "qname error";
- goto badsoa;
- }
- tmp += n;
- bp = tmp;
- if (tmp + 2 * INT16SZ > eom) {
- badsoa_msg = "query error";
- goto badsoa;
- }
- NS_GET16(type, tmp);
- NS_GET16(class, tmp);
- if (class != curclass ||
- 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,
- name2, p_class(class), p_type(type));
- error++;
- tmp = bp;
- check_serial = 0;
- break;
- }
- if (type == T_SOA) {
- ixfr_single_answer_mode = 1;
- if (ixfp &&
- ixfr_log(buf2, len, &delete_soa, ixfp,
- &sin, &serial_no,
- &ixfr_first) < 0) {
- error++;
- break;
- }
- free(buf);
- buf = buf2;
- bufsize = buf2size;
- buf2 = NULL;
- break;
- } else {
- methode = ISNOTIXFR;
- was_ixfr++;
- check_serial = 0;
- cp = buf + HFIXEDSZ;
- n = print_output(zp, serial_no, buf, olen, ocp, 3);
- first_soa_printed = 1;
- free(buf);
- buf = buf2;
- buf2 = NULL;
- bufsize = buf2size;
- break;
- }
- }
- if (loop_cnt > 1) {
- tmp = bp;
- check_serial = 0;
- break;
- }
- } while (1);
-
- if (error != 0) {
- (void) my_close(s);
- continue;
- }
-
- if (ns_samename(zp->z_origin, name2) != 1) {
- syslog(LOG_INFO,
- "wrong answer in resp from [%s], zone %s: [%s %s %s]\n",
- inet_ntoa(sin.sin_addr), zp->z_origin,
- name2, p_class(class), p_type(type));
- error++;
- (void) my_close(s);
- continue;
- }
- if (loop_cnt < 1) {
- 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) {
- if (soa_cnt) {
- if (!first_soa_printed)
- soa_cnt = 0;
- goto axfr_response;
- }
- lprintf(1, "need update, serial %u\n",
- zp_start.z_serial);
- soa_cnt = 0;
- hp = (HEADER *) buf;
- ns_cnt = 0;
- print_comment(s, &sin, check_serial,
- serial_no, tsig_key);
-
- for (;;) {
- if ((soa_cnt == 0) || (zp->z_type == Z_STUB)) {
- if (zp->z_type == Z_STUB) {
- if (soa_cnt == 1 &&
- ns_cnt == 0)
- query_type = T_NS;
- else
- query_type = T_SOA;
- } else if (methode == ISIXFR)
- query_type = T_IXFR;
- else
- query_type = xfr_qtype;
- n = make_query(s, zp, query_type,
- serial_no, tsig_key,
- buf, bufsize);
- syslog(LOG_INFO,
- "send %s query %d to %s for %s",
- p_type(query_type),
- cnt, inet_ntoa(sin.sin_addr),
- (*zp->z_origin != '\0') ?
- zp->z_origin : ".");
- lprintf(1,
- "send %s query to %s\n",
- p_type(query_type),
- inet_ntoa(sin.sin_addr));
- lprintf(1,"bufsize = %d\n", bufsize);
- if (n < 0) {
- if (!quiet) {
- if (zp->z_type == Z_STUB)
- syslog(LOG_INFO,
- "zone %s: res_nmkquery %s failed",
- p_type(query_type),
- zp->z_origin);
- else
- syslog(LOG_INFO,
- "zone %s: res_nmkquery %s failed",
- zp->z_origin,
- p_type(query_type));
- }
- (void) my_close(s);
-#ifdef POSIX_SIGNALS
- sigaction(SIGALRM, &osv,
- (struct sigaction *)0);
-#else
- sigvec(SIGALRM, &osv,
- (struct sigvec *)0);
-#endif
- return (XFER_FAIL);
- }
- }
-/*XXX ZXFR*/
-receive:
- /*
- * Receive length & response
- */
- tsig_req = (soa_cnt == 0);
- len = readandverify(s, &buf, &bufsize, &sin,
- zp->z_origin, tsig_req);
- if (len == 0) {
- error++;
- break;
- }
- hp = (HEADER *)buf;
- eom = buf + len;
- if (len < HFIXEDSZ) {
- badrec:
- 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 ((len >= HFIXEDSZ) &&
- (hp->rcode == REFUSED)) {
- syslog(LOG_INFO,
- "[%s] transfer refused from [%s], zone %s\n",
- my_addr_text,
- inet_ntoa(sin.sin_addr),
- zp->z_origin);
- refused = 1;
- } 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;
- }
-axfr_response:
- if (query_type == T_IXFR)
- if (hp->rcode != NOERROR) {
- lprintf(1,
- "server %s did not support IXFR\n",
- inet_ntoa(sin.sin_addr));
- methode = ISNOTIXFR;
- continue;
- };
- cp = buf + HFIXEDSZ;
- if (ntohs(hp->qdcount) == 1) {
- if ((query_type == T_IXFR) &&
- (methode == ISIXFR)) {
- lprintf(1,
- "server %s rejected IXFR and responded with AXFR\n",
- inet_ntoa(sin.sin_addr));
- methode = ISNOTIXFR;
- }
- n = dn_skipname(cp, eom);
- if ((n == -1) ||
- ((n + QFIXEDSZ) >= (eom - cp)))
- goto badrec;
- cp += n + QFIXEDSZ;
- }
- 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,
- 0);
- 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;
- }
- 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,
- 0);
- 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,
- 0);
- 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 &&
- ixfr_log(buf, len, &delete_soa,
- ixfp, &sin, &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,
- 0);
- if (n < 0)
- break;
- cp += n;
- }
- if (n < 0) {
- syslog(LOG_INFO,
- "print_output: unparseable answer (%d), zone %s",
- hp->rcode,
- zp->z_origin);
- error++;
- break;
- }
- if (cp != eom) {
- syslog(LOG_INFO,
- "print_output: short answer (%d, %d), zone %s",
- cp - buf, eom - buf,
- zp->z_origin);
- error++;
- break;
- }
- }
- if ((soa_cnt >= 2) && (methode == ISNOTIXFR))
- break;
- if ((soa_cnt == -1) && (methode == ISIXFR))
- break;
- }
- (void) my_close(s);
- if (error == 0) {
-#ifdef POSIX_SIGNALS
- (void) sigaction(SIGALRM, &osv,
- (struct sigaction *)0);
-#else
- (void) sigvec(SIGALRM, &osv,
- (struct sigvec *)0);
-#endif
- if (ixfp) {
- (void) fclose(ixfp);
- ixfp = NULL;
- }
- return (XFER_SUCCESSAXFR);
- }
- if (ixfp) {
- (void) fclose(ixfp);
- ixfp = NULL;
- }
- lprintf(2, "error receiving zone transfer\n");
- } else if (zp_start.z_serial == serial_no) {
- (void) my_close(s);
- lprintf(1, "zone up-to-date, serial %u\n",
- zp_start.z_serial);
- if (ixfp) {
- (void) fclose(ixfp);
- (void) unlink (tmpiname);
- ixfp = NULL;
- }
- return (XFER_UPTODATE);
- } else {
- (void) my_close(s);
- 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_start.z_serial, serial_no);
- return (XFER_FAIL);
- }
- } else {
- if (zp_finish.z_serial == query_serial) {
- (void) my_close(s);
- lprintf(1, "zone up-to-date, serial %u\n",
- zp_start.z_serial);
- if (ixfp) {
- (void) fclose(ixfp);
- (void) unlink (tmpiname);
- 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);
- lprintf(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);
- (void) unlink (tmpiname);
- ixfp = NULL;
- }
- if (was_ixfr == 0) {
- was_ixfr++;
- n = make_query(s, zp, T_AXFR,
- serial_no, tsig_key,
- buf, bufsize);
- if (n < 0) {
- (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);
- }
- methode = ISNOTIXFR;
- check_serial = 0;
- soa_cnt = 0;
- was_ixfr = 0;
- goto receive;
- }
- (void) my_close(s);
- return (XFER_FAIL);
- }
- if (soa_cnt > 2) {
- methode = ISNOTIXFR;
- check_serial = 0;
- soa_cnt = 0;
- goto axfr_response;
- }
- lprintf(1, "We have an IXFR\n");
- loop_cnt = 0;
- while (SEQ_GT(zp_finish.z_serial, serial_no)) {
- /*
- * Receive length & response
- */
- tsig_req = (soa_cnt == 0);
- len = readandverify(s, &buf, &bufsize, &sin,
- zp->z_origin, 1);
- if (len == 0) {
- error++;
- break;
- }
- hp = (HEADER *)buf;
- eom = buf + len;
- 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);
- refused = 1;
- } 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 &&
- ixfr_log(buf, len, &delete_soa, ixfp,
- &sin, &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);
-#else
- (void) sigvec(SIGALRM, &osv, (struct sigvec *)0);
-#endif
- if (ixfp) {
- (void) my_fclose(ixfp);
- (void) unlink (tmpiname);
- ixfp = NULL;
- }
- if (!error)
- return (XFER_TIMEOUT);
- if (refused)
- return (XFER_REFUSED);
- return (XFER_FAIL);
-}
-
-static SIG_FN
-term_handler() {
- cleanup_for_exit();
- _exit(XFER_FAIL); /* not safe to call exit() from a signal handler */
-}
-
-/*
- * Set flag saying to read was interrupted
- * used for a read timer
- */
-static SIG_FN
-read_alarm() {
- read_interrupted = 1;
-}
-
-static int
-netread(int fd, char *buf, int len, int timeout) {
- static const char setitimerStr[] = "setitimer: %m";
- struct itimerval ival, zeroival;
- struct sockaddr_in sa;
- int n;
- ISC_SOCKLEN_T salen;
-#if defined(NETREAD_BROKEN)
- int retries = 0;
-#endif
-
- memset(&zeroival, 0, sizeof zeroival);
- ival = zeroival;
- ival.it_value.tv_sec = timeout;
- while (len > 0) {
-#ifndef _WIN32
- 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);
- if (n == 0 && errno == 0) {
-#if defined(NETREAD_BROKEN)
- if (++retries < 42) /* doug adams */
- continue;
-#endif
- syslog(LOG_INFO, "premature EOF, fetching \"%s\"",
- domain);
- return (-1);
- }
- if (n < 0) {
- if (errno == 0) {
-#if defined(NETREAD_BROKEN)
- if (++retries < 42) /* doug adams */
- continue;
-#endif
- syslog(LOG_INFO,
- "recv(len=%d): n=%d && !errno",
- len, n);
- return (-1);
- }
- if (errno == EINTR) {
- if (!read_interrupted) {
- /* It wasn't a timeout; ignore it. */
- continue;
- }
- errno = ETIMEDOUT;
- }
- syslog(LOG_INFO, "recv(len=%d): %m", len);
- return (-1);
- }
- buf += n;
- len -= n;
-#if defined(NETREAD_BROKEN)
- /* Reset the retry counter if we are successfully reading. */
- if(n > 0)
- retries = 0;
-#endif
- }
-#ifndef _WIN32
- if (setitimer(ITIMER_REAL, &zeroival, NULL) < 0) {
- syslog(LOG_INFO, setitimerStr);
- return (-1);
- }
-#endif
- return (0);
-}
-
-/*
- * Write a counted buffer to a file descriptor preceded by a length word.
- */
-static int
-writemsg(int rfd, const u_char *msg, int msglen) {
- struct iovec iov[2];
- u_char len[INT16SZ];
- int ret;
-
- ns_put16(msglen, len);
- iov[0].iov_base = (char *)len;
- iov[0].iov_len = INT16SZ;
- DE_CONST(msg, iov[1].iov_base);
- iov[1].iov_len = msglen;
- ret = writev(rfd, iov, 2);
- if (ret != INT16SZ + msglen) {
- syslog(LOG_DEBUG, "writemsg(%d,%p,%d) failed: %s",
- rfd, msg, msglen, strerror(errno));
- return (-1);
- }
- return (ret);
-}
-
-static const char *
-soa_zinfo(struct zoneinfo *zp, u_char *cp, u_char *eom) {
- int n, type, class;
- u_int32_t ttl;
- u_int16_t dlen;
- u_char *rdatap;
-
- /* Are type, class, and ttl OK? */
- if (eom - cp < 3 * INT16SZ + INT32SZ)
- return ("zinfo too short");
- NS_GET16(type, cp);
- NS_GET16(class, cp);
- NS_GET32(ttl, cp);
- NS_GET16(dlen, cp);
- rdatap = cp;
- if (type != T_SOA || class != curclass)
- return ("zinfo wrong typ/cla/ttl");
- /* Skip master name and contact name, we can't validate them. */
- if ((n = dn_skipname(cp, eom)) == -1)
- return ("zinfo mname");
- cp += n;
- if ((n = dn_skipname(cp, eom)) == -1)
- return ("zinfo hname");
- cp += n;
- /* Grab the data fields. */
- if (eom - cp < 5 * INT32SZ)
- return ("zinfo dlen");
- NS_GET32(zp->z_serial, cp);
- NS_GET32(zp->z_refresh, cp);
- NS_GET32(zp->z_retry, cp);
- NS_GET32(zp->z_expire, cp);
- NS_GET32(zp->z_minimum, cp);
- if (cp != rdatap + dlen)
- return ("bad soa dlen");
- return (NULL);
-}
-
-#define BOUNDS_CHECK(ptr, count) \
- do { \
- if ((ptr) + (count) > eom) { \
- hp->rcode = FORMERR; \
- return (-1); \
- } \
- } while (0)
-
-/*
- * Parse the message, determine if it should be printed, and if so, print it
- * in .db file form. Does minimal error checking on the message content.
- *
- * XXX why aren't we using ns_sprintrr() ?
- */
-static int
-print_output(struct zoneinfo *zp, u_int32_t serial_no, u_char *msg,
- int msglen, u_char *rrp, int xfr_detect) {
- u_char *cp;
- HEADER *hp = (HEADER *) msg;
- u_int32_t ttl, tmpnum;
- int i, j, longname, result, n1, n;
- u_int class, type, dlen;
- char data[MAXDATA];
- u_char *cp1, *cp2, *temp_ptr, *eom, *rr_type_ptr;
- u_char *cdata, *rdatap;
- char *origin, dname[MAXDNAME];
- const char *proto;
- const char *ignore = "";
- const char *badsoa_msg;
- int escaped = 0;
-
- eom = msg + msglen;
- cp = rrp;
- n = dn_expand(msg, msg + msglen, cp, dname, sizeof dname);
- if (n < 0) {
- hp->rcode = FORMERR;
- return (-1);
- }
- cp += n;
- BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
- rr_type_ptr = cp;
- NS_GET16(type, cp);
- NS_GET16(class, cp);
- NS_GET32(ttl, cp);
- /*
- * Following the Clarification draft's direction, we treat TTLs with
- * the MSB set as if they were 0.
- */
- if (ttl > MAXIMUM_TTL) {
- syslog(LOG_INFO, "%s: TTL > %u, converted to 0", dname,
- MAXIMUM_TTL);
- ttl = 0;
- }
- NS_GET16(dlen, cp);
- BOUNDS_CHECK(cp, dlen);
- rdatap = cp;
-
- origin = dname;
- while (*origin) {
- if (!escaped && *origin == '.') {
- origin++; /* skip over '.' */
- break;
- }
- escaped = (*origin++ == '\\') && !escaped;
- }
- lprintf(3, "print_output: dname %s type %d class %d ttl %u\n",
- dname, type, class, ttl);
- /*
- * Convert the resource record data into the internal database format.
- * CP points to the raw resource record.
- * After this switch:
- * CP has been updated to point past the RR.
- * CP1 points to the internal database version.
- * N is the length of the internal database version.
- */
- switch (type) {
- case T_A:
- case T_WKS:
- case T_HINFO:
- case T_TXT:
- case T_X25:
- case T_ISDN:
- case T_LOC:
- case T_NSAP:
- case T_AAAA:
- case T_KEY:
- case ns_t_cert:
- cp1 = cp;
- n = dlen;
- cp += n;
- break;
-
- case T_CNAME:
- case T_MB:
- case T_MG:
- case T_MR:
- case T_NS:
- case T_PTR:
- n = dn_expand(msg, msg + msglen, cp, data, sizeof data);
- if (n < 0) {
- hp->rcode = FORMERR;
- return (-1);
- }
- cp += n;
- cp1 = (u_char *)data;
- n = strlen(data) + 1;
- break;
-
- case T_MINFO:
- case T_SOA:
- case T_RP:
- n = dn_expand(msg, msg + msglen, cp, data, sizeof data);
- if (n < 0) {
- hp->rcode = FORMERR;
- return (-1);
- }
- cp += n;
- n = strlen(data) + 1;
- cp1 = (u_char *)data + n;
- n1 = sizeof data - n;
- if (type == T_SOA)
- n1 -= 5 * INT32SZ;
- n = dn_expand(msg, msg + msglen, cp, (char *)cp1, n1);
- if (n < 0) {
- hp->rcode = FORMERR;
- return (-1);
- }
- cp += n;
- cp1 += strlen((char *) cp1) + 1;
- if (type == T_SOA) {
- BOUNDS_CHECK(cp, 5 * INT32SZ);
- temp_ptr = cp + 4 * INT32SZ;
- NS_GET32(minimum_ttl, temp_ptr);
- /*
- * Following the Clarification draft's direction,
- * we treat TTLs with the MSB set as if they were 0.
- */
- if (minimum_ttl > MAXIMUM_TTL) {
- syslog(LOG_INFO,
- "%s: SOA minimum TTL > %u, converted to 0",
- dname, MAXIMUM_TTL);
- minimum_ttl = 0;
- }
- n = 5 * INT32SZ;
- memcpy(cp1, cp, n);
- cp += n;
- cp1 += n;
- }
- n = cp1 - (u_char *)data;
- cp1 = (u_char *)data;
- break;
-
- case T_NAPTR:
- /* Grab weight and port. */
- BOUNDS_CHECK(cp, INT16SZ*2);
- memcpy(data, cp, INT16SZ*2);
- cp1 = (u_char *)data + INT16SZ*2;
- cp += INT16SZ*2;
-
- /* Flags */
- BOUNDS_CHECK(cp, 1);
- n = *cp++;
- BOUNDS_CHECK(cp, n);
- *cp1++ = n;
- memcpy(cp1, cp, n);
- cp += n; cp1 += n;
-
- /* Service */
- BOUNDS_CHECK(cp, 1);
- n = *cp++;
- BOUNDS_CHECK(cp, n);
- *cp1++ = n;
- memcpy(cp1, cp, n);
- cp += n; cp1 += n;
-
- /* Regexp */
- BOUNDS_CHECK(cp, 1);
- n = *cp++;
- BOUNDS_CHECK(cp, n);
- *cp1++ = n;
- memcpy(cp1, cp, n);
- cp += n; cp1 += n;
-
- /* Replacement */
- n = dn_expand(msg, msg + msglen, cp, (char *)cp1,
- sizeof data - ((char *)cp1 - data));
- if (n < 0)
- return (-1);
- cp += n;
-
- /* compute end of data */
- cp1 += strlen((char *)cp1) + 1;
- /* compute size of data */
- n = cp1 - (u_char *)data;
- cp1 = (u_char *)data;
- break;
-
- case T_MX:
- case T_AFSDB:
- case T_RT:
- case T_SRV:
- /* grab preference */
- BOUNDS_CHECK(cp, INT16SZ);
- memcpy(data, cp, INT16SZ);
- cp1 = (u_char *)data + INT16SZ;
- cp += INT16SZ;
-
- if (type == T_SRV) {
- BOUNDS_CHECK(cp, INT16SZ*2);
- memcpy(cp1, cp, INT16SZ*2);
- cp1 += INT16SZ*2;
- cp += INT16SZ*2;
- }
-
- /* get name */
- n = dn_expand(msg, msg + msglen, cp,
- (char *)cp1,
- sizeof data - (cp1 - (u_char *)data));
- if (n < 0)
- return (-1);
- cp += n;
-
- /* compute end of data */
- cp1 += strlen((char *) cp1) + 1;
- /* compute size of data */
- n = cp1 - (u_char *)data;
- cp1 = (u_char *)data;
- break;
-
- case T_PX:
- /* grab preference */
- BOUNDS_CHECK(cp, INT16SZ);
- memcpy(data, cp, INT16SZ);
- cp1 = (u_char *)data + INT16SZ;
- cp += INT16SZ;
-
- /* get MAP822 name */
- n = dn_expand(msg, msg + msglen, cp,
- (char *)cp1, sizeof data - INT16SZ);
- if (n < 0)
- return (-1);
- cp += n;
- cp1 += (n = (strlen((char *) cp1) + 1));
- n1 = sizeof data - n;
-
- /* get MAPX400 name */
- n = dn_expand(msg, msg + msglen, cp, (char *)cp1, n1);
- if (n < 0)
- return (-1);
- cp += n;
- cp1 += strlen((char *) cp1) + 1;
- n = cp1 - (u_char *)data;
- cp1 = (u_char *)data;
- break;
-
- case T_SIG:
- /* CP is the raw resource record as it arrived.
- * CP1, after this switch, points to the internal database version. */
- cp1 = (u_char *)data;
-
- /* first just copy over the type_covered, algorithm, */
- /* labels, orig ttl, two timestamps, and the footprint */
- BOUNDS_CHECK(cp, NS_SIG_SIGNER);
- memcpy(cp1, cp, NS_SIG_SIGNER);
- cp += NS_SIG_SIGNER;
- cp1 += NS_SIG_SIGNER;
-
- /* then the signer's name */
- n = dn_expand(msg, msg + msglen, cp,
- (char *)cp1, (sizeof data) - 18);
- if (n < 0)
- return (-1);
- cp += n;
- cp1 += strlen((char*)cp1)+1;
-
- /* finally, we copy over the variable-length signature.
- Its size is the total data length, minus what we copied. */
- n = dlen - (NS_SIG_SIGNER + n);
- if (n > ((int)(sizeof data) - (int)(cp1 - (u_char *)data))) {
- hp->rcode = FORMERR;
- return (-1); /* out of room! */
- }
- memcpy(cp1, cp, n);
- cp += n;
- cp1 += n;
-
- /* compute size of data */
- n = cp1 - (u_char *)data;
- cp1 = (u_char *)data;
- break;
-
- case T_NXT:
- n = dn_expand(msg, msg + msglen, cp,
- (char *)data, sizeof data);
- if (n < 0) {
- hp->rcode = FORMERR;
- return (-1);
- }
- cp += n;
- cp1 = (u_char *)data + strlen(data) + 1;
- n = dlen - n;
- if (n > ((int)(sizeof data) - (int)(cp1 - (u_char *)data))) {
- hp->rcode = FORMERR;
- return (-1); /* out of room! */
- }
- if (n > 0) { /* Actually, n should never be less than 4 */
- memcpy(cp1, cp, n);
- cp += n;
- } else {
- hp->rcode = FORMERR;
- return (-1);
- }
- n += cp1 - (u_char *)data;
- cp1 = (u_char *)data;
- break;
-
- default:
- cp1 = cp;
- n = dlen;
- cp += n;
- break;
- }
-
- if (n > MAXDATA) {
- lprintf(1, "update type %d: %d bytes is too much data\n",
- type, n);
- hp->rcode = FORMERR;
- return (-1);
- }
- if (cp != rdatap + dlen) {
- lprintf(1,
- "encoded rdata length is %u, but actual length was %u\n",
- dlen, (u_int)(cp - rdatap));
- hp->rcode = FORMERR;
- return (-1);
- }
-
- cdata = cp1;
- result = cp - rrp;
-
- /*
- * Special handling for SOA records.
- */
-
- if (type == T_SOA) {
- if (ns_samename(dname, zp->z_origin) != 1) {
- syslog(LOG_INFO,
- "wrong zone name in XFR (wanted \"%s\", got \"%s\")",
- zp->z_origin, dname);
- hp->rcode = FORMERR;
- return (-1);
- }
- if (soa_cnt == 0) {
- badsoa_msg = soa_zinfo(&zp_start, rr_type_ptr, eom);
- if (badsoa_msg) {
- syslog(LOG_INFO,
- "malformed SOA for zone %s: %s",
- zp->z_origin, badsoa_msg);
- hp->rcode = FORMERR;
- return (-1);
- }
- if (SEQ_GT(zp_start.z_serial, serial_no) ||
- !check_serial) {
- soa_cnt++;
- } else {
- syslog(LOG_INFO,
- "serial went backwards after transfer started");
- return (-1);
- }
- } else if (soa_cnt == 1) {
- badsoa_msg = soa_zinfo(&zp_finish, rr_type_ptr, eom);
- if (badsoa_msg) {
- syslog(LOG_INFO,
- "malformed SOA for zone %s: %s",
- zp->z_origin, badsoa_msg);
- hp->rcode = FORMERR;
- return (-1);
- }
- if (zp_start.z_serial == zp_finish.z_serial) {
- methode = ISNOTIXFR;
- if (xfr_detect == 3)
- soa_cnt = 0;
- } else if (zp_finish.z_serial != serial_no) {
- syslog(LOG_INFO,
- "Unexpected serial number for zone %s: %u",
- zp->z_origin, zp_finish.z_serial);
- }
- soa_cnt++;
- if (methode == ISIXFR)
- return (result);
- } else {
- badsoa_msg = soa_zinfo(&zp_finish, rr_type_ptr, eom);
- if (badsoa_msg) {
- syslog(LOG_INFO,
- "malformed SOA for zone %s: %s",
- zp->z_origin, badsoa_msg);
- hp->rcode = FORMERR;
- return (-1);
- }
- if (methode == ISIXFR) {
- if (zp_start.z_serial == zp_finish.z_serial) {
- if (scdsoa) {
- soa_cnt = -1;
- return (result);
- } else {
- scdsoa = 1;
- soa_cnt++;
- };
- } else
- soa_cnt++;
- } else {
- lprintf(2, "SOA, serial %u\n",
- zp_finish.z_serial);
- if (zp_start.z_serial != zp_finish.z_serial) {
- lprintf(1, "serial changed, restart\n");
- restarts++;
- if (restarts > MAX_XFER_RESTARTS) {
- syslog(LOG_INFO,
- "too many transfer restarts for zone %s",
- zp->z_origin);
- hp->rcode = FORMERR;
- return (-1);
- }
- soa_cnt = 0;
- ns_cnt = 0;
- minimum_ttl = 0;
- strcpy(prev_origin, zp->z_origin);
- prev_dname[0] = DEF_DNAME;
- /*
- * Flush buffer, truncate file
- * and seek to beginning to restart.
- */
- fflush(dbfp);
- if (ftruncate(fileno(dbfp), 0) != 0) {
- if (!quiet)
- syslog(LOG_INFO,
- "ftruncate %s: %m\n",
- tmpname);
- return (-1);
- }
- fseek(dbfp, 0L, 0);
- return (result);
- }
- soa_cnt++;
- return (result);
- }
- }
- if (soa_cnt == 2)
- return (result);
-
- }
-
- if (zp->z_type == Z_STUB) {
- if (query_type == T_NS && type == T_NS)
- ns_cnt++;
- /*
- * If we're processing a response to an SOA query, we don't
- * want to print anything from the response except for the SOA.
- * We do want to check everything in the packet, which is
- * why we do this check now instead of earlier.
- */
- if (query_type == T_SOA && type != T_SOA)
- return (result);
- }
-
- if ((!soa_cnt || soa_cnt > 2) && methode == ISNOTIXFR) {
- const char *gripe;
-
- if (!soa_cnt)
- gripe = "got RR before first SOA";
- else
- gripe = "got RR after second SOA";
- syslog(LOG_INFO, "%s in zone %s", gripe, zp->z_origin);
- hp->rcode = FORMERR;
- return (-1);
- }
-
- /*
- * If they are trying to tell us info about something that is
- * not in the zone that we are transfering, then ignore it!
- * They don't have the authority to tell us this info.
- *
- * We have to do a bit of checking here - the name that we are
- * checking is is fully qualified & may be in a subdomain of the
- * zone in question. We also need to ignore any final dots.
- *
- * If a domain has both NS records and non-NS records, (for
- * example, NS and MX records), then we should ignore the non-NS
- * records (except that we should not ignore glue A records).
- * XXX: It is difficult to do this properly, so we just compare
- * the current dname with that in the most recent NS record.
- * This defends against the most common error case,
- * where the remote server sends MX records soon after the
- * NS records for a particular domain. If sent earlier, we lose. XXX
- */
- if (!ns_samedomain(dname, domain)) {
- (void) fprintf(dbfp, "; Ignoring info about %s, not in zone %s.\n",
- dname, domain);
- ignore = "; ";
- } else if (type != T_NS && type != T_A &&
- ns_samename(zone_top, dname) != 1 &&
- ns_samename(prev_ns_dname, dname) == 1)
- {
- (void) fprintf(dbfp, "; Ignoring extra info about %s, invalid after NS delegation.\n",
- dname);
- ignore = "; ";
- } else if (class != (unsigned)zp->z_class) {
- (void) fprintf(dbfp, "; Ignoring info about %s, not class %s\n",
- dname, p_class(zp->z_class));
- ignore = "; ";
- }
-
- /*
- * If the current record is not being ignored, but the
- * previous record was ignored, then we invalidate information
- * that might have been altered by ignored records.
- * (This means that we sometimes output unnecessary $ORIGIN
- * lines, but that is harmless.)
- *
- * Also update prev_comment now.
- */
- if (prev_comment && ignore[0] == '\0') {
- prev_dname[0] = DEF_DNAME;
- prev_origin[0] = DEF_DNAME;
- }
- prev_comment = (ignore[0] != '\0');
-
- /*
- * set prev_ns_dname if necessary
- */
- if (type == T_NS) {
- (void) strcpy(prev_ns_dname, dname);
- }
-
- /*
- * If the origin has changed, print the new origin
- */
- if (ns_samename(prev_origin, origin) != 1) {
- (void) strcpy(prev_origin, origin);
- (void) fprintf(dbfp, "%s$ORIGIN %s.\n", ignore, origin);
- }
-
- longname = 0;
-
- if (ns_samename(prev_dname, dname) != 1) {
- /*
- * set the prev_dname to be the current dname, then cut off all
- * characters of dname after (and including) the first '.'
- */
- char *cutp;
-
- (void) strcpy(prev_dname, dname);
- escaped = 0;
- cutp = dname;
- while (*cutp) {
- if (!escaped && *cutp == '.')
- break;
- escaped = (*cutp++ == '\\') && !escaped;
- }
- *cutp = '\0';
-
- if (dname[0] == 0) {
- if (origin[0] == 0)
- (void) fprintf(dbfp, "%s.\t", ignore);
- else
- (void) fprintf(dbfp, "%s.%s.\t",
- ignore, origin); /* ??? */
- } else {
- const char *backslash;
- backslash = (*dname == '@' || *dname == '$') ?
- "\\" : "";
- (void) fprintf(dbfp, "%s%s%s\t", ignore,
- backslash, dname);
- }
- if (strlen(dname) > (size_t)8)
- longname = 1;
- } else {
- (void) fprintf(dbfp, "%s\t", ignore);
- }
-
- (void) fprintf(dbfp, "%d\t", (int) ttl);
-
- (void) fprintf(dbfp, "%s\t%s\t", p_class(class), p_type(type));
- cp = cdata;
-
- /*
- * Print type specific data
- */
- switch (type) {
-
- case T_A:
- switch (class) {
- case C_IN:
- case C_HS:
- fputs(inet_ntoa(ina_get(cp)), dbfp);
- break;
- }
- (void) fprintf(dbfp, "\n");
- break;
-
- case T_CNAME:
- case T_MB:
- case T_MG:
- case T_MR:
- case T_PTR:
- if (cp[0] == '\0')
- (void) fprintf(dbfp, ".\n");
- else
- (void) fprintf(dbfp, "%s.\n", cp);
- break;
-
- case T_NS:
- cp = cdata;
- if (cp[0] == '\0')
- (void) fprintf(dbfp, ".\t");
- else
- (void) fprintf(dbfp, "%s.", cp);
- (void) fprintf(dbfp, "\n");
- break;
-
- case T_HINFO:
- case T_ISDN:
- cp2 = cp + n;
- for (i = 0; i < 2; i++) {
- if (i != 0)
- (void) putc(' ', dbfp);
- n = *cp++;
- cp1 = cp + n;
- if (cp1 > cp2)
- cp1 = cp2;
- (void) putc('"', dbfp);
- j = 0;
- while (cp < cp1) {
- if (*cp == '\0') {
- cp = cp1;
- break;
- }
- if (strchr("\n\"\\", *cp))
- (void) putc('\\', dbfp);
- (void) putc(*cp++, dbfp);
- j++;
- }
- if (j == 0 && (type != T_ISDN || i == 0))
- (void) putc('?', dbfp);
- (void) putc('"', dbfp);
- }
- (void) putc('\n', dbfp);
- break;
-
- case T_SOA:
- (void) fprintf(dbfp, "%s.", cp);
- cp += strlen((char *) cp) + 1;
- (void) fprintf(dbfp, " %s. (\n", cp);
- cp += strlen((char *) cp) + 1;
- NS_GET32(tmpnum, cp);
- (void) fprintf(dbfp, "%s\t\t%u", ignore, tmpnum);
- NS_GET32(tmpnum, cp);
- (void) fprintf(dbfp, " %u", tmpnum);
- NS_GET32(tmpnum, cp);
- (void) fprintf(dbfp, " %u", tmpnum);
- NS_GET32(tmpnum, cp);
- (void) fprintf(dbfp, " %u", tmpnum);
- NS_GET32(tmpnum, cp);
- (void) fprintf(dbfp, " %u )\n", tmpnum);
- break;
-
- case T_MX:
- case T_AFSDB:
- case T_RT:
- NS_GET16(tmpnum, cp);
- (void) fprintf(dbfp, "%u", tmpnum);
- (void) fprintf(dbfp, " %s.\n", cp);
- break;
-
- case T_PX:
- NS_GET16(tmpnum, cp);
- (void) fprintf(dbfp, "%u", tmpnum);
- (void) fprintf(dbfp, " %s.", cp);
- cp += strlen((char *) cp) + 1;
- (void) fprintf(dbfp, " %s.\n", cp);
- break;
-
- case T_TXT:
- case T_X25:
- cp1 = cp + n;
- while (cp < cp1) {
- (void) putc('"', dbfp);
- if ((i = *cp++) != 0) {
- for (j = i; j > 0 && cp < cp1; j--) {
- if (strchr("\n\"\\", *cp))
- (void) putc('\\', dbfp);
- (void) putc(*cp++, dbfp);
- }
- }
- (void) putc('"', dbfp);
- if (cp < cp1)
- (void) putc(' ', dbfp);
- }
- (void) putc('\n', dbfp);
- break;
-
- case T_NSAP:
- fprintf(dbfp, "%s\n", inet_nsap_ntoa(n, cp, NULL));
- break;
-
- case T_AAAA: {
- char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
-
- fprintf(dbfp, "%s\n", inet_ntop(AF_INET6, cp, t, sizeof t));
- break;
- }
-
- case T_LOC: {
- char t[255];
-
- (void) fprintf(dbfp, "%s\n", loc_ntoa(cp, t));
- break;
- }
-
- case T_NAPTR: {
- u_int32_t order, preference;
-
- /* Order */
- NS_GET16(order, cp);
- fprintf(dbfp, "%u", order);
-
- /* Preference */
- NS_GET16(preference, cp);
- fprintf(dbfp, " %u", preference);
-
- /* Flags */
- n = *cp++;
- fprintf(dbfp, " \"%.*s\"", (int)n, cp);
- cp += n;
-
- /* Service */
- n = *cp++;
- fprintf(dbfp, " \"%.*s\"", (int)n, cp);
- cp += n;
-
- /* Regexp */
- n = *cp++;
- fprintf(dbfp, " \"%.*s\"", (int)n, cp);
- cp += n;
-
- /* Replacement */
- fprintf(dbfp, " %s.\n", cp);
-
- break;
- }
- case T_SRV: {
- u_int priority, weight, port;
-
- NS_GET16(priority, cp);
- NS_GET16(weight, cp);
- NS_GET16(port, cp);
- fprintf(dbfp, "\t%u %u %u %s.\n",
- priority, weight, port, cp);
- break;
- }
-
- case T_WKS:
- fputs(inet_ntoa(ina_get(cp)), dbfp);
- cp += INADDRSZ;
- fputc(' ', dbfp);
- proto = protocolname(*cp);
- cp += sizeof(char);
- (void) fprintf(dbfp, "%s ", proto);
- i = 0;
- while (cp < cdata + n) {
- j = *cp++;
- do {
- if (j & 0200)
- (void) fprintf(dbfp, " %s",
- servicename(i, proto));
- j <<= 1;
- } while (++i & 07);
- }
- (void) fprintf(dbfp, "\n");
- break;
-
- case T_MINFO:
- case T_RP:
- (void) fprintf(dbfp, "%s.", cp);
- cp += strlen((char *) cp) + 1;
- (void) fprintf(dbfp, " %s.\n", cp);
- break;
-
- case T_KEY: {
- char databuf[16+NS_MD5RSA_MAX_BASE64]; /* 16 for slop */
- u_int keyflags;
-
- /* get & format key flags */
- keyflags = ns_get16(cp);
- (void) fprintf(dbfp, "0x%04x ", keyflags);
- cp += INT16SZ;
-
- /* protocol id */
- (void) fprintf(dbfp, " %u", *cp++);
-
- /* algorithm id */
- (void) fprintf(dbfp, " %u ", *cp++);
-
- /* key itself (which may have zero length) */
- n = b64_ntop(cp, (cp1 + n) - cp, databuf, sizeof databuf);
- if (n < 0)
- fprintf(dbfp, "; BAD BASE64\n");
- else
- fprintf(dbfp, "%s\n", databuf);
- break;
- }
-
- case T_SIG: {
- char databuf[16+NS_MD5RSA_MAX_BASE64]; /* 16 for slop */
-
- /* get & format rr type which signature covers */
- (void) fprintf(dbfp,"%s", p_type(ns_get16((u_char*)cp)));
- cp += INT16SZ;
-
- /* algorithm id */
- (void) fprintf(dbfp," %d",*cp++);
-
- /* labels (# of labels in name) */
- (void) fprintf(dbfp," %d",*cp++);
-
- /* orig time to live (TTL)) */
- (void) fprintf(dbfp," %u", (u_int32_t)ns_get32((u_char*)cp));
- cp += INT32SZ;
-
- /* expiration time */
- (void) fprintf(dbfp," %s", p_secstodate(ns_get32((u_char*)cp)));
- cp += INT32SZ;
-
- /* time signed */
- (void) fprintf(dbfp," %s", p_secstodate(ns_get32((u_char*)cp)));
- cp += INT32SZ;
-
- /* Key footprint */
- (void) fprintf(dbfp," %d", ns_get16((u_char*)cp));
- cp += INT16SZ;
-
- /* signer's name */
- (void) fprintf(dbfp, " %s. ", cp);
- cp += strlen((char *) cp) + 1;
-
- /* signature itself */
- n = b64_ntop(cp, (cdata + n) - cp, databuf, sizeof databuf);
- if (n < 0)
- fprintf (dbfp, "; BAD BASE64\n");
- else
- fprintf (dbfp, "%s\n", databuf);
- break;
- }
-
- case T_NXT:
- fprintf(dbfp, "%s.", (char *)cp);
- i = strlen((char *)cp)+1;
- cp += i;
- n -= i;
- for (i=0; i < n*NS_NXT_BITS; i++)
- if (NS_NXT_BIT_ISSET (i, cp))
- fprintf(dbfp, " %s", p_type(i));
- fprintf(dbfp,"\n");
- break;
-
- case ns_t_cert: {
- int databufsize = n * 4 / 3 + 4;
- char *databuf = malloc(databufsize);
-
- if (databuf == NULL)
- panic("cert malloc failed", NULL);
-
- /* Object id */
- (void) fprintf(dbfp,"%d ", ns_get16((u_char*)cp));
- cp += INT16SZ;
-
- /* Key tag */
- (void) fprintf(dbfp,"%d ", ns_get16((u_char*)cp));
- cp += INT16SZ;
-
- /* Algorithm id */
- (void) fprintf(dbfp,"%d ", (u_char)*cp);
- cp += 1;
-
- n = b64_ntop(cp, n - 2 * INT16SZ - 1, databuf, databufsize);
- if (n < 0)
- panic ("cert b64_ntop failed", NULL);
- fprintf (dbfp, "%s\n", databuf);
- free(databuf);
- break;
- }
-
- default:
- fprintf (dbfp, "\\# %u", n);
- if (n > 0) {
- fputs(" ( ", dbfp);
- isc_puthexstring(dbfp, cp1, n,
- (longname ? 28 : 40), 48,
- "\n\t\t\t\t");
- fputs(" )\n", dbfp);
- }
-
- }
- if (ferror(dbfp)) {
- syslog(LOG_ERR, "%s: %m", tmpname);
- cleanup_for_exit();
- exit(XFER_FAIL);
- }
- return (result);
-}
-
-#ifdef SHORT_FNAMES
-/*
-** This routine handles creating temporary files with mkstemp
-** in the presence of a 14 char filename system. Pathconf()
-** does not work over NFS.
-*/
-filenamecpy(char *ddtfile, char *optarg) {
- int namelen, extra, len;
- char *dirname, *filename;
-
- /* determine the length of filename allowed */
- if((dirname = strrchr(optarg, '/')) == NULL){
- filename = optarg;
- } else {
- *dirname++ = '\0';
- filename = dirname;
- }
- namelen = pathconf(dirname == NULL? "." : optarg, _PC_NAME_MAX);
- if(namelen <= 0)
- namelen = 255; /* length could not be determined */
- if(dirname != NULL)
- *--dirname = '/';
-
- /* copy a shorter name if it will be longer than allowed */
- extra = (strlen(filename)+strlen(".XXXXXX")) - namelen;
- if(extra > 0){
- len = strlen(optarg) - extra;
- (void) strncpy(ddtfile, optarg, len);
- ddtfile[len] = '\0';
- } else
- (void) strcpy(ddtfile, optarg);
-}
-#endif /* SHORT_FNAMES */
-
-DST_KEY *
-tsig_key_from_addr(struct in_addr addr) {
- tsig_node *n;
- for (n = HEAD(tsig_list); n != NULL; n = NEXT(n, link))
- if (memcpy(&addr, &n->addr, sizeof(struct in_addr)))
- return n->dst_key;
- return NULL;
-}
-
-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 */
- ns_opcode opcode;
- ns_rr rr;
- const unsigned char *cp;
- const unsigned char *eom;
- u_int32_t serial = 0;
- time_t now;
-
- time(&now);
-
- /*
- * Print answer records.
- */
- sflag = (_res.pfcode & pflag);
- if (_res.pfcode && !sflag)
- return (-1);
-
- opcode = (ns_opcode)ns_msg_getflag(*handle, ns_f_opcode);
- rrnum = 0;
- for (;;) {
- if (ns_parserr(handle, section, rrnum, &rr)) {
- if (errno != ENODEV) {
- fprintf(file, ";; ns_parserr: %s\n",
- strerror(errno));
- return (-1);
- } else if (rrnum > 0 && sflag != 0 &&
- (_res.pfcode & RES_PRF_HEAD1))
- putc('\n', file);
- break;
- }
- if (rrnum == 0 && sflag != 0 && (_res.pfcode & RES_PRF_HEAD1))
- fprintf(file, ";; %s SECTION:\n",
- p_section(section, opcode));
- if (section == ns_s_qd)
- fprintf(file, ";;\t%s, type = %s, class = %s\n",
- ns_rr_name(rr),
- p_type(ns_rr_type(rr)),
- p_class(ns_rr_class(rr)));
- else {
- int print_record = 1;
- if (rr.type == ns_t_soa) {
- print_record = 0;
- *delete = !*delete;
- cp = ns_rr_rdata(rr);
- eom = cp + ns_rr_rdlen(rr);
- if ((n = dn_skipname(cp, eom)) < 0) {
- rrnum++;
- continue;
- }
- cp += n;
- if ((n = dn_skipname(cp, eom)) < 0) {
- rrnum++;
- continue;
- }
- cp += n;
- NS_GET32(serial, cp);
- 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(-1);
- }
- n = ns_sprintrr(handle, &rr, NULL, NULL,
- soa_buf, 2*PACKETSZ);
- if (n < 0) {
- fprintf(file, ";; ns_sprintrr: %s\n",
- strerror(errno));
- return (-1);
- }
- }
- print_record = 0;
- break;
- case 2:
- fprintf(file,
- "zone:\torigin %s class %s serial %u\n",
- ns_rr_name(rr),
- p_class(ns_rr_class(rr)),
- serial);
- print_record = 0;
- break;
- default:
- print_record = 0;
- break;
- }
-
- }
-
- if (print_record) {
- if (rr.type != ns_t_soa) {
- fprintf(file, "update:\t{%s} ",
- *delete ? "delete" : "add");
-
- n = ns_sprintrr(handle, &rr, NULL, NULL,
- buf, sizeof buf);
- if (n < 0) {
- fprintf(file, ";; ns_sprintrr: %s\n",
- strerror(errno));
- return(-1);
- }
- fputs(buf, file);
- fputc('\n', file);
- }
- }
-
- }
- rrnum++;
- }
- return (serial);
-}
-
-static int
-ixfr_log(const u_char *msg, int len, int *delete, FILE *file,
- struct sockaddr_in *sin, u_int32_t *serial_no, int *first_rr)
-{
- ns_msg handle;
- ns_type type;
- ns_class class;
- ns_opcode opcode;
- ns_rcode rcode;
- u_int id;
- u_int32_t new_serial = 0;
- char time[25];
- ns_rr rr;
-
- if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
- lprintf(1, "ixfr_log() failed\n");
- return (-1);
- }
-
- if (ns_initparse(msg, len, &handle) < 0) {
- fprintf(file, ";; ns_initparse: %s\n", strerror(errno));
- lprintf(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);
- id = ns_msg_id(handle);
-
- if (ns_parserr(&handle, ns_s_an, 0, &rr))
- {
-
- (void) fprintf(file,"ns_parserr() failed");
- lprintf(1, "ixfr_log() failed\n");
- return (-1);
- }
- type = (ns_type)rr.type;
- class = (ns_class)rr.rr_class;
-
- if (*first_rr == 1) {
- gettime(&tt);
- (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-xfer pid %ld):\n",
- id, inet_ntoa(sin->sin_addr),
- ntohs(sin->sin_port), time, (long)getpid());
- (*first_rr)++;
- }
- new_serial = do_section(&handle, ns_s_an, RES_PRF_ANS, file, delete);
- if (type == T_SOA && SEQ_GT(new_serial, *serial_no) && (*delete))
- *serial_no = new_serial;
- return (1);
-}
-
-static const char *
-tsig_rcode(int rcode) {
- static char buffer[64];
-
- switch (rcode) {
- case ns_r_badkey:
- case ns_r_badsig:
- case ns_r_badtime:
- sprintf(buffer, "message had %s set", p_rcode(rcode));
- return (buffer);
- case -ns_r_badkey:
- case -ns_r_badsig:
- case -ns_r_badtime:
- return (p_rcode(-rcode));
- case NS_TSIG_ERROR_NO_TSIG:
- return ("no TSIG present");
- default:
- break;
- }
- return ("FORMERR");
-}
OpenPOWER on IntegriCloud