1 /* $NetBSD: named-checkzone.c,v 1.7 2014/12/10 04:37:51 christos Exp $ */
4 * Copyright (C) 2004-2014 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.65.32.2 2012/02/07 02:45:21 each 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/master.h>
45 #include <dns/masterdump.h>
47 #include <dns/rdataclass.h>
48 #include <dns/rdataset.h>
49 #include <dns/result.h>
50 #include <dns/types.h>
53 #include "check-tool.h"
56 static isc_mem_t
*mctx
= NULL
;
57 static isc_entropy_t
*ectx
= NULL
;
58 dns_zone_t
*zone
= NULL
;
59 dns_zonetype_t zonetype
= dns_zone_master
;
60 static int dumpzone
= 0;
61 static const char *output_filename
;
62 static char *prog_name
= NULL
;
63 static const dns_master_style_t
*outputstyle
= NULL
;
64 static enum { progmode_check
, progmode_compile
} progmode
;
66 #define ERRRET(result, function) \
68 if (result != ISC_R_SUCCESS) { \
70 fprintf(stderr, "%s() returned %s\n", \
71 function, dns_result_totext(result)); \
74 } while (/*CONSTCOND*/0)
76 ISC_PLATFORM_NORETURN_PRE
static void
77 usage(void) ISC_PLATFORM_NORETURN_POST
;
82 "usage: %s [-djqvD] [-c class] "
83 "[-f inputformat] [-F outputformat] [-J filename] "
84 "[-t directory] [-w directory] [-k (ignore|warn|fail)] "
85 "[-n (ignore|warn|fail)] [-m (ignore|warn|fail)] "
86 "[-r (ignore|warn|fail)] "
87 "[-i (full|full-sibling|local|local-sibling|none)] "
88 "[-M (ignore|warn|fail)] [-S (ignore|warn|fail)] "
90 "%s zonename filename\n",
92 progmode
== progmode_check
? "[-o filename]" : "-o filename");
99 dns_zone_detach(&zone
);
103 /*% main processing routine */
105 main(int argc
, char **argv
) {
108 char *filename
= NULL
;
109 isc_log_t
*lctx
= NULL
;
111 char classname_in
[] = "IN";
112 char *classname
= classname_in
;
113 const char *workdir
= NULL
;
114 const char *inputformatstr
= NULL
;
115 const char *outputformatstr
= NULL
;
116 dns_masterformat_t inputformat
= dns_masterformat_text
;
117 dns_masterformat_t outputformat
= dns_masterformat_text
;
118 dns_masterrawheader_t header
;
119 isc_uint32_t rawversion
= 1, serialnum
= 0;
120 dns_ttl_t maxttl
= 0;
121 isc_boolean_t snset
= ISC_FALSE
;
122 isc_boolean_t logdump
= ISC_FALSE
;
123 FILE *errout
= stdout
;
127 * Uncomment the following line if memory debugging is needed:
128 * isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
131 outputstyle
= &dns_master_style_full
;
133 prog_name
= strrchr(argv
[0], '/');
134 if (prog_name
== NULL
)
135 prog_name
= strrchr(argv
[0], '\\');
136 if (prog_name
!= NULL
)
141 * Libtool doesn't preserve the program name prior to final
142 * installation. Remove the libtool prefix ("lt-").
144 if (strncmp(prog_name
, "lt-", 3) == 0)
148 (strcasecmp(prog_name, X) == 0 || strcasecmp(prog_name, X ".exe") == 0)
150 if (PROGCMP("named-checkzone"))
151 progmode
= progmode_check
;
152 else if (PROGCMP("named-compilezone"))
153 progmode
= progmode_compile
;
157 /* Compilation specific defaults */
158 if (progmode
== progmode_compile
) {
159 zone_options
|= (DNS_ZONEOPT_CHECKNS
|
160 DNS_ZONEOPT_FATALNS
|
161 DNS_ZONEOPT_CHECKSPF
|
162 DNS_ZONEOPT_CHECKDUPRR
|
163 DNS_ZONEOPT_CHECKNAMES
|
164 DNS_ZONEOPT_CHECKNAMESFAIL
|
165 DNS_ZONEOPT_CHECKWILDCARD
);
167 zone_options
|= (DNS_ZONEOPT_CHECKDUPRR
|
168 DNS_ZONEOPT_CHECKSPF
);
170 #define ARGCMP(X) (strcmp(isc_commandline_argument, X) == 0)
172 isc_commandline_errprint
= ISC_FALSE
;
174 while ((c
= isc_commandline_parse(argc
, argv
,
175 "c:df:hi:jJ:k:L:l:m:n:qr:s:t:o:vw:DF:M:S:T:W:"))
179 classname
= isc_commandline_argument
;
187 if (ARGCMP("full")) {
188 zone_options
|= DNS_ZONEOPT_CHECKINTEGRITY
|
189 DNS_ZONEOPT_CHECKSIBLING
;
190 docheckmx
= ISC_TRUE
;
191 docheckns
= ISC_TRUE
;
192 dochecksrv
= ISC_TRUE
;
193 } else if (ARGCMP("full-sibling")) {
194 zone_options
|= DNS_ZONEOPT_CHECKINTEGRITY
;
195 zone_options
&= ~DNS_ZONEOPT_CHECKSIBLING
;
196 docheckmx
= ISC_TRUE
;
197 docheckns
= ISC_TRUE
;
198 dochecksrv
= ISC_TRUE
;
199 } else if (ARGCMP("local")) {
200 zone_options
|= DNS_ZONEOPT_CHECKINTEGRITY
;
201 zone_options
|= DNS_ZONEOPT_CHECKSIBLING
;
202 docheckmx
= ISC_FALSE
;
203 docheckns
= ISC_FALSE
;
204 dochecksrv
= ISC_FALSE
;
205 } else if (ARGCMP("local-sibling")) {
206 zone_options
|= DNS_ZONEOPT_CHECKINTEGRITY
;
207 zone_options
&= ~DNS_ZONEOPT_CHECKSIBLING
;
208 docheckmx
= ISC_FALSE
;
209 docheckns
= ISC_FALSE
;
210 dochecksrv
= ISC_FALSE
;
211 } else if (ARGCMP("none")) {
212 zone_options
&= ~DNS_ZONEOPT_CHECKINTEGRITY
;
213 zone_options
&= ~DNS_ZONEOPT_CHECKSIBLING
;
214 docheckmx
= ISC_FALSE
;
215 docheckns
= ISC_FALSE
;
216 dochecksrv
= ISC_FALSE
;
218 fprintf(stderr
, "invalid argument to -i: %s\n",
219 isc_commandline_argument
);
225 inputformatstr
= isc_commandline_argument
;
229 outputformatstr
= isc_commandline_argument
;
237 journal
= isc_commandline_argument
;
242 if (ARGCMP("warn")) {
243 zone_options
|= DNS_ZONEOPT_CHECKNAMES
;
244 zone_options
&= ~DNS_ZONEOPT_CHECKNAMESFAIL
;
245 } else if (ARGCMP("fail")) {
246 zone_options
|= DNS_ZONEOPT_CHECKNAMES
|
247 DNS_ZONEOPT_CHECKNAMESFAIL
;
248 } else if (ARGCMP("ignore")) {
249 zone_options
&= ~(DNS_ZONEOPT_CHECKNAMES
|
250 DNS_ZONEOPT_CHECKNAMESFAIL
);
252 fprintf(stderr
, "invalid argument to -k: %s\n",
253 isc_commandline_argument
);
261 serialnum
= strtol(isc_commandline_argument
, &endp
, 0);
263 fprintf(stderr
, "source serial number "
270 zone_options2
|= DNS_ZONEOPT2_CHECKTTL
;
272 maxttl
= strtol(isc_commandline_argument
, &endp
, 0);
274 fprintf(stderr
, "maximum TTL "
282 if (ARGCMP("ignore")) {
283 zone_options
&= ~(DNS_ZONEOPT_CHECKNS
|
284 DNS_ZONEOPT_FATALNS
);
285 } else if (ARGCMP("warn")) {
286 zone_options
|= DNS_ZONEOPT_CHECKNS
;
287 zone_options
&= ~DNS_ZONEOPT_FATALNS
;
288 } else if (ARGCMP("fail")) {
289 zone_options
|= DNS_ZONEOPT_CHECKNS
|
292 fprintf(stderr
, "invalid argument to -n: %s\n",
293 isc_commandline_argument
);
299 if (ARGCMP("warn")) {
300 zone_options
|= DNS_ZONEOPT_CHECKMX
;
301 zone_options
&= ~DNS_ZONEOPT_CHECKMXFAIL
;
302 } else if (ARGCMP("fail")) {
303 zone_options
|= DNS_ZONEOPT_CHECKMX
|
304 DNS_ZONEOPT_CHECKMXFAIL
;
305 } else if (ARGCMP("ignore")) {
306 zone_options
&= ~(DNS_ZONEOPT_CHECKMX
|
307 DNS_ZONEOPT_CHECKMXFAIL
);
309 fprintf(stderr
, "invalid argument to -m: %s\n",
310 isc_commandline_argument
);
316 output_filename
= isc_commandline_argument
;
324 if (ARGCMP("warn")) {
325 zone_options
|= DNS_ZONEOPT_CHECKDUPRR
;
326 zone_options
&= ~DNS_ZONEOPT_CHECKDUPRRFAIL
;
327 } else if (ARGCMP("fail")) {
328 zone_options
|= DNS_ZONEOPT_CHECKDUPRR
|
329 DNS_ZONEOPT_CHECKDUPRRFAIL
;
330 } else if (ARGCMP("ignore")) {
331 zone_options
&= ~(DNS_ZONEOPT_CHECKDUPRR
|
332 DNS_ZONEOPT_CHECKDUPRRFAIL
);
334 fprintf(stderr
, "invalid argument to -r: %s\n",
335 isc_commandline_argument
);
342 outputstyle
= &dns_master_style_full
;
343 else if (ARGCMP("relative")) {
344 outputstyle
= &dns_master_style_default
;
347 "unknown or unsupported style: %s\n",
348 isc_commandline_argument
);
354 result
= isc_dir_chroot(isc_commandline_argument
);
355 if (result
!= ISC_R_SUCCESS
) {
356 fprintf(stderr
, "isc_dir_chroot: %s: %s\n",
357 isc_commandline_argument
,
358 isc_result_totext(result
));
364 printf(VERSION
"\n");
368 workdir
= isc_commandline_argument
;
376 if (ARGCMP("fail")) {
377 zone_options
&= ~DNS_ZONEOPT_WARNMXCNAME
;
378 zone_options
&= ~DNS_ZONEOPT_IGNOREMXCNAME
;
379 } else if (ARGCMP("warn")) {
380 zone_options
|= DNS_ZONEOPT_WARNMXCNAME
;
381 zone_options
&= ~DNS_ZONEOPT_IGNOREMXCNAME
;
382 } else if (ARGCMP("ignore")) {
383 zone_options
|= DNS_ZONEOPT_WARNMXCNAME
;
384 zone_options
|= DNS_ZONEOPT_IGNOREMXCNAME
;
386 fprintf(stderr
, "invalid argument to -M: %s\n",
387 isc_commandline_argument
);
393 if (ARGCMP("fail")) {
394 zone_options
&= ~DNS_ZONEOPT_WARNSRVCNAME
;
395 zone_options
&= ~DNS_ZONEOPT_IGNORESRVCNAME
;
396 } else if (ARGCMP("warn")) {
397 zone_options
|= DNS_ZONEOPT_WARNSRVCNAME
;
398 zone_options
&= ~DNS_ZONEOPT_IGNORESRVCNAME
;
399 } else if (ARGCMP("ignore")) {
400 zone_options
|= DNS_ZONEOPT_WARNSRVCNAME
;
401 zone_options
|= DNS_ZONEOPT_IGNORESRVCNAME
;
403 fprintf(stderr
, "invalid argument to -S: %s\n",
404 isc_commandline_argument
);
410 if (ARGCMP("warn")) {
411 zone_options
|= DNS_ZONEOPT_CHECKSPF
;
412 } else if (ARGCMP("ignore")) {
413 zone_options
&= ~DNS_ZONEOPT_CHECKSPF
;
415 fprintf(stderr
, "invalid argument to -T: %s\n",
416 isc_commandline_argument
);
423 zone_options
|= DNS_ZONEOPT_CHECKWILDCARD
;
424 else if (ARGCMP("ignore"))
425 zone_options
&= ~DNS_ZONEOPT_CHECKWILDCARD
;
429 if (isc_commandline_option
!= '?')
430 fprintf(stderr
, "%s: invalid argument -%c\n",
431 prog_name
, isc_commandline_option
);
437 fprintf(stderr
, "%s: unhandled option -%c\n",
438 prog_name
, isc_commandline_option
);
443 if (workdir
!= NULL
) {
444 result
= isc_dir_chdir(workdir
);
445 if (result
!= ISC_R_SUCCESS
) {
446 fprintf(stderr
, "isc_dir_chdir: %s: %s\n",
447 workdir
, isc_result_totext(result
));
452 if (inputformatstr
!= NULL
) {
453 if (strcasecmp(inputformatstr
, "text") == 0)
454 inputformat
= dns_masterformat_text
;
455 else if (strcasecmp(inputformatstr
, "raw") == 0)
456 inputformat
= dns_masterformat_raw
;
457 else if (strncasecmp(inputformatstr
, "raw=", 4) == 0) {
458 inputformat
= dns_masterformat_raw
;
460 "WARNING: input format raw, version ignored\n");
461 } else if (strcasecmp(inputformatstr
, "map") == 0) {
462 inputformat
= dns_masterformat_map
;
464 fprintf(stderr
, "unknown file format: %s\n",
470 if (outputformatstr
!= NULL
) {
471 if (strcasecmp(outputformatstr
, "text") == 0) {
472 outputformat
= dns_masterformat_text
;
473 } else if (strcasecmp(outputformatstr
, "raw") == 0) {
474 outputformat
= dns_masterformat_raw
;
475 } else if (strncasecmp(outputformatstr
, "raw=", 4) == 0) {
478 outputformat
= dns_masterformat_raw
;
479 rawversion
= strtol(outputformatstr
+ 4, &end
, 10);
480 if (end
== outputformatstr
+ 4 || *end
!= '\0' ||
483 "unknown raw format version\n");
486 } else if (strcasecmp(outputformatstr
, "map") == 0) {
487 outputformat
= dns_masterformat_map
;
489 fprintf(stderr
, "unknown file format: %s\n",
495 if (progmode
== progmode_compile
) {
496 dumpzone
= 1; /* always dump */
498 if (output_filename
== NULL
) {
500 "output file required, but not specified\n");
505 if (output_filename
!= NULL
)
509 * If we are outputing to stdout then send the informational
513 (output_filename
== NULL
||
514 strcmp(output_filename
, "-") == 0 ||
515 strcmp(output_filename
, "/dev/fd/1") == 0 ||
516 strcmp(output_filename
, "/dev/stdout") == 0)) {
521 if (isc_commandline_index
+ 2 != argc
)
528 RUNTIME_CHECK(isc_mem_create(0, 0, &mctx
) == ISC_R_SUCCESS
);
530 RUNTIME_CHECK(setup_logging(mctx
, errout
, &lctx
)
532 RUNTIME_CHECK(isc_entropy_create(mctx
, &ectx
) == ISC_R_SUCCESS
);
533 RUNTIME_CHECK(isc_hash_create(mctx
, ectx
, DNS_NAME_MAXWIRE
)
536 dns_result_register();
538 origin
= argv
[isc_commandline_index
++];
539 filename
= argv
[isc_commandline_index
++];
540 result
= load_zone(mctx
, origin
, filename
, inputformat
, classname
,
544 dns_master_initrawheader(&header
);
545 header
.flags
= DNS_MASTERRAW_SOURCESERIALSET
;
546 header
.sourceserial
= serialnum
;
547 dns_zone_setrawdata(zone
, &header
);
550 if (result
== ISC_R_SUCCESS
&& dumpzone
) {
552 fprintf(errout
, "dump zone to %s...", output_filename
);
555 result
= dump_zone(origin
, zone
, output_filename
,
556 outputformat
, outputstyle
, rawversion
);
558 fprintf(errout
, "done\n");
561 if (!quiet
&& result
== ISC_R_SUCCESS
)
562 fprintf(errout
, "OK\n");
565 isc_log_destroy(&lctx
);
567 isc_entropy_detach(&ectx
);
568 isc_mem_destroy(&mctx
);
572 return ((result
== ISC_R_SUCCESS
) ? 0 : 1);