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.49.130.5 2009/05/29 02:18:32 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|full-sibling|local|local-sibling|none)] "
81 "[-M (ignore|warn|fail)] [-S (ignore|warn|fail)] "
83 "zonename filename\n", prog_name
);
90 dns_zone_detach(&zone
);
94 /*% main processing routine */
96 main(int argc
, char **argv
) {
99 char *filename
= NULL
;
100 isc_log_t
*lctx
= NULL
;
102 char classname_in
[] = "IN";
103 char *classname
= classname_in
;
104 const char *workdir
= NULL
;
105 const char *inputformatstr
= NULL
;
106 const char *outputformatstr
= NULL
;
107 dns_masterformat_t inputformat
= dns_masterformat_text
;
108 dns_masterformat_t outputformat
= dns_masterformat_text
;
109 FILE *errout
= stdout
;
111 outputstyle
= &dns_master_style_full
;
113 prog_name
= strrchr(argv
[0], '/');
114 if (prog_name
== NULL
)
115 prog_name
= strrchr(argv
[0], '\\');
116 if (prog_name
!= NULL
)
121 * Libtool doesn't preserve the program name prior to final
122 * installation. Remove the libtool prefix ("lt-").
124 if (strncmp(prog_name
, "lt-", 3) == 0)
128 (strcasecmp(prog_name, X) == 0 || strcasecmp(prog_name, X ".exe") == 0)
130 if (PROGCMP("named-checkzone"))
131 progmode
= progmode_check
;
132 else if (PROGCMP("named-compilezone"))
133 progmode
= progmode_compile
;
137 /* Compilation specific defaults */
138 if (progmode
== progmode_compile
) {
139 zone_options
|= (DNS_ZONEOPT_CHECKNS
|
140 DNS_ZONEOPT_FATALNS
|
141 DNS_ZONEOPT_CHECKNAMES
|
142 DNS_ZONEOPT_CHECKNAMESFAIL
|
143 DNS_ZONEOPT_CHECKWILDCARD
);
146 #define ARGCMP(X) (strcmp(isc_commandline_argument, X) == 0)
148 isc_commandline_errprint
= ISC_FALSE
;
150 while ((c
= isc_commandline_parse(argc
, argv
,
151 "c:df:hi:jk:m:n:qs:t:o:vw:DF:M:S:W:"))
155 classname
= isc_commandline_argument
;
163 if (ARGCMP("full")) {
164 zone_options
|= DNS_ZONEOPT_CHECKINTEGRITY
|
165 DNS_ZONEOPT_CHECKSIBLING
;
166 docheckmx
= ISC_TRUE
;
167 docheckns
= ISC_TRUE
;
168 dochecksrv
= ISC_TRUE
;
169 } else if (ARGCMP("full-sibling")) {
170 zone_options
|= DNS_ZONEOPT_CHECKINTEGRITY
;
171 zone_options
&= ~DNS_ZONEOPT_CHECKSIBLING
;
172 docheckmx
= ISC_TRUE
;
173 docheckns
= ISC_TRUE
;
174 dochecksrv
= ISC_TRUE
;
175 } else if (ARGCMP("local")) {
176 zone_options
|= DNS_ZONEOPT_CHECKINTEGRITY
;
177 zone_options
|= DNS_ZONEOPT_CHECKSIBLING
;
178 docheckmx
= ISC_FALSE
;
179 docheckns
= ISC_FALSE
;
180 dochecksrv
= ISC_FALSE
;
181 } else if (ARGCMP("local-sibling")) {
182 zone_options
|= DNS_ZONEOPT_CHECKINTEGRITY
;
183 zone_options
&= ~DNS_ZONEOPT_CHECKSIBLING
;
184 docheckmx
= ISC_FALSE
;
185 docheckns
= ISC_FALSE
;
186 dochecksrv
= ISC_FALSE
;
187 } else if (ARGCMP("none")) {
188 zone_options
&= ~DNS_ZONEOPT_CHECKINTEGRITY
;
189 zone_options
&= ~DNS_ZONEOPT_CHECKSIBLING
;
190 docheckmx
= ISC_FALSE
;
191 docheckns
= ISC_FALSE
;
192 dochecksrv
= ISC_FALSE
;
194 fprintf(stderr
, "invalid argument to -i: %s\n",
195 isc_commandline_argument
);
201 inputformatstr
= isc_commandline_argument
;
205 outputformatstr
= isc_commandline_argument
;
213 if (ARGCMP("warn")) {
214 zone_options
|= DNS_ZONEOPT_CHECKNAMES
;
215 zone_options
&= ~DNS_ZONEOPT_CHECKNAMESFAIL
;
216 } else if (ARGCMP("fail")) {
217 zone_options
|= DNS_ZONEOPT_CHECKNAMES
|
218 DNS_ZONEOPT_CHECKNAMESFAIL
;
219 } else if (ARGCMP("ignore")) {
220 zone_options
&= ~(DNS_ZONEOPT_CHECKNAMES
|
221 DNS_ZONEOPT_CHECKNAMESFAIL
);
223 fprintf(stderr
, "invalid argument to -k: %s\n",
224 isc_commandline_argument
);
230 if (ARGCMP("ignore")) {
231 zone_options
&= ~(DNS_ZONEOPT_CHECKNS
|
232 DNS_ZONEOPT_FATALNS
);
233 } else if (ARGCMP("warn")) {
234 zone_options
|= DNS_ZONEOPT_CHECKNS
;
235 zone_options
&= ~DNS_ZONEOPT_FATALNS
;
236 } else if (ARGCMP("fail")) {
237 zone_options
|= DNS_ZONEOPT_CHECKNS
|
240 fprintf(stderr
, "invalid argument to -n: %s\n",
241 isc_commandline_argument
);
247 if (ARGCMP("warn")) {
248 zone_options
|= DNS_ZONEOPT_CHECKMX
;
249 zone_options
&= ~DNS_ZONEOPT_CHECKMXFAIL
;
250 } else if (ARGCMP("fail")) {
251 zone_options
|= DNS_ZONEOPT_CHECKMX
|
252 DNS_ZONEOPT_CHECKMXFAIL
;
253 } else if (ARGCMP("ignore")) {
254 zone_options
&= ~(DNS_ZONEOPT_CHECKMX
|
255 DNS_ZONEOPT_CHECKMXFAIL
);
257 fprintf(stderr
, "invalid argument to -m: %s\n",
258 isc_commandline_argument
);
268 result
= isc_dir_chroot(isc_commandline_argument
);
269 if (result
!= ISC_R_SUCCESS
) {
270 fprintf(stderr
, "isc_dir_chroot: %s: %s\n",
271 isc_commandline_argument
,
272 isc_result_totext(result
));
279 outputstyle
= &dns_master_style_full
;
280 else if (ARGCMP("relative")) {
281 outputstyle
= &dns_master_style_default
;
284 "unknown or unsupported style: %s\n",
285 isc_commandline_argument
);
291 output_filename
= isc_commandline_argument
;
295 printf(VERSION
"\n");
299 workdir
= isc_commandline_argument
;
307 if (ARGCMP("fail")) {
308 zone_options
&= ~DNS_ZONEOPT_WARNMXCNAME
;
309 zone_options
&= ~DNS_ZONEOPT_IGNOREMXCNAME
;
310 } else if (ARGCMP("warn")) {
311 zone_options
|= DNS_ZONEOPT_WARNMXCNAME
;
312 zone_options
&= ~DNS_ZONEOPT_IGNOREMXCNAME
;
313 } else if (ARGCMP("ignore")) {
314 zone_options
|= DNS_ZONEOPT_WARNMXCNAME
;
315 zone_options
|= DNS_ZONEOPT_IGNOREMXCNAME
;
317 fprintf(stderr
, "invalid argument to -M: %s\n",
318 isc_commandline_argument
);
324 if (ARGCMP("fail")) {
325 zone_options
&= ~DNS_ZONEOPT_WARNSRVCNAME
;
326 zone_options
&= ~DNS_ZONEOPT_IGNORESRVCNAME
;
327 } else if (ARGCMP("warn")) {
328 zone_options
|= DNS_ZONEOPT_WARNSRVCNAME
;
329 zone_options
&= ~DNS_ZONEOPT_IGNORESRVCNAME
;
330 } else if (ARGCMP("ignore")) {
331 zone_options
|= DNS_ZONEOPT_WARNSRVCNAME
;
332 zone_options
|= DNS_ZONEOPT_IGNORESRVCNAME
;
334 fprintf(stderr
, "invalid argument to -S: %s\n",
335 isc_commandline_argument
);
342 zone_options
|= DNS_ZONEOPT_CHECKWILDCARD
;
343 else if (ARGCMP("ignore"))
344 zone_options
&= ~DNS_ZONEOPT_CHECKWILDCARD
;
348 if (isc_commandline_option
!= '?')
349 fprintf(stderr
, "%s: invalid argument -%c\n",
350 prog_name
, isc_commandline_option
);
355 fprintf(stderr
, "%s: unhandled option -%c\n",
356 prog_name
, isc_commandline_option
);
361 if (workdir
!= NULL
) {
362 result
= isc_dir_chdir(workdir
);
363 if (result
!= ISC_R_SUCCESS
) {
364 fprintf(stderr
, "isc_dir_chdir: %s: %s\n",
365 workdir
, isc_result_totext(result
));
370 if (inputformatstr
!= NULL
) {
371 if (strcasecmp(inputformatstr
, "text") == 0)
372 inputformat
= dns_masterformat_text
;
373 else if (strcasecmp(inputformatstr
, "raw") == 0)
374 inputformat
= dns_masterformat_raw
;
376 fprintf(stderr
, "unknown file format: %s\n",
382 if (outputformatstr
!= NULL
) {
383 if (strcasecmp(outputformatstr
, "text") == 0)
384 outputformat
= dns_masterformat_text
;
385 else if (strcasecmp(outputformatstr
, "raw") == 0)
386 outputformat
= dns_masterformat_raw
;
388 fprintf(stderr
, "unknown file format: %s\n",
394 if (progmode
== progmode_compile
) {
395 dumpzone
= 1; /* always dump */
396 if (output_filename
== NULL
) {
398 "output file required, but not specified\n");
403 if (output_filename
!= NULL
)
407 * If we are outputing to stdout then send the informational
411 (output_filename
== NULL
||
412 strcmp(output_filename
, "-") == 0 ||
413 strcmp(output_filename
, "/dev/fd/1") == 0 ||
414 strcmp(output_filename
, "/dev/stdout") == 0))
417 if (isc_commandline_index
+ 2 != argc
)
420 RUNTIME_CHECK(isc_mem_create(0, 0, &mctx
) == ISC_R_SUCCESS
);
422 RUNTIME_CHECK(setup_logging(mctx
, errout
, &lctx
)
424 RUNTIME_CHECK(isc_entropy_create(mctx
, &ectx
) == ISC_R_SUCCESS
);
425 RUNTIME_CHECK(isc_hash_create(mctx
, ectx
, DNS_NAME_MAXWIRE
)
428 dns_result_register();
430 origin
= argv
[isc_commandline_index
++];
431 filename
= argv
[isc_commandline_index
++];
432 result
= load_zone(mctx
, origin
, filename
, inputformat
, classname
,
435 if (result
== ISC_R_SUCCESS
&& dumpzone
) {
436 if (!quiet
&& progmode
== progmode_compile
) {
437 fprintf(errout
, "dump zone to %s...", output_filename
);
440 result
= dump_zone(origin
, zone
, output_filename
,
441 outputformat
, outputstyle
);
442 if (!quiet
&& progmode
== progmode_compile
)
443 fprintf(errout
, "done\n");
446 if (!quiet
&& result
== ISC_R_SUCCESS
)
447 fprintf(errout
, "OK\n");
450 isc_log_destroy(&lctx
);
452 isc_entropy_detach(&ectx
);
453 isc_mem_destroy(&mctx
);
454 return ((result
== ISC_R_SUCCESS
) ? 0 : 1);