1 /* 2 * services/rpz.c - rpz service 3 * 4 * Copyright (c) 2019, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * Neither the name of the NLNET LABS nor the names of its contributors may 20 * be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 /** 37 * \file 38 * 39 * This file contains functions to enable RPZ service. 40 */ 41 42 #include "config.h" 43 #include "services/rpz.h" 44 #include "util/config_file.h" 45 #include "sldns/wire2str.h" 46 #include "sldns/str2wire.h" 47 #include "util/data/dname.h" 48 #include "util/net_help.h" 49 #include "util/log.h" 50 #include "util/data/dname.h" 51 #include "util/locks.h" 52 #include "util/regional.h" 53 #include "util/data/msgencode.h" 54 #include "services/cache/dns.h" 55 #include "iterator/iterator.h" 56 #include "iterator/iter_delegpt.h" 57 #include "daemon/worker.h" 58 59 typedef struct resp_addr rpz_aclnode_type; 60 61 struct matched_delegation_point { 62 uint8_t* dname; 63 size_t dname_len; 64 }; 65 66 /** string for RPZ action enum */ 67 const char* 68 rpz_action_to_string(enum rpz_action a) 69 { 70 switch(a) { 71 case RPZ_NXDOMAIN_ACTION: return "rpz-nxdomain"; 72 case RPZ_NODATA_ACTION: return "rpz-nodata"; 73 case RPZ_PASSTHRU_ACTION: return "rpz-passthru"; 74 case RPZ_DROP_ACTION: return "rpz-drop"; 75 case RPZ_TCP_ONLY_ACTION: return "rpz-tcp-only"; 76 case RPZ_INVALID_ACTION: return "rpz-invalid"; 77 case RPZ_LOCAL_DATA_ACTION: return "rpz-local-data"; 78 case RPZ_DISABLED_ACTION: return "rpz-disabled"; 79 case RPZ_CNAME_OVERRIDE_ACTION: return "rpz-cname-override"; 80 case RPZ_NO_OVERRIDE_ACTION: return "rpz-no-override"; 81 default: return "rpz-unknown-action"; 82 } 83 } 84 85 /** RPZ action enum for config string */ 86 static enum rpz_action 87 rpz_config_to_action(char* a) 88 { 89 if(strcmp(a, "nxdomain") == 0) return RPZ_NXDOMAIN_ACTION; 90 else if(strcmp(a, "nodata") == 0) return RPZ_NODATA_ACTION; 91 else if(strcmp(a, "passthru") == 0) return RPZ_PASSTHRU_ACTION; 92 else if(strcmp(a, "drop") == 0) return RPZ_DROP_ACTION; 93 else if(strcmp(a, "tcp_only") == 0) return RPZ_TCP_ONLY_ACTION; 94 else if(strcmp(a, "cname") == 0) return RPZ_CNAME_OVERRIDE_ACTION; 95 else if(strcmp(a, "disabled") == 0) return RPZ_DISABLED_ACTION; 96 else return RPZ_INVALID_ACTION; 97 } 98 99 /** string for RPZ trigger enum */ 100 static const char* 101 rpz_trigger_to_string(enum rpz_trigger r) 102 { 103 switch(r) { 104 case RPZ_QNAME_TRIGGER: return "rpz-qname"; 105 case RPZ_CLIENT_IP_TRIGGER: return "rpz-client-ip"; 106 case RPZ_RESPONSE_IP_TRIGGER: return "rpz-response-ip"; 107 case RPZ_NSDNAME_TRIGGER: return "rpz-nsdname"; 108 case RPZ_NSIP_TRIGGER: return "rpz-nsip"; 109 case RPZ_INVALID_TRIGGER: return "rpz-invalid"; 110 default: return "rpz-unknown-trigger"; 111 } 112 } 113 114 /** 115 * Get the label that is just before the root label. 116 * @param dname: dname to work on 117 * @param maxdnamelen: maximum length of the dname 118 * @return: pointer to TLD label, NULL if not found or invalid dname 119 */ 120 static uint8_t* 121 get_tld_label(uint8_t* dname, size_t maxdnamelen) 122 { 123 uint8_t* prevlab = dname; 124 size_t dnamelen = 0; 125 126 /* one byte needed for label length */ 127 if(dnamelen+1 > maxdnamelen) 128 return NULL; 129 130 /* only root label */ 131 if(*dname == 0) 132 return NULL; 133 134 while(*dname) { 135 dnamelen += ((size_t)*dname)+1; 136 if(dnamelen+1 > maxdnamelen) 137 return NULL; 138 dname = dname+((size_t)*dname)+1; 139 if(*dname != 0) 140 prevlab = dname; 141 } 142 return prevlab; 143 } 144 145 /** 146 * The RR types that are to be ignored. 147 * DNSSEC RRs at the apex, and SOA and NS are ignored. 148 */ 149 static int 150 rpz_type_ignored(uint16_t rr_type) 151 { 152 switch(rr_type) { 153 case LDNS_RR_TYPE_SOA: 154 case LDNS_RR_TYPE_NS: 155 case LDNS_RR_TYPE_DNAME: 156 /* all DNSSEC-related RRs must be ignored */ 157 case LDNS_RR_TYPE_DNSKEY: 158 case LDNS_RR_TYPE_DS: 159 case LDNS_RR_TYPE_RRSIG: 160 case LDNS_RR_TYPE_NSEC: 161 case LDNS_RR_TYPE_NSEC3: 162 case LDNS_RR_TYPE_NSEC3PARAM: 163 return 1; 164 default: 165 break; 166 } 167 return 0; 168 } 169 170 /** 171 * Classify RPZ action for RR type/rdata 172 * @param rr_type: the RR type 173 * @param rdatawl: RDATA with 2 bytes length 174 * @param rdatalen: the length of rdatawl (including its 2 bytes length) 175 * @return: the RPZ action 176 */ 177 static enum rpz_action 178 rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen) 179 { 180 char* endptr; 181 uint8_t* rdata; 182 int rdatalabs; 183 uint8_t* tldlab = NULL; 184 185 switch(rr_type) { 186 case LDNS_RR_TYPE_SOA: 187 case LDNS_RR_TYPE_NS: 188 case LDNS_RR_TYPE_DNAME: 189 /* all DNSSEC-related RRs must be ignored */ 190 case LDNS_RR_TYPE_DNSKEY: 191 case LDNS_RR_TYPE_DS: 192 case LDNS_RR_TYPE_RRSIG: 193 case LDNS_RR_TYPE_NSEC: 194 case LDNS_RR_TYPE_NSEC3: 195 case LDNS_RR_TYPE_NSEC3PARAM: 196 return RPZ_INVALID_ACTION; 197 case LDNS_RR_TYPE_CNAME: 198 break; 199 default: 200 return RPZ_LOCAL_DATA_ACTION; 201 } 202 203 /* use CNAME target to determine RPZ action */ 204 log_assert(rr_type == LDNS_RR_TYPE_CNAME); 205 if(rdatalen < 3) 206 return RPZ_INVALID_ACTION; 207 208 rdata = rdatawl + 2; /* 2 bytes of rdata length */ 209 if(dname_valid(rdata, rdatalen-2) != rdatalen-2) 210 return RPZ_INVALID_ACTION; 211 212 rdatalabs = dname_count_labels(rdata); 213 if(rdatalabs == 1) 214 return RPZ_NXDOMAIN_ACTION; 215 else if(rdatalabs == 2) { 216 if(dname_subdomain_c(rdata, (uint8_t*)&"\001*\000")) 217 return RPZ_NODATA_ACTION; 218 else if(dname_subdomain_c(rdata, 219 (uint8_t*)&"\014rpz-passthru\000")) 220 return RPZ_PASSTHRU_ACTION; 221 else if(dname_subdomain_c(rdata, (uint8_t*)&"\010rpz-drop\000")) 222 return RPZ_DROP_ACTION; 223 else if(dname_subdomain_c(rdata, 224 (uint8_t*)&"\014rpz-tcp-only\000")) 225 return RPZ_TCP_ONLY_ACTION; 226 } 227 228 /* all other TLDs starting with "rpz-" are invalid */ 229 tldlab = get_tld_label(rdata, rdatalen-2); 230 if(tldlab && dname_lab_startswith(tldlab, "rpz-", &endptr)) 231 return RPZ_INVALID_ACTION; 232 233 /* no special label found */ 234 return RPZ_LOCAL_DATA_ACTION; 235 } 236 237 static enum localzone_type 238 rpz_action_to_localzone_type(enum rpz_action a) 239 { 240 switch(a) { 241 case RPZ_NXDOMAIN_ACTION: return local_zone_always_nxdomain; 242 case RPZ_NODATA_ACTION: return local_zone_always_nodata; 243 case RPZ_DROP_ACTION: return local_zone_always_deny; 244 case RPZ_PASSTHRU_ACTION: return local_zone_always_transparent; 245 case RPZ_LOCAL_DATA_ACTION: /* fallthrough */ 246 case RPZ_CNAME_OVERRIDE_ACTION: return local_zone_redirect; 247 case RPZ_TCP_ONLY_ACTION: return local_zone_truncate; 248 case RPZ_INVALID_ACTION: /* fallthrough */ 249 default: return local_zone_invalid; 250 } 251 } 252 253 enum respip_action 254 rpz_action_to_respip_action(enum rpz_action a) 255 { 256 switch(a) { 257 case RPZ_NXDOMAIN_ACTION: return respip_always_nxdomain; 258 case RPZ_NODATA_ACTION: return respip_always_nodata; 259 case RPZ_DROP_ACTION: return respip_always_deny; 260 case RPZ_PASSTHRU_ACTION: return respip_always_transparent; 261 case RPZ_LOCAL_DATA_ACTION: /* fallthrough */ 262 case RPZ_CNAME_OVERRIDE_ACTION: return respip_redirect; 263 case RPZ_TCP_ONLY_ACTION: return respip_truncate; 264 case RPZ_INVALID_ACTION: /* fallthrough */ 265 default: return respip_invalid; 266 } 267 } 268 269 static enum rpz_action 270 localzone_type_to_rpz_action(enum localzone_type lzt) 271 { 272 switch(lzt) { 273 case local_zone_always_nxdomain: return RPZ_NXDOMAIN_ACTION; 274 case local_zone_always_nodata: return RPZ_NODATA_ACTION; 275 case local_zone_always_deny: return RPZ_DROP_ACTION; 276 case local_zone_always_transparent: return RPZ_PASSTHRU_ACTION; 277 case local_zone_redirect: return RPZ_LOCAL_DATA_ACTION; 278 case local_zone_truncate: return RPZ_TCP_ONLY_ACTION; 279 case local_zone_invalid: /* fallthrough */ 280 default: return RPZ_INVALID_ACTION; 281 } 282 } 283 284 enum rpz_action 285 respip_action_to_rpz_action(enum respip_action a) 286 { 287 switch(a) { 288 case respip_always_nxdomain: return RPZ_NXDOMAIN_ACTION; 289 case respip_always_nodata: return RPZ_NODATA_ACTION; 290 case respip_always_deny: return RPZ_DROP_ACTION; 291 case respip_always_transparent: return RPZ_PASSTHRU_ACTION; 292 case respip_redirect: return RPZ_LOCAL_DATA_ACTION; 293 case respip_truncate: return RPZ_TCP_ONLY_ACTION; 294 case respip_invalid: /* fallthrough */ 295 default: return RPZ_INVALID_ACTION; 296 } 297 } 298 299 /** 300 * Get RPZ trigger for dname 301 * @param dname: dname containing RPZ trigger 302 * @param dname_len: length of the dname 303 * @return: RPZ trigger enum 304 */ 305 static enum rpz_trigger 306 rpz_dname_to_trigger(uint8_t* dname, size_t dname_len) 307 { 308 uint8_t* tldlab; 309 char* endptr; 310 311 if(dname_valid(dname, dname_len) != dname_len) 312 return RPZ_INVALID_TRIGGER; 313 314 tldlab = get_tld_label(dname, dname_len); 315 if(!tldlab || !dname_lab_startswith(tldlab, "rpz-", &endptr)) 316 return RPZ_QNAME_TRIGGER; 317 318 if(dname_subdomain_c(tldlab, 319 (uint8_t*)&"\015rpz-client-ip\000")) 320 return RPZ_CLIENT_IP_TRIGGER; 321 else if(dname_subdomain_c(tldlab, (uint8_t*)&"\006rpz-ip\000")) 322 return RPZ_RESPONSE_IP_TRIGGER; 323 else if(dname_subdomain_c(tldlab, (uint8_t*)&"\013rpz-nsdname\000")) 324 return RPZ_NSDNAME_TRIGGER; 325 else if(dname_subdomain_c(tldlab, (uint8_t*)&"\010rpz-nsip\000")) 326 return RPZ_NSIP_TRIGGER; 327 328 return RPZ_QNAME_TRIGGER; 329 } 330 331 static inline struct clientip_synthesized_rrset* 332 rpz_clientip_synthesized_set_create(void) 333 { 334 struct clientip_synthesized_rrset* set = calloc(1, sizeof(*set)); 335 if(set == NULL) { 336 return NULL; 337 } 338 set->region = regional_create(); 339 if(set->region == NULL) { 340 free(set); 341 return NULL; 342 } 343 addr_tree_init(&set->entries); 344 lock_rw_init(&set->lock); 345 return set; 346 } 347 348 static void 349 rpz_clientip_synthesized_rr_delete(rbnode_type* n, void* ATTR_UNUSED(arg)) 350 { 351 struct clientip_synthesized_rr* r = (struct clientip_synthesized_rr*)n->key; 352 lock_rw_destroy(&r->lock); 353 #ifdef THREADS_DISABLED 354 (void)r; 355 #endif 356 } 357 358 static inline void 359 rpz_clientip_synthesized_set_delete(struct clientip_synthesized_rrset* set) 360 { 361 if(set == NULL) { 362 return; 363 } 364 lock_rw_destroy(&set->lock); 365 traverse_postorder(&set->entries, rpz_clientip_synthesized_rr_delete, NULL); 366 regional_destroy(set->region); 367 free(set); 368 } 369 370 void 371 rpz_delete(struct rpz* r) 372 { 373 if(!r) 374 return; 375 local_zones_delete(r->local_zones); 376 local_zones_delete(r->nsdname_zones); 377 respip_set_delete(r->respip_set); 378 rpz_clientip_synthesized_set_delete(r->client_set); 379 rpz_clientip_synthesized_set_delete(r->ns_set); 380 regional_destroy(r->region); 381 free(r->taglist); 382 free(r->log_name); 383 free(r); 384 } 385 386 int 387 rpz_clear(struct rpz* r) 388 { 389 /* must hold write lock on auth_zone */ 390 local_zones_delete(r->local_zones); 391 r->local_zones = NULL; 392 local_zones_delete(r->nsdname_zones); 393 r->nsdname_zones = NULL; 394 respip_set_delete(r->respip_set); 395 r->respip_set = NULL; 396 rpz_clientip_synthesized_set_delete(r->client_set); 397 r->client_set = NULL; 398 rpz_clientip_synthesized_set_delete(r->ns_set); 399 r->ns_set = NULL; 400 if(!(r->local_zones = local_zones_create())){ 401 return 0; 402 } 403 r->nsdname_zones = local_zones_create(); 404 if(r->nsdname_zones == NULL) { 405 return 0; 406 } 407 if(!(r->respip_set = respip_set_create())) { 408 return 0; 409 } 410 if(!(r->client_set = rpz_clientip_synthesized_set_create())) { 411 return 0; 412 } 413 if(!(r->ns_set = rpz_clientip_synthesized_set_create())) { 414 return 0; 415 } 416 return 1; 417 } 418 419 void 420 rpz_finish_config(struct rpz* r) 421 { 422 lock_rw_wrlock(&r->respip_set->lock); 423 addr_tree_init_parents(&r->respip_set->ip_tree); 424 lock_rw_unlock(&r->respip_set->lock); 425 426 lock_rw_wrlock(&r->client_set->lock); 427 addr_tree_init_parents(&r->client_set->entries); 428 lock_rw_unlock(&r->client_set->lock); 429 430 lock_rw_wrlock(&r->ns_set->lock); 431 addr_tree_init_parents(&r->ns_set->entries); 432 lock_rw_unlock(&r->ns_set->lock); 433 } 434 435 /** new rrset containing CNAME override, does not yet contain a dname */ 436 static struct ub_packed_rrset_key* 437 new_cname_override(struct regional* region, uint8_t* ct, size_t ctlen) 438 { 439 struct ub_packed_rrset_key* rrset; 440 struct packed_rrset_data* pd; 441 uint16_t rdlength = htons(ctlen); 442 rrset = (struct ub_packed_rrset_key*)regional_alloc_zero(region, 443 sizeof(*rrset)); 444 if(!rrset) { 445 log_err("out of memory"); 446 return NULL; 447 } 448 rrset->entry.key = rrset; 449 pd = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*pd)); 450 if(!pd) { 451 log_err("out of memory"); 452 return NULL; 453 } 454 pd->trust = rrset_trust_prim_noglue; 455 pd->security = sec_status_insecure; 456 457 pd->count = 1; 458 pd->rr_len = regional_alloc_zero(region, sizeof(*pd->rr_len)); 459 pd->rr_ttl = regional_alloc_zero(region, sizeof(*pd->rr_ttl)); 460 pd->rr_data = regional_alloc_zero(region, sizeof(*pd->rr_data)); 461 if(!pd->rr_len || !pd->rr_ttl || !pd->rr_data) { 462 log_err("out of memory"); 463 return NULL; 464 } 465 pd->rr_len[0] = ctlen+2; 466 pd->rr_ttl[0] = 3600; 467 pd->rr_data[0] = regional_alloc_zero(region, 2 /* rdlength */ + ctlen); 468 if(!pd->rr_data[0]) { 469 log_err("out of memory"); 470 return NULL; 471 } 472 memmove(pd->rr_data[0], &rdlength, 2); 473 memmove(pd->rr_data[0]+2, ct, ctlen); 474 475 rrset->entry.data = pd; 476 rrset->rk.type = htons(LDNS_RR_TYPE_CNAME); 477 rrset->rk.rrset_class = htons(LDNS_RR_CLASS_IN); 478 return rrset; 479 } 480 481 struct rpz* 482 rpz_create(struct config_auth* p) 483 { 484 struct rpz* r = calloc(1, sizeof(*r)); 485 if(!r) 486 goto err; 487 488 r->region = regional_create_custom(sizeof(struct regional)); 489 if(!r->region) { 490 goto err; 491 } 492 493 if(!(r->local_zones = local_zones_create())){ 494 goto err; 495 } 496 497 r->nsdname_zones = local_zones_create(); 498 if(r->local_zones == NULL){ 499 goto err; 500 } 501 502 if(!(r->respip_set = respip_set_create())) { 503 goto err; 504 } 505 506 r->client_set = rpz_clientip_synthesized_set_create(); 507 if(r->client_set == NULL) { 508 goto err; 509 } 510 511 r->ns_set = rpz_clientip_synthesized_set_create(); 512 if(r->ns_set == NULL) { 513 goto err; 514 } 515 516 r->taglistlen = p->rpz_taglistlen; 517 r->taglist = memdup(p->rpz_taglist, r->taglistlen); 518 if(p->rpz_action_override) { 519 r->action_override = rpz_config_to_action(p->rpz_action_override); 520 } 521 else 522 r->action_override = RPZ_NO_OVERRIDE_ACTION; 523 524 if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) { 525 uint8_t nm[LDNS_MAX_DOMAINLEN+1]; 526 size_t nmlen = sizeof(nm); 527 528 if(!p->rpz_cname) { 529 log_err("RPZ override with cname action found, but no " 530 "rpz-cname-override configured"); 531 goto err; 532 } 533 534 if(sldns_str2wire_dname_buf(p->rpz_cname, nm, &nmlen) != 0) { 535 log_err("cannot parse RPZ cname override: %s", 536 p->rpz_cname); 537 goto err; 538 } 539 r->cname_override = new_cname_override(r->region, nm, nmlen); 540 if(!r->cname_override) { 541 goto err; 542 } 543 } 544 r->log = p->rpz_log; 545 r->signal_nxdomain_ra = p->rpz_signal_nxdomain_ra; 546 if(p->rpz_log_name) { 547 if(!(r->log_name = strdup(p->rpz_log_name))) { 548 log_err("malloc failure on RPZ log_name strdup"); 549 goto err; 550 } 551 } 552 return r; 553 err: 554 if(r) { 555 if(r->local_zones) 556 local_zones_delete(r->local_zones); 557 if(r->nsdname_zones) 558 local_zones_delete(r->nsdname_zones); 559 if(r->respip_set) 560 respip_set_delete(r->respip_set); 561 if(r->client_set != NULL) 562 rpz_clientip_synthesized_set_delete(r->client_set); 563 if(r->ns_set != NULL) 564 rpz_clientip_synthesized_set_delete(r->ns_set); 565 if(r->taglist) 566 free(r->taglist); 567 if(r->region) 568 regional_destroy(r->region); 569 free(r); 570 } 571 return NULL; 572 } 573 574 /** 575 * Remove RPZ zone name from dname 576 * Copy dname to newdname, without the originlen number of trailing bytes 577 */ 578 static size_t 579 strip_dname_origin(uint8_t* dname, size_t dnamelen, size_t originlen, 580 uint8_t* newdname, size_t maxnewdnamelen) 581 { 582 size_t newdnamelen; 583 if(dnamelen < originlen) 584 return 0; 585 newdnamelen = dnamelen - originlen; 586 if(newdnamelen+1 > maxnewdnamelen) 587 return 0; 588 memmove(newdname, dname, newdnamelen); 589 newdname[newdnamelen] = 0; 590 return newdnamelen + 1; /* + 1 for root label */ 591 } 592 593 static void 594 rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname, 595 size_t dnamelen, enum rpz_action a, uint16_t rrtype, uint16_t rrclass, 596 uint32_t ttl, uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 597 { 598 struct local_zone* z; 599 enum localzone_type tp = local_zone_always_transparent; 600 int dnamelabs = dname_count_labels(dname); 601 int newzone = 0; 602 603 if(a == RPZ_INVALID_ACTION) { 604 char str[255+1]; 605 if(rrtype == LDNS_RR_TYPE_SOA || rrtype == LDNS_RR_TYPE_NS || 606 rrtype == LDNS_RR_TYPE_DNAME || 607 rrtype == LDNS_RR_TYPE_DNSKEY || 608 rrtype == LDNS_RR_TYPE_RRSIG || 609 rrtype == LDNS_RR_TYPE_NSEC || 610 rrtype == LDNS_RR_TYPE_NSEC3PARAM || 611 rrtype == LDNS_RR_TYPE_NSEC3 || 612 rrtype == LDNS_RR_TYPE_DS) { 613 free(dname); 614 return; /* no need to log these types as unsupported */ 615 } 616 dname_str(dname, str); 617 verbose(VERB_ALGO, "RPZ: qname trigger, %s skipping unsupported action: %s", 618 str, rpz_action_to_string(a)); 619 free(dname); 620 return; 621 } 622 623 lock_rw_wrlock(&lz->lock); 624 /* exact match */ 625 z = local_zones_find(lz, dname, dnamelen, dnamelabs, LDNS_RR_CLASS_IN); 626 if(z != NULL && a != RPZ_LOCAL_DATA_ACTION) { 627 char* rrstr = sldns_wire2str_rr(rr, rr_len); 628 if(rrstr == NULL) { 629 log_err("malloc error while inserting rpz nsdname trigger"); 630 free(dname); 631 lock_rw_unlock(&lz->lock); 632 return; 633 } 634 if(rrstr[0]) 635 rrstr[strlen(rrstr)-1]=0; /* remove newline */ 636 verbose(VERB_ALGO, "rpz: skipping duplicate record: '%s'", rrstr); 637 free(rrstr); 638 free(dname); 639 lock_rw_unlock(&lz->lock); 640 return; 641 } 642 if(z == NULL) { 643 tp = rpz_action_to_localzone_type(a); 644 z = local_zones_add_zone(lz, dname, dnamelen, 645 dnamelabs, rrclass, tp); 646 if(z == NULL) { 647 log_warn("rpz: create failed"); 648 lock_rw_unlock(&lz->lock); 649 /* dname will be free'd in failed local_zone_create() */ 650 return; 651 } 652 newzone = 1; 653 } 654 if(a == RPZ_LOCAL_DATA_ACTION) { 655 char* rrstr = sldns_wire2str_rr(rr, rr_len); 656 if(rrstr == NULL) { 657 log_err("malloc error while inserting rpz nsdname trigger"); 658 free(dname); 659 lock_rw_unlock(&lz->lock); 660 return; 661 } 662 lock_rw_wrlock(&z->lock); 663 local_zone_enter_rr(z, dname, dnamelen, dnamelabs, rrtype, 664 rrclass, ttl, rdata, rdata_len, rrstr); 665 lock_rw_unlock(&z->lock); 666 free(rrstr); 667 } 668 if(!newzone) { 669 free(dname); 670 } 671 lock_rw_unlock(&lz->lock); 672 } 673 674 static void 675 rpz_log_dname(char const* msg, uint8_t* dname, size_t dname_len) 676 { 677 char buf[LDNS_MAX_DOMAINLEN+1]; 678 (void)dname_len; 679 dname_str(dname, buf); 680 verbose(VERB_ALGO, "rpz: %s: <%s>", msg, buf); 681 } 682 683 static void 684 rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 685 enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl, 686 uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 687 { 688 if(a == RPZ_INVALID_ACTION) { 689 verbose(VERB_ALGO, "rpz: skipping invalid action"); 690 free(dname); 691 return; 692 } 693 694 rpz_insert_local_zones_trigger(r->local_zones, dname, dnamelen, a, rrtype, 695 rrclass, ttl, rdata, rdata_len, rr, rr_len); 696 } 697 698 static int 699 rpz_strip_nsdname_suffix(uint8_t* dname, size_t maxdnamelen, 700 uint8_t** stripdname, size_t* stripdnamelen) 701 { 702 uint8_t* tldstart = get_tld_label(dname, maxdnamelen); 703 uint8_t swap; 704 if(tldstart == NULL) { 705 if(dname == NULL) { 706 *stripdname = NULL; 707 *stripdnamelen = 0; 708 return 0; 709 } 710 *stripdname = memdup(dname, maxdnamelen); 711 if(!*stripdname) { 712 *stripdnamelen = 0; 713 log_err("malloc failure for rpz strip suffix"); 714 return 0; 715 } 716 *stripdnamelen = maxdnamelen; 717 return 1; 718 } 719 /* shorten the domain name briefly, 720 * then we allocate a new name with the correct length */ 721 swap = *tldstart; 722 *tldstart = 0; 723 (void)dname_count_size_labels(dname, stripdnamelen); 724 *stripdname = memdup(dname, *stripdnamelen); 725 *tldstart = swap; 726 if(!*stripdname) { 727 *stripdnamelen = 0; 728 log_err("malloc failure for rpz strip suffix"); 729 return 0; 730 } 731 return 1; 732 } 733 734 static void 735 rpz_insert_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 736 enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl, 737 uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 738 { 739 uint8_t* dname_stripped = NULL; 740 size_t dnamelen_stripped = 0; 741 742 rpz_strip_nsdname_suffix(dname, dnamelen, &dname_stripped, 743 &dnamelen_stripped); 744 if(a == RPZ_INVALID_ACTION) { 745 verbose(VERB_ALGO, "rpz: skipping invalid action"); 746 free(dname_stripped); 747 return; 748 } 749 750 /* dname_stripped is consumed or freed by the insert routine */ 751 rpz_insert_local_zones_trigger(r->nsdname_zones, dname_stripped, 752 dnamelen_stripped, a, rrtype, rrclass, ttl, rdata, rdata_len, 753 rr, rr_len); 754 } 755 756 static int 757 rpz_insert_ipaddr_based_trigger(struct respip_set* set, struct sockaddr_storage* addr, 758 socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype, 759 uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len, 760 uint8_t* rr, size_t rr_len) 761 { 762 struct resp_addr* node; 763 char* rrstr; 764 enum respip_action respa = rpz_action_to_respip_action(a); 765 766 lock_rw_wrlock(&set->lock); 767 rrstr = sldns_wire2str_rr(rr, rr_len); 768 if(rrstr == NULL) { 769 log_err("malloc error while inserting rpz ipaddr based trigger"); 770 lock_rw_unlock(&set->lock); 771 return 0; 772 } 773 774 node = respip_sockaddr_find_or_create(set, addr, addrlen, net, 1, rrstr); 775 if(node == NULL) { 776 lock_rw_unlock(&set->lock); 777 free(rrstr); 778 return 0; 779 } 780 781 lock_rw_wrlock(&node->lock); 782 lock_rw_unlock(&set->lock); 783 784 node->action = respa; 785 786 if(a == RPZ_LOCAL_DATA_ACTION) { 787 respip_enter_rr(set->region, node, rrtype, 788 rrclass, ttl, rdata, rdata_len, rrstr, ""); 789 } 790 791 lock_rw_unlock(&node->lock); 792 free(rrstr); 793 return 1; 794 } 795 796 static inline struct clientip_synthesized_rr* 797 rpz_clientip_ensure_entry(struct clientip_synthesized_rrset* set, 798 struct sockaddr_storage* addr, socklen_t addrlen, int net) 799 { 800 int insert_ok; 801 struct clientip_synthesized_rr* node = 802 (struct clientip_synthesized_rr*)addr_tree_find(&set->entries, 803 addr, addrlen, net); 804 805 if(node != NULL) { return node; } 806 807 /* node does not yet exist => allocate one */ 808 node = regional_alloc_zero(set->region, sizeof(*node)); 809 if(node == NULL) { 810 log_err("out of memory"); 811 return NULL; 812 } 813 814 lock_rw_init(&node->lock); 815 node->action = RPZ_INVALID_ACTION; 816 insert_ok = addr_tree_insert(&set->entries, &node->node, 817 addr, addrlen, net); 818 if (!insert_ok) { 819 log_warn("rpz: unexpected: unable to insert clientip address node"); 820 /* we can not free the just allocated node. 821 * theoretically a memleak */ 822 return NULL; 823 } 824 825 return node; 826 } 827 828 static void 829 rpz_report_rrset_error(const char* msg, uint8_t* rr, size_t rr_len) { 830 char* rrstr = sldns_wire2str_rr(rr, rr_len); 831 if(rrstr == NULL) { 832 log_err("malloc error while inserting rpz clientip based record"); 833 return; 834 } 835 log_err("rpz: unexpected: unable to insert %s: %s", msg, rrstr); 836 free(rrstr); 837 } 838 839 /* from localzone.c; difference is we don't have a dname */ 840 static struct local_rrset* 841 rpz_clientip_new_rrset(struct regional* region, 842 struct clientip_synthesized_rr* raddr, uint16_t rrtype, uint16_t rrclass) 843 { 844 struct packed_rrset_data* pd; 845 struct local_rrset* rrset = (struct local_rrset*) 846 regional_alloc_zero(region, sizeof(*rrset)); 847 if(rrset == NULL) { 848 log_err("out of memory"); 849 return NULL; 850 } 851 rrset->next = raddr->data; 852 raddr->data = rrset; 853 rrset->rrset = (struct ub_packed_rrset_key*) 854 regional_alloc_zero(region, sizeof(*rrset->rrset)); 855 if(rrset->rrset == NULL) { 856 log_err("out of memory"); 857 return NULL; 858 } 859 rrset->rrset->entry.key = rrset->rrset; 860 pd = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*pd)); 861 if(pd == NULL) { 862 log_err("out of memory"); 863 return NULL; 864 } 865 pd->trust = rrset_trust_prim_noglue; 866 pd->security = sec_status_insecure; 867 rrset->rrset->entry.data = pd; 868 rrset->rrset->rk.type = htons(rrtype); 869 rrset->rrset->rk.rrset_class = htons(rrclass); 870 rrset->rrset->rk.dname = regional_alloc_zero(region, 1); 871 if(rrset->rrset->rk.dname == NULL) { 872 log_err("out of memory"); 873 return NULL; 874 } 875 rrset->rrset->rk.dname_len = 1; 876 return rrset; 877 } 878 879 static int 880 rpz_clientip_enter_rr(struct regional* region, struct clientip_synthesized_rr* raddr, 881 uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata, 882 size_t rdata_len) 883 { 884 struct local_rrset* rrset; 885 if (rrtype == LDNS_RR_TYPE_CNAME && raddr->data != NULL) { 886 log_err("CNAME response-ip data can not co-exist with other " 887 "client-ip data"); 888 return 0; 889 } 890 891 rrset = rpz_clientip_new_rrset(region, raddr, rrtype, rrclass); 892 if(raddr->data == NULL) { 893 return 0; 894 } 895 896 return rrset_insert_rr(region, rrset->rrset->entry.data, rdata, rdata_len, ttl, ""); 897 } 898 899 static int 900 rpz_clientip_insert_trigger_rr(struct clientip_synthesized_rrset* set, struct sockaddr_storage* addr, 901 socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype, 902 uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len, 903 uint8_t* rr, size_t rr_len) 904 { 905 struct clientip_synthesized_rr* node; 906 907 lock_rw_wrlock(&set->lock); 908 909 node = rpz_clientip_ensure_entry(set, addr, addrlen, net); 910 if(node == NULL) { 911 lock_rw_unlock(&set->lock); 912 rpz_report_rrset_error("client ip address", rr, rr_len); 913 return 0; 914 } 915 916 lock_rw_wrlock(&node->lock); 917 lock_rw_unlock(&set->lock); 918 919 node->action = a; 920 if(a == RPZ_LOCAL_DATA_ACTION) { 921 if(!rpz_clientip_enter_rr(set->region, node, rrtype, 922 rrclass, ttl, rdata, rdata_len)) { 923 verbose(VERB_ALGO, "rpz: unable to insert clientip rr"); 924 lock_rw_unlock(&node->lock); 925 return 0; 926 } 927 928 } 929 930 lock_rw_unlock(&node->lock); 931 932 return 1; 933 } 934 935 static int 936 rpz_insert_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 937 enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl, 938 uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 939 { 940 struct sockaddr_storage addr; 941 socklen_t addrlen; 942 int net, af; 943 944 if(a == RPZ_INVALID_ACTION) { 945 return 0; 946 } 947 948 if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) { 949 verbose(VERB_ALGO, "rpz: unable to parse client ip"); 950 return 0; 951 } 952 953 return rpz_clientip_insert_trigger_rr(r->client_set, &addr, addrlen, net, 954 a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len); 955 } 956 957 static int 958 rpz_insert_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 959 enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl, 960 uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 961 { 962 struct sockaddr_storage addr; 963 socklen_t addrlen; 964 int net, af; 965 966 if(a == RPZ_INVALID_ACTION) { 967 return 0; 968 } 969 970 if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) { 971 verbose(VERB_ALGO, "rpz: unable to parse ns ip"); 972 return 0; 973 } 974 975 return rpz_clientip_insert_trigger_rr(r->ns_set, &addr, addrlen, net, 976 a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len); 977 } 978 979 /** Insert RR into RPZ's respip_set */ 980 static int 981 rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 982 enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl, 983 uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len) 984 { 985 struct sockaddr_storage addr; 986 socklen_t addrlen; 987 int net, af; 988 989 if(a == RPZ_INVALID_ACTION) { 990 return 0; 991 } 992 993 if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) { 994 verbose(VERB_ALGO, "rpz: unable to parse response ip"); 995 return 0; 996 } 997 998 if(a == RPZ_INVALID_ACTION || 999 rpz_action_to_respip_action(a) == respip_invalid) { 1000 char str[255+1]; 1001 dname_str(dname, str); 1002 verbose(VERB_ALGO, "RPZ: respip trigger, %s skipping unsupported action: %s", 1003 str, rpz_action_to_string(a)); 1004 return 0; 1005 } 1006 1007 return rpz_insert_ipaddr_based_trigger(r->respip_set, &addr, addrlen, net, 1008 a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len); 1009 } 1010 1011 int 1012 rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname, 1013 size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl, 1014 uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len) 1015 { 1016 size_t policydnamelen; 1017 /* name is free'd in local_zone delete */ 1018 enum rpz_trigger t; 1019 enum rpz_action a; 1020 uint8_t* policydname; 1021 1022 if(rpz_type_ignored(rr_type)) { 1023 /* this rpz action is not valid, eg. this is the SOA or NS RR */ 1024 return 1; 1025 } 1026 if(!dname_subdomain_c(dname, azname)) { 1027 char* dname_str = sldns_wire2str_dname(dname, dnamelen); 1028 char* azname_str = sldns_wire2str_dname(azname, aznamelen); 1029 if(dname_str && azname_str) { 1030 log_err("rpz: name of record (%s) to insert into RPZ is not a " 1031 "subdomain of the configured name of the RPZ zone (%s)", 1032 dname_str, azname_str); 1033 } else { 1034 log_err("rpz: name of record to insert into RPZ is not a " 1035 "subdomain of the configured name of the RPZ zone"); 1036 } 1037 free(dname_str); 1038 free(azname_str); 1039 return 0; 1040 } 1041 1042 log_assert(dnamelen >= aznamelen); 1043 if(!(policydname = calloc(1, (dnamelen-aznamelen)+1))) { 1044 log_err("malloc error while inserting RPZ RR"); 1045 return 0; 1046 } 1047 1048 a = rpz_rr_to_action(rr_type, rdatawl, rdatalen); 1049 if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen, 1050 policydname, (dnamelen-aznamelen)+1))) { 1051 free(policydname); 1052 return 0; 1053 } 1054 t = rpz_dname_to_trigger(policydname, policydnamelen); 1055 if(t == RPZ_INVALID_TRIGGER) { 1056 free(policydname); 1057 verbose(VERB_ALGO, "rpz: skipping invalid trigger"); 1058 return 1; 1059 } 1060 if(t == RPZ_QNAME_TRIGGER) { 1061 /* policydname will be consumed, no free */ 1062 rpz_insert_qname_trigger(r, policydname, policydnamelen, 1063 a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr, 1064 rr_len); 1065 } else if(t == RPZ_RESPONSE_IP_TRIGGER) { 1066 rpz_insert_response_ip_trigger(r, policydname, policydnamelen, 1067 a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr, 1068 rr_len); 1069 free(policydname); 1070 } else if(t == RPZ_CLIENT_IP_TRIGGER) { 1071 rpz_insert_clientip_trigger(r, policydname, policydnamelen, 1072 a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr, 1073 rr_len); 1074 free(policydname); 1075 } else if(t == RPZ_NSIP_TRIGGER) { 1076 rpz_insert_nsip_trigger(r, policydname, policydnamelen, 1077 a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr, 1078 rr_len); 1079 free(policydname); 1080 } else if(t == RPZ_NSDNAME_TRIGGER) { 1081 rpz_insert_nsdname_trigger(r, policydname, policydnamelen, 1082 a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr, 1083 rr_len); 1084 free(policydname); 1085 } else { 1086 free(policydname); 1087 verbose(VERB_ALGO, "rpz: skipping unsupported trigger: %s", 1088 rpz_trigger_to_string(t)); 1089 } 1090 return 1; 1091 } 1092 1093 /** 1094 * Find RPZ local-zone by qname. 1095 * @param zones: local-zone tree 1096 * @param qname: qname 1097 * @param qname_len: length of qname 1098 * @param qclass: qclass 1099 * @param only_exact: if 1 only exact (non wildcard) matches are returned 1100 * @param wr: get write lock for local-zone if 1, read lock if 0 1101 * @param zones_keep_lock: if set do not release the r->local_zones lock, this 1102 * makes the caller of this function responsible for releasing the lock. 1103 * @return: NULL or local-zone holding rd or wr lock 1104 */ 1105 static struct local_zone* 1106 rpz_find_zone(struct local_zones* zones, uint8_t* qname, size_t qname_len, uint16_t qclass, 1107 int only_exact, int wr, int zones_keep_lock) 1108 { 1109 uint8_t* ce; 1110 size_t ce_len; 1111 int ce_labs; 1112 uint8_t wc[LDNS_MAX_DOMAINLEN+1]; 1113 int exact; 1114 struct local_zone* z = NULL; 1115 1116 if(wr) { 1117 lock_rw_wrlock(&zones->lock); 1118 } else { 1119 lock_rw_rdlock(&zones->lock); 1120 } 1121 z = local_zones_find_le(zones, qname, qname_len, 1122 dname_count_labels(qname), 1123 LDNS_RR_CLASS_IN, &exact); 1124 if(!z || (only_exact && !exact)) { 1125 if(!zones_keep_lock) { 1126 lock_rw_unlock(&zones->lock); 1127 } 1128 return NULL; 1129 } 1130 if(wr) { 1131 lock_rw_wrlock(&z->lock); 1132 } else { 1133 lock_rw_rdlock(&z->lock); 1134 } 1135 if(!zones_keep_lock) { 1136 lock_rw_unlock(&zones->lock); 1137 } 1138 1139 if(exact) 1140 return z; 1141 1142 /* No exact match found, lookup wildcard. closest encloser must 1143 * be the shared parent between the qname and the best local 1144 * zone match, append '*' to that and do another lookup. */ 1145 1146 ce = dname_get_shared_topdomain(z->name, qname); 1147 if(!ce /* should not happen */) { 1148 lock_rw_unlock(&z->lock); 1149 if(zones_keep_lock) { 1150 lock_rw_unlock(&zones->lock); 1151 } 1152 return NULL; 1153 } 1154 ce_labs = dname_count_size_labels(ce, &ce_len); 1155 if(ce_len+2 > sizeof(wc)) { 1156 lock_rw_unlock(&z->lock); 1157 if(zones_keep_lock) { 1158 lock_rw_unlock(&zones->lock); 1159 } 1160 return NULL; 1161 } 1162 wc[0] = 1; /* length of wildcard label */ 1163 wc[1] = (uint8_t)'*'; /* wildcard label */ 1164 memmove(wc+2, ce, ce_len); 1165 lock_rw_unlock(&z->lock); 1166 1167 if(!zones_keep_lock) { 1168 if(wr) { 1169 lock_rw_wrlock(&zones->lock); 1170 } else { 1171 lock_rw_rdlock(&zones->lock); 1172 } 1173 } 1174 z = local_zones_find_le(zones, wc, 1175 ce_len+2, ce_labs+1, qclass, &exact); 1176 if(!z || !exact) { 1177 lock_rw_unlock(&zones->lock); 1178 return NULL; 1179 } 1180 if(wr) { 1181 lock_rw_wrlock(&z->lock); 1182 } else { 1183 lock_rw_rdlock(&z->lock); 1184 } 1185 if(!zones_keep_lock) { 1186 lock_rw_unlock(&zones->lock); 1187 } 1188 return z; 1189 } 1190 1191 /** 1192 * Remove RR from RPZ's local-data 1193 * @param z: local-zone for RPZ, holding write lock 1194 * @param policydname: dname of RR to remove 1195 * @param policydnamelen: length of policydname 1196 * @param rr_type: RR type of RR to remove 1197 * @param rdata: rdata of RR to remove 1198 * @param rdatalen: length of rdata 1199 * @return: 1 if zone must be removed after RR deletion 1200 */ 1201 static int 1202 rpz_data_delete_rr(struct local_zone* z, uint8_t* policydname, 1203 size_t policydnamelen, uint16_t rr_type, uint8_t* rdata, 1204 size_t rdatalen) 1205 { 1206 struct local_data* ld; 1207 struct packed_rrset_data* d; 1208 size_t index; 1209 ld = local_zone_find_data(z, policydname, policydnamelen, 1210 dname_count_labels(policydname)); 1211 if(ld) { 1212 struct local_rrset* prev=NULL, *p=ld->rrsets; 1213 while(p && ntohs(p->rrset->rk.type) != rr_type) { 1214 prev = p; 1215 p = p->next; 1216 } 1217 if(!p) 1218 return 0; 1219 d = (struct packed_rrset_data*)p->rrset->entry.data; 1220 if(packed_rrset_find_rr(d, rdata, rdatalen, &index)) { 1221 if(d->count == 1) { 1222 /* no memory recycling for zone deletions ... */ 1223 if(prev) prev->next = p->next; 1224 else ld->rrsets = p->next; 1225 } 1226 if(d->count > 1) { 1227 if(!local_rrset_remove_rr(d, index)) 1228 return 0; 1229 } 1230 } 1231 } 1232 if(ld && ld->rrsets) 1233 return 0; 1234 return 1; 1235 } 1236 1237 /** 1238 * Remove RR from RPZ's respip set 1239 * @param raddr: respip node 1240 * @param rr_type: RR type of RR to remove 1241 * @param rdata: rdata of RR to remove 1242 * @param rdatalen: length of rdata 1243 * @return: 1 if zone must be removed after RR deletion 1244 */ 1245 static int 1246 rpz_rrset_delete_rr(struct resp_addr* raddr, uint16_t rr_type, uint8_t* rdata, 1247 size_t rdatalen) 1248 { 1249 size_t index; 1250 struct packed_rrset_data* d; 1251 if(!raddr->data) 1252 return 1; 1253 d = raddr->data->entry.data; 1254 if(ntohs(raddr->data->rk.type) != rr_type) { 1255 return 0; 1256 } 1257 if(packed_rrset_find_rr(d, rdata, rdatalen, &index)) { 1258 if(d->count == 1) { 1259 /* regional alloc'd */ 1260 raddr->data->entry.data = NULL; 1261 raddr->data = NULL; 1262 return 1; 1263 } 1264 if(d->count > 1) { 1265 if(!local_rrset_remove_rr(d, index)) 1266 return 0; 1267 } 1268 } 1269 return 0; 1270 1271 } 1272 1273 /** Remove RR from RPZ's local-zone */ 1274 static void 1275 rpz_remove_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 1276 enum rpz_action a, uint16_t rr_type, uint16_t rr_class, 1277 uint8_t* rdatawl, size_t rdatalen) 1278 { 1279 struct local_zone* z; 1280 int delete_zone = 1; 1281 z = rpz_find_zone(r->local_zones, dname, dnamelen, rr_class, 1282 1 /* only exact */, 1 /* wr lock */, 1 /* keep lock*/); 1283 if(!z) { 1284 verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, " 1285 "RPZ domain not found"); 1286 return; 1287 } 1288 if(a == RPZ_LOCAL_DATA_ACTION) 1289 delete_zone = rpz_data_delete_rr(z, dname, 1290 dnamelen, rr_type, rdatawl, rdatalen); 1291 else if(a != localzone_type_to_rpz_action(z->type)) { 1292 lock_rw_unlock(&z->lock); 1293 lock_rw_unlock(&r->local_zones->lock); 1294 return; 1295 } 1296 lock_rw_unlock(&z->lock); 1297 if(delete_zone) { 1298 local_zones_del_zone(r->local_zones, z); 1299 } 1300 lock_rw_unlock(&r->local_zones->lock); 1301 return; 1302 } 1303 1304 static void 1305 rpz_remove_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, 1306 enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen) 1307 { 1308 struct resp_addr* node; 1309 struct sockaddr_storage addr; 1310 socklen_t addrlen; 1311 int net, af; 1312 int delete_respip = 1; 1313 1314 if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) 1315 return; 1316 1317 lock_rw_wrlock(&r->respip_set->lock); 1318 if(!(node = (struct resp_addr*)addr_tree_find( 1319 &r->respip_set->ip_tree, &addr, addrlen, net))) { 1320 verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, " 1321 "RPZ domain not found"); 1322 lock_rw_unlock(&r->respip_set->lock); 1323 return; 1324 } 1325 1326 lock_rw_wrlock(&node->lock); 1327 if(a == RPZ_LOCAL_DATA_ACTION) { 1328 /* remove RR, signal whether RR can be removed */ 1329 delete_respip = rpz_rrset_delete_rr(node, rr_type, rdatawl, 1330 rdatalen); 1331 } 1332 lock_rw_unlock(&node->lock); 1333 if(delete_respip) 1334 respip_sockaddr_delete(r->respip_set, node); 1335 lock_rw_unlock(&r->respip_set->lock); 1336 } 1337 1338 void 1339 rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname, size_t dnamelen, 1340 uint16_t rr_type, uint16_t rr_class, uint8_t* rdatawl, size_t rdatalen) 1341 { 1342 size_t policydnamelen; 1343 enum rpz_trigger t; 1344 enum rpz_action a; 1345 uint8_t* policydname; 1346 1347 if(!(policydname = calloc(1, LDNS_MAX_DOMAINLEN + 1))) 1348 return; 1349 1350 a = rpz_rr_to_action(rr_type, rdatawl, rdatalen); 1351 if(a == RPZ_INVALID_ACTION) { 1352 free(policydname); 1353 return; 1354 } 1355 if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen, 1356 policydname, LDNS_MAX_DOMAINLEN + 1))) { 1357 free(policydname); 1358 return; 1359 } 1360 t = rpz_dname_to_trigger(policydname, policydnamelen); 1361 if(t == RPZ_QNAME_TRIGGER) { 1362 rpz_remove_qname_trigger(r, policydname, policydnamelen, a, 1363 rr_type, rr_class, rdatawl, rdatalen); 1364 } else if(t == RPZ_RESPONSE_IP_TRIGGER) { 1365 rpz_remove_response_ip_trigger(r, policydname, policydnamelen, 1366 a, rr_type, rdatawl, rdatalen); 1367 } 1368 free(policydname); 1369 } 1370 1371 /** print log information for an applied RPZ policy. Based on local-zone's 1372 * lz_inform_print(). 1373 * The repinfo contains the reply address. If it is NULL, the module 1374 * state is used to report the first IP address (if any). 1375 * The dname is used, for the applied rpz, if NULL, addrnode is used. 1376 */ 1377 static void 1378 log_rpz_apply(char* trigger, uint8_t* dname, struct addr_tree_node* addrnode, 1379 enum rpz_action a, struct query_info* qinfo, 1380 struct comm_reply* repinfo, struct module_qstate* ms, char* log_name) 1381 { 1382 char ip[128], txt[512], portstr[32]; 1383 char dnamestr[LDNS_MAX_DOMAINLEN+1]; 1384 uint16_t port = 0; 1385 if(dname) { 1386 dname_str(dname, dnamestr); 1387 } else if(addrnode) { 1388 char addrbuf[128]; 1389 addr_to_str(&addrnode->addr, addrnode->addrlen, addrbuf, sizeof(addrbuf)); 1390 snprintf(dnamestr, sizeof(dnamestr), "%s/%d", addrbuf, addrnode->net); 1391 } else { 1392 dnamestr[0]=0; 1393 } 1394 if(repinfo) { 1395 addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip)); 1396 port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port); 1397 } else if(ms && ms->mesh_info && ms->mesh_info->reply_list) { 1398 addr_to_str(&ms->mesh_info->reply_list->query_reply.addr, ms->mesh_info->reply_list->query_reply.addrlen, ip, sizeof(ip)); 1399 port = ntohs(((struct sockaddr_in*)&ms->mesh_info->reply_list->query_reply.addr)->sin_port); 1400 } else { 1401 ip[0]=0; 1402 port = 0; 1403 } 1404 snprintf(portstr, sizeof(portstr), "@%u", (unsigned)port); 1405 snprintf(txt, sizeof(txt), "rpz: applied %s%s%s%s%s%s %s %s%s", 1406 (log_name?"[":""), (log_name?log_name:""), (log_name?"] ":""), 1407 (strcmp(trigger,"qname")==0?"":trigger), 1408 (strcmp(trigger,"qname")==0?"":" "), 1409 dnamestr, rpz_action_to_string(a), 1410 (ip[0]?ip:""), (ip[0]?portstr:"")); 1411 log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass); 1412 } 1413 1414 static struct clientip_synthesized_rr* 1415 rpz_ipbased_trigger_lookup(struct clientip_synthesized_rrset* set, 1416 struct sockaddr_storage* addr, socklen_t addrlen, char* triggername) 1417 { 1418 struct clientip_synthesized_rr* raddr = NULL; 1419 enum rpz_action action = RPZ_INVALID_ACTION; 1420 1421 lock_rw_rdlock(&set->lock); 1422 1423 raddr = (struct clientip_synthesized_rr*)addr_tree_lookup(&set->entries, 1424 addr, addrlen); 1425 if(raddr != NULL) { 1426 lock_rw_rdlock(&raddr->lock); 1427 action = raddr->action; 1428 if(verbosity >= VERB_ALGO) { 1429 char ip[256], net[256]; 1430 addr_to_str(addr, addrlen, ip, sizeof(ip)); 1431 addr_to_str(&raddr->node.addr, raddr->node.addrlen, 1432 net, sizeof(net)); 1433 verbose(VERB_ALGO, "rpz: trigger %s %s/%d on %s action=%s", 1434 triggername, net, raddr->node.net, ip, rpz_action_to_string(action)); 1435 } 1436 } 1437 lock_rw_unlock(&set->lock); 1438 1439 return raddr; 1440 } 1441 1442 static inline 1443 struct clientip_synthesized_rr* 1444 rpz_resolve_client_action_and_zone(struct auth_zones* az, struct query_info* qinfo, 1445 struct comm_reply* repinfo, uint8_t* taglist, size_t taglen, 1446 struct ub_server_stats* stats, 1447 /* output parameters */ 1448 struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out) 1449 { 1450 struct clientip_synthesized_rr* node = NULL; 1451 struct auth_zone* a = NULL; 1452 struct rpz* r = NULL; 1453 struct local_zone* z = NULL; 1454 1455 lock_rw_rdlock(&az->rpz_lock); 1456 1457 for(a = az->rpz_first; a; a = a->rpz_az_next) { 1458 lock_rw_rdlock(&a->lock); 1459 r = a->rpz; 1460 if(r->disabled) { 1461 lock_rw_unlock(&a->lock); 1462 continue; 1463 } 1464 if(r->taglist && !taglist_intersect(r->taglist, 1465 r->taglistlen, taglist, taglen)) { 1466 lock_rw_unlock(&a->lock); 1467 continue; 1468 } 1469 z = rpz_find_zone(r->local_zones, qinfo->qname, qinfo->qname_len, 1470 qinfo->qclass, 0, 0, 0); 1471 node = rpz_ipbased_trigger_lookup(r->client_set, &repinfo->addr, repinfo->addrlen, "clientip"); 1472 if((z || node) && r->action_override == RPZ_DISABLED_ACTION) { 1473 if(r->log) 1474 log_rpz_apply((node?"clientip":"qname"), 1475 (z?z->name:NULL), 1476 (node?&node->node:NULL), 1477 r->action_override, 1478 qinfo, repinfo, NULL, r->log_name); 1479 stats->rpz_action[r->action_override]++; 1480 if(z != NULL) { 1481 lock_rw_unlock(&z->lock); 1482 z = NULL; 1483 } 1484 if(node != NULL) { 1485 lock_rw_unlock(&node->lock); 1486 node = NULL; 1487 } 1488 } 1489 if(z || node) { 1490 break; 1491 } 1492 /* not found in this auth_zone */ 1493 lock_rw_unlock(&a->lock); 1494 } 1495 1496 lock_rw_unlock(&az->rpz_lock); 1497 1498 *r_out = r; 1499 *a_out = a; 1500 *z_out = z; 1501 1502 return node; 1503 } 1504 1505 static inline int 1506 rpz_is_udp_query(struct comm_reply* repinfo) { 1507 return repinfo != NULL 1508 ? (repinfo->c != NULL 1509 ? repinfo->c->type == comm_udp 1510 : 0) 1511 : 0; 1512 } 1513 1514 /** encode answer consisting of 1 rrset */ 1515 static int 1516 rpz_local_encode(struct module_env* env, struct query_info* qinfo, 1517 struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, 1518 struct regional* temp, struct ub_packed_rrset_key* rrset, int ansec, 1519 int rcode, struct ub_packed_rrset_key* soa_rrset) 1520 { 1521 struct reply_info rep; 1522 uint16_t udpsize; 1523 struct ub_packed_rrset_key* rrsetlist[3]; 1524 1525 memset(&rep, 0, sizeof(rep)); 1526 rep.flags = (uint16_t)((BIT_QR | BIT_AA | BIT_RA) | rcode); 1527 rep.qdcount = 1; 1528 rep.rrset_count = ansec; 1529 rep.rrsets = rrsetlist; 1530 if(ansec > 0) { 1531 rep.an_numrrsets = 1; 1532 rep.rrsets[0] = rrset; 1533 rep.ttl = ((struct packed_rrset_data*)rrset->entry.data)->rr_ttl[0]; 1534 } 1535 if(soa_rrset != NULL) { 1536 rep.ar_numrrsets = 1; 1537 rep.rrsets[rep.rrset_count] = soa_rrset; 1538 rep.rrset_count ++; 1539 if(rep.ttl < ((struct packed_rrset_data*)soa_rrset->entry.data)->rr_ttl[0]) { 1540 rep.ttl = ((struct packed_rrset_data*)soa_rrset->entry.data)->rr_ttl[0]; 1541 } 1542 } 1543 1544 udpsize = edns->udp_size; 1545 edns->edns_version = EDNS_ADVERTISED_VERSION; 1546 edns->udp_size = EDNS_ADVERTISED_SIZE; 1547 edns->ext_rcode = 0; 1548 edns->bits &= EDNS_DO; 1549 if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns, 1550 repinfo, temp, env->now_tv) || 1551 !reply_info_answer_encode(qinfo, &rep, 1552 *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2), 1553 buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) { 1554 error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo, 1555 *(uint16_t*)sldns_buffer_begin(buf), 1556 sldns_buffer_read_u16_at(buf, 2), edns); 1557 } 1558 1559 return 1; 1560 } 1561 1562 static struct local_rrset* 1563 rpz_find_synthesized_rrset(int qtype, struct clientip_synthesized_rr* data) { 1564 struct local_rrset* cursor = data->data; 1565 while( cursor != NULL) { 1566 struct packed_rrset_key* packed_rrset = &cursor->rrset->rk; 1567 if(htons(qtype) == packed_rrset->type) { 1568 return cursor; 1569 } 1570 cursor = cursor->next; 1571 } 1572 return NULL; 1573 } 1574 1575 /** allocate SOA record ubrrsetkey in region */ 1576 static struct ub_packed_rrset_key* 1577 make_soa_ubrrset(struct auth_zone* auth_zone, struct auth_rrset* soa, 1578 struct regional* temp) 1579 { 1580 struct ub_packed_rrset_key csoa; 1581 if(!soa) 1582 return NULL; 1583 memset(&csoa, 0, sizeof(csoa)); 1584 csoa.entry.key = &csoa; 1585 csoa.rk.rrset_class = htons(LDNS_RR_CLASS_IN); 1586 csoa.rk.type = htons(LDNS_RR_TYPE_SOA); 1587 csoa.rk.flags |= PACKED_RRSET_FIXEDTTL 1588 | PACKED_RRSET_RPZ; 1589 csoa.rk.dname = auth_zone->name; 1590 csoa.rk.dname_len = auth_zone->namelen; 1591 csoa.entry.hash = rrset_key_hash(&csoa.rk); 1592 csoa.entry.data = soa->data; 1593 return respip_copy_rrset(&csoa, temp); 1594 } 1595 1596 static void 1597 rpz_apply_clientip_localdata_action(struct clientip_synthesized_rr* raddr, 1598 struct module_env* env, struct query_info* qinfo, 1599 struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, 1600 struct regional* temp, struct auth_zone* auth_zone) 1601 { 1602 struct local_rrset* rrset; 1603 enum rpz_action action = RPZ_INVALID_ACTION; 1604 struct ub_packed_rrset_key* rp = NULL; 1605 struct ub_packed_rrset_key* rsoa = NULL; 1606 int rcode = LDNS_RCODE_NOERROR|BIT_AA; 1607 int rrset_count = 1; 1608 1609 /* prepare synthesized answer for client */ 1610 action = raddr->action; 1611 if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL ) { 1612 verbose(VERB_ALGO, "rpz: bug: local-data action but no local data"); 1613 return; 1614 } 1615 1616 /* check query type / rr type */ 1617 rrset = rpz_find_synthesized_rrset(qinfo->qtype, raddr); 1618 if(rrset == NULL) { 1619 verbose(VERB_ALGO, "rpz: unable to find local-data for query"); 1620 rrset_count = 0; 1621 goto nodata; 1622 } 1623 1624 rp = respip_copy_rrset(rrset->rrset, temp); 1625 if(!rp) { 1626 verbose(VERB_ALGO, "rpz: local data action: out of memory"); 1627 return; 1628 } 1629 1630 rp->rk.flags |= PACKED_RRSET_FIXEDTTL | PACKED_RRSET_RPZ; 1631 rp->rk.dname = qinfo->qname; 1632 rp->rk.dname_len = qinfo->qname_len; 1633 rp->entry.hash = rrset_key_hash(&rp->rk); 1634 nodata: 1635 if(auth_zone) { 1636 struct auth_rrset* soa = NULL; 1637 soa = auth_zone_get_soa_rrset(auth_zone); 1638 if(soa) { 1639 rsoa = make_soa_ubrrset(auth_zone, soa, temp); 1640 if(!rsoa) { 1641 verbose(VERB_ALGO, "rpz: local data action soa: out of memory"); 1642 return; 1643 } 1644 } 1645 } 1646 1647 rpz_local_encode(env, qinfo, edns, repinfo, buf, temp, rp, 1648 rrset_count, rcode, rsoa); 1649 } 1650 1651 /** add additional section SOA record to the reply. 1652 * Since this gets fed into the normal iterator answer creation, it 1653 * gets minimal-responses applied to it, that can remove the additional SOA 1654 * again. */ 1655 static int 1656 rpz_add_soa(struct reply_info* rep, struct module_qstate* ms, 1657 struct auth_zone* az) 1658 { 1659 struct auth_rrset* soa = NULL; 1660 struct ub_packed_rrset_key* rsoa = NULL; 1661 struct ub_packed_rrset_key** prevrrsets; 1662 if(!az) return 1; 1663 soa = auth_zone_get_soa_rrset(az); 1664 if(!soa) return 1; 1665 if(!rep) return 0; 1666 rsoa = make_soa_ubrrset(az, soa, ms->region); 1667 if(!rsoa) return 0; 1668 prevrrsets = rep->rrsets; 1669 rep->rrsets = regional_alloc_zero(ms->region, 1670 sizeof(*rep->rrsets)*(rep->rrset_count+1)); 1671 if(!rep->rrsets) 1672 return 0; 1673 if(prevrrsets && rep->rrset_count > 0) 1674 memcpy(rep->rrsets, prevrrsets, rep->rrset_count*sizeof(*rep->rrsets)); 1675 rep->rrset_count++; 1676 rep->ar_numrrsets++; 1677 rep->rrsets[rep->rrset_count-1] = rsoa; 1678 return 1; 1679 } 1680 1681 static inline struct dns_msg* 1682 rpz_dns_msg_new(struct regional* region) 1683 { 1684 struct dns_msg* msg = 1685 (struct dns_msg*)regional_alloc(region, 1686 sizeof(struct dns_msg)); 1687 if(msg == NULL) { return NULL; } 1688 memset(msg, 0, sizeof(struct dns_msg)); 1689 1690 return msg; 1691 } 1692 1693 static inline struct dns_msg* 1694 rpz_synthesize_nodata(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms, 1695 struct query_info* qinfo, struct auth_zone* az) 1696 { 1697 struct dns_msg* msg = rpz_dns_msg_new(ms->region); 1698 if(msg == NULL) { return msg; } 1699 msg->qinfo = *qinfo; 1700 msg->rep = construct_reply_info_base(ms->region, 1701 LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA, 1702 1, /* qd */ 1703 0, /* ttl */ 1704 0, /* prettl */ 1705 0, /* expttl */ 1706 0, /* an */ 1707 0, /* ns */ 1708 0, /* ar */ 1709 0, /* total */ 1710 sec_status_insecure); 1711 if(msg->rep) 1712 msg->rep->authoritative = 1; 1713 if(!rpz_add_soa(msg->rep, ms, az)) 1714 return NULL; 1715 return msg; 1716 } 1717 1718 static inline struct dns_msg* 1719 rpz_synthesize_nxdomain(struct rpz* r, struct module_qstate* ms, 1720 struct query_info* qinfo, struct auth_zone* az) 1721 { 1722 struct dns_msg* msg = rpz_dns_msg_new(ms->region); 1723 uint16_t flags; 1724 if(msg == NULL) { return msg; } 1725 msg->qinfo = *qinfo; 1726 flags = LDNS_RCODE_NXDOMAIN | BIT_QR | BIT_AA | BIT_RA; 1727 if(r->signal_nxdomain_ra) 1728 flags &= ~BIT_RA; 1729 msg->rep = construct_reply_info_base(ms->region, 1730 flags, 1731 1, /* qd */ 1732 0, /* ttl */ 1733 0, /* prettl */ 1734 0, /* expttl */ 1735 0, /* an */ 1736 0, /* ns */ 1737 0, /* ar */ 1738 0, /* total */ 1739 sec_status_insecure); 1740 if(msg->rep) 1741 msg->rep->authoritative = 1; 1742 if(!rpz_add_soa(msg->rep, ms, az)) 1743 return NULL; 1744 return msg; 1745 } 1746 1747 static inline struct dns_msg* 1748 rpz_synthesize_localdata_from_rrset(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms, 1749 struct query_info* qi, struct local_rrset* rrset, struct auth_zone* az) 1750 { 1751 struct dns_msg* msg = NULL; 1752 struct reply_info* new_reply_info; 1753 struct ub_packed_rrset_key* rp; 1754 1755 1756 msg = rpz_dns_msg_new(ms->region); 1757 if(msg == NULL) { return NULL; } 1758 1759 new_reply_info = construct_reply_info_base(ms->region, 1760 LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA, 1761 1, /* qd */ 1762 0, /* ttl */ 1763 0, /* prettl */ 1764 0, /* expttl */ 1765 1, /* an */ 1766 0, /* ns */ 1767 0, /* ar */ 1768 1, /* total */ 1769 sec_status_insecure); 1770 if(new_reply_info == NULL) { 1771 log_err("out of memory"); 1772 return NULL; 1773 } 1774 new_reply_info->authoritative = 1; 1775 rp = respip_copy_rrset(rrset->rrset, ms->region); 1776 if(rp == NULL) { 1777 log_err("out of memory"); 1778 return NULL; 1779 } 1780 rp->rk.dname = qi->qname; 1781 rp->rk.dname_len = qi->qname_len; 1782 /* this rrset is from the rpz data, or synthesized. 1783 * It is not actually from the network, so we flag it with this 1784 * flags as a fake RRset. If later the cache is used to look up 1785 * rrsets, then the fake ones are not returned (if you look without 1786 * the flag). For like CNAME lookups from the iterator or A, AAAA 1787 * lookups for nameserver targets, it would use the without flag 1788 * actual data. So that the actual network data and fake data 1789 * are kept track of separately. */ 1790 rp->rk.flags |= PACKED_RRSET_RPZ; 1791 new_reply_info->rrsets[0] = rp; 1792 msg->rep = new_reply_info; 1793 if(!rpz_add_soa(msg->rep, ms, az)) 1794 return NULL; 1795 return msg; 1796 } 1797 1798 static inline struct dns_msg* 1799 rpz_synthesize_nsip_localdata(struct rpz* r, struct module_qstate* ms, 1800 struct clientip_synthesized_rr* data, struct auth_zone* az) 1801 { 1802 struct query_info* qi = &ms->qinfo; 1803 struct local_rrset* rrset; 1804 1805 rrset = rpz_find_synthesized_rrset(qi->qtype, data); 1806 if(rrset == NULL) { 1807 verbose(VERB_ALGO, "rpz: nsip: no matching local data found"); 1808 return NULL; 1809 } 1810 1811 return rpz_synthesize_localdata_from_rrset(r, ms, &ms->qinfo, rrset, az); 1812 } 1813 1814 /* copy'n'paste from localzone.c */ 1815 static struct local_rrset* 1816 local_data_find_type(struct local_data* data, uint16_t type, int alias_ok) 1817 { 1818 struct local_rrset* p; 1819 type = htons(type); 1820 for(p = data->rrsets; p; p = p->next) { 1821 if(p->rrset->rk.type == type) 1822 return p; 1823 if(alias_ok && p->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME)) 1824 return p; 1825 } 1826 return NULL; 1827 } 1828 1829 /* based on localzone.c:local_data_answer() */ 1830 static inline struct dns_msg* 1831 rpz_synthesize_nsdname_localdata(struct rpz* r, struct module_qstate* ms, 1832 struct local_zone* z, struct matched_delegation_point const* match, 1833 struct auth_zone* az) 1834 { 1835 struct local_data key; 1836 struct local_data* ld; 1837 struct local_rrset* rrset; 1838 1839 if(match->dname == NULL) { return NULL; } 1840 1841 key.node.key = &key; 1842 key.name = match->dname; 1843 key.namelen = match->dname_len; 1844 key.namelabs = dname_count_labels(match->dname); 1845 1846 rpz_log_dname("nsdname local data", key.name, key.namelen); 1847 1848 ld = (struct local_data*)rbtree_search(&z->data, &key.node); 1849 if(ld == NULL) { 1850 verbose(VERB_ALGO, "rpz: nsdname: impossible: qname not found"); 1851 return NULL; 1852 } 1853 1854 rrset = local_data_find_type(ld, ms->qinfo.qtype, 1); 1855 if(rrset == NULL) { 1856 verbose(VERB_ALGO, "rpz: nsdname: no matching local data found"); 1857 return NULL; 1858 } 1859 1860 return rpz_synthesize_localdata_from_rrset(r, ms, &ms->qinfo, rrset, az); 1861 } 1862 1863 /* like local_data_answer for qname triggers after a cname */ 1864 static struct dns_msg* 1865 rpz_synthesize_qname_localdata_msg(struct rpz* r, struct module_qstate* ms, 1866 struct query_info* qinfo, struct local_zone* z, struct auth_zone* az) 1867 { 1868 struct local_data key; 1869 struct local_data* ld; 1870 struct local_rrset* rrset; 1871 key.node.key = &key; 1872 key.name = qinfo->qname; 1873 key.namelen = qinfo->qname_len; 1874 key.namelabs = dname_count_labels(qinfo->qname); 1875 ld = (struct local_data*)rbtree_search(&z->data, &key.node); 1876 if(ld == NULL) { 1877 verbose(VERB_ALGO, "rpz: qname after cname: name not found"); 1878 return NULL; 1879 } 1880 rrset = local_data_find_type(ld, qinfo->qtype, 1); 1881 if(rrset == NULL) { 1882 verbose(VERB_ALGO, "rpz: qname after cname: type not found"); 1883 return NULL; 1884 } 1885 return rpz_synthesize_localdata_from_rrset(r, ms, qinfo, rrset, az); 1886 } 1887 1888 static int 1889 rpz_synthesize_qname_localdata(struct module_env* env, struct rpz* r, 1890 struct local_zone* z, enum localzone_type lzt, struct query_info* qinfo, 1891 struct edns_data* edns, sldns_buffer* buf, struct regional* temp, 1892 struct comm_reply* repinfo, struct ub_server_stats* stats) 1893 { 1894 struct local_data* ld = NULL; 1895 int ret = 0; 1896 if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) { 1897 qinfo->local_alias = regional_alloc_zero(temp, sizeof(struct local_rrset)); 1898 if(qinfo->local_alias == NULL) { 1899 return 0; /* out of memory */ 1900 } 1901 qinfo->local_alias->rrset = regional_alloc_init(temp, r->cname_override, 1902 sizeof(*r->cname_override)); 1903 if(qinfo->local_alias->rrset == NULL) { 1904 return 0; /* out of memory */ 1905 } 1906 qinfo->local_alias->rrset->rk.dname = qinfo->qname; 1907 qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len; 1908 if(r->log) { 1909 log_rpz_apply("qname", z->name, NULL, RPZ_CNAME_OVERRIDE_ACTION, 1910 qinfo, repinfo, NULL, r->log_name); 1911 } 1912 stats->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++; 1913 return 0; 1914 } 1915 1916 if(lzt == local_zone_redirect && local_data_answer(z, env, qinfo, 1917 edns, repinfo, buf, temp, dname_count_labels(qinfo->qname), 1918 &ld, lzt, -1, NULL, 0, NULL, 0)) { 1919 if(r->log) { 1920 log_rpz_apply("qname", z->name, NULL, 1921 localzone_type_to_rpz_action(lzt), qinfo, 1922 repinfo, NULL, r->log_name); 1923 } 1924 stats->rpz_action[localzone_type_to_rpz_action(lzt)]++; 1925 return !qinfo->local_alias; 1926 } 1927 1928 ret = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, 1929 0 /* no local data used */, lzt); 1930 if(r->signal_nxdomain_ra && LDNS_RCODE_WIRE(sldns_buffer_begin(buf)) 1931 == LDNS_RCODE_NXDOMAIN) 1932 LDNS_RA_CLR(sldns_buffer_begin(buf)); 1933 if(r->log) { 1934 log_rpz_apply("qname", z->name, NULL, localzone_type_to_rpz_action(lzt), 1935 qinfo, repinfo, NULL, r->log_name); 1936 } 1937 stats->rpz_action[localzone_type_to_rpz_action(lzt)]++; 1938 return ret; 1939 } 1940 1941 static struct clientip_synthesized_rr* 1942 rpz_delegation_point_ipbased_trigger_lookup(struct rpz* rpz, struct iter_qstate* is) 1943 { 1944 struct delegpt_addr* cursor; 1945 struct clientip_synthesized_rr* action = NULL; 1946 if(is->dp == NULL) { return NULL; } 1947 for(cursor = is->dp->target_list; 1948 cursor != NULL; 1949 cursor = cursor->next_target) { 1950 if(cursor->bogus) { continue; } 1951 action = rpz_ipbased_trigger_lookup(rpz->ns_set, &cursor->addr, 1952 cursor->addrlen, "nsip"); 1953 if(action != NULL) { return action; } 1954 } 1955 return NULL; 1956 } 1957 1958 static struct dns_msg* 1959 rpz_apply_nsip_trigger(struct module_qstate* ms, struct rpz* r, 1960 struct clientip_synthesized_rr* raddr, struct auth_zone* az) 1961 { 1962 enum rpz_action action = raddr->action; 1963 struct dns_msg* ret = NULL; 1964 1965 if(r->action_override != RPZ_NO_OVERRIDE_ACTION) { 1966 verbose(VERB_ALGO, "rpz: using override action=%s (replaces=%s)", 1967 rpz_action_to_string(r->action_override), rpz_action_to_string(action)); 1968 action = r->action_override; 1969 } 1970 1971 if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL) { 1972 verbose(VERB_ALGO, "rpz: bug: nsip local data action but no local data"); 1973 ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); 1974 goto done; 1975 } 1976 1977 switch(action) { 1978 case RPZ_NXDOMAIN_ACTION: 1979 ret = rpz_synthesize_nxdomain(r, ms, &ms->qinfo, az); 1980 break; 1981 case RPZ_NODATA_ACTION: 1982 ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); 1983 break; 1984 case RPZ_TCP_ONLY_ACTION: 1985 /* basically a passthru here but the tcp-only will be 1986 * honored before the query gets sent. */ 1987 ms->respip_action_info->action = respip_truncate; 1988 ret = NULL; 1989 break; 1990 case RPZ_DROP_ACTION: 1991 ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); 1992 ms->is_drop = 1; 1993 break; 1994 case RPZ_LOCAL_DATA_ACTION: 1995 ret = rpz_synthesize_nsip_localdata(r, ms, raddr, az); 1996 if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); } 1997 break; 1998 case RPZ_PASSTHRU_ACTION: 1999 ret = NULL; 2000 break; 2001 default: 2002 verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'", 2003 rpz_action_to_string(action)); 2004 ret = NULL; 2005 } 2006 2007 done: 2008 if(r->log) 2009 log_rpz_apply("nsip", NULL, &raddr->node, 2010 action, &ms->qinfo, NULL, ms, r->log_name); 2011 if(ms->env->worker) 2012 ms->env->worker->stats.rpz_action[action]++; 2013 lock_rw_unlock(&raddr->lock); 2014 return ret; 2015 } 2016 2017 static struct dns_msg* 2018 rpz_apply_nsdname_trigger(struct module_qstate* ms, struct rpz* r, 2019 struct local_zone* z, struct matched_delegation_point const* match, 2020 struct auth_zone* az) 2021 { 2022 struct dns_msg* ret = NULL; 2023 enum rpz_action action = localzone_type_to_rpz_action(z->type); 2024 2025 if(r->action_override != RPZ_NO_OVERRIDE_ACTION) { 2026 verbose(VERB_ALGO, "rpz: using override action=%s (replaces=%s)", 2027 rpz_action_to_string(r->action_override), rpz_action_to_string(action)); 2028 action = r->action_override; 2029 } 2030 2031 switch(action) { 2032 case RPZ_NXDOMAIN_ACTION: 2033 ret = rpz_synthesize_nxdomain(r, ms, &ms->qinfo, az); 2034 break; 2035 case RPZ_NODATA_ACTION: 2036 ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); 2037 break; 2038 case RPZ_TCP_ONLY_ACTION: 2039 /* basically a passthru here but the tcp-only will be 2040 * honored before the query gets sent. */ 2041 ms->respip_action_info->action = respip_truncate; 2042 ret = NULL; 2043 break; 2044 case RPZ_DROP_ACTION: 2045 ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); 2046 ms->is_drop = 1; 2047 break; 2048 case RPZ_LOCAL_DATA_ACTION: 2049 ret = rpz_synthesize_nsdname_localdata(r, ms, z, match, az); 2050 if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); } 2051 break; 2052 case RPZ_PASSTHRU_ACTION: 2053 ret = NULL; 2054 break; 2055 default: 2056 verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'", 2057 rpz_action_to_string(action)); 2058 ret = NULL; 2059 } 2060 2061 if(r->log) 2062 log_rpz_apply("nsdname", match->dname, NULL, 2063 action, &ms->qinfo, NULL, ms, r->log_name); 2064 if(ms->env->worker) 2065 ms->env->worker->stats.rpz_action[action]++; 2066 lock_rw_unlock(&z->lock); 2067 return ret; 2068 } 2069 2070 static struct local_zone* 2071 rpz_delegation_point_zone_lookup(struct delegpt* dp, struct local_zones* zones, 2072 uint16_t qclass, 2073 /* output parameter */ 2074 struct matched_delegation_point* match) 2075 { 2076 struct delegpt_ns* nameserver; 2077 struct local_zone* z = NULL; 2078 2079 /* the rpz specs match the nameserver names (NS records), not the 2080 * name of the delegation point itself, to the nsdname triggers */ 2081 for(nameserver = dp->nslist; 2082 nameserver != NULL; 2083 nameserver = nameserver->next) { 2084 z = rpz_find_zone(zones, nameserver->name, nameserver->namelen, 2085 qclass, 0, 0, 0); 2086 if(z != NULL) { 2087 match->dname = nameserver->name; 2088 match->dname_len = nameserver->namelen; 2089 if(verbosity >= VERB_ALGO) { 2090 char nm[255+1], zn[255+1]; 2091 dname_str(match->dname, nm); 2092 dname_str(z->name, zn); 2093 if(strcmp(nm, zn) != 0) 2094 verbose(VERB_ALGO, "rpz: trigger nsdname %s on %s action=%s", 2095 zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(z->type))); 2096 else 2097 verbose(VERB_ALGO, "rpz: trigger nsdname %s action=%s", 2098 nm, rpz_action_to_string(localzone_type_to_rpz_action(z->type))); 2099 } 2100 break; 2101 } 2102 } 2103 2104 return z; 2105 } 2106 2107 struct dns_msg* 2108 rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate* is) 2109 { 2110 struct auth_zones* az; 2111 struct auth_zone* a; 2112 struct clientip_synthesized_rr* raddr = NULL; 2113 struct rpz* r = NULL; 2114 struct local_zone* z = NULL; 2115 struct matched_delegation_point match = {0}; 2116 2117 if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; } 2118 2119 az = ms->env->auth_zones; 2120 2121 verbose(VERB_ALGO, "rpz: iterator module callback: have_rpz=%d", az->rpz_first != NULL); 2122 2123 lock_rw_rdlock(&az->rpz_lock); 2124 2125 /* precedence of RPZ works, loosely, like this: 2126 * CNAMEs in order of the CNAME chain. rpzs in the order they are 2127 * configured. In an RPZ: first client-IP addr, then QNAME, then 2128 * response IP, then NSDNAME, then NSIP. Longest match first. Smallest 2129 * one from a set. */ 2130 /* we use the precedence rules for the topics and triggers that 2131 * are pertinent at this stage of the resolve processing */ 2132 for(a = az->rpz_first; a != NULL; a = a->rpz_az_next) { 2133 lock_rw_rdlock(&a->lock); 2134 r = a->rpz; 2135 if(r->disabled) { 2136 lock_rw_unlock(&a->lock); 2137 continue; 2138 } 2139 2140 /* the nsdname has precedence over the nsip triggers */ 2141 z = rpz_delegation_point_zone_lookup(is->dp, r->nsdname_zones, 2142 ms->qinfo.qclass, &match); 2143 if(z != NULL) { 2144 lock_rw_unlock(&a->lock); 2145 break; 2146 } 2147 2148 raddr = rpz_delegation_point_ipbased_trigger_lookup(r, is); 2149 if(raddr != NULL) { 2150 lock_rw_unlock(&a->lock); 2151 break; 2152 } 2153 lock_rw_unlock(&a->lock); 2154 } 2155 2156 lock_rw_unlock(&az->rpz_lock); 2157 2158 if(raddr == NULL && z == NULL) { return NULL; } 2159 else if(raddr != NULL) { 2160 if(z) { 2161 lock_rw_unlock(&z->lock); 2162 } 2163 return rpz_apply_nsip_trigger(ms, r, raddr, a); 2164 } else if(z != NULL) { 2165 if(raddr) { 2166 lock_rw_unlock(&raddr->lock); 2167 } 2168 return rpz_apply_nsdname_trigger(ms, r, z, &match, a); 2169 } else { return NULL; } 2170 } 2171 2172 struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms, 2173 struct iter_qstate* is) 2174 { 2175 struct auth_zones* az; 2176 struct auth_zone* a = NULL; 2177 struct rpz* r = NULL; 2178 struct local_zone* z = NULL; 2179 enum localzone_type lzt; 2180 struct dns_msg* ret = NULL; 2181 2182 if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; } 2183 az = ms->env->auth_zones; 2184 2185 lock_rw_rdlock(&az->rpz_lock); 2186 2187 for(a = az->rpz_first; a; a = a->rpz_az_next) { 2188 lock_rw_rdlock(&a->lock); 2189 r = a->rpz; 2190 if(r->disabled) { 2191 lock_rw_unlock(&a->lock); 2192 continue; 2193 } 2194 z = rpz_find_zone(r->local_zones, is->qchase.qname, 2195 is->qchase.qname_len, is->qchase.qclass, 0, 0, 0); 2196 if(z && r->action_override == RPZ_DISABLED_ACTION) { 2197 if(r->log) 2198 log_rpz_apply("qname", z->name, NULL, 2199 r->action_override, 2200 &ms->qinfo, NULL, ms, r->log_name); 2201 if(ms->env->worker) 2202 ms->env->worker->stats.rpz_action[r->action_override]++; 2203 lock_rw_unlock(&z->lock); 2204 z = NULL; 2205 } 2206 if(z) { 2207 break; 2208 } 2209 /* not found in this auth_zone */ 2210 lock_rw_unlock(&a->lock); 2211 } 2212 lock_rw_unlock(&az->rpz_lock); 2213 2214 if(z == NULL) 2215 return NULL; 2216 if(r->action_override == RPZ_NO_OVERRIDE_ACTION) { 2217 lzt = z->type; 2218 } else { 2219 lzt = rpz_action_to_localzone_type(r->action_override); 2220 } 2221 2222 if(verbosity >= VERB_ALGO) { 2223 char nm[255+1], zn[255+1]; 2224 dname_str(is->qchase.qname, nm); 2225 dname_str(z->name, zn); 2226 if(strcmp(zn, nm) != 0) 2227 verbose(VERB_ALGO, "rpz: qname trigger after cname %s on %s, with action=%s", 2228 zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2229 else 2230 verbose(VERB_ALGO, "rpz: qname trigger after cname %s, with action=%s", 2231 nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2232 } 2233 switch(localzone_type_to_rpz_action(lzt)) { 2234 case RPZ_NXDOMAIN_ACTION: 2235 ret = rpz_synthesize_nxdomain(r, ms, &is->qchase, a); 2236 break; 2237 case RPZ_NODATA_ACTION: 2238 ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); 2239 break; 2240 case RPZ_TCP_ONLY_ACTION: 2241 /* basically a passthru here but the tcp-only will be 2242 * honored before the query gets sent. */ 2243 ms->respip_action_info->action = respip_truncate; 2244 ret = NULL; 2245 break; 2246 case RPZ_DROP_ACTION: 2247 ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); 2248 ms->is_drop = 1; 2249 break; 2250 case RPZ_LOCAL_DATA_ACTION: 2251 ret = rpz_synthesize_qname_localdata_msg(r, ms, &is->qchase, z, a); 2252 if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); } 2253 break; 2254 case RPZ_PASSTHRU_ACTION: 2255 ret = NULL; 2256 break; 2257 default: 2258 verbose(VERB_ALGO, "rpz: qname trigger after cname: bug: unhandled or invalid action: '%s'", 2259 rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2260 ret = NULL; 2261 } 2262 lock_rw_unlock(&z->lock); 2263 lock_rw_unlock(&a->lock); 2264 return ret; 2265 } 2266 2267 static int 2268 rpz_apply_maybe_clientip_trigger(struct auth_zones* az, struct module_env* env, 2269 struct query_info* qinfo, struct edns_data* edns, struct comm_reply* repinfo, 2270 uint8_t* taglist, size_t taglen, struct ub_server_stats* stats, 2271 sldns_buffer* buf, struct regional* temp, 2272 /* output parameters */ 2273 struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out) 2274 { 2275 int ret = 0; 2276 enum rpz_action client_action; 2277 struct clientip_synthesized_rr* node = rpz_resolve_client_action_and_zone( 2278 az, qinfo, repinfo, taglist, taglen, stats, z_out, a_out, r_out); 2279 2280 client_action = ((node == NULL) ? RPZ_INVALID_ACTION : node->action); 2281 2282 if(*z_out == NULL || (client_action != RPZ_INVALID_ACTION && 2283 client_action != RPZ_PASSTHRU_ACTION)) { 2284 if(client_action == RPZ_PASSTHRU_ACTION 2285 || client_action == RPZ_INVALID_ACTION 2286 || (client_action == RPZ_TCP_ONLY_ACTION 2287 && !rpz_is_udp_query(repinfo))) { 2288 ret = 0; 2289 goto done; 2290 } 2291 stats->rpz_action[client_action]++; 2292 if(client_action == RPZ_LOCAL_DATA_ACTION) { 2293 rpz_apply_clientip_localdata_action(node, env, qinfo, 2294 edns, repinfo, buf, temp, *a_out); 2295 } else { 2296 if(*r_out && (*r_out)->log) 2297 log_rpz_apply( 2298 (node?"clientip":"qname"), 2299 ((*z_out)?(*z_out)->name:NULL), 2300 (node?&node->node:NULL), 2301 client_action, qinfo, repinfo, NULL, 2302 (*r_out)->log_name); 2303 local_zones_zone_answer(*z_out /*likely NULL, no zone*/, env, qinfo, edns, 2304 repinfo, buf, temp, 0 /* no local data used */, 2305 rpz_action_to_localzone_type(client_action)); 2306 if(*r_out && (*r_out)->signal_nxdomain_ra && 2307 LDNS_RCODE_WIRE(sldns_buffer_begin(buf)) 2308 == LDNS_RCODE_NXDOMAIN) 2309 LDNS_RA_CLR(sldns_buffer_begin(buf)); 2310 } 2311 ret = 1; 2312 goto done; 2313 } 2314 ret = -1; 2315 done: 2316 if(node != NULL) { 2317 lock_rw_unlock(&node->lock); 2318 } 2319 return ret; 2320 } 2321 2322 int 2323 rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env, 2324 struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf, 2325 struct regional* temp, struct comm_reply* repinfo, uint8_t* taglist, 2326 size_t taglen, struct ub_server_stats* stats) 2327 { 2328 struct rpz* r = NULL; 2329 struct auth_zone* a = NULL; 2330 struct local_zone* z = NULL; 2331 int ret; 2332 enum localzone_type lzt; 2333 2334 int clientip_trigger = rpz_apply_maybe_clientip_trigger(az, env, qinfo, 2335 edns, repinfo, taglist, taglen, stats, buf, temp, &z, &a, &r); 2336 if(clientip_trigger >= 0) { 2337 if(a) { 2338 lock_rw_unlock(&a->lock); 2339 } 2340 if(z) { 2341 lock_rw_unlock(&z->lock); 2342 } 2343 return clientip_trigger; 2344 } 2345 2346 if(z == NULL) { 2347 if(a) { 2348 lock_rw_unlock(&a->lock); 2349 } 2350 return 0; 2351 } 2352 2353 log_assert(r); 2354 2355 if(r->action_override == RPZ_NO_OVERRIDE_ACTION) { 2356 lzt = z->type; 2357 } else { 2358 lzt = rpz_action_to_localzone_type(r->action_override); 2359 } 2360 2361 if(verbosity >= VERB_ALGO) { 2362 char nm[255+1], zn[255+1]; 2363 dname_str(qinfo->qname, nm); 2364 dname_str(z->name, zn); 2365 if(strcmp(zn, nm) != 0) 2366 verbose(VERB_ALGO, "rpz: qname trigger %s on %s with action=%s", 2367 zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2368 else 2369 verbose(VERB_ALGO, "rpz: qname trigger %s with action=%s", 2370 nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt))); 2371 } 2372 2373 ret = rpz_synthesize_qname_localdata(env, r, z, lzt, qinfo, edns, buf, temp, 2374 repinfo, stats); 2375 2376 lock_rw_unlock(&z->lock); 2377 lock_rw_unlock(&a->lock); 2378 2379 return ret; 2380 } 2381 2382 void rpz_enable(struct rpz* r) 2383 { 2384 if(!r) 2385 return; 2386 r->disabled = 0; 2387 } 2388 2389 void rpz_disable(struct rpz* r) 2390 { 2391 if(!r) 2392 return; 2393 r->disabled = 1; 2394 } 2395