"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.11.23/bin/check/check-tool.c" (7 Sep 2020, 20230 Bytes) of package /linux/misc/dns/bind9/9.11.23/bind-9.11.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "check-tool.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 
   13 /*! \file */
   14 
   15 #include <config.h>
   16 
   17 #include <stdbool.h>
   18 #include <stdio.h>
   19 #include <inttypes.h>
   20 
   21 #ifdef _WIN32
   22 #include <Winsock2.h>
   23 #endif
   24 
   25 #include "check-tool.h"
   26 #include <isc/buffer.h>
   27 #include <isc/log.h>
   28 #include <isc/mem.h>
   29 #include <isc/netdb.h>
   30 #include <isc/net.h>
   31 #include <isc/print.h>
   32 #include <isc/region.h>
   33 #include <isc/stdio.h>
   34 #include <isc/string.h>
   35 #include <isc/symtab.h>
   36 #include <isc/types.h>
   37 #include <isc/util.h>
   38 
   39 #include <dns/db.h>
   40 #include <dns/dbiterator.h>
   41 #include <dns/fixedname.h>
   42 #include <dns/log.h>
   43 #include <dns/name.h>
   44 #include <dns/rdata.h>
   45 #include <dns/rdataclass.h>
   46 #include <dns/rdataset.h>
   47 #include <dns/rdatasetiter.h>
   48 #include <dns/rdatatype.h>
   49 #include <dns/result.h>
   50 #include <dns/types.h>
   51 #include <dns/zone.h>
   52 
   53 #include <isccfg/log.h>
   54 
   55 #ifndef CHECK_SIBLING
   56 #define CHECK_SIBLING 1
   57 #endif
   58 
   59 #ifndef CHECK_LOCAL
   60 #define CHECK_LOCAL 1
   61 #endif
   62 
   63 #ifdef HAVE_ADDRINFO
   64 #ifdef HAVE_GETADDRINFO
   65 #ifdef HAVE_GAISTRERROR
   66 #define USE_GETADDRINFO
   67 #endif
   68 #endif
   69 #endif
   70 
   71 #define CHECK(r) \
   72     do { \
   73         result = (r); \
   74         if (result != ISC_R_SUCCESS) \
   75             goto cleanup; \
   76     } while (0)
   77 
   78 #define ERR_IS_CNAME 1
   79 #define ERR_NO_ADDRESSES 2
   80 #define ERR_LOOKUP_FAILURE 3
   81 #define ERR_EXTRA_A 4
   82 #define ERR_EXTRA_AAAA 5
   83 #define ERR_MISSING_GLUE 5
   84 #define ERR_IS_MXCNAME 6
   85 #define ERR_IS_SRVCNAME 7
   86 
   87 static const char *dbtype[] = { "rbt" };
   88 
   89 int debug = 0;
   90 const char *journal = NULL;
   91 bool nomerge = true;
   92 #if CHECK_LOCAL
   93 bool docheckmx = true;
   94 bool dochecksrv = true;
   95 bool docheckns = true;
   96 #else
   97 bool docheckmx = false;
   98 bool dochecksrv = false;
   99 bool docheckns = false;
  100 #endif
  101 unsigned int zone_options = DNS_ZONEOPT_CHECKNS |
  102                 DNS_ZONEOPT_CHECKMX |
  103                 DNS_ZONEOPT_MANYERRORS |
  104                 DNS_ZONEOPT_CHECKNAMES |
  105                 DNS_ZONEOPT_CHECKINTEGRITY |
  106 #if CHECK_SIBLING
  107                 DNS_ZONEOPT_CHECKSIBLING |
  108 #endif
  109                 DNS_ZONEOPT_CHECKWILDCARD |
  110                 DNS_ZONEOPT_WARNMXCNAME |
  111                 DNS_ZONEOPT_WARNSRVCNAME;
  112 unsigned int zone_options2 = 0;
  113 
  114 /*
  115  * This needs to match the list in bin/named/log.c.
  116  */
  117 static isc_logcategory_t categories[] = {
  118     { "",            0 },
  119     { "client",      0 },
  120     { "network",         0 },
  121     { "update",      0 },
  122     { "queries",         0 },
  123     { "unmatched",       0 },
  124     { "update-security", 0 },
  125     { "query-errors",    0 },
  126     { "trust-anchor-telemetry",    0 },
  127     { NULL,          0 }
  128 };
  129 
  130 static isc_symtab_t *symtab = NULL;
  131 static isc_mem_t *sym_mctx;
  132 
  133 static void
  134 freekey(char *key, unsigned int type, isc_symvalue_t value, void *userarg) {
  135     UNUSED(type);
  136     UNUSED(value);
  137     isc_mem_free(userarg, key);
  138 }
  139 
  140 static void
  141 add(char *key, int value) {
  142     isc_result_t result;
  143     isc_symvalue_t symvalue;
  144 
  145     if (sym_mctx == NULL) {
  146         result = isc_mem_create(0, 0, &sym_mctx);
  147         if (result != ISC_R_SUCCESS)
  148             return;
  149     }
  150 
  151     if (symtab == NULL) {
  152         result = isc_symtab_create(sym_mctx, 100, freekey, sym_mctx,
  153                        false, &symtab);
  154         if (result != ISC_R_SUCCESS)
  155             return;
  156     }
  157 
  158     key = isc_mem_strdup(sym_mctx, key);
  159     if (key == NULL)
  160         return;
  161 
  162     symvalue.as_pointer = NULL;
  163     result = isc_symtab_define(symtab, key, value, symvalue,
  164                    isc_symexists_reject);
  165     if (result != ISC_R_SUCCESS)
  166         isc_mem_free(sym_mctx, key);
  167 }
  168 
  169 static bool
  170 logged(char *key, int value) {
  171     isc_result_t result;
  172 
  173     if (symtab == NULL)
  174         return (false);
  175 
  176     result = isc_symtab_lookup(symtab, key, value, NULL);
  177     if (result == ISC_R_SUCCESS)
  178         return (true);
  179     return (false);
  180 }
  181 
  182 static bool
  183 checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner,
  184     dns_rdataset_t *a, dns_rdataset_t *aaaa)
  185 {
  186 #ifdef USE_GETADDRINFO
  187     dns_rdataset_t *rdataset;
  188     dns_rdata_t rdata = DNS_RDATA_INIT;
  189     struct addrinfo hints, *ai, *cur;
  190     char namebuf[DNS_NAME_FORMATSIZE + 1];
  191     char ownerbuf[DNS_NAME_FORMATSIZE];
  192     char addrbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123")];
  193     bool answer = true;
  194     bool match;
  195     const char *type;
  196     void *ptr = NULL;
  197     int result;
  198 
  199     REQUIRE(a == NULL || !dns_rdataset_isassociated(a) ||
  200         a->type == dns_rdatatype_a);
  201     REQUIRE(aaaa == NULL || !dns_rdataset_isassociated(aaaa) ||
  202         aaaa->type == dns_rdatatype_aaaa);
  203 
  204     if (a == NULL || aaaa == NULL)
  205         return (answer);
  206 
  207     memset(&hints, 0, sizeof(hints));
  208     hints.ai_flags = AI_CANONNAME;
  209     hints.ai_family = PF_UNSPEC;
  210     hints.ai_socktype = SOCK_STREAM;
  211     hints.ai_protocol = IPPROTO_TCP;
  212 
  213     dns_name_format(name, namebuf, sizeof(namebuf) - 1);
  214     /*
  215      * Turn off search.
  216      */
  217     if (dns_name_countlabels(name) > 1U) {
  218         strlcat(namebuf, ".", sizeof(namebuf));
  219     }
  220     dns_name_format(owner, ownerbuf, sizeof(ownerbuf));
  221 
  222     result = getaddrinfo(namebuf, NULL, &hints, &ai);
  223     dns_name_format(name, namebuf, sizeof(namebuf) - 1);
  224     switch (result) {
  225     case 0:
  226         /*
  227          * Work around broken getaddrinfo() implementations that
  228          * fail to set ai_canonname on first entry.
  229          */
  230         cur = ai;
  231         while (cur != NULL && cur->ai_canonname == NULL &&
  232                cur->ai_next != NULL)
  233             cur = cur->ai_next;
  234         if (cur != NULL && cur->ai_canonname != NULL &&
  235             strcasecmp(cur->ai_canonname, namebuf) != 0 &&
  236             !logged(namebuf, ERR_IS_CNAME)) {
  237             dns_zone_log(zone, ISC_LOG_ERROR,
  238                      "%s/NS '%s' (out of zone) "
  239                      "is a CNAME '%s' (illegal)",
  240                      ownerbuf, namebuf,
  241                      cur->ai_canonname);
  242             /* XXX950 make fatal for 9.5.0 */
  243             /* answer = false; */
  244             add(namebuf, ERR_IS_CNAME);
  245         }
  246         break;
  247     case EAI_NONAME:
  248 #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
  249     case EAI_NODATA:
  250 #endif
  251         if (!logged(namebuf, ERR_NO_ADDRESSES)) {
  252             dns_zone_log(zone, ISC_LOG_ERROR,
  253                      "%s/NS '%s' (out of zone) "
  254                      "has no addresses records (A or AAAA)",
  255                      ownerbuf, namebuf);
  256             add(namebuf, ERR_NO_ADDRESSES);
  257         }
  258         /* XXX950 make fatal for 9.5.0 */
  259         return (true);
  260 
  261     default:
  262         if (!logged(namebuf, ERR_LOOKUP_FAILURE)) {
  263             dns_zone_log(zone, ISC_LOG_WARNING,
  264                      "getaddrinfo(%s) failed: %s",
  265                      namebuf, gai_strerror(result));
  266             add(namebuf, ERR_LOOKUP_FAILURE);
  267         }
  268         return (true);
  269     }
  270 
  271     /*
  272      * Check that all glue records really exist.
  273      */
  274     if (!dns_rdataset_isassociated(a))
  275         goto checkaaaa;
  276     result = dns_rdataset_first(a);
  277     while (result == ISC_R_SUCCESS) {
  278         dns_rdataset_current(a, &rdata);
  279         match = false;
  280         for (cur = ai; cur != NULL; cur = cur->ai_next) {
  281             if (cur->ai_family != AF_INET)
  282                 continue;
  283             ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr;
  284             if (memcmp(ptr, rdata.data, rdata.length) == 0) {
  285                 match = true;
  286                 break;
  287             }
  288         }
  289         if (!match && !logged(namebuf, ERR_EXTRA_A)) {
  290             dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' "
  291                      "extra GLUE A record (%s)",
  292                      ownerbuf, namebuf,
  293                      inet_ntop(AF_INET, rdata.data,
  294                            addrbuf, sizeof(addrbuf)));
  295             add(namebuf, ERR_EXTRA_A);
  296             /* XXX950 make fatal for 9.5.0 */
  297             /* answer = false; */
  298         }
  299         dns_rdata_reset(&rdata);
  300         result = dns_rdataset_next(a);
  301     }
  302 
  303  checkaaaa:
  304     if (!dns_rdataset_isassociated(aaaa))
  305         goto checkmissing;
  306     result = dns_rdataset_first(aaaa);
  307     while (result == ISC_R_SUCCESS) {
  308         dns_rdataset_current(aaaa, &rdata);
  309         match = false;
  310         for (cur = ai; cur != NULL; cur = cur->ai_next) {
  311             if (cur->ai_family != AF_INET6)
  312                 continue;
  313             ptr = &((struct sockaddr_in6 *)(cur->ai_addr))->sin6_addr;
  314             if (memcmp(ptr, rdata.data, rdata.length) == 0) {
  315                 match = true;
  316                 break;
  317             }
  318         }
  319         if (!match && !logged(namebuf, ERR_EXTRA_AAAA)) {
  320             dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' "
  321                      "extra GLUE AAAA record (%s)",
  322                      ownerbuf, namebuf,
  323                      inet_ntop(AF_INET6, rdata.data,
  324                            addrbuf, sizeof(addrbuf)));
  325             add(namebuf, ERR_EXTRA_AAAA);
  326             /* XXX950 make fatal for 9.5.0. */
  327             /* answer = false; */
  328         }
  329         dns_rdata_reset(&rdata);
  330         result = dns_rdataset_next(aaaa);
  331     }
  332 
  333  checkmissing:
  334     /*
  335      * Check that all addresses appear in the glue.
  336      */
  337     if (!logged(namebuf, ERR_MISSING_GLUE)) {
  338         bool missing_glue = false;
  339         for (cur = ai; cur != NULL; cur = cur->ai_next) {
  340             switch (cur->ai_family) {
  341             case AF_INET:
  342                 rdataset = a;
  343                 ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr;
  344                 type = "A";
  345                 break;
  346             case AF_INET6:
  347                 rdataset = aaaa;
  348                 ptr = &((struct sockaddr_in6 *)(cur->ai_addr))->sin6_addr;
  349                 type = "AAAA";
  350                 break;
  351             default:
  352                  continue;
  353             }
  354             match = false;
  355             if (dns_rdataset_isassociated(rdataset))
  356                 result = dns_rdataset_first(rdataset);
  357             else
  358                 result = ISC_R_FAILURE;
  359             while (result == ISC_R_SUCCESS && !match) {
  360                 dns_rdataset_current(rdataset, &rdata);
  361                 if (memcmp(ptr, rdata.data, rdata.length) == 0)
  362                     match = true;
  363                 dns_rdata_reset(&rdata);
  364                 result = dns_rdataset_next(rdataset);
  365             }
  366             if (!match) {
  367                 dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' "
  368                          "missing GLUE %s record (%s)",
  369                          ownerbuf, namebuf, type,
  370                          inet_ntop(cur->ai_family, ptr,
  371                                addrbuf, sizeof(addrbuf)));
  372                 /* XXX950 make fatal for 9.5.0. */
  373                 /* answer = false; */
  374                 missing_glue = true;
  375             }
  376         }
  377         if (missing_glue)
  378             add(namebuf, ERR_MISSING_GLUE);
  379     }
  380     freeaddrinfo(ai);
  381     return (answer);
  382 #else
  383     return (true);
  384 #endif
  385 }
  386 
  387 static bool
  388 checkmx(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) {
  389 #ifdef USE_GETADDRINFO
  390     struct addrinfo hints, *ai, *cur;
  391     char namebuf[DNS_NAME_FORMATSIZE + 1];
  392     char ownerbuf[DNS_NAME_FORMATSIZE];
  393     int result;
  394     int level = ISC_LOG_ERROR;
  395     bool answer = true;
  396 
  397     memset(&hints, 0, sizeof(hints));
  398     hints.ai_flags = AI_CANONNAME;
  399     hints.ai_family = PF_UNSPEC;
  400     hints.ai_socktype = SOCK_STREAM;
  401     hints.ai_protocol = IPPROTO_TCP;
  402 
  403     dns_name_format(name, namebuf, sizeof(namebuf) - 1);
  404     /*
  405      * Turn off search.
  406      */
  407     if (dns_name_countlabels(name) > 1U) {
  408         strlcat(namebuf, ".", sizeof(namebuf));
  409     }
  410     dns_name_format(owner, ownerbuf, sizeof(ownerbuf));
  411 
  412     result = getaddrinfo(namebuf, NULL, &hints, &ai);
  413     dns_name_format(name, namebuf, sizeof(namebuf) - 1);
  414     switch (result) {
  415     case 0:
  416         /*
  417          * Work around broken getaddrinfo() implementations that
  418          * fail to set ai_canonname on first entry.
  419          */
  420         cur = ai;
  421         while (cur != NULL && cur->ai_canonname == NULL &&
  422                cur->ai_next != NULL)
  423             cur = cur->ai_next;
  424         if (cur != NULL && cur->ai_canonname != NULL &&
  425             strcasecmp(cur->ai_canonname, namebuf) != 0) {
  426             if ((zone_options & DNS_ZONEOPT_WARNMXCNAME) != 0)
  427                 level = ISC_LOG_WARNING;
  428             if ((zone_options & DNS_ZONEOPT_IGNOREMXCNAME) == 0) {
  429                 if (!logged(namebuf, ERR_IS_MXCNAME)) {
  430                     dns_zone_log(zone, level,
  431                              "%s/MX '%s' (out of zone)"
  432                              " is a CNAME '%s' "
  433                              "(illegal)",
  434                              ownerbuf, namebuf,
  435                              cur->ai_canonname);
  436                     add(namebuf, ERR_IS_MXCNAME);
  437                 }
  438                 if (level == ISC_LOG_ERROR)
  439                     answer = false;
  440             }
  441         }
  442         freeaddrinfo(ai);
  443         return (answer);
  444 
  445     case EAI_NONAME:
  446 #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
  447     case EAI_NODATA:
  448 #endif
  449         if (!logged(namebuf, ERR_NO_ADDRESSES)) {
  450             dns_zone_log(zone, ISC_LOG_ERROR,
  451                      "%s/MX '%s' (out of zone) "
  452                      "has no addresses records (A or AAAA)",
  453                      ownerbuf, namebuf);
  454             add(namebuf, ERR_NO_ADDRESSES);
  455         }
  456         /* XXX950 make fatal for 9.5.0. */
  457         return (true);
  458 
  459     default:
  460         if (!logged(namebuf, ERR_LOOKUP_FAILURE)) {
  461             dns_zone_log(zone, ISC_LOG_WARNING,
  462                  "getaddrinfo(%s) failed: %s",
  463                  namebuf, gai_strerror(result));
  464             add(namebuf, ERR_LOOKUP_FAILURE);
  465         }
  466         return (true);
  467     }
  468 #else
  469     return (true);
  470 #endif
  471 }
  472 
  473 static bool
  474 checksrv(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) {
  475 #ifdef USE_GETADDRINFO
  476     struct addrinfo hints, *ai, *cur;
  477     char namebuf[DNS_NAME_FORMATSIZE + 1];
  478     char ownerbuf[DNS_NAME_FORMATSIZE];
  479     int result;
  480     int level = ISC_LOG_ERROR;
  481     bool answer = true;
  482 
  483     memset(&hints, 0, sizeof(hints));
  484     hints.ai_flags = AI_CANONNAME;
  485     hints.ai_family = PF_UNSPEC;
  486     hints.ai_socktype = SOCK_STREAM;
  487     hints.ai_protocol = IPPROTO_TCP;
  488 
  489     dns_name_format(name, namebuf, sizeof(namebuf) - 1);
  490     /*
  491      * Turn off search.
  492      */
  493     if (dns_name_countlabels(name) > 1U) {
  494         strlcat(namebuf, ".", sizeof(namebuf));
  495     }
  496     dns_name_format(owner, ownerbuf, sizeof(ownerbuf));
  497 
  498     result = getaddrinfo(namebuf, NULL, &hints, &ai);
  499     dns_name_format(name, namebuf, sizeof(namebuf) - 1);
  500     switch (result) {
  501     case 0:
  502         /*
  503          * Work around broken getaddrinfo() implementations that
  504          * fail to set ai_canonname on first entry.
  505          */
  506         cur = ai;
  507         while (cur != NULL && cur->ai_canonname == NULL &&
  508                cur->ai_next != NULL)
  509             cur = cur->ai_next;
  510         if (cur != NULL && cur->ai_canonname != NULL &&
  511             strcasecmp(cur->ai_canonname, namebuf) != 0) {
  512             if ((zone_options & DNS_ZONEOPT_WARNSRVCNAME) != 0)
  513                 level = ISC_LOG_WARNING;
  514             if ((zone_options & DNS_ZONEOPT_IGNORESRVCNAME) == 0) {
  515                 if (!logged(namebuf, ERR_IS_SRVCNAME)) {
  516                     dns_zone_log(zone, level, "%s/SRV '%s'"
  517                              " (out of zone) is a "
  518                              "CNAME '%s' (illegal)",
  519                              ownerbuf, namebuf,
  520                              cur->ai_canonname);
  521                     add(namebuf, ERR_IS_SRVCNAME);
  522                 }
  523                 if (level == ISC_LOG_ERROR)
  524                     answer = false;
  525             }
  526         }
  527         freeaddrinfo(ai);
  528         return (answer);
  529 
  530     case EAI_NONAME:
  531 #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
  532     case EAI_NODATA:
  533 #endif
  534         if (!logged(namebuf, ERR_NO_ADDRESSES)) {
  535             dns_zone_log(zone, ISC_LOG_ERROR,
  536                      "%s/SRV '%s' (out of zone) "
  537                      "has no addresses records (A or AAAA)",
  538                      ownerbuf, namebuf);
  539             add(namebuf, ERR_NO_ADDRESSES);
  540         }
  541         /* XXX950 make fatal for 9.5.0. */
  542         return (true);
  543 
  544     default:
  545         if (!logged(namebuf, ERR_LOOKUP_FAILURE)) {
  546             dns_zone_log(zone, ISC_LOG_WARNING,
  547                      "getaddrinfo(%s) failed: %s",
  548                      namebuf, gai_strerror(result));
  549             add(namebuf, ERR_LOOKUP_FAILURE);
  550         }
  551         return (true);
  552     }
  553 #else
  554     return (true);
  555 #endif
  556 }
  557 
  558 isc_result_t
  559 setup_logging(isc_mem_t *mctx, FILE *errout, isc_log_t **logp) {
  560     isc_logdestination_t destination;
  561     isc_logconfig_t *logconfig = NULL;
  562     isc_log_t *log = NULL;
  563 
  564     RUNTIME_CHECK(isc_log_create(mctx, &log, &logconfig) == ISC_R_SUCCESS);
  565     isc_log_registercategories(log, categories);
  566     isc_log_setcontext(log);
  567     dns_log_init(log);
  568     dns_log_setcontext(log);
  569     cfg_log_init(log);
  570 
  571     destination.file.stream = errout;
  572     destination.file.name = NULL;
  573     destination.file.versions = ISC_LOG_ROLLNEVER;
  574     destination.file.maximum_size = 0;
  575     RUNTIME_CHECK(isc_log_createchannel(logconfig, "stderr",
  576                        ISC_LOG_TOFILEDESC,
  577                        ISC_LOG_DYNAMIC,
  578                        &destination, 0) == ISC_R_SUCCESS);
  579     RUNTIME_CHECK(isc_log_usechannel(logconfig, "stderr",
  580                      NULL, NULL) == ISC_R_SUCCESS);
  581 
  582     *logp = log;
  583     return (ISC_R_SUCCESS);
  584 }
  585 
  586 /*% scan the zone for oversize TTLs */
  587 static isc_result_t
  588 check_ttls(dns_zone_t *zone, dns_ttl_t maxttl) {
  589     isc_result_t result;
  590     dns_db_t *db = NULL;
  591     dns_dbversion_t *version = NULL;
  592     dns_dbnode_t *node = NULL;
  593     dns_dbiterator_t *dbiter = NULL;
  594     dns_rdatasetiter_t *rdsiter = NULL;
  595     dns_rdataset_t rdataset;
  596     dns_fixedname_t fname;
  597     dns_name_t *name;
  598     name = dns_fixedname_initname(&fname);
  599     dns_rdataset_init(&rdataset);
  600 
  601     CHECK(dns_zone_getdb(zone, &db));
  602     INSIST(db != NULL);
  603 
  604     CHECK(dns_db_newversion(db, &version));
  605     CHECK(dns_db_createiterator(db, 0, &dbiter));
  606 
  607     for (result = dns_dbiterator_first(dbiter);
  608          result == ISC_R_SUCCESS;
  609          result = dns_dbiterator_next(dbiter)) {
  610         result = dns_dbiterator_current(dbiter, &node, name);
  611         if (result == DNS_R_NEWORIGIN)
  612             result = ISC_R_SUCCESS;
  613         CHECK(result);
  614 
  615         CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsiter));
  616         for (result = dns_rdatasetiter_first(rdsiter);
  617              result == ISC_R_SUCCESS;
  618              result = dns_rdatasetiter_next(rdsiter)) {
  619             dns_rdatasetiter_current(rdsiter, &rdataset);
  620             if (rdataset.ttl > maxttl) {
  621                 char nbuf[DNS_NAME_FORMATSIZE];
  622                 char tbuf[255];
  623                 isc_buffer_t b;
  624                 isc_region_t r;
  625 
  626                 dns_name_format(name, nbuf, sizeof(nbuf));
  627                 isc_buffer_init(&b, tbuf, sizeof(tbuf) - 1);
  628                 CHECK(dns_rdatatype_totext(rdataset.type, &b));
  629                 isc_buffer_usedregion(&b, &r);
  630                 r.base[r.length] = 0;
  631 
  632                 dns_zone_log(zone, ISC_LOG_ERROR,
  633                          "%s/%s TTL %d exceeds "
  634                          "maximum TTL %d",
  635                          nbuf, tbuf, rdataset.ttl, maxttl);
  636                 dns_rdataset_disassociate(&rdataset);
  637                 CHECK(ISC_R_RANGE);
  638             }
  639             dns_rdataset_disassociate(&rdataset);
  640         }
  641         if (result == ISC_R_NOMORE)
  642             result = ISC_R_SUCCESS;
  643         CHECK(result);
  644 
  645         dns_rdatasetiter_destroy(&rdsiter);
  646         dns_db_detachnode(db, &node);
  647     }
  648 
  649     if (result == ISC_R_NOMORE)
  650         result = ISC_R_SUCCESS;
  651 
  652  cleanup:
  653     if (node != NULL)
  654         dns_db_detachnode(db, &node);
  655     if (rdsiter != NULL)
  656         dns_rdatasetiter_destroy(&rdsiter);
  657     if (dbiter != NULL)
  658         dns_dbiterator_destroy(&dbiter);
  659     if (version != NULL)
  660         dns_db_closeversion(db, &version, false);
  661     if (db != NULL)
  662         dns_db_detach(&db);
  663 
  664     return (result);
  665 }
  666 
  667 /*% load the zone */
  668 isc_result_t
  669 load_zone(isc_mem_t *mctx, const char *zonename, const char *filename,
  670       dns_masterformat_t fileformat, const char *classname,
  671       dns_ttl_t maxttl, dns_zone_t **zonep)
  672 {
  673     isc_result_t result;
  674     dns_rdataclass_t rdclass;
  675     isc_textregion_t region;
  676     isc_buffer_t buffer;
  677     dns_fixedname_t fixorigin;
  678     dns_name_t *origin;
  679     dns_zone_t *zone = NULL;
  680 
  681     REQUIRE(zonep == NULL || *zonep == NULL);
  682 
  683     if (debug)
  684         fprintf(stderr, "loading \"%s\" from \"%s\" class \"%s\"\n",
  685             zonename, filename, classname);
  686 
  687     CHECK(dns_zone_create(&zone, mctx));
  688 
  689     dns_zone_settype(zone, dns_zone_master);
  690 
  691     isc_buffer_constinit(&buffer, zonename, strlen(zonename));
  692     isc_buffer_add(&buffer, strlen(zonename));
  693     origin = dns_fixedname_initname(&fixorigin);
  694     CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, 0, NULL));
  695     CHECK(dns_zone_setorigin(zone, origin));
  696     CHECK(dns_zone_setdbtype(zone, 1, (const char * const *) dbtype));
  697     CHECK(dns_zone_setfile2(zone, filename, fileformat));
  698     if (journal != NULL)
  699         CHECK(dns_zone_setjournal(zone, journal));
  700 
  701     DE_CONST(classname, region.base);
  702     region.length = strlen(classname);
  703     CHECK(dns_rdataclass_fromtext(&rdclass, &region));
  704 
  705     dns_zone_setclass(zone, rdclass);
  706     dns_zone_setoption(zone, zone_options, true);
  707     dns_zone_setoption2(zone, zone_options2, true);
  708     dns_zone_setoption(zone, DNS_ZONEOPT_NOMERGE, nomerge);
  709 
  710     dns_zone_setmaxttl(zone, maxttl);
  711 
  712     if (docheckmx)
  713         dns_zone_setcheckmx(zone, checkmx);
  714     if (docheckns)
  715         dns_zone_setcheckns(zone, checkns);
  716     if (dochecksrv)
  717         dns_zone_setchecksrv(zone, checksrv);
  718 
  719     CHECK(dns_zone_load(zone));
  720 
  721     /*
  722      * When loading map files we can't catch oversize TTLs during
  723      * load, so we check for them here.
  724      */
  725     if (fileformat == dns_masterformat_map && maxttl != 0) {
  726         CHECK(check_ttls(zone, maxttl));
  727     }
  728 
  729     if (zonep != NULL) {
  730         *zonep = zone;
  731         zone = NULL;
  732     }
  733 
  734  cleanup:
  735     if (zone != NULL)
  736         dns_zone_detach(&zone);
  737     return (result);
  738 }
  739 
  740 /*% dump the zone */
  741 isc_result_t
  742 dump_zone(const char *zonename, dns_zone_t *zone, const char *filename,
  743       dns_masterformat_t fileformat, const dns_master_style_t *style,
  744       const uint32_t rawversion)
  745 {
  746     isc_result_t result;
  747     FILE *output = stdout;
  748     const char *flags;
  749 
  750     flags = (fileformat == dns_masterformat_text) ? "w" : "wb";
  751 
  752     if (debug) {
  753         if (filename != NULL && strcmp(filename, "-") != 0)
  754             fprintf(stderr, "dumping \"%s\" to \"%s\"\n",
  755                 zonename, filename);
  756         else
  757             fprintf(stderr, "dumping \"%s\"\n", zonename);
  758     }
  759 
  760     if (filename != NULL && strcmp(filename, "-") != 0) {
  761         result = isc_stdio_open(filename, flags, &output);
  762 
  763         if (result != ISC_R_SUCCESS) {
  764             fprintf(stderr, "could not open output "
  765                 "file \"%s\" for writing\n", filename);
  766             return (ISC_R_FAILURE);
  767         }
  768     }
  769 
  770     result = dns_zone_dumptostream3(zone, output, fileformat, style,
  771                     rawversion);
  772     if (output != stdout)
  773         (void)isc_stdio_close(output);
  774 
  775     return (result);
  776 }
  777 
  778 #ifdef _WIN32
  779 void
  780 InitSockets(void) {
  781     WORD wVersionRequested;
  782     WSADATA wsaData;
  783     int err;
  784 
  785     wVersionRequested = MAKEWORD(2, 0);
  786 
  787     err = WSAStartup( wVersionRequested, &wsaData );
  788     if (err != 0) {
  789         fprintf(stderr, "WSAStartup() failed: %d\n", err);
  790         exit(1);
  791     }
  792 }
  793 
  794 void
  795 DestroySockets(void) {
  796     WSACleanup();
  797 }
  798 #endif