1 /* $NetBSD: zoneconf.c,v 1.8 2015/07/08 17:28:55 christos Exp $ */
4 * Copyright (C) 2004-2015 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.
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?) */
36 #include <dns/fixedname.h>
39 #include <dns/rdata.h>
40 #include <dns/rdatatype.h>
41 #include <dns/rdataset.h>
42 #include <dns/rdatalist.h>
43 #include <dns/result.h>
46 #include <dns/stats.h>
50 #include <named/client.h>
51 #include <named/config.h>
52 #include <named/globals.h>
53 #include <named/log.h>
54 #include <named/server.h>
55 #include <named/zoneconf.h>
57 /* ACLs associated with zone */
64 allow_update_forwarding
67 #define RETERR(x) do { \
68 isc_result_t _r = (x); \
69 if (_r != ISC_R_SUCCESS) \
71 } while (/*CONSTCOND*/0)
73 #define CHECK(x) do { \
75 if (result != ISC_R_SUCCESS) \
77 } while (/*CONSTCOND*/0)
80 * Convenience function for configuring a single zone ACL.
83 configure_zone_acl(const cfg_obj_t
*zconfig
, const cfg_obj_t
*vconfig
,
84 const cfg_obj_t
*config
, acl_type_t acltype
,
85 cfg_aclconfctx_t
*actx
, dns_zone_t
*zone
,
86 void (*setzacl
)(dns_zone_t
*, dns_acl_t
*),
87 void (*clearzacl
)(dns_zone_t
*))
90 const cfg_obj_t
*maps
[5] = {NULL
, NULL
, NULL
, NULL
, NULL
};
91 const cfg_obj_t
*aclobj
= NULL
;
93 dns_acl_t
**aclp
= NULL
, *acl
= NULL
;
97 view
= dns_zone_getview(zone
);
102 aclp
= &view
->notifyacl
;
103 aclname
= "allow-notify";
107 aclp
= &view
->queryacl
;
108 aclname
= "allow-query";
112 aclp
= &view
->queryonacl
;
113 aclname
= "allow-query-on";
117 aclp
= &view
->transferacl
;
118 aclname
= "allow-transfer";
122 aclp
= &view
->updateacl
;
123 aclname
= "allow-update";
125 case allow_update_forwarding
:
127 aclp
= &view
->upfwdacl
;
128 aclname
= "allow-update-forwarding";
132 return (ISC_R_FAILURE
);
135 /* First check to see if ACL is defined within the zone */
136 if (zconfig
!= NULL
) {
137 maps
[0] = cfg_tuple_get(zconfig
, "options");
138 (void)ns_config_get(maps
, aclname
, &aclobj
);
139 if (aclobj
!= NULL
) {
145 /* Failing that, see if there's a default ACL already in the view */
146 if (aclp
!= NULL
&& *aclp
!= NULL
) {
147 (*setzacl
)(zone
, *aclp
);
148 return (ISC_R_SUCCESS
);
151 /* Check for default ACLs that haven't been parsed yet */
152 if (vconfig
!= NULL
) {
153 const cfg_obj_t
*options
= cfg_tuple_get(vconfig
, "options");
157 if (config
!= NULL
) {
158 const cfg_obj_t
*options
= NULL
;
159 (void)cfg_map_get(config
, "options", &options
);
163 maps
[i
++] = ns_g_defaults
;
166 (void)ns_config_get(maps
, aclname
, &aclobj
);
167 if (aclobj
== NULL
) {
169 return (ISC_R_SUCCESS
);
173 result
= cfg_acl_fromconfig(aclobj
, config
, ns_g_lctx
, actx
,
174 dns_zone_getmctx(zone
), 0, &acl
);
175 if (result
!= ISC_R_SUCCESS
)
177 (*setzacl
)(zone
, acl
);
179 /* Set the view default now */
181 dns_acl_attach(acl
, aclp
);
183 dns_acl_detach(&acl
);
184 return (ISC_R_SUCCESS
);
188 * Parse the zone update-policy statement.
191 configure_zone_ssutable(const cfg_obj_t
*zconfig
, dns_zone_t
*zone
,
194 const cfg_obj_t
*updatepolicy
= NULL
;
195 const cfg_listelt_t
*element
, *element2
;
196 dns_ssutable_t
*table
= NULL
;
197 isc_mem_t
*mctx
= dns_zone_getmctx(zone
);
198 isc_boolean_t autoddns
= ISC_FALSE
;
201 (void)cfg_map_get(zconfig
, "update-policy", &updatepolicy
);
203 if (updatepolicy
== NULL
) {
204 dns_zone_setssutable(zone
, NULL
);
205 return (ISC_R_SUCCESS
);
208 if (cfg_obj_isstring(updatepolicy
) &&
209 strcmp("local", cfg_obj_asstring(updatepolicy
)) == 0) {
214 result
= dns_ssutable_create(mctx
, &table
);
215 if (result
!= ISC_R_SUCCESS
)
218 for (element
= cfg_list_first(updatepolicy
);
220 element
= cfg_list_next(element
))
222 const cfg_obj_t
*stmt
= cfg_listelt_value(element
);
223 const cfg_obj_t
*mode
= cfg_tuple_get(stmt
, "mode");
224 const cfg_obj_t
*identity
= cfg_tuple_get(stmt
, "identity");
225 const cfg_obj_t
*matchtype
= cfg_tuple_get(stmt
, "matchtype");
226 const cfg_obj_t
*dname
= cfg_tuple_get(stmt
, "name");
227 const cfg_obj_t
*typelist
= cfg_tuple_get(stmt
, "types");
229 isc_boolean_t grant
= ISC_FALSE
;
230 isc_boolean_t usezone
= ISC_FALSE
;
231 unsigned int mtype
= DNS_SSUMATCHTYPE_NAME
;
232 dns_fixedname_t fname
, fident
;
234 dns_rdatatype_t
*types
;
237 str
= cfg_obj_asstring(mode
);
238 if (strcasecmp(str
, "grant") == 0)
240 else if (strcasecmp(str
, "deny") == 0)
245 str
= cfg_obj_asstring(matchtype
);
246 if (strcasecmp(str
, "name") == 0)
247 mtype
= DNS_SSUMATCHTYPE_NAME
;
248 else if (strcasecmp(str
, "subdomain") == 0)
249 mtype
= DNS_SSUMATCHTYPE_SUBDOMAIN
;
250 else if (strcasecmp(str
, "wildcard") == 0)
251 mtype
= DNS_SSUMATCHTYPE_WILDCARD
;
252 else if (strcasecmp(str
, "self") == 0)
253 mtype
= DNS_SSUMATCHTYPE_SELF
;
254 else if (strcasecmp(str
, "selfsub") == 0)
255 mtype
= DNS_SSUMATCHTYPE_SELFSUB
;
256 else if (strcasecmp(str
, "selfwild") == 0)
257 mtype
= DNS_SSUMATCHTYPE_SELFWILD
;
258 else if (strcasecmp(str
, "ms-self") == 0)
259 mtype
= DNS_SSUMATCHTYPE_SELFMS
;
260 else if (strcasecmp(str
, "krb5-self") == 0)
261 mtype
= DNS_SSUMATCHTYPE_SELFKRB5
;
262 else if (strcasecmp(str
, "ms-subdomain") == 0)
263 mtype
= DNS_SSUMATCHTYPE_SUBDOMAINMS
;
264 else if (strcasecmp(str
, "krb5-subdomain") == 0)
265 mtype
= DNS_SSUMATCHTYPE_SUBDOMAINKRB5
;
266 else if (strcasecmp(str
, "tcp-self") == 0)
267 mtype
= DNS_SSUMATCHTYPE_TCPSELF
;
268 else if (strcasecmp(str
, "6to4-self") == 0)
269 mtype
= DNS_SSUMATCHTYPE_6TO4SELF
;
270 else if (strcasecmp(str
, "zonesub") == 0) {
271 mtype
= DNS_SSUMATCHTYPE_SUBDOMAIN
;
273 } else if (strcasecmp(str
, "external") == 0)
274 mtype
= DNS_SSUMATCHTYPE_EXTERNAL
;
278 dns_fixedname_init(&fident
);
279 str
= cfg_obj_asstring(identity
);
280 isc_buffer_constinit(&b
, str
, strlen(str
));
281 isc_buffer_add(&b
, strlen(str
));
282 result
= dns_name_fromtext(dns_fixedname_name(&fident
), &b
,
283 dns_rootname
, 0, NULL
);
284 if (result
!= ISC_R_SUCCESS
) {
285 cfg_obj_log(identity
, ns_g_lctx
, ISC_LOG_ERROR
,
286 "'%s' is not a valid name", str
);
290 dns_fixedname_init(&fname
);
292 result
= dns_name_copy(dns_zone_getorigin(zone
),
293 dns_fixedname_name(&fname
),
295 if (result
!= ISC_R_SUCCESS
) {
296 cfg_obj_log(identity
, ns_g_lctx
, ISC_LOG_ERROR
,
297 "error copying origin: %s",
298 isc_result_totext(result
));
302 str
= cfg_obj_asstring(dname
);
303 isc_buffer_constinit(&b
, str
, strlen(str
));
304 isc_buffer_add(&b
, strlen(str
));
305 result
= dns_name_fromtext(dns_fixedname_name(&fname
),
306 &b
, dns_rootname
, 0, NULL
);
307 if (result
!= ISC_R_SUCCESS
) {
308 cfg_obj_log(identity
, ns_g_lctx
, ISC_LOG_ERROR
,
309 "'%s' is not a valid name", str
);
314 n
= ns_config_listcount(typelist
);
318 types
= isc_mem_get(mctx
, n
* sizeof(dns_rdatatype_t
));
320 result
= ISC_R_NOMEMORY
;
326 for (element2
= cfg_list_first(typelist
);
328 element2
= cfg_list_next(element2
))
330 const cfg_obj_t
*typeobj
;
335 typeobj
= cfg_listelt_value(element2
);
336 str
= cfg_obj_asstring(typeobj
);
337 DE_CONST(str
, r
.base
);
338 r
.length
= strlen(str
);
340 result
= dns_rdatatype_fromtext(&types
[i
++], &r
);
341 if (result
!= ISC_R_SUCCESS
) {
342 cfg_obj_log(identity
, ns_g_lctx
, ISC_LOG_ERROR
,
343 "'%s' is not a valid type", str
);
344 isc_mem_put(mctx
, types
,
345 n
* sizeof(dns_rdatatype_t
));
351 result
= dns_ssutable_addrule(table
, grant
,
352 dns_fixedname_name(&fident
),
354 dns_fixedname_name(&fname
),
357 isc_mem_put(mctx
, types
, n
* sizeof(dns_rdatatype_t
));
358 if (result
!= ISC_R_SUCCESS
) {
364 * If "update-policy local;" and a session key exists,
365 * then use the default policy, which is equivalent to:
366 * update-policy { grant <session-keyname> zonesub any; };
369 dns_rdatatype_t any
= dns_rdatatype_any
;
371 if (ns_g_server
->session_keyname
== NULL
) {
372 isc_log_write(ns_g_lctx
, NS_LOGCATEGORY_GENERAL
,
373 NS_LOGMODULE_SERVER
, ISC_LOG_ERROR
,
374 "failed to enable auto DDNS policy "
375 "for zone %s: session key not found",
377 result
= ISC_R_NOTFOUND
;
381 result
= dns_ssutable_addrule(table
, ISC_TRUE
,
382 ns_g_server
->session_keyname
,
383 DNS_SSUMATCHTYPE_SUBDOMAIN
,
384 dns_zone_getorigin(zone
),
387 if (result
!= ISC_R_SUCCESS
)
391 result
= ISC_R_SUCCESS
;
392 dns_zone_setssutable(zone
, table
);
395 dns_ssutable_detach(&table
);
400 * This is the TTL used for internally generated RRsets for static-stub zones.
401 * The value doesn't matter because the mapping is static, but needs to be
402 * defined for the sake of implementation.
404 #define STATICSTUB_SERVER_TTL 86400
407 * Configure an apex NS with glues for a static-stub zone.
408 * For example, for the zone named "example.com", the following RRs will be
409 * added to the zone DB:
410 * example.com. NS example.com.
411 * example.com. A 192.0.2.1
412 * example.com. AAAA 2001:db8::1
415 configure_staticstub_serveraddrs(const cfg_obj_t
*zconfig
, dns_zone_t
*zone
,
416 dns_rdatalist_t
*rdatalist_ns
,
417 dns_rdatalist_t
*rdatalist_a
,
418 dns_rdatalist_t
*rdatalist_aaaa
)
420 const cfg_listelt_t
*element
;
421 isc_mem_t
*mctx
= dns_zone_getmctx(zone
);
422 isc_region_t region
, sregion
;
424 isc_result_t result
= ISC_R_SUCCESS
;
426 for (element
= cfg_list_first(zconfig
);
428 element
= cfg_list_next(element
))
430 const isc_sockaddr_t
* sa
;
432 const cfg_obj_t
*address
= cfg_listelt_value(element
);
433 dns_rdatalist_t
*rdatalist
;
435 sa
= cfg_obj_assockaddr(address
);
436 if (isc_sockaddr_getport(sa
) != 0) {
437 cfg_obj_log(zconfig
, ns_g_lctx
, ISC_LOG_ERROR
,
438 "port is not configurable for "
439 "static stub server-addresses");
440 return (ISC_R_FAILURE
);
442 isc_netaddr_fromsockaddr(&na
, sa
);
443 if (isc_netaddr_getzone(&na
) != 0) {
444 cfg_obj_log(zconfig
, ns_g_lctx
, ISC_LOG_ERROR
,
445 "scoped address is not allowed "
448 return (ISC_R_FAILURE
);
453 region
.length
= sizeof(na
.type
.in
);
454 rdatalist
= rdatalist_a
;
457 INSIST(na
.family
== AF_INET6
);
458 region
.length
= sizeof(na
.type
.in6
);
459 rdatalist
= rdatalist_aaaa
;
463 rdata
= isc_mem_get(mctx
, sizeof(*rdata
) + region
.length
);
465 return (ISC_R_NOMEMORY
);
466 region
.base
= (unsigned char *)(rdata
+ 1);
467 memmove(region
.base
, &na
.type
, region
.length
);
468 dns_rdata_init(rdata
);
469 dns_rdata_fromregion(rdata
, dns_zone_getclass(zone
),
470 rdatalist
->type
, ®ion
);
471 ISC_LIST_APPEND(rdatalist
->rdata
, rdata
, link
);
475 * If no address is specified (unlikely in this context, but possible),
476 * there's nothing to do anymore.
478 if (ISC_LIST_EMPTY(rdatalist_a
->rdata
) &&
479 ISC_LIST_EMPTY(rdatalist_aaaa
->rdata
)) {
480 return (ISC_R_SUCCESS
);
483 /* Add to the list an apex NS with the ns name being the origin name */
484 dns_name_toregion(dns_zone_getorigin(zone
), &sregion
);
485 rdata
= isc_mem_get(mctx
, sizeof(*rdata
) + sregion
.length
);
488 * Already allocated data will be freed in the caller, so
489 * we can simply return here.
491 return (ISC_R_NOMEMORY
);
493 region
.length
= sregion
.length
;
494 region
.base
= (unsigned char *)(rdata
+ 1);
495 memmove(region
.base
, sregion
.base
, region
.length
);
496 dns_rdata_init(rdata
);
497 dns_rdata_fromregion(rdata
, dns_zone_getclass(zone
),
498 dns_rdatatype_ns
, ®ion
);
499 ISC_LIST_APPEND(rdatalist_ns
->rdata
, rdata
, link
);
505 * Configure an apex NS with an out-of-zone NS names for a static-stub zone.
506 * For example, for the zone named "example.com", something like the following
507 * RRs will be added to the zone DB:
508 * example.com. NS ns.example.net.
511 configure_staticstub_servernames(const cfg_obj_t
*zconfig
, dns_zone_t
*zone
,
512 dns_rdatalist_t
*rdatalist
, const char *zname
)
514 const cfg_listelt_t
*element
;
515 isc_mem_t
*mctx
= dns_zone_getmctx(zone
);
517 isc_region_t sregion
, region
;
518 isc_result_t result
= ISC_R_SUCCESS
;
520 for (element
= cfg_list_first(zconfig
);
522 element
= cfg_list_next(element
))
524 const cfg_obj_t
*obj
;
526 dns_fixedname_t fixed_name
;
530 obj
= cfg_listelt_value(element
);
531 str
= cfg_obj_asstring(obj
);
533 dns_fixedname_init(&fixed_name
);
534 nsname
= dns_fixedname_name(&fixed_name
);
536 isc_buffer_constinit(&b
, str
, strlen(str
));
537 isc_buffer_add(&b
, strlen(str
));
538 result
= dns_name_fromtext(nsname
, &b
, dns_rootname
, 0, NULL
);
539 if (result
!= ISC_R_SUCCESS
) {
540 cfg_obj_log(zconfig
, ns_g_lctx
, ISC_LOG_ERROR
,
541 "server-name '%s' is not a valid "
545 if (dns_name_issubdomain(nsname
, dns_zone_getorigin(zone
))) {
546 cfg_obj_log(zconfig
, ns_g_lctx
, ISC_LOG_ERROR
,
547 "server-name '%s' must not be a "
548 "subdomain of zone name '%s'",
550 return (ISC_R_FAILURE
);
553 dns_name_toregion(nsname
, &sregion
);
554 rdata
= isc_mem_get(mctx
, sizeof(*rdata
) + sregion
.length
);
556 return (ISC_R_NOMEMORY
);
557 region
.length
= sregion
.length
;
558 region
.base
= (unsigned char *)(rdata
+ 1);
559 memmove(region
.base
, sregion
.base
, region
.length
);
560 dns_rdata_init(rdata
);
561 dns_rdata_fromregion(rdata
, dns_zone_getclass(zone
),
562 dns_rdatatype_ns
, ®ion
);
563 ISC_LIST_APPEND(rdatalist
->rdata
, rdata
, link
);
570 * Configure static-stub zone.
573 configure_staticstub(const cfg_obj_t
*zconfig
, dns_zone_t
*zone
,
574 const char *zname
, const char *dbtype
)
577 const cfg_obj_t
*obj
;
578 isc_mem_t
*mctx
= dns_zone_getmctx(zone
);
580 dns_dbversion_t
*dbversion
= NULL
;
581 dns_dbnode_t
*apexnode
= NULL
;
584 dns_rdataset_t rdataset
;
585 dns_rdatalist_t rdatalist_ns
, rdatalist_a
, rdatalist_aaaa
;
586 dns_rdatalist_t
* rdatalists
[] = {
587 &rdatalist_ns
, &rdatalist_a
, &rdatalist_aaaa
, NULL
592 /* Create the DB beforehand */
593 RETERR(dns_db_create(mctx
, dbtype
, dns_zone_getorigin(zone
),
594 dns_dbtype_stub
, dns_zone_getclass(zone
),
596 dns_zone_setdb(zone
, db
);
598 dns_rdatalist_init(&rdatalist_ns
);
599 rdatalist_ns
.rdclass
= dns_zone_getclass(zone
);
600 rdatalist_ns
.type
= dns_rdatatype_ns
;
601 rdatalist_ns
.ttl
= STATICSTUB_SERVER_TTL
;
603 dns_rdatalist_init(&rdatalist_a
);
604 rdatalist_a
.rdclass
= dns_zone_getclass(zone
);
605 rdatalist_a
.type
= dns_rdatatype_a
;
606 rdatalist_a
.ttl
= STATICSTUB_SERVER_TTL
;
608 dns_rdatalist_init(&rdatalist_aaaa
);
609 rdatalist_aaaa
.rdclass
= dns_zone_getclass(zone
);
610 rdatalist_aaaa
.type
= dns_rdatatype_aaaa
;
611 rdatalist_aaaa
.ttl
= STATICSTUB_SERVER_TTL
;
613 /* Prepare zone RRs from the configuration */
615 result
= cfg_map_get(zconfig
, "server-addresses", &obj
);
616 if (result
== ISC_R_SUCCESS
) {
618 result
= configure_staticstub_serveraddrs(obj
, zone
,
622 if (result
!= ISC_R_SUCCESS
)
627 result
= cfg_map_get(zconfig
, "server-names", &obj
);
628 if (result
== ISC_R_SUCCESS
) {
630 result
= configure_staticstub_servernames(obj
, zone
,
633 if (result
!= ISC_R_SUCCESS
)
638 * Sanity check: there should be at least one NS RR at the zone apex
639 * to trigger delegation.
641 if (ISC_LIST_EMPTY(rdatalist_ns
.rdata
)) {
642 isc_log_write(ns_g_lctx
, NS_LOGCATEGORY_GENERAL
,
643 NS_LOGMODULE_SERVER
, ISC_LOG_ERROR
,
644 "No NS record is configured for a "
645 "static-stub zone '%s'", zname
);
646 result
= ISC_R_FAILURE
;
651 * Now add NS and glue A/AAAA RRsets to the zone DB.
652 * First open a new version for the add operation and get a pointer
653 * to the apex node (all RRs are of the apex name).
655 result
= dns_db_newversion(db
, &dbversion
);
656 if (result
!= ISC_R_SUCCESS
)
658 dns_name_init(&apexname
, NULL
);
659 dns_name_clone(dns_zone_getorigin(zone
), &apexname
);
660 result
= dns_db_findnode(db
, &apexname
, ISC_FALSE
, &apexnode
);
661 if (result
!= ISC_R_SUCCESS
)
665 dns_rdataset_init(&rdataset
);
666 RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_ns
, &rdataset
)
668 result
= dns_db_addrdataset(db
, apexnode
, dbversion
, 0, &rdataset
,
670 dns_rdataset_disassociate(&rdataset
);
671 if (result
!= ISC_R_SUCCESS
)
674 /* Add glue A RRset, if any */
675 if (!ISC_LIST_EMPTY(rdatalist_a
.rdata
)) {
676 RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_a
, &rdataset
)
678 result
= dns_db_addrdataset(db
, apexnode
, dbversion
, 0,
680 dns_rdataset_disassociate(&rdataset
);
681 if (result
!= ISC_R_SUCCESS
)
685 /* Add glue AAAA RRset, if any */
686 if (!ISC_LIST_EMPTY(rdatalist_aaaa
.rdata
)) {
687 RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_aaaa
,
690 result
= dns_db_addrdataset(db
, apexnode
, dbversion
, 0,
692 dns_rdataset_disassociate(&rdataset
);
693 if (result
!= ISC_R_SUCCESS
)
697 result
= ISC_R_SUCCESS
;
700 if (apexnode
!= NULL
)
701 dns_db_detachnode(db
, &apexnode
);
702 if (dbversion
!= NULL
)
703 dns_db_closeversion(db
, &dbversion
, ISC_TRUE
);
706 for (i
= 0; rdatalists
[i
] != NULL
; i
++) {
707 while ((rdata
= ISC_LIST_HEAD(rdatalists
[i
]->rdata
)) != NULL
) {
708 ISC_LIST_UNLINK(rdatalists
[i
]->rdata
, rdata
, link
);
709 dns_rdata_toregion(rdata
, ®ion
);
710 isc_mem_put(mctx
, rdata
,
711 sizeof(*rdata
) + region
.length
);
715 INSIST(dbversion
== NULL
);
721 * Convert a config file zone type into a server zone type.
723 static inline dns_zonetype_t
724 zonetype_fromconfig(const cfg_obj_t
*map
) {
725 const cfg_obj_t
*obj
= NULL
;
728 result
= cfg_map_get(map
, "type", &obj
);
729 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
730 return (ns_config_getzonetype(obj
));
734 * Helper function for strtoargv(). Pardon the gratuitous recursion.
737 strtoargvsub(isc_mem_t
*mctx
, char *s
, unsigned int *argcp
,
738 char ***argvp
, unsigned int n
)
742 /* Discard leading whitespace. */
743 while (*s
== ' ' || *s
== '\t')
747 /* We have reached the end of the string. */
749 *argvp
= isc_mem_get(mctx
, n
* sizeof(char *));
751 return (ISC_R_NOMEMORY
);
754 while (*p
!= ' ' && *p
!= '\t' && *p
!= '\0')
759 result
= strtoargvsub(mctx
, p
, argcp
, argvp
, n
+ 1);
760 if (result
!= ISC_R_SUCCESS
)
764 return (ISC_R_SUCCESS
);
768 * Tokenize the string "s" into whitespace-separated words,
769 * return the number of words in '*argcp' and an array
770 * of pointers to the words in '*argvp'. The caller
771 * must free the array using isc_mem_put(). The string
772 * is modified in-place.
775 strtoargv(isc_mem_t
*mctx
, char *s
, unsigned int *argcp
, char ***argvp
) {
776 return (strtoargvsub(mctx
, s
, argcp
, argvp
, 0));
780 checknames(dns_zonetype_t ztype
, const cfg_obj_t
**maps
,
781 const cfg_obj_t
**objp
)
783 const char *zone
= NULL
;
787 case dns_zone_slave
: zone
= "slave"; break;
788 case dns_zone_master
: zone
= "master"; break;
792 result
= ns_checknames_get(maps
, zone
, objp
);
793 INSIST(result
== ISC_R_SUCCESS
&& objp
!= NULL
&& *objp
!= NULL
);
797 ns_zone_configure(const cfg_obj_t
*config
, const cfg_obj_t
*vconfig
,
798 const cfg_obj_t
*zconfig
, cfg_aclconfctx_t
*ac
,
799 dns_zone_t
*zone
, dns_zone_t
*raw
)
803 dns_rdataclass_t zclass
;
804 dns_rdataclass_t vclass
;
805 const cfg_obj_t
*maps
[5];
806 const cfg_obj_t
*nodefault
[4];
807 const cfg_obj_t
*zoptions
= NULL
;
808 const cfg_obj_t
*options
= NULL
;
809 const cfg_obj_t
*obj
;
810 const char *filename
= NULL
;
811 const char *dupcheck
;
812 dns_notifytype_t notifytype
= dns_notifytype_yes
;
813 isc_sockaddr_t
*addrs
;
815 dns_name_t
**keynames
;
819 static char default_dbtype
[] = "rbt";
820 static char dlz_dbtype
[] = "dlz";
821 char *cpval
= default_dbtype
;
822 isc_mem_t
*mctx
= dns_zone_getmctx(zone
);
823 dns_dialuptype_t dialup
= dns_dialuptype_no
;
824 dns_zonetype_t ztype
;
826 isc_int32_t journal_size
;
830 isc_boolean_t check
= ISC_FALSE
, fail
= ISC_FALSE
;
831 isc_boolean_t warn
= ISC_FALSE
, ignore
= ISC_FALSE
;
832 isc_boolean_t ixfrdiff
;
833 dns_masterformat_t masterformat
;
834 isc_stats_t
*zoneqrystats
;
835 dns_stats_t
*rcvquerystats
;
836 dns_zonestat_level_t statlevel
;
838 dns_zone_t
*mayberaw
= (raw
!= NULL
) ? raw
: zone
;
842 if (zconfig
!= NULL
) {
843 zoptions
= cfg_tuple_get(zconfig
, "options");
844 nodefault
[i
] = maps
[i
] = zoptions
;
847 if (vconfig
!= NULL
) {
848 nodefault
[i
] = maps
[i
] = cfg_tuple_get(vconfig
, "options");
851 if (config
!= NULL
) {
852 (void)cfg_map_get(config
, "options", &options
);
853 if (options
!= NULL
) {
854 nodefault
[i
] = maps
[i
] = options
;
859 maps
[i
++] = ns_g_defaults
;
863 RETERR(ns_config_getclass(cfg_tuple_get(vconfig
, "class"),
864 dns_rdataclass_in
, &vclass
));
866 vclass
= dns_rdataclass_in
;
869 * Configure values common to all zone types.
872 zname
= cfg_obj_asstring(cfg_tuple_get(zconfig
, "name"));
874 RETERR(ns_config_getclass(cfg_tuple_get(zconfig
, "class"),
876 dns_zone_setclass(zone
, zclass
);
878 dns_zone_setclass(raw
, zclass
);
880 ztype
= zonetype_fromconfig(zoptions
);
882 dns_zone_settype(raw
, ztype
);
883 dns_zone_settype(zone
, dns_zone_master
);
885 dns_zone_settype(zone
, ztype
);
888 result
= cfg_map_get(zoptions
, "database", &obj
);
889 if (result
== ISC_R_SUCCESS
)
890 cpval
= isc_mem_strdup(mctx
, cfg_obj_asstring(obj
));
892 return(ISC_R_NOMEMORY
);
895 result
= cfg_map_get(zoptions
, "dlz", &obj
);
896 if (result
== ISC_R_SUCCESS
) {
897 const char *dlzname
= cfg_obj_asstring(obj
);
900 if (cpval
!= default_dbtype
) {
901 isc_log_write(ns_g_lctx
, NS_LOGCATEGORY_GENERAL
,
902 NS_LOGMODULE_SERVER
, ISC_LOG_ERROR
,
903 "zone '%s': both 'database' and 'dlz' "
905 return (ISC_R_FAILURE
);
908 len
= strlen(dlzname
) + 5;
909 cpval
= isc_mem_allocate(mctx
, len
);
910 snprintf(cpval
, len
, "dlz %s", dlzname
);
913 result
= strtoargv(mctx
, cpval
, &dbargc
, &dbargv
);
914 if (result
!= ISC_R_SUCCESS
&& cpval
!= default_dbtype
) {
915 isc_mem_free(mctx
, cpval
);
920 * ANSI C is strange here. There is no logical reason why (char **)
921 * cannot be promoted automatically to (const char * const *) by the
922 * compiler w/o generating a warning.
924 result
= dns_zone_setdbtype(zone
, dbargc
, (const char * const *)dbargv
);
925 isc_mem_put(mctx
, dbargv
, dbargc
* sizeof(*dbargv
));
926 if (cpval
!= default_dbtype
&& cpval
!= dlz_dbtype
)
927 isc_mem_free(mctx
, cpval
);
928 if (result
!= ISC_R_SUCCESS
)
932 result
= cfg_map_get(zoptions
, "file", &obj
);
933 if (result
== ISC_R_SUCCESS
)
934 filename
= cfg_obj_asstring(obj
);
937 * Unless we're using some alternative database, a master zone
938 * will be needing a master file.
940 if (ztype
== dns_zone_master
&& cpval
== default_dbtype
&&
942 isc_log_write(ns_g_lctx
, NS_LOGCATEGORY_GENERAL
,
943 NS_LOGMODULE_SERVER
, ISC_LOG_ERROR
,
944 "zone '%s': 'file' not specified",
946 return (ISC_R_FAILURE
);
949 if (ztype
== dns_zone_slave
)
950 masterformat
= dns_masterformat_raw
;
952 masterformat
= dns_masterformat_text
;
954 result
= ns_config_get(maps
, "masterfile-format", &obj
);
955 if (result
== ISC_R_SUCCESS
) {
956 const char *masterformatstr
= cfg_obj_asstring(obj
);
958 if (strcasecmp(masterformatstr
, "text") == 0)
959 masterformat
= dns_masterformat_text
;
960 else if (strcasecmp(masterformatstr
, "raw") == 0)
961 masterformat
= dns_masterformat_raw
;
962 else if (strcasecmp(masterformatstr
, "map") == 0)
963 masterformat
= dns_masterformat_map
;
969 result
= ns_config_get(maps
, "max-zone-ttl", &obj
);
970 if (result
== ISC_R_SUCCESS
&& masterformat
== dns_masterformat_map
) {
971 isc_log_write(ns_g_lctx
, NS_LOGCATEGORY_GENERAL
,
972 NS_LOGMODULE_SERVER
, ISC_LOG_ERROR
,
973 "zone '%s': 'max-zone-ttl' is not compatible "
974 "with 'masterfile-format map'", zname
);
975 return (ISC_R_FAILURE
);
976 } else if (result
== ISC_R_SUCCESS
) {
977 dns_ttl_t maxttl
= cfg_obj_asuint32(obj
);
978 dns_zone_setmaxttl(zone
, maxttl
);
980 dns_zone_setmaxttl(raw
, maxttl
);
983 if (raw
!= NULL
&& filename
!= NULL
) {
984 #define SIGNED ".signed"
985 size_t signedlen
= strlen(filename
) + sizeof(SIGNED
);
988 RETERR(dns_zone_setfile2(raw
, filename
, masterformat
));
989 signedname
= isc_mem_get(mctx
, signedlen
);
990 if (signedname
== NULL
)
991 return (ISC_R_NOMEMORY
);
993 (void)snprintf(signedname
, signedlen
, "%s" SIGNED
, filename
);
994 result
= dns_zone_setfile2(zone
, signedname
,
995 dns_masterformat_raw
);
996 isc_mem_put(mctx
, signedname
, signedlen
);
997 if (result
!= ISC_R_SUCCESS
)
1000 RETERR(dns_zone_setfile2(zone
, filename
, masterformat
));
1003 result
= cfg_map_get(zoptions
, "journal", &obj
);
1004 if (result
== ISC_R_SUCCESS
)
1005 RETERR(dns_zone_setjournal(mayberaw
, cfg_obj_asstring(obj
)));
1008 * Notify messages are processed by the raw zone if it exists.
1010 if (ztype
== dns_zone_slave
)
1011 RETERR(configure_zone_acl(zconfig
, vconfig
, config
,
1012 allow_notify
, ac
, mayberaw
,
1013 dns_zone_setnotifyacl
,
1014 dns_zone_clearnotifyacl
));
1017 * XXXAG This probably does not make sense for stubs.
1019 RETERR(configure_zone_acl(zconfig
, vconfig
, config
,
1020 allow_query
, ac
, zone
,
1021 dns_zone_setqueryacl
,
1022 dns_zone_clearqueryacl
));
1024 RETERR(configure_zone_acl(zconfig
, vconfig
, config
,
1025 allow_query_on
, ac
, zone
,
1026 dns_zone_setqueryonacl
,
1027 dns_zone_clearqueryonacl
));
1030 result
= ns_config_get(maps
, "dialup", &obj
);
1031 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1032 if (cfg_obj_isboolean(obj
)) {
1033 if (cfg_obj_asboolean(obj
))
1034 dialup
= dns_dialuptype_yes
;
1036 dialup
= dns_dialuptype_no
;
1038 const char *dialupstr
= cfg_obj_asstring(obj
);
1039 if (strcasecmp(dialupstr
, "notify") == 0)
1040 dialup
= dns_dialuptype_notify
;
1041 else if (strcasecmp(dialupstr
, "notify-passive") == 0)
1042 dialup
= dns_dialuptype_notifypassive
;
1043 else if (strcasecmp(dialupstr
, "refresh") == 0)
1044 dialup
= dns_dialuptype_refresh
;
1045 else if (strcasecmp(dialupstr
, "passive") == 0)
1046 dialup
= dns_dialuptype_passive
;
1051 dns_zone_setdialup(raw
, dialup
);
1052 dns_zone_setdialup(zone
, dialup
);
1055 result
= ns_config_get(maps
, "zone-statistics", &obj
);
1056 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1057 if (cfg_obj_isboolean(obj
)) {
1058 if (cfg_obj_asboolean(obj
))
1059 statlevel
= dns_zonestat_full
;
1061 statlevel
= dns_zonestat_none
;
1063 const char *levelstr
= cfg_obj_asstring(obj
);
1064 if (strcasecmp(levelstr
, "full") == 0)
1065 statlevel
= dns_zonestat_full
;
1066 else if (strcasecmp(levelstr
, "terse") == 0)
1067 statlevel
= dns_zonestat_terse
;
1068 else if (strcasecmp(levelstr
, "none") == 0)
1069 statlevel
= dns_zonestat_none
;
1073 dns_zone_setstatlevel(zone
, statlevel
);
1075 zoneqrystats
= NULL
;
1076 rcvquerystats
= NULL
;
1077 if (statlevel
== dns_zonestat_full
) {
1078 RETERR(isc_stats_create(mctx
, &zoneqrystats
,
1079 dns_nsstatscounter_max
));
1080 RETERR(dns_rdatatypestats_create(mctx
,
1083 dns_zone_setrequeststats(zone
, zoneqrystats
);
1084 dns_zone_setrcvquerystats(zone
, rcvquerystats
);
1086 if (zoneqrystats
!= NULL
)
1087 isc_stats_detach(&zoneqrystats
);
1089 if(rcvquerystats
!= NULL
)
1090 dns_stats_detach(&rcvquerystats
);
1093 * Configure master functionality. This applies
1094 * to primary masters (type "master") and slaves
1095 * acting as masters (type "slave"), but not to stubs.
1097 if (ztype
!= dns_zone_stub
&& ztype
!= dns_zone_staticstub
&&
1098 ztype
!= dns_zone_redirect
) {
1100 result
= ns_config_get(maps
, "notify", &obj
);
1101 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1102 if (cfg_obj_isboolean(obj
)) {
1103 if (cfg_obj_asboolean(obj
))
1104 notifytype
= dns_notifytype_yes
;
1106 notifytype
= dns_notifytype_no
;
1108 const char *notifystr
= cfg_obj_asstring(obj
);
1109 if (strcasecmp(notifystr
, "explicit") == 0)
1110 notifytype
= dns_notifytype_explicit
;
1111 else if (strcasecmp(notifystr
, "master-only") == 0)
1112 notifytype
= dns_notifytype_masteronly
;
1117 dns_zone_setnotifytype(raw
, dns_notifytype_no
);
1118 dns_zone_setnotifytype(zone
, notifytype
);
1121 result
= ns_config_get(maps
, "also-notify", &obj
);
1122 if (result
== ISC_R_SUCCESS
&&
1123 (notifytype
== dns_notifytype_yes
||
1124 notifytype
== dns_notifytype_explicit
||
1125 (notifytype
== dns_notifytype_masteronly
&&
1126 ztype
== dns_zone_master
)))
1128 isc_uint32_t addrcount
;
1132 RETERR(ns_config_getipandkeylist(config
, obj
, mctx
,
1136 result
= dns_zone_setalsonotifydscpkeys(zone
, addrs
,
1140 ns_config_putipandkeylist(mctx
, &addrs
, &dscps
,
1141 &keynames
, addrcount
);
1143 INSIST(addrs
== NULL
&& dscps
== NULL
&&
1147 RETERR(dns_zone_setalsonotify(zone
, NULL
, 0));
1150 result
= ns_config_get(maps
, "notify-source", &obj
);
1151 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1152 RETERR(dns_zone_setnotifysrc4(zone
, cfg_obj_assockaddr(obj
)));
1153 dscp
= cfg_obj_getdscp(obj
);
1156 RETERR(dns_zone_setnotifysrc4dscp(zone
, dscp
));
1157 ns_add_reserved_dispatch(ns_g_server
, cfg_obj_assockaddr(obj
));
1160 result
= ns_config_get(maps
, "notify-source-v6", &obj
);
1161 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1162 RETERR(dns_zone_setnotifysrc6(zone
, cfg_obj_assockaddr(obj
)));
1163 dscp
= cfg_obj_getdscp(obj
);
1166 RETERR(dns_zone_setnotifysrc6dscp(zone
, dscp
));
1167 ns_add_reserved_dispatch(ns_g_server
, cfg_obj_assockaddr(obj
));
1170 result
= ns_config_get(maps
, "notify-to-soa", &obj
);
1171 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1172 dns_zone_setoption(zone
, DNS_ZONEOPT_NOTIFYTOSOA
,
1173 cfg_obj_asboolean(obj
));
1175 dns_zone_setisself(zone
, ns_client_isself
, NULL
);
1177 RETERR(configure_zone_acl(zconfig
, vconfig
, config
,
1178 allow_transfer
, ac
, zone
,
1180 dns_zone_clearxfracl
));
1183 result
= ns_config_get(maps
, "max-transfer-time-out", &obj
);
1184 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1185 dns_zone_setmaxxfrout(zone
, cfg_obj_asuint32(obj
) * 60);
1188 result
= ns_config_get(maps
, "max-transfer-idle-out", &obj
);
1189 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1190 dns_zone_setidleout(zone
, cfg_obj_asuint32(obj
) * 60);
1193 result
= ns_config_get(maps
, "max-journal-size", &obj
);
1194 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1196 dns_zone_setjournalsize(raw
, -1);
1197 dns_zone_setjournalsize(zone
, -1);
1198 if (cfg_obj_isstring(obj
)) {
1199 const char *str
= cfg_obj_asstring(obj
);
1200 INSIST(strcasecmp(str
, "unlimited") == 0);
1201 journal_size
= ISC_UINT32_MAX
/ 2;
1203 isc_resourcevalue_t value
;
1204 value
= cfg_obj_asuint64(obj
);
1205 if (value
> ISC_UINT32_MAX
/ 2) {
1206 cfg_obj_log(obj
, ns_g_lctx
,
1208 "'max-journal-size "
1209 "%" ISC_PRINT_QUADFORMAT
"d' "
1212 RETERR(ISC_R_RANGE
);
1214 journal_size
= (isc_uint32_t
)value
;
1217 dns_zone_setjournalsize(raw
, journal_size
);
1218 dns_zone_setjournalsize(zone
, journal_size
);
1221 result
= ns_config_get(maps
, "ixfr-from-differences", &obj
);
1222 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1223 if (cfg_obj_isboolean(obj
))
1224 ixfrdiff
= cfg_obj_asboolean(obj
);
1225 else if (!strcasecmp(cfg_obj_asstring(obj
), "master") &&
1226 ztype
== dns_zone_master
)
1227 ixfrdiff
= ISC_TRUE
;
1228 else if (!strcasecmp(cfg_obj_asstring(obj
), "slave") &&
1229 ztype
== dns_zone_slave
)
1230 ixfrdiff
= ISC_TRUE
;
1232 ixfrdiff
= ISC_FALSE
;
1234 dns_zone_setoption(raw
, DNS_ZONEOPT_IXFRFROMDIFFS
,
1236 dns_zone_setoption(zone
, DNS_ZONEOPT_IXFRFROMDIFFS
,
1239 dns_zone_setoption(zone
, DNS_ZONEOPT_IXFRFROMDIFFS
,
1243 result
= ns_config_get(maps
, "request-ixfr", &obj
);
1244 INSIST(result
== ISC_R_SUCCESS
);
1245 dns_zone_setrequestixfr(zone
, cfg_obj_asboolean(obj
));
1247 checknames(ztype
, maps
, &obj
);
1248 INSIST(obj
!= NULL
);
1249 if (strcasecmp(cfg_obj_asstring(obj
), "warn") == 0) {
1252 } else if (strcasecmp(cfg_obj_asstring(obj
), "fail") == 0) {
1253 fail
= check
= ISC_TRUE
;
1254 } else if (strcasecmp(cfg_obj_asstring(obj
), "ignore") == 0) {
1255 fail
= check
= ISC_FALSE
;
1259 dns_zone_setoption(raw
, DNS_ZONEOPT_CHECKNAMES
,
1261 dns_zone_setoption(raw
, DNS_ZONEOPT_CHECKNAMESFAIL
,
1263 dns_zone_setoption(zone
, DNS_ZONEOPT_CHECKNAMES
,
1265 dns_zone_setoption(zone
, DNS_ZONEOPT_CHECKNAMESFAIL
,
1268 dns_zone_setoption(zone
, DNS_ZONEOPT_CHECKNAMES
,
1270 dns_zone_setoption(zone
, DNS_ZONEOPT_CHECKNAMESFAIL
,
1275 result
= ns_config_get(maps
, "notify-delay", &obj
);
1276 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1277 dns_zone_setnotifydelay(zone
, cfg_obj_asuint32(obj
));
1280 result
= ns_config_get(maps
, "check-sibling", &obj
);
1281 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1282 dns_zone_setoption(zone
, DNS_ZONEOPT_CHECKSIBLING
,
1283 cfg_obj_asboolean(obj
));
1286 result
= ns_config_get(maps
, "check-spf", &obj
);
1287 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1288 if (strcasecmp(cfg_obj_asstring(obj
), "warn") == 0) {
1290 } else if (strcasecmp(cfg_obj_asstring(obj
), "ignore") == 0) {
1294 dns_zone_setoption(zone
, DNS_ZONEOPT_CHECKSPF
, check
);
1297 result
= ns_config_get(maps
, "zero-no-soa-ttl", &obj
);
1298 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1299 dns_zone_setzeronosoattl(zone
, cfg_obj_asboolean(obj
));
1302 result
= ns_config_get(maps
, "nsec3-test-zone", &obj
);
1303 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1304 dns_zone_setoption(zone
, DNS_ZONEOPT_NSEC3TESTZONE
,
1305 cfg_obj_asboolean(obj
));
1306 } else if (ztype
== dns_zone_redirect
) {
1307 dns_zone_setnotifytype(zone
, dns_notifytype_no
);
1310 result
= ns_config_get(maps
, "max-journal-size", &obj
);
1311 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1312 dns_zone_setjournalsize(zone
, -1);
1313 if (cfg_obj_isstring(obj
)) {
1314 const char *str
= cfg_obj_asstring(obj
);
1315 INSIST(strcasecmp(str
, "unlimited") == 0);
1316 journal_size
= ISC_UINT32_MAX
/ 2;
1318 isc_resourcevalue_t value
;
1319 value
= cfg_obj_asuint64(obj
);
1320 if (value
> ISC_UINT32_MAX
/ 2) {
1321 cfg_obj_log(obj
, ns_g_lctx
,
1323 "'max-journal-size "
1324 "%" ISC_PRINT_QUADFORMAT
"d' "
1327 RETERR(ISC_R_RANGE
);
1329 journal_size
= (isc_uint32_t
)value
;
1331 dns_zone_setjournalsize(zone
, journal_size
);
1335 * Configure update-related options. These apply to
1336 * primary masters only.
1338 if (ztype
== dns_zone_master
) {
1339 dns_acl_t
*updateacl
;
1341 RETERR(configure_zone_acl(zconfig
, vconfig
, config
,
1342 allow_update
, ac
, mayberaw
,
1343 dns_zone_setupdateacl
,
1344 dns_zone_clearupdateacl
));
1346 updateacl
= dns_zone_getupdateacl(mayberaw
);
1347 if (updateacl
!= NULL
&& dns_acl_isinsecure(updateacl
))
1348 isc_log_write(ns_g_lctx
, DNS_LOGCATEGORY_SECURITY
,
1349 NS_LOGMODULE_SERVER
, ISC_LOG_WARNING
,
1350 "zone '%s' allows updates by IP "
1351 "address, which is insecure",
1354 RETERR(configure_zone_ssutable(zoptions
, mayberaw
, zname
));
1357 if (ztype
== dns_zone_master
|| raw
!= NULL
) {
1358 isc_boolean_t allow
= ISC_FALSE
, maint
= ISC_FALSE
;
1361 result
= ns_config_get(maps
, "sig-validity-interval", &obj
);
1362 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1364 const cfg_obj_t
*validity
, *resign
;
1366 validity
= cfg_tuple_get(obj
, "validity");
1367 seconds
= cfg_obj_asuint32(validity
) * 86400;
1368 dns_zone_setsigvalidityinterval(zone
, seconds
);
1370 resign
= cfg_tuple_get(obj
, "re-sign");
1371 if (cfg_obj_isvoid(resign
)) {
1374 if (seconds
> 7 * 86400)
1375 seconds
= cfg_obj_asuint32(resign
) *
1378 seconds
= cfg_obj_asuint32(resign
) *
1381 dns_zone_setsigresigninginterval(zone
, seconds
);
1385 result
= ns_config_get(maps
, "key-directory", &obj
);
1386 if (result
== ISC_R_SUCCESS
) {
1387 filename
= cfg_obj_asstring(obj
);
1388 RETERR(dns_zone_setkeydirectory(zone
, filename
));
1392 result
= ns_config_get(maps
, "sig-signing-signatures", &obj
);
1393 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1394 dns_zone_setsignatures(zone
, cfg_obj_asuint32(obj
));
1397 result
= ns_config_get(maps
, "sig-signing-nodes", &obj
);
1398 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1399 dns_zone_setnodes(zone
, cfg_obj_asuint32(obj
));
1402 result
= ns_config_get(maps
, "sig-signing-type", &obj
);
1403 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1404 dns_zone_setprivatetype(zone
, cfg_obj_asuint32(obj
));
1407 result
= ns_config_get(maps
, "update-check-ksk", &obj
);
1408 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1409 dns_zone_setoption(zone
, DNS_ZONEOPT_UPDATECHECKKSK
,
1410 cfg_obj_asboolean(obj
));
1413 result
= ns_config_get(maps
, "dnssec-dnskey-kskonly", &obj
);
1414 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1415 dns_zone_setoption(zone
, DNS_ZONEOPT_DNSKEYKSKONLY
,
1416 cfg_obj_asboolean(obj
));
1419 result
= ns_config_get(maps
, "dnssec-loadkeys-interval", &obj
);
1420 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1421 RETERR(dns_zone_setrefreshkeyinterval(zone
,
1422 cfg_obj_asuint32(obj
)));
1425 result
= cfg_map_get(zoptions
, "auto-dnssec", &obj
);
1426 if (result
== ISC_R_SUCCESS
) {
1427 const char *arg
= cfg_obj_asstring(obj
);
1428 if (strcasecmp(arg
, "allow") == 0)
1430 else if (strcasecmp(arg
, "maintain") == 0)
1431 allow
= maint
= ISC_TRUE
;
1432 else if (strcasecmp(arg
, "off") == 0)
1436 dns_zone_setkeyopt(zone
, DNS_ZONEKEY_ALLOW
, allow
);
1437 dns_zone_setkeyopt(zone
, DNS_ZONEKEY_MAINTAIN
, maint
);
1441 if (ztype
== dns_zone_slave
) {
1442 RETERR(configure_zone_acl(zconfig
, vconfig
, config
,
1443 allow_update_forwarding
, ac
,
1444 mayberaw
, dns_zone_setforwardacl
,
1445 dns_zone_clearforwardacl
));
1449 * Primary master functionality.
1451 if (ztype
== dns_zone_master
) {
1453 result
= ns_config_get(maps
, "check-wildcard", &obj
);
1454 if (result
== ISC_R_SUCCESS
)
1455 check
= cfg_obj_asboolean(obj
);
1458 dns_zone_setoption(mayberaw
, DNS_ZONEOPT_CHECKWILDCARD
, check
);
1461 * With map files, the default is ignore duplicate
1462 * records. With other master formats, the default is
1463 * taken from the global configuration.
1466 if (masterformat
!= dns_masterformat_map
) {
1467 result
= ns_config_get(maps
, "check-dup-records", &obj
);
1468 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1469 dupcheck
= cfg_obj_asstring(obj
);
1471 result
= ns_config_get(nodefault
, "check-dup-records",
1473 if (result
== ISC_R_SUCCESS
)
1474 dupcheck
= cfg_obj_asstring(obj
);
1476 dupcheck
= "ignore";
1479 if (strcasecmp(dupcheck
, "warn") == 0) {
1482 } else if (strcasecmp(dupcheck
, "fail") == 0) {
1483 fail
= check
= ISC_TRUE
;
1484 } else if (strcasecmp(dupcheck
, "ignore") == 0) {
1485 fail
= check
= ISC_FALSE
;
1488 dns_zone_setoption(mayberaw
, DNS_ZONEOPT_CHECKDUPRR
, check
);
1489 dns_zone_setoption(mayberaw
, DNS_ZONEOPT_CHECKDUPRRFAIL
, fail
);
1492 result
= ns_config_get(maps
, "check-mx", &obj
);
1493 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1494 if (strcasecmp(cfg_obj_asstring(obj
), "warn") == 0) {
1497 } else if (strcasecmp(cfg_obj_asstring(obj
), "fail") == 0) {
1498 fail
= check
= ISC_TRUE
;
1499 } else if (strcasecmp(cfg_obj_asstring(obj
), "ignore") == 0) {
1500 fail
= check
= ISC_FALSE
;
1503 dns_zone_setoption(mayberaw
, DNS_ZONEOPT_CHECKMX
, check
);
1504 dns_zone_setoption(mayberaw
, DNS_ZONEOPT_CHECKMXFAIL
, fail
);
1507 * With map files, the default is *not* to check
1508 * integrity. With other master formats, the default is
1509 * taken from the global configuration.
1512 if (masterformat
!= dns_masterformat_map
) {
1513 result
= ns_config_get(maps
, "check-integrity", &obj
);
1514 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1515 dns_zone_setoption(mayberaw
, DNS_ZONEOPT_CHECKINTEGRITY
,
1516 cfg_obj_asboolean(obj
));
1519 result
= ns_config_get(nodefault
, "check-integrity",
1521 if (result
== ISC_R_SUCCESS
)
1522 check
= cfg_obj_asboolean(obj
);
1523 dns_zone_setoption(mayberaw
, DNS_ZONEOPT_CHECKINTEGRITY
,
1528 result
= ns_config_get(maps
, "check-mx-cname", &obj
);
1529 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1530 if (strcasecmp(cfg_obj_asstring(obj
), "warn") == 0) {
1533 } else if (strcasecmp(cfg_obj_asstring(obj
), "fail") == 0) {
1534 warn
= ignore
= ISC_FALSE
;
1535 } else if (strcasecmp(cfg_obj_asstring(obj
), "ignore") == 0) {
1536 warn
= ignore
= ISC_TRUE
;
1539 dns_zone_setoption(mayberaw
, DNS_ZONEOPT_WARNMXCNAME
, warn
);
1540 dns_zone_setoption(mayberaw
, DNS_ZONEOPT_IGNOREMXCNAME
, ignore
);
1543 result
= ns_config_get(maps
, "check-srv-cname", &obj
);
1544 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1545 if (strcasecmp(cfg_obj_asstring(obj
), "warn") == 0) {
1548 } else if (strcasecmp(cfg_obj_asstring(obj
), "fail") == 0) {
1549 warn
= ignore
= ISC_FALSE
;
1550 } else if (strcasecmp(cfg_obj_asstring(obj
), "ignore") == 0) {
1551 warn
= ignore
= ISC_TRUE
;
1554 dns_zone_setoption(mayberaw
, DNS_ZONEOPT_WARNSRVCNAME
, warn
);
1555 dns_zone_setoption(mayberaw
, DNS_ZONEOPT_IGNORESRVCNAME
,
1559 result
= ns_config_get(maps
, "dnssec-secure-to-insecure", &obj
);
1560 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1561 dns_zone_setoption(mayberaw
, DNS_ZONEOPT_SECURETOINSECURE
,
1562 cfg_obj_asboolean(obj
));
1565 result
= cfg_map_get(zoptions
, "dnssec-update-mode", &obj
);
1566 if (result
== ISC_R_SUCCESS
) {
1567 const char *arg
= cfg_obj_asstring(obj
);
1568 if (strcasecmp(arg
, "no-resign") == 0)
1569 dns_zone_setkeyopt(zone
, DNS_ZONEKEY_NORESIGN
,
1571 else if (strcasecmp(arg
, "maintain") == 0)
1578 result
= ns_config_get(maps
, "serial-update-method", &obj
);
1579 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1580 if (strcasecmp(cfg_obj_asstring(obj
), "unixtime") == 0)
1581 dns_zone_setserialupdatemethod(zone
,
1582 dns_updatemethod_unixtime
);
1584 dns_zone_setserialupdatemethod(zone
,
1585 dns_updatemethod_increment
);
1589 * Configure slave functionality.
1592 case dns_zone_slave
:
1594 case dns_zone_redirect
:
1597 (void)cfg_map_get(zoptions
, "masters", &obj
);
1602 RETERR(ns_config_getipandkeylist(config
, obj
, mctx
,
1604 &keynames
, &count
));
1605 result
= dns_zone_setmasterswithkeys(mayberaw
, addrs
,
1608 ns_config_putipandkeylist(mctx
, &addrs
, &dscps
,
1611 INSIST(addrs
== NULL
&& keynames
== NULL
);
1613 result
= dns_zone_setmasters(mayberaw
, NULL
, 0);
1619 result
= ns_config_get(maps
, "multi-master", &obj
);
1620 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1621 multi
= cfg_obj_asboolean(obj
);
1623 dns_zone_setoption(mayberaw
, DNS_ZONEOPT_MULTIMASTER
, multi
);
1626 result
= ns_config_get(maps
, "max-transfer-time-in", &obj
);
1627 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1628 dns_zone_setmaxxfrin(mayberaw
, cfg_obj_asuint32(obj
) * 60);
1631 result
= ns_config_get(maps
, "max-transfer-idle-in", &obj
);
1632 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1633 dns_zone_setidlein(mayberaw
, cfg_obj_asuint32(obj
) * 60);
1636 result
= ns_config_get(maps
, "max-refresh-time", &obj
);
1637 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1638 dns_zone_setmaxrefreshtime(mayberaw
, cfg_obj_asuint32(obj
));
1641 result
= ns_config_get(maps
, "min-refresh-time", &obj
);
1642 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1643 dns_zone_setminrefreshtime(mayberaw
, cfg_obj_asuint32(obj
));
1646 result
= ns_config_get(maps
, "max-retry-time", &obj
);
1647 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1648 dns_zone_setmaxretrytime(mayberaw
, cfg_obj_asuint32(obj
));
1651 result
= ns_config_get(maps
, "min-retry-time", &obj
);
1652 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1653 dns_zone_setminretrytime(mayberaw
, cfg_obj_asuint32(obj
));
1656 result
= ns_config_get(maps
, "transfer-source", &obj
);
1657 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1658 RETERR(dns_zone_setxfrsource4(mayberaw
,
1659 cfg_obj_assockaddr(obj
)));
1660 dscp
= cfg_obj_getdscp(obj
);
1663 RETERR(dns_zone_setxfrsource4dscp(mayberaw
, dscp
));
1664 ns_add_reserved_dispatch(ns_g_server
, cfg_obj_assockaddr(obj
));
1667 result
= ns_config_get(maps
, "transfer-source-v6", &obj
);
1668 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1669 RETERR(dns_zone_setxfrsource6(mayberaw
,
1670 cfg_obj_assockaddr(obj
)));
1671 dscp
= cfg_obj_getdscp(obj
);
1674 RETERR(dns_zone_setxfrsource6dscp(mayberaw
, dscp
));
1675 ns_add_reserved_dispatch(ns_g_server
, cfg_obj_assockaddr(obj
));
1678 result
= ns_config_get(maps
, "alt-transfer-source", &obj
);
1679 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1680 RETERR(dns_zone_setaltxfrsource4(mayberaw
,
1681 cfg_obj_assockaddr(obj
)));
1682 dscp
= cfg_obj_getdscp(obj
);
1685 RETERR(dns_zone_setaltxfrsource4dscp(mayberaw
, dscp
));
1688 result
= ns_config_get(maps
, "alt-transfer-source-v6", &obj
);
1689 INSIST(result
== ISC_R_SUCCESS
&& obj
!= NULL
);
1690 RETERR(dns_zone_setaltxfrsource6(mayberaw
,
1691 cfg_obj_assockaddr(obj
)));
1692 dscp
= cfg_obj_getdscp(obj
);
1695 RETERR(dns_zone_setaltxfrsource6dscp(mayberaw
, dscp
));
1698 (void)ns_config_get(maps
, "use-alt-transfer-source", &obj
);
1701 * Default off when views are in use otherwise
1702 * on for BIND 8 compatibility.
1704 view
= dns_zone_getview(zone
);
1705 if (view
!= NULL
&& strcmp(view
->name
, "_default") == 0)
1710 alt
= cfg_obj_asboolean(obj
);
1711 dns_zone_setoption(mayberaw
, DNS_ZONEOPT_USEALTXFRSRC
, alt
);
1714 (void)ns_config_get(maps
, "try-tcp-refresh", &obj
);
1715 dns_zone_setoption(mayberaw
, DNS_ZONEOPT_TRYTCPREFRESH
,
1716 cfg_obj_asboolean(obj
));
1719 case dns_zone_staticstub
:
1720 RETERR(configure_staticstub(zoptions
, zone
, zname
,
1728 return (ISC_R_SUCCESS
);
1733 * Set up a DLZ zone as writeable
1736 ns_zone_configure_writeable_dlz(dns_dlzdb_t
*dlzdatabase
, dns_zone_t
*zone
,
1737 dns_rdataclass_t rdclass
, dns_name_t
*name
)
1739 dns_db_t
*db
= NULL
;
1741 isc_result_t result
;
1745 dns_zone_settype(zone
, dns_zone_dlz
);
1746 result
= dns_sdlz_setdb(dlzdatabase
, rdclass
, name
, &db
);
1747 if (result
!= ISC_R_SUCCESS
)
1749 result
= dns_zone_dlzpostload(zone
, db
);
1755 ns_zone_reusable(dns_zone_t
*zone
, const cfg_obj_t
*zconfig
) {
1756 const cfg_obj_t
*zoptions
= NULL
;
1757 const cfg_obj_t
*obj
= NULL
;
1758 const char *cfilename
;
1759 const char *zfilename
;
1760 dns_zone_t
*raw
= NULL
;
1761 isc_boolean_t has_raw
;
1762 dns_zonetype_t ztype
;
1764 zoptions
= cfg_tuple_get(zconfig
, "options");
1767 * We always reconfigure a static-stub zone for simplicity, assuming
1768 * the amount of data to be loaded is small.
1770 if (zonetype_fromconfig(zoptions
) == dns_zone_staticstub
) {
1771 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1772 "not reusable: staticstub");
1776 /* If there's a raw zone, use that for filename and type comparison */
1777 dns_zone_getraw(zone
, &raw
);
1779 zfilename
= dns_zone_getfile(raw
);
1780 ztype
= dns_zone_gettype(raw
);
1781 dns_zone_detach(&raw
);
1784 zfilename
= dns_zone_getfile(zone
);
1785 ztype
= dns_zone_gettype(zone
);
1786 has_raw
= ISC_FALSE
;
1790 (void)cfg_map_get(zoptions
, "inline-signing", &obj
);
1791 if ((obj
== NULL
|| !cfg_obj_asboolean(obj
)) && has_raw
) {
1792 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1793 "not reusable: old zone was inline-signing");
1795 } else if ((obj
!= NULL
&& cfg_obj_asboolean(obj
)) && !has_raw
) {
1796 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1797 "not reusable: old zone was not inline-signing");
1801 if (zonetype_fromconfig(zoptions
) != ztype
) {
1802 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1803 "not reusable: type mismatch");
1808 (void)cfg_map_get(zoptions
, "file", &obj
);
1810 cfilename
= cfg_obj_asstring(obj
);
1813 if (!((cfilename
== NULL
&& zfilename
== NULL
) ||
1814 (cfilename
!= NULL
&& zfilename
!= NULL
&&
1815 strcmp(cfilename
, zfilename
) == 0)))
1817 dns_zone_log(zone
, ISC_LOG_DEBUG(1),
1818 "not reusable: filename mismatch");