4 * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2003 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: named-checkzone.c,v 1.59 2009/12/04 22:06:37 tbox Exp */
29 #include <isc/commandline.h>
31 #include <isc/entropy.h>
35 #include <isc/socket.h>
36 #include <isc/string.h>
38 #include <isc/timer.h>
42 #include <dns/fixedname.h>
44 #include <dns/masterdump.h>
46 #include <dns/rdataclass.h>
47 #include <dns/rdataset.h>
48 #include <dns/result.h>
49 #include <dns/types.h>
52 #include "check-tool.h"
55 static isc_mem_t
*mctx
= NULL
;
56 static isc_entropy_t
*ectx
= NULL
;
57 dns_zone_t
*zone
= NULL
;
58 dns_zonetype_t zonetype
= dns_zone_master
;
59 static int dumpzone
= 0;
60 static const char *output_filename
;
61 static char *prog_name
= NULL
;
62 static const dns_master_style_t
*outputstyle
= NULL
;
63 static enum { progmode_check
, progmode_compile
} progmode
;
65 #define ERRRET(result, function) \
67 if (result != ISC_R_SUCCESS) { \
69 fprintf(stderr, "%s() returned %s\n", \
70 function, dns_result_totext(result)); \
75 ISC_PLATFORM_NORETURN_PRE
static void
76 usage(void) ISC_PLATFORM_NORETURN_POST
;
81 "usage: %s [-djqvD] [-c class] "
82 "[-f inputformat] [-F outputformat] "
83 "[-t directory] [-w directory] [-k (ignore|warn|fail)] "
84 "[-n (ignore|warn|fail)] [-m (ignore|warn|fail)] "
85 "[-r (ignore|warn|fail)] "
86 "[-i (full|full-sibling|local|local-sibling|none)] "
87 "[-M (ignore|warn|fail)] [-S (ignore|warn|fail)] "
89 "%s zonename filename\n",
91 progmode
== progmode_check
? "[-o filename]" : "-o filename");
98 dns_zone_detach(&zone
);
102 /*% main processing routine */
104 main(int argc
, char **argv
) {
107 char *filename
= NULL
;
108 isc_log_t
*lctx
= NULL
;
110 char classname_in
[] = "IN";
111 char *classname
= classname_in
;
112 const char *workdir
= NULL
;
113 const char *inputformatstr
= NULL
;
114 const char *outputformatstr
= NULL
;
115 dns_masterformat_t inputformat
= dns_masterformat_text
;
116 dns_masterformat_t outputformat
= dns_masterformat_text
;
117 FILE *errout
= stdout
;
119 outputstyle
= &dns_master_style_full
;
121 prog_name
= strrchr(argv
[0], '/');
122 if (prog_name
== NULL
)
123 prog_name
= strrchr(argv
[0], '\\');
124 if (prog_name
!= NULL
)
129 * Libtool doesn't preserve the program name prior to final
130 * installation. Remove the libtool prefix ("lt-").
132 if (strncmp(prog_name
, "lt-", 3) == 0)
136 (strcasecmp(prog_name, X) == 0 || strcasecmp(prog_name, X ".exe") == 0)
138 if (PROGCMP("named-checkzone"))
139 progmode
= progmode_check
;
140 else if (PROGCMP("named-compilezone"))
141 progmode
= progmode_compile
;
145 /* Compilation specific defaults */
146 if (progmode
== progmode_compile
) {
147 zone_options
|= (DNS_ZONEOPT_CHECKNS
|
148 DNS_ZONEOPT_FATALNS
|
149 DNS_ZONEOPT_CHECKDUPRR
|
150 DNS_ZONEOPT_CHECKNAMES
|
151 DNS_ZONEOPT_CHECKNAMESFAIL
|
152 DNS_ZONEOPT_CHECKWILDCARD
);
154 zone_options
|= DNS_ZONEOPT_CHECKDUPRR
;
156 #define ARGCMP(X) (strcmp(isc_commandline_argument, X) == 0)
158 isc_commandline_errprint
= ISC_FALSE
;
160 while ((c
= isc_commandline_parse(argc
, argv
,
161 "c:df:hi:jk:m:n:qr:s:t:o:vw:DF:M:S:W:"))
165 classname
= isc_commandline_argument
;
173 if (ARGCMP("full")) {
174 zone_options
|= DNS_ZONEOPT_CHECKINTEGRITY
|
175 DNS_ZONEOPT_CHECKSIBLING
;
176 docheckmx
= ISC_TRUE
;
177 docheckns
= ISC_TRUE
;
178 dochecksrv
= ISC_TRUE
;
179 } else if (ARGCMP("full-sibling")) {
180 zone_options
|= DNS_ZONEOPT_CHECKINTEGRITY
;
181 zone_options
&= ~DNS_ZONEOPT_CHECKSIBLING
;
182 docheckmx
= ISC_TRUE
;
183 docheckns
= ISC_TRUE
;
184 dochecksrv
= ISC_TRUE
;
185 } else if (ARGCMP("local")) {
186 zone_options
|= DNS_ZONEOPT_CHECKINTEGRITY
;
187 zone_options
|= DNS_ZONEOPT_CHECKSIBLING
;
188 docheckmx
= ISC_FALSE
;
189 docheckns
= ISC_FALSE
;
190 dochecksrv
= ISC_FALSE
;
191 } else if (ARGCMP("local-sibling")) {
192 zone_options
|= DNS_ZONEOPT_CHECKINTEGRITY
;
193 zone_options
&= ~DNS_ZONEOPT_CHECKSIBLING
;
194 docheckmx
= ISC_FALSE
;
195 docheckns
= ISC_FALSE
;
196 dochecksrv
= ISC_FALSE
;
197 } else if (ARGCMP("none")) {
198 zone_options
&= ~DNS_ZONEOPT_CHECKINTEGRITY
;
199 zone_options
&= ~DNS_ZONEOPT_CHECKSIBLING
;
200 docheckmx
= ISC_FALSE
;
201 docheckns
= ISC_FALSE
;
202 dochecksrv
= ISC_FALSE
;
204 fprintf(stderr
, "invalid argument to -i: %s\n",
205 isc_commandline_argument
);
211 inputformatstr
= isc_commandline_argument
;
215 outputformatstr
= isc_commandline_argument
;
223 if (ARGCMP("warn")) {
224 zone_options
|= DNS_ZONEOPT_CHECKNAMES
;
225 zone_options
&= ~DNS_ZONEOPT_CHECKNAMESFAIL
;
226 } else if (ARGCMP("fail")) {
227 zone_options
|= DNS_ZONEOPT_CHECKNAMES
|
228 DNS_ZONEOPT_CHECKNAMESFAIL
;
229 } else if (ARGCMP("ignore")) {
230 zone_options
&= ~(DNS_ZONEOPT_CHECKNAMES
|
231 DNS_ZONEOPT_CHECKNAMESFAIL
);
233 fprintf(stderr
, "invalid argument to -k: %s\n",
234 isc_commandline_argument
);
240 if (ARGCMP("ignore")) {
241 zone_options
&= ~(DNS_ZONEOPT_CHECKNS
|
242 DNS_ZONEOPT_FATALNS
);
243 } else if (ARGCMP("warn")) {
244 zone_options
|= DNS_ZONEOPT_CHECKNS
;
245 zone_options
&= ~DNS_ZONEOPT_FATALNS
;
246 } else if (ARGCMP("fail")) {
247 zone_options
|= DNS_ZONEOPT_CHECKNS
|
250 fprintf(stderr
, "invalid argument to -n: %s\n",
251 isc_commandline_argument
);
257 if (ARGCMP("warn")) {
258 zone_options
|= DNS_ZONEOPT_CHECKMX
;
259 zone_options
&= ~DNS_ZONEOPT_CHECKMXFAIL
;
260 } else if (ARGCMP("fail")) {
261 zone_options
|= DNS_ZONEOPT_CHECKMX
|
262 DNS_ZONEOPT_CHECKMXFAIL
;
263 } else if (ARGCMP("ignore")) {
264 zone_options
&= ~(DNS_ZONEOPT_CHECKMX
|
265 DNS_ZONEOPT_CHECKMXFAIL
);
267 fprintf(stderr
, "invalid argument to -m: %s\n",
268 isc_commandline_argument
);
274 output_filename
= isc_commandline_argument
;
282 if (ARGCMP("warn")) {
283 zone_options
|= DNS_ZONEOPT_CHECKDUPRR
;
284 zone_options
&= ~DNS_ZONEOPT_CHECKDUPRRFAIL
;
285 } else if (ARGCMP("fail")) {
286 zone_options
|= DNS_ZONEOPT_CHECKDUPRR
|
287 DNS_ZONEOPT_CHECKDUPRRFAIL
;
288 } else if (ARGCMP("ignore")) {
289 zone_options
&= ~(DNS_ZONEOPT_CHECKDUPRR
|
290 DNS_ZONEOPT_CHECKDUPRRFAIL
);
292 fprintf(stderr
, "invalid argument to -r: %s\n",
293 isc_commandline_argument
);
300 outputstyle
= &dns_master_style_full
;
301 else if (ARGCMP("relative")) {
302 outputstyle
= &dns_master_style_default
;
305 "unknown or unsupported style: %s\n",
306 isc_commandline_argument
);
312 result
= isc_dir_chroot(isc_commandline_argument
);
313 if (result
!= ISC_R_SUCCESS
) {
314 fprintf(stderr
, "isc_dir_chroot: %s: %s\n",
315 isc_commandline_argument
,
316 isc_result_totext(result
));
322 printf(VERSION
"\n");
326 workdir
= isc_commandline_argument
;
334 if (ARGCMP("fail")) {
335 zone_options
&= ~DNS_ZONEOPT_WARNMXCNAME
;
336 zone_options
&= ~DNS_ZONEOPT_IGNOREMXCNAME
;
337 } else if (ARGCMP("warn")) {
338 zone_options
|= DNS_ZONEOPT_WARNMXCNAME
;
339 zone_options
&= ~DNS_ZONEOPT_IGNOREMXCNAME
;
340 } else if (ARGCMP("ignore")) {
341 zone_options
|= DNS_ZONEOPT_WARNMXCNAME
;
342 zone_options
|= DNS_ZONEOPT_IGNOREMXCNAME
;
344 fprintf(stderr
, "invalid argument to -M: %s\n",
345 isc_commandline_argument
);
351 if (ARGCMP("fail")) {
352 zone_options
&= ~DNS_ZONEOPT_WARNSRVCNAME
;
353 zone_options
&= ~DNS_ZONEOPT_IGNORESRVCNAME
;
354 } else if (ARGCMP("warn")) {
355 zone_options
|= DNS_ZONEOPT_WARNSRVCNAME
;
356 zone_options
&= ~DNS_ZONEOPT_IGNORESRVCNAME
;
357 } else if (ARGCMP("ignore")) {
358 zone_options
|= DNS_ZONEOPT_WARNSRVCNAME
;
359 zone_options
|= DNS_ZONEOPT_IGNORESRVCNAME
;
361 fprintf(stderr
, "invalid argument to -S: %s\n",
362 isc_commandline_argument
);
369 zone_options
|= DNS_ZONEOPT_CHECKWILDCARD
;
370 else if (ARGCMP("ignore"))
371 zone_options
&= ~DNS_ZONEOPT_CHECKWILDCARD
;
375 if (isc_commandline_option
!= '?')
376 fprintf(stderr
, "%s: invalid argument -%c\n",
377 prog_name
, isc_commandline_option
);
382 fprintf(stderr
, "%s: unhandled option -%c\n",
383 prog_name
, isc_commandline_option
);
388 if (workdir
!= NULL
) {
389 result
= isc_dir_chdir(workdir
);
390 if (result
!= ISC_R_SUCCESS
) {
391 fprintf(stderr
, "isc_dir_chdir: %s: %s\n",
392 workdir
, isc_result_totext(result
));
397 if (inputformatstr
!= NULL
) {
398 if (strcasecmp(inputformatstr
, "text") == 0)
399 inputformat
= dns_masterformat_text
;
400 else if (strcasecmp(inputformatstr
, "raw") == 0)
401 inputformat
= dns_masterformat_raw
;
403 fprintf(stderr
, "unknown file format: %s\n",
409 if (outputformatstr
!= NULL
) {
410 if (strcasecmp(outputformatstr
, "text") == 0)
411 outputformat
= dns_masterformat_text
;
412 else if (strcasecmp(outputformatstr
, "raw") == 0)
413 outputformat
= dns_masterformat_raw
;
415 fprintf(stderr
, "unknown file format: %s\n",
421 if (progmode
== progmode_compile
) {
422 dumpzone
= 1; /* always dump */
423 if (output_filename
== NULL
) {
425 "output file required, but not specified\n");
430 if (output_filename
!= NULL
)
434 * If we are outputing to stdout then send the informational
438 (output_filename
== NULL
||
439 strcmp(output_filename
, "-") == 0 ||
440 strcmp(output_filename
, "/dev/fd/1") == 0 ||
441 strcmp(output_filename
, "/dev/stdout") == 0))
444 if (isc_commandline_index
+ 2 != argc
)
447 RUNTIME_CHECK(isc_mem_create(0, 0, &mctx
) == ISC_R_SUCCESS
);
449 RUNTIME_CHECK(setup_logging(mctx
, errout
, &lctx
)
451 RUNTIME_CHECK(isc_entropy_create(mctx
, &ectx
) == ISC_R_SUCCESS
);
452 RUNTIME_CHECK(isc_hash_create(mctx
, ectx
, DNS_NAME_MAXWIRE
)
455 dns_result_register();
457 origin
= argv
[isc_commandline_index
++];
458 filename
= argv
[isc_commandline_index
++];
459 result
= load_zone(mctx
, origin
, filename
, inputformat
, classname
,
462 if (result
== ISC_R_SUCCESS
&& dumpzone
) {
463 if (!quiet
&& progmode
== progmode_compile
) {
464 fprintf(errout
, "dump zone to %s...", output_filename
);
467 result
= dump_zone(origin
, zone
, output_filename
,
468 outputformat
, outputstyle
);
469 if (!quiet
&& progmode
== progmode_compile
)
470 fprintf(errout
, "done\n");
473 if (!quiet
&& result
== ISC_R_SUCCESS
)
474 fprintf(errout
, "OK\n");
477 isc_log_destroy(&lctx
);
479 isc_entropy_detach(&ectx
);
480 isc_mem_destroy(&mctx
);
481 return ((result
== ISC_R_SUCCESS
) ? 0 : 1);