diff options
Diffstat (limited to 'contrib/bind9/bin/check/check-tool.c')
-rw-r--r-- | contrib/bind9/bin/check/check-tool.c | 697 |
1 files changed, 0 insertions, 697 deletions
diff --git a/contrib/bind9/bin/check/check-tool.c b/contrib/bind9/bin/check/check-tool.c deleted file mode 100644 index 1e534071d0c8..000000000000 --- a/contrib/bind9/bin/check/check-tool.c +++ /dev/null @@ -1,697 +0,0 @@ -/* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: check-tool.c,v 1.44 2011/12/22 07:32:39 each Exp $ */ - -/*! \file */ - -#include <config.h> - -#include <stdio.h> - -#ifdef _WIN32 -#include <Winsock2.h> -#endif - -#include "check-tool.h" -#include <isc/buffer.h> -#include <isc/log.h> -#include <isc/mem.h> -#include <isc/netdb.h> -#include <isc/net.h> -#include <isc/region.h> -#include <isc/stdio.h> -#include <isc/string.h> -#include <isc/symtab.h> -#include <isc/types.h> -#include <isc/util.h> - -#include <dns/fixedname.h> -#include <dns/log.h> -#include <dns/name.h> -#include <dns/rdata.h> -#include <dns/rdataclass.h> -#include <dns/rdataset.h> -#include <dns/types.h> -#include <dns/zone.h> - -#include <isccfg/log.h> - -#ifndef CHECK_SIBLING -#define CHECK_SIBLING 1 -#endif - -#ifndef CHECK_LOCAL -#define CHECK_LOCAL 1 -#endif - -#ifdef HAVE_ADDRINFO -#ifdef HAVE_GETADDRINFO -#ifdef HAVE_GAISTRERROR -#define USE_GETADDRINFO -#endif -#endif -#endif - -#define CHECK(r) \ - do { \ - result = (r); \ - if (result != ISC_R_SUCCESS) \ - goto cleanup; \ - } while (0) - -#define ERR_IS_CNAME 1 -#define ERR_NO_ADDRESSES 2 -#define ERR_LOOKUP_FAILURE 3 -#define ERR_EXTRA_A 4 -#define ERR_EXTRA_AAAA 5 -#define ERR_MISSING_GLUE 5 -#define ERR_IS_MXCNAME 6 -#define ERR_IS_SRVCNAME 7 - -static const char *dbtype[] = { "rbt" }; - -int debug = 0; -isc_boolean_t nomerge = ISC_TRUE; -#if CHECK_LOCAL -isc_boolean_t docheckmx = ISC_TRUE; -isc_boolean_t dochecksrv = ISC_TRUE; -isc_boolean_t docheckns = ISC_TRUE; -#else -isc_boolean_t docheckmx = ISC_FALSE; -isc_boolean_t dochecksrv = ISC_FALSE; -isc_boolean_t docheckns = ISC_FALSE; -#endif -unsigned int zone_options = DNS_ZONEOPT_CHECKNS | - DNS_ZONEOPT_CHECKMX | - DNS_ZONEOPT_MANYERRORS | - DNS_ZONEOPT_CHECKNAMES | - DNS_ZONEOPT_CHECKINTEGRITY | -#if CHECK_SIBLING - DNS_ZONEOPT_CHECKSIBLING | -#endif - DNS_ZONEOPT_CHECKWILDCARD | - DNS_ZONEOPT_WARNMXCNAME | - DNS_ZONEOPT_WARNSRVCNAME; - -/* - * This needs to match the list in bin/named/log.c. - */ -static isc_logcategory_t categories[] = { - { "", 0 }, - { "client", 0 }, - { "network", 0 }, - { "update", 0 }, - { "queries", 0 }, - { "unmatched", 0 }, - { "update-security", 0 }, - { "query-errors", 0 }, - { NULL, 0 } -}; - -static isc_symtab_t *symtab = NULL; -static isc_mem_t *sym_mctx; - -static void -freekey(char *key, unsigned int type, isc_symvalue_t value, void *userarg) { - UNUSED(type); - UNUSED(value); - isc_mem_free(userarg, key); -} - -static void -add(char *key, int value) { - isc_result_t result; - isc_symvalue_t symvalue; - - if (sym_mctx == NULL) { - result = isc_mem_create(0, 0, &sym_mctx); - if (result != ISC_R_SUCCESS) - return; - } - - if (symtab == NULL) { - result = isc_symtab_create(sym_mctx, 100, freekey, sym_mctx, - ISC_FALSE, &symtab); - if (result != ISC_R_SUCCESS) - return; - } - - key = isc_mem_strdup(sym_mctx, key); - if (key == NULL) - return; - - symvalue.as_pointer = NULL; - result = isc_symtab_define(symtab, key, value, symvalue, - isc_symexists_reject); - if (result != ISC_R_SUCCESS) - isc_mem_free(sym_mctx, key); -} - -static isc_boolean_t -logged(char *key, int value) { - isc_result_t result; - - if (symtab == NULL) - return (ISC_FALSE); - - result = isc_symtab_lookup(symtab, key, value, NULL); - if (result == ISC_R_SUCCESS) - return (ISC_TRUE); - return (ISC_FALSE); -} - -static isc_boolean_t -checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner, - dns_rdataset_t *a, dns_rdataset_t *aaaa) -{ -#ifdef USE_GETADDRINFO - dns_rdataset_t *rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - struct addrinfo hints, *ai, *cur; - char namebuf[DNS_NAME_FORMATSIZE + 1]; - char ownerbuf[DNS_NAME_FORMATSIZE]; - char addrbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123")]; - isc_boolean_t answer = ISC_TRUE; - isc_boolean_t match; - const char *type; - void *ptr = NULL; - int result; - - REQUIRE(a == NULL || !dns_rdataset_isassociated(a) || - a->type == dns_rdatatype_a); - REQUIRE(aaaa == NULL || !dns_rdataset_isassociated(aaaa) || - aaaa->type == dns_rdatatype_aaaa); - - if (a == NULL || aaaa == NULL) - return (answer); - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_CANONNAME; - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - dns_name_format(name, namebuf, sizeof(namebuf) - 1); - /* - * Turn off search. - */ - if (dns_name_countlabels(name) > 1U) - strcat(namebuf, "."); - dns_name_format(owner, ownerbuf, sizeof(ownerbuf)); - - result = getaddrinfo(namebuf, NULL, &hints, &ai); - dns_name_format(name, namebuf, sizeof(namebuf) - 1); - switch (result) { - case 0: - /* - * Work around broken getaddrinfo() implementations that - * fail to set ai_canonname on first entry. - */ - cur = ai; - while (cur != NULL && cur->ai_canonname == NULL && - cur->ai_next != NULL) - cur = cur->ai_next; - if (cur != NULL && cur->ai_canonname != NULL && - strcasecmp(cur->ai_canonname, namebuf) != 0 && - !logged(namebuf, ERR_IS_CNAME)) { - dns_zone_log(zone, ISC_LOG_ERROR, - "%s/NS '%s' (out of zone) " - "is a CNAME '%s' (illegal)", - ownerbuf, namebuf, - cur->ai_canonname); - /* XXX950 make fatal for 9.5.0 */ - /* answer = ISC_FALSE; */ - add(namebuf, ERR_IS_CNAME); - } - break; - case EAI_NONAME: -#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) - case EAI_NODATA: -#endif - if (!logged(namebuf, ERR_NO_ADDRESSES)) { - dns_zone_log(zone, ISC_LOG_ERROR, - "%s/NS '%s' (out of zone) " - "has no addresses records (A or AAAA)", - ownerbuf, namebuf); - add(namebuf, ERR_NO_ADDRESSES); - } - /* XXX950 make fatal for 9.5.0 */ - return (ISC_TRUE); - - default: - if (!logged(namebuf, ERR_LOOKUP_FAILURE)) { - dns_zone_log(zone, ISC_LOG_WARNING, - "getaddrinfo(%s) failed: %s", - namebuf, gai_strerror(result)); - add(namebuf, ERR_LOOKUP_FAILURE); - } - return (ISC_TRUE); - } - - /* - * Check that all glue records really exist. - */ - if (!dns_rdataset_isassociated(a)) - goto checkaaaa; - result = dns_rdataset_first(a); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(a, &rdata); - match = ISC_FALSE; - for (cur = ai; cur != NULL; cur = cur->ai_next) { - if (cur->ai_family != AF_INET) - continue; - ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr; - if (memcmp(ptr, rdata.data, rdata.length) == 0) { - match = ISC_TRUE; - break; - } - } - if (!match && !logged(namebuf, ERR_EXTRA_A)) { - dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' " - "extra GLUE A record (%s)", - ownerbuf, namebuf, - inet_ntop(AF_INET, rdata.data, - addrbuf, sizeof(addrbuf))); - add(namebuf, ERR_EXTRA_A); - /* XXX950 make fatal for 9.5.0 */ - /* answer = ISC_FALSE; */ - } - dns_rdata_reset(&rdata); - result = dns_rdataset_next(a); - } - - checkaaaa: - if (!dns_rdataset_isassociated(aaaa)) - goto checkmissing; - result = dns_rdataset_first(aaaa); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(aaaa, &rdata); - match = ISC_FALSE; - for (cur = ai; cur != NULL; cur = cur->ai_next) { - if (cur->ai_family != AF_INET6) - continue; - ptr = &((struct sockaddr_in6 *)(cur->ai_addr))->sin6_addr; - if (memcmp(ptr, rdata.data, rdata.length) == 0) { - match = ISC_TRUE; - break; - } - } - if (!match && !logged(namebuf, ERR_EXTRA_AAAA)) { - dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' " - "extra GLUE AAAA record (%s)", - ownerbuf, namebuf, - inet_ntop(AF_INET6, rdata.data, - addrbuf, sizeof(addrbuf))); - add(namebuf, ERR_EXTRA_AAAA); - /* XXX950 make fatal for 9.5.0. */ - /* answer = ISC_FALSE; */ - } - dns_rdata_reset(&rdata); - result = dns_rdataset_next(aaaa); - } - - checkmissing: - /* - * Check that all addresses appear in the glue. - */ - if (!logged(namebuf, ERR_MISSING_GLUE)) { - isc_boolean_t missing_glue = ISC_FALSE; - for (cur = ai; cur != NULL; cur = cur->ai_next) { - switch (cur->ai_family) { - case AF_INET: - rdataset = a; - ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr; - type = "A"; - break; - case AF_INET6: - rdataset = aaaa; - ptr = &((struct sockaddr_in6 *)(cur->ai_addr))->sin6_addr; - type = "AAAA"; - break; - default: - continue; - } - match = ISC_FALSE; - if (dns_rdataset_isassociated(rdataset)) - result = dns_rdataset_first(rdataset); - else - result = ISC_R_FAILURE; - while (result == ISC_R_SUCCESS && !match) { - dns_rdataset_current(rdataset, &rdata); - if (memcmp(ptr, rdata.data, rdata.length) == 0) - match = ISC_TRUE; - dns_rdata_reset(&rdata); - result = dns_rdataset_next(rdataset); - } - if (!match) { - dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' " - "missing GLUE %s record (%s)", - ownerbuf, namebuf, type, - inet_ntop(cur->ai_family, ptr, - addrbuf, sizeof(addrbuf))); - /* XXX950 make fatal for 9.5.0. */ - /* answer = ISC_FALSE; */ - missing_glue = ISC_TRUE; - } - } - if (missing_glue) - add(namebuf, ERR_MISSING_GLUE); - } - freeaddrinfo(ai); - return (answer); -#else - return (ISC_TRUE); -#endif -} - -static isc_boolean_t -checkmx(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) { -#ifdef USE_GETADDRINFO - struct addrinfo hints, *ai, *cur; - char namebuf[DNS_NAME_FORMATSIZE + 1]; - char ownerbuf[DNS_NAME_FORMATSIZE]; - int result; - int level = ISC_LOG_ERROR; - isc_boolean_t answer = ISC_TRUE; - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_CANONNAME; - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - dns_name_format(name, namebuf, sizeof(namebuf) - 1); - /* - * Turn off search. - */ - if (dns_name_countlabels(name) > 1U) - strcat(namebuf, "."); - dns_name_format(owner, ownerbuf, sizeof(ownerbuf)); - - result = getaddrinfo(namebuf, NULL, &hints, &ai); - dns_name_format(name, namebuf, sizeof(namebuf) - 1); - switch (result) { - case 0: - /* - * Work around broken getaddrinfo() implementations that - * fail to set ai_canonname on first entry. - */ - cur = ai; - while (cur != NULL && cur->ai_canonname == NULL && - cur->ai_next != NULL) - cur = cur->ai_next; - if (cur != NULL && cur->ai_canonname != NULL && - strcasecmp(cur->ai_canonname, namebuf) != 0) { - if ((zone_options & DNS_ZONEOPT_WARNMXCNAME) != 0) - level = ISC_LOG_WARNING; - if ((zone_options & DNS_ZONEOPT_IGNOREMXCNAME) == 0) { - if (!logged(namebuf, ERR_IS_MXCNAME)) { - dns_zone_log(zone, level, - "%s/MX '%s' (out of zone)" - " is a CNAME '%s' " - "(illegal)", - ownerbuf, namebuf, - cur->ai_canonname); - add(namebuf, ERR_IS_MXCNAME); - } - if (level == ISC_LOG_ERROR) - answer = ISC_FALSE; - } - } - freeaddrinfo(ai); - return (answer); - - case EAI_NONAME: -#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) - case EAI_NODATA: -#endif - if (!logged(namebuf, ERR_NO_ADDRESSES)) { - dns_zone_log(zone, ISC_LOG_ERROR, - "%s/MX '%s' (out of zone) " - "has no addresses records (A or AAAA)", - ownerbuf, namebuf); - add(namebuf, ERR_NO_ADDRESSES); - } - /* XXX950 make fatal for 9.5.0. */ - return (ISC_TRUE); - - default: - if (!logged(namebuf, ERR_LOOKUP_FAILURE)) { - dns_zone_log(zone, ISC_LOG_WARNING, - "getaddrinfo(%s) failed: %s", - namebuf, gai_strerror(result)); - add(namebuf, ERR_LOOKUP_FAILURE); - } - return (ISC_TRUE); - } -#else - return (ISC_TRUE); -#endif -} - -static isc_boolean_t -checksrv(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) { -#ifdef USE_GETADDRINFO - struct addrinfo hints, *ai, *cur; - char namebuf[DNS_NAME_FORMATSIZE + 1]; - char ownerbuf[DNS_NAME_FORMATSIZE]; - int result; - int level = ISC_LOG_ERROR; - isc_boolean_t answer = ISC_TRUE; - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_CANONNAME; - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - dns_name_format(name, namebuf, sizeof(namebuf) - 1); - /* - * Turn off search. - */ - if (dns_name_countlabels(name) > 1U) - strcat(namebuf, "."); - dns_name_format(owner, ownerbuf, sizeof(ownerbuf)); - - result = getaddrinfo(namebuf, NULL, &hints, &ai); - dns_name_format(name, namebuf, sizeof(namebuf) - 1); - switch (result) { - case 0: - /* - * Work around broken getaddrinfo() implementations that - * fail to set ai_canonname on first entry. - */ - cur = ai; - while (cur != NULL && cur->ai_canonname == NULL && - cur->ai_next != NULL) - cur = cur->ai_next; - if (cur != NULL && cur->ai_canonname != NULL && - strcasecmp(cur->ai_canonname, namebuf) != 0) { - if ((zone_options & DNS_ZONEOPT_WARNSRVCNAME) != 0) - level = ISC_LOG_WARNING; - if ((zone_options & DNS_ZONEOPT_IGNORESRVCNAME) == 0) { - if (!logged(namebuf, ERR_IS_SRVCNAME)) { - dns_zone_log(zone, level, "%s/SRV '%s'" - " (out of zone) is a " - "CNAME '%s' (illegal)", - ownerbuf, namebuf, - cur->ai_canonname); - add(namebuf, ERR_IS_SRVCNAME); - } - if (level == ISC_LOG_ERROR) - answer = ISC_FALSE; - } - } - freeaddrinfo(ai); - return (answer); - - case EAI_NONAME: -#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) - case EAI_NODATA: -#endif - if (!logged(namebuf, ERR_NO_ADDRESSES)) { - dns_zone_log(zone, ISC_LOG_ERROR, - "%s/SRV '%s' (out of zone) " - "has no addresses records (A or AAAA)", - ownerbuf, namebuf); - add(namebuf, ERR_NO_ADDRESSES); - } - /* XXX950 make fatal for 9.5.0. */ - return (ISC_TRUE); - - default: - if (!logged(namebuf, ERR_LOOKUP_FAILURE)) { - dns_zone_log(zone, ISC_LOG_WARNING, - "getaddrinfo(%s) failed: %s", - namebuf, gai_strerror(result)); - add(namebuf, ERR_LOOKUP_FAILURE); - } - return (ISC_TRUE); - } -#else - return (ISC_TRUE); -#endif -} - -isc_result_t -setup_logging(isc_mem_t *mctx, FILE *errout, isc_log_t **logp) { - isc_logdestination_t destination; - isc_logconfig_t *logconfig = NULL; - isc_log_t *log = NULL; - - RUNTIME_CHECK(isc_log_create(mctx, &log, &logconfig) == ISC_R_SUCCESS); - isc_log_registercategories(log, categories); - isc_log_setcontext(log); - dns_log_init(log); - dns_log_setcontext(log); - cfg_log_init(log); - - destination.file.stream = errout; - destination.file.name = NULL; - destination.file.versions = ISC_LOG_ROLLNEVER; - destination.file.maximum_size = 0; - RUNTIME_CHECK(isc_log_createchannel(logconfig, "stderr", - ISC_LOG_TOFILEDESC, - ISC_LOG_DYNAMIC, - &destination, 0) == ISC_R_SUCCESS); - RUNTIME_CHECK(isc_log_usechannel(logconfig, "stderr", - NULL, NULL) == ISC_R_SUCCESS); - - *logp = log; - return (ISC_R_SUCCESS); -} - -/*% load the zone */ -isc_result_t -load_zone(isc_mem_t *mctx, const char *zonename, const char *filename, - dns_masterformat_t fileformat, const char *classname, - dns_zone_t **zonep) -{ - isc_result_t result; - dns_rdataclass_t rdclass; - isc_textregion_t region; - isc_buffer_t buffer; - dns_fixedname_t fixorigin; - dns_name_t *origin; - dns_zone_t *zone = NULL; - - REQUIRE(zonep == NULL || *zonep == NULL); - - if (debug) - fprintf(stderr, "loading \"%s\" from \"%s\" class \"%s\"\n", - zonename, filename, classname); - - CHECK(dns_zone_create(&zone, mctx)); - - dns_zone_settype(zone, dns_zone_master); - - isc_buffer_constinit(&buffer, zonename, strlen(zonename)); - isc_buffer_add(&buffer, strlen(zonename)); - dns_fixedname_init(&fixorigin); - origin = dns_fixedname_name(&fixorigin); - CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, 0, NULL)); - CHECK(dns_zone_setorigin(zone, origin)); - CHECK(dns_zone_setdbtype(zone, 1, (const char * const *) dbtype)); - CHECK(dns_zone_setfile2(zone, filename, fileformat)); - - DE_CONST(classname, region.base); - region.length = strlen(classname); - CHECK(dns_rdataclass_fromtext(&rdclass, ®ion)); - - dns_zone_setclass(zone, rdclass); - dns_zone_setoption(zone, zone_options, ISC_TRUE); - dns_zone_setoption(zone, DNS_ZONEOPT_NOMERGE, nomerge); - if (docheckmx) - dns_zone_setcheckmx(zone, checkmx); - if (docheckns) - dns_zone_setcheckns(zone, checkns); - if (dochecksrv) - dns_zone_setchecksrv(zone, checksrv); - - CHECK(dns_zone_load(zone)); - if (zonep != NULL) { - *zonep = zone; - zone = NULL; - } - - cleanup: - if (zone != NULL) - dns_zone_detach(&zone); - return (result); -} - -/*% dump the zone */ -isc_result_t -dump_zone(const char *zonename, dns_zone_t *zone, const char *filename, - dns_masterformat_t fileformat, const dns_master_style_t *style, - const isc_uint32_t rawversion) -{ - isc_result_t result; - FILE *output = stdout; - const char *flags; - - flags = (fileformat == dns_masterformat_text) ? "w+" : "wb+"; - - if (debug) { - if (filename != NULL && strcmp(filename, "-") != 0) - fprintf(stderr, "dumping \"%s\" to \"%s\"\n", - zonename, filename); - else - fprintf(stderr, "dumping \"%s\"\n", zonename); - } - - if (filename != NULL && strcmp(filename, "-") != 0) { - result = isc_stdio_open(filename, flags, &output); - - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "could not open output " - "file \"%s\" for writing\n", filename); - return (ISC_R_FAILURE); - } - } - - result = dns_zone_dumptostream3(zone, output, fileformat, style, - rawversion); - if (output != stdout) - (void)isc_stdio_close(output); - - return (result); -} - -#ifdef _WIN32 -void -InitSockets(void) { - WORD wVersionRequested; - WSADATA wsaData; - int err; - - wVersionRequested = MAKEWORD(2, 0); - - err = WSAStartup( wVersionRequested, &wsaData ); - if (err != 0) { - fprintf(stderr, "WSAStartup() failed: %d\n", err); - exit(1); - } -} - -void -DestroySockets(void) { - WSACleanup(); -} -#endif - |