From 79de6edde82f4417359a49eae1b3f756044d950f Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 3 Jul 2019 17:03:13 +1000 Subject: [PATCH] allow grant rules to be retrieved --- lib/dns/include/dns/ssu.h | 2 +- lib/dns/ssu.c | 18 ++++++++++-------- lib/ns/update.c | 39 ++++++++++++++++++++++++++++++--------- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/lib/dns/include/dns/ssu.h b/lib/dns/include/dns/ssu.h index 19f49f0b5b..b3a6e829e0 100644 --- a/lib/dns/include/dns/ssu.h +++ b/lib/dns/include/dns/ssu.h @@ -141,7 +141,7 @@ bool dns_ssutable_checkrules(dns_ssutable_t *table, const dns_name_t *signer, const dns_name_t *name, const isc_netaddr_t *addr, bool tcp, const dns_aclenv_t *env, dns_rdatatype_t type, - const dst_key_t *key); + const dst_key_t *key, const dns_ssurule_t **rulep); /*%< * Checks that the attempted update of (name, type) is allowed according * to the rules specified in the simple-secure-update rule table. If diff --git a/lib/dns/ssu.c b/lib/dns/ssu.c index c2647b6619..39de705776 100644 --- a/lib/dns/ssu.c +++ b/lib/dns/ssu.c @@ -39,8 +39,7 @@ struct dns_ssurule { unsigned int magic; bool grant; /*%< is this a grant or a deny? */ - dns_ssumatchtype_t matchtype; /*%< which type of pattern match? - * */ + dns_ssumatchtype_t matchtype; /*%< which type of pattern match? */ dns_name_t *identity; /*%< the identity to match */ dns_name_t *name; /*%< the name being updated */ unsigned int ntypes; /*%< number of data types covered */ @@ -284,15 +283,15 @@ bool dns_ssutable_checkrules(dns_ssutable_t *table, const dns_name_t *signer, const dns_name_t *name, const isc_netaddr_t *addr, bool tcp, const dns_aclenv_t *env, dns_rdatatype_t type, - const dst_key_t *key) { - dns_ssurule_t *rule; - unsigned int i; + const dst_key_t *key, const dns_ssurule_t **rulep) { dns_fixedname_t fixed; - dns_name_t *wildcard; - dns_name_t *tcpself; dns_name_t *stfself; - isc_result_t result; + dns_name_t *tcpself; + dns_name_t *wildcard; + dns_ssurule_t *rule; int match; + isc_result_t result; + unsigned int i; REQUIRE(VALID_SSUTABLE(table)); REQUIRE(signer == NULL || dns_name_isabsolute(signer)); @@ -522,6 +521,9 @@ dns_ssutable_checkrules(dns_ssutable_t *table, const dns_name_t *signer, continue; } } + if (rule->grant && rulep != NULL) { + *rulep = rule; + } return (rule->grant); } diff --git a/lib/ns/update.c b/lib/ns/update.c index 3c88115e0b..2a4355a0a3 100644 --- a/lib/ns/update.c +++ b/lib/ns/update.c @@ -899,8 +899,9 @@ typedef struct { static isc_result_t ssu_checkrule(void *data, dns_rdataset_t *rrset) { - ssu_check_t *ssuinfo = data; bool result; + const dns_ssurule_t *rule = NULL; + ssu_check_t *ssuinfo = data; /* * If we're deleting all records, it's ok to delete RRSIG and NSEC even @@ -910,9 +911,10 @@ ssu_checkrule(void *data, dns_rdataset_t *rrset) { rrset->type == dns_rdatatype_nsec) { return (ISC_R_SUCCESS); } - result = dns_ssutable_checkrules( - ssuinfo->table, ssuinfo->signer, ssuinfo->name, ssuinfo->addr, - ssuinfo->tcp, ssuinfo->aclenv, rrset->type, ssuinfo->key); + result = dns_ssutable_checkrules(ssuinfo->table, ssuinfo->signer, + ssuinfo->name, ssuinfo->addr, + ssuinfo->tcp, ssuinfo->aclenv, + rrset->type, ssuinfo->key, &rule); return (result == true ? ISC_R_SUCCESS : ISC_R_FAILURE); } @@ -2565,6 +2567,9 @@ update_action(isc_task_t *task, isc_event_t *event) { uint64_t records; dns_aclenv_t *env = ns_interfacemgr_getaclenv(client->manager->interface->mgr); + size_t ruleslen = 0; + size_t rule; + const dns_ssurule_t **rules = NULL; INSIST(event->ev_type == DNS_EVENT_UPDATE); @@ -2739,15 +2744,24 @@ update_action(isc_task_t *task, isc_event_t *event) { /* * Perform the Update Section Prescan. */ + if (ssutable != NULL) { + ruleslen = request->counts[DNS_SECTION_UPDATE]; + rules = isc_mem_get(mctx, sizeof(*rules) * ruleslen); + memset(rules, 0, sizeof(*rules) * ruleslen); + } - for (result = dns_message_firstname(request, DNS_SECTION_UPDATE); + for (rule = 0, + result = dns_message_firstname(request, DNS_SECTION_UPDATE); result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_UPDATE)) + rule++, result = dns_message_nextname(request, DNS_SECTION_UPDATE)) { dns_name_t *name = NULL; dns_rdata_t rdata = DNS_RDATA_INIT; dns_ttl_t ttl; dns_rdataclass_t update_class; + + INSIST(ssutable == NULL || rule < ruleslen); + get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, &name, &rdata, &covers, &ttl, &update_class); @@ -2820,7 +2834,7 @@ update_action(isc_task_t *task, isc_event_t *event) { if (!dns_ssutable_checkrules( ssutable, client->signer, name, &netaddr, TCPCLIENT(client), env, - rdata.type, tsigkey)) + rdata.type, tsigkey, &rules[rule])) { FAILC(DNS_R_REFUSED, "rejected by " "secure update"); @@ -2847,9 +2861,10 @@ update_action(isc_task_t *task, isc_event_t *event) { */ options = dns_zone_getoptions(zone); - for (result = dns_message_firstname(request, DNS_SECTION_UPDATE); + for (rule = 0, + result = dns_message_firstname(request, DNS_SECTION_UPDATE); result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_UPDATE)) + rule++, result = dns_message_nextname(request, DNS_SECTION_UPDATE)) { dns_name_t *name = NULL; dns_rdata_t rdata = DNS_RDATA_INIT; @@ -2857,6 +2872,8 @@ update_action(isc_task_t *task, isc_event_t *event) { dns_rdataclass_t update_class; bool flag; + INSIST(ssutable == NULL || rule < ruleslen); + get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, &name, &rdata, &covers, &ttl, &update_class); @@ -3420,6 +3437,10 @@ common: dns_db_detach(&db); } + if (rules != NULL) { + isc_mem_put(mctx, rules, sizeof(*rules) * ruleslen); + } + if (ssutable != NULL) { dns_ssutable_detach(&ssutable); }