2 * Copyright (C) 2004-2007 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.29.18.19 2007/08/28 07:19:55 tbox 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
)
113 prog_name
= strrchr(argv
[0], '\\');
114 if (prog_name
!= NULL
)
119 * Libtool doesn't preserve the program name prior to final
120 * installation. Remove the libtool prefix ("lt-").
122 if (strncmp(prog_name
, "lt-", 3) == 0)
124 if (strcmp(prog_name
, "named-checkzone") == 0)
125 progmode
= progmode_check
;
126 else if (strcmp(prog_name
, "named-compilezone") == 0)
127 progmode
= progmode_compile
;
131 /* Compilation specific defaults */
132 if (progmode
== progmode_compile
) {
133 zone_options
|= (DNS_ZONEOPT_CHECKNS
|
134 DNS_ZONEOPT_FATALNS
|
135 DNS_ZONEOPT_CHECKNAMES
|
136 DNS_ZONEOPT_CHECKNAMESFAIL
|
137 DNS_ZONEOPT_CHECKWILDCARD
);
140 #define ARGCMP(X) (strcmp(isc_commandline_argument, X) == 0)
142 while ((c
= isc_commandline_parse(argc
, argv
,
143 "c:df:i:jk:m:n:qs:t:o:vw:DF:M:S:W:"))
147 classname
= isc_commandline_argument
;
155 if (ARGCMP("full")) {
156 zone_options
|= DNS_ZONEOPT_CHECKINTEGRITY
|
157 DNS_ZONEOPT_CHECKSIBLING
;
158 docheckmx
= ISC_TRUE
;
159 docheckns
= ISC_TRUE
;
160 dochecksrv
= ISC_TRUE
;
161 } else if (ARGCMP("full-sibling")) {
162 zone_options
|= DNS_ZONEOPT_CHECKINTEGRITY
;
163 zone_options
&= ~DNS_ZONEOPT_CHECKSIBLING
;
164 docheckmx
= ISC_TRUE
;
165 docheckns
= ISC_TRUE
;
166 dochecksrv
= ISC_TRUE
;
167 } else if (ARGCMP("local")) {
168 zone_options
|= DNS_ZONEOPT_CHECKINTEGRITY
;
169 zone_options
|= DNS_ZONEOPT_CHECKSIBLING
;
170 docheckmx
= ISC_FALSE
;
171 docheckns
= ISC_FALSE
;
172 dochecksrv
= ISC_FALSE
;
173 } else if (ARGCMP("local-sibling")) {
174 zone_options
|= DNS_ZONEOPT_CHECKINTEGRITY
;
175 zone_options
&= ~DNS_ZONEOPT_CHECKSIBLING
;
176 docheckmx
= ISC_FALSE
;
177 docheckns
= ISC_FALSE
;
178 dochecksrv
= ISC_FALSE
;
179 } else if (ARGCMP("none")) {
180 zone_options
&= ~DNS_ZONEOPT_CHECKINTEGRITY
;
181 zone_options
&= ~DNS_ZONEOPT_CHECKSIBLING
;
182 docheckmx
= ISC_FALSE
;
183 docheckns
= ISC_FALSE
;
184 dochecksrv
= ISC_FALSE
;
186 fprintf(stderr
, "invalid argument to -i: %s\n",
187 isc_commandline_argument
);
193 inputformatstr
= isc_commandline_argument
;
197 outputformatstr
= isc_commandline_argument
;
205 if (ARGCMP("warn")) {
206 zone_options
|= DNS_ZONEOPT_CHECKNAMES
;
207 zone_options
&= ~DNS_ZONEOPT_CHECKNAMESFAIL
;
208 } else if (ARGCMP("fail")) {
209 zone_options
|= DNS_ZONEOPT_CHECKNAMES
|
210 DNS_ZONEOPT_CHECKNAMESFAIL
;
211 } else if (ARGCMP("ignore")) {
212 zone_options
&= ~(DNS_ZONEOPT_CHECKNAMES
|
213 DNS_ZONEOPT_CHECKNAMESFAIL
);
215 fprintf(stderr
, "invalid argument to -k: %s\n",
216 isc_commandline_argument
);
222 if (ARGCMP("ignore")) {
223 zone_options
&= ~(DNS_ZONEOPT_CHECKNS
|
224 DNS_ZONEOPT_FATALNS
);
225 } else if (ARGCMP("warn")) {
226 zone_options
|= DNS_ZONEOPT_CHECKNS
;
227 zone_options
&= ~DNS_ZONEOPT_FATALNS
;
228 } else if (ARGCMP("fail")) {
229 zone_options
|= DNS_ZONEOPT_CHECKNS
|
232 fprintf(stderr
, "invalid argument to -n: %s\n",
233 isc_commandline_argument
);
239 if (ARGCMP("warn")) {
240 zone_options
|= DNS_ZONEOPT_CHECKMX
;
241 zone_options
&= ~DNS_ZONEOPT_CHECKMXFAIL
;
242 } else if (ARGCMP("fail")) {
243 zone_options
|= DNS_ZONEOPT_CHECKMX
|
244 DNS_ZONEOPT_CHECKMXFAIL
;
245 } else if (ARGCMP("ignore")) {
246 zone_options
&= ~(DNS_ZONEOPT_CHECKMX
|
247 DNS_ZONEOPT_CHECKMXFAIL
);
249 fprintf(stderr
, "invalid argument to -m: %s\n",
250 isc_commandline_argument
);
260 result
= isc_dir_chroot(isc_commandline_argument
);
261 if (result
!= ISC_R_SUCCESS
) {
262 fprintf(stderr
, "isc_dir_chroot: %s: %s\n",
263 isc_commandline_argument
,
264 isc_result_totext(result
));
267 result
= isc_dir_chdir("/");
268 if (result
!= ISC_R_SUCCESS
) {
269 fprintf(stderr
, "isc_dir_chdir: %s\n",
270 isc_result_totext(result
));
277 outputstyle
= &dns_master_style_full
;
278 else if (ARGCMP("relative")) {
279 outputstyle
= &dns_master_style_default
;
282 "unknown or unsupported style: %s\n",
283 isc_commandline_argument
);
289 output_filename
= isc_commandline_argument
;
293 printf(VERSION
"\n");
297 workdir
= isc_commandline_argument
;
305 if (ARGCMP("fail")) {
306 zone_options
&= ~DNS_ZONEOPT_WARNMXCNAME
;
307 zone_options
&= ~DNS_ZONEOPT_IGNOREMXCNAME
;
308 } else if (ARGCMP("warn")) {
309 zone_options
|= DNS_ZONEOPT_WARNMXCNAME
;
310 zone_options
&= ~DNS_ZONEOPT_IGNOREMXCNAME
;
311 } else if (ARGCMP("ignore")) {
312 zone_options
|= DNS_ZONEOPT_WARNMXCNAME
;
313 zone_options
|= DNS_ZONEOPT_IGNOREMXCNAME
;
315 fprintf(stderr
, "invalid argument to -M: %s\n",
316 isc_commandline_argument
);
322 if (ARGCMP("fail")) {
323 zone_options
&= ~DNS_ZONEOPT_WARNSRVCNAME
;
324 zone_options
&= ~DNS_ZONEOPT_IGNORESRVCNAME
;
325 } else if (ARGCMP("warn")) {
326 zone_options
|= DNS_ZONEOPT_WARNSRVCNAME
;
327 zone_options
&= ~DNS_ZONEOPT_IGNORESRVCNAME
;
328 } else if (ARGCMP("ignore")) {
329 zone_options
|= DNS_ZONEOPT_WARNSRVCNAME
;
330 zone_options
|= DNS_ZONEOPT_IGNORESRVCNAME
;
332 fprintf(stderr
, "invalid argument to -S: %s\n",
333 isc_commandline_argument
);
340 zone_options
|= DNS_ZONEOPT_CHECKWILDCARD
;
341 else if (ARGCMP("ignore"))
342 zone_options
&= ~DNS_ZONEOPT_CHECKWILDCARD
;
350 if (progmode
== progmode_compile
) {
351 dumpzone
= 1; /* always dump */
352 if (output_filename
== NULL
) {
354 "output file required, but not specified\n");
359 if (workdir
!= NULL
) {
360 result
= isc_dir_chdir(workdir
);
361 if (result
!= ISC_R_SUCCESS
) {
362 fprintf(stderr
, "isc_dir_chdir: %s: %s\n",
363 workdir
, isc_result_totext(result
));
368 if (inputformatstr
!= NULL
) {
369 if (strcasecmp(inputformatstr
, "text") == 0)
370 inputformat
= dns_masterformat_text
;
371 else if (strcasecmp(inputformatstr
, "raw") == 0)
372 inputformat
= dns_masterformat_raw
;
374 fprintf(stderr
, "unknown file format: %s\n",
380 if (outputformatstr
!= NULL
) {
381 if (strcasecmp(outputformatstr
, "text") == 0)
382 outputformat
= dns_masterformat_text
;
383 else if (strcasecmp(outputformatstr
, "raw") == 0)
384 outputformat
= dns_masterformat_raw
;
386 fprintf(stderr
, "unknown file format: %s\n",
392 if (isc_commandline_index
+ 2 > argc
)
395 RUNTIME_CHECK(isc_mem_create(0, 0, &mctx
) == ISC_R_SUCCESS
);
397 RUNTIME_CHECK(setup_logging(mctx
, &lctx
) == ISC_R_SUCCESS
);
398 RUNTIME_CHECK(isc_entropy_create(mctx
, &ectx
) == ISC_R_SUCCESS
);
399 RUNTIME_CHECK(isc_hash_create(mctx
, ectx
, DNS_NAME_MAXWIRE
)
402 dns_result_register();
404 origin
= argv
[isc_commandline_index
++];
405 filename
= argv
[isc_commandline_index
++];
406 result
= load_zone(mctx
, origin
, filename
, inputformat
, classname
,
409 if (result
== ISC_R_SUCCESS
&& dumpzone
) {
410 if (!quiet
&& progmode
== progmode_compile
) {
411 fprintf(stdout
, "dump zone to %s...", output_filename
);
414 result
= dump_zone(origin
, zone
, output_filename
,
415 outputformat
, outputstyle
);
416 if (!quiet
&& progmode
== progmode_compile
)
417 fprintf(stdout
, "done\n");
420 if (!quiet
&& result
== ISC_R_SUCCESS
)
421 fprintf(stdout
, "OK\n");
424 isc_log_destroy(&lctx
);
426 isc_entropy_detach(&ectx
);
427 isc_mem_destroy(&mctx
);
428 return ((result
== ISC_R_SUCCESS
) ? 0 : 1);