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: zoneconf.c,v 1.161 2009/12/04 21:09:32 marka Exp */
26 #include <isc/buffer.h>
29 #include <isc/print.h>
30 #include <isc/stats.h>
31 #include <isc/string.h> /* Required for HP/UX (and others?) */
35 #include <dns/fixedname.h>
38 #include <dns/rdatatype.h>
40 #include <dns/stats.h>
44 #include <named/client.h>
45 #include <named/config.h>
46 #include <named/globals.h>
47 #include <named/log.h>
48 #include <named/server.h>
49 #include <named/zoneconf.h>
51 /* ACLs associated with zone */
57 allow_update_forwarding
60 #define RETERR(x) do { \
61 isc_result_t _r = (x); \
62 if (_r != ISC_R_SUCCESS) \
66 #define CHECK(x) do { \
68 if (result != ISC_R_SUCCESS) \
73 * Convenience function for configuring a single zone ACL.
76 configure_zone_acl(const cfg_obj_t
*zconfig
, const cfg_obj_t
*vconfig
,
77 const cfg_obj_t
*config
, acl_type_t acltype
,
78 cfg_aclconfctx_t
*actx
, dns_zone_t
*zone
,
79 void (*setzacl
)(dns_zone_t
*, dns_acl_t
*),
80 void (*clearzacl
)(dns_zone_t
*))
83 const cfg_obj_t
*maps
[5] = {NULL
, NULL
, NULL
, NULL
, NULL
};
84 const cfg_obj_t
*aclobj
= NULL
;
86 dns_acl_t
**aclp
= NULL
, *acl
= NULL
;
90 view
= dns_zone_getview(zone
);
95 aclp
= &view
->notifyacl
;
96 aclname
= "allow-notify";
100 aclp
= &view
->queryacl
;
101 aclname
= "allow-query";
105 aclp
= &view
->transferacl
;
106 aclname
= "allow-transfer";
110 aclp
= &view
->updateacl
;
111 aclname
= "allow-update";
113 case allow_update_forwarding
:
115 aclp
= &view
->upfwdacl
;
116 aclname
= "allow-update-forwarding";
120 return (ISC_R_FAILURE
);
123 /* First check to see if ACL is defined within the zone */
124 if (zconfig
!= NULL
) {
125 maps
[0] = cfg_tuple_get(zconfig
, "options");
126 ns_config_get(maps
, aclname
, &aclobj
);
127 if (aclobj
!= NULL
) {
133 /* Failing that, see if there's a default ACL already in the view */
134 if (aclp
!= NULL
&& *aclp
!= NULL
) {
135 (*setzacl
)(zone
, *aclp
);
136 return (ISC_R_SUCCESS
);
139 /* Check for default ACLs that haven't been parsed yet */
141 maps
[i
++] = cfg_tuple_get(vconfig
, "options");
142 if (config
!= NULL
) {
143 const cfg_obj_t
*options
= NULL
;
144 (void)cfg_map_get(config
, "options", &options
);
148 maps
[i
++] = ns_g_defaults
;
151 result
= ns_config_get(maps
, aclname
, &aclobj
);
152 if (aclobj
== NULL
) {
154 return (ISC_R_SUCCESS
);
158 result
= cfg_acl_fromconfig(aclobj
, config
, ns_g_lctx
, actx
,
159 dns_zone_getmctx(zone
), 0, &acl
);
160 if (result
!= ISC_R_SUCCESS
)
162 (*setzacl
)(zone
, acl
);
164 /* Set the view default now */
166 dns_acl_attach(acl
, aclp
);
168 dns_acl_detach(&acl
);
169 return (ISC_R_SUCCESS
);
173 * Parse the zone update-policy statement.
176 configure_zone_ssutable(const cfg_obj_t
*zconfig
, dns_zone_t
*zone
,
179 const cfg_obj_t
*updatepolicy
= NULL
;
180 const cfg_listelt_t
*element
, *element2
;
181 dns_ssutable_t
*table
= NULL
;
182 isc_mem_t
*mctx
= dns_zone_getmctx(zone
);
183 isc_boolean_t autoddns
= ISC_FALSE
;
186 (void)cfg_map_get(zconfig
, "update-policy", &updatepolicy
);
188 if (updatepolicy
== NULL
) {
189 dns_zone_setssutable(zone
, NULL
);
190 return (ISC_R_SUCCESS
);
193 if (cfg_obj_isstring(updatepolicy
) &&
194 strcmp("local", cfg_obj_asstring(updatepolicy
)) == 0) {
199 result
= dns_ssutable_create(mctx
, &table
);
200 if (result
!= ISC_R_SUCCESS
)
203 for (element
= cfg_list_first(updatepolicy
);
205 element
= cfg_list_next(element
))
207 const cfg_obj_t
*stmt
= cfg_listelt_value(element
);
208 const cfg_obj_t
*mode
= cfg_tuple_get(stmt
, "mode");
209 const cfg_obj_t
*identity
= cfg_tuple_get(stmt
, "identity");
210 const cfg_obj_t
*matchtype
= cfg_tuple_get(stmt
, "matchtype");
211 const cfg_obj_t
*dname
= cfg_tuple_get(stmt
, "name");
212 const cfg_obj_t
*typelist
= cfg_tuple_get(stmt
, "types");
214 isc_boolean_t grant
= ISC_FALSE
;
215 isc_boolean_t usezone
= ISC_FALSE
;
216 unsigned int mtype
= DNS_SSUMATCHTYPE_NAME
;
217 dns_fixedname_t fname
, fident
;
219 dns_rdatatype_t
*types
;
222 str
= cfg_obj_asstring(mode
);
223 if (strcasecmp(str
, "grant") == 0)
225 else if (strcasecmp(str
, "deny") == 0)
230 str
= cfg_obj_asstring(matchtype
);
231 if (strcasecmp(str
, "name") == 0)
232 mtype
= DNS_SSUMATCHTYPE_NAME
;
233 else if (strcasecmp(str
, "subdomain") == 0)
234 mtype
= DNS_SSUMATCHTYPE_SUBDOMAIN
;
235 else if (strcasecmp(str
, "wildcard") == 0)
236 mtype
= DNS_SSUMATCHTYPE_WILDCARD
;
237 else if (strcasecmp(str
, "self") == 0)
238 mtype
= DNS_SSUMATCHTYPE_SELF
;
239 else if (strcasecmp(str
, "selfsub") == 0)
240 mtype
= DNS_SSUMATCHTYPE_SELFSUB
;
241 else if (strcasecmp(str
, "selfwild") == 0)
242 mtype
= DNS_SSUMATCHTYPE_SELFWILD
;
243 else if (strcasecmp(str
, "ms-self") == 0)
244 mtype
= DNS_SSUMATCHTYPE_SELFMS
;
245 else if (strcasecmp(str
, "krb5-self") == 0)
246 mtype
= DNS_SSUMATCHTYPE_SELFKRB5
;
247 else if (strcasecmp(str
, "ms-subdomain") == 0)
248 mtype
= DNS_SSUMATCHTYPE_SUBDOMAINMS
;
249 else if (strcasecmp(str
, "krb5-subdomain") == 0)
250 mtype
= DNS_SSUMATCHTYPE_SUBDOMAINKRB5
;
251 else if (strcasecmp(str
, "tcp-self") == 0)
252 mtype
= DNS_SSUMATCHTYPE_TCPSELF
;
253 else if (strcasecmp(str
, "6to4-self") == 0)
254 mtype
= DNS_SSUMATCHTYPE_6TO4SELF
;
255 else if (strcasecmp(str
, "zonesub") == 0) {
256 mtype
= DNS_SSUMATCHTYPE_SUBDOMAIN
;
261 dns_fixedname_init(&fident
);
262 str
= cfg_obj_asstring(identity
);
263 isc_buffer_init(&b
, str
, strlen(str
));
264 isc_buffer_add(&b
, strlen(str
));
265 result
= dns_name_fromtext(dns_fixedname_name(&fident
), &b
,
266 dns_rootname
, 0, NULL
);
267 if (result
!= ISC_R_SUCCESS
) {
268 cfg_obj_log(identity
, ns_g_lctx
, ISC_LOG_ERROR
,
269 "'%s' is not a valid name", str
);
273 dns_fixedname_init(&fname
);
275 result
= dns_name_copy(dns_zone_getorigin(zone
),
276 dns_fixedname_name(&fname
),
278 if (result
!= ISC_R_SUCCESS
) {
279 cfg_obj_log(identity
, ns_g_lctx
, ISC_LOG_ERROR
,
280 "error copying origin: %s",
281 isc_result_totext(result
));
285 str
= cfg_obj_asstring(dname
);
286 isc_buffer_init(&b
, str
, strlen(str
));
287 isc_buffer_add(&b
, strlen(str
));
288 result
= dns_name_fromtext(dns_fixedname_name(&fname
),
289 &b
, dns_rootname
, 0, NULL
);
290 if (result
!= ISC_R_SUCCESS
) {
291 cfg_obj_log(identity
, ns_g_lctx
, ISC_LOG_ERROR
,
292 "'%s' is not a valid name", str
);
297 n
= ns_config_listcount(typelist
);
301 types
= isc_mem_get(mctx
, n
* sizeof(dns_rdatatype_t
));
303 result
= ISC_R_NOMEMORY
;
309 for (element2
= cfg_list_first(typelist
);
311 element2
= cfg_list_next(element2
))
313 const cfg_obj_t
*typeobj
;
318 typeobj
= cfg_listelt_value(element2
);
319 str
= cfg_obj_asstring(typeobj
);
320 DE_CONST(str
, r
.base
);
321 r
.length
= strlen(str
);
323 result
= dns_rdatatype_fromtext(&types
[i
++], &r
);
324 if (result
!= ISC_R_SUCCESS
) {
325 cfg_obj_log(identity
, ns_g_lctx
, ISC_LOG_ERROR
,
326 "'%s' is not a valid type", str
);
327 isc_mem_put(mctx
, types
,
328 n
* sizeof(dns_rdatatype_t
));
334 result
= dns_ssutable_addrule(table
, grant
,
335 dns_fixedname_name(&fident
),
337 dns_fixedname_name(&fname
),
340 isc_mem_put(mctx
, types
, n
* sizeof(dns_rdatatype_t
));
341 if (result
!= ISC_R_SUCCESS
) {
347 * If "update-policy local;" and a session key exists,
348 * then use the default policy, which is equivalent to:
349 * update-policy { grant <session-keyname> zonesub any; };
352 dns_rdatatype_t any
= dns_rdatatype_any
;
354 if (ns_g_server
->session_keyname
== NULL
) {
355 isc_log_write(ns_g_lctx
, NS_LOGCATEGORY_GENERAL
,
356 NS_LOGMODULE_SERVER
, ISC_LOG_ERROR
,
357 "failed to enable auto DDNS policy "
358 "for zone %s: session key not found",
360 result
= ISC_R_NOTFOUND
;
364 result
= dns_ssutable_addrule(table
, ISC_TRUE
,
365 ns_g_server
->session_keyname
,
366 DNS_SSUMATCHTYPE_SUBDOMAIN
,
367 dns_zone_getorigin(zone
),
370 if (result
!= ISC_R_SUCCESS
)
374 result
= ISC_R_SUCCESS
;
375 dns_zone_setssutable(zone
, table
);
378 dns_ssutable_detach(&table
);
383 * Convert a config file zone type into a server zone type.
385 static inline dns_zonetype_t
386 zonetype_fromconfig(const cfg_obj_t
*map
) {
387 const cfg_obj_t
*obj
= NULL
;
390 result
= cfg_map_get(map
, "type", &obj
);
391 INSIST(result
== ISC_R_SUCCESS
);
392 return (ns_config_getzonetype(obj
));
396 * Helper function for strtoargv(). Pardon the gratuitous recursion.
399 strtoargvsub(isc_mem_t
*mctx
, char *s
, unsigned int *argcp
,
400 char ***argvp
, unsigned int n
)
404 /* Discard leading whitespace. */
405 while (*s
== ' ' || *s
== '\t')
409 /* We have reached the end of the string. */
411 *argvp
= isc_mem_get(mctx
, n
* sizeof(char *));
413 return (ISC_R_NOMEMORY
);
416 while (*p
!= ' ' && *p
!= '\t' && *p
!= '\0')
421 result
= strtoargvsub(mctx
, p
, argcp
, argvp
, n
+ 1);
422 if (result
!= ISC_R_SUCCESS
)
426 return (ISC_R_SUCCESS
);
430 * Tokenize the string "s" into whitespace-separated words,
431 * return the number of words in '*argcp' and an array
432 * of pointers to the words in '*argvp'. The caller
433 * must free the array using isc_mem_put(). The string
434 * is modified in-place.
437 strtoargv(isc_mem_t
*mctx
, char *s
, unsigned int *argcp
, char ***argvp
) {
438 return (strtoargvsub(mctx
, s
, argcp
, argvp
, 0));
442 checknames(dns_zonetype_t ztype
, const cfg_obj_t
**maps
,
443 const cfg_obj_t
**objp
)
445 const char *zone
= NULL
;
449 case dns_zone_slave
: zone
= "slave"; break;
450 case dns_zone_master
: zone
= "master"; break;
454 result
= ns_checknames_get(maps
, zone
, objp
);
455 INSIST(result
== ISC_R_SUCCESS
);
459 ns_zone_configure(const cfg_obj_t
*config
, const cfg_obj_t
*vconfig
,
460 const cfg_obj_t
*zconfig
, cfg_aclconfctx_t
*ac
,
465 dns_rdataclass_t zclass
;
466 dns_rdataclass_t vclass
;
467 const cfg_obj_t
*maps
[5];
468 const cfg_obj_t
*zoptions
= NULL
;
469 const cfg_obj_t
*options
= NULL
;
470 const cfg_obj_t
*obj
;
471 const char *filename
= NULL
;
472 dns_notifytype_t notifytype
= dns_notifytype_yes
;
473 isc_sockaddr_t
*addrs
;
474 dns_name_t
**keynames
;
479 static char default_dbtype
[] = "rbt";
480 isc_mem_t
*mctx
= dns_zone_getmctx(zone
);
481 dns_dialuptype_t dialup
= dns_dialuptype_no
;
482 dns_zonetype_t ztype
;
484 isc_int32_t journal_size
;
488 isc_boolean_t check
= ISC_FALSE
, fail
= ISC_FALSE
;
489 isc_boolean_t warn
= ISC_FALSE
, ignore
= ISC_FALSE
;
490 isc_boolean_t ixfrdiff
;
491 dns_masterformat_t masterformat
;
492 isc_stats_t
*zoneqrystats
;
493 isc_boolean_t zonestats_on
;
497 if (zconfig
!= NULL
) {
498 zoptions
= cfg_tuple_get(zconfig
, "options");
499 maps
[i
++] = zoptions
;
502 maps
[i
++] = cfg_tuple_get(vconfig
, "options");
503 if (config
!= NULL
) {
504 (void)cfg_map_get(config
, "options", &options
);
508 maps
[i
++] = ns_g_defaults
;
512 RETERR(ns_config_getclass(cfg_tuple_get(vconfig
, "class"),
513 dns_rdataclass_in
, &vclass
));
515 vclass
= dns_rdataclass_in
;
518 * Configure values common to all zone types.
521 zname
= cfg_obj_asstring(cfg_tuple_get(zconfig
, "name"));
523 RETERR(ns_config_getclass(cfg_tuple_get(zconfig
, "class"),
525 dns_zone_setclass(zone
, zclass
);
527 ztype
= zonetype_fromconfig(zoptions
);
528 dns_zone_settype(zone
, ztype
);
531 result
= cfg_map_get(zoptions
, "database", &obj
);
532 if (result
== ISC_R_SUCCESS
)
533 cpval
= isc_mem_strdup(mctx
, cfg_obj_asstring(obj
));
535 cpval
= default_dbtype
;
538 return(ISC_R_NOMEMORY
);
540 result
= strtoargv(mctx
, cpval
, &dbargc
, &dbargv
);
541 if (result
!= ISC_R_SUCCESS
&& cpval
!= default_dbtype
) {
542 isc_mem_free(mctx
, cpval
);
547 * ANSI C is strange here. There is no logical reason why (char **)
548 * cannot be promoted automatically to (const char * const *) by the
549 * compiler w/o generating a warning.
551 result
= dns_zone_setdbtype(zone
, dbargc
, (const char * const *)dbargv
);
552 isc_mem_put(mctx
, dbargv
, dbargc
* sizeof(*dbargv
));
553 if (cpval
!= default_dbtype
)
554 isc_mem_free(mctx
, cpval
);
555 if (result
!= ISC_R_SUCCESS
)
559 result
= cfg_map_get(zoptions
, "file", &obj
);
560 if (result
== ISC_R_SUCCESS
)
561 filename
= cfg_obj_asstring(obj
);
563 masterformat
= dns_masterformat_text
;
565 result
= ns_config_get(maps
, "masterfile-format", &obj
);
566 if (result
== ISC_R_SUCCESS
) {
567 const char *masterformatstr
= cfg_obj_asstring(obj
);
569 if (strcasecmp(masterformatstr
, "text") == 0)
570 masterformat
= dns_masterformat_text
;
571 else if (strcasecmp(masterformatstr
, "raw") == 0)
572 masterformat
= dns_masterformat_raw
;
576 RETERR(dns_zone_setfile2(zone
, filename
, masterformat
));
579 result
= cfg_map_get(zoptions
, "journal", &obj
);
580 if (result
== ISC_R_SUCCESS
)
581 RETERR(dns_zone_setjournal(zone
, cfg_obj_asstring(obj
)));
583 if (ztype
== dns_zone_slave
)
584 RETERR(configure_zone_acl(zconfig
, vconfig
, config
,
585 allow_notify
, ac
, zone
,
586 dns_zone_setnotifyacl
,
587 dns_zone_clearnotifyacl
));
589 * XXXAG This probably does not make sense for stubs.
591 RETERR(configure_zone_acl(zconfig
, vconfig
, config
,
592 allow_query
, ac
, zone
,
593 dns_zone_setqueryacl
,
594 dns_zone_clearqueryacl
));
597 result
= ns_config_get(maps
, "dialup", &obj
);
598 INSIST(result
== ISC_R_SUCCESS
);
599 if (cfg_obj_isboolean(obj
)) {
600 if (cfg_obj_asboolean(obj
))
601 dialup
= dns_dialuptype_yes
;
603 dialup
= dns_dialuptype_no
;
605 const char *dialupstr
= cfg_obj_asstring(obj
);
606 if (strcasecmp(dialupstr
, "notify") == 0)
607 dialup
= dns_dialuptype_notify
;
608 else if (strcasecmp(dialupstr
, "notify-passive") == 0)
609 dialup
= dns_dialuptype_notifypassive
;
610 else if (strcasecmp(dialupstr
, "refresh") == 0)
611 dialup
= dns_dialuptype_refresh
;
612 else if (strcasecmp(dialupstr
, "passive") == 0)
613 dialup
= dns_dialuptype_passive
;
617 dns_zone_setdialup(zone
, dialup
);
620 result
= ns_config_get(maps
, "zone-statistics", &obj
);
621 INSIST(result
== ISC_R_SUCCESS
);
622 zonestats_on
= cfg_obj_asboolean(obj
);
625 RETERR(isc_stats_create(mctx
, &zoneqrystats
,
626 dns_nsstatscounter_max
));
628 dns_zone_setrequeststats(zone
, zoneqrystats
);
629 if (zoneqrystats
!= NULL
)
630 isc_stats_detach(&zoneqrystats
);
633 * Configure master functionality. This applies
634 * to primary masters (type "master") and slaves
635 * acting as masters (type "slave"), but not to stubs.
637 if (ztype
!= dns_zone_stub
) {
639 result
= ns_config_get(maps
, "notify", &obj
);
640 INSIST(result
== ISC_R_SUCCESS
);
641 if (cfg_obj_isboolean(obj
)) {
642 if (cfg_obj_asboolean(obj
))
643 notifytype
= dns_notifytype_yes
;
645 notifytype
= dns_notifytype_no
;
647 const char *notifystr
= cfg_obj_asstring(obj
);
648 if (strcasecmp(notifystr
, "explicit") == 0)
649 notifytype
= dns_notifytype_explicit
;
650 else if (strcasecmp(notifystr
, "master-only") == 0)
651 notifytype
= dns_notifytype_masteronly
;
655 dns_zone_setnotifytype(zone
, notifytype
);
658 result
= ns_config_get(maps
, "also-notify", &obj
);
659 if (result
== ISC_R_SUCCESS
) {
660 isc_sockaddr_t
*addrs
= NULL
;
661 isc_uint32_t addrcount
;
662 result
= ns_config_getiplist(config
, obj
, 0, mctx
,
664 if (result
!= ISC_R_SUCCESS
)
666 result
= dns_zone_setalsonotify(zone
, addrs
,
668 ns_config_putiplist(mctx
, &addrs
, addrcount
);
669 if (result
!= ISC_R_SUCCESS
)
672 RETERR(dns_zone_setalsonotify(zone
, NULL
, 0));
675 result
= ns_config_get(maps
, "notify-source", &obj
);
676 INSIST(result
== ISC_R_SUCCESS
);
677 RETERR(dns_zone_setnotifysrc4(zone
, cfg_obj_assockaddr(obj
)));
678 ns_add_reserved_dispatch(ns_g_server
, cfg_obj_assockaddr(obj
));
681 result
= ns_config_get(maps
, "notify-source-v6", &obj
);
682 INSIST(result
== ISC_R_SUCCESS
);
683 RETERR(dns_zone_setnotifysrc6(zone
, cfg_obj_assockaddr(obj
)));
684 ns_add_reserved_dispatch(ns_g_server
, cfg_obj_assockaddr(obj
));
687 result
= ns_config_get(maps
, "notify-to-soa", &obj
);
688 INSIST(result
== ISC_R_SUCCESS
);
689 dns_zone_setoption(zone
, DNS_ZONEOPT_NOTIFYTOSOA
,
690 cfg_obj_asboolean(obj
));
692 dns_zone_setisself(zone
, ns_client_isself
, NULL
);
694 RETERR(configure_zone_acl(zconfig
, vconfig
, config
,
695 allow_transfer
, ac
, zone
,
697 dns_zone_clearxfracl
));
700 result
= ns_config_get(maps
, "max-transfer-time-out", &obj
);
701 INSIST(result
== ISC_R_SUCCESS
);
702 dns_zone_setmaxxfrout(zone
, cfg_obj_asuint32(obj
) * 60);
705 result
= ns_config_get(maps
, "max-transfer-idle-out", &obj
);
706 INSIST(result
== ISC_R_SUCCESS
);
707 dns_zone_setidleout(zone
, cfg_obj_asuint32(obj
) * 60);
710 result
= ns_config_get(maps
, "max-journal-size", &obj
);
711 INSIST(result
== ISC_R_SUCCESS
);
712 dns_zone_setjournalsize(zone
, -1);
713 if (cfg_obj_isstring(obj
)) {
714 const char *str
= cfg_obj_asstring(obj
);
715 INSIST(strcasecmp(str
, "unlimited") == 0);
716 journal_size
= ISC_UINT32_MAX
/ 2;
718 isc_resourcevalue_t value
;
719 value
= cfg_obj_asuint64(obj
);
720 if (value
> ISC_UINT32_MAX
/ 2) {
721 cfg_obj_log(obj
, ns_g_lctx
,
724 "%" ISC_PRINT_QUADFORMAT
"d' "
729 journal_size
= (isc_uint32_t
)value
;
731 dns_zone_setjournalsize(zone
, journal_size
);
734 result
= ns_config_get(maps
, "ixfr-from-differences", &obj
);
735 INSIST(result
== ISC_R_SUCCESS
);
736 if (cfg_obj_isboolean(obj
))
737 ixfrdiff
= cfg_obj_asboolean(obj
);
738 else if (strcasecmp(cfg_obj_asstring(obj
), "master") &&
739 ztype
== dns_zone_master
)
741 else if (strcasecmp(cfg_obj_asstring(obj
), "slave") &&
742 ztype
== dns_zone_slave
)
745 ixfrdiff
= ISC_FALSE
;
746 dns_zone_setoption(zone
, DNS_ZONEOPT_IXFRFROMDIFFS
, ixfrdiff
);
748 checknames(ztype
, maps
, &obj
);
750 if (strcasecmp(cfg_obj_asstring(obj
), "warn") == 0) {
753 } else if (strcasecmp(cfg_obj_asstring(obj
), "fail") == 0) {
754 fail
= check
= ISC_TRUE
;
755 } else if (strcasecmp(cfg_obj_asstring(obj
), "ignore") == 0) {
756 fail
= check
= ISC_FALSE
;
759 dns_zone_setoption(zone
, DNS_ZONEOPT_CHECKNAMES
, check
);
760 dns_zone_setoption(zone
, DNS_ZONEOPT_CHECKNAMESFAIL
, fail
);
763 result
= ns_config_get(maps
, "notify-delay", &obj
);
764 INSIST(result
== ISC_R_SUCCESS
);
765 dns_zone_setnotifydelay(zone
, cfg_obj_asuint32(obj
));
768 result
= ns_config_get(maps
, "check-sibling", &obj
);
769 INSIST(result
== ISC_R_SUCCESS
);
770 dns_zone_setoption(zone
, DNS_ZONEOPT_CHECKSIBLING
,
771 cfg_obj_asboolean(obj
));
774 result
= ns_config_get(maps
, "zero-no-soa-ttl", &obj
);
775 INSIST(result
== ISC_R_SUCCESS
);
776 dns_zone_setzeronosoattl(zone
, cfg_obj_asboolean(obj
));
779 result
= ns_config_get(maps
, "nsec3-test-zone", &obj
);
780 INSIST(result
== ISC_R_SUCCESS
);
781 dns_zone_setoption(zone
, DNS_ZONEOPT_NSEC3TESTZONE
,
782 cfg_obj_asboolean(obj
));
786 * Configure update-related options. These apply to
787 * primary masters only.
789 if (ztype
== dns_zone_master
) {
790 dns_acl_t
*updateacl
;
792 RETERR(configure_zone_acl(zconfig
, vconfig
, config
,
793 allow_update
, ac
, zone
,
794 dns_zone_setupdateacl
,
795 dns_zone_clearupdateacl
));
797 updateacl
= dns_zone_getupdateacl(zone
);
798 if (updateacl
!= NULL
&& dns_acl_isinsecure(updateacl
))
799 isc_log_write(ns_g_lctx
, DNS_LOGCATEGORY_SECURITY
,
800 NS_LOGMODULE_SERVER
, ISC_LOG_WARNING
,
801 "zone '%s' allows updates by IP "
802 "address, which is insecure",
805 RETERR(configure_zone_ssutable(zoptions
, zone
, zname
));
808 result
= ns_config_get(maps
, "sig-validity-interval", &obj
);
809 INSIST(result
== ISC_R_SUCCESS
);
811 const cfg_obj_t
*validity
, *resign
;
813 validity
= cfg_tuple_get(obj
, "validity");
814 seconds
= cfg_obj_asuint32(validity
) * 86400;
815 dns_zone_setsigvalidityinterval(zone
, seconds
);
817 resign
= cfg_tuple_get(obj
, "re-sign");
818 if (cfg_obj_isvoid(resign
)) {
821 if (seconds
> 7 * 86400)
822 seconds
= cfg_obj_asuint32(resign
) *
825 seconds
= cfg_obj_asuint32(resign
) *
828 dns_zone_setsigresigninginterval(zone
, seconds
);
832 result
= ns_config_get(maps
, "key-directory", &obj
);
833 if (result
== ISC_R_SUCCESS
) {
834 filename
= cfg_obj_asstring(obj
);
835 RETERR(dns_zone_setkeydirectory(zone
, filename
));
839 result
= ns_config_get(maps
, "sig-signing-signatures", &obj
);
840 INSIST(result
== ISC_R_SUCCESS
);
841 dns_zone_setsignatures(zone
, cfg_obj_asuint32(obj
));
844 result
= ns_config_get(maps
, "sig-signing-nodes", &obj
);
845 INSIST(result
== ISC_R_SUCCESS
);
846 dns_zone_setnodes(zone
, cfg_obj_asuint32(obj
));
849 result
= ns_config_get(maps
, "sig-signing-type", &obj
);
850 INSIST(result
== ISC_R_SUCCESS
);
851 dns_zone_setprivatetype(zone
, cfg_obj_asuint32(obj
));
854 result
= ns_config_get(maps
, "update-check-ksk", &obj
);
855 INSIST(result
== ISC_R_SUCCESS
);
856 dns_zone_setoption(zone
, DNS_ZONEOPT_UPDATECHECKKSK
,
857 cfg_obj_asboolean(obj
));
860 result
= ns_config_get(maps
, "dnssec-dnskey-kskonly", &obj
);
861 INSIST(result
== ISC_R_SUCCESS
);
862 dns_zone_setoption(zone
, DNS_ZONEOPT_DNSKEYKSKONLY
,
863 cfg_obj_asboolean(obj
));
864 } else if (ztype
== dns_zone_slave
) {
865 RETERR(configure_zone_acl(zconfig
, vconfig
, config
,
866 allow_update_forwarding
, ac
, zone
,
867 dns_zone_setforwardacl
,
868 dns_zone_clearforwardacl
));
872 * Primary master functionality.
874 if (ztype
== dns_zone_master
) {
875 isc_boolean_t allow
= ISC_FALSE
, maint
= ISC_FALSE
;
876 isc_boolean_t create
= ISC_FALSE
;
879 result
= ns_config_get(maps
, "check-wildcard", &obj
);
880 if (result
== ISC_R_SUCCESS
)
881 check
= cfg_obj_asboolean(obj
);
884 dns_zone_setoption(zone
, DNS_ZONEOPT_CHECKWILDCARD
, check
);
887 result
= ns_config_get(maps
, "check-dup-records", &obj
);
889 if (strcasecmp(cfg_obj_asstring(obj
), "warn") == 0) {
892 } else if (strcasecmp(cfg_obj_asstring(obj
), "fail") == 0) {
893 fail
= check
= ISC_TRUE
;
894 } else if (strcasecmp(cfg_obj_asstring(obj
), "ignore") == 0) {
895 fail
= check
= ISC_FALSE
;
898 dns_zone_setoption(zone
, DNS_ZONEOPT_CHECKDUPRR
, check
);
899 dns_zone_setoption(zone
, DNS_ZONEOPT_CHECKDUPRRFAIL
, fail
);
902 result
= ns_config_get(maps
, "check-mx", &obj
);
904 if (strcasecmp(cfg_obj_asstring(obj
), "warn") == 0) {
907 } else if (strcasecmp(cfg_obj_asstring(obj
), "fail") == 0) {
908 fail
= check
= ISC_TRUE
;
909 } else if (strcasecmp(cfg_obj_asstring(obj
), "ignore") == 0) {
910 fail
= check
= ISC_FALSE
;
913 dns_zone_setoption(zone
, DNS_ZONEOPT_CHECKMX
, check
);
914 dns_zone_setoption(zone
, DNS_ZONEOPT_CHECKMXFAIL
, fail
);
917 result
= ns_config_get(maps
, "check-integrity", &obj
);
919 dns_zone_setoption(zone
, DNS_ZONEOPT_CHECKINTEGRITY
,
920 cfg_obj_asboolean(obj
));
923 result
= ns_config_get(maps
, "check-mx-cname", &obj
);
925 if (strcasecmp(cfg_obj_asstring(obj
), "warn") == 0) {
928 } else if (strcasecmp(cfg_obj_asstring(obj
), "fail") == 0) {
929 warn
= ignore
= ISC_FALSE
;
930 } else if (strcasecmp(cfg_obj_asstring(obj
), "ignore") == 0) {
931 warn
= ignore
= ISC_TRUE
;
934 dns_zone_setoption(zone
, DNS_ZONEOPT_WARNMXCNAME
, warn
);
935 dns_zone_setoption(zone
, DNS_ZONEOPT_IGNOREMXCNAME
, ignore
);
938 result
= ns_config_get(maps
, "check-srv-cname", &obj
);
940 if (strcasecmp(cfg_obj_asstring(obj
), "warn") == 0) {
943 } else if (strcasecmp(cfg_obj_asstring(obj
), "fail") == 0) {
944 warn
= ignore
= ISC_FALSE
;
945 } else if (strcasecmp(cfg_obj_asstring(obj
), "ignore") == 0) {
946 warn
= ignore
= ISC_TRUE
;
949 dns_zone_setoption(zone
, DNS_ZONEOPT_WARNSRVCNAME
, warn
);
950 dns_zone_setoption(zone
, DNS_ZONEOPT_IGNORESRVCNAME
, ignore
);
953 result
= ns_config_get(maps
, "dnssec-secure-to-insecure", &obj
);
955 dns_zone_setoption(zone
, DNS_ZONEOPT_SECURETOINSECURE
,
956 cfg_obj_asboolean(obj
));
959 result
= cfg_map_get(zoptions
, "auto-dnssec", &obj
);
960 if (result
== ISC_R_SUCCESS
) {
961 const char *arg
= cfg_obj_asstring(obj
);
962 if (strcasecmp(arg
, "allow") == 0)
964 else if (strcasecmp(arg
, "maintain") == 0)
965 allow
= maint
= ISC_TRUE
;
966 else if (strcasecmp(arg
, "create") == 0)
967 allow
= maint
= create
= ISC_TRUE
;
968 else if (strcasecmp(arg
, "off") == 0)
972 dns_zone_setkeyopt(zone
, DNS_ZONEKEY_ALLOW
, allow
);
973 dns_zone_setkeyopt(zone
, DNS_ZONEKEY_MAINTAIN
, maint
);
974 dns_zone_setkeyopt(zone
, DNS_ZONEKEY_CREATE
, create
);
979 * Configure slave functionality.
986 result
= cfg_map_get(zoptions
, "masters", &obj
);
990 RETERR(ns_config_getipandkeylist(config
, obj
, mctx
,
993 result
= dns_zone_setmasterswithkeys(zone
, addrs
,
995 ns_config_putipandkeylist(mctx
, &addrs
, &keynames
,
998 result
= dns_zone_setmasters(zone
, NULL
, 0);
1004 result
= ns_config_get(maps
, "multi-master", &obj
);
1005 INSIST(result
== ISC_R_SUCCESS
);
1006 multi
= cfg_obj_asboolean(obj
);
1008 dns_zone_setoption(zone
, DNS_ZONEOPT_MULTIMASTER
, multi
);
1011 result
= ns_config_get(maps
, "max-transfer-time-in", &obj
);
1012 INSIST(result
== ISC_R_SUCCESS
);
1013 dns_zone_setmaxxfrin(zone
, cfg_obj_asuint32(obj
) * 60);
1016 result
= ns_config_get(maps
, "max-transfer-idle-in", &obj
);
1017 INSIST(result
== ISC_R_SUCCESS
);
1018 dns_zone_setidlein(zone
, cfg_obj_asuint32(obj
) * 60);
1021 result
= ns_config_get(maps
, "max-refresh-time", &obj
);
1022 INSIST(result
== ISC_R_SUCCESS
);
1023 dns_zone_setmaxrefreshtime(zone
, cfg_obj_asuint32(obj
));
1026 result
= ns_config_get(maps
, "min-refresh-time", &obj
);
1027 INSIST(result
== ISC_R_SUCCESS
);
1028 dns_zone_setminrefreshtime(zone
, cfg_obj_asuint32(obj
));
1031 result
= ns_config_get(maps
, "max-retry-time", &obj
);
1032 INSIST(result
== ISC_R_SUCCESS
);
1033 dns_zone_setmaxretrytime(zone
, cfg_obj_asuint32(obj
));
1036 result
= ns_config_get(maps
, "min-retry-time", &obj
);
1037 INSIST(result
== ISC_R_SUCCESS
);
1038 dns_zone_setminretrytime(zone
, cfg_obj_asuint32(obj
));
1041 result
= ns_config_get(maps
, "transfer-source", &obj
);
1042 INSIST(result
== ISC_R_SUCCESS
);
1043 RETERR(dns_zone_setxfrsource4(zone
, cfg_obj_assockaddr(obj
)));
1044 ns_add_reserved_dispatch(ns_g_server
, cfg_obj_assockaddr(obj
));
1047 result
= ns_config_get(maps
, "transfer-source-v6", &obj
);
1048 INSIST(result
== ISC_R_SUCCESS
);
1049 RETERR(dns_zone_setxfrsource6(zone
, cfg_obj_assockaddr(obj
)));
1050 ns_add_reserved_dispatch(ns_g_server
, cfg_obj_assockaddr(obj
));
1053 result
= ns_config_get(maps
, "alt-transfer-source", &obj
);
1054 INSIST(result
== ISC_R_SUCCESS
);
1055 RETERR(dns_zone_setaltxfrsource4(zone
, cfg_obj_assockaddr(obj
)));
1058 result
= ns_config_get(maps
, "alt-transfer-source-v6", &obj
);
1059 INSIST(result
== ISC_R_SUCCESS
);
1060 RETERR(dns_zone_setaltxfrsource6(zone
, cfg_obj_assockaddr(obj
)));
1063 (void)ns_config_get(maps
, "use-alt-transfer-source", &obj
);
1066 * Default off when views are in use otherwise
1067 * on for BIND 8 compatibility.
1069 view
= dns_zone_getview(zone
);
1070 if (view
!= NULL
&& strcmp(view
->name
, "_default") == 0)
1075 alt
= cfg_obj_asboolean(obj
);
1076 dns_zone_setoption(zone
, DNS_ZONEOPT_USEALTXFRSRC
, alt
);
1079 (void)ns_config_get(maps
, "try-tcp-refresh", &obj
);
1080 dns_zone_setoption(zone
, DNS_ZONEOPT_TRYTCPREFRESH
,
1081 cfg_obj_asboolean(obj
));
1088 return (ISC_R_SUCCESS
);
1092 ns_zone_reusable(dns_zone_t
*zone
, const cfg_obj_t
*zconfig
) {
1093 const cfg_obj_t
*zoptions
= NULL
;
1094 const cfg_obj_t
*obj
= NULL
;
1095 const char *cfilename
;
1096 const char *zfilename
;
1098 zoptions
= cfg_tuple_get(zconfig
, "options");
1100 if (zonetype_fromconfig(zoptions
) != dns_zone_gettype(zone
))
1104 (void)cfg_map_get(zoptions
, "file", &obj
);
1106 cfilename
= cfg_obj_asstring(obj
);
1109 zfilename
= dns_zone_getfile(zone
);
1110 if (!((cfilename
== NULL
&& zfilename
== NULL
) ||
1111 (cfilename
!= NULL
&& zfilename
!= NULL
&&
1112 strcmp(cfilename
, zfilename
) == 0)))