2 * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 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-checkzone.c,v 1.29.18.16 2006/10/05 05:24:35 marka Exp $ */
27 #include <isc/commandline.h>
29 #include <isc/entropy.h>
33 #include <isc/socket.h>
34 #include <isc/string.h>
36 #include <isc/timer.h>
40 #include <dns/fixedname.h>
42 #include <dns/masterdump.h>
44 #include <dns/rdataclass.h>
45 #include <dns/rdataset.h>
46 #include <dns/result.h>
47 #include <dns/types.h>
50 #include "check-tool.h"
53 static isc_mem_t *mctx = NULL;
54 static isc_entropy_t *ectx = NULL;
55 dns_zone_t *zone = NULL;
56 dns_zonetype_t zonetype = dns_zone_master;
57 static int dumpzone = 0;
58 static const char *output_filename;
59 static char *prog_name = NULL;
60 static const dns_master_style_t *outputstyle = NULL;
61 static enum { progmode_check, progmode_compile } progmode;
63 #define ERRRET(result, function) \
65 if (result != ISC_R_SUCCESS) { \
67 fprintf(stderr, "%s() returned %s\n", \
68 function, dns_result_totext(result)); \
76 "usage: %s [-djqvD] [-c class] [-o output] "
77 "[-f inputformat] [-F outputformat] "
78 "[-t directory] [-w directory] [-k (ignore|warn|fail)] "
79 "[-n (ignore|warn|fail)] [-m (ignore|warn|fail)] "
80 "[-i (full|local|none)] [-M (ignore|warn|fail)] "
81 "[-S (ignore|warn|fail)] [-W (ignore|warn)] "
82 "zonename filename\n", prog_name);
89 dns_zone_detach(&zone);
93 /*% main processing routine */
95 main(int argc, char **argv) {
98 char *filename = NULL;
99 isc_log_t *lctx = NULL;
101 char classname_in[] = "IN";
102 char *classname = classname_in;
103 const char *workdir = NULL;
104 const char *inputformatstr = NULL;
105 const char *outputformatstr = NULL;
106 dns_masterformat_t inputformat = dns_masterformat_text;
107 dns_masterformat_t outputformat = dns_masterformat_text;
109 outputstyle = &dns_master_style_full;
111 prog_name = strrchr(argv[0], '/');
112 if (prog_name != NULL)
117 * Libtool doesn't preserve the program name prior to final
118 * installation. Remove the libtool prefix ("lt-").
120 if (strncmp(prog_name, "lt-", 3) == 0)
122 if (strcmp(prog_name, "named-checkzone") == 0)
123 progmode = progmode_check;
124 else if (strcmp(prog_name, "named-compilezone") == 0)
125 progmode = progmode_compile;
129 /* Compilation specific defaults */
130 if (progmode == progmode_compile) {
131 zone_options |= (DNS_ZONEOPT_CHECKNS |
132 DNS_ZONEOPT_FATALNS |
133 DNS_ZONEOPT_CHECKNAMES |
134 DNS_ZONEOPT_CHECKNAMESFAIL |
135 DNS_ZONEOPT_CHECKWILDCARD);
138 #define ARGCMP(X) (strcmp(isc_commandline_argument, X) == 0)
140 while ((c = isc_commandline_parse(argc, argv,
141 "c:df:i:jk:m:n:qs:t:o:vw:DF:M:S:W:"))
145 classname = isc_commandline_argument;
153 if (ARGCMP("full")) {
154 zone_options |= DNS_ZONEOPT_CHECKINTEGRITY |
155 DNS_ZONEOPT_CHECKSIBLING;
156 docheckmx = ISC_TRUE;
157 docheckns = ISC_TRUE;
158 dochecksrv = ISC_TRUE;
159 } else if (ARGCMP("full-sibling")) {
160 zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
161 zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
162 docheckmx = ISC_TRUE;
163 docheckns = ISC_TRUE;
164 dochecksrv = ISC_TRUE;
165 } else if (ARGCMP("local")) {
166 zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
167 zone_options |= DNS_ZONEOPT_CHECKSIBLING;
168 docheckmx = ISC_FALSE;
169 docheckns = ISC_FALSE;
170 dochecksrv = ISC_FALSE;
171 } else if (ARGCMP("local-sibling")) {
172 zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
173 zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
174 docheckmx = ISC_FALSE;
175 docheckns = ISC_FALSE;
176 dochecksrv = ISC_FALSE;
177 } else if (ARGCMP("none")) {
178 zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY;
179 zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
180 docheckmx = ISC_FALSE;
181 docheckns = ISC_FALSE;
182 dochecksrv = ISC_FALSE;
184 fprintf(stderr, "invalid argument to -i: %s\n",
185 isc_commandline_argument);
191 inputformatstr = isc_commandline_argument;
195 outputformatstr = isc_commandline_argument;
203 if (ARGCMP("warn")) {
204 zone_options |= DNS_ZONEOPT_CHECKNAMES;
205 zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL;
206 } else if (ARGCMP("fail")) {
207 zone_options |= DNS_ZONEOPT_CHECKNAMES |
208 DNS_ZONEOPT_CHECKNAMESFAIL;
209 } else if (ARGCMP("ignore")) {
210 zone_options &= ~(DNS_ZONEOPT_CHECKNAMES |
211 DNS_ZONEOPT_CHECKNAMESFAIL);
213 fprintf(stderr, "invalid argument to -k: %s\n",
214 isc_commandline_argument);
220 if (ARGCMP("ignore")) {
221 zone_options &= ~(DNS_ZONEOPT_CHECKNS|
222 DNS_ZONEOPT_FATALNS);
223 } else if (ARGCMP("warn")) {
224 zone_options |= DNS_ZONEOPT_CHECKNS;
225 zone_options &= ~DNS_ZONEOPT_FATALNS;
226 } else if (ARGCMP("fail")) {
227 zone_options |= DNS_ZONEOPT_CHECKNS|
230 fprintf(stderr, "invalid argument to -n: %s\n",
231 isc_commandline_argument);
237 if (ARGCMP("warn")) {
238 zone_options |= DNS_ZONEOPT_CHECKMX;
239 zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL;
240 } else if (ARGCMP("fail")) {
241 zone_options |= DNS_ZONEOPT_CHECKMX |
242 DNS_ZONEOPT_CHECKMXFAIL;
243 } else if (ARGCMP("ignore")) {
244 zone_options &= ~(DNS_ZONEOPT_CHECKMX |
245 DNS_ZONEOPT_CHECKMXFAIL);
247 fprintf(stderr, "invalid argument to -m: %s\n",
248 isc_commandline_argument);
258 result = isc_dir_chroot(isc_commandline_argument);
259 if (result != ISC_R_SUCCESS) {
260 fprintf(stderr, "isc_dir_chroot: %s: %s\n",
261 isc_commandline_argument,
262 isc_result_totext(result));
265 result = isc_dir_chdir("/");
266 if (result != ISC_R_SUCCESS) {
267 fprintf(stderr, "isc_dir_chdir: %s\n",
268 isc_result_totext(result));
275 outputstyle = &dns_master_style_full;
276 else if (ARGCMP("relative")) {
277 outputstyle = &dns_master_style_default;
280 "unknown or unsupported style: %s\n",
281 isc_commandline_argument);
287 output_filename = isc_commandline_argument;
291 printf(VERSION "\n");
295 workdir = isc_commandline_argument;
303 if (ARGCMP("fail")) {
304 zone_options &= ~DNS_ZONEOPT_WARNMXCNAME;
305 zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME;
306 } else if (ARGCMP("warn")) {
307 zone_options |= DNS_ZONEOPT_WARNMXCNAME;
308 zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME;
309 } else if (ARGCMP("ignore")) {
310 zone_options |= DNS_ZONEOPT_WARNMXCNAME;
311 zone_options |= DNS_ZONEOPT_IGNOREMXCNAME;
313 fprintf(stderr, "invalid argument to -M: %s\n",
314 isc_commandline_argument);
320 if (ARGCMP("fail")) {
321 zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME;
322 zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME;
323 } else if (ARGCMP("warn")) {
324 zone_options |= DNS_ZONEOPT_WARNSRVCNAME;
325 zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME;
326 } else if (ARGCMP("ignore")) {
327 zone_options |= DNS_ZONEOPT_WARNSRVCNAME;
328 zone_options |= DNS_ZONEOPT_IGNORESRVCNAME;
330 fprintf(stderr, "invalid argument to -S: %s\n",
331 isc_commandline_argument);
338 zone_options |= DNS_ZONEOPT_CHECKWILDCARD;
339 else if (ARGCMP("ignore"))
340 zone_options &= ~DNS_ZONEOPT_CHECKWILDCARD;
348 if (progmode == progmode_compile) {
349 dumpzone = 1; /* always dump */
350 if (output_filename == NULL) {
352 "output file required, but not specified\n");
357 if (workdir != NULL) {
358 result = isc_dir_chdir(workdir);
359 if (result != ISC_R_SUCCESS) {
360 fprintf(stderr, "isc_dir_chdir: %s: %s\n",
361 workdir, isc_result_totext(result));
366 if (inputformatstr != NULL) {
367 if (strcasecmp(inputformatstr, "text") == 0)
368 inputformat = dns_masterformat_text;
369 else if (strcasecmp(inputformatstr, "raw") == 0)
370 inputformat = dns_masterformat_raw;
372 fprintf(stderr, "unknown file format: %s\n",
378 if (outputformatstr != NULL) {
379 if (strcasecmp(outputformatstr, "text") == 0)
380 outputformat = dns_masterformat_text;
381 else if (strcasecmp(outputformatstr, "raw") == 0)
382 outputformat = dns_masterformat_raw;
384 fprintf(stderr, "unknown file format: %s\n",
390 if (isc_commandline_index + 2 > argc)
393 RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
395 RUNTIME_CHECK(setup_logging(mctx, &lctx) == ISC_R_SUCCESS);
396 RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS);
397 RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)
400 dns_result_register();
402 origin = argv[isc_commandline_index++];
403 filename = argv[isc_commandline_index++];
404 result = load_zone(mctx, origin, filename, inputformat, classname,
407 if (result == ISC_R_SUCCESS && dumpzone) {
408 if (!quiet && progmode == progmode_compile) {
409 fprintf(stdout, "dump zone to %s...", output_filename);
412 result = dump_zone(origin, zone, output_filename,
413 outputformat, outputstyle);
414 if (!quiet && progmode == progmode_compile)
415 fprintf(stdout, "done\n");
418 if (!quiet && result == ISC_R_SUCCESS)
419 fprintf(stdout, "OK\n");
422 isc_log_destroy(&lctx);
424 isc_entropy_detach(&ectx);
425 isc_mem_destroy(&mctx);
426 return ((result == ISC_R_SUCCESS) ? 0 : 1);