Parse "parental-agents" configuration

Parse the new "parental-agents" configuration and store it in the zone
structure.
This commit is contained in:
Matthijs Mekking 2021-05-11 14:46:38 +02:00
parent 6040c71478
commit 6f92d4b9a5
3 changed files with 125 additions and 14 deletions

View file

@ -1710,6 +1710,28 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_zone_clearforwardacl));
}
/*%
* Configure parental agents, applies to primary and secondary zones.
*/
if (ztype == dns_zone_master || ztype == dns_zone_slave) {
obj = NULL;
(void)cfg_map_get(zoptions, "parental-agents", &obj);
if (obj != NULL) {
dns_ipkeylist_t ipkl;
dns_ipkeylist_init(&ipkl);
RETERR(named_config_getipandkeylist(
config, "parental-agents", obj, mctx, &ipkl));
result = dns_zone_setparentals(zone, ipkl.addrs,
ipkl.keys, ipkl.tlss,
ipkl.count);
dns_ipkeylist_clear(mctx, &ipkl);
RETERR(result);
} else {
RETERR(dns_zone_setparentals(zone, NULL, NULL, NULL,
0));
}
}
/*%
* Primary master functionality.
*/

View file

@ -642,12 +642,30 @@ dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *primaries,
*\li 'zone' to be a valid zone.
*\li 'primaries' array of isc_sockaddr_t with port set or NULL.
*\li 'count' the number of primaries.
*\li 'keynames' array of dns_name_t's for tsig keys or NULL.
*\li 'keynames' array of dns_name_t's for tsig keys or NULL.
*
* \li dns_zone_setprimaries() is just a wrapper to setprimarieswithkeys(),
* passing NULL in the keynames field.
*\li If 'primaries' is NULL then 'count' must be zero.
*
* \li If 'primaries' is NULL then 'count' must be zero.
* Returns:
*\li #ISC_R_SUCCESS
*\li #ISC_R_NOMEMORY
*\li Any result dns_name_dup() can return, if keynames!=NULL
*/
isc_result_t
dns_zone_setparentals(dns_zone_t *zone, const isc_sockaddr_t *parentals,
dns_name_t **keynames, dns_name_t **tlsnames,
uint32_t count);
/*%<
* Set the list of parental agents for the zone.
*
* Require:
*\li 'zone' to be a valid zone.
*\li 'parentals' array of isc_sockaddr_t with port set or NULL.
*\li 'count' the number of primaries.
*\li 'keynames' array of dns_name_t's for tsig keys or NULL.
*
*\li If 'parentals' is NULL then 'count' must be zero.
*
* Returns:
*\li #ISC_R_SUCCESS

View file

@ -281,6 +281,15 @@ struct dns_zone {
unsigned int masterscnt;
unsigned int curmaster;
isc_sockaddr_t masteraddr;
isc_sockaddr_t *parentals;
isc_dscp_t *parentaldscps;
dns_name_t **parentalkeynames;
dns_name_t **parentaltlsnames;
dns_dnsseckeylist_t checkds_ok;
unsigned int parentalscnt;
isc_sockaddr_t parentaladdr;
dns_notifytype_t notifytype;
isc_sockaddr_t *notify;
dns_name_t **notifykeynames;
@ -1129,6 +1138,16 @@ free_refs:
return (result);
}
static void
clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
dns_dnsseckey_t *key;
while (!ISC_LIST_EMPTY(*list)) {
key = ISC_LIST_HEAD(*list);
ISC_LIST_UNLINK(*list, key, link);
dns_dnsseckey_destroy(mctx, &key);
}
}
/*
* Free a zone. Because we require that there be no more
* outstanding events or references, no locking is necessary.
@ -1222,6 +1241,10 @@ zone_free(dns_zone_t *zone) {
if (zone->kasp != NULL) {
dns_kasp_detach(&zone->kasp);
}
if (!ISC_LIST_EMPTY(zone->checkds_ok)) {
clear_keylist(&zone->checkds_ok, zone->mctx);
}
zone->journalsize = -1;
if (zone->journal != NULL) {
isc_mem_free(zone->mctx, zone->journal);
@ -1251,6 +1274,8 @@ zone_free(dns_zone_t *zone) {
dns_catz_catzs_detach(&zone->catzs);
}
zone_freedbargs(zone);
RUNTIME_CHECK(dns_zone_setparentals(zone, NULL, NULL, NULL, 0) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(dns_zone_setprimaries(zone, NULL, NULL, NULL, 0) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, NULL, NULL, NULL, 0) ==
@ -6305,6 +6330,62 @@ unlock:
return (result);
}
isc_result_t
dns_zone_setparentals(dns_zone_t *zone, const isc_sockaddr_t *parentals,
dns_name_t **keynames, dns_name_t **tlsnames,
uint32_t count) {
isc_result_t result = ISC_R_SUCCESS;
isc_sockaddr_t *newaddrs = NULL;
isc_dscp_t *newdscps = NULL;
dns_name_t **newkeynames = NULL;
dns_name_t **newtlsnames = NULL;
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(count == 0 || parentals != NULL);
if (keynames != NULL || tlsnames != NULL) {
REQUIRE(count != 0);
}
LOCK_ZONE(zone);
clear_serverslist(&zone->parentals, &zone->parentaldscps,
&zone->parentalkeynames, &zone->parentaltlsnames,
&zone->parentalscnt, zone->mctx);
/*
* If count == 0, don't allocate any space for parentals, or keynames
* so internally, those pointers are NULL if count == 0
*/
if (count == 0) {
goto unlock;
}
/*
* Now set up the parentals and parental key lists
*/
result = set_serverslist(count, parentals, &newaddrs, NULL, &newdscps,
keynames, &newkeynames, tlsnames, &newtlsnames,
zone->mctx);
INSIST(newdscps == NULL);
if (result != ISC_R_SUCCESS) {
goto unlock;
}
/*
* Everything is ok so attach to the zone.
*/
zone->parentals = newaddrs;
zone->parentaldscps = newdscps;
zone->parentalkeynames = newkeynames;
zone->parentaltlsnames = newtlsnames;
zone->parentalscnt = count;
dns_zone_log(zone, ISC_LOG_NOTICE, "checkds: set %u parentals", count);
unlock:
UNLOCK_ZONE(zone);
return (result);
}
isc_result_t
dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
isc_result_t result = ISC_R_SUCCESS;
@ -19617,16 +19698,6 @@ cleanup:
return (result);
}
static void
clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
dns_dnsseckey_t *key;
while (!ISC_LIST_EMPTY(*list)) {
key = ISC_LIST_HEAD(*list);
ISC_LIST_UNLINK(*list, key, link);
dns_dnsseckey_destroy(mctx, &key);
}
}
/* Called once; *timep should be set to the current time. */
static isc_result_t
next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {