2 * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or 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.51.34.4 2009/11/10 20:01:41 each 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] "
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|full-sibling|local|local-sibling|none)] "
81 "[-M (ignore|warn|fail)] [-S (ignore|warn|fail)] "
83 "%s zonename filename\n",
85 progmode == progmode_check ? "[-o filename]" : "{-o filename}");
92 dns_zone_detach(&zone);
96 /*% main processing routine */
98 main(int argc, char **argv) {
101 char *filename = NULL;
102 isc_log_t *lctx = NULL;
104 char classname_in[] = "IN";
105 char *classname = classname_in;
106 const char *workdir = NULL;
107 const char *inputformatstr = NULL;
108 const char *outputformatstr = NULL;
109 dns_masterformat_t inputformat = dns_masterformat_text;
110 dns_masterformat_t outputformat = dns_masterformat_text;
111 FILE *errout = stdout;
113 outputstyle = &dns_master_style_full;
115 prog_name = strrchr(argv[0], '/');
116 if (prog_name == NULL)
117 prog_name = strrchr(argv[0], '\\');
118 if (prog_name != NULL)
123 * Libtool doesn't preserve the program name prior to final
124 * installation. Remove the libtool prefix ("lt-").
126 if (strncmp(prog_name, "lt-", 3) == 0)
130 (strcasecmp(prog_name, X) == 0 || strcasecmp(prog_name, X ".exe") == 0)
132 if (PROGCMP("named-checkzone"))
133 progmode = progmode_check;
134 else if (PROGCMP("named-compilezone"))
135 progmode = progmode_compile;
139 /* Compilation specific defaults */
140 if (progmode == progmode_compile) {
141 zone_options |= (DNS_ZONEOPT_CHECKNS |
142 DNS_ZONEOPT_FATALNS |
143 DNS_ZONEOPT_CHECKNAMES |
144 DNS_ZONEOPT_CHECKNAMESFAIL |
145 DNS_ZONEOPT_CHECKWILDCARD);
148 #define ARGCMP(X) (strcmp(isc_commandline_argument, X) == 0)
150 isc_commandline_errprint = ISC_FALSE;
152 while ((c = isc_commandline_parse(argc, argv,
153 "c:df:hi:jk:m:n:qs:t:o:vw:DF:M:S:W:"))
157 classname = isc_commandline_argument;
165 if (ARGCMP("full")) {
166 zone_options |= DNS_ZONEOPT_CHECKINTEGRITY |
167 DNS_ZONEOPT_CHECKSIBLING;
168 docheckmx = ISC_TRUE;
169 docheckns = ISC_TRUE;
170 dochecksrv = ISC_TRUE;
171 } else if (ARGCMP("full-sibling")) {
172 zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
173 zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
174 docheckmx = ISC_TRUE;
175 docheckns = ISC_TRUE;
176 dochecksrv = ISC_TRUE;
177 } else if (ARGCMP("local")) {
178 zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
179 zone_options |= DNS_ZONEOPT_CHECKSIBLING;
180 docheckmx = ISC_FALSE;
181 docheckns = ISC_FALSE;
182 dochecksrv = ISC_FALSE;
183 } else if (ARGCMP("local-sibling")) {
184 zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
185 zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
186 docheckmx = ISC_FALSE;
187 docheckns = ISC_FALSE;
188 dochecksrv = ISC_FALSE;
189 } else if (ARGCMP("none")) {
190 zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY;
191 zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
192 docheckmx = ISC_FALSE;
193 docheckns = ISC_FALSE;
194 dochecksrv = ISC_FALSE;
196 fprintf(stderr, "invalid argument to -i: %s\n",
197 isc_commandline_argument);
203 inputformatstr = isc_commandline_argument;
207 outputformatstr = isc_commandline_argument;
215 if (ARGCMP("warn")) {
216 zone_options |= DNS_ZONEOPT_CHECKNAMES;
217 zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL;
218 } else if (ARGCMP("fail")) {
219 zone_options |= DNS_ZONEOPT_CHECKNAMES |
220 DNS_ZONEOPT_CHECKNAMESFAIL;
221 } else if (ARGCMP("ignore")) {
222 zone_options &= ~(DNS_ZONEOPT_CHECKNAMES |
223 DNS_ZONEOPT_CHECKNAMESFAIL);
225 fprintf(stderr, "invalid argument to -k: %s\n",
226 isc_commandline_argument);
232 if (ARGCMP("ignore")) {
233 zone_options &= ~(DNS_ZONEOPT_CHECKNS|
234 DNS_ZONEOPT_FATALNS);
235 } else if (ARGCMP("warn")) {
236 zone_options |= DNS_ZONEOPT_CHECKNS;
237 zone_options &= ~DNS_ZONEOPT_FATALNS;
238 } else if (ARGCMP("fail")) {
239 zone_options |= DNS_ZONEOPT_CHECKNS|
242 fprintf(stderr, "invalid argument to -n: %s\n",
243 isc_commandline_argument);
249 if (ARGCMP("warn")) {
250 zone_options |= DNS_ZONEOPT_CHECKMX;
251 zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL;
252 } else if (ARGCMP("fail")) {
253 zone_options |= DNS_ZONEOPT_CHECKMX |
254 DNS_ZONEOPT_CHECKMXFAIL;
255 } else if (ARGCMP("ignore")) {
256 zone_options &= ~(DNS_ZONEOPT_CHECKMX |
257 DNS_ZONEOPT_CHECKMXFAIL);
259 fprintf(stderr, "invalid argument to -m: %s\n",
260 isc_commandline_argument);
270 result = isc_dir_chroot(isc_commandline_argument);
271 if (result != ISC_R_SUCCESS) {
272 fprintf(stderr, "isc_dir_chroot: %s: %s\n",
273 isc_commandline_argument,
274 isc_result_totext(result));
281 outputstyle = &dns_master_style_full;
282 else if (ARGCMP("relative")) {
283 outputstyle = &dns_master_style_default;
286 "unknown or unsupported style: %s\n",
287 isc_commandline_argument);
293 output_filename = isc_commandline_argument;
297 printf(VERSION "\n");
301 workdir = isc_commandline_argument;
309 if (ARGCMP("fail")) {
310 zone_options &= ~DNS_ZONEOPT_WARNMXCNAME;
311 zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME;
312 } else if (ARGCMP("warn")) {
313 zone_options |= DNS_ZONEOPT_WARNMXCNAME;
314 zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME;
315 } else if (ARGCMP("ignore")) {
316 zone_options |= DNS_ZONEOPT_WARNMXCNAME;
317 zone_options |= DNS_ZONEOPT_IGNOREMXCNAME;
319 fprintf(stderr, "invalid argument to -M: %s\n",
320 isc_commandline_argument);
326 if (ARGCMP("fail")) {
327 zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME;
328 zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME;
329 } else if (ARGCMP("warn")) {
330 zone_options |= DNS_ZONEOPT_WARNSRVCNAME;
331 zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME;
332 } else if (ARGCMP("ignore")) {
333 zone_options |= DNS_ZONEOPT_WARNSRVCNAME;
334 zone_options |= DNS_ZONEOPT_IGNORESRVCNAME;
336 fprintf(stderr, "invalid argument to -S: %s\n",
337 isc_commandline_argument);
344 zone_options |= DNS_ZONEOPT_CHECKWILDCARD;
345 else if (ARGCMP("ignore"))
346 zone_options &= ~DNS_ZONEOPT_CHECKWILDCARD;
350 if (isc_commandline_option != '?')
351 fprintf(stderr, "%s: invalid argument -%c\n",
352 prog_name, isc_commandline_option);
357 fprintf(stderr, "%s: unhandled option -%c\n",
358 prog_name, isc_commandline_option);
363 if (workdir != NULL) {
364 result = isc_dir_chdir(workdir);
365 if (result != ISC_R_SUCCESS) {
366 fprintf(stderr, "isc_dir_chdir: %s: %s\n",
367 workdir, isc_result_totext(result));
372 if (inputformatstr != NULL) {
373 if (strcasecmp(inputformatstr, "text") == 0)
374 inputformat = dns_masterformat_text;
375 else if (strcasecmp(inputformatstr, "raw") == 0)
376 inputformat = dns_masterformat_raw;
378 fprintf(stderr, "unknown file format: %s\n",
384 if (outputformatstr != NULL) {
385 if (strcasecmp(outputformatstr, "text") == 0)
386 outputformat = dns_masterformat_text;
387 else if (strcasecmp(outputformatstr, "raw") == 0)
388 outputformat = dns_masterformat_raw;
390 fprintf(stderr, "unknown file format: %s\n",
396 if (progmode == progmode_compile) {
397 dumpzone = 1; /* always dump */
398 if (output_filename == NULL) {
400 "output file required, but not specified\n");
405 if (output_filename != NULL)
409 * If we are outputing to stdout then send the informational
413 (output_filename == NULL ||
414 strcmp(output_filename, "-") == 0 ||
415 strcmp(output_filename, "/dev/fd/1") == 0 ||
416 strcmp(output_filename, "/dev/stdout") == 0))
419 if (isc_commandline_index + 2 != argc)
422 RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
424 RUNTIME_CHECK(setup_logging(mctx, errout, &lctx)
426 RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS);
427 RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)
430 dns_result_register();
432 origin = argv[isc_commandline_index++];
433 filename = argv[isc_commandline_index++];
434 result = load_zone(mctx, origin, filename, inputformat, classname,
437 if (result == ISC_R_SUCCESS && dumpzone) {
438 if (!quiet && progmode == progmode_compile) {
439 fprintf(errout, "dump zone to %s...", output_filename);
442 result = dump_zone(origin, zone, output_filename,
443 outputformat, outputstyle);
444 if (!quiet && progmode == progmode_compile)
445 fprintf(errout, "done\n");
448 if (!quiet && result == ISC_R_SUCCESS)
449 fprintf(errout, "OK\n");
452 isc_log_destroy(&lctx);
454 isc_entropy_detach(&ectx);
455 isc_mem_destroy(&mctx);
456 return ((result == ISC_R_SUCCESS) ? 0 : 1);