named-checkconf.c revision 254402
1135446Strhodes/* 2254402Serwin * Copyright (C) 2004-2007, 2009-2013 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 18234010Sdougb/* $Id: named-checkconf.c,v 1.54.62.2 2011/03/12 04:59:13 tbox 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 } 193225361Sdougb 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; 298254402Serwin if (get_maps(maps, "check-spf", &obj)) { 299254402Serwin if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { 300254402Serwin zone_options |= DNS_ZONEOPT_CHECKSPF; 301254402Serwin } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { 302254402Serwin zone_options &= ~DNS_ZONEOPT_CHECKSPF; 303254402Serwin } else 304254402Serwin INSIST(0); 305254402Serwin } else { 306254402Serwin zone_options |= DNS_ZONEOPT_CHECKSPF; 307254402Serwin } 308254402Serwin 309254402Serwin obj = NULL; 310170222Sdougb if (get_checknames(maps, &obj)) { 311170222Sdougb if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { 312170222Sdougb zone_options |= DNS_ZONEOPT_CHECKNAMES; 313170222Sdougb zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; 314170222Sdougb } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { 315170222Sdougb zone_options |= DNS_ZONEOPT_CHECKNAMES; 316170222Sdougb zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; 317170222Sdougb } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { 318170222Sdougb zone_options &= ~DNS_ZONEOPT_CHECKNAMES; 319170222Sdougb zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; 320170222Sdougb } else 321170222Sdougb INSIST(0); 322170222Sdougb } else { 323193149Sdougb zone_options |= DNS_ZONEOPT_CHECKNAMES; 324193149Sdougb zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; 325170222Sdougb } 326170222Sdougb 327170222Sdougb masterformat = dns_masterformat_text; 328170222Sdougb fmtobj = NULL; 329170222Sdougb result = config_get(maps, "masterfile-format", &fmtobj); 330170222Sdougb if (result == ISC_R_SUCCESS) { 331170222Sdougb const char *masterformatstr = cfg_obj_asstring(fmtobj); 332170222Sdougb if (strcasecmp(masterformatstr, "text") == 0) 333170222Sdougb masterformat = dns_masterformat_text; 334170222Sdougb else if (strcasecmp(masterformatstr, "raw") == 0) 335170222Sdougb masterformat = dns_masterformat_raw; 336170222Sdougb else 337170222Sdougb INSIST(0); 338170222Sdougb } 339170222Sdougb 340170222Sdougb result = load_zone(mctx, zname, zfile, masterformat, zclass, NULL); 341135446Strhodes if (result != ISC_R_SUCCESS) 342135446Strhodes fprintf(stderr, "%s/%s/%s: %s\n", view, zname, zclass, 343135446Strhodes dns_result_totext(result)); 344135446Strhodes return(result); 345135446Strhodes} 346135446Strhodes 347170222Sdougb/*% configure a view */ 348135446Strhodesstatic isc_result_t 349165071Sdougbconfigure_view(const char *vclass, const char *view, const cfg_obj_t *config, 350165071Sdougb const cfg_obj_t *vconfig, isc_mem_t *mctx) 351135446Strhodes{ 352165071Sdougb const cfg_listelt_t *element; 353165071Sdougb const cfg_obj_t *voptions; 354165071Sdougb const cfg_obj_t *zonelist; 355135446Strhodes isc_result_t result = ISC_R_SUCCESS; 356135446Strhodes isc_result_t tresult; 357135446Strhodes 358135446Strhodes voptions = NULL; 359135446Strhodes if (vconfig != NULL) 360135446Strhodes voptions = cfg_tuple_get(vconfig, "options"); 361135446Strhodes 362135446Strhodes zonelist = NULL; 363135446Strhodes if (voptions != NULL) 364135446Strhodes (void)cfg_map_get(voptions, "zone", &zonelist); 365135446Strhodes else 366135446Strhodes (void)cfg_map_get(config, "zone", &zonelist); 367135446Strhodes 368135446Strhodes for (element = cfg_list_first(zonelist); 369135446Strhodes element != NULL; 370135446Strhodes element = cfg_list_next(element)) 371135446Strhodes { 372165071Sdougb const cfg_obj_t *zconfig = cfg_listelt_value(element); 373170222Sdougb tresult = configure_zone(vclass, view, zconfig, vconfig, 374170222Sdougb config, mctx); 375135446Strhodes if (tresult != ISC_R_SUCCESS) 376135446Strhodes result = tresult; 377135446Strhodes } 378135446Strhodes return (result); 379135446Strhodes} 380135446Strhodes 381135446Strhodes 382170222Sdougb/*% load zones from the configuration */ 383135446Strhodesstatic isc_result_t 384165071Sdougbload_zones_fromconfig(const cfg_obj_t *config, isc_mem_t *mctx) { 385165071Sdougb const cfg_listelt_t *element; 386165071Sdougb const cfg_obj_t *classobj; 387165071Sdougb const cfg_obj_t *views; 388165071Sdougb const cfg_obj_t *vconfig; 389135446Strhodes const char *vclass; 390135446Strhodes isc_result_t result = ISC_R_SUCCESS; 391135446Strhodes isc_result_t tresult; 392135446Strhodes 393135446Strhodes views = NULL; 394135446Strhodes 395135446Strhodes (void)cfg_map_get(config, "view", &views); 396135446Strhodes for (element = cfg_list_first(views); 397135446Strhodes element != NULL; 398135446Strhodes element = cfg_list_next(element)) 399135446Strhodes { 400135446Strhodes const char *vname; 401135446Strhodes 402135446Strhodes vclass = "IN"; 403135446Strhodes vconfig = cfg_listelt_value(element); 404135446Strhodes if (vconfig != NULL) { 405135446Strhodes classobj = cfg_tuple_get(vconfig, "class"); 406135446Strhodes if (cfg_obj_isstring(classobj)) 407135446Strhodes vclass = cfg_obj_asstring(classobj); 408135446Strhodes } 409135446Strhodes vname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name")); 410135446Strhodes tresult = configure_view(vclass, vname, config, vconfig, mctx); 411135446Strhodes if (tresult != ISC_R_SUCCESS) 412135446Strhodes result = tresult; 413135446Strhodes } 414135446Strhodes 415135446Strhodes if (views == NULL) { 416135446Strhodes tresult = configure_view("IN", "_default", config, NULL, mctx); 417135446Strhodes if (tresult != ISC_R_SUCCESS) 418135446Strhodes result = tresult; 419135446Strhodes } 420135446Strhodes return (result); 421135446Strhodes} 422135446Strhodes 423224092Sdougbstatic void 424224092Sdougboutput(void *closure, const char *text, int textlen) { 425224092Sdougb UNUSED(closure); 426224092Sdougb if (fwrite(text, 1, textlen, stdout) != (size_t)textlen) { 427224092Sdougb perror("fwrite"); 428224092Sdougb exit(1); 429224092Sdougb } 430224092Sdougb} 431224092Sdougb 432170222Sdougb/*% The main processing routine */ 433135446Strhodesint 434135446Strhodesmain(int argc, char **argv) { 435135446Strhodes int c; 436135446Strhodes cfg_parser_t *parser = NULL; 437135446Strhodes cfg_obj_t *config = NULL; 438135446Strhodes const char *conffile = NULL; 439135446Strhodes isc_mem_t *mctx = NULL; 440135446Strhodes isc_result_t result; 441135446Strhodes int exit_status = 0; 442143731Sdougb isc_entropy_t *ectx = NULL; 443135446Strhodes isc_boolean_t load_zones = ISC_FALSE; 444224092Sdougb isc_boolean_t print = ISC_FALSE; 445193149Sdougb 446193149Sdougb isc_commandline_errprint = ISC_FALSE; 447193149Sdougb 448224092Sdougb while ((c = isc_commandline_parse(argc, argv, "dhjt:pvz")) != EOF) { 449135446Strhodes switch (c) { 450135446Strhodes case 'd': 451135446Strhodes debug++; 452135446Strhodes break; 453135446Strhodes 454135446Strhodes case 'j': 455135446Strhodes nomerge = ISC_FALSE; 456135446Strhodes break; 457135446Strhodes 458135446Strhodes case 't': 459135446Strhodes result = isc_dir_chroot(isc_commandline_argument); 460135446Strhodes if (result != ISC_R_SUCCESS) { 461135446Strhodes fprintf(stderr, "isc_dir_chroot: %s\n", 462135446Strhodes isc_result_totext(result)); 463135446Strhodes exit(1); 464135446Strhodes } 465135446Strhodes break; 466135446Strhodes 467224092Sdougb case 'p': 468224092Sdougb print = ISC_TRUE; 469224092Sdougb break; 470224092Sdougb 471135446Strhodes case 'v': 472135446Strhodes printf(VERSION "\n"); 473135446Strhodes exit(0); 474135446Strhodes 475135446Strhodes case 'z': 476135446Strhodes load_zones = ISC_TRUE; 477170222Sdougb docheckmx = ISC_FALSE; 478170222Sdougb docheckns = ISC_FALSE; 479170222Sdougb dochecksrv = ISC_FALSE; 480135446Strhodes break; 481135446Strhodes 482193149Sdougb case '?': 483193149Sdougb if (isc_commandline_option != '?') 484193149Sdougb fprintf(stderr, "%s: invalid argument -%c\n", 485193149Sdougb program, isc_commandline_option); 486254402Serwin /* FALLTHROUGH */ 487193149Sdougb case 'h': 488193149Sdougb usage(); 489193149Sdougb 490135446Strhodes default: 491193149Sdougb fprintf(stderr, "%s: unhandled option -%c\n", 492193149Sdougb program, isc_commandline_option); 493193149Sdougb exit(1); 494135446Strhodes } 495135446Strhodes } 496135446Strhodes 497193149Sdougb if (isc_commandline_index + 1 < argc) 498193149Sdougb usage(); 499135446Strhodes if (argv[isc_commandline_index] != NULL) 500135446Strhodes conffile = argv[isc_commandline_index]; 501135446Strhodes if (conffile == NULL || conffile[0] == '\0') 502135446Strhodes conffile = NAMED_CONFFILE; 503135446Strhodes 504216175Sdougb#ifdef _WIN32 505216175Sdougb InitSockets(); 506216175Sdougb#endif 507216175Sdougb 508135446Strhodes RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); 509135446Strhodes 510193149Sdougb RUNTIME_CHECK(setup_logging(mctx, stdout, &logc) == ISC_R_SUCCESS); 511135446Strhodes 512143731Sdougb RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS); 513143731Sdougb RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE) 514143731Sdougb == ISC_R_SUCCESS); 515143731Sdougb 516135446Strhodes dns_result_register(); 517135446Strhodes 518135446Strhodes RUNTIME_CHECK(cfg_parser_create(mctx, logc, &parser) == ISC_R_SUCCESS); 519135446Strhodes 520135446Strhodes cfg_parser_setcallback(parser, directory_callback, NULL); 521135446Strhodes 522135446Strhodes if (cfg_parse_file(parser, conffile, &cfg_type_namedconf, &config) != 523135446Strhodes ISC_R_SUCCESS) 524135446Strhodes exit(1); 525135446Strhodes 526135446Strhodes result = bind9_check_namedconf(config, logc, mctx); 527135446Strhodes if (result != ISC_R_SUCCESS) 528135446Strhodes exit_status = 1; 529135446Strhodes 530135446Strhodes if (result == ISC_R_SUCCESS && load_zones) { 531135446Strhodes result = load_zones_fromconfig(config, mctx); 532135446Strhodes if (result != ISC_R_SUCCESS) 533135446Strhodes exit_status = 1; 534135446Strhodes } 535135446Strhodes 536224092Sdougb if (print && exit_status == 0) 537224092Sdougb cfg_print(config, output, NULL); 538135446Strhodes cfg_obj_destroy(parser, &config); 539135446Strhodes 540135446Strhodes cfg_parser_destroy(&parser); 541135446Strhodes 542170222Sdougb dns_name_destroy(); 543170222Sdougb 544135446Strhodes isc_log_destroy(&logc); 545135446Strhodes 546143731Sdougb isc_hash_destroy(); 547143731Sdougb isc_entropy_detach(&ectx); 548143731Sdougb 549135446Strhodes isc_mem_destroy(&mctx); 550135446Strhodes 551216175Sdougb#ifdef _WIN32 552216175Sdougb DestroySockets(); 553216175Sdougb#endif 554216175Sdougb 555135446Strhodes return (exit_status); 556135446Strhodes} 557