diff options
Diffstat (limited to 'services/rpz.c')
-rw-r--r-- | services/rpz.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/services/rpz.c b/services/rpz.c index 643b20c91d20..105f238d0a6d 100644 --- a/services/rpz.c +++ b/services/rpz.c @@ -586,7 +586,7 @@ rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, } int -rpz_insert_rr(struct rpz* r, size_t aznamelen, uint8_t* dname, +rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname, size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl, uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len) { @@ -596,9 +596,17 @@ rpz_insert_rr(struct rpz* r, size_t aznamelen, uint8_t* dname, enum rpz_action a; uint8_t* policydname; + if(!dname_subdomain_c(dname, azname)) { + log_err("RPZ: name of record to insert into RPZ is not a " + "subdomain of the configured name of the RPZ zone"); + return 0; + } + log_assert(dnamelen >= aznamelen); - if(!(policydname = calloc(1, (dnamelen-aznamelen)+1))) + if(!(policydname = calloc(1, (dnamelen-aznamelen)+1))) { + log_err("malloc error while inserting RPZ RR"); return 0; + } a = rpz_rr_to_action(rr_type, rdatawl, rdatalen); if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen, @@ -826,6 +834,8 @@ rpz_remove_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, delete_zone = rpz_data_delete_rr(z, dname, dnamelen, rr_type, rdatawl, rdatalen); else if(a != localzone_type_to_rpz_action(z->type)) { + lock_rw_unlock(&z->lock); + lock_rw_unlock(&r->local_zones->lock); return; } lock_rw_unlock(&z->lock); @@ -931,13 +941,16 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env, struct regional* temp, struct comm_reply* repinfo, uint8_t* taglist, size_t taglen, struct ub_server_stats* stats) { - struct rpz* r; + struct rpz* r = NULL; + struct auth_zone* a; int ret; enum localzone_type lzt; struct local_zone* z = NULL; struct local_data* ld = NULL; lock_rw_rdlock(&az->rpz_lock); - for(r = az->rpz_first; r; r = r->next) { + for(a = az->rpz_first; a; a = a->rpz_az_next) { + lock_rw_rdlock(&a->lock); + r = a->rpz; if(!r->taglist || taglist_intersect(r->taglist, r->taglistlen, taglist, taglen)) { z = rpz_find_zone(r, qinfo->qname, qinfo->qname_len, @@ -955,13 +968,14 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env, } if(z) break; - } + } + lock_rw_unlock(&a->lock); /* not found in this auth_zone */ } lock_rw_unlock(&az->rpz_lock); if(!z) - return 0; + return 0; /* not holding auth_zone.lock anymore */ - + log_assert(r); if(r->action_override == RPZ_NO_OVERRIDE_ACTION) lzt = z->type; else @@ -972,6 +986,7 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env, regional_alloc_zero(temp, sizeof(struct local_rrset)); if(!qinfo->local_alias) { lock_rw_unlock(&z->lock); + lock_rw_unlock(&a->lock); return 0; /* out of memory */ } qinfo->local_alias->rrset = @@ -979,6 +994,7 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env, sizeof(*r->cname_override)); if(!qinfo->local_alias->rrset) { lock_rw_unlock(&z->lock); + lock_rw_unlock(&a->lock); return 0; /* out of memory */ } qinfo->local_alias->rrset->rk.dname = qinfo->qname; @@ -988,6 +1004,7 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env, qinfo, repinfo, r->log_name); stats->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++; lock_rw_unlock(&z->lock); + lock_rw_unlock(&a->lock); return 0; } @@ -1000,6 +1017,7 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env, repinfo, r->log_name); stats->rpz_action[localzone_type_to_rpz_action(lzt)]++; lock_rw_unlock(&z->lock); + lock_rw_unlock(&a->lock); return !qinfo->local_alias; } @@ -1010,6 +1028,7 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env, qinfo, repinfo, r->log_name); stats->rpz_action[localzone_type_to_rpz_action(lzt)]++; lock_rw_unlock(&z->lock); + lock_rw_unlock(&a->lock); return ret; } |