Import bind-9.3.4
[dragonfly.git] / contrib / bind-9.3 / bin / check / named-checkconf.c
blobf50461d792561af413585816934f666e8d09abd5
1 /*
2 * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2002 Internet Software Consortium.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: named-checkconf.c,v 1.12.12.11 2006/03/02 00:37:20 marka Exp $ */
20 #include <config.h>
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <stdio.h>
26 #include <isc/commandline.h>
27 #include <isc/dir.h>
28 #include <isc/entropy.h>
29 #include <isc/hash.h>
30 #include <isc/log.h>
31 #include <isc/mem.h>
32 #include <isc/result.h>
33 #include <isc/string.h>
34 #include <isc/util.h>
36 #include <isccfg/namedconf.h>
38 #include <bind9/check.h>
40 #include <dns/fixedname.h>
41 #include <dns/log.h>
42 #include <dns/result.h>
44 #include "check-tool.h"
46 isc_log_t *logc = NULL;
48 #define CHECK(r)\
49 do { \
50 result = (r); \
51 if (result != ISC_R_SUCCESS) \
52 goto cleanup; \
53 } while (0)
55 static void
56 usage(void) {
57 fprintf(stderr, "usage: named-checkconf [-j] [-v] [-z] [-t directory] "
58 "[named.conf]\n");
59 exit(1);
62 static isc_result_t
63 directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) {
64 isc_result_t result;
65 const char *directory;
67 REQUIRE(strcasecmp("directory", clausename) == 0);
69 UNUSED(arg);
70 UNUSED(clausename);
73 * Change directory.
75 directory = cfg_obj_asstring(obj);
76 result = isc_dir_chdir(directory);
77 if (result != ISC_R_SUCCESS) {
78 cfg_obj_log(obj, logc, ISC_LOG_ERROR,
79 "change directory to '%s' failed: %s\n",
80 directory, isc_result_totext(result));
81 return (result);
84 return (ISC_R_SUCCESS);
87 static isc_result_t
88 configure_zone(const char *vclass, const char *view,
89 const cfg_obj_t *zconfig, isc_mem_t *mctx)
91 isc_result_t result;
92 const char *zclass;
93 const char *zname;
94 const char *zfile;
95 const cfg_obj_t *zoptions = NULL;
96 const cfg_obj_t *classobj = NULL;
97 const cfg_obj_t *typeobj = NULL;
98 const cfg_obj_t *fileobj = NULL;
99 const cfg_obj_t *dbobj = NULL;
101 zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
102 classobj = cfg_tuple_get(zconfig, "class");
103 if (!cfg_obj_isstring(classobj))
104 zclass = vclass;
105 else
106 zclass = cfg_obj_asstring(classobj);
107 zoptions = cfg_tuple_get(zconfig, "options");
108 cfg_map_get(zoptions, "type", &typeobj);
109 if (typeobj == NULL)
110 return (ISC_R_FAILURE);
111 if (strcasecmp(cfg_obj_asstring(typeobj), "master") != 0)
112 return (ISC_R_SUCCESS);
113 cfg_map_get(zoptions, "database", &dbobj);
114 if (dbobj != NULL)
115 return (ISC_R_SUCCESS);
116 cfg_map_get(zoptions, "file", &fileobj);
117 if (fileobj == NULL)
118 return (ISC_R_FAILURE);
119 zfile = cfg_obj_asstring(fileobj);
120 result = load_zone(mctx, zname, zfile, zclass, NULL);
121 if (result != ISC_R_SUCCESS)
122 fprintf(stderr, "%s/%s/%s: %s\n", view, zname, zclass,
123 dns_result_totext(result));
124 return(result);
127 static isc_result_t
128 configure_view(const char *vclass, const char *view, const cfg_obj_t *config,
129 const cfg_obj_t *vconfig, isc_mem_t *mctx)
131 const cfg_listelt_t *element;
132 const cfg_obj_t *voptions;
133 const cfg_obj_t *zonelist;
134 isc_result_t result = ISC_R_SUCCESS;
135 isc_result_t tresult;
137 voptions = NULL;
138 if (vconfig != NULL)
139 voptions = cfg_tuple_get(vconfig, "options");
141 zonelist = NULL;
142 if (voptions != NULL)
143 (void)cfg_map_get(voptions, "zone", &zonelist);
144 else
145 (void)cfg_map_get(config, "zone", &zonelist);
147 for (element = cfg_list_first(zonelist);
148 element != NULL;
149 element = cfg_list_next(element))
151 const cfg_obj_t *zconfig = cfg_listelt_value(element);
152 tresult = configure_zone(vclass, view, zconfig, mctx);
153 if (tresult != ISC_R_SUCCESS)
154 result = tresult;
156 return (result);
160 static isc_result_t
161 load_zones_fromconfig(const cfg_obj_t *config, isc_mem_t *mctx) {
162 const cfg_listelt_t *element;
163 const cfg_obj_t *classobj;
164 const cfg_obj_t *views;
165 const cfg_obj_t *vconfig;
166 const char *vclass;
167 isc_result_t result = ISC_R_SUCCESS;
168 isc_result_t tresult;
170 views = NULL;
172 (void)cfg_map_get(config, "view", &views);
173 for (element = cfg_list_first(views);
174 element != NULL;
175 element = cfg_list_next(element))
177 const char *vname;
179 vclass = "IN";
180 vconfig = cfg_listelt_value(element);
181 if (vconfig != NULL) {
182 classobj = cfg_tuple_get(vconfig, "class");
183 if (cfg_obj_isstring(classobj))
184 vclass = cfg_obj_asstring(classobj);
186 vname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name"));
187 tresult = configure_view(vclass, vname, config, vconfig, mctx);
188 if (tresult != ISC_R_SUCCESS)
189 result = tresult;
192 if (views == NULL) {
193 tresult = configure_view("IN", "_default", config, NULL, mctx);
194 if (tresult != ISC_R_SUCCESS)
195 result = tresult;
197 return (result);
201 main(int argc, char **argv) {
202 int c;
203 cfg_parser_t *parser = NULL;
204 cfg_obj_t *config = NULL;
205 const char *conffile = NULL;
206 isc_mem_t *mctx = NULL;
207 isc_result_t result;
208 int exit_status = 0;
209 isc_entropy_t *ectx = NULL;
210 isc_boolean_t load_zones = ISC_FALSE;
212 while ((c = isc_commandline_parse(argc, argv, "djt:vz")) != EOF) {
213 switch (c) {
214 case 'd':
215 debug++;
216 break;
218 case 'j':
219 nomerge = ISC_FALSE;
220 break;
222 case 't':
223 result = isc_dir_chroot(isc_commandline_argument);
224 if (result != ISC_R_SUCCESS) {
225 fprintf(stderr, "isc_dir_chroot: %s\n",
226 isc_result_totext(result));
227 exit(1);
229 result = isc_dir_chdir("/");
230 if (result != ISC_R_SUCCESS) {
231 fprintf(stderr, "isc_dir_chdir: %s\n",
232 isc_result_totext(result));
233 exit(1);
235 break;
237 case 'v':
238 printf(VERSION "\n");
239 exit(0);
241 case 'z':
242 load_zones = ISC_TRUE;
243 break;
245 default:
246 usage();
250 if (argv[isc_commandline_index] != NULL)
251 conffile = argv[isc_commandline_index];
252 if (conffile == NULL || conffile[0] == '\0')
253 conffile = NAMED_CONFFILE;
255 RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
257 RUNTIME_CHECK(setup_logging(mctx, &logc) == ISC_R_SUCCESS);
259 RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS);
260 RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)
261 == ISC_R_SUCCESS);
263 dns_result_register();
265 RUNTIME_CHECK(cfg_parser_create(mctx, logc, &parser) == ISC_R_SUCCESS);
267 cfg_parser_setcallback(parser, directory_callback, NULL);
269 if (cfg_parse_file(parser, conffile, &cfg_type_namedconf, &config) !=
270 ISC_R_SUCCESS)
271 exit(1);
273 result = bind9_check_namedconf(config, logc, mctx);
274 if (result != ISC_R_SUCCESS)
275 exit_status = 1;
277 if (result == ISC_R_SUCCESS && load_zones) {
278 dns_log_init(logc);
279 dns_log_setcontext(logc);
280 result = load_zones_fromconfig(config, mctx);
281 if (result != ISC_R_SUCCESS)
282 exit_status = 1;
285 cfg_obj_destroy(parser, &config);
287 cfg_parser_destroy(&parser);
289 isc_log_destroy(&logc);
291 isc_hash_destroy();
292 isc_entropy_detach(&ectx);
294 isc_mem_destroy(&mctx);
296 return (exit_status);