min-transfer-rate-in 10240 5;\n\
multi-master no;\n\
notify yes;\n\
- notify-cds no;\n\
notify-defer 0;\n\
notify-delay 5;\n\
notify-to-soa no;\n\
allow_update_forwarding
} acl_type_t;
+#define MAPS_SIZE 6
+#define NODEFAULT_MAPS_SIZE 5
+#define NOOPTIONS_MAPS_SIZE 3
+
/*%
* Convenience function for configuring a single zone ACL.
*/
cfg_aclconfctx_t *aclctx, dns_zone_t *zone,
void (*setzacl)(dns_zone_t *, dns_acl_t *),
void (*clearzacl)(dns_zone_t *)) {
- const cfg_obj_t *maps[6] = { 0 };
+ const cfg_obj_t *maps[MAPS_SIZE] = { 0 };
const cfg_obj_t *aclobj = NULL;
int i = 0;
dns_acl_t **aclp = NULL, *acl = NULL;
* default configuration.
*/
static dns_notifytype_t
-process_notifytype(dns_notifytype_t ntype, dns_zonetype_t ztype,
- const char *zname, const cfg_obj_t **maps) {
+process_notifysoatype(dns_notifytype_t ntype, dns_zonetype_t ztype,
+ const char *zname, const cfg_obj_t **maps) {
const cfg_obj_t *obj = NULL;
/*
return dns_notifytype_explicit;
}
+static void
+process_notify_options(dns_rdatatype_t type, const cfg_obj_t **maps,
+ dns_zone_t *zone, dns_zone_t *raw, bool notifycfg) {
+ isc_result_t result;
+ const cfg_obj_t *obj = NULL;
+
+ /*
+ * "notify" for SOA is already inherited and set in
+ * named_zone_configure(), and for other types it can only be
+ * configured within "notify-cfg". Only look into first map
+ * to see if sending NOTIFY(type) messages are allowed.
+ */
+ if (notifycfg) {
+ obj = NULL;
+ result = cfg_map_get(maps[0], "notify", &obj);
+ if (result == ISC_R_SUCCESS && obj != NULL) {
+ dns_zone_setnotifytype(zone, type,
+ cfg_obj_asboolean(obj));
+ } else {
+ dns_zone_setnotifytype(zone, type, dns_notifytype_no);
+ }
+ if (raw != NULL) {
+ dns_zone_setnotifytype(raw, type, dns_notifytype_no);
+ }
+ }
+
+ obj = NULL;
+ result = named_config_get(maps, "notify-delay", &obj);
+ INSIST(result == ISC_R_SUCCESS && obj != NULL);
+ dns_zone_setnotifydelay(zone, type, cfg_obj_asuint32(obj));
+
+ obj = NULL;
+ result = named_config_get(maps, "notify-defer", &obj);
+ INSIST(result == ISC_R_SUCCESS && obj != NULL);
+ dns_zone_setnotifydefer(zone, type, cfg_obj_asuint32(obj));
+
+ obj = NULL;
+ result = named_config_get(maps, "notify-source", &obj);
+ INSIST(result == ISC_R_SUCCESS && obj != NULL);
+ dns_zone_setnotifysrc4(zone, type, cfg_obj_assockaddr(obj));
+
+ obj = NULL;
+ result = named_config_get(maps, "notify-source-v6", &obj);
+ INSIST(result == ISC_R_SUCCESS && obj != NULL);
+ dns_zone_setnotifysrc6(zone, type, cfg_obj_assockaddr(obj));
+}
+
+static isc_result_t
+process_notify_cfg(const cfg_obj_t **maps, dns_zone_t *zone, dns_zone_t *raw) {
+ isc_result_t result;
+ const cfg_obj_t *obj = NULL;
+
+ result = named_config_get(maps, "notify-cfg", &obj);
+ if (result == ISC_R_SUCCESS && obj != NULL) {
+ CFG_LIST_FOREACH(obj, element) {
+ const cfg_obj_t *nmaps[MAPS_SIZE + 1];
+ const cfg_obj_t *map = cfg_listelt_value(element);
+ const char *name =
+ cfg_obj_asstring(cfg_map_getname(map));
+ isc_textregion_t tr;
+ dns_rdatatype_t rdtype = 0;
+
+ tr.base = UNCONST(name);
+ tr.length = strlen(name);
+ result = dns_rdatatype_fromtext(&rdtype, &tr);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(map, ISC_LOG_ERROR,
+ "%s is not a valid notify type",
+ name);
+ return result;
+ }
+ switch (rdtype) {
+ case dns_rdatatype_soa:
+ case dns_rdatatype_cds:
+ break;
+ default:
+ cfg_obj_log(map, ISC_LOG_ERROR,
+ "%s notify type is not supported",
+ name);
+ return ISC_R_NOTIMPLEMENTED;
+ }
+
+ /* Prepend the notify-cfg map. */
+ size_t i = 0;
+ nmaps[i] = map;
+ while (maps[i] != NULL) {
+ nmaps[i + 1] = maps[i];
+ i++;
+ }
+ INSIST(i <= MAPS_SIZE);
+ nmaps[i + 1] = NULL;
+
+ process_notify_options(rdtype, nmaps, zone, raw, true);
+ }
+ }
+
+ return ISC_R_SUCCESS;
+}
+
isc_result_t
named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
const cfg_obj_t *zconfig, cfg_aclconfctx_t *aclctx,
const char *zname;
dns_rdataclass_t zclass;
dns_rdataclass_t vclass;
- const cfg_obj_t *maps[6];
- const cfg_obj_t *nodefault[5];
- const cfg_obj_t *nooptions[3];
+ const cfg_obj_t *maps[MAPS_SIZE];
+ const cfg_obj_t *nodefault[NODEFAULT_MAPS_SIZE];
+ const cfg_obj_t *nooptions[NOOPTIONS_MAPS_SIZE];
const cfg_obj_t *zoptions = NULL;
const cfg_obj_t *toptions = NULL;
const cfg_obj_t *options = NULL;
} else {
notifytype = dns_notifytype_no;
}
+ notifytype = cfg_obj_asboolean(obj);
} else {
const char *str = cfg_obj_asstring(obj);
if (strcasecmp(str, "explicit") == 0) {
UNREACHABLE();
}
}
- notifytype = process_notifytype(notifytype, ztype, zname,
- nodefault);
+ notifytype = process_notifysoatype(notifytype, ztype, zname,
+ nodefault);
if (raw != NULL) {
dns_zone_setnotifytype(raw, dns_rdatatype_soa,
dns_notifytype_no);
}
dns_zone_setnotifytype(zone, dns_rdatatype_soa, notifytype);
- obj = NULL;
- result = named_config_get(maps, "notify-cds", &obj);
- INSIST(result == ISC_R_SUCCESS && obj != NULL);
- if (raw != NULL) {
- dns_zone_setnotifytype(raw, dns_rdatatype_cds,
- dns_notifytype_no);
- }
- dns_zone_setnotifytype(zone, dns_rdatatype_cds,
- cfg_obj_asboolean(obj));
-
obj = NULL;
result = named_config_get(maps, "also-notify", &obj);
if (result == ISC_R_SUCCESS &&
INSIST(result == ISC_R_SUCCESS && obj != NULL);
dns_zone_setparentalsrc6(zone, cfg_obj_assockaddr(obj));
- obj = NULL;
- result = named_config_get(maps, "notify-source", &obj);
- INSIST(result == ISC_R_SUCCESS && obj != NULL);
- dns_zone_setnotifysrc4(zone, dns_rdatatype_soa,
- cfg_obj_assockaddr(obj));
-
- obj = NULL;
- result = named_config_get(maps, "notify-source-v6", &obj);
- INSIST(result == ISC_R_SUCCESS && obj != NULL);
- dns_zone_setnotifysrc6(zone, dns_rdatatype_soa,
- cfg_obj_assockaddr(obj));
-
obj = NULL;
result = named_config_get(maps, "notify-to-soa", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
fail);
}
- obj = NULL;
- result = named_config_get(maps, "notify-delay", &obj);
- INSIST(result == ISC_R_SUCCESS && obj != NULL);
- dns_zone_setnotifydelay(zone, dns_rdatatype_soa,
- cfg_obj_asuint32(obj));
-
- obj = NULL;
- result = named_config_get(maps, "notify-defer", &obj);
- INSIST(result == ISC_R_SUCCESS && obj != NULL);
- dns_zone_setnotifydefer(zone, dns_rdatatype_soa,
- cfg_obj_asuint32(obj));
-
obj = NULL;
result = named_config_get(maps, "check-sibling", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
dns_zone_setrad(zone, rad);
}
}
+
+ process_notify_options(dns_rdatatype_soa, maps, zone, raw,
+ false);
+ CHECK(process_notify_cfg(maps, zone, raw));
+
} else if (ztype == dns_zone_redirect) {
dns_zone_setnotifytype(zone, dns_rdatatype_soa,
dns_notifytype_no);
bool
named_zone_inlinesigning(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig,
const cfg_obj_t *config, dns_kasplist_t *kasplist) {
- const cfg_obj_t *maps[5] = { 0 }, *noopts[3] = { 0 };
+ const cfg_obj_t *maps[NODEFAULT_MAPS_SIZE] = { 0 },
+ *noopts[NOOPTIONS_MAPS_SIZE] = { 0 };
const cfg_obj_t *signing = NULL;
const cfg_obj_t *policy = NULL;
const cfg_obj_t *toptions = NULL;
*/
/*
- * Bad notify-cds type
+ * Bad notify-cfg CDS notify type
*/
zone dummy {
type primary;
file "xxxx";
- notify-cds explicit;
+ notify-cfg CDS { notify explicit; };
};
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*
+ * Bad notify-cfg TXT not supported
+ */
+
+zone dummy {
+ type primary;
+ file "xxxx";
+ notify-cfg TXT { notify yes; };
+};
1.2.3.5;
};
dnssec-policy "test";
- notify-cds no;
+ notify-cfg "SOA" {
+ notify yes;
+ notify-defer 1;
+ notify-delay 3;
+ notify-source 192.0.2.1;
+ notify-source-v6 2001:db8::1;
+ };
+ notify-cfg "CDS" {
+ notify no;
+ };
parental-source 10.10.10.10;
};
zone "dnssec-default" {
"parents";
};
dnssec-policy "default";
- notify-cds yes;
+ notify-cfg "CDS" {
+ notify yes;
+ notify-defer 0;
+ notify-delay 5;
+ notify-source 0.0.0.0;
+ notify-source-v6 ::;
+ };
};
zone "dnssec-inherit" {
type primary;
allow-transfer { any; };
key-directory ".";
dnssec-validation yes;
- notify-cds yes;
+ notify-cfg CDS { notify yes; };
};
key rndc_key {
allow-transfer { any; };
key-directory ".";
dnssec-validation yes;
- notify-cds yes;
+ notify-cfg cds { notify yes; };
};
key rndc_key {
allow-transfer { any; };
recursion yes;
dnssec-validation @dnssec_validation@;
- notify-cds yes;
+ notify-cfg CDS { notify yes; };
};
key rndc_key {
statement. It would only be necessary to turn off this option if it
caused secondary zones to crash.
-.. namedconf:statement:: notify-cds
+.. namedconf:statement:: notify-cfg
:tags: dnssec
- :short: Controls whether ``NOTIFY(CDS)`` messages are sent on zone changes.
-
- If set to ``yes``, DNS NOTIFY(CDS) messages are sent when the CDS or CDNSKEY
- RRset changes. The messages are sent to the servers listed in the parent
- zone's matching DSYNC records. A DSYNC record matches if the owner name under
- `_dsync` subdomain of the parent zone corresponds to the given zone. For
- example, the zone `child.example` should have a DSYNC record at
- `child._dsync.example`. In addition, the RRtype field of the record must be
- `CDS` and the Scheme field must be 1 (NOTIFY).
-
- The default is ``no``. The :namedconf:ref:`notify-cds` option may also be
- specified in the :any:`zone` statement, in which case it overrides the
- ``options notify-cds`` statement.
+ :short: Controls generalized DNS notifications configuration.
+
+ This option can be used to override NOTIFY configuration options
+ for specific types. The following options can be set within a
+ :any:`notify-cfg` statement: :any:`notify-defer`, :any:`notify-delay`,
+ :any:`notify-source`, :any:`notify-source-v6`, and
+ :namedconf:ref:`notify`. The latter can only be set to
+ ``yes`` or ``no``.
+
+ By default, only NOTIFY(SOA) messages are enabled. When configuring
+ notify configuration for other types you enable sending DNS notifications
+ for the given type. For example, to enable NOTIFY(CDS) messages, using a
+ specific source, you can add the following configuration:
+
+ ::
+
+ notify-cfg CDS { notify yes; notify-source-v6 2001:DB8::1; };
+
+ If enabled, DNS NOTIFY(CDS) messages are sent when the CDS or CDNSKEY
+ RRset changes. The messages are sent to the servers listed in the parent
+ zone's matching DSYNC records. A DSYNC record matches if the owner name under
+ `_dsync` subdomain of the parent zone corresponds to the given zone. For
+ example, the zone `child.example` should have a DSYNC record at
+ `child._dsync.example`. In addition, the RRtype field of the record must be
+ `CDS` and the Scheme field must be 1 (NOTIFY).
+
+ The :any:`notify-defer` and :any:`notify-delay` options are not applicable
+ to NOTIFY(CDS) messages and they are ignored for that type.
+
+ The :namedconf:ref:`notify-cfg` option may also be specified in the
+ :any:`zone` statement, in which case it overrides the ``options notify-cfg``
+ statement. The only supported types are ``SOA`` and ``CDS``.
.. namedconf:statement:: notify-to-soa
:tags: transfer
min-transfer-rate-in <integer> <integer>;
multi-master <boolean>;
notify ( explicit | master-only | primary-only | <boolean> );
- notify-cds <boolean>;
+ notify-cfg <string> {
+ notify <boolean>;
+ notify-defer <integer>;
+ notify-delay <integer>;
+ notify-source ( <ipv4_address> | * );
+ notify-source-v6 ( <ipv6_address> | * );
+ }; // may occur multiple times
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * );
no-case-compress { <address_match_element>; ... };
nocookie-udp-size <integer>;
notify ( explicit | master-only | primary-only | <boolean> );
- notify-cds <boolean>;
+ notify-cfg <string> {
+ notify <boolean>;
+ notify-defer <integer>;
+ notify-delay <integer>;
+ notify-source ( <ipv4_address> | * );
+ notify-source-v6 ( <ipv6_address> | * );
+ }; // may occur multiple times
notify-defer <integer>;
notify-delay <integer>;
notify-rate <integer>;
min-transfer-rate-in <integer> <integer>;
multi-master <boolean>;
notify ( explicit | master-only | primary-only | <boolean> );
- notify-cds <boolean>;
+ notify-cfg <string> {
+ notify <boolean>;
+ notify-defer <integer>;
+ notify-delay <integer>;
+ notify-source ( <ipv4_address> | * );
+ notify-source-v6 ( <ipv6_address> | * );
+ }; // may occur multiple times
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * );
no-case-compress { <address_match_element>; ... };
nocookie-udp-size <integer>;
notify ( explicit | master-only | primary-only | <boolean> );
- notify-cds <boolean>;
+ notify-cfg <string> {
+ notify <boolean>;
+ notify-defer <integer>;
+ notify-delay <integer>;
+ notify-source ( <ipv4_address> | * );
+ notify-source-v6 ( <ipv6_address> | * );
+ }; // may occur multiple times
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * );
max-types-per-name <integer>;
max-zone-ttl ( unlimited | <duration> ); // deprecated
notify ( explicit | master-only | primary-only | <boolean> );
- notify-cds <boolean>;
+ notify-cfg <string> {
+ notify <boolean>;
+ notify-defer <integer>;
+ notify-delay <integer>;
+ notify-source ( <ipv4_address> | * );
+ notify-source-v6 ( <ipv6_address> | * );
+ }; // may occur multiple times
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * );
min-transfer-rate-in <integer> <integer>;
multi-master <boolean>;
notify ( explicit | master-only | primary-only | <boolean> );
- notify-cds <boolean>;
+ notify-cfg <string> {
+ notify <boolean>;
+ notify-defer <integer>;
+ notify-delay <integer>;
+ notify-source ( <ipv4_address> | * );
+ notify-source-v6 ( <ipv6_address> | * );
+ }; // may occur multiple times
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * );
/*
* Primary, secondary, and mirror zones may have an "also-notify"
- * field, but shouldn't if notify is disabled.
+ * field, but shouldn't if notify is disabled. Also check "notify-cfg"
+ * for valid types.
*/
if (ztype == CFG_ZONE_PRIMARY || ztype == CFG_ZONE_SECONDARY ||
ztype == CFG_ZONE_MIRROR)
result = tresult;
}
}
+
+ obj = NULL;
+ (void)get_zoneopt(zoptions, toptions, voptions, goptions,
+ "notify-cfg", &obj);
+ if (obj != NULL) {
+ CFG_LIST_FOREACH(obj, element) {
+ const cfg_obj_t *map =
+ cfg_listelt_value(element);
+ const char *name =
+ cfg_obj_asstring(cfg_map_getname(map));
+ isc_textregion_t tr;
+ dns_rdatatype_t rdtype = 0;
+
+ tr.base = UNCONST(name);
+ tr.length = strlen(name);
+ tresult = dns_rdatatype_fromtext(&rdtype, &tr);
+ if (tresult != ISC_R_SUCCESS &&
+ result == ISC_R_SUCCESS)
+ {
+ cfg_obj_log(
+ map, ISC_LOG_ERROR,
+ "%s is not a valid notify type",
+ name);
+ result = tresult;
+ }
+
+ switch (rdtype) {
+ case dns_rdatatype_soa:
+ case dns_rdatatype_cds:
+ break;
+ default:
+ if (result == ISC_R_SUCCESS) {
+ cfg_obj_log(map, ISC_LOG_ERROR,
+ "%s notify type is "
+ "not supported",
+ name);
+ result = ISC_R_NOTIMPLEMENTED;
+ }
+ }
+ }
+ }
}
/*
static cfg_type_t cfg_type_maxduration;
static cfg_type_t cfg_type_minimal;
static cfg_type_t cfg_type_nameportiplist;
+static cfg_type_t cfg_type_notifycfg;
static cfg_type_t cfg_type_notifytype;
static cfg_type_t cfg_type_optional_allow;
static cfg_type_t cfg_type_optional_class;
CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB, NULL },
{ "notify", &cfg_type_notifytype,
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR, NULL },
- { "notify-cds", &cfg_type_boolean,
- CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR, NULL },
+ { "notify-cfg", &cfg_type_notifycfg,
+ CFG_CLAUSEFLAG_MULTI | CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY |
+ CFG_ZONE_MIRROR,
+ NULL },
{ "notify-defer", &cfg_type_uint32,
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR, NULL },
{ "notify-delay", &cfg_type_uint32,
doc_notify_type, &cfg_rep_string, notify_enums,
};
+/*
+ * Generalized DNS Notifications.
+ */
+static cfg_clausedef_t notify_clauses[] = {
+ { "notify", &cfg_type_boolean, 0, NULL }, /* this limits the options for
+ NOTIFY(SOA) */
+ { "notify-defer", &cfg_type_uint32, 0, NULL },
+ { "notify-delay", &cfg_type_uint32, 0, NULL },
+ { "notify-source", &cfg_type_sockaddr4wild, 0, NULL },
+ { "notify-source-v6", &cfg_type_sockaddr6wild, 0, NULL },
+ { NULL, NULL, 0, NULL },
+};
+
+static cfg_clausedef_t *notify_clausesets[] = { notify_clauses, NULL };
+
+static cfg_type_t cfg_type_notifycfg = { "notify-cfg", cfg_parse_named_map,
+ cfg_print_map, cfg_doc_map,
+ &cfg_rep_map, notify_clausesets };
+
static const char *minimal_enums[] = { "no-auth", "no-auth-recursive", NULL };
static isc_result_t
parse_minimal(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {