diff options
author | Jakob Schlyter <jakob@cvs.openbsd.org> | 2011-01-27 12:29:15 +0000 |
---|---|---|
committer | Jakob Schlyter <jakob@cvs.openbsd.org> | 2011-01-27 12:29:15 +0000 |
commit | 1194ec552c2edfd49dc234cab7316344ffb9f684 (patch) | |
tree | 2c7bb9abb45db12d9f1dca5b2d96a3cdba0884eb | |
parent | 7fd092e3c00a7462220af27f13cdb7328470e250 (diff) |
upgrade to NSD 3.2.7; ok sthen@, tested by multiple people
-rw-r--r-- | usr.sbin/nsd/config.h.in | 102 | ||||
-rw-r--r-- | usr.sbin/nsd/configparser.y | 27 | ||||
-rw-r--r-- | usr.sbin/nsd/configure.ac | 13 | ||||
-rw-r--r-- | usr.sbin/nsd/dns.c | 36 | ||||
-rw-r--r-- | usr.sbin/nsd/dns.h | 8 | ||||
-rw-r--r-- | usr.sbin/nsd/mkinstalldirs | 2 | ||||
-rw-r--r-- | usr.sbin/nsd/nsd-checkconf.c | 29 | ||||
-rw-r--r-- | usr.sbin/nsd/nsd-notify.c | 2 | ||||
-rw-r--r-- | usr.sbin/nsd/nsd-patch.c | 4 | ||||
-rw-r--r-- | usr.sbin/nsd/nsdc.sh.in | 48 | ||||
-rw-r--r-- | usr.sbin/nsd/nsec3.c | 10 | ||||
-rw-r--r-- | usr.sbin/nsd/query.c | 37 | ||||
-rw-r--r-- | usr.sbin/nsd/rdata.c | 52 | ||||
-rw-r--r-- | usr.sbin/nsd/server.c | 38 | ||||
-rw-r--r-- | usr.sbin/nsd/util.c | 8 | ||||
-rw-r--r-- | usr.sbin/nsd/zonec.c | 68 | ||||
-rw-r--r-- | usr.sbin/nsd/zonec.h | 2 | ||||
-rw-r--r-- | usr.sbin/nsd/zparser.y | 7 |
18 files changed, 284 insertions, 209 deletions
diff --git a/usr.sbin/nsd/config.h.in b/usr.sbin/nsd/config.h.in index b6a98363972..f26fae53a71 100644 --- a/usr.sbin/nsd/config.h.in +++ b/usr.sbin/nsd/config.h.in @@ -3,9 +3,6 @@ /* Define this to enable BIND8 like NSTATS & XSTATS. */ #undef BIND8_STATS -/* NSD default chroot directory */ -#undef CHROOTDIR - /* Pathname to the NSD configuration file */ #undef CONFIGFILE @@ -19,6 +16,9 @@ /* Pathname to the NSD diff transfer journal file. */ #undef DIFFFILE +/* Define this to enable DNSSEC (RFCs 4033, 4034, and 4035) support. */ +#undef DNSSEC + /* Define to the default maximum message length with EDNS. */ #undef EDNS_MAX_MESSAGE_LEN @@ -134,12 +134,6 @@ /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET -/* Define to 1 if you have the `mmap' function. */ -#undef HAVE_MMAP - -/* Define to 1 if you have the `munmap' function. */ -#undef HAVE_MUNMAP - /* Define to 1 if you have the <netdb.h> header file. */ #undef HAVE_NETDB_H @@ -215,9 +209,6 @@ /* Define to 1 if you have the <string.h> header file. */ #undef HAVE_STRING_H -/* Define to 1 if you have the `strlcat' function. */ -#undef HAVE_STRLCAT - /* Define to 1 if you have the `strlcpy' function. */ #undef HAVE_STRLCPY @@ -239,9 +230,6 @@ /* Define to 1 if you have the <sys/bitypes.h> header file. */ #undef HAVE_SYS_BITYPES_H -/* Define to 1 if you have the <sys/mman.h> header file. */ -#undef HAVE_SYS_MMAN_H - /* Define to 1 if you have the <sys/param.h> header file. */ #undef HAVE_SYS_PARAM_H @@ -293,18 +281,18 @@ /* Define to the maximum message length to pass to syslog. */ #undef MAXSYSLOGMSGLEN -/* Define to the maximum ip-addresses to serve. */ +/* Define to the maximum interfaces to serve. */ #undef MAX_INTERFACES -/* Define if memcmp() does not compare unsigned bytes */ -#undef MEMCMP_IS_BROKEN - /* Undefine this to enable internal runtime checks. */ #undef NDEBUG /* Define this to enable NSEC3 support. */ #undef NSEC3 +/* Define this to enable NSID support. */ +#undef NSID + /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT @@ -350,6 +338,9 @@ /* Define to the default tcp timeout. */ #undef TCP_TIMEOUT +/* Define this to enable TSIG support. */ +#undef TSIG + /* Define to the default maximum udp message length. */ #undef UDP_MAX_MESSAGE_LEN @@ -359,31 +350,6 @@ /* the user name to drop privileges to */ #undef USER -/* Define this to enable mmap instead of malloc. Experimental. */ -#undef USE_MMAP_ALLOC - -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# undef _ALL_SOURCE -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# undef _GNU_SOURCE -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# undef _POSIX_PTHREAD_SEMANTICS -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# undef _TANDEM_SOURCE -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# undef __EXTENSIONS__ -#endif - - /* Define to the NSD version to answer version.server query. */ #undef VERSION @@ -416,6 +382,28 @@ /* Define to 1 if you need to in order for `stat' and other things to work. */ #undef _POSIX_SOURCE +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + /* Define to empty if `const' does not conform to ANSI C. */ #undef const @@ -461,15 +449,9 @@ /* Define "socklen_t" to "int" if "socklen_t" is missing */ #undef socklen_t -/* Fallback member name for socket family in struct sockaddr_storage */ -#undef ss_family - /* Define "ssize_t" to "int" if "ssize_t" is missing */ #undef ssize_t -/* Define "suseconds_t" to "time_t" if "suseconds_t" is missing */ -#undef suseconds_t - /* Define to `int' if <sys/types.h> doesn't define. */ #undef uid_t @@ -485,9 +467,6 @@ /* Define "uint8_t" to "unsigned char" if "uint8_t" is missing */ #undef uint8_t -/* Define "uintptr_t" to "void*" if "uintptr_t" is missing */ -#undef uintptr_t - /* Define as `fork' if `vfork' does not work. */ #undef vfork @@ -619,9 +598,6 @@ int inet_aton(const char *cp, struct in_addr *addr); #ifndef HAVE_MEMMOVE void *memmove(void *dest, const void *src, size_t n); #endif -#ifndef HAVE_STRLCAT -size_t strlcat(char *dst, const char *src, size_t siz); -#endif #ifndef HAVE_STRLCPY size_t strlcpy(char *dst, const char *src, size_t siz); #endif @@ -637,20 +613,6 @@ char *strptime(const char *s, const char *format, struct tm *tm); #define strptime(a,b,c) nsd_strptime((a),(b),(c)) #endif - - -#ifdef MEMCMP_IS_BROKEN -# ifdef memcmp -# undef memcmp -# endif -#define memcmp memcmp_nsd -int memcmp(const void *x, const void *y, size_t n); -#endif - - - - - /* provide timespec def if not available */ #ifndef CONFIG_DEFINES #define CONFIG_DEFINES diff --git a/usr.sbin/nsd/configparser.y b/usr.sbin/nsd/configparser.y index 96969a238df..ef8eb2dcd86 100644 --- a/usr.sbin/nsd/configparser.y +++ b/usr.sbin/nsd/configparser.y @@ -17,6 +17,7 @@ #include <assert.h> #include "options.h" +#include "util.h" #include "configyyrename.h" int c_lex(void); void c_error(const char *message); @@ -43,7 +44,7 @@ static int server_settings_seen = 0; %token SPACE LETTER NEWLINE COMMENT COLON ANY ZONESTR %token <str> STRING %token VAR_SERVER VAR_NAME VAR_IP_ADDRESS VAR_DEBUG_MODE -%token VAR_IP4_ONLY VAR_IP6_ONLY VAR_DATABASE VAR_IDENTITY VAR_LOGFILE +%token VAR_IP4_ONLY VAR_IP6_ONLY VAR_DATABASE VAR_IDENTITY VAR_NSID VAR_LOGFILE %token VAR_SERVER_COUNT VAR_TCP_COUNT VAR_PIDFILE VAR_PORT VAR_STATISTICS %token VAR_CHROOT VAR_USERNAME VAR_ZONESDIR VAR_XFRDFILE VAR_DIFFFILE %token VAR_XFRD_RELOAD_TIMEOUT VAR_TCP_QUERY_COUNT VAR_TCP_TIMEOUT @@ -73,7 +74,7 @@ serverstart: VAR_SERVER ; contents_server: contents_server content_server | ; content_server: server_ip_address | server_debug_mode | server_ip4_only | - server_ip6_only | server_database | server_identity | server_logfile | + server_ip6_only | server_database | server_identity | server_nsid | server_logfile | server_server_count | server_tcp_count | server_pidfile | server_port | server_statistics | server_chroot | server_username | server_zonesdir | server_difffile | server_xfrdfile | server_xfrd_reload_timeout | @@ -153,6 +154,26 @@ server_identity: VAR_IDENTITY STRING cfg_parser->opt->identity = region_strdup(cfg_parser->opt->region, $2); } ; +server_nsid: VAR_NSID STRING + { + unsigned char* nsid = 0; + uint16_t nsid_len = 0; + + OUTYY(("P(server_nsid:%s)\n", $2)); + + if (strlen($2) % 2 != 0) { + yyerror("the NSID must be a hex string of an even length."); + } else { + nsid_len = strlen($2) / 2; + nsid = xalloc(nsid_len); + if (hex_pton($2, nsid, nsid_len) == -1) + yyerror("hex string cannot be parsed in NSID."); + else + cfg_parser->opt->nsid = region_strdup(cfg_parser->opt->region, $2); + free(nsid); + } + } + ; server_logfile: VAR_LOGFILE STRING { OUTYY(("P(server_logfile:%s)\n", $2)); @@ -401,7 +422,7 @@ zone_outgoing_interface: VAR_OUTGOING_INTERFACE STRING { acl_options_t* acl = parse_acl_info(cfg_parser->opt->region, $2, "NOKEY"); OUTYY(("P(zone_outgoing_interface:%s)\n", $2)); - + if(acl->rangetype!=acl_range_single) c_error("address range used for outgoing interface"); if(cfg_parser->current_outgoing_interface) cfg_parser->current_outgoing_interface->next = acl; else diff --git a/usr.sbin/nsd/configure.ac b/usr.sbin/nsd/configure.ac index b80ba667d07..ee2061684fe 100644 --- a/usr.sbin/nsd/configure.ac +++ b/usr.sbin/nsd/configure.ac @@ -4,7 +4,7 @@ dnl sinclude(acx_nlnetlabs.m4) -AC_INIT(NSD,3.2.6,nsd-bugs@nlnetlabs.nl) +AC_INIT(NSD,3.2.7,nsd-bugs@nlnetlabs.nl) AC_CONFIG_HEADER([config.h]) AC_AIX @@ -275,7 +275,9 @@ AC_DEFUN([CHECK_SSL], [ if test -f "$dir/include/openssl/ssl.h"; then found_ssl="yes"; AC_DEFINE_UNQUOTED([HAVE_SSL], [], [Define if you have the SSL libraries installed.]) - CPPFLAGS="$CPPFLAGS -I$ssldir/include"; + if test x_$ssldir != x_/usr; then + CPPFLAGS="$CPPFLAGS -I$ssldir/include"; + fi break; fi done @@ -284,7 +286,9 @@ AC_DEFUN([CHECK_SSL], [ else AC_MSG_RESULT(found in $ssldir) HAVE_SSL=yes - LDFLAGS="$LDFLAGS -L$ssldir/lib"; + if test x_$ssldir != x_/usr; then + LDFLAGS="$LDFLAGS -L$ssldir/lib"; + fi if test x_$ssldir = x_/usr/sfw; then LDFLAGS="$LDFLAGS -R$ssldir/lib"; fi @@ -463,6 +467,7 @@ AC_FUNC_MALLOC AC_TYPE_SIGNAL AC_FUNC_FSEEKO AC_SYS_LARGEFILE +AC_CHECK_FUNCS([arc4random arc4random_uniform]) AC_CHECK_FUNCS([alarm chroot dup2 endpwent gethostname memset memcpy socket strcasecmp strchr strdup strerror strncasecmp strtol getaddrinfo getnameinfo freeaddrinfo gai_strerror sigaction sigprocmask strptime setusercontext initgroups setresuid setreuid setresgid setregid getpwnam]) # check if setreuid en setregid fail, on MacOSX10.4(darwin8). @@ -527,7 +532,7 @@ AC_ARG_WITH([facility], AC_DEFINE_UNQUOTED([FACILITY], $facility, [Define to the default facility for syslog.]) dnl -dnl Determine the maximum number of interfaces that are allowed +dnl Determine the maximum number of ip-addresses that are allowed dnl max_ips=8 AC_ARG_WITH([max_ips], diff --git a/usr.sbin/nsd/dns.c b/usr.sbin/nsd/dns.c index ec227f9f5d9..c54e120a012 100644 --- a/usr.sbin/nsd/dns.c +++ b/usr.sbin/nsd/dns.c @@ -88,39 +88,9 @@ static rrtype_descriptor_type rrtype_descriptors[(RRTYPE_DESCRIPTORS_LENGTH+1)] { RDATA_WF_SHORT, RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_SHORT, RDATA_ZF_DNAME } }, /* 16 */ - { TYPE_TXT, "TXT", T_TXT, 1, MAXRDATALEN, - { RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, - RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, - RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, - RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, - RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, - RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, - RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, - RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, - RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, - RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, - RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, - RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, - RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, - RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, - RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, - RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT }, - { RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, - RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, - RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, - RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, - RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, - RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, - RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, - RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, - RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, - RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, - RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, - RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, - RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, - RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, - RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, - RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT } }, + { TYPE_TXT, "TXT", T_TXT, 1, 1, + { RDATA_WF_TEXTS }, + { RDATA_ZF_TEXTS } }, /* 17 */ { TYPE_RP, "RP", T_RP, 2, 2, { RDATA_WF_COMPRESSED_DNAME, RDATA_WF_COMPRESSED_DNAME }, diff --git a/usr.sbin/nsd/dns.h b/usr.sbin/nsd/dns.h index 650d6fa8883..5e53ec13bea 100644 --- a/usr.sbin/nsd/dns.h +++ b/usr.sbin/nsd/dns.h @@ -146,7 +146,7 @@ typedef enum nsd_rc nsd_rc_type; #define MAXLABELLEN 63 #define MAXDOMAINLEN 255 -#define MAXRDATALEN 64 /* This is more than enough, think multiple TXT. */ +#define MAXRDATALEN 64 /* This is more than enough, think multiple TXT. */ #define MAX_RDLENGTH 65535 /* Maximum size of a single RR. */ @@ -168,6 +168,7 @@ enum rdata_wireformat RDATA_WF_SHORT, /* 16-bit integer. */ RDATA_WF_LONG, /* 32-bit integer. */ RDATA_WF_TEXT, /* Text string. */ + RDATA_WF_TEXTS, /* Text string sequence. */ RDATA_WF_A, /* 32-bit IPv4 address. */ RDATA_WF_AAAA, /* 128-bit IPv6 address. */ RDATA_WF_BINARY, /* Binary data (unknown length). */ @@ -185,6 +186,7 @@ enum rdata_zoneformat RDATA_ZF_DNAME, /* Domain name. */ RDATA_ZF_LITERAL_DNAME, /* DNS name (not lowercased domain name). */ RDATA_ZF_TEXT, /* Text string. */ + RDATA_ZF_TEXTS, /* Text string sequence. */ RDATA_ZF_BYTE, /* 8-bit integer. */ RDATA_ZF_SHORT, /* 16-bit integer. */ RDATA_ZF_LONG, /* 32-bit integer. */ @@ -215,8 +217,8 @@ struct rrtype_descriptor uint16_t type; /* RR type */ const char *name; /* Textual name. */ int token; /* Parser token. */ - uint8_t minimum; /* Minimum number of RDATAs. */ - uint8_t maximum; /* Maximum number of RDATAs. */ + uint32_t minimum; /* Minimum number of RDATAs. */ + uint32_t maximum; /* Maximum number of RDATAs. */ uint8_t wireformat[MAXRDATALEN]; /* rdata_wireformat_type */ uint8_t zoneformat[MAXRDATALEN]; /* rdata_zoneformat_type */ }; diff --git a/usr.sbin/nsd/mkinstalldirs b/usr.sbin/nsd/mkinstalldirs index 2c8850ef89b..a246f542699 100644 --- a/usr.sbin/nsd/mkinstalldirs +++ b/usr.sbin/nsd/mkinstalldirs @@ -4,7 +4,7 @@ # Created: 1993-05-16 # Public domain -# $Id: mkinstalldirs,v 1.1 2010/01/15 19:24:49 jakob Exp $ +# $Id: mkinstalldirs,v 1.2 2011/01/27 12:29:14 jakob Exp $ errstatus=0 diff --git a/usr.sbin/nsd/nsd-checkconf.c b/usr.sbin/nsd/nsd-checkconf.c index 8210bc65f91..e19cbd4c4b6 100644 --- a/usr.sbin/nsd/nsd-checkconf.c +++ b/usr.sbin/nsd/nsd-checkconf.c @@ -99,6 +99,7 @@ usage(void) fprintf(stderr, "-h Print this help information.\n"); fprintf(stderr, "-o option Print value of the option specified to stdout.\n"); fprintf(stderr, "-z zonename Print option value for the zone given.\n"); + fprintf(stderr, "-a keyname Print algorithm name for the TSIG key.\n"); fprintf(stderr, "-s keyname Print base64 secret blob for the TSIG key.\n"); exit(1); } @@ -184,7 +185,7 @@ print_acl(const char* varname, acl_options_t* acl) void -config_print_zone(nsd_options_t* opt, const char* k, const char *o, const char *z) +config_print_zone(nsd_options_t* opt, const char* k, int s, const char *o, const char *z) { zone_options_t* zone; ip_address_option_t* ip; @@ -194,7 +195,11 @@ config_print_zone(nsd_options_t* opt, const char* k, const char *o, const char * key_options_t* key = opt->keys; for( ; key ; key=key->next) { if(strcmp(key->name, k) == 0) { - quote(key->secret); + if (s) { + quote(key->secret); + } else { + quote(key->algorithm); + } return; } } @@ -456,14 +461,18 @@ main(int argc, char* argv[]) { int c; int verbose = 0; + int key_sec = 0; const char * conf_opt = NULL; /* what option do you want? Can be NULL -> print all */ const char * conf_zone = NULL; /* what zone are we talking about */ const char * conf_key = NULL; /* what key is needed */ const char* configfile; nsd_options_t *options; + log_init("nsd-checkconf"); + + /* Parse the command line... */ - while ((c = getopt(argc, argv, "vo:s:z:")) != -1) { + while ((c = getopt(argc, argv, "vo:a:s:z:")) != -1) { switch (c) { case 'v': verbose = 1; @@ -471,8 +480,20 @@ main(int argc, char* argv[]) case 'o': conf_opt = optarg; break; + case 'a': + if (conf_key) { + fprintf(stderr, "Error: cannot combine -a with -s or other -a.\n"); + exit(1); + } + conf_key = optarg; + break; case 's': + if (conf_key) { + fprintf(stderr, "Error: cannot combine -s with -a or other -s.\n"); + exit(1); + } conf_key = optarg; + key_sec = 1; break; case 'z': conf_zone = optarg; @@ -495,7 +516,7 @@ main(int argc, char* argv[]) exit(2); } if (conf_opt || conf_key) { - config_print_zone(options, conf_key, underscore(conf_opt), conf_zone); + config_print_zone(options, conf_key, key_sec, underscore(conf_opt), conf_zone); } else { if (verbose) { printf("# Read file %s: %d zones, %d keys.\n", diff --git a/usr.sbin/nsd/nsd-notify.c b/usr.sbin/nsd/nsd-notify.c index 5029cacc4b3..9929a3917a0 100644 --- a/usr.sbin/nsd/nsd-notify.c +++ b/usr.sbin/nsd/nsd-notify.c @@ -213,7 +213,7 @@ add_key(region_type* region, const char* opt, tsig_algorithm_type** algo) *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), "hmac-%s", delim2+1); + snprintf(by_name, 5+strlen(delim2), "%s", delim2+1); *algo = tsig_get_algorithm_by_name(by_name); free(by_name); *delim2 = '\0'; diff --git a/usr.sbin/nsd/nsd-patch.c b/usr.sbin/nsd/nsd-patch.c index 46d4afeebc6..ca429f5a578 100644 --- a/usr.sbin/nsd/nsd-patch.c +++ b/usr.sbin/nsd/nsd-patch.c @@ -57,7 +57,7 @@ list_xfr(FILE *in) return; } skiplen = len - (sizeof(uint32_t)*3 + sizeof(uint16_t) + strlen(zone_name)); - fprintf(stdout, "zone %s transfer id %x serial %d timestamp %u.%u: " + 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); @@ -243,7 +243,7 @@ write_to_zonefile(struct zone* zone, struct diff_log* commit_log) time_t now = time(0); FILE *out; - fprintf(stderr, "writing zone %s to file %s\n", zone->opts->name, + fprintf(stdout, "writing zone %s to file %s\n", zone->opts->name, filename); if(!zone->apex) { diff --git a/usr.sbin/nsd/nsdc.sh.in b/usr.sbin/nsd/nsdc.sh.in index c3dab0087f0..dd01812f643 100644 --- a/usr.sbin/nsd/nsdc.sh.in +++ b/usr.sbin/nsd/nsdc.sh.in @@ -230,20 +230,10 @@ do_reload() { signal "HUP" } -# send_updates zone_name ifc_spec {ip_spec key_spec} +# send_updates zone_name {ip_spec key_spec} send_updates() { local zonename=$1 - # set local interface - ifc_spec="" - if test I$2 = INOKEY; then - return - fi - if test I$2 != INOKEY -a I$2 != INOIFC; then - ifc_spec="-a $2" - fi - - shift 2 - + shift 1 # extract port number (if any) port=`${nsd_checkconf} -o port ${configfile}` if test -n "${port}"; then @@ -261,12 +251,12 @@ send_updates() { secret="" if test K${key_spec} != KNOKEY -a K${key_spec} != KBLOCKED; then secret=`${nsd_checkconf} -s ${key_spec} ${configfile}` - secret="-y ${key_spec}:${secret}" + 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 ${ifc_spec} ${port} -z ${zonename} ${ip_spec} # with ${key_spec}" - ${sbindir}/nsd-notify ${ifc_spec} ${port} ${secret} \ - -z ${zonename} ${ip_spec} && update_sent="yes" + #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 @@ -279,16 +269,12 @@ send_updates() { fi } -# send_notify zone_name {ifc_spec} {ip_spec key_spec} +# send_notify zone_name ifc_spec {ip_spec key_spec} send_notify() { local zonename=$1 # set local interface ifc_spec="" - if test I$2 = INOKEY; then - return - fi - - if test I$2 != INOKEY -a I$2 != INOIFC; then + if test I$2 != INOIFC; then ifc_spec="-a $2" fi shift 2 @@ -301,7 +287,8 @@ send_notify() { if test K${key_spec} != KNOKEY -a K${key_spec} != KBLOCKED; then secret=`${nsd_checkconf} -s ${key_spec} ${configfile}` - secret="-y ${key_spec}:${secret}" + algo=`${nsd_checkconf} -a ${key_spec} ${configfile}` + secret="-y ${key_spec}:${secret}:${algo}" fi if test K${key_spec} != KBLOCKED; then port="" @@ -310,9 +297,8 @@ send_notify() { 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} -z ${zonename} ${ip_spec} # with ${key_spec}" - ${sbindir}/nsd-notify ${ifc_spec} ${port} ${secret} \ - -z ${zonename} ${ipaddr} + #echo "${sbindir}/nsd-notify ${ifc_spec} ${port} ${secret} -z ${zonename} ${ipaddr}" + ${sbindir}/nsd-notify ${ifc_spec} ${port} ${secret} -z ${zonename} ${ipaddr} fi done } @@ -381,7 +367,7 @@ patch) mv ${difffile}.$$ ${difffile} fi echo "`basename $0`: patch failed." - return 1 + exit 1 fi else echo "`basename $0`: no patch necessary." @@ -397,14 +383,8 @@ update) zoneslist=`${nsd_checkconf} -o zones ${configfile}` for zonename in ${zoneslist}; do notify_allow=`${nsd_checkconf} -z "${zonename}" -o allow-notify ${configfile}` - local_ifc=`${nsd_checkconf} -z "${zonename}" -o outgoing-interface ${configfile}` - if test "" = "${local_ifc}"; then - local_ifc="NOIFC" - fi if test "" != "${notify_allow}"; then - for ifc in ${local_ifc}; do - send_updates ${zonename} ${ifc} ${notify_allow} - done + send_updates ${zonename} ${notify_allow} fi done else diff --git a/usr.sbin/nsd/nsec3.c b/usr.sbin/nsd/nsec3.c index b285e9a28be..8197d47c28b 100644 --- a/usr.sbin/nsd/nsec3.c +++ b/usr.sbin/nsd/nsec3.c @@ -475,7 +475,7 @@ nsec3_answer_wildcard(struct query *query, struct answer *answer, static void nsec3_add_ds_proof(struct query *query, struct answer *answer, - struct domain *domain) + struct domain *domain, int delegpt) { /* assert we are above the zone cut */ assert(domain != query->zone->apex); @@ -483,10 +483,14 @@ nsec3_add_ds_proof(struct query *query, struct answer *answer, /* use NSEC3 record from above the zone cut. */ nsec3_add_rrset(query, answer, AUTHORITY_SECTION, domain->nsec3_ds_parent_cover); + } else if (!delegpt && domain->nsec3_is_exact) { + nsec3_add_rrset(query, answer, AUTHORITY_SECTION, + domain->nsec3_cover); } else { /* prove closest provable encloser */ domain_type* par = domain->parent; domain_type* prev_par = 0; + while(par && !par->nsec3_is_exact) { prev_par = par; @@ -528,7 +532,7 @@ nsec3_answer_nodata(struct query *query, struct answer *answer, return; } /* query->zone must be the parent zone */ - nsec3_add_ds_proof(query, answer, original); + nsec3_add_ds_proof(query, answer, original, 0); } /* the nodata is result from a wildcard match */ else if (original==original->wildcard_child_closest_match @@ -554,7 +558,7 @@ nsec3_answer_delegation(struct query *query, struct answer *answer) { if(!query->zone->nsec3_soa_rr) return; - nsec3_add_ds_proof(query, answer, query->delegation_domain); + nsec3_add_ds_proof(query, answer, query->delegation_domain, 1); } int diff --git a/usr.sbin/nsd/query.c b/usr.sbin/nsd/query.c index 758d6e0877e..6e36fe036e3 100644 --- a/usr.sbin/nsd/query.c +++ b/usr.sbin/nsd/query.c @@ -39,9 +39,10 @@ #include "tsig.h" /* [Bug #253] Adding unnecessary NS RRset may lead to undesired truncation. - * This function determines if the final response packet needs the NS RRset included. - * Currently, it will only return negative if QTYPE == DNSKEY. This way, resolvers - * won't fallback to TCP unnecessarily when priming DNSKEYs. + * This function determines if the final response packet needs the NS RRset + * included. Currently, it will only return negative if QTYPE == DNSKEY|DS. + * This way, resolvers won't fallback to TCP unnecessarily when priming + * trust anchors. */ static int answer_needs_ns(struct query *query); @@ -176,12 +177,10 @@ query_create(region_type *region, uint16_t *compressed_dname_offsets, query->packet = buffer_create(region, QIOBUFSZ); region_add_cleanup(region, query_cleanup, query); query->compressed_dname_offsets_size = compressed_dname_size; -#ifdef TSIG tsig_create_record(&query->tsig, region); query->tsig_prepare_it = 1; query->tsig_update_it = 1; query->tsig_sign_it = 1; -#endif /* TSIG */ return query; } @@ -205,12 +204,10 @@ query_reset(query_type *q, size_t maxlen, int is_tcp) q->reserved_space = 0; buffer_clear(q->packet); edns_init_record(&q->edns); -#ifdef TSIG tsig_init_record(&q->tsig, NULL, NULL); q->tsig_prepare_it = 1; q->tsig_update_it = 1; q->tsig_sign_it = 1; -#endif /* TSIG */ q->tcp = is_tcp; q->qname = NULL; q->qtype = 0; @@ -355,7 +352,6 @@ process_edns(nsd_type* nsd, struct query *q) * Processes TSIG. * Sets error when tsig does not verify on the query. */ -#ifdef TSIG static nsd_rc_type process_tsig(struct query* q) { @@ -380,7 +376,6 @@ process_tsig(struct query* q) } return NSD_RC_OK; } -#endif /* TSIG */ /* * Check notify acl and forward to xfrd (or return an error). @@ -403,7 +398,6 @@ answer_notify(struct nsd* nsd, struct query *query) if(!nsd->this_child) /* we are in debug mode or something */ return query_error(query, NSD_RC_SERVFAIL); -#ifdef TSIG if(!tsig_find_rr(&query->tsig, query->packet)) { DEBUG(DEBUG_XFRD,2, (LOG_ERR, "bad tsig RR format")); return query_error(query, NSD_RC_FORMAT); @@ -411,7 +405,6 @@ answer_notify(struct nsd* nsd, struct query *query) rc = process_tsig(query); if(rc != NSD_RC_OK) return query_error(query, rc); -#endif /* TSIG */ /* check if it passes acl */ if((acl_num = acl_check_incoming(zone_opt->allow_notify, query, @@ -625,8 +618,9 @@ static int answer_needs_ns(struct query* query) { assert(query); - /* Currently, only troublesome for DNSKEYs, cuz their RRSETs are quite large. */ - return (query->qtype != TYPE_DNSKEY); + /* Currently, only troublesome for DNSKEY and DS, + * cuz their RRSETs are quite large. */ + return (query->qtype != TYPE_DNSKEY && query->qtype != TYPE_DS); } static int @@ -1220,9 +1214,7 @@ query_prepare_response(query_type *q) * Reserve space for the EDNS records if required. */ q->reserved_space = edns_reserved_space(&q->edns); -#ifdef TSIG q->reserved_space += tsig_reserved_space(&q->tsig); -#endif /* TSIG */ /* Update the flags. */ flags = FLAGS(q->packet); @@ -1292,7 +1284,6 @@ query_process(query_type *q, nsd_type *nsd) } arcount = ARCOUNT(q->packet); -#ifdef TSIG if (arcount > 0) { /* see if tsig is before edns record */ if (!tsig_parse_rr(&q->tsig, q->packet)) @@ -1300,12 +1291,10 @@ query_process(query_type *q, nsd_type *nsd) if(q->tsig.status != TSIG_NOT_PRESENT) --arcount; } -#endif /* TSIG */ if (arcount > 0) { if (edns_parse_record(&q->edns, q->packet)) --arcount; } -#ifdef TSIG if (arcount > 0 && q->tsig.status == TSIG_NOT_PRESENT) { /* see if tsig is after the edns record */ if (!tsig_parse_rr(&q->tsig, q->packet)) @@ -1313,7 +1302,6 @@ query_process(query_type *q, nsd_type *nsd) if(q->tsig.status != TSIG_NOT_PRESENT) --arcount; } -#endif /* TSIG */ if (arcount > 0) { return query_formerr(q); } @@ -1328,12 +1316,10 @@ query_process(query_type *q, nsd_type *nsd) /* Remove trailing garbage. */ buffer_set_limit(q->packet, buffer_position(q->packet)); -#ifdef TSIG rc = process_tsig(q); if (rc != NSD_RC_OK) { return query_error(q, rc); } -#endif /* TSIG */ rc = process_edns(nsd, q); if (rc != NSD_RC_OK) { /* We should not return FORMERR, but BADVERS (=16). @@ -1377,8 +1363,6 @@ query_add_optional(query_type *q, nsd_type *nsd) break; case EDNS_OK: buffer_write(q->packet, edns->ok, OPT_LEN); - /* check if nsid data should be written */ -#ifdef NSID if (nsd->nsid_len > 0 && q->edns.nsid == 1 && !query_overflow_nsid(q, nsd->nsid_len)) { /* rdata length */ @@ -1391,12 +1375,7 @@ query_add_optional(query_type *q, nsd_type *nsd) /* fill with NULLs */ buffer_write(q->packet, edns->rdata_none, OPT_RDATA); } -#else - buffer_write(q->packet, edns->rdata_none, OPT_RDATA); -#endif /* NSID */ - ARCOUNT_SET(q->packet, ARCOUNT(q->packet) + 1); - STATUP(nsd, edns); break; case EDNS_ERROR: @@ -1407,7 +1386,6 @@ query_add_optional(query_type *q, nsd_type *nsd) break; } -#ifdef TSIG if (q->tsig.status != TSIG_NOT_PRESENT) { if (q->tsig.status == TSIG_ERROR || q->tsig.error_code != TSIG_ERROR_NOERROR) { @@ -1428,5 +1406,4 @@ query_add_optional(query_type *q, nsd_type *nsd) } } } -#endif /* TSIG */ } diff --git a/usr.sbin/nsd/rdata.c b/usr.sbin/nsd/rdata.c index 26f4b703b8c..796eda55a94 100644 --- a/usr.sbin/nsd/rdata.c +++ b/usr.sbin/nsd/rdata.c @@ -87,11 +87,17 @@ rdata_dns_name_to_string(buffer_type *output, rdata_atom_type rdata, buffer_printf(output, "."); for (i = 1; i <= length; ++i) { - char ch = (char) data[i+offset]; - if (isprint((int)ch)) - buffer_printf(output, "%c", ch); - else - buffer_printf(output, "\\%03u", (unsigned) ch); + uint8_t ch = data[i+offset]; + + if (ch=='.' || ch==';' || ch=='(' || ch==')' || ch=='\\') { + buffer_printf(output, "\\%c", (char) ch); + } else if (!isgraph((int) ch)) { + buffer_printf(output, "\\%03u", (unsigned int) ch); + } else if (isprint((int) ch)) { + buffer_printf(output, "%c", (char) ch); + } else { + buffer_printf(output, "\\%03u", (unsigned int) ch); + } } /* next label */ offset = offset+length+1; @@ -128,6 +134,34 @@ rdata_text_to_string(buffer_type *output, rdata_atom_type rdata, } static int +rdata_texts_to_string(buffer_type *output, rdata_atom_type rdata, + rr_type* ATTR_UNUSED(rr)) +{ + uint16_t pos = 0; + const uint8_t *data = rdata_atom_data(rdata); + uint16_t length = rdata_atom_size(rdata); + size_t i; + + while (pos < length && pos + data[pos] < length) { + buffer_printf(output, "\""); + for (i = 1; i <= data[pos]; ++i) { + char ch = (char) data[pos + i]; + if (isprint((int)ch)) { + if (ch == '"' || ch == '\\') { + buffer_printf(output, "\\"); + } + buffer_printf(output, "%c", ch); + } else { + buffer_printf(output, "\\%03u", (unsigned) ch); + } + } + pos += data[pos]+1; + buffer_printf(output, pos < length?"\" ":"\""); + } + return 1; +} + +static int rdata_byte_to_string(buffer_type *output, rdata_atom_type rdata, rr_type* ATTR_UNUSED(rr)) { @@ -509,6 +543,7 @@ static rdata_to_string_type rdata_to_string_table[RDATA_ZF_UNKNOWN + 1] = { rdata_dname_to_string, rdata_dns_name_to_string, rdata_text_to_string, + rdata_texts_to_string, rdata_byte_to_string, rdata_short_to_string, rdata_long_to_string, @@ -549,7 +584,7 @@ rdata_wireformat_to_rdata_atoms(region_type *region, rdata_atom_type **rdatas) { size_t end = buffer_position(packet) + data_size; - ssize_t i; + size_t i; rdata_atom_type temp_rdatas[MAXRDATALEN]; rrtype_descriptor_type *descriptor = rrtype_descriptor_by_type(rrtype); region_type *temp_region; @@ -588,6 +623,9 @@ rdata_wireformat_to_rdata_atoms(region_type *region, case RDATA_WF_LONG: length = sizeof(uint32_t); break; + case RDATA_WF_TEXTS: + length = data_size; + break; case RDATA_WF_TEXT: case RDATA_WF_BINARYWITHLENGTH: /* Length is stored in the first byte. */ @@ -687,7 +725,7 @@ rdata_wireformat_to_rdata_atoms(region_type *region, *rdatas = (rdata_atom_type *) region_alloc_init( region, temp_rdatas, i * sizeof(rdata_atom_type)); region_destroy(temp_region); - return i; + return (ssize_t)i; } size_t diff --git a/usr.sbin/nsd/server.c b/usr.sbin/nsd/server.c index c0a84dafe0b..6640a653aa8 100644 --- a/usr.sbin/nsd/server.c +++ b/usr.sbin/nsd/server.c @@ -29,6 +29,9 @@ #include <unistd.h> #include <fcntl.h> #include <netdb.h> +#ifndef SHUT_WR +#define SHUT_WR 1 +#endif #include "axfr.h" #include "namedb.h" @@ -567,7 +570,7 @@ close_all_sockets(struct nsd_socket sockets[], size_t n) for (i = 0; i < n; ++i) { if (sockets[i].s != -1) { close(sockets[i].s); - free(sockets[i].addr); + freeaddrinfo(sockets[i].addr); sockets[i].s = -1; } } @@ -771,6 +774,16 @@ server_reload(struct nsd *nsd, region_type* server_region, netio_type* netio, exit(1); } + /* if the parent has quit, we must quit too, poll the fd for cmds */ + if(block_read(nsd, cmdsocket, &cmd, sizeof(cmd), 0) == sizeof(cmd)) { + DEBUG(DEBUG_IPC,1, (LOG_INFO, "reload: ipc command from main %d", cmd)); + if(cmd == NSD_QUIT) { + DEBUG(DEBUG_IPC,1, (LOG_INFO, "reload: quit to follow nsd")); + send_children_quit(nsd); + exit(0); + } + } + /* Overwrite pid before closing old parent, to avoid race condition: * - parent process already closed * - pidfile still contains old_pid @@ -802,6 +815,12 @@ server_reload(struct nsd *nsd, region_type* server_region, netio_type* netio, strerror(errno)); } DEBUG(DEBUG_IPC,1, (LOG_INFO, "reload: ipc reply main %d %d", ret, cmd)); + if(cmd == NSD_QUIT) { + /* small race condition possible here, parent got quit cmd. */ + send_children_quit(nsd); + unlinkpid(nsd->pidfile); + exit(1); + } assert(ret==-1 || ret == 0 || cmd == NSD_RELOAD); /* inform xfrd of new SOAs */ @@ -1114,8 +1133,8 @@ server_main(struct nsd *nsd) /* only quit children after xfrd has acked */ send_children_quit(nsd); + namedb_fd_close(nsd->db); region_destroy(server_region); - namedb_close(nsd->db); server_shutdown(nsd); /* ENOTREACH */ @@ -1150,8 +1169,17 @@ server_main(struct nsd *nsd) /* Unlink it if possible... */ unlinkpid(nsd->pidfile); - if(reload_listener.fd > 0) + if(reload_listener.fd > 0) { + sig_atomic_t cmd = NSD_QUIT; + DEBUG(DEBUG_IPC,1, (LOG_INFO, + "main: ipc send quit to reload-process")); + if(!write_socket(reload_listener.fd, &cmd, sizeof(cmd))) { + log_msg(LOG_ERR, "server_main: could not send quit to reload: %s", + strerror(errno)); + } + fsync(reload_listener.fd); close(reload_listener.fd); + } if(xfrd_listener.fd > 0) { /* complete quit, stop xfrd */ sig_atomic_t cmd = NSD_QUIT; @@ -1165,7 +1193,7 @@ server_main(struct nsd *nsd) close(xfrd_listener.fd); } - namedb_close(nsd->db); + namedb_fd_close(nsd->db); region_destroy(server_region); server_shutdown(nsd); } @@ -1324,7 +1352,7 @@ server_child(struct nsd *nsd) bind8_stats(nsd); #endif /* BIND8_STATS */ - namedb_close(nsd->db); + namedb_fd_close(nsd->db); region_destroy(server_region); server_shutdown(nsd); } diff --git a/usr.sbin/nsd/util.c b/usr.sbin/nsd/util.c index c9f41aedde3..ab374c2b3e0 100644 --- a/usr.sbin/nsd/util.c +++ b/usr.sbin/nsd/util.c @@ -834,7 +834,13 @@ compare_serial(uint32_t a, uint32_t b) uint16_t qid_generate(void) { - return (uint16_t) arc4random(); +#ifdef HAVE_ARC4RANDOM_UNIFORM + return (uint16_t) arc4random_uniform(65536); +#elif HAVE_ARC4RANDOM + return (uint16_t) arc4random(); +#else + return (uint16_t) random(); +#endif } void diff --git a/usr.sbin/nsd/zonec.c b/usr.sbin/nsd/zonec.c index 34a58569def..f7a63c26658 100644 --- a/usr.sbin/nsd/zonec.c +++ b/usr.sbin/nsd/zonec.c @@ -935,7 +935,7 @@ zparser_ttl2int(const char *ttlstr, int* error) void zadd_rdata_wireformat(uint16_t *data) { - if (parser->current_rr.rdata_count > MAXRDATALEN) { + if (parser->current_rr.rdata_count >= MAXRDATALEN) { zc_error_prev_line("too many rdata elements"); } else { parser->current_rr.rdatas[parser->current_rr.rdata_count].data @@ -944,10 +944,62 @@ zadd_rdata_wireformat(uint16_t *data) } } +/** + * Used for TXT RR's to grow with undefined number of strings. + */ +void +zadd_rdata_txt_wireformat(uint16_t *data, int first) +{ + rdata_atom_type *rd; + + /* First STR in str_seq, allocate 65K in first unused rdata + * else find last used rdata */ + if (first) { + rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count]; + if ((rd->data = (uint16_t *) region_alloc(parser->rr_region, + sizeof(uint16_t) + 65535 * sizeof(uint8_t))) == NULL) { + zc_error_prev_line("Could not allocate memory for TXT RR"); + return; + } + parser->current_rr.rdata_count++; + rd->data[0] = 0; + } + else + rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1]; + + if ((size_t)rd->data[0] + (size_t)data[0] > 65535) { + zc_error_prev_line("too large rdata element"); + return; + } + + memcpy((uint8_t *)rd->data + 2 + rd->data[0], data + 1, data[0]); + rd->data[0] += data[0]; +} + +/** + * Clean up after last call of zadd_rdata_txt_wireformat + */ +void +zadd_rdata_txt_clean_wireformat() +{ + uint16_t *tmp_data; + rdata_atom_type *rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1]; + if ((tmp_data = (uint16_t *) region_alloc(parser->region, + rd->data[0] + 2)) != NULL) { + memcpy(tmp_data, rd->data, rd->data[0] + 2); + rd->data = tmp_data; + } + else { + /* We could not get memory in non-volatile region */ + zc_error_prev_line("could not allocate memory for rdata"); + return; + } +} + void zadd_rdata_domain(domain_type *domain) { - if (parser->current_rr.rdata_count > MAXRDATALEN) { + if (parser->current_rr.rdata_count >= MAXRDATALEN) { zc_error_prev_line("too many rdata elements"); } else { parser->current_rr.rdatas[parser->current_rr.rdata_count].domain @@ -1260,10 +1312,10 @@ domain_find_rrset_any(domain_type *domain, uint16_t type) while (result) { if (rrset_rrtype(result) == type) { return result; - } + } result = result->next; - } - return NULL; + } + return NULL; } /* @@ -1556,8 +1608,12 @@ main (int argc, char **argv) /* Print the total number of errors */ if (vflag > 0 || totalerrors > 0) { - fprintf(stderr, "\nnsd-zonec: done with %ld errors.\n", + if (totalerrors > 0) { + fprintf(stderr, "\nnsd-zonec: done with %ld errors.\n", totalerrors); + } else { + fprintf(stdout, "\nnsd-zonec: done with no errors.\n"); + } } /* Disable this to save some time. */ diff --git a/usr.sbin/nsd/zonec.h b/usr.sbin/nsd/zonec.h index f732377740d..9bf7a4b6642 100644 --- a/usr.sbin/nsd/zonec.h +++ b/usr.sbin/nsd/zonec.h @@ -108,6 +108,8 @@ void parse_unknown_rdata(uint16_t type, uint16_t *wireformat); uint32_t zparser_ttl2int(const char *ttlstr, int* error); void zadd_rdata_wireformat(uint16_t *data); +void zadd_rdata_txt_wireformat(uint16_t *data, int first); +void zadd_rdata_txt_clean_wireformat(); void zadd_rdata_domain(domain_type *domain); void set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE], diff --git a/usr.sbin/nsd/zparser.y b/usr.sbin/nsd/zparser.y index 0b50b172ede..a5e896553dd 100644 --- a/usr.sbin/nsd/zparser.y +++ b/usr.sbin/nsd/zparser.y @@ -334,11 +334,11 @@ wire_rel_dname: wire_label str_seq: STR { - zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); + zadd_rdata_txt_wireformat(zparser_conv_text(parser->region, $1.str, $1.len), 1); } | str_seq sp STR { - zadd_rdata_wireformat(zparser_conv_text(parser->region, $3.str, $3.len)); + zadd_rdata_txt_wireformat(zparser_conv_text(parser->region, $3.str, $3.len), 0); } ; @@ -661,6 +661,9 @@ rdata_mx: STR sp dname trail ; rdata_txt: str_seq trail + { + zadd_rdata_txt_clean_wireformat(); + } ; /* RFC 1183 */ |