2 * Copyright (C) 2004-2014 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.
24 #include <isc/buffer.h>
27 #include <isc/print.h>
28 #include <isc/stats.h>
29 #include <isc/string.h> /* Required for HP/UX (and others?) */
34 #include <dns/fixedname.h>
37 #include <dns/rdata.h>
38 #include <dns/rdatatype.h>
39 #include <dns/rdataset.h>
40 #include <dns/rdatalist.h>
41 #include <dns/result.h>
44 #include <dns/stats.h>
48 #include <named/client.h>
49 #include <named/config.h>
50 #include <named/globals.h>
51 #include <named/log.h>
52 #include <named/server.h>
53 #include <named/zoneconf.h>
55 /* ACLs associated with zone */
62 allow_update_forwarding
65 #define RETERR(x) do { \
66 isc_result_t _r = (x); \
67 if (_r != ISC_R_SUCCESS) \
71 #define CHECK(x) do { \
73 if (result != ISC_R_SUCCESS) \
78 * Convenience function for configuring a single zone ACL.
81 configure_zone_acl(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig,
82 const cfg_obj_t *config, acl_type_t acltype,
83 cfg_aclconfctx_t *actx, dns_zone_t *zone,
84 void (*setzacl)(dns_zone_t *, dns_acl_t *),
85 void (*clearzacl)(dns_zone_t *))
88 const cfg_obj_t *maps[5] = {NULL, NULL, NULL, NULL, NULL};
89 const cfg_obj_t *aclobj = NULL;
91 dns_acl_t **aclp = NULL, *acl = NULL;
95 view = dns_zone_getview(zone);
100 aclp = &view->notifyacl;
101 aclname = "allow-notify";
105 aclp = &view->queryacl;
106 aclname = "allow-query";
110 aclp = &view->queryonacl;
111 aclname = "allow-query-on";
115 aclp = &view->transferacl;
116 aclname = "allow-transfer";
120 aclp = &view->updateacl;
121 aclname = "allow-update";
123 case allow_update_forwarding:
125 aclp = &view->upfwdacl;
126 aclname = "allow-update-forwarding";
130 return (ISC_R_FAILURE);
133 /* First check to see if ACL is defined within the zone */
134 if (zconfig != NULL) {
135 maps[0] = cfg_tuple_get(zconfig, "options");
136 (void)ns_config_get(maps, aclname, &aclobj);
137 if (aclobj != NULL) {
143 /* Failing that, see if there's a default ACL already in the view */
144 if (aclp != NULL && *aclp != NULL) {
145 (*setzacl)(zone, *aclp);
146 return (ISC_R_SUCCESS);
149 /* Check for default ACLs that haven't been parsed yet */
150 if (vconfig != NULL) {
151 const cfg_obj_t *options = cfg_tuple_get(vconfig, "options");
155 if (config != NULL) {
156 const cfg_obj_t *options = NULL;
157 (void)cfg_map_get(config, "options", &options);
161 maps[i++] = ns_g_defaults;
164 (void)ns_config_get(maps, aclname, &aclobj);
165 if (aclobj == NULL) {
167 return (ISC_R_SUCCESS);
171 result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx, actx,
172 dns_zone_getmctx(zone), 0, &acl);
173 if (result != ISC_R_SUCCESS)
175 (*setzacl)(zone, acl);
177 /* Set the view default now */
179 dns_acl_attach(acl, aclp);
181 dns_acl_detach(&acl);
182 return (ISC_R_SUCCESS);
186 * Parse the zone update-policy statement.
189 configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
192 const cfg_obj_t *updatepolicy = NULL;
193 const cfg_listelt_t *element, *element2;
194 dns_ssutable_t *table = NULL;
195 isc_mem_t *mctx = dns_zone_getmctx(zone);
196 isc_boolean_t autoddns = ISC_FALSE;
199 (void)cfg_map_get(zconfig, "update-policy", &updatepolicy);
201 if (updatepolicy == NULL) {
202 dns_zone_setssutable(zone, NULL);
203 return (ISC_R_SUCCESS);
206 if (cfg_obj_isstring(updatepolicy) &&
207 strcmp("local", cfg_obj_asstring(updatepolicy)) == 0) {
212 result = dns_ssutable_create(mctx, &table);
213 if (result != ISC_R_SUCCESS)
216 for (element = cfg_list_first(updatepolicy);
218 element = cfg_list_next(element))
220 const cfg_obj_t *stmt = cfg_listelt_value(element);
221 const cfg_obj_t *mode = cfg_tuple_get(stmt, "mode");
222 const cfg_obj_t *identity = cfg_tuple_get(stmt, "identity");
223 const cfg_obj_t *matchtype = cfg_tuple_get(stmt, "matchtype");
224 const cfg_obj_t *dname = cfg_tuple_get(stmt, "name");
225 const cfg_obj_t *typelist = cfg_tuple_get(stmt, "types");
227 isc_boolean_t grant = ISC_FALSE;
228 isc_boolean_t usezone = ISC_FALSE;
229 unsigned int mtype = DNS_SSUMATCHTYPE_NAME;
230 dns_fixedname_t fname, fident;
232 dns_rdatatype_t *types;
235 str = cfg_obj_asstring(mode);
236 if (strcasecmp(str, "grant") == 0)
238 else if (strcasecmp(str, "deny") == 0)
243 str = cfg_obj_asstring(matchtype);
244 if (strcasecmp(str, "name") == 0)
245 mtype = DNS_SSUMATCHTYPE_NAME;
246 else if (strcasecmp(str, "subdomain") == 0)
247 mtype = DNS_SSUMATCHTYPE_SUBDOMAIN;
248 else if (strcasecmp(str, "wildcard") == 0)
249 mtype = DNS_SSUMATCHTYPE_WILDCARD;
250 else if (strcasecmp(str, "self") == 0)
251 mtype = DNS_SSUMATCHTYPE_SELF;
252 else if (strcasecmp(str, "selfsub") == 0)
253 mtype = DNS_SSUMATCHTYPE_SELFSUB;
254 else if (strcasecmp(str, "selfwild") == 0)
255 mtype = DNS_SSUMATCHTYPE_SELFWILD;
256 else if (strcasecmp(str, "ms-self") == 0)
257 mtype = DNS_SSUMATCHTYPE_SELFMS;
258 else if (strcasecmp(str, "krb5-self") == 0)
259 mtype = DNS_SSUMATCHTYPE_SELFKRB5;
260 else if (strcasecmp(str, "ms-subdomain") == 0)
261 mtype = DNS_SSUMATCHTYPE_SUBDOMAINMS;
262 else if (strcasecmp(str, "krb5-subdomain") == 0)
263 mtype = DNS_SSUMATCHTYPE_SUBDOMAINKRB5;
264 else if (strcasecmp(str, "tcp-self") == 0)
265 mtype = DNS_SSUMATCHTYPE_TCPSELF;
266 else if (strcasecmp(str, "6to4-self") == 0)
267 mtype = DNS_SSUMATCHTYPE_6TO4SELF;
268 else if (strcasecmp(str, "zonesub") == 0) {
269 mtype = DNS_SSUMATCHTYPE_SUBDOMAIN;
271 } else if (strcasecmp(str, "external") == 0)
272 mtype = DNS_SSUMATCHTYPE_EXTERNAL;
276 dns_fixedname_init(&fident);
277 str = cfg_obj_asstring(identity);
278 isc_buffer_constinit(&b, str, strlen(str));
279 isc_buffer_add(&b, strlen(str));
280 result = dns_name_fromtext(dns_fixedname_name(&fident), &b,
281 dns_rootname, 0, NULL);
282 if (result != ISC_R_SUCCESS) {
283 cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
284 "'%s' is not a valid name", str);
288 dns_fixedname_init(&fname);
290 result = dns_name_copy(dns_zone_getorigin(zone),
291 dns_fixedname_name(&fname),
293 if (result != ISC_R_SUCCESS) {
294 cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
295 "error copying origin: %s",
296 isc_result_totext(result));
300 str = cfg_obj_asstring(dname);
301 isc_buffer_constinit(&b, str, strlen(str));
302 isc_buffer_add(&b, strlen(str));
303 result = dns_name_fromtext(dns_fixedname_name(&fname),
304 &b, dns_rootname, 0, NULL);
305 if (result != ISC_R_SUCCESS) {
306 cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
307 "'%s' is not a valid name", str);
312 n = ns_config_listcount(typelist);
316 types = isc_mem_get(mctx, n * sizeof(dns_rdatatype_t));
318 result = ISC_R_NOMEMORY;
324 for (element2 = cfg_list_first(typelist);
326 element2 = cfg_list_next(element2))
328 const cfg_obj_t *typeobj;
333 typeobj = cfg_listelt_value(element2);
334 str = cfg_obj_asstring(typeobj);
335 DE_CONST(str, r.base);
336 r.length = strlen(str);
338 result = dns_rdatatype_fromtext(&types[i++], &r);
339 if (result != ISC_R_SUCCESS) {
340 cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
341 "'%s' is not a valid type", str);
342 isc_mem_put(mctx, types,
343 n * sizeof(dns_rdatatype_t));
349 result = dns_ssutable_addrule(table, grant,
350 dns_fixedname_name(&fident),
352 dns_fixedname_name(&fname),
355 isc_mem_put(mctx, types, n * sizeof(dns_rdatatype_t));
356 if (result != ISC_R_SUCCESS) {
362 * If "update-policy local;" and a session key exists,
363 * then use the default policy, which is equivalent to:
364 * update-policy { grant <session-keyname> zonesub any; };
367 dns_rdatatype_t any = dns_rdatatype_any;
369 if (ns_g_server->session_keyname == NULL) {
370 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
371 NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
372 "failed to enable auto DDNS policy "
373 "for zone %s: session key not found",
375 result = ISC_R_NOTFOUND;
379 result = dns_ssutable_addrule(table, ISC_TRUE,
380 ns_g_server->session_keyname,
381 DNS_SSUMATCHTYPE_SUBDOMAIN,
382 dns_zone_getorigin(zone),
385 if (result != ISC_R_SUCCESS)
389 result = ISC_R_SUCCESS;
390 dns_zone_setssutable(zone, table);
393 dns_ssutable_detach(&table);
398 * This is the TTL used for internally generated RRsets for static-stub zones.
399 * The value doesn't matter because the mapping is static, but needs to be
400 * defined for the sake of implementation.
402 #define STATICSTUB_SERVER_TTL 86400
405 * Configure an apex NS with glues for a static-stub zone.
406 * For example, for the zone named "example.com", the following RRs will be
407 * added to the zone DB:
408 * example.com. NS example.com.
409 * example.com. A 192.0.2.1
410 * example.com. AAAA 2001:db8::1
413 configure_staticstub_serveraddrs(const cfg_obj_t *zconfig, dns_zone_t *zone,
414 dns_rdatalist_t *rdatalist_ns,
415 dns_rdatalist_t *rdatalist_a,
416 dns_rdatalist_t *rdatalist_aaaa)
418 const cfg_listelt_t *element;
419 isc_mem_t *mctx = dns_zone_getmctx(zone);
420 isc_region_t region, sregion;
422 isc_result_t result = ISC_R_SUCCESS;
424 for (element = cfg_list_first(zconfig);
426 element = cfg_list_next(element))
428 const isc_sockaddr_t* sa;
430 const cfg_obj_t *address = cfg_listelt_value(element);
431 dns_rdatalist_t *rdatalist;
433 sa = cfg_obj_assockaddr(address);
434 if (isc_sockaddr_getport(sa) != 0) {
435 cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
436 "port is not configurable for "
437 "static stub server-addresses");
438 return (ISC_R_FAILURE);
440 isc_netaddr_fromsockaddr(&na, sa);
441 if (isc_netaddr_getzone(&na) != 0) {
442 cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
443 "scoped address is not allowed "
446 return (ISC_R_FAILURE);
451 region.length = sizeof(na.type.in);
452 rdatalist = rdatalist_a;
455 INSIST(na.family == AF_INET6);
456 region.length = sizeof(na.type.in6);
457 rdatalist = rdatalist_aaaa;
461 rdata = isc_mem_get(mctx, sizeof(*rdata) + region.length);
463 return (ISC_R_NOMEMORY);
464 region.base = (unsigned char *)(rdata + 1);
465 memmove(region.base, &na.type, region.length);
466 dns_rdata_init(rdata);
467 dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
468 rdatalist->type, ®ion);
469 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
473 * If no address is specified (unlikely in this context, but possible),
474 * there's nothing to do anymore.
476 if (ISC_LIST_EMPTY(rdatalist_a->rdata) &&
477 ISC_LIST_EMPTY(rdatalist_aaaa->rdata)) {
478 return (ISC_R_SUCCESS);
481 /* Add to the list an apex NS with the ns name being the origin name */
482 dns_name_toregion(dns_zone_getorigin(zone), &sregion);
483 rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length);
486 * Already allocated data will be freed in the caller, so
487 * we can simply return here.
489 return (ISC_R_NOMEMORY);
491 region.length = sregion.length;
492 region.base = (unsigned char *)(rdata + 1);
493 memmove(region.base, sregion.base, region.length);
494 dns_rdata_init(rdata);
495 dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
496 dns_rdatatype_ns, ®ion);
497 ISC_LIST_APPEND(rdatalist_ns->rdata, rdata, link);
503 * Configure an apex NS with an out-of-zone NS names for a static-stub zone.
504 * For example, for the zone named "example.com", something like the following
505 * RRs will be added to the zone DB:
506 * example.com. NS ns.example.net.
509 configure_staticstub_servernames(const cfg_obj_t *zconfig, dns_zone_t *zone,
510 dns_rdatalist_t *rdatalist, const char *zname)
512 const cfg_listelt_t *element;
513 isc_mem_t *mctx = dns_zone_getmctx(zone);
515 isc_region_t sregion, region;
516 isc_result_t result = ISC_R_SUCCESS;
518 for (element = cfg_list_first(zconfig);
520 element = cfg_list_next(element))
522 const cfg_obj_t *obj;
524 dns_fixedname_t fixed_name;
528 obj = cfg_listelt_value(element);
529 str = cfg_obj_asstring(obj);
531 dns_fixedname_init(&fixed_name);
532 nsname = dns_fixedname_name(&fixed_name);
534 isc_buffer_constinit(&b, str, strlen(str));
535 isc_buffer_add(&b, strlen(str));
536 result = dns_name_fromtext(nsname, &b, dns_rootname, 0, NULL);
537 if (result != ISC_R_SUCCESS) {
538 cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
539 "server-name '%s' is not a valid "
543 if (dns_name_issubdomain(nsname, dns_zone_getorigin(zone))) {
544 cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
545 "server-name '%s' must not be a "
546 "subdomain of zone name '%s'",
548 return (ISC_R_FAILURE);
551 dns_name_toregion(nsname, &sregion);
552 rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length);
554 return (ISC_R_NOMEMORY);
555 region.length = sregion.length;
556 region.base = (unsigned char *)(rdata + 1);
557 memmove(region.base, sregion.base, region.length);
558 dns_rdata_init(rdata);
559 dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
560 dns_rdatatype_ns, ®ion);
561 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
568 * Configure static-stub zone.
571 configure_staticstub(const cfg_obj_t *zconfig, dns_zone_t *zone,
572 const char *zname, const char *dbtype)
575 const cfg_obj_t *obj;
576 isc_mem_t *mctx = dns_zone_getmctx(zone);
578 dns_dbversion_t *dbversion = NULL;
579 dns_dbnode_t *apexnode = NULL;
582 dns_rdataset_t rdataset;
583 dns_rdatalist_t rdatalist_ns, rdatalist_a, rdatalist_aaaa;
584 dns_rdatalist_t* rdatalists[] = {
585 &rdatalist_ns, &rdatalist_a, &rdatalist_aaaa, NULL
590 /* Create the DB beforehand */
591 RETERR(dns_db_create(mctx, dbtype, dns_zone_getorigin(zone),
592 dns_dbtype_stub, dns_zone_getclass(zone),
594 dns_zone_setdb(zone, db);
596 dns_rdatalist_init(&rdatalist_ns);
597 rdatalist_ns.rdclass = dns_zone_getclass(zone);
598 rdatalist_ns.type = dns_rdatatype_ns;
599 rdatalist_ns.ttl = STATICSTUB_SERVER_TTL;
601 dns_rdatalist_init(&rdatalist_a);
602 rdatalist_a.rdclass = dns_zone_getclass(zone);
603 rdatalist_a.type = dns_rdatatype_a;
604 rdatalist_a.ttl = STATICSTUB_SERVER_TTL;
606 dns_rdatalist_init(&rdatalist_aaaa);
607 rdatalist_aaaa.rdclass = dns_zone_getclass(zone);
608 rdatalist_aaaa.type = dns_rdatatype_aaaa;
609 rdatalist_aaaa.ttl = STATICSTUB_SERVER_TTL;
611 /* Prepare zone RRs from the configuration */
613 result = cfg_map_get(zconfig, "server-addresses", &obj);
614 if (result == ISC_R_SUCCESS) {
616 result = configure_staticstub_serveraddrs(obj, zone,
620 if (result != ISC_R_SUCCESS)
625 result = cfg_map_get(zconfig, "server-names", &obj);
626 if (result == ISC_R_SUCCESS) {
628 result = configure_staticstub_servernames(obj, zone,
631 if (result != ISC_R_SUCCESS)
636 * Sanity check: there should be at least one NS RR at the zone apex
637 * to trigger delegation.
639 if (ISC_LIST_EMPTY(rdatalist_ns.rdata)) {
640 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
641 NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
642 "No NS record is configured for a "
643 "static-stub zone '%s'", zname);
644 result = ISC_R_FAILURE;
649 * Now add NS and glue A/AAAA RRsets to the zone DB.
650 * First open a new version for the add operation and get a pointer
651 * to the apex node (all RRs are of the apex name).
653 result = dns_db_newversion(db, &dbversion);
654 if (result != ISC_R_SUCCESS)
656 dns_name_init(&apexname, NULL);
657 dns_name_clone(dns_zone_getorigin(zone), &apexname);
658 result = dns_db_findnode(db, &apexname, ISC_FALSE, &apexnode);
659 if (result != ISC_R_SUCCESS)
663 dns_rdataset_init(&rdataset);
664 RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_ns, &rdataset)
666 result = dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset,
668 dns_rdataset_disassociate(&rdataset);
669 if (result != ISC_R_SUCCESS)
672 /* Add glue A RRset, if any */
673 if (!ISC_LIST_EMPTY(rdatalist_a.rdata)) {
674 RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_a, &rdataset)
676 result = dns_db_addrdataset(db, apexnode, dbversion, 0,
678 dns_rdataset_disassociate(&rdataset);
679 if (result != ISC_R_SUCCESS)
683 /* Add glue AAAA RRset, if any */
684 if (!ISC_LIST_EMPTY(rdatalist_aaaa.rdata)) {
685 RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_aaaa,
688 result = dns_db_addrdataset(db, apexnode, dbversion, 0,
690 dns_rdataset_disassociate(&rdataset);
691 if (result != ISC_R_SUCCESS)
695 result = ISC_R_SUCCESS;
698 if (apexnode != NULL)
699 dns_db_detachnode(db, &apexnode);
700 if (dbversion != NULL)
701 dns_db_closeversion(db, &dbversion, ISC_TRUE);
704 for (i = 0; rdatalists[i] != NULL; i++) {
705 while ((rdata = ISC_LIST_HEAD(rdatalists[i]->rdata)) != NULL) {
706 ISC_LIST_UNLINK(rdatalists[i]->rdata, rdata, link);
707 dns_rdata_toregion(rdata, ®ion);
708 isc_mem_put(mctx, rdata,
709 sizeof(*rdata) + region.length);
717 * Convert a config file zone type into a server zone type.
719 static inline dns_zonetype_t
720 zonetype_fromconfig(const cfg_obj_t *map) {
721 const cfg_obj_t *obj = NULL;
724 result = cfg_map_get(map, "type", &obj);
725 INSIST(result == ISC_R_SUCCESS && obj != NULL);
726 return (ns_config_getzonetype(obj));
730 * Helper function for strtoargv(). Pardon the gratuitous recursion.
733 strtoargvsub(isc_mem_t *mctx, char *s, unsigned int *argcp,
734 char ***argvp, unsigned int n)
738 /* Discard leading whitespace. */
739 while (*s == ' ' || *s == '\t')
743 /* We have reached the end of the string. */
745 *argvp = isc_mem_get(mctx, n * sizeof(char *));
747 return (ISC_R_NOMEMORY);
750 while (*p != ' ' && *p != '\t' && *p != '\0')
755 result = strtoargvsub(mctx, p, argcp, argvp, n + 1);
756 if (result != ISC_R_SUCCESS)
760 return (ISC_R_SUCCESS);
764 * Tokenize the string "s" into whitespace-separated words,
765 * return the number of words in '*argcp' and an array
766 * of pointers to the words in '*argvp'. The caller
767 * must free the array using isc_mem_put(). The string
768 * is modified in-place.
771 strtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp) {
772 return (strtoargvsub(mctx, s, argcp, argvp, 0));
776 checknames(dns_zonetype_t ztype, const cfg_obj_t **maps,
777 const cfg_obj_t **objp)
779 const char *zone = NULL;
783 case dns_zone_slave: zone = "slave"; break;
784 case dns_zone_master: zone = "master"; break;
788 result = ns_checknames_get(maps, zone, objp);
789 INSIST(result == ISC_R_SUCCESS && objp != NULL && *objp != NULL);
793 ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
794 const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac,
795 dns_zone_t *zone, dns_zone_t *raw)
799 dns_rdataclass_t zclass;
800 dns_rdataclass_t vclass;
801 const cfg_obj_t *maps[5];
802 const cfg_obj_t *zoptions = NULL;
803 const cfg_obj_t *options = NULL;
804 const cfg_obj_t *obj;
805 const char *filename = NULL;
806 dns_notifytype_t notifytype = dns_notifytype_yes;
807 isc_sockaddr_t *addrs;
808 dns_name_t **keynames;
813 static char default_dbtype[] = "rbt";
814 isc_mem_t *mctx = dns_zone_getmctx(zone);
815 dns_dialuptype_t dialup = dns_dialuptype_no;
816 dns_zonetype_t ztype;
818 isc_int32_t journal_size;
822 isc_boolean_t check = ISC_FALSE, fail = ISC_FALSE;
823 isc_boolean_t warn = ISC_FALSE, ignore = ISC_FALSE;
824 isc_boolean_t ixfrdiff;
825 dns_masterformat_t masterformat;
826 isc_stats_t *zoneqrystats;
828 dns_stats_t *rcvquerystats;
830 dns_zonestat_level_t statlevel;
832 dns_zone_t *mayberaw = (raw != NULL) ? raw : zone;
835 if (zconfig != NULL) {
836 zoptions = cfg_tuple_get(zconfig, "options");
837 maps[i++] = zoptions;
840 maps[i++] = cfg_tuple_get(vconfig, "options");
841 if (config != NULL) {
842 (void)cfg_map_get(config, "options", &options);
846 maps[i++] = ns_g_defaults;
850 RETERR(ns_config_getclass(cfg_tuple_get(vconfig, "class"),
851 dns_rdataclass_in, &vclass));
853 vclass = dns_rdataclass_in;
856 * Configure values common to all zone types.
859 zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
861 RETERR(ns_config_getclass(cfg_tuple_get(zconfig, "class"),
863 dns_zone_setclass(zone, zclass);
865 dns_zone_setclass(raw, zclass);
867 ztype = zonetype_fromconfig(zoptions);
869 dns_zone_settype(raw, ztype);
870 dns_zone_settype(zone, dns_zone_master);
872 dns_zone_settype(zone, ztype);
876 result = cfg_map_get(zoptions, "database", &obj);
877 if (result == ISC_R_SUCCESS)
878 cpval = isc_mem_strdup(mctx, cfg_obj_asstring(obj));
880 cpval = default_dbtype;
883 return(ISC_R_NOMEMORY);
885 result = strtoargv(mctx, cpval, &dbargc, &dbargv);
886 if (result != ISC_R_SUCCESS && cpval != default_dbtype) {
887 isc_mem_free(mctx, cpval);
892 * ANSI C is strange here. There is no logical reason why (char **)
893 * cannot be promoted automatically to (const char * const *) by the
894 * compiler w/o generating a warning.
896 result = dns_zone_setdbtype(zone, dbargc, (const char * const *)dbargv);
897 isc_mem_put(mctx, dbargv, dbargc * sizeof(*dbargv));
898 if (cpval != default_dbtype)
899 isc_mem_free(mctx, cpval);
900 if (result != ISC_R_SUCCESS)
904 result = cfg_map_get(zoptions, "file", &obj);
905 if (result == ISC_R_SUCCESS)
906 filename = cfg_obj_asstring(obj);
909 * Unless we're using some alternative database, a master zone
910 * will be needing a master file.
912 if (ztype == dns_zone_master && cpval == default_dbtype &&
914 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
915 NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
916 "zone '%s': 'file' not specified",
918 return (ISC_R_FAILURE);
921 if (ztype == dns_zone_slave)
922 masterformat = dns_masterformat_raw;
924 masterformat = dns_masterformat_text;
926 result= ns_config_get(maps, "masterfile-format", &obj);
927 if (result == ISC_R_SUCCESS) {
928 const char *masterformatstr = cfg_obj_asstring(obj);
930 if (strcasecmp(masterformatstr, "text") == 0)
931 masterformat = dns_masterformat_text;
932 else if (strcasecmp(masterformatstr, "raw") == 0)
933 masterformat = dns_masterformat_raw;
938 if (raw != NULL && filename != NULL) {
939 #define SIGNED ".signed"
940 size_t signedlen = strlen(filename) + sizeof(SIGNED);
943 RETERR(dns_zone_setfile2(raw, filename, masterformat));
944 signedname = isc_mem_get(mctx, signedlen);
945 if (signedname == NULL)
946 return (ISC_R_NOMEMORY);
948 (void)snprintf(signedname, signedlen, "%s" SIGNED, filename);
949 result = dns_zone_setfile2(zone, signedname,
950 dns_masterformat_raw);
951 isc_mem_put(mctx, signedname, signedlen);
952 if (result != ISC_R_SUCCESS)
955 RETERR(dns_zone_setfile2(zone, filename, masterformat));
958 result = cfg_map_get(zoptions, "journal", &obj);
959 if (result == ISC_R_SUCCESS)
960 RETERR(dns_zone_setjournal(mayberaw, cfg_obj_asstring(obj)));
963 * Notify messages are processed by the raw zone if it exists.
965 if (ztype == dns_zone_slave)
966 RETERR(configure_zone_acl(zconfig, vconfig, config,
967 allow_notify, ac, mayberaw,
968 dns_zone_setnotifyacl,
969 dns_zone_clearnotifyacl));
972 * XXXAG This probably does not make sense for stubs.
974 RETERR(configure_zone_acl(zconfig, vconfig, config,
975 allow_query, ac, zone,
976 dns_zone_setqueryacl,
977 dns_zone_clearqueryacl));
979 RETERR(configure_zone_acl(zconfig, vconfig, config,
980 allow_query_on, ac, zone,
981 dns_zone_setqueryonacl,
982 dns_zone_clearqueryonacl));
985 result = ns_config_get(maps, "dialup", &obj);
986 INSIST(result == ISC_R_SUCCESS && obj != NULL);
987 if (cfg_obj_isboolean(obj)) {
988 if (cfg_obj_asboolean(obj))
989 dialup = dns_dialuptype_yes;
991 dialup = dns_dialuptype_no;
993 const char *dialupstr = cfg_obj_asstring(obj);
994 if (strcasecmp(dialupstr, "notify") == 0)
995 dialup = dns_dialuptype_notify;
996 else if (strcasecmp(dialupstr, "notify-passive") == 0)
997 dialup = dns_dialuptype_notifypassive;
998 else if (strcasecmp(dialupstr, "refresh") == 0)
999 dialup = dns_dialuptype_refresh;
1000 else if (strcasecmp(dialupstr, "passive") == 0)
1001 dialup = dns_dialuptype_passive;
1006 dns_zone_setdialup(raw, dialup);
1007 dns_zone_setdialup(zone, dialup);
1010 result = ns_config_get(maps, "zone-statistics", &obj);
1011 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1012 if (cfg_obj_isboolean(obj)) {
1013 if (cfg_obj_asboolean(obj))
1014 statlevel = dns_zonestat_full;
1016 statlevel = dns_zonestat_terse; /* XXX */
1018 const char *levelstr = cfg_obj_asstring(obj);
1019 if (strcasecmp(levelstr, "full") == 0)
1020 statlevel = dns_zonestat_full;
1021 else if (strcasecmp(levelstr, "terse") == 0)
1022 statlevel = dns_zonestat_terse;
1023 else if (strcasecmp(levelstr, "none") == 0)
1024 statlevel = dns_zonestat_none;
1028 dns_zone_setstatlevel(zone, statlevel);
1030 zoneqrystats = NULL;
1032 rcvquerystats = NULL;
1034 if (statlevel == dns_zonestat_full) {
1035 RETERR(isc_stats_create(mctx, &zoneqrystats,
1036 dns_nsstatscounter_max));
1038 RETERR(dns_rdatatypestats_create(mctx,
1042 dns_zone_setrequeststats(zone, zoneqrystats );
1044 dns_zone_setrcvquerystats(zone, rcvquerystats);
1047 if (zoneqrystats != NULL)
1048 isc_stats_detach(&zoneqrystats);
1051 if(rcvquerystats != NULL)
1052 dns_stats_detach(&rcvquerystats);
1056 * Configure master functionality. This applies
1057 * to primary masters (type "master") and slaves
1058 * acting as masters (type "slave"), but not to stubs.
1060 if (ztype != dns_zone_stub && ztype != dns_zone_staticstub &&
1061 ztype != dns_zone_redirect) {
1063 result = ns_config_get(maps, "notify", &obj);
1064 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1065 if (cfg_obj_isboolean(obj)) {
1066 if (cfg_obj_asboolean(obj))
1067 notifytype = dns_notifytype_yes;
1069 notifytype = dns_notifytype_no;
1071 const char *notifystr = cfg_obj_asstring(obj);
1072 if (strcasecmp(notifystr, "explicit") == 0)
1073 notifytype = dns_notifytype_explicit;
1074 else if (strcasecmp(notifystr, "master-only") == 0)
1075 notifytype = dns_notifytype_masteronly;
1080 dns_zone_setnotifytype(raw, dns_notifytype_no);
1081 dns_zone_setnotifytype(zone, notifytype);
1084 result = ns_config_get(maps, "also-notify", &obj);
1085 if (result == ISC_R_SUCCESS) {
1086 isc_uint32_t addrcount;
1089 RETERR(ns_config_getipandkeylist(config, obj, mctx,
1092 result = dns_zone_setalsonotifywithkeys(zone, addrs,
1096 ns_config_putipandkeylist(mctx, &addrs,
1097 &keynames, addrcount);
1099 INSIST(addrs == NULL && keynames == NULL);
1102 RETERR(dns_zone_setalsonotify(zone, NULL, 0));
1105 result = ns_config_get(maps, "notify-source", &obj);
1106 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1107 RETERR(dns_zone_setnotifysrc4(zone, cfg_obj_assockaddr(obj)));
1108 ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
1111 result = ns_config_get(maps, "notify-source-v6", &obj);
1112 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1113 RETERR(dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj)));
1114 ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
1117 result = ns_config_get(maps, "notify-to-soa", &obj);
1118 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1119 dns_zone_setoption(zone, DNS_ZONEOPT_NOTIFYTOSOA,
1120 cfg_obj_asboolean(obj));
1122 dns_zone_setisself(zone, ns_client_isself, NULL);
1124 RETERR(configure_zone_acl(zconfig, vconfig, config,
1125 allow_transfer, ac, zone,
1127 dns_zone_clearxfracl));
1130 result = ns_config_get(maps, "max-transfer-time-out", &obj);
1131 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1132 dns_zone_setmaxxfrout(zone, cfg_obj_asuint32(obj) * 60);
1135 result = ns_config_get(maps, "max-transfer-idle-out", &obj);
1136 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1137 dns_zone_setidleout(zone, cfg_obj_asuint32(obj) * 60);
1140 result = ns_config_get(maps, "max-journal-size", &obj);
1141 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1143 dns_zone_setjournalsize(raw, -1);
1144 dns_zone_setjournalsize(zone, -1);
1145 if (cfg_obj_isstring(obj)) {
1146 const char *str = cfg_obj_asstring(obj);
1147 INSIST(strcasecmp(str, "unlimited") == 0);
1148 journal_size = ISC_UINT32_MAX / 2;
1150 isc_resourcevalue_t value;
1151 value = cfg_obj_asuint64(obj);
1152 if (value > ISC_UINT32_MAX / 2) {
1153 cfg_obj_log(obj, ns_g_lctx,
1155 "'max-journal-size "
1156 "%" ISC_PRINT_QUADFORMAT "d' "
1159 RETERR(ISC_R_RANGE);
1161 journal_size = (isc_uint32_t)value;
1164 dns_zone_setjournalsize(raw, journal_size);
1165 dns_zone_setjournalsize(zone, journal_size);
1168 result = ns_config_get(maps, "ixfr-from-differences", &obj);
1169 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1170 if (cfg_obj_isboolean(obj))
1171 ixfrdiff = cfg_obj_asboolean(obj);
1172 else if (!strcasecmp(cfg_obj_asstring(obj), "master") &&
1173 ztype == dns_zone_master)
1174 ixfrdiff = ISC_TRUE;
1175 else if (!strcasecmp(cfg_obj_asstring(obj), "slave") &&
1176 ztype == dns_zone_slave)
1177 ixfrdiff = ISC_TRUE;
1179 ixfrdiff = ISC_FALSE;
1181 dns_zone_setoption(raw, DNS_ZONEOPT_IXFRFROMDIFFS,
1183 dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS,
1186 dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS,
1190 result = ns_config_get(maps, "request-ixfr", &obj);
1191 INSIST(result == ISC_R_SUCCESS);
1192 dns_zone_setrequestixfr(zone, cfg_obj_asboolean(obj));
1194 checknames(ztype, maps, &obj);
1195 INSIST(obj != NULL);
1196 if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
1199 } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
1200 fail = check = ISC_TRUE;
1201 } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
1202 fail = check = ISC_FALSE;
1206 dns_zone_setoption(raw, DNS_ZONEOPT_CHECKNAMES,
1208 dns_zone_setoption(raw, DNS_ZONEOPT_CHECKNAMESFAIL,
1210 dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES,
1212 dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL,
1215 dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES,
1217 dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL,
1222 result = ns_config_get(maps, "notify-delay", &obj);
1223 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1224 dns_zone_setnotifydelay(zone, cfg_obj_asuint32(obj));
1227 result = ns_config_get(maps, "check-sibling", &obj);
1228 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1229 dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSIBLING,
1230 cfg_obj_asboolean(obj));
1233 result = ns_config_get(maps, "check-spf", &obj);
1234 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1235 if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
1237 } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
1241 dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSPF, check);
1244 result = ns_config_get(maps, "zero-no-soa-ttl", &obj);
1245 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1246 dns_zone_setzeronosoattl(zone, cfg_obj_asboolean(obj));
1249 result = ns_config_get(maps, "nsec3-test-zone", &obj);
1250 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1251 dns_zone_setoption(zone, DNS_ZONEOPT_NSEC3TESTZONE,
1252 cfg_obj_asboolean(obj));
1253 } else if (ztype == dns_zone_redirect) {
1254 dns_zone_setnotifytype(zone, dns_notifytype_no);
1257 result = ns_config_get(maps, "max-journal-size", &obj);
1258 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1259 dns_zone_setjournalsize(zone, -1);
1260 if (cfg_obj_isstring(obj)) {
1261 const char *str = cfg_obj_asstring(obj);
1262 INSIST(strcasecmp(str, "unlimited") == 0);
1263 journal_size = ISC_UINT32_MAX / 2;
1265 isc_resourcevalue_t value;
1266 value = cfg_obj_asuint64(obj);
1267 if (value > ISC_UINT32_MAX / 2) {
1268 cfg_obj_log(obj, ns_g_lctx,
1270 "'max-journal-size "
1271 "%" ISC_PRINT_QUADFORMAT "d' "
1274 RETERR(ISC_R_RANGE);
1276 journal_size = (isc_uint32_t)value;
1278 dns_zone_setjournalsize(zone, journal_size);
1282 * Configure update-related options. These apply to
1283 * primary masters only.
1285 if (ztype == dns_zone_master) {
1286 dns_acl_t *updateacl;
1288 RETERR(configure_zone_acl(zconfig, vconfig, config,
1289 allow_update, ac, mayberaw,
1290 dns_zone_setupdateacl,
1291 dns_zone_clearupdateacl));
1293 updateacl = dns_zone_getupdateacl(mayberaw);
1294 if (updateacl != NULL && dns_acl_isinsecure(updateacl))
1295 isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY,
1296 NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
1297 "zone '%s' allows updates by IP "
1298 "address, which is insecure",
1301 RETERR(configure_zone_ssutable(zoptions, mayberaw, zname));
1304 if (ztype == dns_zone_master || raw != NULL) {
1305 isc_boolean_t allow = ISC_FALSE, maint = ISC_FALSE;
1308 result = ns_config_get(maps, "sig-validity-interval", &obj);
1309 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1311 const cfg_obj_t *validity, *resign;
1313 validity = cfg_tuple_get(obj, "validity");
1314 seconds = cfg_obj_asuint32(validity) * 86400;
1315 dns_zone_setsigvalidityinterval(zone, seconds);
1317 resign = cfg_tuple_get(obj, "re-sign");
1318 if (cfg_obj_isvoid(resign)) {
1321 if (seconds > 7 * 86400)
1322 seconds = cfg_obj_asuint32(resign) *
1325 seconds = cfg_obj_asuint32(resign) *
1328 dns_zone_setsigresigninginterval(zone, seconds);
1332 result = ns_config_get(maps, "key-directory", &obj);
1333 if (result == ISC_R_SUCCESS) {
1334 filename = cfg_obj_asstring(obj);
1335 RETERR(dns_zone_setkeydirectory(zone, filename));
1339 result = ns_config_get(maps, "sig-signing-signatures", &obj);
1340 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1341 dns_zone_setsignatures(zone, cfg_obj_asuint32(obj));
1344 result = ns_config_get(maps, "sig-signing-nodes", &obj);
1345 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1346 dns_zone_setnodes(zone, cfg_obj_asuint32(obj));
1349 result = ns_config_get(maps, "sig-signing-type", &obj);
1350 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1351 dns_zone_setprivatetype(zone, cfg_obj_asuint32(obj));
1354 result = ns_config_get(maps, "update-check-ksk", &obj);
1355 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1356 dns_zone_setoption(zone, DNS_ZONEOPT_UPDATECHECKKSK,
1357 cfg_obj_asboolean(obj));
1360 result = ns_config_get(maps, "dnssec-dnskey-kskonly", &obj);
1361 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1362 dns_zone_setoption(zone, DNS_ZONEOPT_DNSKEYKSKONLY,
1363 cfg_obj_asboolean(obj));
1366 result = ns_config_get(maps, "dnssec-loadkeys-interval", &obj);
1367 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1368 RETERR(dns_zone_setrefreshkeyinterval(zone,
1369 cfg_obj_asuint32(obj)));
1372 result = cfg_map_get(zoptions, "auto-dnssec", &obj);
1373 if (result == ISC_R_SUCCESS) {
1374 const char *arg = cfg_obj_asstring(obj);
1375 if (strcasecmp(arg, "allow") == 0)
1377 else if (strcasecmp(arg, "maintain") == 0)
1378 allow = maint = ISC_TRUE;
1379 else if (strcasecmp(arg, "off") == 0)
1383 dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, allow);
1384 dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, maint);
1388 if (ztype == dns_zone_slave) {
1389 RETERR(configure_zone_acl(zconfig, vconfig, config,
1390 allow_update_forwarding, ac,
1391 mayberaw, dns_zone_setforwardacl,
1392 dns_zone_clearforwardacl));
1396 * Primary master functionality.
1398 if (ztype == dns_zone_master) {
1400 result = ns_config_get(maps, "check-wildcard", &obj);
1401 if (result == ISC_R_SUCCESS)
1402 check = cfg_obj_asboolean(obj);
1405 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKWILDCARD, check);
1408 result = ns_config_get(maps, "check-dup-records", &obj);
1409 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1410 if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
1413 } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
1414 fail = check = ISC_TRUE;
1415 } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
1416 fail = check = ISC_FALSE;
1419 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKDUPRR, check);
1420 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKDUPRRFAIL, fail);
1423 result = ns_config_get(maps, "check-mx", &obj);
1424 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1425 if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
1428 } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
1429 fail = check = ISC_TRUE;
1430 } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
1431 fail = check = ISC_FALSE;
1434 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKMX, check);
1435 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKMXFAIL, fail);
1438 result = ns_config_get(maps, "check-integrity", &obj);
1439 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1440 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKINTEGRITY,
1441 cfg_obj_asboolean(obj));
1444 result = ns_config_get(maps, "check-mx-cname", &obj);
1445 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1446 if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
1449 } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
1450 warn = ignore = ISC_FALSE;
1451 } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
1452 warn = ignore = ISC_TRUE;
1455 dns_zone_setoption(mayberaw, DNS_ZONEOPT_WARNMXCNAME, warn);
1456 dns_zone_setoption(mayberaw, DNS_ZONEOPT_IGNOREMXCNAME, ignore);
1459 result = ns_config_get(maps, "check-srv-cname", &obj);
1460 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1461 if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
1464 } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
1465 warn = ignore = ISC_FALSE;
1466 } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
1467 warn = ignore = ISC_TRUE;
1470 dns_zone_setoption(mayberaw, DNS_ZONEOPT_WARNSRVCNAME, warn);
1471 dns_zone_setoption(mayberaw, DNS_ZONEOPT_IGNORESRVCNAME,
1475 result = ns_config_get(maps, "dnssec-secure-to-insecure", &obj);
1476 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1477 dns_zone_setoption(mayberaw, DNS_ZONEOPT_SECURETOINSECURE,
1478 cfg_obj_asboolean(obj));
1481 result = cfg_map_get(zoptions, "dnssec-update-mode", &obj);
1482 if (result == ISC_R_SUCCESS) {
1483 const char *arg = cfg_obj_asstring(obj);
1484 if (strcasecmp(arg, "no-resign") == 0)
1485 dns_zone_setkeyopt(zone, DNS_ZONEKEY_NORESIGN,
1487 else if (strcasecmp(arg, "maintain") == 0)
1494 result = ns_config_get(maps, "serial-update-method", &obj);
1495 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1496 if (strcasecmp(cfg_obj_asstring(obj), "unixtime") == 0)
1497 dns_zone_setserialupdatemethod(zone,
1498 dns_updatemethod_unixtime);
1500 dns_zone_setserialupdatemethod(zone,
1501 dns_updatemethod_increment);
1505 * Configure slave functionality.
1508 case dns_zone_slave:
1510 case dns_zone_redirect:
1513 (void)cfg_map_get(zoptions, "masters", &obj);
1517 RETERR(ns_config_getipandkeylist(config, obj, mctx,
1520 result = dns_zone_setmasterswithkeys(mayberaw, addrs,
1523 ns_config_putipandkeylist(mctx, &addrs,
1526 INSIST(addrs == NULL && keynames == NULL);
1528 result = dns_zone_setmasters(mayberaw, NULL, 0);
1534 result = ns_config_get(maps, "multi-master", &obj);
1535 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1536 multi = cfg_obj_asboolean(obj);
1538 dns_zone_setoption(mayberaw, DNS_ZONEOPT_MULTIMASTER, multi);
1541 result = ns_config_get(maps, "max-transfer-time-in", &obj);
1542 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1543 dns_zone_setmaxxfrin(mayberaw, cfg_obj_asuint32(obj) * 60);
1546 result = ns_config_get(maps, "max-transfer-idle-in", &obj);
1547 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1548 dns_zone_setidlein(mayberaw, cfg_obj_asuint32(obj) * 60);
1551 result = ns_config_get(maps, "max-refresh-time", &obj);
1552 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1553 dns_zone_setmaxrefreshtime(mayberaw, cfg_obj_asuint32(obj));
1556 result = ns_config_get(maps, "min-refresh-time", &obj);
1557 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1558 dns_zone_setminrefreshtime(mayberaw, cfg_obj_asuint32(obj));
1561 result = ns_config_get(maps, "max-retry-time", &obj);
1562 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1563 dns_zone_setmaxretrytime(mayberaw, cfg_obj_asuint32(obj));
1566 result = ns_config_get(maps, "min-retry-time", &obj);
1567 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1568 dns_zone_setminretrytime(mayberaw, cfg_obj_asuint32(obj));
1571 result = ns_config_get(maps, "transfer-source", &obj);
1572 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1573 RETERR(dns_zone_setxfrsource4(mayberaw,
1574 cfg_obj_assockaddr(obj)));
1575 ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
1578 result = ns_config_get(maps, "transfer-source-v6", &obj);
1579 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1580 RETERR(dns_zone_setxfrsource6(mayberaw,
1581 cfg_obj_assockaddr(obj)));
1582 ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
1585 result = ns_config_get(maps, "alt-transfer-source", &obj);
1586 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1587 RETERR(dns_zone_setaltxfrsource4(mayberaw,
1588 cfg_obj_assockaddr(obj)));
1591 result = ns_config_get(maps, "alt-transfer-source-v6", &obj);
1592 INSIST(result == ISC_R_SUCCESS && obj != NULL);
1593 RETERR(dns_zone_setaltxfrsource6(mayberaw,
1594 cfg_obj_assockaddr(obj)));
1597 (void)ns_config_get(maps, "use-alt-transfer-source", &obj);
1600 * Default off when views are in use otherwise
1601 * on for BIND 8 compatibility.
1603 view = dns_zone_getview(zone);
1604 if (view != NULL && strcmp(view->name, "_default") == 0)
1609 alt = cfg_obj_asboolean(obj);
1610 dns_zone_setoption(mayberaw, DNS_ZONEOPT_USEALTXFRSRC, alt);
1613 (void)ns_config_get(maps, "try-tcp-refresh", &obj);
1614 dns_zone_setoption(mayberaw, DNS_ZONEOPT_TRYTCPREFRESH,
1615 cfg_obj_asboolean(obj));
1618 case dns_zone_staticstub:
1619 RETERR(configure_staticstub(zoptions, zone, zname,
1627 return (ISC_R_SUCCESS);
1632 * Set up a DLZ zone as writeable
1635 ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone,
1636 dns_rdataclass_t rdclass, dns_name_t *name)
1638 dns_db_t *db = NULL;
1640 isc_result_t result;
1644 dns_zone_settype(zone, dns_zone_dlz);
1645 result = dns_sdlz_setdb(dlzdatabase, rdclass, name, &db);
1646 if (result != ISC_R_SUCCESS)
1648 result = dns_zone_dlzpostload(zone, db);
1654 ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) {
1655 const cfg_obj_t *zoptions = NULL;
1656 const cfg_obj_t *obj = NULL;
1657 const char *cfilename;
1658 const char *zfilename;
1659 dns_zone_t *raw = NULL;
1660 isc_boolean_t has_raw;
1661 dns_zonetype_t ztype;
1663 zoptions = cfg_tuple_get(zconfig, "options");
1666 * We always reconfigure a static-stub zone for simplicity, assuming
1667 * the amount of data to be loaded is small.
1669 if (zonetype_fromconfig(zoptions) == dns_zone_staticstub) {
1670 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1671 "not reusable: staticstub");
1675 /* If there's a raw zone, use that for filename and type comparison */
1676 dns_zone_getraw(zone, &raw);
1678 zfilename = dns_zone_getfile(raw);
1679 ztype = dns_zone_gettype(raw);
1680 dns_zone_detach(&raw);
1683 zfilename = dns_zone_getfile(zone);
1684 ztype = dns_zone_gettype(zone);
1685 has_raw = ISC_FALSE;
1689 (void)cfg_map_get(zoptions, "inline-signing", &obj);
1690 if ((obj == NULL || !cfg_obj_asboolean(obj)) && has_raw) {
1691 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1692 "not reusable: old zone was inline-signing");
1694 } else if ((obj != NULL && cfg_obj_asboolean(obj)) && !has_raw) {
1695 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1696 "not reusable: old zone was not inline-signing");
1700 if (zonetype_fromconfig(zoptions) != ztype) {
1701 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1702 "not reusable: type mismatch");
1707 (void)cfg_map_get(zoptions, "file", &obj);
1709 cfilename = cfg_obj_asstring(obj);
1712 if (!((cfilename == NULL && zfilename == NULL) ||
1713 (cfilename != NULL && zfilename != NULL &&
1714 strcmp(cfilename, zfilename) == 0)))
1716 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1717 "not reusable: filename mismatch");