]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Make IXFR deletion more robust
authorRalph Dolmans <ralph@nlnetlabs.nl>
Thu, 25 Apr 2019 18:00:56 +0000 (20:00 +0200)
committerRalph Dolmans <ralph@nlnetlabs.nl>
Thu, 25 Apr 2019 18:00:56 +0000 (20:00 +0200)
services/authzone.c
services/localzone.h
services/rpz.c
services/rpz.h

index 04f1c7d5a08fbe805ed533d226746ad4aab83573..a408166e576e66df244e7106c9ad50e32624c4c3 100644 (file)
@@ -1248,7 +1248,7 @@ az_remove_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
        }
        if(z->rpz) {
                rpz_remove_rr(z->rpz, z->namelen, dname, dname_len, rr_type,
-                       rr_class, rdata, rdatalen, rr, rr_len);
+                       rr_class, rdata, rdatalen);
        }
        return 1;
 }
index d8dfa014570ee899a50c00d403f4555c4e05c41f..e8c493f63a85b8ef18b4133f768d3a452770eb3c 100644 (file)
@@ -95,7 +95,9 @@ enum localzone_type {
        /** answer with noerror/nodata, even when there is local data */
        local_zone_always_nodata,
        /** answer not from the view, but global or no-answer */
-       local_zone_noview
+       local_zone_noview,
+       /** Invalid type, cannot be used to generate answer */
+       local_zone_invalid
 };
 
 /**
index b479bed0b232440011a65920d360358664729972..ab482e5a6647733e9239bd335805dfd510fc9f5e 100644 (file)
@@ -167,6 +167,37 @@ rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
        return RPZ_LOCAL_DATA_ACTION;
 }
 
+static enum localzone_type 
+rpz_action_to_localzone_type(enum rpz_action a)
+{
+       switch(a) {
+       case RPZ_NXDOMAIN_ACTION:       return local_zone_always_nxdomain;
+       case RPZ_NODATA_ACTION:         return local_zone_always_nodata;
+       case RPZ_DROP_ACTION:           return local_zone_deny;
+       case RPZ_PASSTHRU_ACTION:       return local_zone_always_transparent;
+       case RPZ_LOCAL_DATA_ACTION:     return local_zone_redirect;
+       case RPZ_INVALID_ACTION:
+       case RPZ_TCP_ONLY_ACTION:
+       default:
+               return local_zone_invalid;
+       }
+}
+
+static enum rpz_action
+localzone_type_to_rpz_action(enum localzone_type lzt)
+{
+       switch(lzt) {
+       case local_zone_always_nxdomain:        return RPZ_NXDOMAIN_ACTION;
+       case local_zone_always_nodata:          return RPZ_NODATA_ACTION;
+       case local_zone_deny:                   return RPZ_DROP_ACTION;
+       case local_zone_always_transparent:     return RPZ_PASSTHRU_ACTION;
+       case local_zone_redirect:               return RPZ_LOCAL_DATA_ACTION;
+       case local_zone_invalid:
+       default:
+               return RPZ_INVALID_ACTION;
+       }
+}
+
 /**
  * Get RPZ trigger for dname
  * @param dname: dname containing RPZ trigger
@@ -254,17 +285,7 @@ rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
        int dnamelabs = dname_count_labels(dname);
        char* rrstr;
 
-       if(a == RPZ_NXDOMAIN_ACTION)
-               tp = local_zone_always_nxdomain;
-       else if(a == RPZ_NODATA_ACTION)
-               tp = local_zone_always_nodata;
-       else if(a == RPZ_DROP_ACTION)
-               tp = local_zone_deny;
-       else if(a == RPZ_PASSTHRU_ACTION)
-               tp = local_zone_always_transparent;
-       else if(a == RPZ_LOCAL_DATA_ACTION)
-               tp = local_zone_redirect;
-       else {
+       if(a == RPZ_TCP_ONLY_ACTION || a == RPZ_INVALID_ACTION) {
                verbose(VERB_ALGO, "RPZ: skipping unusupported action: %s",
                        rpz_action_to_string(a));
                return 0;
@@ -283,6 +304,7 @@ rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
                return 0;
        }
        if(!z) {
+               tp = rpz_action_to_localzone_type(a);
                z = local_zones_add_zone(r->local_zones, dname, dnamelen,
                        dnamelabs, rrclass, tp);
        }
@@ -460,7 +482,7 @@ rpz_data_delete_rr(struct local_zone* z, uint8_t* policydname,
 void
 rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
        size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint8_t* rdatawl,
-       size_t rdatalen, uint8_t* rr, size_t rr_len)
+       size_t rdatalen)
 {
        struct local_zone* z;
        size_t policydnamelen;
@@ -470,10 +492,6 @@ rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
        enum rpz_action a;
        int delete_zone = 1;
 
-       /* TODO, use for logging */
-       (void)rr;
-       (void)rr_len;
-       
        a = rpz_rr_to_action(rr_type, rdatawl, rdatalen);
        if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen,
                policydname))) {
@@ -481,7 +499,7 @@ rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
                return;
        }
        t = rpz_dname_to_trigger(policydname);
-       if(a != RPZ_INVALID_ACTION && t != RPZ_QNAME_TRIGGER) {
+       if(a != RPZ_INVALID_ACTION && t == RPZ_QNAME_TRIGGER) {
                z = rpz_find_zone(r, policydname, policydnamelen, rr_class,
                        1 /* only exact */, 1 /* wr lock */);
                if(!z) {
@@ -493,6 +511,10 @@ rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
                if(a == RPZ_LOCAL_DATA_ACTION)
                        delete_zone = rpz_data_delete_rr(z, policydname,
                                policydnamelen, rr_type, rdatawl, rdatalen);
+               else if(a != localzone_type_to_rpz_action(z->type)) {
+                       free(policydname);
+                       return;
+               }
                lock_rw_unlock(&z->lock); 
                if(delete_zone) {
                        local_zones_del_zone(r->local_zones, z);
index a6318932978873b05f19ed194fc3af6dc884bc06..2d880d69dae8e376f911acf34ea0537a32d0f69f 100644 (file)
@@ -117,12 +117,10 @@ void rpz_insert_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
  * @param rr_class: RR class of the RR
  * @param rdatawl: rdata of the RR, prepended with the rdata size
  * @param rdatalen: length if the RR, including the prepended rdata size
- * @param rr: the complete RR, for logging purposes
- * @param rr_len: the length of the complete RR
  */
 void rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
        size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint8_t* rdatawl,
-       size_t rdatalen, uint8_t* rr, size_t rr_len);
+       size_t rdatalen);
 
 /**
  * Walk over the RPZ zones to find and apply a QNAME trigger policy.