1999-12-16 23:11:07 +00:00
|
|
|
/*
|
2016-05-26 12:36:17 -07:00
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
1999-12-16 23:11:07 +00:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: MPL-2.0
|
2021-06-03 08:37:05 +02:00
|
|
|
*
|
1999-12-16 23:11:07 +00:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
2018-02-23 09:53:12 +01:00
|
|
|
*
|
1999-12-16 23:11:07 +00:00
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
|
|
* information regarding copyright ownership.
|
|
|
|
*/
|
|
|
|
|
2018-03-28 14:56:40 +02:00
|
|
|
#include <inttypes.h>
|
2018-04-17 08:29:14 -07:00
|
|
|
#include <stdbool.h>
|
2018-03-28 14:56:40 +02:00
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
#include <isc/buffer.h>
|
2024-08-14 13:25:50 +02:00
|
|
|
#include <isc/log.h>
|
2000-08-10 00:53:36 +00:00
|
|
|
#include <isc/mem.h>
|
2021-10-04 17:14:53 +02:00
|
|
|
#include <isc/result.h>
|
2009-01-27 22:30:00 +00:00
|
|
|
#include <isc/stats.h>
|
2022-04-11 15:53:34 +01:00
|
|
|
#include <isc/string.h>
|
2000-04-28 01:12:23 +00:00
|
|
|
#include <isc/util.h>
|
1999-12-16 23:11:07 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <dns/acl.h>
|
2010-12-16 09:51:30 +00:00
|
|
|
#include <dns/db.h>
|
2001-03-04 21:21:39 +00:00
|
|
|
#include <dns/fixedname.h>
|
2016-05-26 21:23:19 +02:00
|
|
|
#include <dns/ipkeylist.h>
|
2017-05-02 13:23:08 -07:00
|
|
|
#include <dns/journal.h>
|
2019-09-03 11:42:10 +02:00
|
|
|
#include <dns/kasp.h>
|
2014-04-17 17:10:29 -07:00
|
|
|
#include <dns/masterdump.h>
|
2001-03-04 21:21:39 +00:00
|
|
|
#include <dns/name.h>
|
2020-10-23 15:02:19 +02:00
|
|
|
#include <dns/nsec3.h>
|
2010-12-16 09:51:30 +00:00
|
|
|
#include <dns/rdata.h>
|
|
|
|
#include <dns/rdatalist.h>
|
|
|
|
#include <dns/rdataset.h>
|
2001-03-04 21:21:39 +00:00
|
|
|
#include <dns/rdatatype.h>
|
2010-12-18 01:56:23 +00:00
|
|
|
#include <dns/sdlz.h>
|
2000-08-29 03:48:00 +00:00
|
|
|
#include <dns/ssu.h>
|
2008-04-03 05:55:52 +00:00
|
|
|
#include <dns/stats.h>
|
2017-09-08 13:39:09 -07:00
|
|
|
#include <dns/tsig.h>
|
2003-02-26 23:29:00 +00:00
|
|
|
#include <dns/view.h>
|
1999-12-16 23:11:07 +00:00
|
|
|
#include <dns/zone.h>
|
2000-11-27 19:42:38 +00:00
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
#include <ns/client.h>
|
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
#include <named/config.h>
|
2000-12-01 18:22:17 +00:00
|
|
|
#include <named/globals.h>
|
|
|
|
#include <named/log.h>
|
2004-01-05 06:56:44 +00:00
|
|
|
#include <named/server.h>
|
2000-11-27 19:42:38 +00:00
|
|
|
#include <named/zoneconf.h>
|
1999-12-16 23:11:07 +00:00
|
|
|
|
2008-05-21 23:17:21 +00:00
|
|
|
/* ACLs associated with zone */
|
|
|
|
typedef enum {
|
|
|
|
allow_notify,
|
|
|
|
allow_query,
|
2013-01-03 15:13:45 -08:00
|
|
|
allow_query_on,
|
2008-05-21 23:17:21 +00:00
|
|
|
allow_transfer,
|
|
|
|
allow_update,
|
|
|
|
allow_update_forwarding
|
|
|
|
} acl_type_t;
|
|
|
|
|
2009-06-10 00:27:22 +00:00
|
|
|
#define CHECK(x) \
|
|
|
|
do { \
|
|
|
|
result = (x); \
|
|
|
|
if (result != ISC_R_SUCCESS) \
|
|
|
|
goto cleanup; \
|
|
|
|
} while (0)
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
1999-12-16 23:11:07 +00:00
|
|
|
* Convenience function for configuring a single zone ACL.
|
|
|
|
*/
|
|
|
|
static isc_result_t
|
2006-02-28 02:39:52 +00:00
|
|
|
configure_zone_acl(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig,
|
2008-05-21 23:17:21 +00:00
|
|
|
const cfg_obj_t *config, acl_type_t acltype,
|
2008-01-18 23:46:58 +00:00
|
|
|
cfg_aclconfctx_t *actx, dns_zone_t *zone,
|
1999-12-16 23:11:07 +00:00
|
|
|
void (*setzacl)(dns_zone_t *, dns_acl_t *),
|
|
|
|
void (*clearzacl)(dns_zone_t *)) {
|
|
|
|
isc_result_t result;
|
2025-04-15 13:39:57 -07:00
|
|
|
const cfg_obj_t *maps[6] = { 0 };
|
2006-02-28 02:39:52 +00:00
|
|
|
const cfg_obj_t *aclobj = NULL;
|
2001-03-04 21:21:39 +00:00
|
|
|
int i = 0;
|
2008-05-21 23:17:21 +00:00
|
|
|
dns_acl_t **aclp = NULL, *acl = NULL;
|
|
|
|
const char *aclname;
|
2025-04-15 13:39:57 -07:00
|
|
|
dns_view_t *view = NULL;
|
2008-05-21 23:17:21 +00:00
|
|
|
|
2008-05-21 23:47:01 +00:00
|
|
|
view = dns_zone_getview(zone);
|
2008-05-21 23:17:21 +00:00
|
|
|
|
|
|
|
switch (acltype) {
|
|
|
|
case allow_notify:
|
2008-05-21 23:47:01 +00:00
|
|
|
if (view != NULL) {
|
|
|
|
aclp = &view->notifyacl;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-05-21 23:17:21 +00:00
|
|
|
aclname = "allow-notify";
|
|
|
|
break;
|
|
|
|
case allow_query:
|
2008-05-21 23:47:01 +00:00
|
|
|
if (view != NULL) {
|
|
|
|
aclp = &view->queryacl;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-05-21 23:17:21 +00:00
|
|
|
aclname = "allow-query";
|
|
|
|
break;
|
2013-01-03 15:13:45 -08:00
|
|
|
case allow_query_on:
|
|
|
|
if (view != NULL) {
|
|
|
|
aclp = &view->queryonacl;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-01-03 15:13:45 -08:00
|
|
|
aclname = "allow-query-on";
|
|
|
|
break;
|
2008-05-21 23:17:21 +00:00
|
|
|
case allow_transfer:
|
2008-05-21 23:47:01 +00:00
|
|
|
if (view != NULL) {
|
|
|
|
aclp = &view->transferacl;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-05-21 23:17:21 +00:00
|
|
|
aclname = "allow-transfer";
|
|
|
|
break;
|
|
|
|
case allow_update:
|
2008-05-21 23:47:01 +00:00
|
|
|
if (view != NULL) {
|
|
|
|
aclp = &view->updateacl;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-05-21 23:17:21 +00:00
|
|
|
aclname = "allow-update";
|
|
|
|
break;
|
|
|
|
case allow_update_forwarding:
|
2008-05-21 23:47:01 +00:00
|
|
|
if (view != NULL) {
|
|
|
|
aclp = &view->upfwdacl;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-05-21 23:17:21 +00:00
|
|
|
aclname = "allow-update-forwarding";
|
|
|
|
break;
|
2008-05-21 23:47:01 +00:00
|
|
|
default:
|
2021-10-11 12:50:17 +02:00
|
|
|
UNREACHABLE();
|
2008-05-21 23:17:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* First check to see if ACL is defined within the zone */
|
|
|
|
if (zconfig != NULL) {
|
2025-04-15 13:39:57 -07:00
|
|
|
maps[i] = cfg_tuple_get(zconfig, "options");
|
2017-09-08 13:39:09 -07:00
|
|
|
(void)named_config_get(maps, aclname, &aclobj);
|
2008-05-21 23:17:21 +00:00
|
|
|
if (aclobj != NULL) {
|
|
|
|
aclp = NULL;
|
|
|
|
goto parse_acl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-04-15 13:39:57 -07:00
|
|
|
if (config != NULL && maps[i] != NULL) {
|
|
|
|
const cfg_obj_t *toptions = named_zone_templateopts(config,
|
|
|
|
maps[i]);
|
|
|
|
if (toptions != NULL) {
|
|
|
|
maps[i++] = toptions;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-05-21 23:17:21 +00:00
|
|
|
/* Failing that, see if there's a default ACL already in the view */
|
|
|
|
if (aclp != NULL && *aclp != NULL) {
|
|
|
|
(*setzacl)(zone, *aclp);
|
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
}
|
2001-03-04 21:21:39 +00:00
|
|
|
|
2008-05-21 23:17:21 +00:00
|
|
|
/* Check for default ACLs that haven't been parsed yet */
|
2010-08-11 18:14:20 +00:00
|
|
|
if (vconfig != NULL) {
|
|
|
|
const cfg_obj_t *options = cfg_tuple_get(vconfig, "options");
|
|
|
|
if (options != NULL) {
|
|
|
|
maps[i++] = options;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2010-08-11 18:14:20 +00:00
|
|
|
}
|
2001-03-04 21:21:39 +00:00
|
|
|
if (config != NULL) {
|
2006-02-28 02:39:52 +00:00
|
|
|
const cfg_obj_t *options = NULL;
|
2001-03-04 21:21:39 +00:00
|
|
|
(void)cfg_map_get(config, "options", &options);
|
|
|
|
if (options != NULL) {
|
|
|
|
maps[i++] = options;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-02-22 21:24:24 +00:00
|
|
|
}
|
2025-04-22 13:46:47 +02:00
|
|
|
maps[i++] = named_g_defaultoptions;
|
2001-03-04 21:21:39 +00:00
|
|
|
maps[i] = NULL;
|
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
(void)named_config_get(maps, aclname, &aclobj);
|
2001-03-04 21:21:39 +00:00
|
|
|
if (aclobj == NULL) {
|
1999-12-16 23:11:07 +00:00
|
|
|
(*clearzacl)(zone);
|
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
}
|
2001-03-04 21:21:39 +00:00
|
|
|
|
2008-05-21 23:17:21 +00:00
|
|
|
parse_acl:
|
2025-07-15 12:56:04 +02:00
|
|
|
result = cfg_acl_fromconfig(aclobj, config, actx, isc_g_mctx, 0, &acl);
|
2001-03-04 21:21:39 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
return result;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-05-21 23:17:21 +00:00
|
|
|
(*setzacl)(zone, acl);
|
|
|
|
|
2008-05-21 23:47:01 +00:00
|
|
|
/* Set the view default now */
|
2008-05-21 23:17:21 +00:00
|
|
|
if (aclp != NULL) {
|
|
|
|
dns_acl_attach(acl, aclp);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-05-21 23:17:21 +00:00
|
|
|
|
|
|
|
dns_acl_detach(&acl);
|
2001-03-04 21:21:39 +00:00
|
|
|
return ISC_R_SUCCESS;
|
1999-12-16 23:11:07 +00:00
|
|
|
}
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
2001-03-04 21:21:39 +00:00
|
|
|
* Parse the zone update-policy statement.
|
2000-05-25 19:27:48 +00:00
|
|
|
*/
|
2001-03-04 21:21:39 +00:00
|
|
|
static isc_result_t
|
2025-04-15 13:39:57 -07:00
|
|
|
configure_zone_ssutable(const cfg_obj_t *zconfig, const cfg_obj_t *tconfig,
|
|
|
|
dns_zone_t *zone, const char *zname) {
|
2006-02-28 02:39:52 +00:00
|
|
|
const cfg_obj_t *updatepolicy = NULL;
|
2001-03-04 21:21:39 +00:00
|
|
|
dns_ssutable_t *table = NULL;
|
|
|
|
isc_mem_t *mctx = dns_zone_getmctx(zone);
|
2018-04-17 08:29:14 -07:00
|
|
|
bool autoddns = false;
|
2021-10-06 13:18:16 +02:00
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
Add per rule logging of dns_ssutable_checkrules processing
These are logged to the update category at debug level 99 and
have the following form.
update-policy: using: signer=ddns-key.example.nil, name=updated.example.nil, addr=10.53.0.1, tcp=0, type=A, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: matched: grant ddns-key.example.nil zonesub ANY
or
update-policy: using: signer=restricted.example.nil, name=example.nil, addr=10.53.0.1, tcp=0, type=TXT, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: next rule: signer does not match identity
update-policy: trying: grant restricted.example.nil zonesub ANY
update-policy: next rule: name/subdomain mismatch
update-policy: no match found
where 'using:' is the calling parameters of dns_ssutable_checkrules,
'trying:' in the rule bing evaluated, "next rule:" is the reason
the rule does not match, "matched:" repeats the matched rule, and
no match found is reported when te set of rules is exhausted.
2024-05-29 15:04:37 +10:00
|
|
|
char debug[1024];
|
|
|
|
isc_buffer_t dbuf;
|
|
|
|
|
|
|
|
isc_buffer_init(&dbuf, debug, sizeof(debug));
|
|
|
|
isc_buffer_setmctx(&dbuf, mctx);
|
2001-03-04 21:21:39 +00:00
|
|
|
|
2025-04-15 13:39:57 -07:00
|
|
|
(void)named_config_findopt(zconfig, tconfig, "update-policy",
|
|
|
|
&updatepolicy);
|
2009-07-14 22:54:57 +00:00
|
|
|
if (updatepolicy == NULL) {
|
2006-01-05 03:32:50 +00:00
|
|
|
dns_zone_setssutable(zone, NULL);
|
2001-03-04 21:21:39 +00:00
|
|
|
return ISC_R_SUCCESS;
|
2006-01-05 03:32:50 +00:00
|
|
|
}
|
2001-03-04 21:21:39 +00:00
|
|
|
|
2009-07-14 23:47:54 +00:00
|
|
|
if (cfg_obj_isstring(updatepolicy) &&
|
|
|
|
strcmp("local", cfg_obj_asstring(updatepolicy)) == 0)
|
|
|
|
{
|
2018-04-17 08:29:14 -07:00
|
|
|
autoddns = true;
|
2009-07-14 23:47:54 +00:00
|
|
|
updatepolicy = NULL;
|
|
|
|
}
|
2009-07-14 22:54:57 +00:00
|
|
|
|
2021-10-06 13:18:16 +02:00
|
|
|
dns_ssutable_create(mctx, &table);
|
2001-03-04 21:21:39 +00:00
|
|
|
|
2025-03-26 18:54:05 -07:00
|
|
|
CFG_LIST_FOREACH(updatepolicy, element) {
|
2006-02-28 02:39:52 +00:00
|
|
|
const cfg_obj_t *stmt = cfg_listelt_value(element);
|
|
|
|
const cfg_obj_t *mode = cfg_tuple_get(stmt, "mode");
|
|
|
|
const cfg_obj_t *identity = cfg_tuple_get(stmt, "identity");
|
|
|
|
const cfg_obj_t *matchtype = cfg_tuple_get(stmt, "matchtype");
|
|
|
|
const cfg_obj_t *dname = cfg_tuple_get(stmt, "name");
|
|
|
|
const cfg_obj_t *typelist = cfg_tuple_get(stmt, "types");
|
2005-08-23 02:36:11 +00:00
|
|
|
const char *str;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool grant = false;
|
|
|
|
bool usezone = false;
|
2018-09-20 15:50:07 +10:00
|
|
|
dns_ssumatchtype_t mtype = dns_ssumatchtype_name;
|
2001-03-04 21:21:39 +00:00
|
|
|
dns_fixedname_t fname, fident;
|
|
|
|
isc_buffer_t b;
|
2019-07-03 16:42:15 +10:00
|
|
|
dns_ssuruletype_t *types;
|
2001-03-04 21:21:39 +00:00
|
|
|
unsigned int i, n;
|
Add per rule logging of dns_ssutable_checkrules processing
These are logged to the update category at debug level 99 and
have the following form.
update-policy: using: signer=ddns-key.example.nil, name=updated.example.nil, addr=10.53.0.1, tcp=0, type=A, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: matched: grant ddns-key.example.nil zonesub ANY
or
update-policy: using: signer=restricted.example.nil, name=example.nil, addr=10.53.0.1, tcp=0, type=TXT, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: next rule: signer does not match identity
update-policy: trying: grant restricted.example.nil zonesub ANY
update-policy: next rule: name/subdomain mismatch
update-policy: no match found
where 'using:' is the calling parameters of dns_ssutable_checkrules,
'trying:' in the rule bing evaluated, "next rule:" is the reason
the rule does not match, "matched:" repeats the matched rule, and
no match found is reported when te set of rules is exhausted.
2024-05-29 15:04:37 +10:00
|
|
|
char namebuf[DNS_NAME_FORMATSIZE];
|
2001-03-04 21:21:39 +00:00
|
|
|
|
Add per rule logging of dns_ssutable_checkrules processing
These are logged to the update category at debug level 99 and
have the following form.
update-policy: using: signer=ddns-key.example.nil, name=updated.example.nil, addr=10.53.0.1, tcp=0, type=A, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: matched: grant ddns-key.example.nil zonesub ANY
or
update-policy: using: signer=restricted.example.nil, name=example.nil, addr=10.53.0.1, tcp=0, type=TXT, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: next rule: signer does not match identity
update-policy: trying: grant restricted.example.nil zonesub ANY
update-policy: next rule: name/subdomain mismatch
update-policy: no match found
where 'using:' is the calling parameters of dns_ssutable_checkrules,
'trying:' in the rule bing evaluated, "next rule:" is the reason
the rule does not match, "matched:" repeats the matched rule, and
no match found is reported when te set of rules is exhausted.
2024-05-29 15:04:37 +10:00
|
|
|
isc_buffer_clear(&dbuf);
|
2001-03-04 21:21:39 +00:00
|
|
|
str = cfg_obj_asstring(mode);
|
2018-11-07 15:00:07 +07:00
|
|
|
if (strcasecmp(str, "grant") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
grant = true;
|
2018-11-07 15:00:07 +07:00
|
|
|
} else if (strcasecmp(str, "deny") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
grant = false;
|
2018-11-07 15:00:07 +07:00
|
|
|
} else {
|
2021-10-11 12:50:17 +02:00
|
|
|
UNREACHABLE();
|
2018-11-07 15:00:07 +07:00
|
|
|
}
|
Add per rule logging of dns_ssutable_checkrules processing
These are logged to the update category at debug level 99 and
have the following form.
update-policy: using: signer=ddns-key.example.nil, name=updated.example.nil, addr=10.53.0.1, tcp=0, type=A, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: matched: grant ddns-key.example.nil zonesub ANY
or
update-policy: using: signer=restricted.example.nil, name=example.nil, addr=10.53.0.1, tcp=0, type=TXT, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: next rule: signer does not match identity
update-policy: trying: grant restricted.example.nil zonesub ANY
update-policy: next rule: name/subdomain mismatch
update-policy: no match found
where 'using:' is the calling parameters of dns_ssutable_checkrules,
'trying:' in the rule bing evaluated, "next rule:" is the reason
the rule does not match, "matched:" repeats the matched rule, and
no match found is reported when te set of rules is exhausted.
2024-05-29 15:04:37 +10:00
|
|
|
isc_buffer_putstr(&dbuf, str);
|
2001-03-04 21:21:39 +00:00
|
|
|
|
|
|
|
dns_fixedname_init(&fident);
|
|
|
|
str = cfg_obj_asstring(identity);
|
2012-12-08 12:48:57 +11:00
|
|
|
isc_buffer_constinit(&b, str, strlen(str));
|
2001-03-04 21:21:39 +00:00
|
|
|
isc_buffer_add(&b, strlen(str));
|
|
|
|
result = dns_name_fromtext(dns_fixedname_name(&fident), &b,
|
2025-02-22 00:11:38 -08:00
|
|
|
dns_rootname, 0);
|
2001-03-04 21:21:39 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2024-08-13 18:20:26 +02:00
|
|
|
cfg_obj_log(identity, ISC_LOG_ERROR,
|
2001-03-04 21:21:39 +00:00
|
|
|
"'%s' is not a valid name", str);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
Add per rule logging of dns_ssutable_checkrules processing
These are logged to the update category at debug level 99 and
have the following form.
update-policy: using: signer=ddns-key.example.nil, name=updated.example.nil, addr=10.53.0.1, tcp=0, type=A, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: matched: grant ddns-key.example.nil zonesub ANY
or
update-policy: using: signer=restricted.example.nil, name=example.nil, addr=10.53.0.1, tcp=0, type=TXT, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: next rule: signer does not match identity
update-policy: trying: grant restricted.example.nil zonesub ANY
update-policy: next rule: name/subdomain mismatch
update-policy: no match found
where 'using:' is the calling parameters of dns_ssutable_checkrules,
'trying:' in the rule bing evaluated, "next rule:" is the reason
the rule does not match, "matched:" repeats the matched rule, and
no match found is reported when te set of rules is exhausted.
2024-05-29 15:04:37 +10:00
|
|
|
dns_name_format(dns_fixedname_name(&fident), namebuf,
|
|
|
|
sizeof(namebuf));
|
|
|
|
isc_buffer_putstr(&dbuf, " ");
|
|
|
|
isc_buffer_putstr(&dbuf, namebuf);
|
|
|
|
|
|
|
|
str = cfg_obj_asstring(matchtype);
|
|
|
|
CHECK(dns_ssu_mtypefromstring(str, &mtype));
|
|
|
|
if (mtype == dns_ssumatchtype_subdomain &&
|
|
|
|
strcasecmp(str, "zonesub") == 0)
|
|
|
|
{
|
|
|
|
usezone = true;
|
|
|
|
}
|
|
|
|
isc_buffer_putstr(&dbuf, " ");
|
|
|
|
isc_buffer_putstr(&dbuf, str);
|
2001-03-04 21:21:39 +00:00
|
|
|
|
|
|
|
dns_fixedname_init(&fname);
|
2009-06-10 00:27:22 +00:00
|
|
|
if (usezone) {
|
2021-05-21 17:20:44 -07:00
|
|
|
dns_name_copy(dns_zone_getorigin(zone),
|
|
|
|
dns_fixedname_name(&fname));
|
2009-06-10 00:27:22 +00:00
|
|
|
} else {
|
|
|
|
str = cfg_obj_asstring(dname);
|
2012-12-08 12:48:57 +11:00
|
|
|
isc_buffer_constinit(&b, str, strlen(str));
|
2009-06-10 00:27:22 +00:00
|
|
|
isc_buffer_add(&b, strlen(str));
|
|
|
|
result = dns_name_fromtext(dns_fixedname_name(&fname),
|
2025-02-22 00:11:38 -08:00
|
|
|
&b, dns_rootname, 0);
|
2009-06-10 00:27:22 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2024-08-13 18:20:26 +02:00
|
|
|
cfg_obj_log(identity, ISC_LOG_ERROR,
|
2009-06-10 00:27:22 +00:00
|
|
|
"'%s' is not a valid name", str);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
Add per rule logging of dns_ssutable_checkrules processing
These are logged to the update category at debug level 99 and
have the following form.
update-policy: using: signer=ddns-key.example.nil, name=updated.example.nil, addr=10.53.0.1, tcp=0, type=A, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: matched: grant ddns-key.example.nil zonesub ANY
or
update-policy: using: signer=restricted.example.nil, name=example.nil, addr=10.53.0.1, tcp=0, type=TXT, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: next rule: signer does not match identity
update-policy: trying: grant restricted.example.nil zonesub ANY
update-policy: next rule: name/subdomain mismatch
update-policy: no match found
where 'using:' is the calling parameters of dns_ssutable_checkrules,
'trying:' in the rule bing evaluated, "next rule:" is the reason
the rule does not match, "matched:" repeats the matched rule, and
no match found is reported when te set of rules is exhausted.
2024-05-29 15:04:37 +10:00
|
|
|
dns_name_format(dns_fixedname_name(&fname), namebuf,
|
|
|
|
sizeof(namebuf));
|
|
|
|
isc_buffer_putstr(&dbuf, " ");
|
|
|
|
isc_buffer_putstr(&dbuf, namebuf);
|
2001-03-04 21:21:39 +00:00
|
|
|
}
|
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
n = named_config_listcount(typelist);
|
2001-03-04 21:21:39 +00:00
|
|
|
if (n == 0) {
|
|
|
|
types = NULL;
|
|
|
|
} else {
|
2023-08-23 08:56:31 +02:00
|
|
|
types = isc_mem_cget(mctx, n, sizeof(*types));
|
2001-03-04 21:21:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
i = 0;
|
2025-03-26 18:54:05 -07:00
|
|
|
CFG_LIST_FOREACH(typelist, element2) {
|
2006-02-28 02:39:52 +00:00
|
|
|
const cfg_obj_t *typeobj;
|
2019-07-03 16:42:15 +10:00
|
|
|
const char *bracket;
|
2001-03-04 21:21:39 +00:00
|
|
|
isc_textregion_t r;
|
2019-07-03 16:42:15 +10:00
|
|
|
unsigned long max = 0;
|
2001-03-04 21:21:39 +00:00
|
|
|
|
|
|
|
INSIST(i < n);
|
|
|
|
|
|
|
|
typeobj = cfg_listelt_value(element2);
|
|
|
|
str = cfg_obj_asstring(typeobj);
|
2023-03-30 22:34:12 +02:00
|
|
|
r.base = UNCONST(str);
|
Add per rule logging of dns_ssutable_checkrules processing
These are logged to the update category at debug level 99 and
have the following form.
update-policy: using: signer=ddns-key.example.nil, name=updated.example.nil, addr=10.53.0.1, tcp=0, type=A, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: matched: grant ddns-key.example.nil zonesub ANY
or
update-policy: using: signer=restricted.example.nil, name=example.nil, addr=10.53.0.1, tcp=0, type=TXT, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: next rule: signer does not match identity
update-policy: trying: grant restricted.example.nil zonesub ANY
update-policy: next rule: name/subdomain mismatch
update-policy: no match found
where 'using:' is the calling parameters of dns_ssutable_checkrules,
'trying:' in the rule bing evaluated, "next rule:" is the reason
the rule does not match, "matched:" repeats the matched rule, and
no match found is reported when te set of rules is exhausted.
2024-05-29 15:04:37 +10:00
|
|
|
isc_buffer_putstr(&dbuf, " ");
|
|
|
|
isc_buffer_putstr(&dbuf, str);
|
2001-03-04 21:21:39 +00:00
|
|
|
|
2019-07-03 16:42:15 +10:00
|
|
|
bracket = strchr(str, '(' /*)*/);
|
|
|
|
if (bracket != NULL) {
|
|
|
|
char *end = NULL;
|
|
|
|
r.length = bracket - str;
|
|
|
|
max = strtoul(bracket + 1, &end, 10);
|
|
|
|
if (max > 0xffff || end[0] != /*(*/ ')' ||
|
2022-11-02 19:33:14 +01:00
|
|
|
end[1] != 0)
|
|
|
|
{
|
2024-08-13 18:20:26 +02:00
|
|
|
cfg_obj_log(identity, ISC_LOG_ERROR,
|
2019-07-03 16:42:15 +10:00
|
|
|
"'%s' is not a valid count",
|
|
|
|
bracket);
|
2023-08-23 08:56:31 +02:00
|
|
|
isc_mem_cput(mctx, types, n,
|
|
|
|
sizeof(*types));
|
2019-07-03 16:42:15 +10:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
r.length = strlen(str);
|
|
|
|
}
|
|
|
|
types[i].max = max;
|
|
|
|
|
|
|
|
result = dns_rdatatype_fromtext(&types[i++].type, &r);
|
2001-03-04 21:21:39 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2024-08-13 18:20:26 +02:00
|
|
|
cfg_obj_log(identity, ISC_LOG_ERROR,
|
2019-07-03 16:42:15 +10:00
|
|
|
"'%.*s' is not a valid type",
|
|
|
|
(int)r.length, str);
|
2023-08-23 08:56:31 +02:00
|
|
|
isc_mem_cput(mctx, types, n, sizeof(*types));
|
2001-03-04 21:21:39 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
INSIST(i == n);
|
|
|
|
|
Add per rule logging of dns_ssutable_checkrules processing
These are logged to the update category at debug level 99 and
have the following form.
update-policy: using: signer=ddns-key.example.nil, name=updated.example.nil, addr=10.53.0.1, tcp=0, type=A, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: matched: grant ddns-key.example.nil zonesub ANY
or
update-policy: using: signer=restricted.example.nil, name=example.nil, addr=10.53.0.1, tcp=0, type=TXT, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: next rule: signer does not match identity
update-policy: trying: grant restricted.example.nil zonesub ANY
update-policy: next rule: name/subdomain mismatch
update-policy: no match found
where 'using:' is the calling parameters of dns_ssutable_checkrules,
'trying:' in the rule bing evaluated, "next rule:" is the reason
the rule does not match, "matched:" repeats the matched rule, and
no match found is reported when te set of rules is exhausted.
2024-05-29 15:04:37 +10:00
|
|
|
isc_buffer_putuint8(&dbuf, '\0');
|
2021-10-06 13:18:16 +02:00
|
|
|
dns_ssutable_addrule(table, grant, dns_fixedname_name(&fident),
|
|
|
|
mtype, dns_fixedname_name(&fname), n,
|
Add per rule logging of dns_ssutable_checkrules processing
These are logged to the update category at debug level 99 and
have the following form.
update-policy: using: signer=ddns-key.example.nil, name=updated.example.nil, addr=10.53.0.1, tcp=0, type=A, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: matched: grant ddns-key.example.nil zonesub ANY
or
update-policy: using: signer=restricted.example.nil, name=example.nil, addr=10.53.0.1, tcp=0, type=TXT, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: next rule: signer does not match identity
update-policy: trying: grant restricted.example.nil zonesub ANY
update-policy: next rule: name/subdomain mismatch
update-policy: no match found
where 'using:' is the calling parameters of dns_ssutable_checkrules,
'trying:' in the rule bing evaluated, "next rule:" is the reason
the rule does not match, "matched:" repeats the matched rule, and
no match found is reported when te set of rules is exhausted.
2024-05-29 15:04:37 +10:00
|
|
|
types, isc_buffer_base(&dbuf));
|
2001-03-04 21:21:39 +00:00
|
|
|
if (types != NULL) {
|
2023-08-23 08:56:31 +02:00
|
|
|
isc_mem_cput(mctx, types, n, sizeof(*types));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2009-06-10 00:27:22 +00:00
|
|
|
}
|
2001-03-04 21:21:39 +00:00
|
|
|
|
2009-06-10 00:27:22 +00:00
|
|
|
/*
|
2009-07-14 22:54:57 +00:00
|
|
|
* If "update-policy local;" and a session key exists,
|
|
|
|
* then use the default policy, which is equivalent to:
|
|
|
|
* update-policy { grant <session-keyname> zonesub any; };
|
2009-06-10 00:27:22 +00:00
|
|
|
*/
|
|
|
|
if (autoddns) {
|
2019-07-03 16:42:15 +10:00
|
|
|
dns_ssuruletype_t any = { dns_rdatatype_any, 0 };
|
2009-06-10 00:27:22 +00:00
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
if (named_g_server->session_keyname == NULL) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL,
|
2017-09-08 13:39:09 -07:00
|
|
|
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
|
2009-06-10 00:27:22 +00:00
|
|
|
"failed to enable auto DDNS policy "
|
|
|
|
"for zone %s: session key not found",
|
|
|
|
zname);
|
|
|
|
result = ISC_R_NOTFOUND;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
Add per rule logging of dns_ssutable_checkrules processing
These are logged to the update category at debug level 99 and
have the following form.
update-policy: using: signer=ddns-key.example.nil, name=updated.example.nil, addr=10.53.0.1, tcp=0, type=A, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: matched: grant ddns-key.example.nil zonesub ANY
or
update-policy: using: signer=restricted.example.nil, name=example.nil, addr=10.53.0.1, tcp=0, type=TXT, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: next rule: signer does not match identity
update-policy: trying: grant restricted.example.nil zonesub ANY
update-policy: next rule: name/subdomain mismatch
update-policy: no match found
where 'using:' is the calling parameters of dns_ssutable_checkrules,
'trying:' in the rule bing evaluated, "next rule:" is the reason
the rule does not match, "matched:" repeats the matched rule, and
no match found is reported when te set of rules is exhausted.
2024-05-29 15:04:37 +10:00
|
|
|
dns_ssutable_addrule(
|
|
|
|
table, true, named_g_server->session_keyname,
|
|
|
|
dns_ssumatchtype_local, dns_zone_getorigin(zone), 1,
|
|
|
|
&any, "local");
|
2000-01-21 19:22:35 +00:00
|
|
|
}
|
2001-03-04 21:21:39 +00:00
|
|
|
|
|
|
|
dns_zone_setssutable(zone, table);
|
|
|
|
|
|
|
|
cleanup:
|
Add per rule logging of dns_ssutable_checkrules processing
These are logged to the update category at debug level 99 and
have the following form.
update-policy: using: signer=ddns-key.example.nil, name=updated.example.nil, addr=10.53.0.1, tcp=0, type=A, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: matched: grant ddns-key.example.nil zonesub ANY
or
update-policy: using: signer=restricted.example.nil, name=example.nil, addr=10.53.0.1, tcp=0, type=TXT, target=
update-policy: trying: grant zonesub-key.example.nil zonesub TXT
update-policy: next rule: signer does not match identity
update-policy: trying: grant ddns-key.example.nil zonesub ANY
update-policy: next rule: signer does not match identity
update-policy: trying: grant restricted.example.nil zonesub ANY
update-policy: next rule: name/subdomain mismatch
update-policy: no match found
where 'using:' is the calling parameters of dns_ssutable_checkrules,
'trying:' in the rule bing evaluated, "next rule:" is the reason
the rule does not match, "matched:" repeats the matched rule, and
no match found is reported when te set of rules is exhausted.
2024-05-29 15:04:37 +10:00
|
|
|
isc_buffer_clearmctx(&dbuf);
|
2001-03-04 21:21:39 +00:00
|
|
|
dns_ssutable_detach(&table);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2010-12-16 09:51:30 +00:00
|
|
|
/*
|
|
|
|
* This is the TTL used for internally generated RRsets for static-stub zones.
|
|
|
|
* The value doesn't matter because the mapping is static, but needs to be
|
|
|
|
* defined for the sake of implementation.
|
|
|
|
*/
|
|
|
|
#define STATICSTUB_SERVER_TTL 86400
|
|
|
|
|
|
|
|
/*%
|
|
|
|
* Configure an apex NS with glues for a static-stub zone.
|
|
|
|
* For example, for the zone named "example.com", the following RRs will be
|
|
|
|
* added to the zone DB:
|
|
|
|
* example.com. NS example.com.
|
|
|
|
* example.com. A 192.0.2.1
|
|
|
|
* example.com. AAAA 2001:db8::1
|
|
|
|
*/
|
|
|
|
static isc_result_t
|
|
|
|
configure_staticstub_serveraddrs(const cfg_obj_t *zconfig, dns_zone_t *zone,
|
|
|
|
dns_rdatalist_t *rdatalist_ns,
|
|
|
|
dns_rdatalist_t *rdatalist_a,
|
|
|
|
dns_rdatalist_t *rdatalist_aaaa) {
|
|
|
|
isc_mem_t *mctx = dns_zone_getmctx(zone);
|
|
|
|
isc_region_t region, sregion;
|
2025-03-26 18:54:05 -07:00
|
|
|
dns_rdata_t *rdata = NULL;
|
2010-12-16 09:51:30 +00:00
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
2020-02-12 13:59:18 +01:00
|
|
|
|
2025-03-26 18:54:05 -07:00
|
|
|
CFG_LIST_FOREACH(zconfig, element) {
|
2010-12-16 09:51:30 +00:00
|
|
|
const isc_sockaddr_t *sa;
|
|
|
|
isc_netaddr_t na;
|
|
|
|
const cfg_obj_t *address = cfg_listelt_value(element);
|
|
|
|
dns_rdatalist_t *rdatalist;
|
|
|
|
|
|
|
|
sa = cfg_obj_assockaddr(address);
|
|
|
|
if (isc_sockaddr_getport(sa) != 0) {
|
2024-08-13 18:20:26 +02:00
|
|
|
cfg_obj_log(zconfig, ISC_LOG_ERROR,
|
2010-12-16 09:51:30 +00:00
|
|
|
"port is not configurable for "
|
|
|
|
"static stub server-addresses");
|
|
|
|
return ISC_R_FAILURE;
|
|
|
|
}
|
|
|
|
isc_netaddr_fromsockaddr(&na, sa);
|
|
|
|
if (isc_netaddr_getzone(&na) != 0) {
|
2024-08-13 18:20:26 +02:00
|
|
|
cfg_obj_log(zconfig, ISC_LOG_ERROR,
|
2010-12-16 09:51:30 +00:00
|
|
|
"scoped address is not allowed "
|
|
|
|
"for static stub "
|
|
|
|
"server-addresses");
|
|
|
|
return ISC_R_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (na.family) {
|
|
|
|
case AF_INET:
|
|
|
|
region.length = sizeof(na.type.in);
|
|
|
|
rdatalist = rdatalist_a;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
INSIST(na.family == AF_INET6);
|
|
|
|
region.length = sizeof(na.type.in6);
|
|
|
|
rdatalist = rdatalist_aaaa;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
rdata = isc_mem_get(mctx, sizeof(*rdata) + region.length);
|
|
|
|
region.base = (unsigned char *)(rdata + 1);
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(region.base, &na.type, region.length);
|
2010-12-16 09:51:30 +00:00
|
|
|
dns_rdata_init(rdata);
|
|
|
|
dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
|
|
|
|
rdatalist->type, ®ion);
|
|
|
|
ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If no address is specified (unlikely in this context, but possible),
|
|
|
|
* there's nothing to do anymore.
|
|
|
|
*/
|
|
|
|
if (ISC_LIST_EMPTY(rdatalist_a->rdata) &&
|
2022-11-02 19:33:14 +01:00
|
|
|
ISC_LIST_EMPTY(rdatalist_aaaa->rdata))
|
|
|
|
{
|
2010-12-16 09:51:30 +00:00
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add to the list an apex NS with the ns name being the origin name */
|
|
|
|
dns_name_toregion(dns_zone_getorigin(zone), &sregion);
|
|
|
|
rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length);
|
|
|
|
region.length = sregion.length;
|
|
|
|
region.base = (unsigned char *)(rdata + 1);
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(region.base, sregion.base, region.length);
|
2010-12-16 09:51:30 +00:00
|
|
|
dns_rdata_init(rdata);
|
|
|
|
dns_rdata_fromregion(rdata, dns_zone_getclass(zone), dns_rdatatype_ns,
|
|
|
|
®ion);
|
|
|
|
ISC_LIST_APPEND(rdatalist_ns->rdata, rdata, link);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*%
|
|
|
|
* Configure an apex NS with an out-of-zone NS names for a static-stub zone.
|
|
|
|
* For example, for the zone named "example.com", something like the following
|
|
|
|
* RRs will be added to the zone DB:
|
|
|
|
* example.com. NS ns.example.net.
|
|
|
|
*/
|
|
|
|
static isc_result_t
|
|
|
|
configure_staticstub_servernames(const cfg_obj_t *zconfig, dns_zone_t *zone,
|
|
|
|
dns_rdatalist_t *rdatalist,
|
|
|
|
const char *zname) {
|
|
|
|
isc_mem_t *mctx = dns_zone_getmctx(zone);
|
2025-03-26 18:54:05 -07:00
|
|
|
dns_rdata_t *rdata = NULL;
|
2010-12-16 09:51:30 +00:00
|
|
|
isc_region_t sregion, region;
|
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
2020-02-12 13:59:18 +01:00
|
|
|
|
2025-03-26 18:54:05 -07:00
|
|
|
CFG_LIST_FOREACH(zconfig, element) {
|
|
|
|
const cfg_obj_t *obj = NULL;
|
|
|
|
const char *str = NULL;
|
2010-12-16 09:51:30 +00:00
|
|
|
dns_fixedname_t fixed_name;
|
2025-03-26 18:54:05 -07:00
|
|
|
dns_name_t *nsname = NULL;
|
2010-12-16 09:51:30 +00:00
|
|
|
isc_buffer_t b;
|
|
|
|
|
|
|
|
obj = cfg_listelt_value(element);
|
|
|
|
str = cfg_obj_asstring(obj);
|
|
|
|
|
2018-03-28 14:38:09 +02:00
|
|
|
nsname = dns_fixedname_initname(&fixed_name);
|
2010-12-16 09:51:30 +00:00
|
|
|
|
2012-12-08 12:48:57 +11:00
|
|
|
isc_buffer_constinit(&b, str, strlen(str));
|
2010-12-16 09:51:30 +00:00
|
|
|
isc_buffer_add(&b, strlen(str));
|
2025-02-22 00:11:38 -08:00
|
|
|
result = dns_name_fromtext(nsname, &b, dns_rootname, 0);
|
2010-12-16 09:51:30 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2024-08-13 18:20:26 +02:00
|
|
|
cfg_obj_log(zconfig, ISC_LOG_ERROR,
|
2010-12-16 09:51:30 +00:00
|
|
|
"server-name '%s' is not a valid "
|
|
|
|
"name",
|
|
|
|
str);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
if (dns_name_issubdomain(nsname, dns_zone_getorigin(zone))) {
|
2024-08-13 18:20:26 +02:00
|
|
|
cfg_obj_log(zconfig, ISC_LOG_ERROR,
|
2010-12-16 09:51:30 +00:00
|
|
|
"server-name '%s' must not be a "
|
|
|
|
"subdomain of zone name '%s'",
|
|
|
|
str, zname);
|
|
|
|
return ISC_R_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
dns_name_toregion(nsname, &sregion);
|
|
|
|
rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length);
|
|
|
|
region.length = sregion.length;
|
|
|
|
region.base = (unsigned char *)(rdata + 1);
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(region.base, sregion.base, region.length);
|
2010-12-16 09:51:30 +00:00
|
|
|
dns_rdata_init(rdata);
|
|
|
|
dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
|
|
|
|
dns_rdatatype_ns, ®ion);
|
|
|
|
ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*%
|
|
|
|
* Configure static-stub zone.
|
|
|
|
*/
|
|
|
|
static isc_result_t
|
2025-04-15 13:39:57 -07:00
|
|
|
configure_staticstub(const cfg_obj_t *zconfig, const cfg_obj_t *tconfig,
|
|
|
|
dns_zone_t *zone, const char *zname, const char *dbtype) {
|
2010-12-16 23:47:08 +00:00
|
|
|
int i = 0;
|
2010-12-16 09:51:30 +00:00
|
|
|
const cfg_obj_t *obj;
|
|
|
|
isc_mem_t *mctx = dns_zone_getmctx(zone);
|
|
|
|
dns_db_t *db = NULL;
|
|
|
|
dns_dbversion_t *dbversion = NULL;
|
|
|
|
dns_dbnode_t *apexnode = NULL;
|
|
|
|
dns_name_t apexname;
|
|
|
|
isc_result_t result;
|
|
|
|
dns_rdataset_t rdataset;
|
|
|
|
dns_rdatalist_t rdatalist_ns, rdatalist_a, rdatalist_aaaa;
|
|
|
|
dns_rdatalist_t *rdatalists[] = { &rdatalist_ns, &rdatalist_a,
|
|
|
|
&rdatalist_aaaa, NULL };
|
|
|
|
isc_region_t region;
|
|
|
|
|
|
|
|
/* Create the DB beforehand */
|
2024-12-09 15:10:53 +01:00
|
|
|
result = dns_db_create(mctx, dbtype, dns_zone_getorigin(zone),
|
|
|
|
dns_dbtype_stub, dns_zone_getclass(zone), 0,
|
|
|
|
NULL, &db);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
return result;
|
|
|
|
}
|
2019-09-04 14:02:33 +10:00
|
|
|
|
|
|
|
dns_rdataset_init(&rdataset);
|
2010-12-16 09:51:30 +00:00
|
|
|
|
|
|
|
dns_rdatalist_init(&rdatalist_ns);
|
|
|
|
rdatalist_ns.rdclass = dns_zone_getclass(zone);
|
|
|
|
rdatalist_ns.type = dns_rdatatype_ns;
|
|
|
|
rdatalist_ns.ttl = STATICSTUB_SERVER_TTL;
|
|
|
|
|
|
|
|
dns_rdatalist_init(&rdatalist_a);
|
|
|
|
rdatalist_a.rdclass = dns_zone_getclass(zone);
|
|
|
|
rdatalist_a.type = dns_rdatatype_a;
|
|
|
|
rdatalist_a.ttl = STATICSTUB_SERVER_TTL;
|
|
|
|
|
|
|
|
dns_rdatalist_init(&rdatalist_aaaa);
|
|
|
|
rdatalist_aaaa.rdclass = dns_zone_getclass(zone);
|
|
|
|
rdatalist_aaaa.type = dns_rdatatype_aaaa;
|
|
|
|
rdatalist_aaaa.ttl = STATICSTUB_SERVER_TTL;
|
|
|
|
|
|
|
|
/* Prepare zone RRs from the configuration */
|
|
|
|
obj = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
(void)named_config_findopt(zconfig, tconfig, "server-addresses", &obj);
|
|
|
|
if (obj != NULL) {
|
2019-09-04 14:02:33 +10:00
|
|
|
CHECK(configure_staticstub_serveraddrs(obj, zone, &rdatalist_ns,
|
|
|
|
&rdatalist_a,
|
|
|
|
&rdatalist_aaaa));
|
2010-12-16 09:51:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
obj = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
(void)named_config_findopt(zconfig, tconfig, "server-names", &obj);
|
|
|
|
if (obj != NULL) {
|
2019-09-04 14:02:33 +10:00
|
|
|
CHECK(configure_staticstub_servernames(obj, zone, &rdatalist_ns,
|
|
|
|
zname));
|
2010-12-16 09:51:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Sanity check: there should be at least one NS RR at the zone apex
|
|
|
|
* to trigger delegation.
|
|
|
|
*/
|
|
|
|
if (ISC_LIST_EMPTY(rdatalist_ns.rdata)) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
|
|
|
ISC_LOG_ERROR,
|
2010-12-16 09:51:30 +00:00
|
|
|
"No NS record is configured for a "
|
|
|
|
"static-stub zone '%s'",
|
|
|
|
zname);
|
|
|
|
result = ISC_R_FAILURE;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Now add NS and glue A/AAAA RRsets to the zone DB.
|
|
|
|
* First open a new version for the add operation and get a pointer
|
|
|
|
* to the apex node (all RRs are of the apex name).
|
|
|
|
*/
|
2019-09-04 14:02:33 +10:00
|
|
|
CHECK(dns_db_newversion(db, &dbversion));
|
|
|
|
|
2025-02-21 12:09:39 +01:00
|
|
|
dns_name_init(&apexname);
|
2010-12-16 09:51:30 +00:00
|
|
|
dns_name_clone(dns_zone_getorigin(zone), &apexname);
|
2019-09-04 14:02:33 +10:00
|
|
|
CHECK(dns_db_findnode(db, &apexname, false, &apexnode));
|
2010-12-16 09:51:30 +00:00
|
|
|
|
|
|
|
/* Add NS RRset */
|
2022-07-29 12:40:45 +00:00
|
|
|
dns_rdatalist_tordataset(&rdatalist_ns, &rdataset);
|
2019-09-04 14:02:33 +10:00
|
|
|
CHECK(dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset, 0,
|
|
|
|
NULL));
|
2010-12-16 09:51:30 +00:00
|
|
|
dns_rdataset_disassociate(&rdataset);
|
|
|
|
|
|
|
|
/* Add glue A RRset, if any */
|
|
|
|
if (!ISC_LIST_EMPTY(rdatalist_a.rdata)) {
|
2022-07-29 12:40:45 +00:00
|
|
|
dns_rdatalist_tordataset(&rdatalist_a, &rdataset);
|
2019-09-04 14:02:33 +10:00
|
|
|
CHECK(dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset,
|
|
|
|
0, NULL));
|
2010-12-16 09:51:30 +00:00
|
|
|
dns_rdataset_disassociate(&rdataset);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add glue AAAA RRset, if any */
|
|
|
|
if (!ISC_LIST_EMPTY(rdatalist_aaaa.rdata)) {
|
2022-07-29 12:40:45 +00:00
|
|
|
dns_rdatalist_tordataset(&rdatalist_aaaa, &rdataset);
|
2019-09-04 14:02:33 +10:00
|
|
|
CHECK(dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset,
|
|
|
|
0, NULL));
|
2010-12-16 09:51:30 +00:00
|
|
|
dns_rdataset_disassociate(&rdataset);
|
|
|
|
}
|
|
|
|
|
2019-09-04 14:02:33 +10:00
|
|
|
dns_db_closeversion(db, &dbversion, true);
|
|
|
|
dns_zone_setdb(zone, db);
|
|
|
|
|
2010-12-16 09:51:30 +00:00
|
|
|
result = ISC_R_SUCCESS;
|
|
|
|
|
|
|
|
cleanup:
|
2019-09-04 14:02:33 +10:00
|
|
|
if (dns_rdataset_isassociated(&rdataset)) {
|
|
|
|
dns_rdataset_disassociate(&rdataset);
|
|
|
|
}
|
|
|
|
if (apexnode != NULL) {
|
Decouple database and node lifetimes by adding node-specific vtables
All databases in the codebase follow the same structure: a database is
an associative container from DNS names to nodes, and each node is an
associative container from RR types to RR data.
Each database implementation (qpzone, qpcache, sdlz, builtin, dyndb) has
its own corresponding node type (qpznode, qpcnode, etc). However, some
code needs to work with nodes generically regardless of their specific
type - for example, to acquire locks, manage references, or
register/unregister slabs from the heap.
Currently, these generic node operations are implemented as methods in
the database vtable, which creates problematic coupling between database
and node lifetimes. If a node outlives its parent database, the node
destructor will destroy all RR data, and each RR data destructor will
try to unregister from heaps by calling a virtual function from the
database vtable. Since the database was already freed, this causes a
crash.
This commit breaks the coupling by standardizing the layout of all
database nodes, adding a dedicated vtable for node operations, and
moving node-specific methods from the database vtable to the node
vtable.
2025-06-05 11:51:29 +02:00
|
|
|
dns_db_detachnode(&apexnode);
|
2019-09-04 14:02:33 +10:00
|
|
|
}
|
|
|
|
if (dbversion != NULL) {
|
|
|
|
dns_db_closeversion(db, &dbversion, false);
|
|
|
|
}
|
|
|
|
if (db != NULL) {
|
2010-12-16 09:51:30 +00:00
|
|
|
dns_db_detach(&db);
|
2019-09-04 14:02:33 +10:00
|
|
|
}
|
2010-12-16 09:51:30 +00:00
|
|
|
for (i = 0; rdatalists[i] != NULL; i++) {
|
2025-05-23 13:02:22 -07:00
|
|
|
ISC_LIST_FOREACH(rdatalists[i]->rdata, rdata, link) {
|
2010-12-16 09:51:30 +00:00
|
|
|
ISC_LIST_UNLINK(rdatalists[i]->rdata, rdata, link);
|
|
|
|
dns_rdata_toregion(rdata, ®ion);
|
|
|
|
isc_mem_put(mctx, rdata,
|
|
|
|
sizeof(*rdata) + region.length);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-03 07:50:09 +10:00
|
|
|
INSIST(dbversion == NULL);
|
|
|
|
|
2010-12-16 09:51:30 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
2001-03-04 21:21:39 +00:00
|
|
|
* Convert a config file zone type into a server zone type.
|
|
|
|
*/
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_zonetype_t
|
2025-04-15 13:39:57 -07:00
|
|
|
zonetype_fromconfig(const cfg_obj_t *zmap, const cfg_obj_t *tmap) {
|
2006-02-28 02:39:52 +00:00
|
|
|
const cfg_obj_t *obj = NULL;
|
2001-03-04 21:21:39 +00:00
|
|
|
|
2025-04-15 13:39:57 -07:00
|
|
|
(void)named_config_findopt(zmap, tmap, "type", &obj);
|
|
|
|
INSIST(obj != NULL);
|
2017-09-08 13:39:09 -07:00
|
|
|
return named_config_getzonetype(obj);
|
2000-01-21 19:22:35 +00:00
|
|
|
}
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
2000-08-10 00:53:36 +00:00
|
|
|
* Helper function for strtoargv(). Pardon the gratuitous recursion.
|
|
|
|
*/
|
|
|
|
static isc_result_t
|
2000-08-14 03:50:59 +00:00
|
|
|
strtoargvsub(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp,
|
|
|
|
unsigned int n) {
|
2000-08-10 00:53:36 +00:00
|
|
|
isc_result_t result;
|
2008-01-18 23:46:58 +00:00
|
|
|
|
2000-08-10 00:53:36 +00:00
|
|
|
/* Discard leading whitespace. */
|
|
|
|
while (*s == ' ' || *s == '\t') {
|
|
|
|
s++;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-01-18 23:46:58 +00:00
|
|
|
|
2000-08-10 00:53:36 +00:00
|
|
|
if (*s == '\0') {
|
|
|
|
/* We have reached the end of the string. */
|
|
|
|
*argcp = n;
|
2023-08-23 08:56:31 +02:00
|
|
|
*argvp = isc_mem_cget(mctx, n, sizeof(char *));
|
2000-08-10 00:53:36 +00:00
|
|
|
} else {
|
|
|
|
char *p = s;
|
|
|
|
while (*p != ' ' && *p != '\t' && *p != '\0') {
|
|
|
|
p++;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-10 00:53:36 +00:00
|
|
|
if (*p != '\0') {
|
|
|
|
*p++ = '\0';
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-10 00:53:36 +00:00
|
|
|
|
|
|
|
result = strtoargvsub(mctx, p, argcp, argvp, n + 1);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
return result;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-10 00:53:36 +00:00
|
|
|
(*argvp)[n] = s;
|
|
|
|
}
|
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
2000-08-10 00:53:36 +00:00
|
|
|
* Tokenize the string "s" into whitespace-separated words,
|
|
|
|
* return the number of words in '*argcp' and an array
|
|
|
|
* of pointers to the words in '*argvp'. The caller
|
|
|
|
* must free the array using isc_mem_put(). The string
|
|
|
|
* is modified in-place.
|
|
|
|
*/
|
|
|
|
static isc_result_t
|
2000-08-14 03:50:59 +00:00
|
|
|
strtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp) {
|
2000-08-10 00:53:36 +00:00
|
|
|
return strtoargvsub(mctx, s, argcp, argvp, 0);
|
|
|
|
}
|
|
|
|
|
2021-09-19 09:11:15 +10:00
|
|
|
static const char *const primary_synonyms[] = { "primary", "master", NULL };
|
|
|
|
|
|
|
|
static const char *const secondary_synonyms[] = { "secondary", "slave", NULL };
|
|
|
|
|
2004-02-27 20:41:51 +00:00
|
|
|
static void
|
2006-02-28 02:39:52 +00:00
|
|
|
checknames(dns_zonetype_t ztype, const cfg_obj_t **maps,
|
|
|
|
const cfg_obj_t **objp) {
|
2004-04-20 14:11:47 +00:00
|
|
|
isc_result_t result;
|
2004-02-27 20:41:51 +00:00
|
|
|
|
|
|
|
switch (ztype) {
|
2021-08-25 22:29:25 -07:00
|
|
|
case dns_zone_secondary:
|
2018-10-09 10:54:51 +02:00
|
|
|
case dns_zone_mirror:
|
2021-09-19 09:11:15 +10:00
|
|
|
result = named_checknames_get(maps, secondary_synonyms, objp);
|
2018-10-09 10:54:51 +02:00
|
|
|
break;
|
2021-08-25 22:29:25 -07:00
|
|
|
case dns_zone_primary:
|
2021-09-19 09:11:15 +10:00
|
|
|
result = named_checknames_get(maps, primary_synonyms, objp);
|
2018-10-09 10:54:51 +02:00
|
|
|
break;
|
2004-02-27 20:41:51 +00:00
|
|
|
default:
|
2021-10-11 12:50:17 +02:00
|
|
|
UNREACHABLE();
|
2004-02-27 20:41:51 +00:00
|
|
|
}
|
2020-06-16 17:48:42 -07:00
|
|
|
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && objp != NULL && *objp != NULL);
|
2004-02-27 20:41:51 +00:00
|
|
|
}
|
|
|
|
|
2017-09-08 13:39:09 -07:00
|
|
|
/*
|
|
|
|
* Callback to see if a non-recursive query coming from 'srcaddr' to
|
|
|
|
* 'destaddr', with optional key 'mykey' for class 'rdclass' would be
|
|
|
|
* delivered to 'myview'.
|
|
|
|
*
|
|
|
|
* We run this unlocked as both the view list and the interface list
|
|
|
|
* are updated when the appropriate task has exclusivity.
|
|
|
|
*/
|
2018-04-17 08:29:14 -07:00
|
|
|
static bool
|
2017-09-08 13:39:09 -07:00
|
|
|
isself(dns_view_t *myview, dns_tsigkey_t *mykey, const isc_sockaddr_t *srcaddr,
|
Fix an interfacemgr use-after-free error in zoneconf.c:isself()
The 'named_g_server->interfacemgr' pointer is saved in the zone
structure using dns_zone_setisself(), as a void* argument to be
passed to the isself() callback, so there is no attach/detach,
and when shutting down, the interface manager can be destroyed
by the shutdown_server(), running in exclusive mode, and causing
isself() to crash when trying to use the pointer.
Instead of keeping the interface manager pointer in the zone
structure, just check and use the 'named_g_server->interfacemgr'
itself, as it was implemented originally in the
3aca8e5bf3740bbcc3bb13dde242d7cc369abb27 commit. Later, in the
8eb88aafee951859264e36c315b1289cd8c2088b commit, the code was
changed to pass the interface manager pointer using the additional
void* argument, but the commit message doesn't mention if there
was any practical reason for that.
Additionally, don't pass the interfacemgr pointer to the
ns_interfacemgr_getaclenv() function before it is checked
against NULL.
2023-05-24 14:26:04 +00:00
|
|
|
const isc_sockaddr_t *dstaddr, dns_rdataclass_t rdclass,
|
|
|
|
void *arg ISC_ATTR_UNUSED) {
|
|
|
|
dns_aclenv_t *env = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
dns_tsigkey_t *key = NULL;
|
|
|
|
isc_netaddr_t netsrc;
|
|
|
|
isc_netaddr_t netdst;
|
|
|
|
|
Fix an interfacemgr use-after-free error in zoneconf.c:isself()
The 'named_g_server->interfacemgr' pointer is saved in the zone
structure using dns_zone_setisself(), as a void* argument to be
passed to the isself() callback, so there is no attach/detach,
and when shutting down, the interface manager can be destroyed
by the shutdown_server(), running in exclusive mode, and causing
isself() to crash when trying to use the pointer.
Instead of keeping the interface manager pointer in the zone
structure, just check and use the 'named_g_server->interfacemgr'
itself, as it was implemented originally in the
3aca8e5bf3740bbcc3bb13dde242d7cc369abb27 commit. Later, in the
8eb88aafee951859264e36c315b1289cd8c2088b commit, the code was
changed to pass the interface manager pointer using the additional
void* argument, but the commit message doesn't mention if there
was any practical reason for that.
Additionally, don't pass the interfacemgr pointer to the
ns_interfacemgr_getaclenv() function before it is checked
against NULL.
2023-05-24 14:26:04 +00:00
|
|
|
/* interfacemgr can be destroyed only in exclusive mode. */
|
|
|
|
if (named_g_server->interfacemgr == NULL) {
|
2018-04-17 08:29:14 -07:00
|
|
|
return true;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-09-08 13:39:09 -07:00
|
|
|
|
Fix an interfacemgr use-after-free error in zoneconf.c:isself()
The 'named_g_server->interfacemgr' pointer is saved in the zone
structure using dns_zone_setisself(), as a void* argument to be
passed to the isself() callback, so there is no attach/detach,
and when shutting down, the interface manager can be destroyed
by the shutdown_server(), running in exclusive mode, and causing
isself() to crash when trying to use the pointer.
Instead of keeping the interface manager pointer in the zone
structure, just check and use the 'named_g_server->interfacemgr'
itself, as it was implemented originally in the
3aca8e5bf3740bbcc3bb13dde242d7cc369abb27 commit. Later, in the
8eb88aafee951859264e36c315b1289cd8c2088b commit, the code was
changed to pass the interface manager pointer using the additional
void* argument, but the commit message doesn't mention if there
was any practical reason for that.
Additionally, don't pass the interfacemgr pointer to the
ns_interfacemgr_getaclenv() function before it is checked
against NULL.
2023-05-24 14:26:04 +00:00
|
|
|
if (!ns_interfacemgr_listeningon(named_g_server->interfacemgr, dstaddr))
|
|
|
|
{
|
2018-04-17 08:29:14 -07:00
|
|
|
return false;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-09-08 13:39:09 -07:00
|
|
|
|
|
|
|
isc_netaddr_fromsockaddr(&netsrc, srcaddr);
|
|
|
|
isc_netaddr_fromsockaddr(&netdst, dstaddr);
|
Fix an interfacemgr use-after-free error in zoneconf.c:isself()
The 'named_g_server->interfacemgr' pointer is saved in the zone
structure using dns_zone_setisself(), as a void* argument to be
passed to the isself() callback, so there is no attach/detach,
and when shutting down, the interface manager can be destroyed
by the shutdown_server(), running in exclusive mode, and causing
isself() to crash when trying to use the pointer.
Instead of keeping the interface manager pointer in the zone
structure, just check and use the 'named_g_server->interfacemgr'
itself, as it was implemented originally in the
3aca8e5bf3740bbcc3bb13dde242d7cc369abb27 commit. Later, in the
8eb88aafee951859264e36c315b1289cd8c2088b commit, the code was
changed to pass the interface manager pointer using the additional
void* argument, but the commit message doesn't mention if there
was any practical reason for that.
Additionally, don't pass the interfacemgr pointer to the
ns_interfacemgr_getaclenv() function before it is checked
against NULL.
2023-05-24 14:26:04 +00:00
|
|
|
env = ns_interfacemgr_getaclenv(named_g_server->interfacemgr);
|
2017-09-08 13:39:09 -07:00
|
|
|
|
2025-03-20 22:25:56 -07:00
|
|
|
ISC_LIST_FOREACH(named_g_server->viewlist, view, link) {
|
2019-09-27 09:39:35 +02:00
|
|
|
const dns_name_t *tsig = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
|
|
|
|
if (view->matchrecursiveonly) {
|
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-09-08 13:39:09 -07:00
|
|
|
|
|
|
|
if (rdclass != view->rdclass) {
|
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-09-08 13:39:09 -07:00
|
|
|
|
|
|
|
if (mykey != NULL) {
|
2018-04-17 08:29:14 -07:00
|
|
|
bool match;
|
2017-09-08 13:39:09 -07:00
|
|
|
isc_result_t result;
|
|
|
|
|
2023-04-12 00:14:04 -07:00
|
|
|
result = dns_view_gettsig(view, mykey->name, &key);
|
2017-09-08 13:39:09 -07:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-09-08 13:39:09 -07:00
|
|
|
match = dst_key_compare(mykey->key, key->key);
|
|
|
|
dns_tsigkey_detach(&key);
|
|
|
|
if (!match) {
|
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-09-08 13:39:09 -07:00
|
|
|
tsig = dns_tsigkey_identity(mykey);
|
|
|
|
}
|
|
|
|
|
2018-04-26 20:57:41 -07:00
|
|
|
if (dns_acl_allowed(&netsrc, tsig, view->matchclients, env) &&
|
|
|
|
dns_acl_allowed(&netdst, tsig, view->matchdestinations,
|
|
|
|
env))
|
|
|
|
{
|
2025-03-20 22:25:56 -07:00
|
|
|
return view == myview;
|
2018-04-26 20:57:41 -07:00
|
|
|
}
|
2017-09-08 13:39:09 -07:00
|
|
|
}
|
2025-03-20 22:25:56 -07:00
|
|
|
|
|
|
|
return false;
|
2017-09-08 13:39:09 -07:00
|
|
|
}
|
|
|
|
|
Clean up handling of NOTIFY settings for mirror zones
Previous way of handling NOTIFY settings for mirror zones was a bit
tricky: any value of the "notify" option was accepted, but it was
subsequently overridden with dns_notifytype_explicit. Given the way
zone configuration is performed, this resulted in the following
behavior:
- if "notify yes;" was set explicitly at any configuration level or
inherited from default configuration, it was silently changed and so
only hosts specified in "also-notify", if any, were notified,
- if "notify no;" was set at any configuration level, it was
effectively honored since even though zone->notifytype was silently
set to dns_notifytype_explicit, the "also-notify" option was never
processed due to "notify no;" being set.
Effectively, this only allowed the hosts specified in "also-notify" to
be notified, when either "notify yes;" or "notify explicit;" was
explicitly set or inherited from default configuration.
Clean up handling of NOTIFY settings for mirror zones by:
- reporting a configuration error when anything else than "notify no;"
or "notify explicit;" is set for a mirror zone at the zone level,
- overriding inherited "notify yes;" setting with "notify explicit;"
for mirror zones,
- informing the user when the "notify" setting is overridden, unless
the setting in question was inherited from default configuration.
2018-10-09 10:54:51 +02:00
|
|
|
/*%
|
|
|
|
* For mirror zones, change "notify yes;" to "notify explicit;", informing the
|
|
|
|
* user only if "notify" was explicitly configured rather than inherited from
|
|
|
|
* default configuration.
|
|
|
|
*/
|
|
|
|
static dns_notifytype_t
|
|
|
|
process_notifytype(dns_notifytype_t ntype, dns_zonetype_t ztype,
|
|
|
|
const char *zname, const cfg_obj_t **maps) {
|
|
|
|
const cfg_obj_t *obj = NULL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return the original setting if this is not a mirror zone or if the
|
|
|
|
* zone is configured with something else than "notify yes;".
|
|
|
|
*/
|
|
|
|
if (ztype != dns_zone_mirror || ntype != dns_notifytype_yes) {
|
|
|
|
return ntype;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Only log a message if "notify" was set in the configuration
|
|
|
|
* hierarchy supplied in 'maps'.
|
|
|
|
*/
|
|
|
|
if (named_config_get(maps, "notify", &obj) == ISC_R_SUCCESS) {
|
2024-08-13 18:20:26 +02:00
|
|
|
cfg_obj_log(obj, ISC_LOG_INFO,
|
Clean up handling of NOTIFY settings for mirror zones
Previous way of handling NOTIFY settings for mirror zones was a bit
tricky: any value of the "notify" option was accepted, but it was
subsequently overridden with dns_notifytype_explicit. Given the way
zone configuration is performed, this resulted in the following
behavior:
- if "notify yes;" was set explicitly at any configuration level or
inherited from default configuration, it was silently changed and so
only hosts specified in "also-notify", if any, were notified,
- if "notify no;" was set at any configuration level, it was
effectively honored since even though zone->notifytype was silently
set to dns_notifytype_explicit, the "also-notify" option was never
processed due to "notify no;" being set.
Effectively, this only allowed the hosts specified in "also-notify" to
be notified, when either "notify yes;" or "notify explicit;" was
explicitly set or inherited from default configuration.
Clean up handling of NOTIFY settings for mirror zones by:
- reporting a configuration error when anything else than "notify no;"
or "notify explicit;" is set for a mirror zone at the zone level,
- overriding inherited "notify yes;" setting with "notify explicit;"
for mirror zones,
- informing the user when the "notify" setting is overridden, unless
the setting in question was inherited from default configuration.
2018-10-09 10:54:51 +02:00
|
|
|
"'notify explicit;' will be used for mirror zone "
|
|
|
|
"'%s'",
|
|
|
|
zname);
|
|
|
|
}
|
|
|
|
|
|
|
|
return dns_notifytype_explicit;
|
|
|
|
}
|
2017-09-08 13:39:09 -07:00
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
2017-09-08 13:39:09 -07:00
|
|
|
named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
2019-09-03 11:42:10 +02:00
|
|
|
const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac,
|
2022-03-09 10:55:48 +01:00
|
|
|
dns_kasplist_t *kasplist, dns_keystorelist_t *keystorelist,
|
|
|
|
dns_zone_t *zone, dns_zone_t *raw) {
|
1999-12-16 23:11:07 +00:00
|
|
|
isc_result_t result;
|
2005-08-23 02:36:11 +00:00
|
|
|
const char *zname;
|
2001-03-04 21:21:39 +00:00
|
|
|
dns_rdataclass_t zclass;
|
2001-08-07 01:58:59 +00:00
|
|
|
dns_rdataclass_t vclass;
|
2025-04-15 13:39:57 -07:00
|
|
|
const cfg_obj_t *maps[6];
|
|
|
|
const cfg_obj_t *nodefault[5];
|
|
|
|
const cfg_obj_t *nooptions[3];
|
2006-02-28 02:39:52 +00:00
|
|
|
const cfg_obj_t *zoptions = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
const cfg_obj_t *toptions = NULL;
|
2006-02-28 02:39:52 +00:00
|
|
|
const cfg_obj_t *options = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
const cfg_obj_t *obj = NULL;
|
1999-12-16 23:11:07 +00:00
|
|
|
const char *filename = NULL;
|
2025-04-13 00:28:49 -07:00
|
|
|
const char *initial_file = NULL;
|
2019-09-03 11:42:10 +02:00
|
|
|
const char *kaspname = NULL;
|
2012-06-20 14:13:12 -05:00
|
|
|
const char *dupcheck;
|
2023-03-28 16:54:47 +02:00
|
|
|
dns_checkdstype_t checkdstype = dns_checkdstype_yes;
|
2001-03-05 12:04:46 +00:00
|
|
|
dns_notifytype_t notifytype = dns_notifytype_yes;
|
2018-03-28 14:19:37 +02:00
|
|
|
uint32_t count;
|
2000-08-10 00:53:36 +00:00
|
|
|
unsigned int dbargc;
|
|
|
|
char **dbargv;
|
2024-03-05 16:17:33 -08:00
|
|
|
static char default_dbtype[] = ZONEDB_DEFAULT;
|
2012-12-06 12:39:52 -08:00
|
|
|
static char dlz_dbtype[] = "dlz";
|
|
|
|
char *cpval = default_dbtype;
|
2000-08-10 00:53:36 +00:00
|
|
|
isc_mem_t *mctx = dns_zone_getmctx(zone);
|
2001-03-04 21:21:39 +00:00
|
|
|
dns_zonetype_t ztype;
|
|
|
|
int i;
|
2018-03-28 14:19:37 +02:00
|
|
|
int32_t journal_size;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool multi;
|
2019-09-03 11:42:10 +02:00
|
|
|
dns_kasp_t *kasp = NULL;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool check = false, fail = false;
|
|
|
|
bool warn = false, ignore = false;
|
|
|
|
bool ixfrdiff;
|
2020-12-03 15:01:42 +01:00
|
|
|
bool use_kasp = false;
|
2005-06-20 01:05:33 +00:00
|
|
|
dns_masterformat_t masterformat;
|
2014-04-17 17:10:29 -07:00
|
|
|
const dns_master_style_t *masterstyle = &dns_master_style_default;
|
2009-01-27 22:30:00 +00:00
|
|
|
isc_stats_t *zoneqrystats;
|
2012-11-14 12:44:15 -06:00
|
|
|
dns_stats_t *rcvquerystats;
|
2019-06-19 16:02:50 +02:00
|
|
|
dns_stats_t *dnssecsignstats;
|
2018-06-04 13:41:09 +02:00
|
|
|
dns_zonestat_level_t statlevel = dns_zonestat_none;
|
2022-07-13 10:28:59 +02:00
|
|
|
dns_ttl_t maxttl = 0; /* unlimited */
|
2011-08-30 05:16:15 +00:00
|
|
|
dns_zone_t *mayberaw = (raw != NULL) ? raw : zone;
|
2023-04-17 12:22:38 +00:00
|
|
|
bool transferinsecs = ns_server_getoption(named_g_server->sctx,
|
|
|
|
NS_SERVER_TRANSFERINSECS);
|
2000-07-31 19:36:48 +00:00
|
|
|
|
2025-04-15 13:39:57 -07:00
|
|
|
REQUIRE(config != NULL);
|
|
|
|
REQUIRE(zconfig != NULL);
|
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
i = 0;
|
2025-04-15 13:39:57 -07:00
|
|
|
|
|
|
|
zoptions = cfg_tuple_get(zconfig, "options");
|
|
|
|
INSIST(zoptions != NULL);
|
|
|
|
nodefault[i] = nooptions[i] = maps[i] = zoptions;
|
|
|
|
i++;
|
|
|
|
|
|
|
|
toptions = named_zone_templateopts(config, zoptions);
|
|
|
|
if (toptions != NULL) {
|
|
|
|
nodefault[i] = nooptions[i] = maps[i] = toptions;
|
2012-06-20 14:13:12 -05:00
|
|
|
i++;
|
|
|
|
}
|
2025-04-15 13:39:57 -07:00
|
|
|
|
|
|
|
nooptions[i] = NULL;
|
2012-06-20 14:13:12 -05:00
|
|
|
if (vconfig != NULL) {
|
|
|
|
nodefault[i] = maps[i] = cfg_tuple_get(vconfig, "options");
|
|
|
|
i++;
|
2001-03-04 21:21:39 +00:00
|
|
|
}
|
2025-04-15 13:39:57 -07:00
|
|
|
|
|
|
|
(void)cfg_map_get(config, "options", &options);
|
|
|
|
if (options != NULL) {
|
|
|
|
nodefault[i] = maps[i] = options;
|
|
|
|
i++;
|
2001-03-04 21:21:39 +00:00
|
|
|
}
|
2025-04-15 13:39:57 -07:00
|
|
|
|
2012-06-20 14:13:12 -05:00
|
|
|
nodefault[i] = NULL;
|
2025-04-22 13:46:47 +02:00
|
|
|
maps[i++] = named_g_defaultoptions;
|
2011-03-11 06:11:27 +00:00
|
|
|
maps[i] = NULL;
|
2001-08-07 01:58:59 +00:00
|
|
|
|
|
|
|
if (vconfig != NULL) {
|
2023-02-21 12:15:01 +11:00
|
|
|
CHECK(named_config_getclass(cfg_tuple_get(vconfig, "class"),
|
|
|
|
dns_rdataclass_in, &vclass));
|
2001-08-07 01:58:59 +00:00
|
|
|
} else {
|
|
|
|
vclass = dns_rdataclass_in;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-08-07 01:58:59 +00:00
|
|
|
|
2000-05-25 19:27:48 +00:00
|
|
|
/*
|
|
|
|
* Configure values common to all zone types.
|
|
|
|
*/
|
1999-12-16 23:11:07 +00:00
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
|
1999-12-16 23:11:07 +00:00
|
|
|
|
2023-02-21 12:15:01 +11:00
|
|
|
CHECK(named_config_getclass(cfg_tuple_get(zconfig, "class"), vclass,
|
|
|
|
&zclass));
|
2001-03-04 21:21:39 +00:00
|
|
|
dns_zone_setclass(zone, zclass);
|
2011-08-30 05:16:15 +00:00
|
|
|
if (raw != NULL) {
|
|
|
|
dns_zone_setclass(raw, zclass);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-12-16 23:11:07 +00:00
|
|
|
|
2025-04-15 13:39:57 -07:00
|
|
|
ztype = zonetype_fromconfig(zoptions, toptions);
|
2011-08-30 05:16:15 +00:00
|
|
|
if (raw != NULL) {
|
|
|
|
dns_zone_settype(raw, ztype);
|
2021-08-25 22:29:25 -07:00
|
|
|
dns_zone_settype(zone, dns_zone_primary);
|
2011-08-30 05:16:15 +00:00
|
|
|
} else {
|
|
|
|
dns_zone_settype(zone, ztype);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2011-08-30 23:46:53 +00:00
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
obj = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
result = named_config_get(nooptions, "database", &obj);
|
2001-03-04 21:21:39 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
2005-08-23 02:36:11 +00:00
|
|
|
cpval = isc_mem_strdup(mctx, cfg_obj_asstring(obj));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-08-23 02:36:11 +00:00
|
|
|
|
2012-12-06 12:39:52 -08:00
|
|
|
obj = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
result = named_config_get(nooptions, "dlz", &obj);
|
2012-12-06 12:39:52 -08:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
const char *dlzname = cfg_obj_asstring(obj);
|
2025-05-30 23:11:14 -07:00
|
|
|
size_t len = strlen(dlzname) + 5;
|
2012-12-06 12:39:52 -08:00
|
|
|
cpval = isc_mem_allocate(mctx, len);
|
|
|
|
snprintf(cpval, len, "dlz %s", dlzname);
|
|
|
|
}
|
|
|
|
|
2005-08-23 02:36:11 +00:00
|
|
|
result = strtoargv(mctx, cpval, &dbargc, &dbargv);
|
|
|
|
if (result != ISC_R_SUCCESS && cpval != default_dbtype) {
|
|
|
|
isc_mem_free(mctx, cpval);
|
2023-02-21 12:15:01 +11:00
|
|
|
CHECK(result);
|
2005-08-23 02:36:11 +00:00
|
|
|
}
|
|
|
|
|
2000-08-22 05:14:59 +00:00
|
|
|
/*
|
|
|
|
* ANSI C is strange here. There is no logical reason why (char **)
|
|
|
|
* cannot be promoted automatically to (const char * const *) by the
|
|
|
|
* compiler w/o generating a warning.
|
|
|
|
*/
|
2019-07-23 14:56:24 -04:00
|
|
|
dns_zone_setdbtype(zone, dbargc, (const char *const *)dbargv);
|
2023-08-23 08:56:31 +02:00
|
|
|
isc_mem_cput(mctx, dbargv, dbargc, sizeof(*dbargv));
|
2019-07-23 14:56:24 -04:00
|
|
|
if (cpval != default_dbtype && cpval != dlz_dbtype) {
|
2005-08-23 02:36:11 +00:00
|
|
|
isc_mem_free(mctx, cpval);
|
2019-07-23 14:56:24 -04:00
|
|
|
}
|
1999-12-16 23:11:07 +00:00
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
obj = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
result = named_config_get(nooptions, "file", &obj);
|
2001-03-04 21:21:39 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
filename = cfg_obj_asstring(obj);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
|
2025-04-13 00:28:49 -07:00
|
|
|
obj = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
result = named_config_get(nooptions, "initial-file", &obj);
|
2025-04-13 00:28:49 -07:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
initial_file = cfg_obj_asstring(obj);
|
|
|
|
}
|
|
|
|
|
2021-08-25 22:29:25 -07:00
|
|
|
if (ztype == dns_zone_secondary || ztype == dns_zone_mirror) {
|
2011-10-26 15:23:37 +00:00
|
|
|
masterformat = dns_masterformat_raw;
|
|
|
|
} else {
|
|
|
|
masterformat = dns_masterformat_text;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "masterfile-format", &obj);
|
2005-06-20 01:05:33 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
2005-08-23 02:36:11 +00:00
|
|
|
const char *masterformatstr = cfg_obj_asstring(obj);
|
2005-06-20 01:05:33 +00:00
|
|
|
|
2018-11-07 15:00:07 +07:00
|
|
|
if (strcasecmp(masterformatstr, "text") == 0) {
|
2005-06-20 01:05:33 +00:00
|
|
|
masterformat = dns_masterformat_text;
|
2018-11-07 15:00:07 +07:00
|
|
|
} else {
|
2025-05-30 23:11:14 -07:00
|
|
|
masterformat = dns_masterformat_raw;
|
2018-11-07 15:00:07 +07:00
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
}
|
2011-08-30 05:16:15 +00:00
|
|
|
|
2014-04-17 17:10:29 -07:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "masterfile-style", &obj);
|
2014-04-17 17:10:29 -07:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
const char *masterstylestr = cfg_obj_asstring(obj);
|
2018-11-07 15:00:07 +07:00
|
|
|
if (strcasecmp(masterstylestr, "full") == 0) {
|
2014-04-17 17:10:29 -07:00
|
|
|
masterstyle = &dns_master_style_full;
|
2018-11-07 15:00:07 +07:00
|
|
|
} else {
|
2025-05-30 23:11:14 -07:00
|
|
|
masterstyle = &dns_master_style_default;
|
2018-11-07 15:00:07 +07:00
|
|
|
}
|
2014-04-17 17:10:29 -07:00
|
|
|
}
|
|
|
|
|
2016-11-02 17:31:27 +11:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "max-records", &obj);
|
2016-11-02 17:31:27 +11:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
|
|
|
dns_zone_setmaxrecords(mayberaw, cfg_obj_asuint32(obj));
|
|
|
|
if (zone != mayberaw) {
|
|
|
|
dns_zone_setmaxrecords(zone, 0);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-11-02 17:31:27 +11:00
|
|
|
|
2024-03-01 08:26:07 +01:00
|
|
|
obj = NULL;
|
|
|
|
result = named_config_get(maps, "max-records-per-type", &obj);
|
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
|
|
|
dns_zone_setmaxrrperset(mayberaw, cfg_obj_asuint32(obj));
|
|
|
|
if (zone != mayberaw) {
|
|
|
|
dns_zone_setmaxrrperset(zone, 0);
|
|
|
|
}
|
|
|
|
|
2024-05-25 11:46:56 +02:00
|
|
|
obj = NULL;
|
|
|
|
result = named_config_get(maps, "max-types-per-name", &obj);
|
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
|
|
|
dns_zone_setmaxtypepername(mayberaw, cfg_obj_asuint32(obj));
|
|
|
|
if (zone != mayberaw) {
|
|
|
|
dns_zone_setmaxtypepername(zone, 0);
|
|
|
|
}
|
|
|
|
|
2012-10-02 23:44:03 -07:00
|
|
|
if (raw != NULL && filename != NULL) {
|
2011-08-30 05:16:15 +00:00
|
|
|
#define SIGNED ".signed"
|
|
|
|
size_t signedlen = strlen(filename) + sizeof(SIGNED);
|
|
|
|
char *signedname;
|
|
|
|
|
2025-04-13 00:28:49 -07:00
|
|
|
dns_zone_setfile(raw, filename, initial_file, masterformat,
|
|
|
|
masterstyle);
|
2011-08-30 05:16:15 +00:00
|
|
|
signedname = isc_mem_get(mctx, signedlen);
|
|
|
|
|
|
|
|
(void)snprintf(signedname, signedlen, "%s" SIGNED, filename);
|
2025-04-13 00:28:49 -07:00
|
|
|
dns_zone_setfile(zone, signedname, NULL, dns_masterformat_raw,
|
|
|
|
NULL);
|
2011-08-30 05:16:15 +00:00
|
|
|
isc_mem_put(mctx, signedname, signedlen);
|
|
|
|
} else {
|
2025-04-13 00:28:49 -07:00
|
|
|
dns_zone_setfile(zone, filename, initial_file, masterformat,
|
|
|
|
masterstyle);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-12-16 23:11:07 +00:00
|
|
|
|
2004-10-07 02:15:14 +00:00
|
|
|
obj = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
result = named_config_get(nooptions, "journal", &obj);
|
2004-10-07 02:15:14 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
2025-01-07 19:03:07 -08:00
|
|
|
dns_zone_setjournal(mayberaw, cfg_obj_asstring(obj));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2004-10-07 02:15:14 +00:00
|
|
|
|
2011-08-30 05:16:15 +00:00
|
|
|
/*
|
|
|
|
* Notify messages are processed by the raw zone if it exists.
|
|
|
|
*/
|
2021-08-25 22:29:25 -07:00
|
|
|
if (ztype == dns_zone_secondary || ztype == dns_zone_mirror) {
|
2023-02-21 12:15:01 +11:00
|
|
|
CHECK(configure_zone_acl(zconfig, vconfig, config, allow_notify,
|
|
|
|
ac, mayberaw, dns_zone_setnotifyacl,
|
|
|
|
dns_zone_clearnotifyacl));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2011-08-30 05:16:15 +00:00
|
|
|
|
2000-05-25 19:27:48 +00:00
|
|
|
/*
|
|
|
|
* XXXAG This probably does not make sense for stubs.
|
|
|
|
*/
|
2023-02-21 12:15:01 +11:00
|
|
|
CHECK(configure_zone_acl(zconfig, vconfig, config, allow_query, ac,
|
|
|
|
zone, dns_zone_setqueryacl,
|
|
|
|
dns_zone_clearqueryacl));
|
2000-05-25 19:27:48 +00:00
|
|
|
|
2023-02-21 12:15:01 +11:00
|
|
|
CHECK(configure_zone_acl(zconfig, vconfig, config, allow_query_on, ac,
|
|
|
|
zone, dns_zone_setqueryonacl,
|
|
|
|
dns_zone_clearqueryonacl));
|
2013-01-03 15:13:45 -08:00
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "zone-statistics", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2013-02-27 11:53:58 -08:00
|
|
|
if (cfg_obj_isboolean(obj)) {
|
|
|
|
if (cfg_obj_asboolean(obj)) {
|
|
|
|
statlevel = dns_zonestat_full;
|
|
|
|
} else {
|
2013-02-27 13:37:54 -08:00
|
|
|
statlevel = dns_zonestat_none;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-02-27 11:53:58 -08:00
|
|
|
} else {
|
|
|
|
const char *levelstr = cfg_obj_asstring(obj);
|
2018-11-07 15:00:07 +07:00
|
|
|
if (strcasecmp(levelstr, "full") == 0) {
|
2013-02-27 11:53:58 -08:00
|
|
|
statlevel = dns_zonestat_full;
|
2018-11-07 15:00:07 +07:00
|
|
|
} else if (strcasecmp(levelstr, "terse") == 0) {
|
2013-02-27 11:53:58 -08:00
|
|
|
statlevel = dns_zonestat_terse;
|
2018-11-07 15:00:07 +07:00
|
|
|
} else if (strcasecmp(levelstr, "none") == 0) {
|
2013-02-27 11:53:58 -08:00
|
|
|
statlevel = dns_zonestat_none;
|
2018-11-07 15:00:07 +07:00
|
|
|
} else {
|
2021-10-11 12:50:17 +02:00
|
|
|
UNREACHABLE();
|
2018-11-07 15:00:07 +07:00
|
|
|
}
|
2013-02-27 11:53:58 -08:00
|
|
|
}
|
|
|
|
dns_zone_setstatlevel(zone, statlevel);
|
2012-11-14 12:44:15 -06:00
|
|
|
|
|
|
|
zoneqrystats = NULL;
|
|
|
|
rcvquerystats = NULL;
|
2019-06-19 16:02:50 +02:00
|
|
|
dnssecsignstats = NULL;
|
2013-02-27 11:53:58 -08:00
|
|
|
if (statlevel == dns_zonestat_full) {
|
2023-06-26 10:58:30 +02:00
|
|
|
isc_stats_create(mctx, &zoneqrystats, ns_statscounter_max);
|
|
|
|
dns_rdatatypestats_create(mctx, &rcvquerystats);
|
|
|
|
dns_dnssecsignstats_create(mctx, &dnssecsignstats);
|
2008-04-03 05:55:52 +00:00
|
|
|
}
|
2013-02-27 11:53:58 -08:00
|
|
|
dns_zone_setrequeststats(zone, zoneqrystats);
|
2012-11-14 12:44:15 -06:00
|
|
|
dns_zone_setrcvquerystats(zone, rcvquerystats);
|
2019-06-19 16:02:50 +02:00
|
|
|
dns_zone_setdnssecsignstats(zone, dnssecsignstats);
|
2012-11-14 12:44:15 -06:00
|
|
|
|
2008-04-03 05:55:52 +00:00
|
|
|
if (zoneqrystats != NULL) {
|
2009-01-27 22:30:00 +00:00
|
|
|
isc_stats_detach(&zoneqrystats);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-11-07 23:49:42 +00:00
|
|
|
|
2012-11-14 12:44:15 -06:00
|
|
|
if (rcvquerystats != NULL) {
|
|
|
|
dns_stats_detach(&rcvquerystats);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-11-14 12:44:15 -06:00
|
|
|
|
2019-06-19 16:02:50 +02:00
|
|
|
if (dnssecsignstats != NULL) {
|
|
|
|
dns_stats_detach(&dnssecsignstats);
|
|
|
|
}
|
|
|
|
|
2000-05-25 19:27:48 +00:00
|
|
|
/*
|
2021-10-05 11:07:44 +02:00
|
|
|
* Configure authoritative zone functionality. This applies
|
2020-06-17 02:02:27 -07:00
|
|
|
* to primary servers (type "primary") and secondaries
|
|
|
|
* acting as primaries (type "secondary"), but not to stubs.
|
2000-05-25 19:27:48 +00:00
|
|
|
*/
|
2011-02-23 03:08:11 +00:00
|
|
|
if (ztype != dns_zone_stub && ztype != dns_zone_staticstub &&
|
|
|
|
ztype != dns_zone_redirect)
|
|
|
|
{
|
2024-10-22 13:48:58 -07:00
|
|
|
bool logreports = false;
|
|
|
|
|
2023-02-10 15:18:36 +01:00
|
|
|
/* Make a reference to the default policy. */
|
|
|
|
result = dns_kasplist_find(kasplist, "default", &kasp);
|
|
|
|
INSIST(result == ISC_R_SUCCESS && kasp != NULL);
|
|
|
|
dns_zone_setdefaultkasp(zone, kasp);
|
2023-02-21 12:15:01 +11:00
|
|
|
dns_kasp_detach(&kasp);
|
2023-02-10 15:18:36 +01:00
|
|
|
|
2019-09-03 11:42:10 +02:00
|
|
|
obj = NULL;
|
2019-11-05 17:22:35 +01:00
|
|
|
result = named_config_get(maps, "dnssec-policy", &obj);
|
2019-09-03 11:42:10 +02:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
kaspname = cfg_obj_asstring(obj);
|
2021-04-21 16:09:06 +02:00
|
|
|
if (strcmp(kaspname, "none") != 0) {
|
|
|
|
result = dns_kasplist_find(kasplist, kaspname,
|
|
|
|
&kasp);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
cfg_obj_log(
|
2024-08-13 18:20:26 +02:00
|
|
|
obj, ISC_LOG_ERROR,
|
2021-04-21 16:09:06 +02:00
|
|
|
"dnssec-policy '%s' not found ",
|
|
|
|
kaspname);
|
2023-02-21 12:15:01 +11:00
|
|
|
CHECK(result);
|
2021-04-21 16:09:06 +02:00
|
|
|
}
|
|
|
|
dns_zone_setkasp(zone, kasp);
|
|
|
|
use_kasp = true;
|
2019-09-03 11:42:10 +02:00
|
|
|
}
|
2021-04-21 16:09:06 +02:00
|
|
|
}
|
|
|
|
if (!use_kasp) {
|
|
|
|
dns_zone_setkasp(zone, NULL);
|
2019-09-03 11:42:10 +02:00
|
|
|
}
|
|
|
|
|
2024-08-29 09:43:21 +10:00
|
|
|
obj = NULL;
|
|
|
|
result = named_config_get(maps, "provide-zoneversion", &obj);
|
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
|
|
|
dns_zone_setoption(zone, DNS_ZONEOPT_ZONEVERSION,
|
|
|
|
cfg_obj_asboolean(obj));
|
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "notify", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2001-03-04 21:21:39 +00:00
|
|
|
if (cfg_obj_isboolean(obj)) {
|
|
|
|
if (cfg_obj_asboolean(obj)) {
|
|
|
|
notifytype = dns_notifytype_yes;
|
|
|
|
} else {
|
|
|
|
notifytype = dns_notifytype_no;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-03-04 21:21:39 +00:00
|
|
|
} else {
|
2020-06-17 02:45:07 -07:00
|
|
|
const char *str = cfg_obj_asstring(obj);
|
|
|
|
if (strcasecmp(str, "explicit") == 0) {
|
2001-03-04 21:21:39 +00:00
|
|
|
notifytype = dns_notifytype_explicit;
|
2020-06-17 02:45:07 -07:00
|
|
|
} else if (strcasecmp(str, "master-only") == 0 ||
|
|
|
|
strcasecmp(str, "primary-only") == 0)
|
|
|
|
{
|
2004-03-30 02:13:45 +00:00
|
|
|
notifytype = dns_notifytype_masteronly;
|
2018-11-07 15:00:07 +07:00
|
|
|
} else {
|
2021-10-11 12:50:17 +02:00
|
|
|
UNREACHABLE();
|
2018-11-07 15:00:07 +07:00
|
|
|
}
|
2001-03-04 21:21:39 +00:00
|
|
|
}
|
Clean up handling of NOTIFY settings for mirror zones
Previous way of handling NOTIFY settings for mirror zones was a bit
tricky: any value of the "notify" option was accepted, but it was
subsequently overridden with dns_notifytype_explicit. Given the way
zone configuration is performed, this resulted in the following
behavior:
- if "notify yes;" was set explicitly at any configuration level or
inherited from default configuration, it was silently changed and so
only hosts specified in "also-notify", if any, were notified,
- if "notify no;" was set at any configuration level, it was
effectively honored since even though zone->notifytype was silently
set to dns_notifytype_explicit, the "also-notify" option was never
processed due to "notify no;" being set.
Effectively, this only allowed the hosts specified in "also-notify" to
be notified, when either "notify yes;" or "notify explicit;" was
explicitly set or inherited from default configuration.
Clean up handling of NOTIFY settings for mirror zones by:
- reporting a configuration error when anything else than "notify no;"
or "notify explicit;" is set for a mirror zone at the zone level,
- overriding inherited "notify yes;" setting with "notify explicit;"
for mirror zones,
- informing the user when the "notify" setting is overridden, unless
the setting in question was inherited from default configuration.
2018-10-09 10:54:51 +02:00
|
|
|
notifytype = process_notifytype(notifytype, ztype, zname,
|
|
|
|
nodefault);
|
2011-08-30 05:16:15 +00:00
|
|
|
if (raw != NULL) {
|
|
|
|
dns_zone_setnotifytype(raw, dns_notifytype_no);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-07-24 22:59:44 +00:00
|
|
|
dns_zone_setnotifytype(zone, notifytype);
|
1999-12-16 23:11:07 +00:00
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "also-notify", &obj);
|
2014-01-20 15:53:51 -08:00
|
|
|
if (result == ISC_R_SUCCESS &&
|
|
|
|
(notifytype == dns_notifytype_yes ||
|
|
|
|
notifytype == dns_notifytype_explicit ||
|
|
|
|
(notifytype == dns_notifytype_masteronly &&
|
2021-08-25 22:29:25 -07:00
|
|
|
ztype == dns_zone_primary)))
|
2014-01-20 15:53:51 -08:00
|
|
|
{
|
2016-05-26 21:23:19 +02:00
|
|
|
dns_ipkeylist_t ipkl;
|
2016-06-22 10:49:25 +02:00
|
|
|
dns_ipkeylist_init(&ipkl);
|
|
|
|
|
2024-12-05 08:52:03 +01:00
|
|
|
CHECK(named_config_getipandkeylist(config, obj, mctx,
|
|
|
|
&ipkl));
|
2022-11-22 11:55:49 +01:00
|
|
|
dns_zone_setalsonotify(zone, ipkl.addrs, ipkl.sources,
|
2023-01-05 22:18:55 -08:00
|
|
|
ipkl.keys, ipkl.tlss,
|
2021-10-06 13:41:21 +02:00
|
|
|
ipkl.count);
|
2016-05-26 21:23:19 +02:00
|
|
|
dns_ipkeylist_clear(mctx, &ipkl);
|
2000-07-25 20:26:11 +00:00
|
|
|
} else {
|
2023-01-05 22:18:55 -08:00
|
|
|
dns_zone_setalsonotify(zone, NULL, NULL, NULL, NULL, 0);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2021-05-14 11:33:51 +02:00
|
|
|
obj = NULL;
|
|
|
|
result = named_config_get(maps, "parental-source", &obj);
|
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2024-09-12 12:54:25 +10:00
|
|
|
dns_zone_setparentalsrc4(zone, cfg_obj_assockaddr(obj));
|
2021-05-14 11:33:51 +02:00
|
|
|
|
|
|
|
obj = NULL;
|
|
|
|
result = named_config_get(maps, "parental-source-v6", &obj);
|
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2024-09-12 12:54:25 +10:00
|
|
|
dns_zone_setparentalsrc6(zone, cfg_obj_assockaddr(obj));
|
2021-05-14 11:33:51 +02:00
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "notify-source", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2024-09-12 12:54:25 +10:00
|
|
|
dns_zone_setnotifysrc4(zone, cfg_obj_assockaddr(obj));
|
2000-11-25 02:43:56 +00:00
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "notify-source-v6", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2024-09-12 12:54:25 +10:00
|
|
|
dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj));
|
2000-11-25 02:43:56 +00:00
|
|
|
|
2007-09-18 00:22:31 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "notify-to-soa", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2007-09-18 00:22:31 +00:00
|
|
|
dns_zone_setoption(zone, DNS_ZONEOPT_NOTIFYTOSOA,
|
|
|
|
cfg_obj_asboolean(obj));
|
|
|
|
|
Fix an interfacemgr use-after-free error in zoneconf.c:isself()
The 'named_g_server->interfacemgr' pointer is saved in the zone
structure using dns_zone_setisself(), as a void* argument to be
passed to the isself() callback, so there is no attach/detach,
and when shutting down, the interface manager can be destroyed
by the shutdown_server(), running in exclusive mode, and causing
isself() to crash when trying to use the pointer.
Instead of keeping the interface manager pointer in the zone
structure, just check and use the 'named_g_server->interfacemgr'
itself, as it was implemented originally in the
3aca8e5bf3740bbcc3bb13dde242d7cc369abb27 commit. Later, in the
8eb88aafee951859264e36c315b1289cd8c2088b commit, the code was
changed to pass the interface manager pointer using the additional
void* argument, but the commit message doesn't mention if there
was any practical reason for that.
Additionally, don't pass the interfacemgr pointer to the
ns_interfacemgr_getaclenv() function before it is checked
against NULL.
2023-05-24 14:26:04 +00:00
|
|
|
dns_zone_setisself(zone, isself, NULL);
|
2005-02-10 05:53:43 +00:00
|
|
|
|
2023-02-21 12:15:01 +11:00
|
|
|
CHECK(configure_zone_acl(
|
2008-05-21 23:17:21 +00:00
|
|
|
zconfig, vconfig, config, allow_transfer, ac, zone,
|
2000-05-25 19:27:48 +00:00
|
|
|
dns_zone_setxfracl, dns_zone_clearxfracl));
|
1999-12-16 23:11:07 +00:00
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "max-transfer-time-out", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2023-04-17 12:22:38 +00:00
|
|
|
dns_zone_setmaxxfrout(
|
|
|
|
zone, transferinsecs ? cfg_obj_asuint32(obj)
|
|
|
|
: cfg_obj_asuint32(obj) * 60);
|
1999-12-16 23:11:07 +00:00
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "max-transfer-idle-out", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2023-04-17 12:22:38 +00:00
|
|
|
dns_zone_setidleout(zone, transferinsecs
|
|
|
|
? cfg_obj_asuint32(obj)
|
|
|
|
: cfg_obj_asuint32(obj) * 60);
|
2001-08-30 05:23:00 +00:00
|
|
|
|
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "max-journal-size", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2011-08-30 05:16:15 +00:00
|
|
|
if (raw != NULL) {
|
|
|
|
dns_zone_setjournalsize(raw, -1);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-09-01 01:43:24 +00:00
|
|
|
dns_zone_setjournalsize(zone, -1);
|
|
|
|
if (cfg_obj_isstring(obj)) {
|
|
|
|
const char *str = cfg_obj_asstring(obj);
|
2017-05-02 13:23:08 -07:00
|
|
|
if (strcasecmp(str, "unlimited") == 0) {
|
|
|
|
journal_size = DNS_JOURNAL_SIZE_MAX;
|
|
|
|
} else {
|
|
|
|
INSIST(strcasecmp(str, "default") == 0);
|
|
|
|
journal_size = -1;
|
|
|
|
}
|
2001-09-01 01:43:24 +00:00
|
|
|
} else {
|
2025-05-30 23:11:14 -07:00
|
|
|
journal_size = (uint32_t)cfg_obj_asuint64(obj);
|
2001-09-01 01:43:24 +00:00
|
|
|
}
|
2011-08-30 05:16:15 +00:00
|
|
|
if (raw != NULL) {
|
|
|
|
dns_zone_setjournalsize(raw, journal_size);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-09-01 01:43:24 +00:00
|
|
|
dns_zone_setjournalsize(zone, journal_size);
|
2001-09-08 00:21:49 +00:00
|
|
|
|
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "ixfr-from-differences", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2017-12-15 01:47:05 -08:00
|
|
|
if (cfg_obj_isboolean(obj)) {
|
2004-10-14 00:49:34 +00:00
|
|
|
ixfrdiff = cfg_obj_asboolean(obj);
|
2017-12-15 10:01:07 -08:00
|
|
|
} else if ((strcasecmp(cfg_obj_asstring(obj), "primary") == 0 ||
|
|
|
|
strcasecmp(cfg_obj_asstring(obj), "master") == 0) &&
|
2021-08-25 22:29:25 -07:00
|
|
|
ztype == dns_zone_primary)
|
2017-12-15 01:47:05 -08:00
|
|
|
{
|
2018-04-17 08:29:14 -07:00
|
|
|
ixfrdiff = true;
|
2017-12-15 10:01:07 -08:00
|
|
|
} else if ((strcasecmp(cfg_obj_asstring(obj), "secondary") ==
|
|
|
|
0 ||
|
|
|
|
strcasecmp(cfg_obj_asstring(obj), "slave") == 0) &&
|
2021-08-25 22:29:25 -07:00
|
|
|
ztype == dns_zone_secondary)
|
2017-12-15 01:47:05 -08:00
|
|
|
{
|
2018-04-17 08:29:14 -07:00
|
|
|
ixfrdiff = true;
|
2017-12-15 01:47:05 -08:00
|
|
|
} else {
|
2018-04-17 08:29:14 -07:00
|
|
|
ixfrdiff = false;
|
2017-12-15 01:47:05 -08:00
|
|
|
}
|
2011-08-30 05:16:15 +00:00
|
|
|
if (raw != NULL) {
|
|
|
|
dns_zone_setoption(raw, DNS_ZONEOPT_IXFRFROMDIFFS,
|
2018-04-17 08:29:14 -07:00
|
|
|
true);
|
2011-08-30 05:16:15 +00:00
|
|
|
dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS,
|
2018-04-17 08:29:14 -07:00
|
|
|
false);
|
2011-08-30 05:16:15 +00:00
|
|
|
} else {
|
|
|
|
dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS,
|
|
|
|
ixfrdiff);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2004-02-27 20:41:51 +00:00
|
|
|
|
2020-02-21 10:53:08 -08:00
|
|
|
obj = NULL;
|
|
|
|
result = named_config_get(maps, "max-ixfr-ratio", &obj);
|
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
|
|
|
if (cfg_obj_isstring(obj)) {
|
|
|
|
dns_zone_setixfrratio(zone, 0);
|
|
|
|
} else {
|
|
|
|
dns_zone_setixfrratio(zone, cfg_obj_aspercentage(obj));
|
|
|
|
}
|
|
|
|
|
2014-08-06 11:50:40 +10:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "request-expire", &obj);
|
2014-08-06 11:50:40 +10:00
|
|
|
INSIST(result == ISC_R_SUCCESS);
|
|
|
|
dns_zone_setrequestexpire(zone, cfg_obj_asboolean(obj));
|
|
|
|
|
2011-09-06 22:29:33 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "request-ixfr", &obj);
|
2011-09-06 22:29:33 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS);
|
|
|
|
dns_zone_setrequestixfr(zone, cfg_obj_asboolean(obj));
|
|
|
|
|
2024-06-07 14:47:55 +00:00
|
|
|
obj = NULL;
|
|
|
|
result = named_config_get(maps, "request-ixfr-max-diffs", &obj);
|
|
|
|
INSIST(result == ISC_R_SUCCESS);
|
|
|
|
dns_zone_setrequestixfrmaxdiffs(zone, cfg_obj_asuint32(obj));
|
|
|
|
|
2020-05-20 11:56:01 +10:00
|
|
|
obj = NULL;
|
2004-02-27 20:41:51 +00:00
|
|
|
checknames(ztype, maps, &obj);
|
|
|
|
INSIST(obj != NULL);
|
|
|
|
if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
fail = false;
|
|
|
|
check = true;
|
2004-02-27 20:41:51 +00:00
|
|
|
} else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
fail = check = true;
|
2004-02-27 20:41:51 +00:00
|
|
|
} else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
fail = check = false;
|
2018-11-07 15:00:07 +07:00
|
|
|
} else {
|
2021-10-11 12:50:17 +02:00
|
|
|
UNREACHABLE();
|
2018-11-07 15:00:07 +07:00
|
|
|
}
|
2011-08-30 05:16:15 +00:00
|
|
|
if (raw != NULL) {
|
|
|
|
dns_zone_setoption(raw, DNS_ZONEOPT_CHECKNAMES, check);
|
|
|
|
dns_zone_setoption(raw, DNS_ZONEOPT_CHECKNAMESFAIL,
|
|
|
|
fail);
|
|
|
|
dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES, false);
|
|
|
|
dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL,
|
2018-04-17 08:29:14 -07:00
|
|
|
false);
|
2011-08-30 05:16:15 +00:00
|
|
|
} else {
|
|
|
|
dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES, check);
|
|
|
|
dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL,
|
|
|
|
fail);
|
|
|
|
}
|
2005-01-11 23:10:06 +00:00
|
|
|
|
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "notify-delay", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2005-01-11 23:10:06 +00:00
|
|
|
dns_zone_setnotifydelay(zone, cfg_obj_asuint32(obj));
|
|
|
|
|
2025-04-22 13:33:48 +00:00
|
|
|
obj = NULL;
|
|
|
|
result = named_config_get(maps, "notify-defer", &obj);
|
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
|
|
|
dns_zone_setnotifydefer(zone, cfg_obj_asuint32(obj));
|
|
|
|
|
2005-08-24 23:54:04 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "check-sibling", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2008-01-18 23:46:58 +00:00
|
|
|
dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSIBLING,
|
2005-08-24 23:54:04 +00:00
|
|
|
cfg_obj_asboolean(obj));
|
2006-01-05 02:19:02 +00:00
|
|
|
|
2013-04-30 13:49:41 +10:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "check-spf", &obj);
|
2013-04-30 13:49:41 +10:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
|
|
|
if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
check = true;
|
2013-04-30 13:49:41 +10:00
|
|
|
} else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
check = false;
|
2018-11-07 15:00:07 +07:00
|
|
|
} else {
|
2021-10-11 12:50:17 +02:00
|
|
|
UNREACHABLE();
|
2018-11-07 15:00:07 +07:00
|
|
|
}
|
2013-04-30 13:49:41 +10:00
|
|
|
dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSPF, check);
|
|
|
|
|
2022-10-05 17:49:07 +11:00
|
|
|
obj = NULL;
|
|
|
|
result = named_config_get(maps, "check-svcb", &obj);
|
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
|
|
|
dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSVCB,
|
|
|
|
cfg_obj_asboolean(obj));
|
|
|
|
|
2006-01-05 02:19:02 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "zero-no-soa-ttl", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2006-01-05 02:19:02 +00:00
|
|
|
dns_zone_setzeronosoattl(zone, cfg_obj_asboolean(obj));
|
2008-09-24 02:46:23 +00:00
|
|
|
|
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "nsec3-test-zone", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2008-09-24 02:46:23 +00:00
|
|
|
dns_zone_setoption(zone, DNS_ZONEOPT_NSEC3TESTZONE,
|
|
|
|
cfg_obj_asboolean(obj));
|
2024-05-15 14:10:43 +10:00
|
|
|
|
2024-10-19 13:26:38 -07:00
|
|
|
obj = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
result = named_config_get(nooptions, "log-report-channel",
|
|
|
|
&obj);
|
2024-10-19 13:26:38 -07:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
2024-10-22 13:48:58 -07:00
|
|
|
logreports = cfg_obj_asboolean(obj);
|
2024-10-19 13:26:38 -07:00
|
|
|
dns_zone_setoption(zone, DNS_ZONEOPT_LOGREPORTS,
|
2024-10-22 13:48:58 -07:00
|
|
|
logreports);
|
|
|
|
}
|
|
|
|
obj = NULL;
|
|
|
|
result = named_config_get(maps, "send-report-channel", &obj);
|
|
|
|
if (result == ISC_R_SUCCESS && obj != NULL) {
|
|
|
|
dns_fixedname_t fixed;
|
|
|
|
dns_name_t *rad = dns_fixedname_initname(&fixed);
|
|
|
|
const char *adstr = cfg_obj_asstring(obj);
|
|
|
|
dns_name_t *zn = dns_zone_getorigin(zone);
|
|
|
|
|
|
|
|
CHECK(dns_name_fromstring(rad, adstr, dns_rootname, 0,
|
|
|
|
mctx));
|
|
|
|
if (logreports || dns_name_equal(rad, dns_rootname)) {
|
|
|
|
/* Disable RC for error-logging zones or root */
|
|
|
|
dns_zone_setrad(zone, NULL);
|
|
|
|
} else if (dns_name_equal(rad, zn)) {
|
|
|
|
/*
|
|
|
|
* It's illegal to set a matching agent
|
|
|
|
* domain at the zone level, but it could
|
|
|
|
* be set in options/view. If so, and the
|
|
|
|
* matching zone doesn't log reports, warn.
|
|
|
|
*/
|
|
|
|
cfg_obj_log(obj, ISC_LOG_WARNING,
|
|
|
|
"send-report-channel is set to "
|
|
|
|
"'%s' but that zone does not have "
|
|
|
|
"log-report-channel set",
|
|
|
|
zname);
|
|
|
|
dns_zone_setrad(zone, NULL);
|
|
|
|
} else if (dns_name_issubdomain(rad, zn)) {
|
|
|
|
cfg_obj_log(obj, ISC_LOG_WARNING,
|
|
|
|
"send-report-channel '%s' ignored "
|
|
|
|
"for zone '%s' because it is a "
|
|
|
|
"subdomain of the zone",
|
|
|
|
adstr, zname);
|
|
|
|
dns_zone_setrad(zone, NULL);
|
|
|
|
} else {
|
|
|
|
dns_zone_setrad(zone, rad);
|
|
|
|
}
|
2024-10-19 13:26:38 -07:00
|
|
|
}
|
2011-02-23 03:08:11 +00:00
|
|
|
} else if (ztype == dns_zone_redirect) {
|
|
|
|
dns_zone_setnotifytype(zone, dns_notifytype_no);
|
|
|
|
|
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "max-journal-size", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2011-02-23 03:08:11 +00:00
|
|
|
dns_zone_setjournalsize(zone, -1);
|
|
|
|
if (cfg_obj_isstring(obj)) {
|
|
|
|
const char *str = cfg_obj_asstring(obj);
|
2017-05-02 13:23:08 -07:00
|
|
|
if (strcasecmp(str, "unlimited") == 0) {
|
|
|
|
journal_size = DNS_JOURNAL_SIZE_MAX;
|
|
|
|
} else {
|
|
|
|
INSIST(strcasecmp(str, "default") == 0);
|
|
|
|
journal_size = -1;
|
|
|
|
}
|
2011-02-23 03:08:11 +00:00
|
|
|
} else {
|
2025-05-30 23:11:14 -07:00
|
|
|
journal_size = (uint32_t)cfg_obj_asuint64(obj);
|
2011-02-23 03:08:11 +00:00
|
|
|
}
|
|
|
|
dns_zone_setjournalsize(zone, journal_size);
|
2000-05-25 19:27:48 +00:00
|
|
|
}
|
1999-12-16 23:11:07 +00:00
|
|
|
|
2022-07-13 10:28:59 +02:00
|
|
|
if (use_kasp) {
|
2023-07-26 11:50:57 +02:00
|
|
|
maxttl = dns_kasp_zonemaxttl(dns_zone_getkasp(zone), false);
|
2022-07-13 10:28:59 +02:00
|
|
|
} else {
|
|
|
|
obj = NULL;
|
|
|
|
result = named_config_get(maps, "max-zone-ttl", &obj);
|
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
if (cfg_obj_isduration(obj)) {
|
|
|
|
maxttl = cfg_obj_asduration(obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dns_zone_setmaxttl(zone, maxttl);
|
|
|
|
if (raw != NULL) {
|
|
|
|
dns_zone_setmaxttl(raw, maxttl);
|
|
|
|
}
|
|
|
|
|
2000-05-25 19:27:48 +00:00
|
|
|
/*
|
|
|
|
* Configure update-related options. These apply to
|
2020-06-17 02:02:27 -07:00
|
|
|
* primary servers only.
|
2000-05-25 19:27:48 +00:00
|
|
|
*/
|
2021-08-25 22:29:25 -07:00
|
|
|
if (ztype == dns_zone_primary) {
|
2000-12-01 18:22:17 +00:00
|
|
|
dns_acl_t *updateacl;
|
2009-06-10 00:27:22 +00:00
|
|
|
|
2023-02-21 12:15:01 +11:00
|
|
|
CHECK(configure_zone_acl(zconfig, vconfig, config, allow_update,
|
|
|
|
ac, mayberaw, dns_zone_setupdateacl,
|
|
|
|
dns_zone_clearupdateacl));
|
2008-01-18 23:46:58 +00:00
|
|
|
|
2011-08-30 05:16:15 +00:00
|
|
|
updateacl = dns_zone_getupdateacl(mayberaw);
|
2000-12-01 18:22:17 +00:00
|
|
|
if (updateacl != NULL && dns_acl_isinsecure(updateacl)) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(DNS_LOGCATEGORY_SECURITY,
|
2017-09-08 13:39:09 -07:00
|
|
|
NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
|
2016-12-27 09:49:02 +11:00
|
|
|
"zone '%s' allows unsigned updates "
|
|
|
|
"from remote hosts, which is insecure",
|
2001-03-04 21:21:39 +00:00
|
|
|
zname);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-01-18 23:46:58 +00:00
|
|
|
|
2025-04-15 13:39:57 -07:00
|
|
|
CHECK(configure_zone_ssutable(zoptions, toptions, mayberaw,
|
|
|
|
zname));
|
2011-08-30 05:16:15 +00:00
|
|
|
}
|
|
|
|
|
2022-06-17 10:29:51 +02:00
|
|
|
/*
|
|
|
|
* Configure DNSSEC signing. These apply to primary zones or zones that
|
|
|
|
* use inline-signing (raw != NULL).
|
|
|
|
*/
|
2021-08-25 22:29:25 -07:00
|
|
|
if (ztype == dns_zone_primary || raw != NULL) {
|
2020-12-03 15:01:42 +01:00
|
|
|
if (use_kasp) {
|
2023-07-05 10:59:24 +02:00
|
|
|
int seconds;
|
|
|
|
|
2020-10-13 14:39:21 +02:00
|
|
|
if (dns_kasp_nsec3(kasp)) {
|
2020-11-05 11:12:24 +01:00
|
|
|
result = dns_zone_setnsec3param(
|
2020-10-13 14:39:21 +02:00
|
|
|
zone, 1, dns_kasp_nsec3flags(kasp),
|
|
|
|
dns_kasp_nsec3iter(kasp),
|
2020-11-05 11:12:24 +01:00
|
|
|
dns_kasp_nsec3saltlen(kasp), NULL, true,
|
|
|
|
false);
|
2020-10-13 14:39:21 +02:00
|
|
|
} else {
|
2020-11-05 11:12:24 +01:00
|
|
|
result = dns_zone_setnsec3param(
|
|
|
|
zone, 0, 0, 0, 0, NULL, true, false);
|
2020-10-13 14:39:21 +02:00
|
|
|
}
|
|
|
|
INSIST(result == ISC_R_SUCCESS);
|
|
|
|
|
2019-10-17 11:38:56 +02:00
|
|
|
seconds = (uint32_t)dns_kasp_sigvalidity_dnskey(kasp);
|
2023-07-05 10:59:24 +02:00
|
|
|
dns_zone_setkeyvalidityinterval(zone, seconds);
|
2018-03-12 22:14:26 -07:00
|
|
|
|
2019-10-17 11:38:56 +02:00
|
|
|
seconds = (uint32_t)dns_kasp_sigvalidity(kasp);
|
|
|
|
dns_zone_setsigvalidityinterval(zone, seconds);
|
|
|
|
|
2023-07-05 10:59:24 +02:00
|
|
|
seconds = (uint32_t)dns_kasp_sigrefresh(kasp);
|
2019-10-17 11:38:56 +02:00
|
|
|
dns_zone_setsigresigninginterval(zone, seconds);
|
2008-04-02 02:37:42 +00:00
|
|
|
}
|
2002-01-21 11:00:25 +00:00
|
|
|
|
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "key-directory", &obj);
|
2002-01-21 11:00:25 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
filename = cfg_obj_asstring(obj);
|
2025-01-07 19:03:07 -08:00
|
|
|
dns_zone_setkeydirectory(zone, filename);
|
2002-01-21 11:00:25 +00:00
|
|
|
}
|
2022-03-09 10:55:48 +01:00
|
|
|
/* Also save a reference to the keystore list. */
|
|
|
|
dns_zone_setkeystores(zone, keystorelist);
|
2005-05-19 04:59:05 +00:00
|
|
|
|
2008-04-02 02:37:42 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "sig-signing-signatures", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2008-04-02 02:37:42 +00:00
|
|
|
dns_zone_setsignatures(zone, cfg_obj_asuint32(obj));
|
|
|
|
|
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "sig-signing-nodes", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2008-04-02 02:37:42 +00:00
|
|
|
dns_zone_setnodes(zone, cfg_obj_asuint32(obj));
|
|
|
|
|
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "sig-signing-type", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2008-04-02 02:37:42 +00:00
|
|
|
dns_zone_setprivatetype(zone, cfg_obj_asuint32(obj));
|
|
|
|
|
2011-04-29 21:37:15 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "dnssec-loadkeys-interval",
|
|
|
|
&obj);
|
2011-04-29 21:37:15 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2023-02-21 12:15:01 +11:00
|
|
|
CHECK(dns_zone_setrefreshkeyinterval(zone,
|
|
|
|
cfg_obj_asuint32(obj)));
|
2011-08-30 23:46:53 +00:00
|
|
|
}
|
2011-08-30 05:16:15 +00:00
|
|
|
|
2021-08-25 22:29:25 -07:00
|
|
|
if (ztype == dns_zone_secondary || ztype == dns_zone_mirror) {
|
2023-02-21 12:15:01 +11:00
|
|
|
CHECK(configure_zone_acl(zconfig, vconfig, config,
|
|
|
|
allow_update_forwarding, ac, mayberaw,
|
|
|
|
dns_zone_setforwardacl,
|
|
|
|
dns_zone_clearforwardacl));
|
2008-04-02 02:37:42 +00:00
|
|
|
}
|
|
|
|
|
2021-05-11 14:46:38 +02:00
|
|
|
/*%
|
|
|
|
* Configure parental agents, applies to primary and secondary zones.
|
|
|
|
*/
|
2021-08-25 22:29:25 -07:00
|
|
|
if (ztype == dns_zone_primary || ztype == dns_zone_secondary) {
|
2023-03-28 16:57:58 +02:00
|
|
|
const cfg_obj_t *parentals = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
(void)named_config_get(nooptions, "parental-agents",
|
|
|
|
&parentals);
|
2023-03-28 16:57:58 +02:00
|
|
|
if (parentals != NULL) {
|
2021-05-11 14:46:38 +02:00
|
|
|
dns_ipkeylist_t ipkl;
|
|
|
|
dns_ipkeylist_init(&ipkl);
|
2024-12-05 08:52:03 +01:00
|
|
|
CHECK(named_config_getipandkeylist(config, parentals,
|
|
|
|
mctx, &ipkl));
|
2022-11-22 11:55:49 +01:00
|
|
|
dns_zone_setparentals(zone, ipkl.addrs, ipkl.sources,
|
|
|
|
ipkl.keys, ipkl.tlss, ipkl.count);
|
2021-05-11 14:46:38 +02:00
|
|
|
dns_ipkeylist_clear(mctx, &ipkl);
|
|
|
|
} else {
|
2022-11-22 11:55:49 +01:00
|
|
|
dns_zone_setparentals(zone, NULL, NULL, NULL, NULL, 0);
|
2021-05-11 14:46:38 +02:00
|
|
|
}
|
2023-03-28 16:57:58 +02:00
|
|
|
|
|
|
|
obj = NULL;
|
|
|
|
result = named_config_get(maps, "checkds", &obj);
|
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
if (cfg_obj_isboolean(obj)) {
|
|
|
|
if (cfg_obj_asboolean(obj)) {
|
|
|
|
checkdstype = dns_checkdstype_yes;
|
|
|
|
} else {
|
|
|
|
checkdstype = dns_checkdstype_no;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const char *str = cfg_obj_asstring(obj);
|
|
|
|
if (strcasecmp(str, "explicit") == 0) {
|
|
|
|
checkdstype = dns_checkdstype_explicit;
|
|
|
|
} else {
|
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (parentals != NULL) {
|
|
|
|
checkdstype = dns_checkdstype_explicit;
|
|
|
|
} else {
|
|
|
|
checkdstype = dns_checkdstype_yes;
|
|
|
|
}
|
|
|
|
if (raw != NULL) {
|
|
|
|
dns_zone_setcheckdstype(raw, dns_checkdstype_no);
|
|
|
|
}
|
|
|
|
dns_zone_setcheckdstype(zone, checkdstype);
|
2021-05-11 14:46:38 +02:00
|
|
|
}
|
|
|
|
|
2008-04-02 02:37:42 +00:00
|
|
|
/*%
|
2021-10-05 11:07:44 +02:00
|
|
|
* Configure primary zone functionality.
|
2008-04-02 02:37:42 +00:00
|
|
|
*/
|
2021-08-25 22:29:25 -07:00
|
|
|
if (ztype == dns_zone_primary) {
|
2005-01-09 23:40:04 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "check-wildcard", &obj);
|
2005-01-09 23:40:04 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
check = cfg_obj_asboolean(obj);
|
|
|
|
} else {
|
2018-04-17 08:29:14 -07:00
|
|
|
check = false;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2011-08-30 05:16:15 +00:00
|
|
|
dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKWILDCARD, check);
|
2005-05-19 04:59:05 +00:00
|
|
|
|
2009-12-04 21:09:34 +00:00
|
|
|
obj = NULL;
|
2021-09-16 11:46:13 +02:00
|
|
|
result = named_config_get(maps, "check-dup-records", &obj);
|
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
|
|
|
dupcheck = cfg_obj_asstring(obj);
|
2012-06-20 14:13:12 -05:00
|
|
|
if (strcasecmp(dupcheck, "warn") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
fail = false;
|
|
|
|
check = true;
|
2012-06-20 14:13:12 -05:00
|
|
|
} else if (strcasecmp(dupcheck, "fail") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
fail = check = true;
|
2012-06-20 14:13:12 -05:00
|
|
|
} else if (strcasecmp(dupcheck, "ignore") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
fail = check = false;
|
2018-11-07 15:00:07 +07:00
|
|
|
} else {
|
2021-10-11 12:50:17 +02:00
|
|
|
UNREACHABLE();
|
2018-11-07 15:00:07 +07:00
|
|
|
}
|
2011-08-30 05:16:15 +00:00
|
|
|
dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKDUPRR, check);
|
|
|
|
dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKDUPRRFAIL, fail);
|
2009-12-04 21:09:34 +00:00
|
|
|
|
2005-05-19 04:59:05 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "check-mx", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2005-05-19 04:59:05 +00:00
|
|
|
if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
fail = false;
|
|
|
|
check = true;
|
2005-05-19 04:59:05 +00:00
|
|
|
} else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
fail = check = true;
|
2005-05-19 04:59:05 +00:00
|
|
|
} else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
fail = check = false;
|
2018-11-07 15:00:07 +07:00
|
|
|
} else {
|
2021-10-11 12:50:17 +02:00
|
|
|
UNREACHABLE();
|
2018-11-07 15:00:07 +07:00
|
|
|
}
|
2011-08-30 05:16:15 +00:00
|
|
|
dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKMX, check);
|
|
|
|
dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKMXFAIL, fail);
|
2005-05-19 04:59:05 +00:00
|
|
|
|
|
|
|
obj = NULL;
|
2021-09-16 11:46:13 +02:00
|
|
|
result = named_config_get(maps, "check-integrity", &obj);
|
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
|
|
|
dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKINTEGRITY,
|
|
|
|
cfg_obj_asboolean(obj));
|
2006-01-05 23:45:34 +00:00
|
|
|
|
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "check-mx-cname", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2006-01-05 23:45:34 +00:00
|
|
|
if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
warn = true;
|
|
|
|
ignore = false;
|
2006-01-05 23:45:34 +00:00
|
|
|
} else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
warn = ignore = false;
|
2006-01-05 23:45:34 +00:00
|
|
|
} else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
warn = ignore = true;
|
2018-11-07 15:00:07 +07:00
|
|
|
} else {
|
2021-10-11 12:50:17 +02:00
|
|
|
UNREACHABLE();
|
2018-11-07 15:00:07 +07:00
|
|
|
}
|
2011-08-30 05:16:15 +00:00
|
|
|
dns_zone_setoption(mayberaw, DNS_ZONEOPT_WARNMXCNAME, warn);
|
|
|
|
dns_zone_setoption(mayberaw, DNS_ZONEOPT_IGNOREMXCNAME, ignore);
|
2006-01-05 23:45:34 +00:00
|
|
|
|
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "check-srv-cname", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2006-01-05 23:45:34 +00:00
|
|
|
if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
warn = true;
|
|
|
|
ignore = false;
|
2006-01-05 23:45:34 +00:00
|
|
|
} else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
warn = ignore = false;
|
2006-01-05 23:45:34 +00:00
|
|
|
} else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
warn = ignore = true;
|
2018-11-07 15:00:07 +07:00
|
|
|
} else {
|
2021-10-11 12:50:17 +02:00
|
|
|
UNREACHABLE();
|
2018-11-07 15:00:07 +07:00
|
|
|
}
|
2011-08-30 05:16:15 +00:00
|
|
|
dns_zone_setoption(mayberaw, DNS_ZONEOPT_WARNSRVCNAME, warn);
|
|
|
|
dns_zone_setoption(mayberaw, DNS_ZONEOPT_IGNORESRVCNAME,
|
|
|
|
ignore);
|
2009-10-08 23:13:07 +00:00
|
|
|
|
2011-07-01 02:25:48 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "serial-update-method", &obj);
|
2011-07-01 02:25:48 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
|
|
|
if (strcasecmp(cfg_obj_asstring(obj), "unixtime") == 0) {
|
|
|
|
dns_zone_setserialupdatemethod(
|
|
|
|
zone, dns_updatemethod_unixtime);
|
2014-04-17 16:05:50 -07:00
|
|
|
} else if (strcasecmp(cfg_obj_asstring(obj), "date") == 0) {
|
|
|
|
dns_zone_setserialupdatemethod(zone,
|
|
|
|
dns_updatemethod_date);
|
2011-07-01 02:25:48 +00:00
|
|
|
} else {
|
|
|
|
dns_zone_setserialupdatemethod(
|
|
|
|
zone, dns_updatemethod_increment);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-05-25 19:27:48 +00:00
|
|
|
}
|
2000-03-06 19:06:07 +00:00
|
|
|
|
2000-05-25 19:27:48 +00:00
|
|
|
/*
|
2021-10-05 11:07:44 +02:00
|
|
|
* Configure secondary zone functionality.
|
2000-05-25 19:27:48 +00:00
|
|
|
*/
|
2001-03-04 21:21:39 +00:00
|
|
|
switch (ztype) {
|
2018-10-09 10:54:51 +02:00
|
|
|
case dns_zone_mirror:
|
2018-10-09 10:54:51 +02:00
|
|
|
/*
|
|
|
|
* Disable outgoing zone transfers for mirror zones unless they
|
|
|
|
* are explicitly enabled by zone configuration.
|
|
|
|
*/
|
|
|
|
obj = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
(void)named_config_get(nooptions, "allow-transfer", &obj);
|
2018-10-09 10:54:51 +02:00
|
|
|
if (obj == NULL) {
|
|
|
|
dns_acl_t *none;
|
2023-02-21 12:15:01 +11:00
|
|
|
CHECK(dns_acl_none(mctx, &none));
|
2018-10-09 10:54:51 +02:00
|
|
|
dns_zone_setxfracl(zone, none);
|
|
|
|
dns_acl_detach(&none);
|
|
|
|
}
|
2021-10-11 12:09:16 +02:00
|
|
|
FALLTHROUGH;
|
2021-08-25 22:29:25 -07:00
|
|
|
case dns_zone_secondary:
|
2001-03-04 21:21:39 +00:00
|
|
|
case dns_zone_stub:
|
2011-02-23 03:08:11 +00:00
|
|
|
case dns_zone_redirect:
|
2005-11-30 03:33:49 +00:00
|
|
|
count = 0;
|
2001-03-04 21:21:39 +00:00
|
|
|
obj = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
(void)named_config_get(nooptions, "primaries", &obj);
|
2020-06-17 02:02:27 -07:00
|
|
|
if (obj == NULL) {
|
2025-04-15 13:39:57 -07:00
|
|
|
(void)named_config_get(nooptions, "masters", &obj);
|
2020-06-17 02:02:27 -07:00
|
|
|
}
|
|
|
|
|
2018-10-09 10:54:51 +02:00
|
|
|
/*
|
2020-06-17 02:02:27 -07:00
|
|
|
* Use the built-in primary server list if one was not
|
2018-10-09 10:54:51 +02:00
|
|
|
* explicitly specified and this is a root zone mirror.
|
|
|
|
*/
|
|
|
|
if (obj == NULL && ztype == dns_zone_mirror &&
|
|
|
|
dns_name_equal(dns_zone_getorigin(zone), dns_rootname))
|
|
|
|
{
|
2021-05-11 14:43:02 +02:00
|
|
|
result = named_config_getremotesdef(
|
2025-04-22 13:46:47 +02:00
|
|
|
named_g_defaultconfig, "remote-servers",
|
2020-06-17 02:02:27 -07:00
|
|
|
DEFAULT_IANA_ROOT_ZONE_PRIMARIES, &obj);
|
2023-02-21 12:15:01 +11:00
|
|
|
CHECK(result);
|
2018-10-09 10:54:51 +02:00
|
|
|
}
|
2001-03-04 21:21:39 +00:00
|
|
|
if (obj != NULL) {
|
2016-05-26 21:23:19 +02:00
|
|
|
dns_ipkeylist_t ipkl;
|
2016-06-22 10:49:25 +02:00
|
|
|
dns_ipkeylist_init(&ipkl);
|
|
|
|
|
2024-12-05 08:52:03 +01:00
|
|
|
CHECK(named_config_getipandkeylist(config, obj, mctx,
|
|
|
|
&ipkl));
|
2022-11-22 11:55:49 +01:00
|
|
|
dns_zone_setprimaries(mayberaw, ipkl.addrs,
|
|
|
|
ipkl.sources, ipkl.keys,
|
2021-10-06 13:41:21 +02:00
|
|
|
ipkl.tlss, ipkl.count);
|
2018-02-15 14:56:13 +11:00
|
|
|
count = ipkl.count;
|
2016-05-26 21:23:19 +02:00
|
|
|
dns_ipkeylist_clear(mctx, &ipkl);
|
2011-08-30 23:46:53 +00:00
|
|
|
} else {
|
2022-11-22 11:55:49 +01:00
|
|
|
dns_zone_setprimaries(mayberaw, NULL, NULL, NULL, NULL,
|
|
|
|
0);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-12-16 23:11:07 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
multi = false;
|
2002-07-29 06:58:46 +00:00
|
|
|
if (count > 1) {
|
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "multi-master", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2002-07-29 06:58:46 +00:00
|
|
|
multi = cfg_obj_asboolean(obj);
|
|
|
|
}
|
2011-08-30 05:16:15 +00:00
|
|
|
dns_zone_setoption(mayberaw, DNS_ZONEOPT_MULTIMASTER, multi);
|
2002-07-29 06:58:46 +00:00
|
|
|
|
2024-06-10 16:48:26 +00:00
|
|
|
obj = NULL;
|
|
|
|
result = named_config_get(maps, "min-transfer-rate-in", &obj);
|
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
|
|
|
uint32_t traffic_bytes =
|
|
|
|
cfg_obj_asuint32(cfg_tuple_get(obj, "traffic_bytes"));
|
|
|
|
uint32_t time_minutes =
|
|
|
|
cfg_obj_asuint32(cfg_tuple_get(obj, "time_minutes"));
|
|
|
|
dns_zone_setminxfrratein(mayberaw, traffic_bytes,
|
|
|
|
transferinsecs ? time_minutes
|
|
|
|
: time_minutes * 60);
|
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "max-transfer-time-in", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2023-04-17 12:22:38 +00:00
|
|
|
dns_zone_setmaxxfrin(
|
|
|
|
mayberaw, transferinsecs ? cfg_obj_asuint32(obj)
|
|
|
|
: cfg_obj_asuint32(obj) * 60);
|
2000-01-31 19:53:14 +00:00
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "max-transfer-idle-in", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2023-04-17 12:22:38 +00:00
|
|
|
dns_zone_setidlein(mayberaw,
|
|
|
|
transferinsecs ? cfg_obj_asuint32(obj)
|
|
|
|
: cfg_obj_asuint32(obj) * 60);
|
1999-12-16 23:11:07 +00:00
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "max-refresh-time", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2011-08-30 05:16:15 +00:00
|
|
|
dns_zone_setmaxrefreshtime(mayberaw, cfg_obj_asuint32(obj));
|
2000-08-02 22:29:16 +00:00
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "min-refresh-time", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2011-08-30 05:16:15 +00:00
|
|
|
dns_zone_setminrefreshtime(mayberaw, cfg_obj_asuint32(obj));
|
2000-08-02 22:29:16 +00:00
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "max-retry-time", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2011-08-30 05:16:15 +00:00
|
|
|
dns_zone_setmaxretrytime(mayberaw, cfg_obj_asuint32(obj));
|
2000-08-02 22:29:16 +00:00
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "min-retry-time", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2011-08-30 05:16:15 +00:00
|
|
|
dns_zone_setminretrytime(mayberaw, cfg_obj_asuint32(obj));
|
2000-08-02 22:29:16 +00:00
|
|
|
|
2001-10-11 01:55:03 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "transfer-source", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2024-09-12 12:54:25 +10:00
|
|
|
dns_zone_setxfrsource4(mayberaw, cfg_obj_assockaddr(obj));
|
2001-10-11 01:55:03 +00:00
|
|
|
|
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
result = named_config_get(maps, "transfer-source-v6", &obj);
|
2011-03-11 06:11:27 +00:00
|
|
|
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
2024-09-12 12:54:25 +10:00
|
|
|
dns_zone_setxfrsource6(mayberaw, cfg_obj_assockaddr(obj));
|
2003-02-26 23:29:00 +00:00
|
|
|
|
2006-06-04 23:17:07 +00:00
|
|
|
obj = NULL;
|
2017-09-08 13:39:09 -07:00
|
|
|
(void)named_config_get(maps, "try-tcp-refresh", &obj);
|
2011-08-30 05:16:15 +00:00
|
|
|
dns_zone_setoption(mayberaw, DNS_ZONEOPT_TRYTCPREFRESH,
|
2006-06-04 23:17:07 +00:00
|
|
|
cfg_obj_asboolean(obj));
|
1999-12-16 23:11:07 +00:00
|
|
|
break;
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2010-12-16 09:51:30 +00:00
|
|
|
case dns_zone_staticstub:
|
2025-04-15 13:39:57 -07:00
|
|
|
CHECK(configure_staticstub(zoptions, toptions, zone, zname,
|
2023-02-21 12:15:01 +11:00
|
|
|
default_dbtype));
|
2010-12-16 09:51:30 +00:00
|
|
|
break;
|
|
|
|
|
2000-05-25 19:27:48 +00:00
|
|
|
default:
|
|
|
|
break;
|
1999-12-16 23:11:07 +00:00
|
|
|
}
|
|
|
|
|
2023-02-21 12:15:01 +11:00
|
|
|
result = ISC_R_SUCCESS;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (kasp != NULL) {
|
|
|
|
dns_kasp_detach(&kasp);
|
|
|
|
}
|
|
|
|
return result;
|
1999-12-16 23:11:07 +00:00
|
|
|
}
|
|
|
|
|
2010-12-18 01:56:23 +00:00
|
|
|
/*
|
|
|
|
* Set up a DLZ zone as writeable
|
|
|
|
*/
|
|
|
|
isc_result_t
|
2017-09-08 13:39:09 -07:00
|
|
|
named_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone,
|
|
|
|
dns_rdataclass_t rdclass, dns_name_t *name) {
|
2010-12-18 01:56:23 +00:00
|
|
|
dns_db_t *db = NULL;
|
|
|
|
isc_result_t result;
|
|
|
|
|
|
|
|
dns_zone_settype(zone, dns_zone_dlz);
|
|
|
|
result = dns_sdlz_setdb(dlzdatabase, rdclass, name, &db);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
2011-10-11 00:09:03 +00:00
|
|
|
return result;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2010-12-18 01:56:23 +00:00
|
|
|
result = dns_zone_dlzpostload(zone, db);
|
|
|
|
dns_db_detach(&db);
|
2011-10-11 00:09:03 +00:00
|
|
|
return result;
|
2010-12-18 01:56:23 +00:00
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2023-04-03 17:00:36 +02:00
|
|
|
named_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig,
|
|
|
|
const cfg_obj_t *vconfig, const cfg_obj_t *config,
|
|
|
|
dns_kasplist_t *kasplist) {
|
2006-02-28 02:39:52 +00:00
|
|
|
const cfg_obj_t *zoptions = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
const cfg_obj_t *toptions = NULL;
|
2006-02-28 02:39:52 +00:00
|
|
|
const cfg_obj_t *obj = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
const char *cfilename = NULL;
|
|
|
|
const char *zfilename = NULL;
|
2011-10-12 00:10:20 +00:00
|
|
|
dns_zone_t *raw = NULL;
|
2020-10-13 14:48:04 +02:00
|
|
|
bool has_raw, inline_signing;
|
2012-01-31 01:13:10 +00:00
|
|
|
dns_zonetype_t ztype;
|
2000-01-21 19:22:35 +00:00
|
|
|
|
2001-03-04 21:21:39 +00:00
|
|
|
zoptions = cfg_tuple_get(zconfig, "options");
|
2025-04-15 13:39:57 -07:00
|
|
|
toptions = named_zone_templateopts(config, zoptions);
|
2001-03-04 21:21:39 +00:00
|
|
|
|
2010-12-16 09:51:30 +00:00
|
|
|
/*
|
|
|
|
* We always reconfigure a static-stub zone for simplicity, assuming
|
2010-12-16 23:47:08 +00:00
|
|
|
* the amount of data to be loaded is small.
|
2010-12-16 09:51:30 +00:00
|
|
|
*/
|
2025-04-15 13:39:57 -07:00
|
|
|
if (zonetype_fromconfig(zoptions, toptions) == dns_zone_staticstub) {
|
2012-01-31 01:13:10 +00:00
|
|
|
dns_zone_log(zone, ISC_LOG_DEBUG(1),
|
|
|
|
"not reusable: staticstub");
|
2018-04-17 08:29:14 -07:00
|
|
|
return false;
|
2012-01-31 01:13:10 +00:00
|
|
|
}
|
2011-08-30 05:16:15 +00:00
|
|
|
|
2012-01-31 01:13:10 +00:00
|
|
|
/* If there's a raw zone, use that for filename and type comparison */
|
2011-10-12 00:10:20 +00:00
|
|
|
dns_zone_getraw(zone, &raw);
|
|
|
|
if (raw != NULL) {
|
2012-01-31 01:13:10 +00:00
|
|
|
zfilename = dns_zone_getfile(raw);
|
|
|
|
ztype = dns_zone_gettype(raw);
|
2011-10-12 00:10:20 +00:00
|
|
|
dns_zone_detach(&raw);
|
2018-04-17 08:29:14 -07:00
|
|
|
has_raw = true;
|
2012-01-31 01:13:10 +00:00
|
|
|
} else {
|
|
|
|
zfilename = dns_zone_getfile(zone);
|
|
|
|
ztype = dns_zone_gettype(zone);
|
2018-04-17 08:29:14 -07:00
|
|
|
has_raw = false;
|
2012-01-31 01:13:10 +00:00
|
|
|
}
|
2011-10-12 00:10:20 +00:00
|
|
|
|
2023-04-03 17:00:36 +02:00
|
|
|
inline_signing = named_zone_inlinesigning(zconfig, vconfig, config,
|
|
|
|
kasplist);
|
2020-10-13 14:48:04 +02:00
|
|
|
if (!inline_signing && has_raw) {
|
2012-01-31 01:13:10 +00:00
|
|
|
dns_zone_log(zone, ISC_LOG_DEBUG(1),
|
|
|
|
"not reusable: old zone was inline-signing");
|
2018-04-17 08:29:14 -07:00
|
|
|
return false;
|
2020-10-13 14:48:04 +02:00
|
|
|
} else if (inline_signing && !has_raw) {
|
2012-01-31 01:13:10 +00:00
|
|
|
dns_zone_log(zone, ISC_LOG_DEBUG(1),
|
|
|
|
"not reusable: old zone was not inline-signing");
|
2018-04-17 08:29:14 -07:00
|
|
|
return false;
|
2012-01-31 01:13:10 +00:00
|
|
|
}
|
|
|
|
|
2025-04-15 13:39:57 -07:00
|
|
|
if (zonetype_fromconfig(zoptions, toptions) != ztype) {
|
2012-01-31 01:13:10 +00:00
|
|
|
dns_zone_log(zone, ISC_LOG_DEBUG(1),
|
|
|
|
"not reusable: type mismatch");
|
2018-04-17 08:29:14 -07:00
|
|
|
return false;
|
2012-01-31 01:13:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
obj = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
(void)named_config_findopt(zoptions, toptions, "file", &obj);
|
2012-01-31 01:13:10 +00:00
|
|
|
if (obj != NULL) {
|
|
|
|
cfilename = cfg_obj_asstring(obj);
|
|
|
|
} else {
|
|
|
|
cfilename = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-01-31 01:13:10 +00:00
|
|
|
if (!((cfilename == NULL && zfilename == NULL) ||
|
|
|
|
(cfilename != NULL && zfilename != NULL &&
|
|
|
|
strcmp(cfilename, zfilename) == 0)))
|
|
|
|
{
|
|
|
|
dns_zone_log(zone, ISC_LOG_DEBUG(1),
|
|
|
|
"not reusable: filename mismatch");
|
2018-04-17 08:29:14 -07:00
|
|
|
return false;
|
2012-01-31 01:13:10 +00:00
|
|
|
}
|
2000-01-21 19:22:35 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
return true;
|
2000-01-21 19:22:35 +00:00
|
|
|
}
|
2020-10-13 14:48:04 +02:00
|
|
|
|
|
|
|
bool
|
2023-04-03 17:00:36 +02:00
|
|
|
named_zone_inlinesigning(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig,
|
|
|
|
const cfg_obj_t *config, dns_kasplist_t *kasplist) {
|
2025-04-15 13:39:57 -07:00
|
|
|
const cfg_obj_t *maps[5] = { 0 }, *noopts[3] = { 0 };
|
2020-10-13 14:48:04 +02:00
|
|
|
const cfg_obj_t *signing = NULL;
|
2023-04-03 17:00:36 +02:00
|
|
|
const cfg_obj_t *policy = NULL;
|
2025-04-15 13:39:57 -07:00
|
|
|
const cfg_obj_t *toptions = NULL;
|
2023-04-03 17:00:36 +02:00
|
|
|
dns_kasp_t *kasp = NULL;
|
|
|
|
isc_result_t res;
|
2020-12-03 15:01:42 +01:00
|
|
|
bool inline_signing = false;
|
2023-04-03 17:00:36 +02:00
|
|
|
int i = 0;
|
2020-10-13 14:48:04 +02:00
|
|
|
|
2025-04-15 13:39:57 -07:00
|
|
|
noopts[i] = maps[i] = cfg_tuple_get(zconfig, "options");
|
|
|
|
i++;
|
|
|
|
|
|
|
|
if (config != NULL) {
|
|
|
|
toptions = named_zone_templateopts(config, maps[0]);
|
|
|
|
if (toptions != NULL) {
|
|
|
|
noopts[i] = maps[i] = toptions;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
noopts[i] = NULL;
|
2023-04-03 17:00:36 +02:00
|
|
|
if (vconfig != NULL) {
|
|
|
|
maps[i++] = cfg_tuple_get(vconfig, "options");
|
|
|
|
}
|
|
|
|
if (config != NULL) {
|
|
|
|
const cfg_obj_t *options = NULL;
|
|
|
|
(void)cfg_map_get(config, "options", &options);
|
|
|
|
if (options != NULL) {
|
|
|
|
maps[i++] = options;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
maps[i] = NULL;
|
|
|
|
|
2023-10-12 12:02:02 +02:00
|
|
|
/* Check the value in dnssec-policy. */
|
2023-04-03 17:00:36 +02:00
|
|
|
policy = NULL;
|
|
|
|
res = named_config_get(maps, "dnssec-policy", &policy);
|
|
|
|
/* If no dnssec-policy found, then zone is not using inline-signing. */
|
|
|
|
if (res != ISC_R_SUCCESS ||
|
|
|
|
strcmp(cfg_obj_asstring(policy), "none") == 0)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Lookup the policy. */
|
|
|
|
res = dns_kasplist_find(kasplist, cfg_obj_asstring(policy), &kasp);
|
|
|
|
if (res != ISC_R_SUCCESS) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline_signing = dns_kasp_inlinesigning(kasp);
|
|
|
|
dns_kasp_detach(&kasp);
|
2020-10-13 14:48:04 +02:00
|
|
|
|
2023-10-12 12:02:02 +02:00
|
|
|
/*
|
|
|
|
* The zone option 'inline-signing' may override the value in
|
2025-04-15 13:39:57 -07:00
|
|
|
* dnssec-policy. This is a zone-only option, so look in the
|
|
|
|
* zone and template blocks only.
|
2023-10-12 12:02:02 +02:00
|
|
|
*/
|
2025-04-15 13:39:57 -07:00
|
|
|
res = named_config_get(noopts, "inline-signing", &signing);
|
2023-10-12 12:02:02 +02:00
|
|
|
if (res == ISC_R_SUCCESS && cfg_obj_isboolean(signing)) {
|
|
|
|
return cfg_obj_asboolean(signing);
|
|
|
|
}
|
|
|
|
|
2020-10-13 14:48:04 +02:00
|
|
|
return inline_signing;
|
|
|
|
}
|
2025-04-15 13:39:57 -07:00
|
|
|
|
|
|
|
const cfg_obj_t *
|
|
|
|
named_zone_templateopts(const cfg_obj_t *config, const cfg_obj_t *zoptions) {
|
|
|
|
const cfg_obj_t *templates = NULL;
|
|
|
|
const cfg_obj_t *obj = NULL;
|
|
|
|
|
|
|
|
(void)cfg_map_get(config, "template", &templates);
|
|
|
|
(void)cfg_map_get(zoptions, "template", &obj);
|
|
|
|
if (obj != NULL && templates != NULL) {
|
|
|
|
const char *tmplname = cfg_obj_asstring(obj);
|
|
|
|
CFG_LIST_FOREACH(templates, e) {
|
|
|
|
const cfg_obj_t *t = cfg_tuple_get(cfg_listelt_value(e),
|
|
|
|
"name");
|
|
|
|
if (strcasecmp(cfg_obj_asstring(t), tmplname) == 0) {
|
|
|
|
return cfg_tuple_get(cfg_listelt_value(e),
|
|
|
|
"options");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|