"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.16.7/bin/check/named-checkconf.c" (4 Sep 2020, 18538 Bytes) of package /linux/misc/dns/bind9/9.16.7/bind-9.16.7.tar.xz:


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 "named-checkconf.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.17.2_vs_9.17.3.

    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 /*! \file */
   13 
   14 #include <errno.h>
   15 #include <stdbool.h>
   16 #include <stdio.h>
   17 #include <stdlib.h>
   18 
   19 #include <isc/commandline.h>
   20 #include <isc/dir.h>
   21 #include <isc/hash.h>
   22 #include <isc/log.h>
   23 #include <isc/mem.h>
   24 #include <isc/print.h>
   25 #include <isc/result.h>
   26 #include <isc/string.h>
   27 #include <isc/util.h>
   28 
   29 #include <dns/db.h>
   30 #include <dns/fixedname.h>
   31 #include <dns/log.h>
   32 #include <dns/name.h>
   33 #include <dns/rdataclass.h>
   34 #include <dns/result.h>
   35 #include <dns/rootns.h>
   36 #include <dns/zone.h>
   37 
   38 #include <isccfg/grammar.h>
   39 #include <isccfg/namedconf.h>
   40 
   41 #include <bind9/check.h>
   42 
   43 #include "check-tool.h"
   44 
   45 static const char *program = "named-checkconf";
   46 
   47 static bool loadplugins = true;
   48 
   49 isc_log_t *logc = NULL;
   50 
   51 #define CHECK(r)                             \
   52     do {                                 \
   53         result = (r);                \
   54         if (result != ISC_R_SUCCESS) \
   55             goto cleanup;        \
   56     } while (0)
   57 
   58 /*% usage */
   59 ISC_PLATFORM_NORETURN_PRE static void
   60 usage(void) ISC_PLATFORM_NORETURN_POST;
   61 
   62 static void
   63 usage(void) {
   64     fprintf(stderr,
   65         "usage: %s [-chijlvz] [-p [-x]] [-t directory] "
   66         "[named.conf]\n",
   67         program);
   68     exit(1);
   69 }
   70 
   71 /*% directory callback */
   72 static isc_result_t
   73 directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) {
   74     isc_result_t result;
   75     const char *directory;
   76 
   77     REQUIRE(strcasecmp("directory", clausename) == 0);
   78 
   79     UNUSED(arg);
   80     UNUSED(clausename);
   81 
   82     /*
   83      * Change directory.
   84      */
   85     directory = cfg_obj_asstring(obj);
   86     result = isc_dir_chdir(directory);
   87     if (result != ISC_R_SUCCESS) {
   88         cfg_obj_log(obj, logc, ISC_LOG_ERROR,
   89                 "change directory to '%s' failed: %s\n", directory,
   90                 isc_result_totext(result));
   91         return (result);
   92     }
   93 
   94     return (ISC_R_SUCCESS);
   95 }
   96 
   97 static bool
   98 get_maps(const cfg_obj_t **maps, const char *name, const cfg_obj_t **obj) {
   99     int i;
  100     for (i = 0;; i++) {
  101         if (maps[i] == NULL) {
  102             return (false);
  103         }
  104         if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) {
  105             return (true);
  106         }
  107     }
  108 }
  109 
  110 static bool
  111 get_checknames(const cfg_obj_t **maps, const cfg_obj_t **obj) {
  112     const cfg_listelt_t *element;
  113     const cfg_obj_t *checknames;
  114     const cfg_obj_t *type;
  115     const cfg_obj_t *value;
  116     isc_result_t result;
  117     int i;
  118 
  119     for (i = 0;; i++) {
  120         if (maps[i] == NULL) {
  121             return (false);
  122         }
  123         checknames = NULL;
  124         result = cfg_map_get(maps[i], "check-names", &checknames);
  125         if (result != ISC_R_SUCCESS) {
  126             continue;
  127         }
  128         if (checknames != NULL && !cfg_obj_islist(checknames)) {
  129             *obj = checknames;
  130             return (true);
  131         }
  132         for (element = cfg_list_first(checknames); element != NULL;
  133              element = cfg_list_next(element))
  134         {
  135             value = cfg_listelt_value(element);
  136             type = cfg_tuple_get(value, "type");
  137             if ((strcasecmp(cfg_obj_asstring(type), "primary") !=
  138                  0) &&
  139                 (strcasecmp(cfg_obj_asstring(type), "master") != 0))
  140             {
  141                 continue;
  142             }
  143             *obj = cfg_tuple_get(value, "mode");
  144             return (true);
  145         }
  146     }
  147 }
  148 
  149 static isc_result_t
  150 configure_hint(const char *zfile, const char *zclass, isc_mem_t *mctx) {
  151     isc_result_t result;
  152     dns_db_t *db = NULL;
  153     dns_rdataclass_t rdclass;
  154     isc_textregion_t r;
  155 
  156     if (zfile == NULL) {
  157         return (ISC_R_FAILURE);
  158     }
  159 
  160     DE_CONST(zclass, r.base);
  161     r.length = strlen(zclass);
  162     result = dns_rdataclass_fromtext(&rdclass, &r);
  163     if (result != ISC_R_SUCCESS) {
  164         return (result);
  165     }
  166 
  167     result = dns_rootns_create(mctx, rdclass, zfile, &db);
  168     if (result != ISC_R_SUCCESS) {
  169         return (result);
  170     }
  171 
  172     dns_db_detach(&db);
  173     return (ISC_R_SUCCESS);
  174 }
  175 
  176 /*% configure the zone */
  177 static isc_result_t
  178 configure_zone(const char *vclass, const char *view, const cfg_obj_t *zconfig,
  179            const cfg_obj_t *vconfig, const cfg_obj_t *config,
  180            isc_mem_t *mctx, bool list) {
  181     int i = 0;
  182     isc_result_t result;
  183     const char *zclass;
  184     const char *zname;
  185     const char *zfile = NULL;
  186     const cfg_obj_t *maps[4];
  187     const cfg_obj_t *mastersobj = NULL;
  188     const cfg_obj_t *inviewobj = NULL;
  189     const cfg_obj_t *zoptions = NULL;
  190     const cfg_obj_t *classobj = NULL;
  191     const cfg_obj_t *typeobj = NULL;
  192     const cfg_obj_t *fileobj = NULL;
  193     const cfg_obj_t *dlzobj = NULL;
  194     const cfg_obj_t *dbobj = NULL;
  195     const cfg_obj_t *obj = NULL;
  196     const cfg_obj_t *fmtobj = NULL;
  197     dns_masterformat_t masterformat;
  198     dns_ttl_t maxttl = 0;
  199 
  200     zone_options = DNS_ZONEOPT_CHECKNS | DNS_ZONEOPT_MANYERRORS;
  201 
  202     zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
  203     classobj = cfg_tuple_get(zconfig, "class");
  204     if (!cfg_obj_isstring(classobj)) {
  205         zclass = vclass;
  206     } else {
  207         zclass = cfg_obj_asstring(classobj);
  208     }
  209 
  210     zoptions = cfg_tuple_get(zconfig, "options");
  211     maps[i++] = zoptions;
  212     if (vconfig != NULL) {
  213         maps[i++] = cfg_tuple_get(vconfig, "options");
  214     }
  215     if (config != NULL) {
  216         cfg_map_get(config, "options", &obj);
  217         if (obj != NULL) {
  218             maps[i++] = obj;
  219         }
  220     }
  221     maps[i] = NULL;
  222 
  223     cfg_map_get(zoptions, "in-view", &inviewobj);
  224     if (inviewobj != NULL && list) {
  225         const char *inview = cfg_obj_asstring(inviewobj);
  226         printf("%s %s %s in-view %s\n", zname, zclass, view, inview);
  227     }
  228     if (inviewobj != NULL) {
  229         return (ISC_R_SUCCESS);
  230     }
  231 
  232     cfg_map_get(zoptions, "type", &typeobj);
  233     if (typeobj == NULL) {
  234         return (ISC_R_FAILURE);
  235     }
  236 
  237     if (list) {
  238         const char *ztype = cfg_obj_asstring(typeobj);
  239         printf("%s %s %s %s\n", zname, zclass, view, ztype);
  240         return (ISC_R_SUCCESS);
  241     }
  242 
  243     /*
  244      * Skip checks when using an alternate data source.
  245      */
  246     cfg_map_get(zoptions, "database", &dbobj);
  247     if (dbobj != NULL && strcmp("rbt", cfg_obj_asstring(dbobj)) != 0 &&
  248         strcmp("rbt64", cfg_obj_asstring(dbobj)) != 0)
  249     {
  250         return (ISC_R_SUCCESS);
  251     }
  252 
  253     cfg_map_get(zoptions, "dlz", &dlzobj);
  254     if (dlzobj != NULL) {
  255         return (ISC_R_SUCCESS);
  256     }
  257 
  258     cfg_map_get(zoptions, "file", &fileobj);
  259     if (fileobj != NULL) {
  260         zfile = cfg_obj_asstring(fileobj);
  261     }
  262 
  263     /*
  264      * Check hints files for hint zones.
  265      * Skip loading checks for any type other than
  266      * master and redirect
  267      */
  268     if (strcasecmp(cfg_obj_asstring(typeobj), "hint") == 0) {
  269         return (configure_hint(zfile, zclass, mctx));
  270     } else if ((strcasecmp(cfg_obj_asstring(typeobj), "primary") != 0) &&
  271            (strcasecmp(cfg_obj_asstring(typeobj), "master") != 0) &&
  272            (strcasecmp(cfg_obj_asstring(typeobj), "redirect") != 0))
  273     {
  274         return (ISC_R_SUCCESS);
  275     }
  276 
  277     /*
  278      * Is the redirect zone configured as a slave?
  279      */
  280     if (strcasecmp(cfg_obj_asstring(typeobj), "redirect") == 0) {
  281         cfg_map_get(zoptions, "masters", &mastersobj);
  282         if (mastersobj != NULL) {
  283             return (ISC_R_SUCCESS);
  284         }
  285     }
  286 
  287     if (zfile == NULL) {
  288         return (ISC_R_FAILURE);
  289     }
  290 
  291     obj = NULL;
  292     if (get_maps(maps, "check-dup-records", &obj)) {
  293         if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
  294             zone_options |= DNS_ZONEOPT_CHECKDUPRR;
  295             zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL;
  296         } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
  297             zone_options |= DNS_ZONEOPT_CHECKDUPRR;
  298             zone_options |= DNS_ZONEOPT_CHECKDUPRRFAIL;
  299         } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
  300             zone_options &= ~DNS_ZONEOPT_CHECKDUPRR;
  301             zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL;
  302         } else {
  303             INSIST(0);
  304             ISC_UNREACHABLE();
  305         }
  306     } else {
  307         zone_options |= DNS_ZONEOPT_CHECKDUPRR;
  308         zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL;
  309     }
  310 
  311     obj = NULL;
  312     if (get_maps(maps, "check-mx", &obj)) {
  313         if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
  314             zone_options |= DNS_ZONEOPT_CHECKMX;
  315             zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL;
  316         } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
  317             zone_options |= DNS_ZONEOPT_CHECKMX;
  318             zone_options |= DNS_ZONEOPT_CHECKMXFAIL;
  319         } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
  320             zone_options &= ~DNS_ZONEOPT_CHECKMX;
  321             zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL;
  322         } else {
  323             INSIST(0);
  324             ISC_UNREACHABLE();
  325         }
  326     } else {
  327         zone_options |= DNS_ZONEOPT_CHECKMX;
  328         zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL;
  329     }
  330 
  331     obj = NULL;
  332     if (get_maps(maps, "check-integrity", &obj)) {
  333         if (cfg_obj_asboolean(obj)) {
  334             zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
  335         } else {
  336             zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY;
  337         }
  338     } else {
  339         zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
  340     }
  341 
  342     obj = NULL;
  343     if (get_maps(maps, "check-mx-cname", &obj)) {
  344         if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
  345             zone_options |= DNS_ZONEOPT_WARNMXCNAME;
  346             zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME;
  347         } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
  348             zone_options &= ~DNS_ZONEOPT_WARNMXCNAME;
  349             zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME;
  350         } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
  351             zone_options |= DNS_ZONEOPT_WARNMXCNAME;
  352             zone_options |= DNS_ZONEOPT_IGNOREMXCNAME;
  353         } else {
  354             INSIST(0);
  355             ISC_UNREACHABLE();
  356         }
  357     } else {
  358         zone_options |= DNS_ZONEOPT_WARNMXCNAME;
  359         zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME;
  360     }
  361 
  362     obj = NULL;
  363     if (get_maps(maps, "check-srv-cname", &obj)) {
  364         if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
  365             zone_options |= DNS_ZONEOPT_WARNSRVCNAME;
  366             zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME;
  367         } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
  368             zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME;
  369             zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME;
  370         } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
  371             zone_options |= DNS_ZONEOPT_WARNSRVCNAME;
  372             zone_options |= DNS_ZONEOPT_IGNORESRVCNAME;
  373         } else {
  374             INSIST(0);
  375             ISC_UNREACHABLE();
  376         }
  377     } else {
  378         zone_options |= DNS_ZONEOPT_WARNSRVCNAME;
  379         zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME;
  380     }
  381 
  382     obj = NULL;
  383     if (get_maps(maps, "check-sibling", &obj)) {
  384         if (cfg_obj_asboolean(obj)) {
  385             zone_options |= DNS_ZONEOPT_CHECKSIBLING;
  386         } else {
  387             zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
  388         }
  389     }
  390 
  391     obj = NULL;
  392     if (get_maps(maps, "check-spf", &obj)) {
  393         if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
  394             zone_options |= DNS_ZONEOPT_CHECKSPF;
  395         } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
  396             zone_options &= ~DNS_ZONEOPT_CHECKSPF;
  397         } else {
  398             INSIST(0);
  399             ISC_UNREACHABLE();
  400         }
  401     } else {
  402         zone_options |= DNS_ZONEOPT_CHECKSPF;
  403     }
  404 
  405     obj = NULL;
  406     if (get_checknames(maps, &obj)) {
  407         if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
  408             zone_options |= DNS_ZONEOPT_CHECKNAMES;
  409             zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL;
  410         } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
  411             zone_options |= DNS_ZONEOPT_CHECKNAMES;
  412             zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL;
  413         } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
  414             zone_options &= ~DNS_ZONEOPT_CHECKNAMES;
  415             zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL;
  416         } else {
  417             INSIST(0);
  418             ISC_UNREACHABLE();
  419         }
  420     } else {
  421         zone_options |= DNS_ZONEOPT_CHECKNAMES;
  422         zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL;
  423     }
  424 
  425     masterformat = dns_masterformat_text;
  426     fmtobj = NULL;
  427     if (get_maps(maps, "masterfile-format", &fmtobj)) {
  428         const char *masterformatstr = cfg_obj_asstring(fmtobj);
  429         if (strcasecmp(masterformatstr, "text") == 0) {
  430             masterformat = dns_masterformat_text;
  431         } else if (strcasecmp(masterformatstr, "raw") == 0) {
  432             masterformat = dns_masterformat_raw;
  433         } else if (strcasecmp(masterformatstr, "map") == 0) {
  434             masterformat = dns_masterformat_map;
  435         } else {
  436             INSIST(0);
  437             ISC_UNREACHABLE();
  438         }
  439     }
  440 
  441     obj = NULL;
  442     if (get_maps(maps, "max-zone-ttl", &obj)) {
  443         maxttl = cfg_obj_asduration(obj);
  444         zone_options |= DNS_ZONEOPT_CHECKTTL;
  445     }
  446 
  447     result = load_zone(mctx, zname, zfile, masterformat, zclass, maxttl,
  448                NULL);
  449     if (result != ISC_R_SUCCESS) {
  450         fprintf(stderr, "%s/%s/%s: %s\n", view, zname, zclass,
  451             dns_result_totext(result));
  452     }
  453     return (result);
  454 }
  455 
  456 /*% configure a view */
  457 static isc_result_t
  458 configure_view(const char *vclass, const char *view, const cfg_obj_t *config,
  459            const cfg_obj_t *vconfig, isc_mem_t *mctx, bool list) {
  460     const cfg_listelt_t *element;
  461     const cfg_obj_t *voptions;
  462     const cfg_obj_t *zonelist;
  463     isc_result_t result = ISC_R_SUCCESS;
  464     isc_result_t tresult;
  465 
  466     voptions = NULL;
  467     if (vconfig != NULL) {
  468         voptions = cfg_tuple_get(vconfig, "options");
  469     }
  470 
  471     zonelist = NULL;
  472     if (voptions != NULL) {
  473         (void)cfg_map_get(voptions, "zone", &zonelist);
  474     } else {
  475         (void)cfg_map_get(config, "zone", &zonelist);
  476     }
  477 
  478     for (element = cfg_list_first(zonelist); element != NULL;
  479          element = cfg_list_next(element))
  480     {
  481         const cfg_obj_t *zconfig = cfg_listelt_value(element);
  482         tresult = configure_zone(vclass, view, zconfig, vconfig, config,
  483                      mctx, list);
  484         if (tresult != ISC_R_SUCCESS) {
  485             result = tresult;
  486         }
  487     }
  488     return (result);
  489 }
  490 
  491 static isc_result_t
  492 config_getclass(const cfg_obj_t *classobj, dns_rdataclass_t defclass,
  493         dns_rdataclass_t *classp) {
  494     isc_textregion_t r;
  495 
  496     if (!cfg_obj_isstring(classobj)) {
  497         *classp = defclass;
  498         return (ISC_R_SUCCESS);
  499     }
  500     DE_CONST(cfg_obj_asstring(classobj), r.base);
  501     r.length = strlen(r.base);
  502     return (dns_rdataclass_fromtext(classp, &r));
  503 }
  504 
  505 /*% load zones from the configuration */
  506 static isc_result_t
  507 load_zones_fromconfig(const cfg_obj_t *config, isc_mem_t *mctx,
  508               bool list_zones) {
  509     const cfg_listelt_t *element;
  510     const cfg_obj_t *views;
  511     const cfg_obj_t *vconfig;
  512     isc_result_t result = ISC_R_SUCCESS;
  513     isc_result_t tresult;
  514 
  515     views = NULL;
  516 
  517     (void)cfg_map_get(config, "view", &views);
  518     for (element = cfg_list_first(views); element != NULL;
  519          element = cfg_list_next(element))
  520     {
  521         const cfg_obj_t *classobj;
  522         dns_rdataclass_t viewclass;
  523         const char *vname;
  524         char buf[sizeof("CLASS65535")];
  525 
  526         vconfig = cfg_listelt_value(element);
  527         if (vconfig == NULL) {
  528             continue;
  529         }
  530 
  531         classobj = cfg_tuple_get(vconfig, "class");
  532         tresult = config_getclass(classobj, dns_rdataclass_in,
  533                       &viewclass);
  534         if (tresult != ISC_R_SUCCESS) {
  535             CHECK(tresult);
  536         }
  537 
  538         if (dns_rdataclass_ismeta(viewclass)) {
  539             CHECK(ISC_R_FAILURE);
  540         }
  541 
  542         dns_rdataclass_format(viewclass, buf, sizeof(buf));
  543         vname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name"));
  544         tresult = configure_view(buf, vname, config, vconfig, mctx,
  545                      list_zones);
  546         if (tresult != ISC_R_SUCCESS) {
  547             result = tresult;
  548         }
  549     }
  550 
  551     if (views == NULL) {
  552         tresult = configure_view("IN", "_default", config, NULL, mctx,
  553                      list_zones);
  554         if (tresult != ISC_R_SUCCESS) {
  555             result = tresult;
  556         }
  557     }
  558 
  559 cleanup:
  560     return (result);
  561 }
  562 
  563 static void
  564 output(void *closure, const char *text, int textlen) {
  565     UNUSED(closure);
  566     if (fwrite(text, 1, textlen, stdout) != (size_t)textlen) {
  567         perror("fwrite");
  568         exit(1);
  569     }
  570 }
  571 
  572 /*% The main processing routine */
  573 int
  574 main(int argc, char **argv) {
  575     int c;
  576     cfg_parser_t *parser = NULL;
  577     cfg_obj_t *config = NULL;
  578     const char *conffile = NULL;
  579     isc_mem_t *mctx = NULL;
  580     isc_result_t result;
  581     int exit_status = 0;
  582     bool load_zones = false;
  583     bool list_zones = false;
  584     bool print = false;
  585     bool nodeprecate = false;
  586     unsigned int flags = 0;
  587 
  588     isc_commandline_errprint = false;
  589 
  590     /*
  591      * Process memory debugging argument first.
  592      */
  593 #define CMDLINE_FLAGS "cdhijlm:t:pvxz"
  594     while ((c = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
  595         switch (c) {
  596         case 'm':
  597             if (strcasecmp(isc_commandline_argument, "record") == 0)
  598             {
  599                 isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
  600             }
  601             if (strcasecmp(isc_commandline_argument, "trace") == 0)
  602             {
  603                 isc_mem_debugging |= ISC_MEM_DEBUGTRACE;
  604             }
  605             if (strcasecmp(isc_commandline_argument, "usage") == 0)
  606             {
  607                 isc_mem_debugging |= ISC_MEM_DEBUGUSAGE;
  608             }
  609             if (strcasecmp(isc_commandline_argument, "size") == 0) {
  610                 isc_mem_debugging |= ISC_MEM_DEBUGSIZE;
  611             }
  612             if (strcasecmp(isc_commandline_argument, "mctx") == 0) {
  613                 isc_mem_debugging |= ISC_MEM_DEBUGCTX;
  614             }
  615             break;
  616         default:
  617             break;
  618         }
  619     }
  620     isc_commandline_reset = true;
  621 
  622     isc_mem_create(&mctx);
  623 
  624     while ((c = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != EOF) {
  625         switch (c) {
  626         case 'c':
  627             loadplugins = false;
  628             break;
  629 
  630         case 'd':
  631             debug++;
  632             break;
  633 
  634         case 'i':
  635             nodeprecate = true;
  636             break;
  637 
  638         case 'j':
  639             nomerge = false;
  640             break;
  641 
  642         case 'l':
  643             list_zones = true;
  644             break;
  645 
  646         case 'm':
  647             break;
  648 
  649         case 't':
  650             result = isc_dir_chroot(isc_commandline_argument);
  651             if (result != ISC_R_SUCCESS) {
  652                 fprintf(stderr, "isc_dir_chroot: %s\n",
  653                     isc_result_totext(result));
  654                 exit(1);
  655             }
  656             break;
  657 
  658         case 'p':
  659             print = true;
  660             break;
  661 
  662         case 'v':
  663             printf(VERSION "\n");
  664             exit(0);
  665 
  666         case 'x':
  667             flags |= CFG_PRINTER_XKEY;
  668             break;
  669 
  670         case 'z':
  671             load_zones = true;
  672             docheckmx = false;
  673             docheckns = false;
  674             dochecksrv = false;
  675             break;
  676 
  677         case '?':
  678             if (isc_commandline_option != '?') {
  679                 fprintf(stderr, "%s: invalid argument -%c\n",
  680                     program, isc_commandline_option);
  681             }
  682         /* FALLTHROUGH */
  683         case 'h':
  684             usage();
  685 
  686         default:
  687             fprintf(stderr, "%s: unhandled option -%c\n", program,
  688                 isc_commandline_option);
  689             exit(1);
  690         }
  691     }
  692 
  693     if (((flags & CFG_PRINTER_XKEY) != 0) && !print) {
  694         fprintf(stderr, "%s: -x cannot be used without -p\n", program);
  695         exit(1);
  696     }
  697     if (print && list_zones) {
  698         fprintf(stderr, "%s: -l cannot be used with -p\n", program);
  699         exit(1);
  700     }
  701 
  702     if (isc_commandline_index + 1 < argc) {
  703         usage();
  704     }
  705     if (argv[isc_commandline_index] != NULL) {
  706         conffile = argv[isc_commandline_index];
  707     }
  708     if (conffile == NULL || conffile[0] == '\0') {
  709         conffile = NAMED_CONFFILE;
  710     }
  711 
  712 #ifdef _WIN32
  713     InitSockets();
  714 #endif /* ifdef _WIN32 */
  715 
  716     RUNTIME_CHECK(setup_logging(mctx, stdout, &logc) == ISC_R_SUCCESS);
  717 
  718     dns_result_register();
  719 
  720     RUNTIME_CHECK(cfg_parser_create(mctx, logc, &parser) == ISC_R_SUCCESS);
  721 
  722     if (nodeprecate) {
  723         cfg_parser_setflags(parser, CFG_PCTX_NODEPRECATED, true);
  724     }
  725     cfg_parser_setcallback(parser, directory_callback, NULL);
  726 
  727     if (cfg_parse_file(parser, conffile, &cfg_type_namedconf, &config) !=
  728         ISC_R_SUCCESS)
  729     {
  730         exit(1);
  731     }
  732 
  733     result = bind9_check_namedconf(config, loadplugins, logc, mctx);
  734     if (result != ISC_R_SUCCESS) {
  735         exit_status = 1;
  736     }
  737 
  738     if (result == ISC_R_SUCCESS && (load_zones || list_zones)) {
  739         result = load_zones_fromconfig(config, mctx, list_zones);
  740         if (result != ISC_R_SUCCESS) {
  741             exit_status = 1;
  742         }
  743     }
  744 
  745     if (print && exit_status == 0) {
  746         cfg_printx(config, flags, output, NULL);
  747     }
  748     cfg_obj_destroy(parser, &config);
  749 
  750     cfg_parser_destroy(&parser);
  751 
  752     isc_log_destroy(&logc);
  753 
  754     isc_mem_destroy(&mctx);
  755 
  756 #ifdef _WIN32
  757     DestroySockets();
  758 #endif /* ifdef _WIN32 */
  759 
  760     return (exit_status);
  761 }