]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
allow grant rules to be retrieved
authorMark Andrews <marka@isc.org>
Wed, 3 Jul 2019 07:03:13 +0000 (17:03 +1000)
committerMark Andrews <marka@isc.org>
Wed, 13 May 2020 05:35:28 +0000 (15:35 +1000)
lib/dns/include/dns/ssu.h
lib/dns/ssu.c
lib/ns/update.c

index 19f49f0b5b1bd7cd7636f12018dac3b14a8f85ab..b3a6e829e007f43f230a7f96549e6a560078bbd9 100644 (file)
@@ -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
index c2647b6619641eaa33ba72873b24b5edaab9f14a..39de7057763b22291d2e5932b27af126f52d0c3d 100644 (file)
@@ -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);
        }
 
index 3c88115e0b04c2f83eb6ef7da9b8510e9e7f49bf..2a4355a0a3dde92f75ba70b2994a62e4034c7fa3 100644 (file)
@@ -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);
        }