named-checkconf.c revision 224092
1135446Strhodes/* 2216175Sdougb * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC") 3135446Strhodes * Copyright (C) 1999-2002 Internet Software Consortium. 4135446Strhodes * 5186462Sdougb * Permission to use, copy, modify, and/or distribute this software for any 6135446Strhodes * purpose with or without fee is hereby granted, provided that the above 7135446Strhodes * copyright notice and this permission notice appear in all copies. 8135446Strhodes * 9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11135446Strhodes * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15135446Strhodes * PERFORMANCE OF THIS SOFTWARE. 16135446Strhodes */ 17135446Strhodes 18224092Sdougb/* $Id: named-checkconf.c,v 1.54 2010-09-07 01:49:08 marka Exp $ */ 19135446Strhodes 20170222Sdougb/*! \file */ 21170222Sdougb 22135446Strhodes#include <config.h> 23135446Strhodes 24135446Strhodes#include <errno.h> 25135446Strhodes#include <stdlib.h> 26135446Strhodes#include <stdio.h> 27135446Strhodes 28135446Strhodes#include <isc/commandline.h> 29135446Strhodes#include <isc/dir.h> 30143731Sdougb#include <isc/entropy.h> 31143731Sdougb#include <isc/hash.h> 32135446Strhodes#include <isc/log.h> 33135446Strhodes#include <isc/mem.h> 34135446Strhodes#include <isc/result.h> 35135446Strhodes#include <isc/string.h> 36135446Strhodes#include <isc/util.h> 37135446Strhodes 38135446Strhodes#include <isccfg/namedconf.h> 39135446Strhodes 40135446Strhodes#include <bind9/check.h> 41135446Strhodes 42143731Sdougb#include <dns/fixedname.h> 43135446Strhodes#include <dns/log.h> 44170222Sdougb#include <dns/name.h> 45135446Strhodes#include <dns/result.h> 46170222Sdougb#include <dns/zone.h> 47135446Strhodes 48135446Strhodes#include "check-tool.h" 49135446Strhodes 50193149Sdougbstatic const char *program = "named-checkconf"; 51193149Sdougb 52135446Strhodesisc_log_t *logc = NULL; 53135446Strhodes 54135446Strhodes#define CHECK(r)\ 55135446Strhodes do { \ 56135446Strhodes result = (r); \ 57135446Strhodes if (result != ISC_R_SUCCESS) \ 58135446Strhodes goto cleanup; \ 59135446Strhodes } while (0) 60135446Strhodes 61170222Sdougb/*% usage */ 62224092SdougbISC_PLATFORM_NORETURN_PRE static void 63224092Sdougbusage(void) ISC_PLATFORM_NORETURN_POST; 64224092Sdougb 65135446Strhodesstatic void 66135446Strhodesusage(void) { 67224092Sdougb fprintf(stderr, "usage: %s [-h] [-j] [-p] [-v] [-z] [-t directory] " 68193149Sdougb "[named.conf]\n", program); 69193149Sdougb exit(1); 70135446Strhodes} 71135446Strhodes 72170222Sdougb/*% directory callback */ 73135446Strhodesstatic isc_result_t 74165071Sdougbdirectory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) { 75135446Strhodes isc_result_t result; 76165071Sdougb const char *directory; 77135446Strhodes 78135446Strhodes REQUIRE(strcasecmp("directory", clausename) == 0); 79135446Strhodes 80135446Strhodes UNUSED(arg); 81135446Strhodes UNUSED(clausename); 82135446Strhodes 83135446Strhodes /* 84135446Strhodes * Change directory. 85135446Strhodes */ 86135446Strhodes directory = cfg_obj_asstring(obj); 87135446Strhodes result = isc_dir_chdir(directory); 88135446Strhodes if (result != ISC_R_SUCCESS) { 89135446Strhodes cfg_obj_log(obj, logc, ISC_LOG_ERROR, 90135446Strhodes "change directory to '%s' failed: %s\n", 91135446Strhodes directory, isc_result_totext(result)); 92135446Strhodes return (result); 93135446Strhodes } 94135446Strhodes 95135446Strhodes return (ISC_R_SUCCESS); 96135446Strhodes} 97135446Strhodes 98170222Sdougbstatic isc_boolean_t 99170222Sdougbget_maps(const cfg_obj_t **maps, const char *name, const cfg_obj_t **obj) { 100170222Sdougb int i; 101170222Sdougb for (i = 0;; i++) { 102170222Sdougb if (maps[i] == NULL) 103170222Sdougb return (ISC_FALSE); 104170222Sdougb if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) 105170222Sdougb return (ISC_TRUE); 106170222Sdougb } 107170222Sdougb} 108170222Sdougb 109170222Sdougbstatic isc_boolean_t 110170222Sdougbget_checknames(const cfg_obj_t **maps, const cfg_obj_t **obj) { 111170222Sdougb const cfg_listelt_t *element; 112170222Sdougb const cfg_obj_t *checknames; 113170222Sdougb const cfg_obj_t *type; 114170222Sdougb const cfg_obj_t *value; 115170222Sdougb isc_result_t result; 116170222Sdougb int i; 117170222Sdougb 118170222Sdougb for (i = 0;; i++) { 119170222Sdougb if (maps[i] == NULL) 120170222Sdougb return (ISC_FALSE); 121170222Sdougb checknames = NULL; 122170222Sdougb result = cfg_map_get(maps[i], "check-names", &checknames); 123170222Sdougb if (result != ISC_R_SUCCESS) 124170222Sdougb continue; 125170222Sdougb if (checknames != NULL && !cfg_obj_islist(checknames)) { 126170222Sdougb *obj = checknames; 127170222Sdougb return (ISC_TRUE); 128170222Sdougb } 129170222Sdougb for (element = cfg_list_first(checknames); 130170222Sdougb element != NULL; 131170222Sdougb element = cfg_list_next(element)) { 132170222Sdougb value = cfg_listelt_value(element); 133170222Sdougb type = cfg_tuple_get(value, "type"); 134170222Sdougb if (strcasecmp(cfg_obj_asstring(type), "master") != 0) 135170222Sdougb continue; 136170222Sdougb *obj = cfg_tuple_get(value, "mode"); 137170222Sdougb return (ISC_TRUE); 138170222Sdougb } 139170222Sdougb } 140170222Sdougb} 141170222Sdougb 142135446Strhodesstatic isc_result_t 143170222Sdougbconfig_get(const cfg_obj_t **maps, const char *name, const cfg_obj_t **obj) { 144170222Sdougb int i; 145170222Sdougb 146170222Sdougb for (i = 0;; i++) { 147170222Sdougb if (maps[i] == NULL) 148170222Sdougb return (ISC_R_NOTFOUND); 149170222Sdougb if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) 150170222Sdougb return (ISC_R_SUCCESS); 151170222Sdougb } 152170222Sdougb} 153170222Sdougb 154170222Sdougb/*% configure the zone */ 155170222Sdougbstatic isc_result_t 156165071Sdougbconfigure_zone(const char *vclass, const char *view, 157170222Sdougb const cfg_obj_t *zconfig, const cfg_obj_t *vconfig, 158170222Sdougb const cfg_obj_t *config, isc_mem_t *mctx) 159135446Strhodes{ 160170222Sdougb int i = 0; 161135446Strhodes isc_result_t result; 162135446Strhodes const char *zclass; 163135446Strhodes const char *zname; 164135446Strhodes const char *zfile; 165170222Sdougb const cfg_obj_t *maps[4]; 166165071Sdougb const cfg_obj_t *zoptions = NULL; 167165071Sdougb const cfg_obj_t *classobj = NULL; 168165071Sdougb const cfg_obj_t *typeobj = NULL; 169165071Sdougb const cfg_obj_t *fileobj = NULL; 170165071Sdougb const cfg_obj_t *dbobj = NULL; 171170222Sdougb const cfg_obj_t *obj = NULL; 172170222Sdougb const cfg_obj_t *fmtobj = NULL; 173170222Sdougb dns_masterformat_t masterformat; 174135446Strhodes 175170222Sdougb zone_options = DNS_ZONEOPT_CHECKNS | DNS_ZONEOPT_MANYERRORS; 176170222Sdougb 177135446Strhodes zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); 178135446Strhodes classobj = cfg_tuple_get(zconfig, "class"); 179193149Sdougb if (!cfg_obj_isstring(classobj)) 180193149Sdougb zclass = vclass; 181193149Sdougb else 182135446Strhodes zclass = cfg_obj_asstring(classobj); 183170222Sdougb 184135446Strhodes zoptions = cfg_tuple_get(zconfig, "options"); 185170222Sdougb maps[i++] = zoptions; 186170222Sdougb if (vconfig != NULL) 187170222Sdougb maps[i++] = cfg_tuple_get(vconfig, "options"); 188170222Sdougb if (config != NULL) { 189170222Sdougb cfg_map_get(config, "options", &obj); 190170222Sdougb if (obj != NULL) 191170222Sdougb maps[i++] = obj; 192170222Sdougb } 193170222Sdougb maps[i++] = NULL; 194170222Sdougb 195135446Strhodes cfg_map_get(zoptions, "type", &typeobj); 196135446Strhodes if (typeobj == NULL) 197135446Strhodes return (ISC_R_FAILURE); 198135446Strhodes if (strcasecmp(cfg_obj_asstring(typeobj), "master") != 0) 199135446Strhodes return (ISC_R_SUCCESS); 200193149Sdougb cfg_map_get(zoptions, "database", &dbobj); 201193149Sdougb if (dbobj != NULL) 202193149Sdougb return (ISC_R_SUCCESS); 203135446Strhodes cfg_map_get(zoptions, "file", &fileobj); 204135446Strhodes if (fileobj == NULL) 205135446Strhodes return (ISC_R_FAILURE); 206135446Strhodes zfile = cfg_obj_asstring(fileobj); 207170222Sdougb 208170222Sdougb obj = NULL; 209224092Sdougb if (get_maps(maps, "check-dup-records", &obj)) { 210224092Sdougb if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { 211224092Sdougb zone_options |= DNS_ZONEOPT_CHECKDUPRR; 212224092Sdougb zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; 213224092Sdougb } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { 214224092Sdougb zone_options |= DNS_ZONEOPT_CHECKDUPRR; 215224092Sdougb zone_options |= DNS_ZONEOPT_CHECKDUPRRFAIL; 216224092Sdougb } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { 217224092Sdougb zone_options &= ~DNS_ZONEOPT_CHECKDUPRR; 218224092Sdougb zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; 219224092Sdougb } else 220224092Sdougb INSIST(0); 221224092Sdougb } else { 222224092Sdougb zone_options |= DNS_ZONEOPT_CHECKDUPRR; 223224092Sdougb zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; 224224092Sdougb } 225224092Sdougb 226224092Sdougb obj = NULL; 227170222Sdougb if (get_maps(maps, "check-mx", &obj)) { 228170222Sdougb if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { 229170222Sdougb zone_options |= DNS_ZONEOPT_CHECKMX; 230170222Sdougb zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; 231170222Sdougb } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { 232170222Sdougb zone_options |= DNS_ZONEOPT_CHECKMX; 233170222Sdougb zone_options |= DNS_ZONEOPT_CHECKMXFAIL; 234170222Sdougb } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { 235170222Sdougb zone_options &= ~DNS_ZONEOPT_CHECKMX; 236170222Sdougb zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; 237170222Sdougb } else 238170222Sdougb INSIST(0); 239170222Sdougb } else { 240170222Sdougb zone_options |= DNS_ZONEOPT_CHECKMX; 241170222Sdougb zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; 242170222Sdougb } 243170222Sdougb 244170222Sdougb obj = NULL; 245170222Sdougb if (get_maps(maps, "check-integrity", &obj)) { 246170222Sdougb if (cfg_obj_asboolean(obj)) 247170222Sdougb zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; 248170222Sdougb else 249170222Sdougb zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY; 250186462Sdougb } else 251186462Sdougb zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; 252170222Sdougb 253170222Sdougb obj = NULL; 254170222Sdougb if (get_maps(maps, "check-mx-cname", &obj)) { 255170222Sdougb if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { 256170222Sdougb zone_options |= DNS_ZONEOPT_WARNMXCNAME; 257170222Sdougb zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; 258170222Sdougb } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { 259170222Sdougb zone_options &= ~DNS_ZONEOPT_WARNMXCNAME; 260170222Sdougb zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; 261170222Sdougb } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { 262170222Sdougb zone_options |= DNS_ZONEOPT_WARNMXCNAME; 263170222Sdougb zone_options |= DNS_ZONEOPT_IGNOREMXCNAME; 264170222Sdougb } else 265170222Sdougb INSIST(0); 266170222Sdougb } else { 267170222Sdougb zone_options |= DNS_ZONEOPT_WARNMXCNAME; 268170222Sdougb zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; 269170222Sdougb } 270170222Sdougb 271170222Sdougb obj = NULL; 272170222Sdougb if (get_maps(maps, "check-srv-cname", &obj)) { 273170222Sdougb if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { 274170222Sdougb zone_options |= DNS_ZONEOPT_WARNSRVCNAME; 275170222Sdougb zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; 276170222Sdougb } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { 277170222Sdougb zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME; 278170222Sdougb zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; 279170222Sdougb } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { 280170222Sdougb zone_options |= DNS_ZONEOPT_WARNSRVCNAME; 281170222Sdougb zone_options |= DNS_ZONEOPT_IGNORESRVCNAME; 282170222Sdougb } else 283170222Sdougb INSIST(0); 284170222Sdougb } else { 285170222Sdougb zone_options |= DNS_ZONEOPT_WARNSRVCNAME; 286170222Sdougb zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; 287170222Sdougb } 288170222Sdougb 289170222Sdougb obj = NULL; 290170222Sdougb if (get_maps(maps, "check-sibling", &obj)) { 291170222Sdougb if (cfg_obj_asboolean(obj)) 292170222Sdougb zone_options |= DNS_ZONEOPT_CHECKSIBLING; 293170222Sdougb else 294170222Sdougb zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; 295170222Sdougb } 296170222Sdougb 297170222Sdougb obj = NULL; 298170222Sdougb if (get_checknames(maps, &obj)) { 299170222Sdougb if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { 300170222Sdougb zone_options |= DNS_ZONEOPT_CHECKNAMES; 301170222Sdougb zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; 302170222Sdougb } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { 303170222Sdougb zone_options |= DNS_ZONEOPT_CHECKNAMES; 304170222Sdougb zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; 305170222Sdougb } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { 306170222Sdougb zone_options &= ~DNS_ZONEOPT_CHECKNAMES; 307170222Sdougb zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; 308170222Sdougb } else 309170222Sdougb INSIST(0); 310170222Sdougb } else { 311193149Sdougb zone_options |= DNS_ZONEOPT_CHECKNAMES; 312193149Sdougb zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; 313170222Sdougb } 314170222Sdougb 315170222Sdougb masterformat = dns_masterformat_text; 316170222Sdougb fmtobj = NULL; 317170222Sdougb result = config_get(maps, "masterfile-format", &fmtobj); 318170222Sdougb if (result == ISC_R_SUCCESS) { 319170222Sdougb const char *masterformatstr = cfg_obj_asstring(fmtobj); 320170222Sdougb if (strcasecmp(masterformatstr, "text") == 0) 321170222Sdougb masterformat = dns_masterformat_text; 322170222Sdougb else if (strcasecmp(masterformatstr, "raw") == 0) 323170222Sdougb masterformat = dns_masterformat_raw; 324170222Sdougb else 325170222Sdougb INSIST(0); 326170222Sdougb } 327170222Sdougb 328170222Sdougb result = load_zone(mctx, zname, zfile, masterformat, zclass, NULL); 329135446Strhodes if (result != ISC_R_SUCCESS) 330135446Strhodes fprintf(stderr, "%s/%s/%s: %s\n", view, zname, zclass, 331135446Strhodes dns_result_totext(result)); 332135446Strhodes return(result); 333135446Strhodes} 334135446Strhodes 335170222Sdougb/*% configure a view */ 336135446Strhodesstatic isc_result_t 337165071Sdougbconfigure_view(const char *vclass, const char *view, const cfg_obj_t *config, 338165071Sdougb const cfg_obj_t *vconfig, isc_mem_t *mctx) 339135446Strhodes{ 340165071Sdougb const cfg_listelt_t *element; 341165071Sdougb const cfg_obj_t *voptions; 342165071Sdougb const cfg_obj_t *zonelist; 343135446Strhodes isc_result_t result = ISC_R_SUCCESS; 344135446Strhodes isc_result_t tresult; 345135446Strhodes 346135446Strhodes voptions = NULL; 347135446Strhodes if (vconfig != NULL) 348135446Strhodes voptions = cfg_tuple_get(vconfig, "options"); 349135446Strhodes 350135446Strhodes zonelist = NULL; 351135446Strhodes if (voptions != NULL) 352135446Strhodes (void)cfg_map_get(voptions, "zone", &zonelist); 353135446Strhodes else 354135446Strhodes (void)cfg_map_get(config, "zone", &zonelist); 355135446Strhodes 356135446Strhodes for (element = cfg_list_first(zonelist); 357135446Strhodes element != NULL; 358135446Strhodes element = cfg_list_next(element)) 359135446Strhodes { 360165071Sdougb const cfg_obj_t *zconfig = cfg_listelt_value(element); 361170222Sdougb tresult = configure_zone(vclass, view, zconfig, vconfig, 362170222Sdougb config, mctx); 363135446Strhodes if (tresult != ISC_R_SUCCESS) 364135446Strhodes result = tresult; 365135446Strhodes } 366135446Strhodes return (result); 367135446Strhodes} 368135446Strhodes 369135446Strhodes 370170222Sdougb/*% load zones from the configuration */ 371135446Strhodesstatic isc_result_t 372165071Sdougbload_zones_fromconfig(const cfg_obj_t *config, isc_mem_t *mctx) { 373165071Sdougb const cfg_listelt_t *element; 374165071Sdougb const cfg_obj_t *classobj; 375165071Sdougb const cfg_obj_t *views; 376165071Sdougb const cfg_obj_t *vconfig; 377135446Strhodes const char *vclass; 378135446Strhodes isc_result_t result = ISC_R_SUCCESS; 379135446Strhodes isc_result_t tresult; 380135446Strhodes 381135446Strhodes views = NULL; 382135446Strhodes 383135446Strhodes (void)cfg_map_get(config, "view", &views); 384135446Strhodes for (element = cfg_list_first(views); 385135446Strhodes element != NULL; 386135446Strhodes element = cfg_list_next(element)) 387135446Strhodes { 388135446Strhodes const char *vname; 389135446Strhodes 390135446Strhodes vclass = "IN"; 391135446Strhodes vconfig = cfg_listelt_value(element); 392135446Strhodes if (vconfig != NULL) { 393135446Strhodes classobj = cfg_tuple_get(vconfig, "class"); 394135446Strhodes if (cfg_obj_isstring(classobj)) 395135446Strhodes vclass = cfg_obj_asstring(classobj); 396135446Strhodes } 397135446Strhodes vname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name")); 398135446Strhodes tresult = configure_view(vclass, vname, config, vconfig, mctx); 399135446Strhodes if (tresult != ISC_R_SUCCESS) 400135446Strhodes result = tresult; 401135446Strhodes } 402135446Strhodes 403135446Strhodes if (views == NULL) { 404135446Strhodes tresult = configure_view("IN", "_default", config, NULL, mctx); 405135446Strhodes if (tresult != ISC_R_SUCCESS) 406135446Strhodes result = tresult; 407135446Strhodes } 408135446Strhodes return (result); 409135446Strhodes} 410135446Strhodes 411224092Sdougbstatic void 412224092Sdougboutput(void *closure, const char *text, int textlen) { 413224092Sdougb UNUSED(closure); 414224092Sdougb if (fwrite(text, 1, textlen, stdout) != (size_t)textlen) { 415224092Sdougb perror("fwrite"); 416224092Sdougb exit(1); 417224092Sdougb } 418224092Sdougb} 419224092Sdougb 420170222Sdougb/*% The main processing routine */ 421135446Strhodesint 422135446Strhodesmain(int argc, char **argv) { 423135446Strhodes int c; 424135446Strhodes cfg_parser_t *parser = NULL; 425135446Strhodes cfg_obj_t *config = NULL; 426135446Strhodes const char *conffile = NULL; 427135446Strhodes isc_mem_t *mctx = NULL; 428135446Strhodes isc_result_t result; 429135446Strhodes int exit_status = 0; 430143731Sdougb isc_entropy_t *ectx = NULL; 431135446Strhodes isc_boolean_t load_zones = ISC_FALSE; 432224092Sdougb isc_boolean_t print = ISC_FALSE; 433193149Sdougb 434193149Sdougb isc_commandline_errprint = ISC_FALSE; 435193149Sdougb 436224092Sdougb while ((c = isc_commandline_parse(argc, argv, "dhjt:pvz")) != EOF) { 437135446Strhodes switch (c) { 438135446Strhodes case 'd': 439135446Strhodes debug++; 440135446Strhodes break; 441135446Strhodes 442135446Strhodes case 'j': 443135446Strhodes nomerge = ISC_FALSE; 444135446Strhodes break; 445135446Strhodes 446135446Strhodes case 't': 447135446Strhodes result = isc_dir_chroot(isc_commandline_argument); 448135446Strhodes if (result != ISC_R_SUCCESS) { 449135446Strhodes fprintf(stderr, "isc_dir_chroot: %s\n", 450135446Strhodes isc_result_totext(result)); 451135446Strhodes exit(1); 452135446Strhodes } 453135446Strhodes break; 454135446Strhodes 455224092Sdougb case 'p': 456224092Sdougb print = ISC_TRUE; 457224092Sdougb break; 458224092Sdougb 459135446Strhodes case 'v': 460135446Strhodes printf(VERSION "\n"); 461135446Strhodes exit(0); 462135446Strhodes 463135446Strhodes case 'z': 464135446Strhodes load_zones = ISC_TRUE; 465170222Sdougb docheckmx = ISC_FALSE; 466170222Sdougb docheckns = ISC_FALSE; 467170222Sdougb dochecksrv = ISC_FALSE; 468135446Strhodes break; 469135446Strhodes 470193149Sdougb case '?': 471193149Sdougb if (isc_commandline_option != '?') 472193149Sdougb fprintf(stderr, "%s: invalid argument -%c\n", 473193149Sdougb program, isc_commandline_option); 474193149Sdougb case 'h': 475193149Sdougb usage(); 476193149Sdougb 477135446Strhodes default: 478193149Sdougb fprintf(stderr, "%s: unhandled option -%c\n", 479193149Sdougb program, isc_commandline_option); 480193149Sdougb exit(1); 481135446Strhodes } 482135446Strhodes } 483135446Strhodes 484193149Sdougb if (isc_commandline_index + 1 < argc) 485193149Sdougb usage(); 486135446Strhodes if (argv[isc_commandline_index] != NULL) 487135446Strhodes conffile = argv[isc_commandline_index]; 488135446Strhodes if (conffile == NULL || conffile[0] == '\0') 489135446Strhodes conffile = NAMED_CONFFILE; 490135446Strhodes 491216175Sdougb#ifdef _WIN32 492216175Sdougb InitSockets(); 493216175Sdougb#endif 494216175Sdougb 495135446Strhodes RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); 496135446Strhodes 497193149Sdougb RUNTIME_CHECK(setup_logging(mctx, stdout, &logc) == ISC_R_SUCCESS); 498135446Strhodes 499143731Sdougb RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS); 500143731Sdougb RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE) 501143731Sdougb == ISC_R_SUCCESS); 502143731Sdougb 503135446Strhodes dns_result_register(); 504135446Strhodes 505135446Strhodes RUNTIME_CHECK(cfg_parser_create(mctx, logc, &parser) == ISC_R_SUCCESS); 506135446Strhodes 507135446Strhodes cfg_parser_setcallback(parser, directory_callback, NULL); 508135446Strhodes 509135446Strhodes if (cfg_parse_file(parser, conffile, &cfg_type_namedconf, &config) != 510135446Strhodes ISC_R_SUCCESS) 511135446Strhodes exit(1); 512135446Strhodes 513135446Strhodes result = bind9_check_namedconf(config, logc, mctx); 514135446Strhodes if (result != ISC_R_SUCCESS) 515135446Strhodes exit_status = 1; 516135446Strhodes 517135446Strhodes if (result == ISC_R_SUCCESS && load_zones) { 518135446Strhodes result = load_zones_fromconfig(config, mctx); 519135446Strhodes if (result != ISC_R_SUCCESS) 520135446Strhodes exit_status = 1; 521135446Strhodes } 522135446Strhodes 523224092Sdougb if (print && exit_status == 0) 524224092Sdougb cfg_print(config, output, NULL); 525135446Strhodes cfg_obj_destroy(parser, &config); 526135446Strhodes 527135446Strhodes cfg_parser_destroy(&parser); 528135446Strhodes 529170222Sdougb dns_name_destroy(); 530170222Sdougb 531135446Strhodes isc_log_destroy(&logc); 532135446Strhodes 533143731Sdougb isc_hash_destroy(); 534143731Sdougb isc_entropy_detach(&ectx); 535143731Sdougb 536135446Strhodes isc_mem_destroy(&mctx); 537135446Strhodes 538216175Sdougb#ifdef _WIN32 539216175Sdougb DestroySockets(); 540216175Sdougb#endif 541216175Sdougb 542135446Strhodes return (exit_status); 543135446Strhodes} 544