diff options
author | 2013-11-26 13:04:24 +0000 | |
---|---|---|
committer | 2013-11-26 13:04:24 +0000 | |
commit | d117b116d30bf49e63be98bc0b701ef1cf19418a (patch) | |
tree | 8f51aef85577b825209647f8475002c862b2ff8e | |
parent | update for NSD 4.0.0; generate keys for nsd-control if non-existent, and (diff) | |
download | wireguard-openbsd-d117b116d30bf49e63be98bc0b701ef1cf19418a.tar.xz wireguard-openbsd-d117b116d30bf49e63be98bc0b701ef1cf19418a.zip |
remove old files
-rw-r--r-- | usr.sbin/nsd/nsd-notify.8.in | 66 | ||||
-rw-r--r-- | usr.sbin/nsd/nsd-notify.c | 466 | ||||
-rw-r--r-- | usr.sbin/nsd/nsd-patch.8.in | 69 | ||||
-rw-r--r-- | usr.sbin/nsd/nsd-patch.c | 430 | ||||
-rw-r--r-- | usr.sbin/nsd/nsd-xfer.8.in | 83 | ||||
-rw-r--r-- | usr.sbin/nsd/nsd-xfer.c | 1087 | ||||
-rw-r--r-- | usr.sbin/nsd/nsdc.8.in | 169 | ||||
-rw-r--r-- | usr.sbin/nsd/nsdc.sh.in | 431 | ||||
-rw-r--r-- | usr.sbin/nsd/zonec.8.in | 126 |
9 files changed, 0 insertions, 2927 deletions
diff --git a/usr.sbin/nsd/nsd-notify.8.in b/usr.sbin/nsd/nsd-notify.8.in deleted file mode 100644 index 6ce8fe74e9a..00000000000 --- a/usr.sbin/nsd/nsd-notify.8.in +++ /dev/null @@ -1,66 +0,0 @@ -.TH "nsd\-notify" "8" "Jul 22, 2013" "NLnet Labs" "nsd 3.2.16" -.\" Copyright (c) 2001\-2011, NLnet Labs. All rights reserved. -.\" See LICENSE for the license. -.SH "NAME" -.LP -.B nsd\-notify -\- program to send NOTIFY's to remote nameservers. -.SH "SYNOPSIS" -.LP -.B nsd\-notify -.RB [ \-4 ] -.RB [ \-6 ] -.RB [ \-h ] -.RB [ \-a -.IR address[@port] ] -.RB [ \-p -.IR port ] -.RB [ \-y -.IR key:secret[:algorithm] ] -.B \-z -.I zone servers -.SH "DESCRIPTION" -.LP -.B Nsd\-notify -is simple program to send NOTIFY's to remote nameservers. -.B NSD -is a complete implementation of an authoritative DNS nameserver. -.SH "OPTIONS" -.TP -.B \-4 -Only send to IPv4 addresses. -.TP -.B \-6 -Only send to IPv6 addresses. -.TP -.B \-h -Print help information and exit. -.TP -.B \-a\fI address[@port] -Specify the source address (and port) to send from. -.TP -.B \-p\fI port -Specify the port to send to. -.TP -.B \-y\fI key:secret[:algorithm] -Specify a TSIG key and base64 encoded secret to sign the notification with. If -the TSIG algorithm is not defined, MD5 is used. -.TP -.B z\fI zone -Specify the zone to notify about. -.TP -.I servers -List of nameservers to send to. -.SH "EXAMPLES" -.LP -To run this program the standard way type: -.LP -.B # nsd\-notify \-z foobar.cz 1.2.3.4 -.SH "SEE ALSO" -.LP -nsd(8), nsdc(8), nsd.conf(5), nsd\-checkconf(8), -nsd\-patch(8), nsd\-xfer(8), nsd\-zonec(8) -.SH "AUTHORS" -.B NSD -was written by NLnet Labs and RIPE NCC joint team. Please see CREDITS -file in the distribution for further details. diff --git a/usr.sbin/nsd/nsd-notify.c b/usr.sbin/nsd/nsd-notify.c deleted file mode 100644 index 91fd591340e..00000000000 --- a/usr.sbin/nsd/nsd-notify.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * nsd-notify.c -- sends notify(rfc1996) message to a list of servers - * - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * - * See LICENSE for the license. - * - */ - -#include <config.h> - -#include <sys/types.h> -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> -#endif -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <errno.h> -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <tsig.h> -#include <unistd.h> -#include <netdb.h> - -#include "query.h" - -extern char *optarg; -extern int optind; - -/* - * Check if two getaddrinfo result lists have records with matching - * ai_family fields. - */ -int check_matching_address_family(struct addrinfo *a, struct addrinfo *b); - -/* - * Returns the first record with ai_family == FAMILY, or NULL if no - * such record is found. - */ -struct addrinfo *find_by_address_family(struct addrinfo *addrs, int family); - -/* - * Assigns pointers to hostname and port and wipes out the optional delimiter. - */ -void get_hostname_port_frm_str(char* arg, const char** hostname, - const char** port); - -/* - * Log a warning message. - */ -static void warning(const char *format, ...) ATTR_FORMAT(printf, 1, 2); -static void -warning(const char *format, ...) -{ - va_list args; - va_start(args, format); - log_vmsg(LOG_WARNING, format, args); - va_end(args); -} - -static void -usage(void) -{ - fprintf(stderr, "usage: nsd-notify [-4] [-6] [-a src[@port] [-h] [-p \ -port] [-y key:secret[:algo]] -z zone servers\n\n"); - fprintf(stderr, "Send NOTIFY to secondary servers to force a zone \ -update.\n"); - fprintf(stderr, "Version %s. Report bugs to <%s>.\n\n", - PACKAGE_VERSION, PACKAGE_BUGREPORT); - fprintf(stderr, " -4 Send using IPv4.\n"); - fprintf(stderr, " -6 Send using IPv6.\n"); - fprintf(stderr, " -a src[@port] Local hostname/ip-address for " - "the connection, including optional source port.\n"); - fprintf(stderr, " -h Print this help " - "information.\n"); - fprintf(stderr, " -p port Port number of secondary " - "server.\n"); - fprintf(stderr, " -y key:secret[:algo] TSIG keyname, base64 secret " - "blob and HMAC algorithm.\n" - " If algo is not provided, " - "HMAC-MD5 is assumed.\n"); - fprintf(stderr, " -z zone Name of zone to be updated.\n"); - fprintf(stderr, " servers IP addresses of the secondary " - "server(s).\n"); - exit(1); -} - -/* - * Send NOTIFY messages to the host, as in struct q, - * waiting for ack packet (received in buffer answer). - * Will retry transmission after a timeout. - * addrstr is the string describing the address of the host. - */ -static void -notify_host(int udp_s, struct query* q, struct query *answer, - struct addrinfo* res, const dname_type *zone, const char* addrstr) -{ - int timeout_retry = 1; /* seconds */ - int num_retry = 6; /* times to try */ - fd_set rfds; - struct timeval tv; - int retval = 0; - ssize_t received = 0; - int got_ack = 0; - socklen_t addrlen = 0; - - while(!got_ack) { - /* WE ARE READY SEND IT OUT */ - if (sendto(udp_s, - buffer_current(q->packet), - buffer_remaining(q->packet), 0, - res->ai_addr, res->ai_addrlen) == -1) { - warning("send to %s failed: %s\n", addrstr, - strerror(errno)); - close(udp_s); - return; - } - - /* wait for ACK packet */ - FD_ZERO(&rfds); - FD_SET(udp_s, &rfds); - tv.tv_sec = timeout_retry; /* seconds */ - tv.tv_usec = 0; /* microseconds */ - retval = select(udp_s + 1, &rfds, NULL, NULL, &tv); - if (retval == -1) { - warning("error waiting for reply from %s: %s\n", - addrstr, strerror(errno)); - close(udp_s); - return; - } - if (retval == 0) { - num_retry--; - if(num_retry == 0) { - warning("error: failed to send notify to %s.\n", - addrstr); - exit(1); - } - warning("timeout (%d s) expired, retry notify to %s.\n", - timeout_retry, addrstr); - } - if (retval == 1) { - got_ack = 1; - } - /* Exponential backoff */ - timeout_retry *= 2; - } - - /* receive reply */ - addrlen = res->ai_addrlen; - received = recvfrom(udp_s, buffer_begin(answer->packet), - buffer_remaining(answer->packet), 0, - res->ai_addr, &addrlen); - res->ai_addrlen = addrlen; - - if (received == -1) { - warning("recv %s failed: %s\n", addrstr, strerror(errno)); - } else { - /* check the answer */ - if ((ID(q->packet) == ID(answer->packet)) && - (OPCODE(answer->packet) == OPCODE_NOTIFY) && - AA(answer->packet) && - QR(answer->packet) && (RCODE(answer->packet) == RCODE_OK)) { - /* no news is good news */ - /* info("reply from: %s, acknowledges notify.\n", - addrstr); */ - } else { - warning("bad reply from %s for zone %s, error response %s (%d).\n", - addrstr, dname_to_string(zone, NULL), rcode2str(RCODE(answer->packet)), - RCODE(answer->packet)); - } - } - close(udp_s); -} - -static tsig_key_type* -add_key(region_type* region, const char* opt, tsig_algorithm_type** algo) -{ - /* parse -y key:secret_base64 format option */ - char* delim = strchr(opt, ':'); - char* delim2 = NULL; - tsig_key_type *key = (tsig_key_type*)region_alloc( - region, sizeof(tsig_key_type)); - size_t len; - int sz; - - if (delim) { - delim2 = strchr(delim+1, ':'); - } - - if(!key) { - log_msg(LOG_ERR, "region_alloc failed (add_key)"); - return 0; - } - - if(!delim) { - log_msg(LOG_ERR, "bad key syntax %s", opt); - return 0; - } - *delim = '\0'; - key->name = dname_parse(region, opt); - if(!key->name) { - log_msg(LOG_ERR, "bad key name %s", opt); - return 0; - } - *delim = ':'; - - if (!delim2) - *algo = tsig_get_algorithm_by_name("hmac-md5"); - else { - char* by_name = (char*) malloc(sizeof(char)*(5+strlen(delim2))); - snprintf(by_name, 5+strlen(delim2), "%s", delim2+1); - *algo = tsig_get_algorithm_by_name(by_name); - free(by_name); - *delim2 = '\0'; - } - - if (!(*algo)) { - log_msg(LOG_ERR, "bad tsig algorithm %s", opt); - return 0; - } - - len = strlen(delim+1); - key->data = region_alloc(region, len+1); - if(!key->data) { - log_msg(LOG_ERR, "region_alloc failed (add_key, key->data)"); - return 0; - } - sz= b64_pton(delim+1, (uint8_t*)key->data, len); - if(sz == -1) { - log_msg(LOG_ERR, "bad key syntax %s", opt); - return 0; - } - key->size = sz; - tsig_add_key(key); - return key; -} - -int -main (int argc, char *argv[]) -{ - int c, udp_s; - struct query q; - struct query answer; - const dname_type *zone = NULL; - struct addrinfo hints, *res0, *res; - int error; - int default_family = DEFAULT_AI_FAMILY; - const char *local_hostname = NULL; - struct addrinfo *local_address, *local_addresses = NULL; - const char *port = UDP_PORT; - const char *local_port = NULL; - region_type *region = region_create(xalloc, free); - tsig_key_type *tsig_key = 0; - tsig_record_type tsig; - tsig_algorithm_type* algo = NULL; - - log_init("nsd-notify"); - if(!tsig_init(region)) { - log_msg(LOG_ERR, "could not init tsig\n"); - exit(1); - } - - srandom((unsigned long) getpid() * (unsigned long) time(NULL)); - - /* Parse the command line... */ - while ((c = getopt(argc, argv, "46a:hp:y:z:")) != -1) { - switch (c) { - case '4': - default_family = AF_INET; - break; - case '6': -#ifdef INET6 - default_family = AF_INET6; - break; -#else /* !INET6 */ - log_msg(LOG_ERR, "IPv6 support not enabled\n"); - exit(1); -#endif /* !INET6 */ - case 'a': - get_hostname_port_frm_str((char *) optarg, - &local_hostname, &local_port); - break; - case 'p': - port = optarg; - break; - case 'y': - if (!(tsig_key = add_key(region, optarg, &algo))) - exit(1); - break; - case 'z': - zone = dname_parse(region, optarg); - if (!zone) { - log_msg(LOG_ERR, - "incorrect domain name '%s'", - optarg); - exit(1); - } - break; - case 'h': - default: - usage(); - } - } - argc -= optind; - argv += optind; - - if (argc == 0 || zone == NULL) { - usage(); - } - - /* Initialize the query */ - memset(&q, 0, sizeof(struct query)); - q.addrlen = sizeof(q.addr); - q.maxlen = 512; - q.packet = buffer_create(region, QIOBUFSZ); - memset(buffer_begin(q.packet), 0, buffer_remaining(q.packet)); - - /* Set up the header */ - OPCODE_SET(q.packet, OPCODE_NOTIFY); - ID_SET(q.packet, qid_generate()); - AA_SET(q.packet); - QDCOUNT_SET(q.packet, 1); - buffer_skip(q.packet, QHEADERSZ); - buffer_write(q.packet, dname_name(zone), zone->name_size); - buffer_write_u16(q.packet, TYPE_SOA); - buffer_write_u16(q.packet, CLASS_IN); - if(tsig_key) { - assert(algo); - tsig_create_record(&tsig, region); - tsig_init_record(&tsig, algo, tsig_key); - tsig_init_query(&tsig, ID(q.packet)); - tsig_prepare(&tsig); - tsig_update(&tsig, q.packet, buffer_position(q.packet)); - tsig_sign(&tsig); - tsig_append_rr(&tsig, q.packet); - ARCOUNT_SET(q.packet, ARCOUNT(q.packet) + 1); - } - buffer_flip(q.packet); - - /* initialize buffer for ack */ - memset(&answer, 0, sizeof(struct query)); - answer.addrlen = sizeof(answer.addr); - answer.maxlen = 512; - answer.packet = buffer_create(region, QIOBUFSZ); - memset(buffer_begin(answer.packet), 0, buffer_remaining(answer.packet)); - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = default_family; - hints.ai_socktype = SOCK_DGRAM; - hints.ai_protocol = IPPROTO_UDP; - - if (local_hostname) { - int rc = getaddrinfo(local_hostname, local_port, - &hints, &local_addresses); - if (rc) { - warning("local hostname '%s' not found: %s", - local_hostname, gai_strerror(rc)); - } - } - - for (/*empty*/; *argv; argv++) { - error = getaddrinfo(*argv, port, &hints, &res0); - if (error) { - warning("skipping bad address %s: %s\n", *argv, - gai_strerror(error)); - continue; - } - - if (local_addresses - && !check_matching_address_family(res0, local_addresses)) - { - warning("no local address family matches remote " - "address family, skipping server '%s'", - *argv); - continue; - } - - for (res = res0; res; res = res->ai_next) { - if (res->ai_addrlen > (socklen_t)sizeof(q.addr)) { - continue; - } - - /* - * If a local address is specified, use an - * address with the same family as the remote - * address. - */ - local_address = find_by_address_family(local_addresses, - res->ai_family); - if (local_addresses && !local_address) { - /* Continue with next remote address. */ - continue; - } - - udp_s = socket(res->ai_family, res->ai_socktype, - res->ai_protocol); - if (udp_s == -1) { - warning("cannot create socket: %s\n", - strerror(errno)); - continue; - } - - /* Bind socket to local address, if required. */ - if (local_address && bind(udp_s, - local_address->ai_addr, - local_address->ai_addrlen) < 0) - { - warning("cannot bind to %s: %s\n", - local_hostname, strerror(errno)); - } - - memcpy(&q.addr, res->ai_addr, res->ai_addrlen); - notify_host(udp_s, &q, &answer, res, zone, *argv); - } - freeaddrinfo(res0); - } - exit(0); -} - -void -get_hostname_port_frm_str(char* arg, const char** hostname, - const char** port) -{ - /* parse -a src[@port] option */ - char* delim = strchr(arg, '@'); - - if (delim) { - *delim = '\0'; - *port = delim+1; - } - *hostname = arg; -} - - -int -check_matching_address_family(struct addrinfo *a0, struct addrinfo *b0) -{ - struct addrinfo *a; - struct addrinfo *b; - - for (a = a0; a; a = a->ai_next) { - for (b = b0; b; b = b->ai_next) { - if (a->ai_family == b->ai_family) { - return 1; - } - } - } - return 0; -} - -struct addrinfo * -find_by_address_family(struct addrinfo *addrs, int family) -{ - for (; addrs; addrs = addrs->ai_next) { - if (addrs->ai_family == family) { - return addrs; - } - } - return NULL; -} - diff --git a/usr.sbin/nsd/nsd-patch.8.in b/usr.sbin/nsd/nsd-patch.8.in deleted file mode 100644 index 087f4be7617..00000000000 --- a/usr.sbin/nsd/nsd-patch.8.in +++ /dev/null @@ -1,69 +0,0 @@ -.TH "nsd\-patch" "8" "Jul 22, 2013" "NLnet Labs" "nsd 3.2.16" -.\" Copyright (c) 2001\-2011, NLnet Labs. All rights reserved. -.\" See LICENSE for the license. -.SH "NAME" -.LP -.B nsd\-patch -\- NSD zone patcher version 3.2.16. -.SH "SYNOPSIS" -.B nsd\-patch -.RB [ \-c -.IR configfile ] -.RB [ \-f ] -.RB [ \-h ] -.RB [ \-l ] -.RB [ \-o -.IR dbfile ] -.RB [ \-s ] -.RB [ \-x -.IR difffile ] -.SH "DESCRIPTION" -.LP -.B Nsd\-patch -is the zone patcher for nsd(8). It reads in the nsd database -(nsd.db) and difffile (ixfr.db), and overwrites the zone text files -if they have been updated. Running this regularly ensures that the -difffile does not grow infinitely. -.SH "OPTIONS" -.TP -.B \-c\fI configfile -Read specified configfile instead of the default -.IR @nsdconfigfile@ . -.TP -.B \-f -Forces writing zone files. Also zones that have not changed are written -back to their zone files. -.TP -.B \-h -Print usage help information and exit. -.TP -.B \-l -List the journal entries from the difffile. Does not write to zone files. -.TP -.B \-o\fI dbfile -Store the output directly to dbfile. -.TP -.B \-s -Skip writing zone files. No zones are written back to their zone files. -.TP -.B \-x\fI difffile -Read specified difffile. Overrides the config file setting. -.SH "FILES" -.TP -@dbfile@ -default -.B NSD -database -.TP -@nsdconfigfile@ -default -.B NSD -configuration file -.SH "SEE ALSO" -nsd(8), nsdc(8), nsd.conf(5), nsd-checkconf(8), nsd-notify(8), -nsd-xfer(8), nsd\-zonec(8) -.SH "AUTHORS" -.LP -.B NSD -was written by NLnet Labs and RIPE NCC joint team. Please see -CREDITS file in the distribution for further details. diff --git a/usr.sbin/nsd/nsd-patch.c b/usr.sbin/nsd/nsd-patch.c deleted file mode 100644 index 6b722122291..00000000000 --- a/usr.sbin/nsd/nsd-patch.c +++ /dev/null @@ -1,430 +0,0 @@ -/* - * nsd-patch - read database and ixfrs and patch up zone files. - * - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * - * See LICENSE for the license. - * - */ -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include "options.h" -#include "difffile.h" -#include "namedb.h" -#include "util.h" - -extern char *optarg; -extern int optind; - -static void -usage(void) -{ - fprintf(stderr, "usage: nsd-patch [options]\n"); - fprintf(stderr, " Reads database and ixfrs and patches up zone files.\n"); - fprintf(stderr, " Version %s. Report bugs to <%s>.\n\n", PACKAGE_VERSION, PACKAGE_BUGREPORT); - fprintf(stderr, "-c configfile Specify config file to use, instead of %s\n", CONFIGFILE); - fprintf(stderr, "-f Force writing of zone files.\n"); - fprintf(stderr, "-h Print this help information.\n"); - fprintf(stderr, "-l List contents of transfer journal difffile, %s\n", DIFFFILE); - fprintf(stderr, "-o dbfile Specify dbfile to output the result " - "directly to dbfile, nsd.db.\n"); - fprintf(stderr, "-s Skip writing of zone files.\n"); - fprintf(stderr, "-x difffile Specify diff file to use, instead of diff file from config.\n"); - exit(1); -} - -static void -list_xfr(FILE *in) -{ - uint32_t timestamp[2]; - uint32_t skiplen, len, new_serial; - char zone_name[3072]; - uint16_t id; - uint32_t seq_nr, len2; - - if(!diff_read_32(in, ×tamp[0]) || - !diff_read_32(in, ×tamp[1]) || - !diff_read_32(in, &len) || - !diff_read_str(in, zone_name, sizeof(zone_name)) || - !diff_read_32(in, &new_serial) || - !diff_read_16(in, &id) || - !diff_read_32(in, &seq_nr)) { - fprintf(stderr, "incomplete zone transfer content packet\n"); - return; - } - skiplen = len - (sizeof(uint32_t)*3 + sizeof(uint16_t) + strlen(zone_name)); - fprintf(stdout, "zone %s transfer id %x serial %u timestamp %u.%u: " - "seq_nr %d of %d bytes\n", zone_name, id, new_serial, - timestamp[0], timestamp[1], seq_nr, skiplen); - - if(fseeko(in, skiplen, SEEK_CUR) == -1) - fprintf(stderr, "fseek failed: %s\n", strerror(errno)); - - if(!diff_read_32(in, &len2)) { - fprintf(stderr, "incomplete zone transfer content packet\n"); - return; - } - if(len != len2) { - fprintf(stderr, "packet seq %d had bad length check bytes!\n", - seq_nr); - } -} - -static const char* -get_date(const char* log) -{ - const char *entry = strstr(log, " time "); - time_t t = 0; - static char timep[30]; - if(!entry) return "<notime>"; - t = strtol(entry + 6, NULL, 10); - if(t == 0) return "0"; - timep[0]=0; - strlcpy(timep, ctime(&t), sizeof(timep)); - /* remove newline at end */ - if(strlen(timep) > 0 && timep[strlen(timep)-1]=='\n') - timep[strlen(timep)-1] = 0; - return timep; -} - -static void -list_commit(FILE *in) -{ - uint32_t timestamp[2]; - uint32_t len; - char zone_name[3072]; - uint32_t old_serial, new_serial; - uint16_t id; - uint32_t num; - uint8_t commit; - char log_msg[10240]; - uint32_t len2; - - if(!diff_read_32(in, ×tamp[0]) || - !diff_read_32(in, ×tamp[1]) || - !diff_read_32(in, &len) || - !diff_read_str(in, zone_name, sizeof(zone_name)) || - !diff_read_32(in, &old_serial) || - !diff_read_32(in, &new_serial) || - !diff_read_16(in, &id) || - !diff_read_32(in, &num) || - !diff_read_8(in, &commit) || - !diff_read_str(in, log_msg, sizeof(log_msg)) || - !diff_read_32(in, &len2)) { - fprintf(stderr, "incomplete commit/rollback packet\n"); - return; - } - fprintf(stdout, "zone %s transfer id %x serial %d: %s of %d packets\n", - zone_name, id, new_serial, commit?"commit":"rollback", num); - fprintf(stdout, " time %s, from serial %d, log message: %s\n", - get_date(log_msg), old_serial, log_msg); - if(len != len2) { - fprintf(stderr, " commit packet with bad length check \ - bytes!\n"); - } -} - -static void -debug_list(struct nsd_options* opt) -{ - const char* file = opt->difffile; - FILE *f; - uint32_t type; - fprintf(stdout, "debug listing of the contents of %s\n", file); - f = fopen(file, "r"); - if(!f) { - fprintf(stderr, "error opening %s: %s\n", file, - strerror(errno)); - return; - } - while(diff_read_32(f, &type)) { - switch(type) { - case DIFF_PART_IXFR: - list_xfr(f); - break; - case DIFF_PART_SURE: - list_commit(f); - break; - default: - fprintf(stderr, "bad part of type %x\n", type); - break; - } - } - - fclose(f); -} - -static int -exist_difffile(struct nsd_options* opt) -{ - /* see if diff file exists */ - const char* file = opt->difffile; - FILE *f; - - f = fopen(file, "r"); - if(!f) { - if(errno == ENOENT) - return 0; - fprintf(stderr, "could not open file %s: %s\n", - file, strerror(errno)); - return 0; - } - fclose(f); - return 1; -} - -static void -print_rrs(FILE* out, struct zone* zone) -{ - rrset_type *rrset; - domain_type *domain = zone->apex; - region_type* region = region_create(xalloc, free); - struct state_pretty_rr* state = create_pretty_rr(region); - /* first print the SOA record for the zone */ - if(zone->soa_rrset) { - size_t i; - for(i=0; i < zone->soa_rrset->rr_count; i++) { - if(!print_rr(out, state, &zone->soa_rrset->rrs[i])){ - fprintf(stderr, "There was an error " - "printing SOARR to zone %s\n", - zone->opts->name); - } - } - } - /* go through entire tree below the zone apex (incl subzones) */ - while(domain && dname_is_subdomain( - domain_dname(domain), domain_dname(zone->apex))) - { - for(rrset = domain->rrsets; rrset; rrset=rrset->next) - { - size_t i; - if(rrset->zone != zone || rrset == zone->soa_rrset) - continue; - for(i=0; i < rrset->rr_count; i++) { - if(!print_rr(out, state, &rrset->rrs[i])){ - fprintf(stderr, "There was an error " - "printing RR to zone %s\n", - zone->opts->name); - } - } - } - domain = domain_next(domain); - } - region_destroy(region); -} - -static void -print_commit_log(FILE* out, const dname_type* zone, struct diff_log* commit_log) -{ - struct diff_log* p = commit_log; - region_type* region = region_create(xalloc, free); - while(p) - { - const dname_type* dname = dname_parse(region, p->zone_name); - if(dname_compare(dname, zone) == 0) - { - fprintf(out, "; commit"); - if(p->error) - fprintf(out, "(%s)", p->error); - fprintf(out, ": %s\n", p->comment); - } - p = p->next; - } - region_destroy(region); -} - -static void -write_to_zonefile(struct zone* zone, struct diff_log* commit_log) -{ - const char* filename = zone->opts->zonefile; - time_t now = time(0); - FILE *out; - - fprintf(stdout, "writing zone %s to file %s\n", zone->opts->name, - filename); - - if(!zone->apex) { - fprintf(stderr, "zone %s has no apex, no data.\n", filename); - return; - } - - out = fopen(filename, "w"); - if(!out) { - fprintf(stderr, "cannot open or create file %s for writing: %s\n", - filename, strerror(errno)); - return; - } - - /* print zone header */ - fprintf(out, "; NSD version %s\n", PACKAGE_VERSION); - fprintf(out, "; nsd-patch zone %s run at time %s", - zone->opts->name, ctime(&now)); - print_commit_log(out, domain_dname(zone->apex), commit_log); - - print_rrs(out, zone); - - fclose(out); -} - -int main(int argc, char* argv[]) -{ - int c; - const char* configfile = CONFIGFILE; - const char* difffile = NULL; - const char* dbfile = NULL; - nsd_options_t *options; - struct namedb* db = NULL; - struct namedb* dbout = NULL; - struct zone* zone; - struct diff_log* commit_log = 0; - size_t fake_child_count = 1; - int debug_list_diff = 0; - int force_write = 0; - int skip_write = 0; - int difffile_exists = 0; - - /* Parse the command line... */ - while ((c = getopt(argc, argv, "c:fhlo:sx:")) != -1) { - switch (c) { - case 'c': - configfile = optarg; - break; - case 'l': - debug_list_diff = 1; - break; - case 'f': - if (skip_write) - { - fprintf(stderr, "Cannot force and skip writing " - "zonefiles at the same time\n"); - exit(1); - } - else - force_write = 1; - break; - case 's': - if (force_write) - { - fprintf(stderr, "Cannot skip and force writing " - "zonefiles at the same time\n"); - exit(1); - } - else - skip_write = 1; - break; - case 'o': - dbfile = optarg; - break; - case 'x': - difffile = optarg; - break; - case 'h': - default: - usage(); - }; - } - argc -= optind; - argv += optind; - if (argc != 0) - usage(); - - /* read config file */ - log_init("nsd-patch"); - options = nsd_options_create(region_create(xalloc, free)); - if(!parse_options_file(options, configfile)) { - fprintf(stderr, "Could not read config: %s\n", configfile); - exit(1); - } - if(options->zonesdir && options->zonesdir[0]) { - if (chdir(options->zonesdir)) { - fprintf(stderr, "nsd-patch: cannot chdir to %s: %s\n", - options->zonesdir, strerror(errno)); - exit(1); - } - } - - /* override difffile if commandline option given */ - if(difffile) - options->difffile = difffile; - - /* see if necessary */ - if(!exist_difffile(options)) { - fprintf(stderr, "No diff file.\n"); - if (!force_write) - exit(0); - } - else difffile_exists = 1; - - if(debug_list_diff) { - debug_list(options); - exit(0); - } - - /* read database and diff file */ - fprintf(stdout, "reading database\n"); - db = namedb_open(options->database, options, fake_child_count); - if(!db) { - fprintf(stderr, "could not read database: %s\n", - options->database); - exit(1); - } - - /* set all updated to 0 so we know what has changed */ - for(zone = db->zones; zone; zone = zone->next) - { - zone->updated = 0; - } - - if (dbfile) - dbout = namedb_new(dbfile); - if (dbout) - { - db->fd = dbout->fd; - db->filename = (char*) dbfile; - } - - /* read ixfr diff file */ - if (difffile_exists) { - fprintf(stdout, "reading updates to database\n"); - if(!diff_read_file(db, options, &commit_log, fake_child_count)) - { - fprintf(stderr, "unable to load the diff file: %s\n", - options->difffile); - exit(1); - } - } - - if (skip_write) - fprintf(stderr, "skip patching up zonefiles.\n"); - else { - fprintf(stdout, "writing changed zones\n"); - for(zone = db->zones; zone; zone = zone->next) - { - if(!force_write && !zone->updated) { - fprintf(stdout, "zone %s had not changed.\n", - zone->opts->name); - continue; - } - /* write zone to its zone file */ - write_to_zonefile(zone, commit_log); - } - } - - /* output result directly to dbfile */ - if (dbout) - { - fprintf(stdout, "storing database to %s.\n", dbout->filename); - if (namedb_save(db) != 0) { - fprintf(stderr, "error writing the database (%s): %s\n", - dbfile, strerror(errno)); - exit(1); - } - } - fprintf(stdout, "done\n"); - - return 0; -} diff --git a/usr.sbin/nsd/nsd-xfer.8.in b/usr.sbin/nsd/nsd-xfer.8.in deleted file mode 100644 index 16c833e010a..00000000000 --- a/usr.sbin/nsd/nsd-xfer.8.in +++ /dev/null @@ -1,83 +0,0 @@ -.TH "nsd\-xfer" "8" "Jul 22, 2013" "NLnet Labs" "nsd 3.2.16" -.\" Copyright (c) 2001\-2011, NLnet Labs. All rights reserved. -.\" See LICENSE for the license. -.SH "NAME" -.LP -.B nsd\-xfer -\- AXFR client to transfer zones from a name server -.SH "SYNOPSIS" -.LP -.B nsd\-xfer -.RB [ \-4 ] -.RB [ \-6 ] -.RB [ \-a -.IR address[@port] ] -.RB [ \-p -.IR port ] -.RB [ \-s -.IR serial ] -.RB [ \-T -.IR tsiginfo ] -.RB [ \-v ] -.B \-z -.I zone -.B \-f -.I file -.I servers -.SH "DESCRIPTION" -.LP -.B Nsd\-xfer -is program to transfer zones from a name server using AXFR. -.B NSD -is a complete implementation of an authoritative DNS nameserver. -.SH "OPTIONS" -.LP -.TP -.B \-4 -Only send to IPv4 addresses. -.TP -.B \-6 -Only send to IPv6 addresses. -.TP -.B \-a\fI address[@port] -Specify the source address (and port) to send from. -.TP -.B \-f\fI file -The file to store the zone in. -.TP -.B \-p\fI port -Specify the port to send to. -.TP -.B \-s\fI serial -Specify the serial of the current zone. The zone is only transferred -if the master server has a zone with a greater serial number. -.TP -.B \-T\fI tsiginfo -Use TSIG to verify the zone transfer. The -.I tsiginfo -file must contain the TSIG key information. The file is removed -upon successful reading of the key. The format of the tsiginfo file -is described in the doc/README file (section 3.3). -.TP -.B \-v -Be more verbose. -.TP -.B \-z\fI zone -Specify the zone to receive. -.TP -.I servers -List of nameservers to try. -.SH "EXAMPLES" -.LP -To run this program the standard way type: -.LP -# nsd\-xfer \-z foobar.cz \-f foobar.cz.zone 1.2.3.4 -.SH "SEE ALSO" -.LP -nsd(8), nsdc(8), nsd.conf(5), nsd-checkconf(8), -nsd-notify(8), nsd-patch(8), nsd\-zonec(8) -.SH "AUTHORS" -.LP -.B NSD -was written by NLnet Labs and RIPE NCC joint team. Please see CREDITS -file in the distribution for further details. diff --git a/usr.sbin/nsd/nsd-xfer.c b/usr.sbin/nsd/nsd-xfer.c deleted file mode 100644 index 1d91993b10a..00000000000 --- a/usr.sbin/nsd/nsd-xfer.c +++ /dev/null @@ -1,1087 +0,0 @@ -/* - * nsd-xfer.c -- nsd-xfer(8). - * - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * - * See LICENSE for the license. - * - */ - -#include <config.h> - -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <limits.h> -#include <assert.h> -#include <errno.h> -#include <netdb.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -#include <unistd.h> - -#include "dname.h" -#include "dns.h" -#include "packet.h" -#include "query.h" -#include "region-allocator.h" -#include "tsig.h" -#include "tsig-openssl.h" -#include "util.h" - - -/* - * Number of seconds to wait when recieving no data from the remote - * server. - */ -#define MAX_WAITING_TIME TCP_TIMEOUT - -/* - * Exit codes are based on named-xfer for now. See ns_defs.h in - * bind8. - */ -#define XFER_UPTODATE 0 -#define XFER_SUCCESS 1 -#define XFER_FAIL 3 - -struct axfr_state -{ - int verbose; - size_t packets_received; - size_t bytes_received; - - int s; /* AXFR socket. */ - query_type *q; /* Query buffer. */ - uint16_t query_id; /* AXFR query ID. */ - tsig_record_type *tsig; /* TSIG data. */ - - int first_transfer; /* First transfer of this zone. */ - uint32_t last_serial; /* Otherwise the last serial. */ - uint32_t zone_serial; /* And the new zone serial. */ - const dname_type *zone; /* Zone name. */ - - int done; /* AXFR is complete. */ - size_t rr_count; /* Number of RRs received so far. */ - - /* - * Region used to allocate data needed to process a single RR. - */ - region_type *rr_region; - - /* - * Region used to store owner and origin of previous RR (used - * for pretty printing of zone data). - */ - struct state_pretty_rr *pretty_rr; -}; -typedef struct axfr_state axfr_state_type; - -static sig_atomic_t timeout_flag = 0; -static void to_alarm(int sig); /* our alarm() signal handler */ - -extern char *optarg; -extern int optind; - -static uint16_t init_query(query_type *q, - const dname_type *dname, - uint16_t type, - uint16_t klass, - tsig_record_type *tsig); - - -/* - * Check if two getaddrinfo result lists have records with matching - * ai_family fields. - */ -int check_matching_address_family(struct addrinfo *a, struct addrinfo *b); - -/* - * Returns the first record with ai_family == FAMILY, or NULL if no - * such record is found. - */ -struct addrinfo *find_by_address_family(struct addrinfo *addrs, int family); - -/* - * Assigns pointers to hostname and port and wipes out the optional delimiter. - */ -void get_hostname_port_frm_str(char* arg, const char** hostname, - const char** port); - -/* - * Log an error message and exit. - */ -static void error(const char *format, ...) ATTR_FORMAT(printf, 1, 2); -static void -error(const char *format, ...) -{ - va_list args; - va_start(args, format); - log_vmsg(LOG_ERR, format, args); - va_end(args); - exit(XFER_FAIL); -} - - -/* - * Log a warning message. - */ -static void warning(const char *format, ...) ATTR_FORMAT(printf, 1, 2); -static void -warning(const char *format, ...) -{ - va_list args; - va_start(args, format); - log_vmsg(LOG_WARNING, format, args); - va_end(args); -} - - -/* - * Display usage information and exit. - */ -static void -usage (void) -{ - fprintf(stderr, - "Usage: nsd-xfer [OPTION]... -z zone -f file server...\n" - "NSD AXFR client.\n\nSupported options:\n" - " -4 Only use IPv4 connections.\n" - " -6 Only use IPv6 connections.\n" - " -a src[@port] Local hostname/ip-address for the \ -connection, including optional source port.\n" - " -f file Output zone file name.\n" - " -p port The port to connect to.\n" - " -s serial The current zone serial.\n" - " -T tsiginfo The TSIG key file name. The file is removed " - "after reading the\n key.\n" - " -v Verbose output.\n"); - fprintf(stderr, - " -z zone Specify the name of the zone to transfer.\n" - " server The name or IP address of the master server.\n" - "\nVersion %s. Report bugs to <%s>.\n", PACKAGE_VERSION, PACKAGE_BUGREPORT); - exit(XFER_FAIL); -} - - -/* - * Find an HMAC algorithm based on its id. - */ -static tsig_algorithm_type * -tsig_get_algorithm_by_id(uint8_t alg) -{ - if (alg == TSIG_HMAC_MD5) - return tsig_get_algorithm_by_name("hmac-md5"); -#ifdef HAVE_EVP_SHA1 - if (alg == TSIG_HMAC_SHA1) - return tsig_get_algorithm_by_name("hmac-sha1"); -#endif /* HAVE_EVP_SHA1 */ -#ifdef HAVE_EVP_SHA256 - if (alg == TSIG_HMAC_SHA256) - return tsig_get_algorithm_by_name("hmac-sha256"); -#endif /* HAVE_EVP_SHA256 */ - - return NULL; -} - - -/* - * Signal handler for timeouts (SIGALRM). This function is called when - * the alarm() value that was set counts down to zero. This indicates - * that we haven't received a response from the server. - * - * All we do is set a flag and return from the signal handler. The - * occurrence of the signal interrupts the read() system call (errno - * == EINTR) above, and we then check the timeout_flag flag. - */ -static void -to_alarm(int ATTR_UNUSED(sig)) -{ - timeout_flag = 1; -} - -/* - * Read a line from IN. If successful, the line is stripped of - * leading and trailing whitespace and non-zero is returned. - */ -static int -tsig_read_line(FILE *in, char *line, size_t size) -{ - if (!fgets(line, size, in)) { - return 0; - } else { - strip_string(line); - return 1; - } -} - -static tsig_key_type * -read_tsig_key_data(region_type *region, FILE *in, - int ATTR_UNUSED(default_family), tsig_algorithm_type** tsig_algo) -{ - char line[4000]; - tsig_key_type *key = (tsig_key_type *) region_alloc( - region, sizeof(tsig_key_type)); - int size; - uint8_t algo = 0; - uint8_t data[4000]; - - /* server address */ - if (!tsig_read_line(in, line, sizeof(line))) { - error("failed to read TSIG key server address: '%s'", - strerror(errno)); - return NULL; - } - /* server address unused */ - - /* tsig keyname */ - if (!tsig_read_line(in, line, sizeof(line))) { - error("failed to read TSIG key name: '%s'", strerror(errno)); - return NULL; - } - - key->name = dname_parse(region, line); - if (!key->name) { - error("failed to parse TSIG key name '%s'", line); - return NULL; - } - - /* tsig algorithm */ - if (!tsig_read_line(in, line, sizeof(line))) { - error("failed to read TSIG key algorithm: '%s'", strerror(errno)); - return NULL; - } - algo = (uint8_t) atoi((const char*) line); - *tsig_algo = tsig_get_algorithm_by_id(algo); - if (*tsig_algo == NULL) { - error("failed to parse TSIG key algorithm %i: '%s'\n", algo, strerror(errno)); - return NULL; - } - - /* tsig secret */ - if (!tsig_read_line(in, line, sizeof(line))) { - error("failed to read TSIG key data: '%s'\n", strerror(errno)); - return NULL; - } - - size = b64_pton(line, data, sizeof(data)); - if (size == -1) { - error("failed to parse TSIG key data"); - return NULL; - } - - key->size = size; - key->data = (uint8_t *) region_alloc_init(region, data, key->size); - - return key; -} - -/* - * Read the TSIG key from a .tsiginfo file and remove the file. - */ -static tsig_key_type * -read_tsig_key(region_type *region, - const char *tsiginfo_filename, - int default_family, tsig_algorithm_type** algo) -{ - FILE *in; - tsig_key_type *key; - - in = fopen(tsiginfo_filename, "r"); - if (!in) { - error("failed to open %s: %s", - tsiginfo_filename, - strerror(errno)); - return NULL; - } - - key = read_tsig_key_data(region, in, default_family, algo); - - fclose(in); - - if (unlink(tsiginfo_filename) == -1) { - warning("failed to remove %s: %s", - tsiginfo_filename, - strerror(errno)); - } - - return key; -} - -/* - * Read SIZE bytes from the socket into BUF. Keep reading unless an - * error occurs (except for EAGAIN) or EOF is reached. - */ -static int -read_socket(int s, void *buf, size_t size) -{ - char *data = (char *) buf; - size_t total_count = 0; - - while (total_count < size) { - ssize_t count = read(s, data + total_count, size - total_count); - if (count == -1) { - /* Error or interrupt. */ - if (errno != EAGAIN) { - error("network read failed: %s", - strerror(errno)); - return 0; - } else { - continue; - } - } else if (count == 0) { - /* End of file (connection closed?) */ - error("network read failed: Connection closed by peer"); - return 0; - } - total_count += count; - } - - return 1; -} - -static int -parse_response(FILE *out, axfr_state_type *state) -{ - size_t rr_count; - size_t qdcount = QDCOUNT(state->q->packet); - size_t ancount = ANCOUNT(state->q->packet); - - /* Skip question section. */ - for (rr_count = 0; rr_count < qdcount; ++rr_count) { - if (!packet_skip_rr(state->q->packet, 1)) { - error("bad RR in question section"); - return 0; - } - } - - /* Read RRs from answer section and print them. */ - for (rr_count = 0; rr_count < ancount; ++rr_count) { - domain_table_type *owners - = domain_table_create(state->rr_region); - rr_type *record = packet_read_rr( - state->rr_region, owners, state->q->packet, 0); - if (!record) { - error("bad RR in answer section"); - return 0; - } - - if (state->rr_count == 0 - && (record->type != TYPE_SOA || record->klass != CLASS_IN)) - { - error("First RR must be the SOA record, but is a %s record", - rrtype_to_string(record->type)); - return 0; - } else if (state->rr_count > 0 - && record->type == TYPE_SOA - && record->klass == CLASS_IN) - { - state->done = 1; - return 1; - } - - ++state->rr_count; - - if (!print_rr(out, state->pretty_rr, record)) { - return 0; - } - - region_free_all(state->rr_region); - } - - return 1; -} - -static int -send_query(int s, query_type *q) -{ - uint16_t size = htons(buffer_remaining(q->packet)); - - if (!write_socket(s, &size, sizeof(size))) { - error("network write failed: %s", strerror(errno)); - return 0; - } - if (!write_socket(s, buffer_begin(q->packet), buffer_limit(q->packet))) - { - error("network write failed: %s", strerror(errno)); - return 0; - } - return 1; -} - -static int -receive_response_no_timeout(axfr_state_type *state) -{ - uint16_t size; - - buffer_clear(state->q->packet); - if (!read_socket(state->s, &size, sizeof(size))) { - return 0; - } - size = ntohs(size); - if (size > state->q->maxlen) { - error("response size (%d) exceeds maximum (%d)", - (int) size, (int) state->q->maxlen); - return 0; - } - if (!read_socket(state->s, buffer_begin(state->q->packet), size)) { - return 0; - } - - buffer_set_position(state->q->packet, size); - - ++state->packets_received; - state->bytes_received += sizeof(size) + size; - - return 1; -} - -static int -receive_response(axfr_state_type *state) -{ - int result; - - timeout_flag = 0; - alarm(MAX_WAITING_TIME); - result = receive_response_no_timeout(state); - alarm(0); - if (!result && timeout_flag) { - error("timeout reading response, server unreachable?"); - } - - return result; -} - -static int -check_response_tsig(query_type *q, tsig_record_type *tsig) -{ - if (!tsig) - return 1; - - if (!tsig_find_rr(tsig, q->packet)) { - error("error parsing response"); - return 0; - } - if (tsig->status == TSIG_NOT_PRESENT) { - if (tsig->response_count == 0) { - error("required TSIG not present"); - return 0; - } - if (tsig->updates_since_last_prepare > 100) { - error("too many response packets without TSIG"); - return 0; - } - tsig_update(tsig, q->packet, buffer_limit(q->packet)); - return 1; - } - - ARCOUNT_SET(q->packet, ARCOUNT(q->packet) - 1); - - if (tsig->status == TSIG_ERROR) { - error("TSIG record is not correct"); - return 0; - } else if (tsig->error_code != TSIG_ERROR_NOERROR) { - error("TSIG error code: %s", - tsig_error(tsig->error_code)); - return 0; - } else { - tsig_update(tsig, q->packet, tsig->position); - if (!tsig_verify(tsig)) { - error("TSIG record did not authenticate"); - return 0; - } - tsig_prepare(tsig); - } - - return 1; -} - - -/* - * Query the server for the zone serial. Return 1 if the zone serial - * is higher than the current serial, 0 if the zone serial is lower or - * equal to the current serial, and -1 on error. - * - * On success, the zone serial is returned in ZONE_SERIAL. - */ -static int -check_serial(axfr_state_type *state) -{ - region_type *local; - uint16_t query_id; - uint16_t i; - domain_table_type *owners; - - query_id = init_query( - state->q, state->zone, TYPE_SOA, CLASS_IN, state->tsig); - - if (!send_query(state->s, state->q)) { - return -1; - } - - if (state->tsig) { - /* Prepare for checking responses. */ - tsig_prepare(state->tsig); - } - - if (!receive_response(state)) { - return -1; - } - buffer_flip(state->q->packet); - - if (buffer_limit(state->q->packet) <= QHEADERSZ) { - error("response size (%d) is too small", - (int) buffer_limit(state->q->packet)); - return -1; - } - - if (!QR(state->q->packet)) { - error("response is not a response"); - return -1; - } - - if (TC(state->q->packet)) { - error("response is truncated"); - return -1; - } - - if (ID(state->q->packet) != query_id) { - error("bad response id (%d), expected (%d)", - (int) ID(state->q->packet), (int) query_id); - return -1; - } - - if (RCODE(state->q->packet) != RCODE_OK) { - error("error response %d (%s)", (int) RCODE(state->q->packet), - rcode2str((int) RCODE(state->q->packet))); - return -1; - } - - if (QDCOUNT(state->q->packet) != 1) { - error("question section count not equal to 1"); - return -1; - } - - if (ANCOUNT(state->q->packet) == 0) { - error("answer section is empty"); - return -1; - } - - if (!check_response_tsig(state->q, state->tsig)) { - return -1; - } - - buffer_set_position(state->q->packet, QHEADERSZ); - - local = region_create(xalloc, free); - owners = domain_table_create(local); - - /* Skip question records. */ - for (i = 0; i < QDCOUNT(state->q->packet); ++i) { - rr_type *record - = packet_read_rr(local, owners, state->q->packet, 1); - if (!record) { - error("bad RR in question section"); - region_destroy(local); - return -1; - } - - if (dname_compare(state->zone, domain_dname(record->owner)) != 0 - || record->type != TYPE_SOA - || record->klass != CLASS_IN) - { - error("response does not match query"); - region_destroy(local); - return -1; - } - } - - /* Find the SOA record in the response. */ - for (i = 0; i < ANCOUNT(state->q->packet); ++i) { - rr_type *record - = packet_read_rr(local, owners, state->q->packet, 0); - if (!record) { - error("bad RR in answer section"); - region_destroy(local); - return -1; - } - - if (dname_compare(state->zone, domain_dname(record->owner)) == 0 - && record->type == TYPE_SOA - && record->klass == CLASS_IN) - { - assert(record->rdata_count == 7); - assert(rdata_atom_size(record->rdatas[2]) == 4); - state->zone_serial = read_uint32( - rdata_atom_data(record->rdatas[2])); - region_destroy(local); - return (state->first_transfer - || compare_serial(state->zone_serial, - state->last_serial) > 0); - } - } - - error("SOA not found in answer"); - region_destroy(local); - return -1; -} - -/* - * Receive and parse the AXFR response packets. - */ -static int -handle_axfr_response(FILE *out, axfr_state_type *axfr) -{ - while (!axfr->done) { - if (!receive_response(axfr)) { - return 0; - } - - buffer_flip(axfr->q->packet); - - if (buffer_limit(axfr->q->packet) <= QHEADERSZ) { - error("response size (%d) is too small", - (int) buffer_limit(axfr->q->packet)); - return 0; - } - - if (!QR(axfr->q->packet)) { - error("response is not a response"); - return 0; - } - - if (ID(axfr->q->packet) != axfr->query_id) { - error("bad response id (%d), expected (%d)", - (int) ID(axfr->q->packet), - (int) axfr->query_id); - return 0; - } - - if (RCODE(axfr->q->packet) != RCODE_OK) { - error("error response %d (%s)", (int) RCODE(axfr->q->packet), - rcode2str((int) RCODE(axfr->q->packet))); - return 0; - } - - if (QDCOUNT(axfr->q->packet) > 1) { - error("query section count greater than 1"); - return 0; - } - - if (ANCOUNT(axfr->q->packet) == 0) { - error("answer section is empty"); - return 0; - } - - if (!check_response_tsig(axfr->q, axfr->tsig)) { - return 0; - } - - buffer_set_position(axfr->q->packet, QHEADERSZ); - - if (!parse_response(out, axfr)) { - return 0; - } - } - return 1; -} - -static int -axfr(FILE *out, axfr_state_type *state, const char *server) -{ - state->query_id = init_query( - state->q, state->zone, TYPE_AXFR, CLASS_IN, state->tsig); - - log_msg(LOG_INFO, - "send AXFR query to %s for %s", - server, - dname_to_string(state->zone, NULL)); - - if (!send_query(state->s, state->q)) { - return 0; - } - - if (state->tsig) { - /* Prepare for checking responses. */ - tsig_prepare(state->tsig); - } - - return handle_axfr_response(out, state); -} - -static uint16_t -init_query(query_type *q, - const dname_type *dname, - uint16_t type, - uint16_t klass, - tsig_record_type *tsig) -{ - uint16_t query_id = qid_generate(); - - buffer_clear(q->packet); - - /* Set up the header */ - ID_SET(q->packet, query_id); - FLAGS_SET(q->packet, 0); - OPCODE_SET(q->packet, OPCODE_QUERY); - AA_SET(q->packet); - QDCOUNT_SET(q->packet, 1); - ANCOUNT_SET(q->packet, 0); - NSCOUNT_SET(q->packet, 0); - ARCOUNT_SET(q->packet, 0); - buffer_skip(q->packet, QHEADERSZ); - - /* The question record. */ - buffer_write(q->packet, dname_name(dname), dname->name_size); - buffer_write_u16(q->packet, type); - buffer_write_u16(q->packet, klass); - - if (tsig) { - tsig_init_query(tsig, query_id); - tsig_prepare(tsig); - tsig_update(tsig, q->packet, buffer_position(q->packet)); - tsig_sign(tsig); - tsig_append_rr(tsig, q->packet); - ARCOUNT_SET(q->packet, 1); - } - - buffer_flip(q->packet); - - return ID(q->packet); -} - -static void -print_zone_header(FILE *out, axfr_state_type *state, const char *server) -{ - time_t now = time(NULL); - fprintf(out, "; NSD version %s\n", PACKAGE_VERSION); - fprintf(out, "; zone '%s'", dname_to_string(state->zone, NULL)); - if (state->first_transfer) { - fprintf(out, " first transfer\n"); - } else { - fprintf(out, - " last serial %lu\n", - (unsigned long) state->last_serial); - } - fprintf(out, "; from %s using AXFR at %s", server, ctime(&now)); - if (state->tsig) { - fprintf(out, "; TSIG verified with key '%s'\n", - dname_to_string(state->tsig->key->name, NULL)); - } else { - fprintf(out, "; NOT TSIG verified\n"); - } -} - -static void -print_stats(axfr_state_type *state) -{ - log_msg(LOG_INFO, - "received %lu RRs in %lu bytes (using %lu response packets)", - (unsigned long) state->rr_count, - (unsigned long) state->bytes_received, - (unsigned long) state->packets_received); -} - -int -main(int argc, char *argv[]) -{ - region_type *region = region_create(xalloc, free); - int c; - query_type q; - struct addrinfo hints, *res0, *res; - const char *zone_filename = NULL; - const char *local_hostname = NULL; - struct addrinfo *local_address, *local_addresses = NULL; - const char *port = TCP_PORT; - const char *local_port = NULL; - int default_family = DEFAULT_AI_FAMILY; - struct sigaction mysigaction; - FILE *zone_file; - const char *tsig_key_filename = NULL; - tsig_key_type *tsig_key = NULL; - axfr_state_type state; - - log_init("nsd-xfer"); - - /* Initialize the query. */ - memset(&q, 0, sizeof(query_type)); - q.region = region; - q.addrlen = sizeof(q.addr); - q.packet = buffer_create(region, QIOBUFSZ); - q.maxlen = TCP_MAX_MESSAGE_LEN; - - /* Initialize the state. */ - state.verbose = 0; - state.packets_received = 0; - state.bytes_received = 0; - state.q = &q; - state.tsig = NULL; - state.zone = NULL; - state.first_transfer = 1; - state.done = 0; - state.rr_count = 0; - state.rr_region = region_create(xalloc, free); - state.pretty_rr = create_pretty_rr(region); - - region_add_cleanup(region, cleanup_region, state.rr_region); - - srandom((unsigned long) getpid() * (unsigned long) time(NULL)); - - if (!tsig_init(region)) { - error("TSIG initialization failed"); - } - - /* Parse the command line... */ - while ((c = getopt(argc, argv, "46a:f:hp:s:T:vz:")) != -1) { - switch (c) { - case '4': - default_family = AF_INET; - break; - case '6': -#ifdef INET6 - default_family = AF_INET6; -#else /* !INET6 */ - error("IPv6 support not enabled."); -#endif /* !INET6 */ - break; - case 'a': - get_hostname_port_frm_str((char *) optarg, - &local_hostname, &local_port); - break; - case 'f': - zone_filename = optarg; - break; - case 'h': - usage(); - break; - case 'p': - port = optarg; - break; - case 's': { - uint32_t v; - const char *t; - state.first_transfer = 0; - v = strtoserial(optarg, &t); - if (optarg[0] == '\0' || *t != '\0') - { - error("bad serial '%s'", optarg); - exit(XFER_FAIL); - } - state.last_serial = v; - break; - } - case 'T': - tsig_key_filename = optarg; - break; - case 'v': - ++state.verbose; - break; - case 'z': - state.zone = dname_parse(region, optarg); - if (!state.zone) { - error("incorrect domain name '%s'", optarg); - } - break; - case '?': - default: - usage(); - } - } - argc -= optind; - argv += optind; - - if (argc == 0 || !zone_filename || !state.zone) - usage(); - - if (tsig_key_filename) { - tsig_algorithm_type *tsig_algo = NULL; - tsig_key = read_tsig_key( - region, tsig_key_filename, default_family, &tsig_algo); - if (!tsig_key) { - error("cannot initialize TSIG: error in tsiginfo file"); - exit(XFER_FAIL); - } - - tsig_add_key(tsig_key); - - state.tsig = (tsig_record_type *) region_alloc( - region, sizeof(tsig_record_type)); - tsig_create_record(state.tsig, region); - tsig_init_record(state.tsig, tsig_algo, tsig_key); - } - - mysigaction.sa_handler = to_alarm; - sigfillset(&mysigaction.sa_mask); - mysigaction.sa_flags = 0; - if (sigaction(SIGALRM, &mysigaction, NULL) < 0) { - error("cannot set signal handler"); - } - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = default_family; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - if (local_hostname) { - int rc = getaddrinfo(local_hostname, local_port, - &hints, &local_addresses); - if (rc) { - error("local hostname '%s' not found: %s", - local_hostname, gai_strerror(rc)); - } - } - - for (/*empty*/; *argv; ++argv) { - /* Try each server separately until one succeeds. */ - int rc; - - rc = getaddrinfo(*argv, port, &hints, &res0); - if (rc) { - warning("skipping bad address %s: %s\n", *argv, - gai_strerror(rc)); - continue; - } - - if (local_addresses - && !check_matching_address_family(res0, local_addresses)) - { - warning("no local address family matches remote " - "address family, skipping server '%s'", - *argv); - continue; - } - - for (res = res0; res; res = res->ai_next) { - if (res->ai_addrlen > (socklen_t)sizeof(q.addr)) - continue; - - /* - * If a local address is specified, use an - * address with the same family as the remote - * address. - */ - local_address = find_by_address_family(local_addresses, - res->ai_family); - if (local_addresses && !local_address) { - /* Continue with next remote address. */ - continue; - } - - state.s = socket(res->ai_family, res->ai_socktype, - res->ai_protocol); - if (state.s == -1) { - warning("cannot create socket: %s\n", - strerror(errno)); - continue; - } - - /* Bind socket to local address, if required. */ - if (local_address && bind(state.s, - local_address->ai_addr, - local_address->ai_addrlen) < 0) - { - warning("cannot bind to %s: %s\n", - local_hostname, strerror(errno)); - } - - if (connect(state.s, res->ai_addr, res->ai_addrlen) < 0) - { - warning("cannot connect to %s: %s\n", - *argv, - strerror(errno)); - close(state.s); - continue; - } - - memcpy(&q.addr, res->ai_addr, res->ai_addrlen); - - rc = check_serial(&state); - if (rc == -1) { - close(state.s); - continue; - } - if (rc == 0) { - /* Zone is up-to-date. */ - close(state.s); - exit(XFER_UPTODATE); - } else if (rc > 0) { - zone_file = fopen(zone_filename, "w"); - if (!zone_file) { - error("cannot open or create zone file '%s' for writing: %s", - zone_filename, strerror(errno)); - close(state.s); - exit(XFER_FAIL); - } - - print_zone_header(zone_file, &state, *argv); - - if (axfr(zone_file, &state, *argv)) { - /* AXFR succeeded, done. */ - fclose(zone_file); - close(state.s); - - if (state.verbose > 0) { - print_stats(&state); - } - - exit(XFER_SUCCESS); - } - - fclose(zone_file); - } - - close(state.s); - } - - freeaddrinfo(res0); - } - - log_msg(LOG_ERR, - "cannot contact an authoritative server, zone NOT transferred"); - exit(XFER_FAIL); -} - -void -get_hostname_port_frm_str(char* arg, const char** hostname, - const char** port) -{ - /* parse -a src[@port] option */ - char* delim = strchr(arg, '@'); - - if (delim) { - *delim = '\0'; - *port = delim+1; - } - *hostname = arg; -} - - -int -check_matching_address_family(struct addrinfo *a0, struct addrinfo *b0) -{ - struct addrinfo *a; - struct addrinfo *b; - - for (a = a0; a; a = a->ai_next) { - for (b = b0; b; b = b->ai_next) { - if (a->ai_family == b->ai_family) { - return 1; - } - } - } - return 0; -} - -struct addrinfo * -find_by_address_family(struct addrinfo *addrs, int family) -{ - for (; addrs; addrs = addrs->ai_next) { - if (addrs->ai_family == family) { - return addrs; - } - } - return NULL; -} diff --git a/usr.sbin/nsd/nsdc.8.in b/usr.sbin/nsd/nsdc.8.in deleted file mode 100644 index 4ae05909701..00000000000 --- a/usr.sbin/nsd/nsdc.8.in +++ /dev/null @@ -1,169 +0,0 @@ -.TH "NSDC" "8" "Jul 22, 2013" "NLnet Labs" "NSDC 3.2.16" -.\" Copyright (c) 2001\-2011, NLnet Labs. All rights reserved. -.\" See LICENSE for the license. -.SH "NAME" -.LP -.B nsdc -\- Name Server Daemon (NSD) control script. -.SH "SYNOPSIS" -.LP -.B nsdc -.RB [ \-c -.IR configfile ] -.I start -| -.I stop -| -.I reload -| -.I rebuild -| -.I restart -| -.I running -| -.I update -| -.I notify -| -.I patch -.SH "DESCRIPTION" -.LP -.B Nsdc -is the shell script that used to control nsd(8) and nsd\-zonec(8) from -.B NSD -distribution. -.B Nsdc -is also suitable to be linked into -.I /etc/rc.d -directory on -.I BSD -like systems for automatic startup of nsd(8) at boot time. -.P -At every invokation, -.B nsdc -will try to read the nsd.conf(5) configuration file. An example of -such configuration file is distributed with the -.B NSD -package as -.IR nsd.conf.sample . -The config file is checked for errors before it is used, see -nsd\-checkconf(8). -.P -Possible -.B nsdc -applications are: -.TP -.I start -Start nsd(8). -.TP -.I stop -Shut down nsd(8) by sending -.I SIGTERM -to it. -.TP -.I reload -Initiate nsd(8) name space database reload by sending -.IR SIGHUP. -.TP -.I rebuild -Rebuild the nsd(8) database by invoking nsd\-zonec(8) with appropriate -arguments. -.TP -.I restart -Restart nsd(8). This equals to nsdc stop && nsdc start. -.TP -.I running -Check whether nsd(8) is running. Returns error message and error -code if it is not running, and no message and zero error code -otherwise. -.TP -.I update -Updates all the slave zones which have -.I allow\-notify: -from localhost (127.0.0.1 or ::1) allowed. -If a TSIG key is specified for the allow\-notify statement in the -config file, it will be used to secure the notify. Note that NSD -keeps track of zone timeouts automatically, this is only needed if -you want to manually force updates by sending notify messages to the -localhost. -.P -.RS -Another method you can use is to stop nsd, delete the xfrd.state -file and then start nsd again. It will try to update all zones. -This method does not require allow\-notify: statements. -.RE -.TP -.I notify -Sends notify messages to all the slaves for all the zones that have the -.I notify: -keyword in the -.I nsd.conf -file. If a TSIG key is specified for a notify statement, it will be -used to secure the notification message to that slave server. -.TP -.I patch -Merge zone transfer changes back to zone files. It reads in the nsd -database (nsd.db) and difffile (ixfr.db), and overwrites the zone -text files if they have been updated. Running this regularly -ensures that the difffile does not grow infinitely. If any zone text -files have been changed (including those of the master zones), the -nsd.db is rebuild and nsd is reloaded. -.SH "OPTIONS" -.TP -.B \-c\fI configfile -Specify configfile to use instead of the default -.IR @nsdconfigfile@ . -.SH "FILES" -.TP -@nsdconfigfile@ -Configuration file for nsd to change default pathnames and -.B NSD -flags. The zone names, pathnames to zone files and access control -lists are also in nsd.conf(5). -.TP -@dbfile@ -default -.B NSD -database -.TP -@dbfile@.lock -Lockfile for the -.B NSD -database access by operator tools. -.TP -@difffile@ -Journal of zone transfers, the diff file containing the new zone -contents transferred. -.TP -@xfrdfile@ -State for the zone transfer process of -.BR NSD. -Contains timeouts for the zones and whether zones are expired. -.TP -@pidfile@ -the process id of the name server. -.SH "DIAGNOSTICS" -.LP -.B Nsdc -will return zero return code if operation was successful and -an error message to standard output plus a non\-zero return code -otherwise. -.SH "SEE ALSO" -.LP -nsd(8), nsd.conf(5), nsd\-checkconf(8), nsd\-notify(8), -nsd\-patch(8), nsd\-xfer(8), nsd\-zonec(8) -.SH "AUTHORS" -.LP -.B NSD -was written by NLnet Labs and RIPE NCC joint team. Please see -CREDITS file in the distribution for further details. -.SH "BUGS" -Syntax checking of the config file is rudimentary and error -messages may be wrong. If you do a nsdc patch, whilst a (long) zone -transfer is busy, the zone transfer contents will be partially -lost. After a reload, this will be detected and the zone transfer -should be restarted. The reload that happens at the end of nsdc -patch also frees up memory churn in -.B NSD -caused by zone transfers. diff --git a/usr.sbin/nsd/nsdc.sh.in b/usr.sbin/nsd/nsdc.sh.in deleted file mode 100644 index d02690026ce..00000000000 --- a/usr.sbin/nsd/nsdc.sh.in +++ /dev/null @@ -1,431 +0,0 @@ -#!@shell@ -# -# nsdc.sh -- a shell script to manage the beast -# -# Copyright (c) 2001-2011, NLnet Labs. All rights reserved. -# -# See LICENSE for the license. -# -# - -# chkconfig: 2345 @spriority@ @kpriority@ -# description: NSD, authoritative only high performance name server. - -# configuration file default -configfile="@nsdconfigfile@" - -# The directory where NSD binaries reside -sbindir="@sbindir@" - -# how verbose is nsd-zonec run. Specify Nothing " ", -v or -vv. -NSDC_ZONEC_VERBOSE=${NSDC_ZONEC_VERBOSE:-" "} - -# how patch is done. Specify 1 (with use of textfiles, default) or 0 (without) -NSDC_PATCH_STYLE=${NSDC_PATCH_STYLE:-1} - -# -# You sure heard this many times before: NO USER SERVICEABLE PARTS BELOW -# - -# see if user selects a different config file, with -c <filename> -if test "x$1" = "x-c"; then - shift - if [ -e $1 ]; then - configfile=$1 - shift - else - echo "`basename $0`: Config file "$1" does not exist." - exit 1 - fi -fi - -# locate nsd-checkconf : in sbindir, PATH, nsdc_dir or . -nsd_checkconf="" -if [ -e ${sbindir}/nsd-checkconf ]; then - nsd_checkconf=${sbindir}/nsd-checkconf -else - if which nsd-checkconf >/dev/null 2>&1 ; then - if which nsd-checkconf 2>&1 | grep "^[Nn]o " >/dev/null; then - nsd_checkconf="" - else - nsd_checkconf=`which nsd-checkconf` - fi - fi - if [ -z "${nsd_checkconf}" -a -e `dirname $0`/nsd-checkconf ]; then - nsd_checkconf=`dirname $0`/nsd-checkconf - fi - if [ -z "${nsd_checkconf}" -a -e ./nsd-checkconf ]; then - nsd_checkconf=./nsd-checkconf - fi - if [ -z "${nsd_checkconf}" ]; then - echo "`basename $0`: Could not find nsd programs" \ - "in $sbindir, in PATH=$PATH, in cwd=`pwd`," \ - "or in dir of nsdc=`dirname $0`" - exit 1 - fi -fi - -usage() { - echo "Usage: `basename $0` [-c configfile] {start|stop|reload|rebuild|restart|" - echo " running|update|notify|patch}" - echo "options:" - echo " -c configfile Use specified configfile (default: @nsdconfigfile@)." - echo "commands:" - echo " start Start nsd server." - echo " stop Stop nsd server." - echo " reload Nsd server reloads database file." - echo " rebuild Compile database file from zone files." - echo " restart Stop the nsd server and start it again." - echo " running Prints message and exit nonzero if server not running." - echo " update Try to update all slave zones hosted on this server." - echo " notify Send notify messages to all secondary servers." - echo " patch Merge zone transfer changes back to zone files." -} - -# check the config syntax before using it -${nsd_checkconf} ${configfile} -if test $? -ne 0 ; then - usage - exit 1 -fi - -# Read some settings from the config file. -dbfile=`${nsd_checkconf} -o database ${configfile}` -pidfile=`${nsd_checkconf} -o pidfile ${configfile}` -difffile=`${nsd_checkconf} -o difffile ${configfile}` -zonesdir=`${nsd_checkconf} -o zonesdir ${configfile}` -lockfile="${dbfile}.lock" # still needed -sbindir=`dirname ${nsd_checkconf}` - -# move to zonesdir (if specified), and make absolute pathnames. -if test -n "${zonesdir}"; then - zonesdir=`dirname ${zonesdir}/.` - if echo "${zonesdir}" | grep "^[^/]" >/dev/null; then - zonesdir=`pwd`/${zonesdir} - fi - if echo "${dbfile}" | grep "^[^/]" >/dev/null; then - dbfile=${zonesdir}/${dbfile} - fi - if echo "${pidfile}" | grep "^[^/]" >/dev/null; then - pidfile=${zonesdir}/${pidfile} - fi - if echo "${lockfile}" | grep "^[^/]" >/dev/null; then - lockfile=${zonesdir}/${lockfile} - fi - if echo "${difffile}" | grep "^[^/]" >/dev/null; then - difffile=${zonesdir}/${difffile} - fi -fi - -# for bash: -C or noclobber. For tcsh: noclobber. For bourne: -C. -noclobber_set="set -C" -# ugly check for tcsh -if echo @shell@ | grep tcsh >/dev/null; then - noclobber_set="set noclobber" -fi - -# -# useful routines -# -signal() { - if [ -s ${pidfile} ] - then - kill -"$1" `cat ${pidfile}` && return 0 - else - echo "nsd is not running" - fi - return 1 -} - -lock_file() { - (umask 222; ${noclobber_set}; echo "$$" >${lockfile}) -} - -lock() { - lock_file - if [ $? = 1 ] - then - # check if the lockfile has not gone stale - LPID=`cat ${lockfile}` - echo database locked by PID: $LPID - if kill -0 $LPID 2>/dev/null; then - exit 1 - fi - - # locking process does not exist, consider lockfile stale - echo stale lockfile, removing... && rm -f ${lockfile} && lock_file - fi - - if [ $? = 1 ] - then - echo lock failed - exit 1 - fi - return 0 -} - -unlock() { - rm -f ${lockfile} -} - -do_start() { - if test -x ${sbindir}/nsd; then - ${sbindir}/nsd -c ${configfile} - test $? = 0 || (echo "nsd startup failed."; exit 1) - else - echo "${sbindir}/nsd not an executable file, nsd startup failed."; exit 1 - fi -} - -controlled_sleep() { - if [ $1 -ge 25 ]; then - sleep 1 - fi -} - -controlled_stop() { - pid=$1 - try=1 - - while [ $try -ne 0 ]; do - if [ ${try} -gt 50 ]; then - echo "nsdc stop failed" - return 1 - else - if [ $try -eq 1 ]; then - kill -TERM ${pid} - else - kill -TERM ${pid} >/dev/null 2>&1 - fi - - # really stopped? - kill -0 ${pid} >/dev/null 2>&1 - if [ $? -eq 0 ]; then - controlled_sleep ${try} - try=`expr ${try} + 1` - else - try=0 - fi - fi - done - - return 0 -} - -do_controlled_stop() { - if [ -s ${pidfile} ]; then - pid=`cat ${pidfile}` - controlled_stop ${pid} && return 0 - else - echo "nsd is not running, starting anyway" && return 0 - fi - return 1 -} - -do_stop() { - signal "TERM" -} - -do_reload() { - signal "HUP" -} - -# send_updates zone_name {ip_spec key_spec} -send_updates() { - local zonename=$1 - shift 1 - # extract port number (if any) - port=`${nsd_checkconf} -o port ${configfile}` - if test -n "${port}"; then - port="-p ${port}" - fi - update_sent="no" - - while test $# -gt 0; do - ip_spec=$1 - key_spec=$2 - shift 2 - # only localhost is allowed. - # see if zone has 127.0.0.1 or ::1 as allowed. - if test Z${ip_spec} = "Z127.0.0.1" -o Z${ip_spec} = "Z::1"; then - secret="" - if test K${key_spec} != KNOKEY -a K${key_spec} != KBLOCKED; then - secret=`${nsd_checkconf} -s ${key_spec} ${configfile}` - algo=`${nsd_checkconf} -a ${key_spec} ${configfile}` - secret="-y ${key_spec}:${secret}:${algo}" - fi - if test K${key_spec} != KBLOCKED; then - #echo "${sbindir}/nsd-notify -a ${ip_spec} ${port} ${secret} -z ${zonename} ${ip_spec}" - ${sbindir}/nsd-notify -a ${ip_spec} ${port} ${secret} -z ${zonename} ${ip_spec} && update_sent="yes" - fi - fi - done - if test ${update_sent} = no; then - req_xfr=`${nsd_checkconf} -z "${zonename}" -o request-xfr ${configfile}` - if test -n "${req_xfr}"; then - # must be a slave zone (has request-xfr). - echo "`basename $0`: Could not send notify for slave zone ${zonename}: not configured (with allow-notify: 127.0.0.1 or ::1)" - fi - fi -} - -# send_notify zone_name ifc_spec {ip_spec key_spec} -send_notify() { - local zonename=$1 - # set local interface - ifc_spec="" - if test I$2 != INOIFC; then - ifc_spec="-a $2" - # with a : is IPv6 - case "$2" in - *:*) ifc_is_ip6="yes" ;; - *) ifc_is_ip6="no" ;; - esac - fi - shift 2 - - while test $# -gt 0; do - ip_spec=$1 - key_spec=$2 - shift 2 - secret="" - # skip if ifc is set and mismatch v4-v6 - if test -n "$ifc_spec"; then - case "$ip_spec" in - *:*) if test "$ifc_is_ip6" = "no"; then continue; fi;; - *) if test "$ifc_is_ip6" = "yes"; then continue; fi;; - esac - fi - - if test K${key_spec} != KNOKEY -a K${key_spec} != KBLOCKED; then - secret=`${nsd_checkconf} -s ${key_spec} ${configfile}` - algo=`${nsd_checkconf} -a ${key_spec} ${configfile}` - secret="-y ${key_spec}:${secret}:${algo}" - fi - if test K${key_spec} != KBLOCKED; then - port="" - ipaddr=${ip_spec} - if echo ${ip_spec} | grep @ >/dev/null; then - port="-p "`echo ${ip_spec} | sed -e 's/[^@]*@\([0-9]*\)/\1/'` - ipaddr=`echo ${ip_spec} | sed -e 's/\([^@]*\)@[0-9]*/\1/'` - fi - #echo "${sbindir}/nsd-notify ${ifc_spec} ${port} ${secret} -z ${zonename} ${ipaddr}" - ${sbindir}/nsd-notify ${ifc_spec} ${port} ${secret} -z ${zonename} ${ipaddr} - fi - done -} - -# do_patch {with-textfile} -do_patch() { - if test I$1 = I1; then - lock && mv ${difffile} ${difffile}.$$ && \ - ${sbindir}/nsd-patch -c ${configfile} -x ${difffile}.$$ && \ - rm -f ${difffile}.$$ && unlock && do_rebuild - result=$? - else # without textfile - lock && mv ${difffile} ${difffile}.$$ && \ - ${sbindir}/nsd-patch -c ${configfile} -x ${difffile}.$$ -s -o ${dbfile}.$$ \ - && rm -f ${difffile}.$$ && unlock && \ - mv ${dbfile}.$$ ${dbfile} - result=$? - fi - - return ${result} -} - -do_rebuild() { - lock && \ - ${sbindir}/nsd-zonec ${NSDC_ZONEC_VERBOSE} -c ${configfile} -f ${dbfile}.$$ && \ - mv ${dbfile}.$$ ${dbfile} - result=$? - unlock - [ $result != 0 ] && echo "${dbfile} is unmodified" - rm -f ${dbfile}.$$ - return ${result} -} - -case "$1" in -start) - if test -s ${pidfile} && kill -"0" `cat ${pidfile}` - then - (echo "process `cat ${pidfile}` exists, please use restart"; exit 1) - else - do_start - fi - ;; -stop) - do_stop - ;; -stats) - signal "USR1" - ;; -reload) - do_reload - ;; -running) - signal "0" - ;; -patch) - # patch queue clearen - if test -s ${difffile}; then - #${sbindir}/nsd-patch -c ${configfile} -x ${difffile} -l #debug - #echo ${sbindir}/nsd-patch -c ${configfile} -x ${difffile} - if do_patch ${NSDC_PATCH_STYLE}; then - do_reload - else - unlock - # try to move back the transfer data - if [ -e ${difffile}.$$ -a ! -e ${difffile} ]; then - mv ${difffile}.$$ ${difffile} - fi - echo "`basename $0`: patch failed." - exit 1 - fi - else - echo "`basename $0`: no patch necessary." - fi - ;; -rebuild) - do_rebuild - ;; -update) - # send notifies to localhost for all zones that allow it - echo "Sending notify to localhost to update secondary zones..." - if [ -s ${pidfile} ]; then - zoneslist=`${nsd_checkconf} -o zones ${configfile}` - for zonename in ${zoneslist}; do - notify_allow=`${nsd_checkconf} -z "${zonename}" -o allow-notify ${configfile}` - if test "" != "${notify_allow}"; then - send_updates ${zonename} ${notify_allow} - fi - done - else - echo "nsd is not running" - fi - ;; -notify) - # send notifies to all slaves - echo "Sending notify to slave servers..." - zoneslist=`${nsd_checkconf} -o zones ${configfile}` - for zonename in ${zoneslist}; do - notify=`${nsd_checkconf} -z "${zonename}" -o notify ${configfile}` - local_ifc=`${nsd_checkconf} -z "${zonename}" -o outgoing-interface ${configfile}` - if test "" = "${local_ifc}"; then - local_ifc="NOIFC" - fi - if test "" != "${notify}"; then - for ifc in ${local_ifc}; do - send_notify ${zonename} ${ifc} ${notify} - done - fi - done - ;; -restart) - do_controlled_stop && do_start - ;; -*) - usage - ;; -esac - -exit $? diff --git a/usr.sbin/nsd/zonec.8.in b/usr.sbin/nsd/zonec.8.in deleted file mode 100644 index 5178f544894..00000000000 --- a/usr.sbin/nsd/zonec.8.in +++ /dev/null @@ -1,126 +0,0 @@ -.TH "nsd\-zonec" "8" "Jul 22, 2013" "NLnet Labs" "nsd 3.2.16" -.\" Copyright (c) 2001\-2011, NLnet Labs. All rights reserved. -.\" See LICENSE for the license. -.SH "NAME" -.LP -.B nsd\-zonec -\- NSD zone compiler version 3.2.16. -.SH "SYNOPSIS" -.LP -.B nsd\-zonec -.RB [ \-v ] -.RB [ \-h ] -.RB [ \-C ] -.RB [ \-L ] -.RB [ \-F ] -.RB [ \-c -.IR configfile ] -.RB [ \-d -.IR directory ] -.RB [ \-o -.IR origin ] -.RB [ \-z -.IR zonefile ] -.RB [ \-f -.IR database ] -.SH "DESCRIPTION" -.LP -.B Zonec -is the nsd(8) database compiler for creating name space databases -from a set of input master zone files specified in nsd.conf(5) file. -.LP -It is normally invoked via nsdc(8) rebuild command. -.B Zonec -will then parse every zone in nsd.conf(5) file and add it to the -name space database, -.I @dbfile@ -by default, that is used by nsd(8) to answer incoming queries. -.SH "OPTIONS" -.TP -.B \-c\fI configfile -Read specified configfile instead of the default -.IR @nsdconfigfile@ . -.TP -.B \-C -No config file is read (use with \-f, \-o and \-z). -.TP -.B \-d\fI directory -Change the working directory to -.I directory -before doing any work. Overrides zonesdir: option in config file. -.TP -.B \-f\fI database -Create the specified -.I database -instead of the file specified as database: in the config file. -.TP -.B \-o\fI origin -Use this as the first origin. Zone information is read from -zonefile specified with \-z. When reading zones from config file -this option is ignored. -.TP -.B \-z\fI zonefile -Reads all zone information from -.IR zonefile . -If -.IR zonefile -equals `\-`, then all zone information is read from stdin, making -constructs like: -.LP -.RS -.B # cat zones* -| -.B ./nsd\-zonec \-C \-f nsd.db \-o example.net \-z \- -.RE -.LP -.RS -possible. When reading zones from config file this option is -ignored. -.RE -.TP -.B \-v -Increase the verbosity of nsd\-zonec. This flag can be specified multiple -times to increase the level of verbosity. The first level of -verbosity will print per zone summary information. The second level -of will print progress information for each 10,000 RRs processed. -.TP -.B \-F -Set debug facilities. (If compiled with \-\-enable\-checking.) -.TP -.B \-L -Set debug level. (If compiled with \-\-enable\-checking.) -.SH "FILES" -.TP -@dbfile@ -default -.B NSD -database -.TP -@nsdconfigfile@ -default -.B NSD -configuration file -.SH "DIAGNOSTICS" -.LP -.B Zonec -will log all the problems via the standard error output and -progress via stdout if the -.B v -option is specified. -.SH "SEE ALSO" -.LP -nsd(8), nsdc(8), nsd.conf(5), nsd\-checkconf(8), nsd-notify(8), -nsd-patch(8), nsd-xfer(8) -.SH "AUTHORS" -.LP -.B NSD -was written by NLnet Labs and RIPE NCC joint team. Please see -CREDITS file in the distribution for further details. -.SH "BUGS" -.LP -.B Zonec -has rather weak error diagnostics that will change in further -versions. -.B Zonec -expects the input files to be free of syntax errors and very little -fool proof checks are done. |