named-checkconf.c revision 135446
1135446Strhodes/* 2135446Strhodes * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") 3135446Strhodes * Copyright (C) 1999-2002 Internet Software Consortium. 4135446Strhodes * 5135446Strhodes * Permission to use, copy, modify, and 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 18135446Strhodes/* $Id: named-checkconf.c,v 1.12.12.7 2004/03/08 09:04:14 marka Exp $ */ 19135446Strhodes 20135446Strhodes#include <config.h> 21135446Strhodes 22135446Strhodes#include <errno.h> 23135446Strhodes#include <stdlib.h> 24135446Strhodes#include <stdio.h> 25135446Strhodes 26135446Strhodes#include <isc/commandline.h> 27135446Strhodes#include <isc/dir.h> 28135446Strhodes#include <isc/log.h> 29135446Strhodes#include <isc/mem.h> 30135446Strhodes#include <isc/result.h> 31135446Strhodes#include <isc/string.h> 32135446Strhodes#include <isc/util.h> 33135446Strhodes 34135446Strhodes#include <isccfg/namedconf.h> 35135446Strhodes 36135446Strhodes#include <bind9/check.h> 37135446Strhodes 38135446Strhodes#include <dns/log.h> 39135446Strhodes#include <dns/result.h> 40135446Strhodes 41135446Strhodes#include "check-tool.h" 42135446Strhodes 43135446Strhodesisc_log_t *logc = NULL; 44135446Strhodes 45135446Strhodes#define CHECK(r)\ 46135446Strhodes do { \ 47135446Strhodes result = (r); \ 48135446Strhodes if (result != ISC_R_SUCCESS) \ 49135446Strhodes goto cleanup; \ 50135446Strhodes } while (0) 51135446Strhodes 52135446Strhodesstatic void 53135446Strhodesusage(void) { 54135446Strhodes fprintf(stderr, "usage: named-checkconf [-j] [-v] [-z] [-t directory] " 55135446Strhodes "[named.conf]\n"); 56135446Strhodes exit(1); 57135446Strhodes} 58135446Strhodes 59135446Strhodesstatic isc_result_t 60135446Strhodesdirectory_callback(const char *clausename, cfg_obj_t *obj, void *arg) { 61135446Strhodes isc_result_t result; 62135446Strhodes char *directory; 63135446Strhodes 64135446Strhodes REQUIRE(strcasecmp("directory", clausename) == 0); 65135446Strhodes 66135446Strhodes UNUSED(arg); 67135446Strhodes UNUSED(clausename); 68135446Strhodes 69135446Strhodes /* 70135446Strhodes * Change directory. 71135446Strhodes */ 72135446Strhodes directory = cfg_obj_asstring(obj); 73135446Strhodes result = isc_dir_chdir(directory); 74135446Strhodes if (result != ISC_R_SUCCESS) { 75135446Strhodes cfg_obj_log(obj, logc, ISC_LOG_ERROR, 76135446Strhodes "change directory to '%s' failed: %s\n", 77135446Strhodes directory, isc_result_totext(result)); 78135446Strhodes return (result); 79135446Strhodes } 80135446Strhodes 81135446Strhodes return (ISC_R_SUCCESS); 82135446Strhodes} 83135446Strhodes 84135446Strhodesstatic isc_result_t 85135446Strhodesconfigure_zone(const char *vclass, const char *view, cfg_obj_t *zconfig, 86135446Strhodes isc_mem_t *mctx) 87135446Strhodes{ 88135446Strhodes isc_result_t result; 89135446Strhodes const char *zclass; 90135446Strhodes const char *zname; 91135446Strhodes const char *zfile; 92135446Strhodes cfg_obj_t *zoptions = NULL; 93135446Strhodes cfg_obj_t *classobj = NULL; 94135446Strhodes cfg_obj_t *typeobj = NULL; 95135446Strhodes cfg_obj_t *fileobj = NULL; 96135446Strhodes cfg_obj_t *dbobj = NULL; 97135446Strhodes 98135446Strhodes zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); 99135446Strhodes classobj = cfg_tuple_get(zconfig, "class"); 100135446Strhodes if (!cfg_obj_isstring(classobj)) 101135446Strhodes zclass = vclass; 102135446Strhodes else 103135446Strhodes zclass = cfg_obj_asstring(classobj); 104135446Strhodes zoptions = cfg_tuple_get(zconfig, "options"); 105135446Strhodes cfg_map_get(zoptions, "type", &typeobj); 106135446Strhodes if (typeobj == NULL) 107135446Strhodes return (ISC_R_FAILURE); 108135446Strhodes if (strcasecmp(cfg_obj_asstring(typeobj), "master") != 0) 109135446Strhodes return (ISC_R_SUCCESS); 110135446Strhodes cfg_map_get(zoptions, "database", &dbobj); 111135446Strhodes if (dbobj != NULL) 112135446Strhodes return (ISC_R_SUCCESS); 113135446Strhodes cfg_map_get(zoptions, "file", &fileobj); 114135446Strhodes if (fileobj == NULL) 115135446Strhodes return (ISC_R_FAILURE); 116135446Strhodes zfile = cfg_obj_asstring(fileobj); 117135446Strhodes result = load_zone(mctx, zname, zfile, zclass, NULL); 118135446Strhodes if (result != ISC_R_SUCCESS) 119135446Strhodes fprintf(stderr, "%s/%s/%s: %s\n", view, zname, zclass, 120135446Strhodes dns_result_totext(result)); 121135446Strhodes return(result); 122135446Strhodes} 123135446Strhodes 124135446Strhodesstatic isc_result_t 125135446Strhodesconfigure_view(const char *vclass, const char *view, cfg_obj_t *config, 126135446Strhodes cfg_obj_t *vconfig, isc_mem_t *mctx) 127135446Strhodes{ 128135446Strhodes cfg_listelt_t *element; 129135446Strhodes cfg_obj_t *voptions; 130135446Strhodes cfg_obj_t *zonelist; 131135446Strhodes isc_result_t result = ISC_R_SUCCESS; 132135446Strhodes isc_result_t tresult; 133135446Strhodes 134135446Strhodes voptions = NULL; 135135446Strhodes if (vconfig != NULL) 136135446Strhodes voptions = cfg_tuple_get(vconfig, "options"); 137135446Strhodes 138135446Strhodes zonelist = NULL; 139135446Strhodes if (voptions != NULL) 140135446Strhodes (void)cfg_map_get(voptions, "zone", &zonelist); 141135446Strhodes else 142135446Strhodes (void)cfg_map_get(config, "zone", &zonelist); 143135446Strhodes 144135446Strhodes for (element = cfg_list_first(zonelist); 145135446Strhodes element != NULL; 146135446Strhodes element = cfg_list_next(element)) 147135446Strhodes { 148135446Strhodes cfg_obj_t *zconfig = cfg_listelt_value(element); 149135446Strhodes tresult = configure_zone(vclass, view, zconfig, mctx); 150135446Strhodes if (tresult != ISC_R_SUCCESS) 151135446Strhodes result = tresult; 152135446Strhodes } 153135446Strhodes return (result); 154135446Strhodes} 155135446Strhodes 156135446Strhodes 157135446Strhodesstatic isc_result_t 158135446Strhodesload_zones_fromconfig(cfg_obj_t *config, isc_mem_t *mctx) { 159135446Strhodes cfg_listelt_t *element; 160135446Strhodes cfg_obj_t *classobj; 161135446Strhodes cfg_obj_t *views; 162135446Strhodes cfg_obj_t *vconfig; 163135446Strhodes const char *vclass; 164135446Strhodes isc_result_t result = ISC_R_SUCCESS; 165135446Strhodes isc_result_t tresult; 166135446Strhodes 167135446Strhodes views = NULL; 168135446Strhodes 169135446Strhodes (void)cfg_map_get(config, "view", &views); 170135446Strhodes for (element = cfg_list_first(views); 171135446Strhodes element != NULL; 172135446Strhodes element = cfg_list_next(element)) 173135446Strhodes { 174135446Strhodes const char *vname; 175135446Strhodes 176135446Strhodes vclass = "IN"; 177135446Strhodes vconfig = cfg_listelt_value(element); 178135446Strhodes if (vconfig != NULL) { 179135446Strhodes classobj = cfg_tuple_get(vconfig, "class"); 180135446Strhodes if (cfg_obj_isstring(classobj)) 181135446Strhodes vclass = cfg_obj_asstring(classobj); 182135446Strhodes } 183135446Strhodes vname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name")); 184135446Strhodes tresult = configure_view(vclass, vname, config, vconfig, mctx); 185135446Strhodes if (tresult != ISC_R_SUCCESS) 186135446Strhodes result = tresult; 187135446Strhodes } 188135446Strhodes 189135446Strhodes if (views == NULL) { 190135446Strhodes tresult = configure_view("IN", "_default", config, NULL, mctx); 191135446Strhodes if (tresult != ISC_R_SUCCESS) 192135446Strhodes result = tresult; 193135446Strhodes } 194135446Strhodes return (result); 195135446Strhodes} 196135446Strhodes 197135446Strhodesint 198135446Strhodesmain(int argc, char **argv) { 199135446Strhodes int c; 200135446Strhodes cfg_parser_t *parser = NULL; 201135446Strhodes cfg_obj_t *config = NULL; 202135446Strhodes const char *conffile = NULL; 203135446Strhodes isc_mem_t *mctx = NULL; 204135446Strhodes isc_result_t result; 205135446Strhodes int exit_status = 0; 206135446Strhodes isc_boolean_t load_zones = ISC_FALSE; 207135446Strhodes 208135446Strhodes while ((c = isc_commandline_parse(argc, argv, "djt:vz")) != EOF) { 209135446Strhodes switch (c) { 210135446Strhodes case 'd': 211135446Strhodes debug++; 212135446Strhodes break; 213135446Strhodes 214135446Strhodes case 'j': 215135446Strhodes nomerge = ISC_FALSE; 216135446Strhodes break; 217135446Strhodes 218135446Strhodes case 't': 219135446Strhodes result = isc_dir_chroot(isc_commandline_argument); 220135446Strhodes if (result != ISC_R_SUCCESS) { 221135446Strhodes fprintf(stderr, "isc_dir_chroot: %s\n", 222135446Strhodes isc_result_totext(result)); 223135446Strhodes exit(1); 224135446Strhodes } 225135446Strhodes result = isc_dir_chdir("/"); 226135446Strhodes if (result != ISC_R_SUCCESS) { 227135446Strhodes fprintf(stderr, "isc_dir_chdir: %s\n", 228135446Strhodes isc_result_totext(result)); 229135446Strhodes exit(1); 230135446Strhodes } 231135446Strhodes break; 232135446Strhodes 233135446Strhodes case 'v': 234135446Strhodes printf(VERSION "\n"); 235135446Strhodes exit(0); 236135446Strhodes 237135446Strhodes case 'z': 238135446Strhodes load_zones = ISC_TRUE; 239135446Strhodes break; 240135446Strhodes 241135446Strhodes default: 242135446Strhodes usage(); 243135446Strhodes } 244135446Strhodes } 245135446Strhodes 246135446Strhodes if (argv[isc_commandline_index] != NULL) 247135446Strhodes conffile = argv[isc_commandline_index]; 248135446Strhodes if (conffile == NULL || conffile[0] == '\0') 249135446Strhodes conffile = NAMED_CONFFILE; 250135446Strhodes 251135446Strhodes RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); 252135446Strhodes 253135446Strhodes RUNTIME_CHECK(setup_logging(mctx, &logc) == ISC_R_SUCCESS); 254135446Strhodes 255135446Strhodes dns_result_register(); 256135446Strhodes 257135446Strhodes RUNTIME_CHECK(cfg_parser_create(mctx, logc, &parser) == ISC_R_SUCCESS); 258135446Strhodes 259135446Strhodes cfg_parser_setcallback(parser, directory_callback, NULL); 260135446Strhodes 261135446Strhodes if (cfg_parse_file(parser, conffile, &cfg_type_namedconf, &config) != 262135446Strhodes ISC_R_SUCCESS) 263135446Strhodes exit(1); 264135446Strhodes 265135446Strhodes result = bind9_check_namedconf(config, logc, mctx); 266135446Strhodes if (result != ISC_R_SUCCESS) 267135446Strhodes exit_status = 1; 268135446Strhodes 269135446Strhodes if (result == ISC_R_SUCCESS && load_zones) { 270135446Strhodes dns_log_init(logc); 271135446Strhodes dns_log_setcontext(logc); 272135446Strhodes result = load_zones_fromconfig(config, mctx); 273135446Strhodes if (result != ISC_R_SUCCESS) 274135446Strhodes exit_status = 1; 275135446Strhodes } 276135446Strhodes 277135446Strhodes cfg_obj_destroy(parser, &config); 278135446Strhodes 279135446Strhodes cfg_parser_destroy(&parser); 280135446Strhodes 281135446Strhodes isc_log_destroy(&logc); 282135446Strhodes 283135446Strhodes isc_mem_destroy(&mctx); 284135446Strhodes 285135446Strhodes return (exit_status); 286135446Strhodes} 287