1 /* 2 * difffile.c - DIFF file handling source code. Read and write diff files. 3 * 4 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. 5 * 6 * See LICENSE for the license. 7 * 8 */ 9 10 #include "config.h" 11 #include <assert.h> 12 #include <string.h> 13 #include <unistd.h> 14 #include <stdlib.h> 15 #include <errno.h> 16 #include "difffile.h" 17 #include "xfrd-disk.h" 18 #include "util.h" 19 #include "packet.h" 20 #include "rdata.h" 21 #include "udb.h" 22 #include "udbzone.h" 23 #include "nsec3.h" 24 #include "nsd.h" 25 #include "rrl.h" 26 #include "ixfr.h" 27 #include "zonec.h" 28 29 static int 30 write_64(FILE *out, uint64_t val) 31 { 32 return write_data(out, &val, sizeof(val)); 33 } 34 35 static int 36 write_32(FILE *out, uint32_t val) 37 { 38 val = htonl(val); 39 return write_data(out, &val, sizeof(val)); 40 } 41 42 static int 43 write_8(FILE *out, uint8_t val) 44 { 45 return write_data(out, &val, sizeof(val)); 46 } 47 48 static int 49 write_str(FILE *out, const char* str) 50 { 51 uint32_t len = strlen(str); 52 if(!write_32(out, len)) 53 return 0; 54 return write_data(out, str, len); 55 } 56 57 void 58 diff_write_packet(const char* zone, const char* pat, uint32_t old_serial, 59 uint32_t new_serial, uint32_t seq_nr, uint8_t* data, size_t len, 60 struct nsd* nsd, uint64_t filenumber) 61 { 62 FILE* df = xfrd_open_xfrfile(nsd, filenumber, seq_nr?"a":"w"); 63 if(!df) { 64 log_msg(LOG_ERR, "could not open transfer %s file %lld: %s", 65 zone, (long long)filenumber, strerror(errno)); 66 return; 67 } 68 69 /* if first part, first write the header */ 70 if(seq_nr == 0) { 71 struct timeval tv; 72 if (gettimeofday(&tv, NULL) != 0) { 73 log_msg(LOG_ERR, "could not get timestamp for %s: %s", 74 zone, strerror(errno)); 75 } 76 if(!write_32(df, DIFF_PART_XFRF) || 77 !write_8(df, 0) /* notcommitted(yet) */ || 78 !write_32(df, 0) /* numberofparts when done */ || 79 !write_64(df, (uint64_t) tv.tv_sec) || 80 !write_32(df, (uint32_t) tv.tv_usec) || 81 !write_32(df, old_serial) || 82 !write_32(df, new_serial) || 83 !write_64(df, (uint64_t) tv.tv_sec) || 84 !write_32(df, (uint32_t) tv.tv_usec) || 85 !write_str(df, zone) || 86 !write_str(df, pat)) { 87 log_msg(LOG_ERR, "could not write transfer %s file %lld: %s", 88 zone, (long long)filenumber, strerror(errno)); 89 fclose(df); 90 return; 91 } 92 } 93 94 if(!write_32(df, DIFF_PART_XXFR) || 95 !write_32(df, len) || 96 !write_data(df, data, len) || 97 !write_32(df, len)) 98 { 99 log_msg(LOG_ERR, "could not write transfer %s file %lld: %s", 100 zone, (long long)filenumber, strerror(errno)); 101 } 102 fclose(df); 103 } 104 105 void 106 diff_write_commit(const char* zone, uint32_t old_serial, uint32_t new_serial, 107 uint32_t num_parts, uint8_t commit, const char* log_str, 108 struct nsd* nsd, uint64_t filenumber) 109 { 110 struct timeval tv; 111 FILE* df; 112 113 if (gettimeofday(&tv, NULL) != 0) { 114 log_msg(LOG_ERR, "could not set timestamp for %s: %s", 115 zone, strerror(errno)); 116 } 117 118 /* overwrite the first part of the file with 'committed = 1', 119 * as well as the end_time and number of parts. 120 * also write old_serial and new_serial, so that a bad file mixup 121 * will result in unusable serial numbers. */ 122 123 df = xfrd_open_xfrfile(nsd, filenumber, "r+"); 124 if(!df) { 125 log_msg(LOG_ERR, "could not open transfer %s file %lld: %s", 126 zone, (long long)filenumber, strerror(errno)); 127 return; 128 } 129 if(!write_32(df, DIFF_PART_XFRF) || 130 !write_8(df, commit) /* committed */ || 131 !write_32(df, num_parts) || 132 !write_64(df, (uint64_t) tv.tv_sec) || 133 !write_32(df, (uint32_t) tv.tv_usec) || 134 !write_32(df, old_serial) || 135 !write_32(df, new_serial)) 136 { 137 log_msg(LOG_ERR, "could not write transfer %s file %lld: %s", 138 zone, (long long)filenumber, strerror(errno)); 139 fclose(df); 140 return; 141 } 142 143 /* append the log_str to the end of the file */ 144 if(fseek(df, 0, SEEK_END) == -1) { 145 log_msg(LOG_ERR, "could not fseek transfer %s file %lld: %s", 146 zone, (long long)filenumber, strerror(errno)); 147 fclose(df); 148 return; 149 } 150 if(!write_str(df, log_str)) { 151 log_msg(LOG_ERR, "could not write transfer %s file %lld: %s", 152 zone, (long long)filenumber, strerror(errno)); 153 fclose(df); 154 return; 155 156 } 157 fflush(df); 158 fclose(df); 159 } 160 161 void 162 diff_update_commit( 163 const char* zone, uint8_t commit, struct nsd* nsd, uint64_t filenumber) 164 { 165 FILE *df; 166 167 assert(zone != NULL); 168 assert(nsd != NULL); 169 assert(commit == DIFF_NOT_COMMITTED || 170 commit == DIFF_COMMITTED || 171 commit == DIFF_CORRUPT || 172 commit == DIFF_INCONSISTENT || 173 commit == DIFF_VERIFIED); 174 175 df = xfrd_open_xfrfile(nsd, filenumber, "r+"); 176 if(!df) { 177 log_msg(LOG_ERR, "could not open transfer %s file %lld: %s", 178 zone, (long long)filenumber, strerror(errno)); 179 return; 180 } 181 if(!write_32(df, DIFF_PART_XFRF) || !write_8(df, commit)) { 182 log_msg(LOG_ERR, "could not write transfer %s file %lld: %s", 183 zone, (long long)filenumber, strerror(errno)); 184 fclose(df); 185 return; 186 } 187 fflush(df); 188 fclose(df); 189 } 190 191 int 192 diff_read_64(FILE *in, uint64_t* result) 193 { 194 if (fread(result, sizeof(*result), 1, in) == 1) { 195 return 1; 196 } else { 197 return 0; 198 } 199 } 200 201 int 202 diff_read_32(FILE *in, uint32_t* result) 203 { 204 if (fread(result, sizeof(*result), 1, in) == 1) { 205 *result = ntohl(*result); 206 return 1; 207 } else { 208 return 0; 209 } 210 } 211 212 int 213 diff_read_8(FILE *in, uint8_t* result) 214 { 215 if (fread(result, sizeof(*result), 1, in) == 1) { 216 return 1; 217 } else { 218 return 0; 219 } 220 } 221 222 int 223 diff_read_str(FILE* in, char* buf, size_t len) 224 { 225 uint32_t disklen; 226 if(!diff_read_32(in, &disklen)) 227 return 0; 228 if(disklen >= len) 229 return 0; 230 if(fread(buf, disklen, 1, in) != 1) 231 return 0; 232 buf[disklen] = 0; 233 return 1; 234 } 235 236 static void 237 add_rdata_to_recyclebin(namedb_type* db, rr_type* rr) 238 { 239 /* add rdatas to recycle bin. */ 240 size_t i; 241 for(i=0; i<rr->rdata_count; i++) 242 { 243 if(!rdata_atom_is_domain(rr->type, i)) 244 region_recycle(db->region, rr->rdatas[i].data, 245 rdata_atom_size(rr->rdatas[i]) 246 + sizeof(uint16_t)); 247 } 248 region_recycle(db->region, rr->rdatas, 249 sizeof(rdata_atom_type)*rr->rdata_count); 250 } 251 252 /* this routine determines if below a domain there exist names with 253 * data (is_existing) or no names below the domain have data. 254 */ 255 static int 256 has_data_below(domain_type* top) 257 { 258 domain_type* d = top; 259 assert(d != NULL); 260 /* in the canonical ordering subdomains are after this name */ 261 d = domain_next(d); 262 while(d != NULL && domain_is_subdomain(d, top)) { 263 if(d->is_existing) 264 return 1; 265 d = domain_next(d); 266 } 267 return 0; 268 } 269 270 /** check if domain with 0 rrsets has become empty (nonexist) */ 271 static domain_type* 272 rrset_zero_nonexist_check(domain_type* domain, domain_type* ce) 273 { 274 /* is the node now an empty node (completely deleted) */ 275 if(domain->rrsets == 0) { 276 /* if there is no data below it, it becomes non existing. 277 also empty nonterminals above it become nonexisting */ 278 /* check for data below this node. */ 279 if(!has_data_below(domain)) { 280 /* nonexist this domain and all parent empty nonterminals */ 281 domain_type* p = domain; 282 while(p != NULL && p->rrsets == 0) { 283 if(p == ce || has_data_below(p)) 284 return p; 285 p->is_existing = 0; 286 /* fixup wildcard child of parent */ 287 if(p->parent && 288 p->parent->wildcard_child_closest_match == p) 289 p->parent->wildcard_child_closest_match = domain_previous_existing_child(p); 290 p = p->parent; 291 } 292 } 293 } 294 return NULL; 295 } 296 297 /** remove rrset. Adjusts zone params. Does not remove domain */ 298 static void 299 rrset_delete(namedb_type* db, domain_type* domain, rrset_type* rrset) 300 { 301 int i; 302 /* find previous */ 303 rrset_type** pp = &domain->rrsets; 304 while(*pp && *pp != rrset) { 305 pp = &( (*pp)->next ); 306 } 307 if(!*pp) { 308 /* rrset does not exist for domain */ 309 return; 310 } 311 *pp = rrset->next; 312 313 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "delete rrset of %s type %s", 314 domain_to_string(domain), 315 rrtype_to_string(rrset_rrtype(rrset)))); 316 317 /* is this a SOA rrset ? */ 318 if(rrset->zone->soa_rrset == rrset) { 319 rrset->zone->soa_rrset = 0; 320 } 321 if(rrset->zone->ns_rrset == rrset) { 322 rrset->zone->ns_rrset = 0; 323 } 324 if(domain == rrset->zone->apex && rrset_rrtype(rrset) == TYPE_RRSIG) { 325 for (i = 0; i < rrset->rr_count; ++i) { 326 if(rr_rrsig_type_covered(&rrset->rrs[i])==TYPE_DNSKEY) { 327 rrset->zone->is_secure = 0; 328 break; 329 } 330 } 331 } 332 /* recycle the memory space of the rrset */ 333 for (i = 0; i < rrset->rr_count; ++i) 334 add_rdata_to_recyclebin(db, &rrset->rrs[i]); 335 region_recycle(db->region, rrset->rrs, 336 sizeof(rr_type) * rrset->rr_count); 337 rrset->rr_count = 0; 338 region_recycle(db->region, rrset, sizeof(rrset_type)); 339 } 340 341 static int 342 rdatas_equal(rdata_atom_type *a, rdata_atom_type *b, int num, uint16_t type, 343 int* rdnum, char** reason) 344 { 345 int k, start, end; 346 start = 0; 347 end = num; 348 /** 349 * SOA RDATA comparisons in XFR are more lenient, 350 * only serial rdata is checked. 351 **/ 352 if (type == TYPE_SOA) { 353 start = 2; 354 end = 3; 355 } 356 for(k = start; k < end; k++) 357 { 358 if(rdata_atom_is_domain(type, k)) { 359 if(dname_compare(domain_dname(a[k].domain), 360 domain_dname(b[k].domain))!=0) { 361 *rdnum = k; 362 *reason = "dname data"; 363 return 0; 364 } 365 } else if(rdata_atom_is_literal_domain(type, k)) { 366 /* literal dname, but compare case insensitive */ 367 if(a[k].data[0] != b[k].data[0]) { 368 *rdnum = k; 369 *reason = "literal dname len"; 370 return 0; /* uncompressed len must be equal*/ 371 } 372 if(!dname_equal_nocase((uint8_t*)(a[k].data+1), 373 (uint8_t*)(b[k].data+1), a[k].data[0])) { 374 *rdnum = k; 375 *reason = "literal dname data"; 376 return 0; 377 } 378 } else { 379 /* check length */ 380 if(a[k].data[0] != b[k].data[0]) { 381 *rdnum = k; 382 *reason = "rdata len"; 383 return 0; 384 } 385 /* check data */ 386 if(memcmp(a[k].data+1, b[k].data+1, a[k].data[0])!=0) { 387 *rdnum = k; 388 *reason = "rdata data"; 389 return 0; 390 } 391 } 392 } 393 return 1; 394 } 395 396 static void 397 debug_find_rr_num(rrset_type* rrset, uint16_t type, uint16_t klass, 398 rdata_atom_type *rdatas, ssize_t rdata_num) 399 { 400 int i, rd; 401 char* reason = ""; 402 403 for(i=0; i < rrset->rr_count; ++i) { 404 if (rrset->rrs[i].type != type) { 405 log_msg(LOG_WARNING, "diff: RR <%s, %s> does not match " 406 "RR num %d type %s", 407 dname_to_string(domain_dname(rrset->rrs[i].owner),0), 408 rrtype_to_string(type), i, 409 rrtype_to_string(rrset->rrs[i].type)); 410 } 411 if (rrset->rrs[i].klass != klass) { 412 log_msg(LOG_WARNING, "diff: RR <%s, %s> class %d " 413 "does not match RR num %d class %d", 414 dname_to_string(domain_dname(rrset->rrs[i].owner),0), 415 rrtype_to_string(type), 416 klass, i, 417 rrset->rrs[i].klass); 418 } 419 if (rrset->rrs[i].rdata_count != rdata_num) { 420 log_msg(LOG_WARNING, "diff: RR <%s, %s> rdlen %u " 421 "does not match RR num %d rdlen %d", 422 dname_to_string(domain_dname(rrset->rrs[i].owner),0), 423 rrtype_to_string(type), 424 (unsigned) rdata_num, i, 425 (unsigned) rrset->rrs[i].rdata_count); 426 } 427 if (!rdatas_equal(rdatas, rrset->rrs[i].rdatas, rdata_num, type, 428 &rd, &reason)) { 429 log_msg(LOG_WARNING, "diff: RR <%s, %s> rdata element " 430 "%d differs from RR num %d rdata (%s)", 431 dname_to_string(domain_dname(rrset->rrs[i].owner),0), 432 rrtype_to_string(type), 433 rd, i, reason); 434 } 435 } 436 } 437 438 static int 439 find_rr_num(rrset_type* rrset, uint16_t type, uint16_t klass, 440 rdata_atom_type *rdatas, ssize_t rdata_num, int add) 441 { 442 int i, rd; 443 char* reason; 444 445 for(i=0; i < rrset->rr_count; ++i) { 446 if(rrset->rrs[i].type == type && 447 rrset->rrs[i].klass == klass && 448 rrset->rrs[i].rdata_count == rdata_num && 449 rdatas_equal(rdatas, rrset->rrs[i].rdatas, rdata_num, type, 450 &rd, &reason)) 451 { 452 return i; 453 } 454 } 455 /* this is odd. Log why rr cannot be found. */ 456 if (!add) { 457 debug_find_rr_num(rrset, type, klass, rdatas, rdata_num); 458 } 459 return -1; 460 } 461 462 #ifdef NSEC3 463 /* see if nsec3 deletion triggers need action */ 464 static void 465 nsec3_delete_rr_trigger(namedb_type* db, rr_type* rr, zone_type* zone, 466 udb_ptr* udbz) 467 { 468 /* the RR has not actually been deleted yet, so we can inspect it */ 469 if(!zone->nsec3_param) 470 return; 471 /* see if the domain was an NSEC3-domain in the chain, but no longer */ 472 if(rr->type == TYPE_NSEC3 && rr->owner->nsec3 && 473 rr->owner->nsec3->nsec3_node.key && 474 nsec3_rr_uses_params(rr, zone) && 475 nsec3_in_chain_count(rr->owner, zone) <= 1) { 476 domain_type* prev = nsec3_chain_find_prev(zone, rr->owner); 477 /* remove from prehash because no longer an NSEC3 domain */ 478 if(domain_is_prehash(db->domains, rr->owner)) 479 prehash_del(db->domains, rr->owner); 480 /* fixup the last in the zone */ 481 if(rr->owner == zone->nsec3_last) 482 zone->nsec3_last = prev; 483 /* unlink from the nsec3tree */ 484 zone_del_domain_in_hash_tree(zone->nsec3tree, 485 &rr->owner->nsec3->nsec3_node); 486 /* add previous NSEC3 to the prehash list */ 487 if(prev && prev != rr->owner) 488 prehash_add(db->domains, prev); 489 else nsec3_clear_precompile(db, zone); 490 /* this domain becomes ordinary data domain: done later */ 491 } 492 /* see if the rr was NSEC3PARAM that we were using */ 493 else if(rr->type == TYPE_NSEC3PARAM && rr == zone->nsec3_param) { 494 /* clear trees, wipe hashes, wipe precompile */ 495 nsec3_clear_precompile(db, zone); 496 /* pick up new nsec3param (from udb, or avoid deleted rr) */ 497 nsec3_find_zone_param(db, zone, udbz, rr, 0); 498 /* if no more NSEC3, done */ 499 if(!zone->nsec3_param) 500 return; 501 nsec3_precompile_newparam(db, zone); 502 } 503 } 504 505 /* see if nsec3 prehash can be removed with new rrset content */ 506 static void 507 nsec3_rrsets_changed_remove_prehash(domain_type* domain, zone_type* zone) 508 { 509 /* deletion of rrset already done, we can check if conditions apply */ 510 /* see if the domain is no longer precompiled */ 511 /* it has a hash_node, but no longer fulfills conditions */ 512 if(nsec3_domain_part_of_zone(domain, zone) && domain->nsec3 && 513 domain->nsec3->hash_wc && 514 domain->nsec3->hash_wc->hash.node.key && 515 !nsec3_condition_hash(domain, zone)) { 516 /* remove precompile */ 517 domain->nsec3->nsec3_cover = NULL; 518 domain->nsec3->nsec3_wcard_child_cover = NULL; 519 domain->nsec3->nsec3_is_exact = 0; 520 /* remove it from the hash tree */ 521 zone_del_domain_in_hash_tree(zone->hashtree, 522 &domain->nsec3->hash_wc->hash.node); 523 zone_del_domain_in_hash_tree(zone->wchashtree, 524 &domain->nsec3->hash_wc->wc.node); 525 } 526 if(domain != zone->apex && domain->nsec3 && 527 domain->nsec3->ds_parent_hash && 528 domain->nsec3->ds_parent_hash->node.key && 529 (!domain->parent || nsec3_domain_part_of_zone(domain->parent, zone)) && 530 !nsec3_condition_dshash(domain, zone)) { 531 /* remove precompile */ 532 domain->nsec3->nsec3_ds_parent_cover = NULL; 533 domain->nsec3->nsec3_ds_parent_is_exact = 0; 534 /* remove it from the hash tree */ 535 zone_del_domain_in_hash_tree(zone->dshashtree, 536 &domain->nsec3->ds_parent_hash->node); 537 } 538 } 539 540 /* see if domain needs to get precompiled info */ 541 static void 542 nsec3_rrsets_changed_add_prehash(namedb_type* db, domain_type* domain, 543 zone_type* zone) 544 { 545 if(!zone->nsec3_param) 546 return; 547 if((!domain->nsec3 || !domain->nsec3->hash_wc 548 || !domain->nsec3->hash_wc->hash.node.key) 549 && nsec3_condition_hash(domain, zone)) { 550 region_type* tmpregion = region_create(xalloc, free); 551 nsec3_precompile_domain(db, domain, zone, tmpregion); 552 region_destroy(tmpregion); 553 } 554 if((!domain->nsec3 || !domain->nsec3->ds_parent_hash 555 || !domain->nsec3->ds_parent_hash->node.key) 556 && nsec3_condition_dshash(domain, zone)) { 557 nsec3_precompile_domain_ds(db, domain, zone); 558 } 559 } 560 561 /* see if nsec3 rrset-deletion triggers need action */ 562 static void 563 nsec3_delete_rrset_trigger(namedb_type* db, domain_type* domain, 564 zone_type* zone, uint16_t type) 565 { 566 if(!zone->nsec3_param) 567 return; 568 nsec3_rrsets_changed_remove_prehash(domain, zone); 569 /* for type nsec3, or a delegation, the domain may have become a 570 * 'normal' domain with its remaining data now */ 571 if(type == TYPE_NSEC3 || type == TYPE_NS || type == TYPE_DS) 572 nsec3_rrsets_changed_add_prehash(db, domain, zone); 573 /* for type DNAME or a delegation, obscured data may be revealed */ 574 if(type == TYPE_NS || type == TYPE_DS || type == TYPE_DNAME) { 575 /* walk over subdomains and check them each */ 576 domain_type *d; 577 for(d=domain_next(domain); d && domain_is_subdomain(d, domain); 578 d=domain_next(d)) { 579 nsec3_rrsets_changed_add_prehash(db, d, zone); 580 } 581 } 582 } 583 584 /* see if nsec3 addition triggers need action */ 585 static void 586 nsec3_add_rr_trigger(namedb_type* db, rr_type* rr, zone_type* zone, 587 udb_ptr* udbz) 588 { 589 /* the RR has been added in full, also to UDB (and thus NSEC3PARAM 590 * in the udb has been adjusted) */ 591 if(zone->nsec3_param && rr->type == TYPE_NSEC3 && 592 (!rr->owner->nsec3 || !rr->owner->nsec3->nsec3_node.key) 593 && nsec3_rr_uses_params(rr, zone)) { 594 if(!zone->nsec3_last) { 595 /* all nsec3s have previously been deleted, but 596 * we have nsec3 parameters, set it up again from 597 * being cleared. */ 598 nsec3_precompile_newparam(db, zone); 599 } 600 /* added NSEC3 into the chain */ 601 nsec3_precompile_nsec3rr(db, rr->owner, zone); 602 /* the domain has become an NSEC3-domain, if it was precompiled 603 * previously, remove that, neatly done in routine above */ 604 nsec3_rrsets_changed_remove_prehash(rr->owner, zone); 605 /* set this NSEC3 to prehash */ 606 prehash_add(db->domains, rr->owner); 607 } else if(!zone->nsec3_param && rr->type == TYPE_NSEC3PARAM) { 608 /* see if this means NSEC3 chain can be used */ 609 nsec3_find_zone_param(db, zone, udbz, NULL, 0); 610 if(!zone->nsec3_param) 611 return; 612 nsec3_zone_trees_create(db->region, zone); 613 nsec3_precompile_newparam(db, zone); 614 } 615 } 616 617 /* see if nsec3 rrset-addition triggers need action */ 618 static void 619 nsec3_add_rrset_trigger(namedb_type* db, domain_type* domain, zone_type* zone, 620 uint16_t type) 621 { 622 /* the rrset has been added so we can inspect it */ 623 if(!zone->nsec3_param) 624 return; 625 /* because the rrset is added we can check conditions easily. 626 * check if domain needs to become precompiled now */ 627 nsec3_rrsets_changed_add_prehash(db, domain, zone); 628 /* if a delegation, it changes from normal name to unhashed referral */ 629 if(type == TYPE_NS || type == TYPE_DS) { 630 nsec3_rrsets_changed_remove_prehash(domain, zone); 631 } 632 /* if delegation or DNAME added, then some RRs may get obscured */ 633 if(type == TYPE_NS || type == TYPE_DS || type == TYPE_DNAME) { 634 /* walk over subdomains and check them each */ 635 domain_type *d; 636 for(d=domain_next(domain); d && domain_is_subdomain(d, domain); 637 d=domain_next(d)) { 638 nsec3_rrsets_changed_remove_prehash(d, zone); 639 } 640 } 641 } 642 #endif /* NSEC3 */ 643 644 /* fixup usage lower for domain names in the rdata */ 645 static void 646 rr_lower_usage(namedb_type* db, rr_type* rr) 647 { 648 unsigned i; 649 for(i=0; i<rr->rdata_count; i++) { 650 if(rdata_atom_is_domain(rr->type, i)) { 651 assert(rdata_atom_domain(rr->rdatas[i])->usage > 0); 652 rdata_atom_domain(rr->rdatas[i])->usage --; 653 if(rdata_atom_domain(rr->rdatas[i])->usage == 0) 654 domain_table_deldomain(db, 655 rdata_atom_domain(rr->rdatas[i])); 656 } 657 } 658 } 659 660 static void 661 rrset_lower_usage(namedb_type* db, rrset_type* rrset) 662 { 663 unsigned i; 664 for(i=0; i<rrset->rr_count; i++) 665 rr_lower_usage(db, &rrset->rrs[i]); 666 } 667 668 int 669 delete_RR(namedb_type* db, const dname_type* dname, 670 uint16_t type, uint16_t klass, 671 buffer_type* packet, size_t rdatalen, zone_type *zone, 672 region_type* temp_region, udb_ptr* udbz, int* softfail) 673 { 674 domain_type *domain; 675 rrset_type *rrset; 676 domain = domain_table_find(db->domains, dname); 677 if(!domain) { 678 log_msg(LOG_WARNING, "diff: domain %s does not exist", 679 dname_to_string(dname,0)); 680 buffer_skip(packet, rdatalen); 681 *softfail = 1; 682 return 1; /* not fatal error */ 683 } 684 rrset = domain_find_rrset(domain, zone, type); 685 if(!rrset) { 686 log_msg(LOG_WARNING, "diff: rrset %s does not exist", 687 dname_to_string(dname,0)); 688 buffer_skip(packet, rdatalen); 689 *softfail = 1; 690 return 1; /* not fatal error */ 691 } else { 692 /* find the RR in the rrset */ 693 domain_table_type *temptable; 694 rdata_atom_type *rdatas; 695 ssize_t rdata_num; 696 int rrnum; 697 temptable = domain_table_create(temp_region); 698 /* This will ensure that the dnames in rdata are 699 * normalized, conform RFC 4035, section 6.2 700 */ 701 rdata_num = rdata_wireformat_to_rdata_atoms( 702 temp_region, temptable, type, rdatalen, packet, &rdatas); 703 if(rdata_num == -1) { 704 log_msg(LOG_ERR, "diff: bad rdata for %s", 705 dname_to_string(dname,0)); 706 return 0; 707 } 708 rrnum = find_rr_num(rrset, type, klass, rdatas, rdata_num, 0); 709 if(rrnum == -1 && type == TYPE_SOA && domain == zone->apex 710 && rrset->rr_count != 0) 711 rrnum = 0; /* replace existing SOA if no match */ 712 if(rrnum == -1) { 713 log_msg(LOG_WARNING, "diff: RR <%s, %s> does not exist", 714 dname_to_string(dname,0), rrtype_to_string(type)); 715 *softfail = 1; 716 return 1; /* not fatal error */ 717 } 718 /* delete the normalized RR from the udb */ 719 if(db->udb) 720 udb_del_rr(db->udb, udbz, &rrset->rrs[rrnum]); 721 #ifdef NSEC3 722 /* process triggers for RR deletions */ 723 nsec3_delete_rr_trigger(db, &rrset->rrs[rrnum], zone, udbz); 724 #endif 725 /* lower usage (possibly deleting other domains, and thus 726 * invalidating the current RR's domain pointers) */ 727 rr_lower_usage(db, &rrset->rrs[rrnum]); 728 if(rrset->rr_count == 1) { 729 /* delete entire rrset */ 730 rrset_delete(db, domain, rrset); 731 /* check if domain is now nonexisting (or parents) */ 732 rrset_zero_nonexist_check(domain, NULL); 733 #ifdef NSEC3 734 /* cleanup nsec3 */ 735 nsec3_delete_rrset_trigger(db, domain, zone, type); 736 #endif 737 /* see if the domain can be deleted (and inspect parents) */ 738 domain_table_deldomain(db, domain); 739 } else { 740 /* swap out the bad RR and decrease the count */ 741 rr_type* rrs_orig = rrset->rrs; 742 add_rdata_to_recyclebin(db, &rrset->rrs[rrnum]); 743 if(rrnum < rrset->rr_count-1) 744 rrset->rrs[rrnum] = rrset->rrs[rrset->rr_count-1]; 745 memset(&rrset->rrs[rrset->rr_count-1], 0, sizeof(rr_type)); 746 /* realloc the rrs array one smaller */ 747 rrset->rrs = region_alloc_array_init(db->region, rrs_orig, 748 (rrset->rr_count-1), sizeof(rr_type)); 749 if(!rrset->rrs) { 750 log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__); 751 exit(1); 752 } 753 region_recycle(db->region, rrs_orig, 754 sizeof(rr_type) * rrset->rr_count); 755 #ifdef NSEC3 756 if(type == TYPE_NSEC3PARAM && zone->nsec3_param) { 757 /* fixup nsec3_param pointer to same RR */ 758 assert(zone->nsec3_param >= rrs_orig && 759 zone->nsec3_param <= 760 rrs_orig+rrset->rr_count); 761 /* last moved to rrnum, others at same index*/ 762 if(zone->nsec3_param == &rrs_orig[ 763 rrset->rr_count-1]) 764 zone->nsec3_param = &rrset->rrs[rrnum]; 765 else 766 zone->nsec3_param = 767 (void*)zone->nsec3_param 768 -(void*)rrs_orig + 769 (void*)rrset->rrs; 770 } 771 #endif /* NSEC3 */ 772 rrset->rr_count --; 773 #ifdef NSEC3 774 /* for type nsec3, the domain may have become a 775 * 'normal' domain with its remaining data now */ 776 if(type == TYPE_NSEC3) 777 nsec3_rrsets_changed_add_prehash(db, domain, 778 zone); 779 #endif /* NSEC3 */ 780 } 781 } 782 return 1; 783 } 784 785 int 786 add_RR(namedb_type* db, const dname_type* dname, 787 uint16_t type, uint16_t klass, uint32_t ttl, 788 buffer_type* packet, size_t rdatalen, zone_type *zone, udb_ptr* udbz, 789 int* softfail) 790 { 791 domain_type* domain; 792 rrset_type* rrset; 793 rdata_atom_type *rdatas; 794 rr_type *rrs_old; 795 ssize_t rdata_num; 796 int rrnum; 797 #ifdef NSEC3 798 int rrset_added = 0; 799 #endif 800 domain = domain_table_find(db->domains, dname); 801 if(!domain) { 802 /* create the domain */ 803 domain = domain_table_insert(db->domains, dname); 804 } 805 rrset = domain_find_rrset(domain, zone, type); 806 if(!rrset) { 807 /* create the rrset */ 808 rrset = region_alloc(db->region, sizeof(rrset_type)); 809 if(!rrset) { 810 log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__); 811 exit(1); 812 } 813 rrset->zone = zone; 814 rrset->rrs = 0; 815 rrset->rr_count = 0; 816 domain_add_rrset(domain, rrset); 817 #ifdef NSEC3 818 rrset_added = 1; 819 #endif 820 } 821 822 /* dnames in rdata are normalized, conform RFC 4035, 823 * Section 6.2 824 */ 825 rdata_num = rdata_wireformat_to_rdata_atoms( 826 db->region, db->domains, type, rdatalen, packet, &rdatas); 827 if(rdata_num == -1) { 828 log_msg(LOG_ERR, "diff: bad rdata for %s", 829 dname_to_string(dname,0)); 830 return 0; 831 } 832 rrnum = find_rr_num(rrset, type, klass, rdatas, rdata_num, 1); 833 if(rrnum != -1) { 834 DEBUG(DEBUG_XFRD, 2, (LOG_ERR, "diff: RR <%s, %s> already exists", 835 dname_to_string(dname,0), rrtype_to_string(type))); 836 /* ignore already existing RR: lenient accepting of messages */ 837 *softfail = 1; 838 return 1; 839 } 840 if(rrset->rr_count == 65535) { 841 log_msg(LOG_ERR, "diff: too many RRs at %s", 842 dname_to_string(dname,0)); 843 return 0; 844 } 845 846 /* re-alloc the rrs and add the new */ 847 rrs_old = rrset->rrs; 848 rrset->rrs = region_alloc_array(db->region, 849 (rrset->rr_count+1), sizeof(rr_type)); 850 if(!rrset->rrs) { 851 log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__); 852 exit(1); 853 } 854 if(rrs_old) 855 memcpy(rrset->rrs, rrs_old, rrset->rr_count * sizeof(rr_type)); 856 region_recycle(db->region, rrs_old, sizeof(rr_type) * rrset->rr_count); 857 rrset->rr_count ++; 858 859 rrset->rrs[rrset->rr_count - 1].owner = domain; 860 rrset->rrs[rrset->rr_count - 1].rdatas = rdatas; 861 rrset->rrs[rrset->rr_count - 1].ttl = ttl; 862 rrset->rrs[rrset->rr_count - 1].type = type; 863 rrset->rrs[rrset->rr_count - 1].klass = klass; 864 rrset->rrs[rrset->rr_count - 1].rdata_count = rdata_num; 865 866 /* see if it is a SOA */ 867 if(domain == zone->apex) { 868 apex_rrset_checks(db, rrset, domain); 869 #ifdef NSEC3 870 if(type == TYPE_NSEC3PARAM && zone->nsec3_param) { 871 /* the pointer just changed, fix it up to point 872 * to the same record */ 873 assert(zone->nsec3_param >= rrs_old && 874 zone->nsec3_param < rrs_old+rrset->rr_count); 875 /* in this order to make sure no overflow/underflow*/ 876 zone->nsec3_param = (void*)zone->nsec3_param - 877 (void*)rrs_old + (void*)rrset->rrs; 878 } 879 #endif /* NSEC3 */ 880 } 881 882 /* write the just-normalized RR to the udb */ 883 if(db->udb) { 884 if(!udb_write_rr(db->udb, udbz, &rrset->rrs[rrset->rr_count - 1])) { 885 log_msg(LOG_ERR, "could not add RR to nsd.db, disk-space?"); 886 return 0; 887 } 888 } 889 #ifdef NSEC3 890 if(rrset_added) { 891 domain_type* p = domain->parent; 892 nsec3_add_rrset_trigger(db, domain, zone, type); 893 /* go up and process (possibly created) empty nonterminals, 894 * until we hit the apex or root */ 895 while(p && p->rrsets == NULL && !p->is_apex) { 896 nsec3_rrsets_changed_add_prehash(db, p, zone); 897 p = p->parent; 898 } 899 } 900 nsec3_add_rr_trigger(db, &rrset->rrs[rrset->rr_count - 1], zone, udbz); 901 #endif /* NSEC3 */ 902 return 1; 903 } 904 905 static zone_type* 906 find_or_create_zone(namedb_type* db, const dname_type* zone_name, 907 struct nsd_options* opt, const char* zstr, const char* patname) 908 { 909 zone_type* zone; 910 struct zone_options* zopt; 911 zone = namedb_find_zone(db, zone_name); 912 if(zone) { 913 return zone; 914 } 915 zopt = zone_options_find(opt, zone_name); 916 if(!zopt) { 917 /* if _implicit_ then insert as _part_of_config */ 918 if(strncmp(patname, PATTERN_IMPLICIT_MARKER, 919 strlen(PATTERN_IMPLICIT_MARKER)) == 0) { 920 zopt = zone_options_create(opt->region); 921 if(!zopt) return 0; 922 zopt->part_of_config = 1; 923 zopt->name = region_strdup(opt->region, zstr); 924 zopt->pattern = pattern_options_find(opt, patname); 925 if(!zopt->name || !zopt->pattern) return 0; 926 if(!nsd_options_insert_zone(opt, zopt)) { 927 log_msg(LOG_ERR, "bad domain name or duplicate zone '%s' " 928 "pattern %s", zstr, patname); 929 } 930 } else { 931 /* create zone : presumably already added to zonelist 932 * by xfrd, who wrote the AXFR or IXFR to disk, so we only 933 * need to add it to our config. 934 * This process does not need linesize and offset zonelist */ 935 zopt = zone_list_zone_insert(opt, zstr, patname, 0, 0); 936 if(!zopt) 937 return 0; 938 } 939 } 940 zone = namedb_zone_create(db, zone_name, zopt); 941 return zone; 942 } 943 944 void 945 delete_zone_rrs(namedb_type* db, zone_type* zone) 946 { 947 rrset_type *rrset; 948 domain_type *domain = zone->apex, *next; 949 int nonexist_check = 0; 950 /* go through entire tree below the zone apex (incl subzones) */ 951 while(domain && domain_is_subdomain(domain, zone->apex)) 952 { 953 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "delete zone visit %s", 954 domain_to_string(domain))); 955 /* delete all rrsets of the zone */ 956 while((rrset = domain_find_any_rrset(domain, zone))) { 957 /* lower usage can delete other domains */ 958 rrset_lower_usage(db, rrset); 959 /* rrset del does not delete our domain(yet) */ 960 rrset_delete(db, domain, rrset); 961 /* no rrset_zero_nonexist_check, do that later */ 962 if(domain->rrsets == 0) 963 nonexist_check = 1; 964 } 965 /* the delete upcoming could delete parents, but nothing next 966 * or after the domain so store next ptr */ 967 next = domain_next(domain); 968 /* see if the domain can be deleted (and inspect parents) */ 969 domain_table_deldomain(db, domain); 970 domain = next; 971 } 972 973 /* check if data deletions have created nonexisting domain entries, 974 * but after deleting domains so the checks are faster */ 975 if(nonexist_check) { 976 domain_type* ce = NULL; /* for speeding up has_data_below */ 977 DEBUG(DEBUG_XFRD, 1, (LOG_INFO, "axfrdel: zero rrset check")); 978 domain = zone->apex; 979 while(domain && domain_is_subdomain(domain, zone->apex)) 980 { 981 /* the interesting domains should be existing==1 982 * and rrsets==0, speeding up out processing of 983 * sub-zones, since we only spuriously check empty 984 * nonterminals */ 985 if(domain->is_existing) 986 ce = rrset_zero_nonexist_check(domain, ce); 987 domain = domain_next(domain); 988 } 989 } 990 991 DEBUG(DEBUG_XFRD, 1, (LOG_INFO, "axfrdel: recyclebin holds %lu bytes", 992 (unsigned long) region_get_recycle_size(db->region))); 993 #ifndef NDEBUG 994 if(nsd_debug_level >= 2) 995 region_log_stats(db->region); 996 #endif 997 998 assert(zone->soa_rrset == 0); 999 /* keep zone->soa_nx_rrset alloced: it is reused */ 1000 assert(zone->ns_rrset == 0); 1001 assert(zone->is_secure == 0); 1002 } 1003 1004 /* return value 0: syntaxerror,badIXFR, 1:OK, 2:done_and_skip_it */ 1005 static int 1006 apply_ixfr(namedb_type* db, FILE *in, const char* zone, uint32_t serialno, 1007 struct nsd_options* opt, uint32_t seq_nr, uint32_t seq_total, 1008 int* is_axfr, int* delete_mode, int* rr_count, 1009 udb_ptr* udbz, struct zone** zone_res, const char* patname, int* bytes, 1010 int* softfail, struct ixfr_store* ixfr_store) 1011 { 1012 uint32_t msglen, checklen, pkttype; 1013 int qcount, ancount, counter; 1014 buffer_type* packet; 1015 region_type* region; 1016 int i; 1017 uint16_t rrlen; 1018 const dname_type *dname_zone, *dname; 1019 zone_type* zone_db; 1020 1021 /* note that errors could not really happen due to format of the 1022 * packet since xfrd has checked all dnames and RRs before commit, 1023 * this is why the errors are fatal (exit process), it must be 1024 * something internal or a bad disk or something. */ 1025 1026 /* read ixfr packet RRs and apply to in memory db */ 1027 if(!diff_read_32(in, &pkttype) || pkttype != DIFF_PART_XXFR) { 1028 log_msg(LOG_ERR, "could not read type or wrong type"); 1029 return 0; 1030 } 1031 1032 if(!diff_read_32(in, &msglen)) { 1033 log_msg(LOG_ERR, "could not read len"); 1034 return 0; 1035 } 1036 1037 if(msglen < QHEADERSZ) { 1038 log_msg(LOG_ERR, "msg too short"); 1039 return 0; 1040 } 1041 1042 region = region_create(xalloc, free); 1043 if(!region) { 1044 log_msg(LOG_ERR, "out of memory"); 1045 return 0; 1046 } 1047 packet = buffer_create(region, QIOBUFSZ); 1048 if(msglen > QIOBUFSZ) { 1049 log_msg(LOG_ERR, "msg too long"); 1050 region_destroy(region); 1051 return 0; 1052 } 1053 buffer_clear(packet); 1054 if(fread(buffer_begin(packet), msglen, 1, in) != 1) { 1055 log_msg(LOG_ERR, "short fread: %s", strerror(errno)); 1056 region_destroy(region); 1057 return 0; 1058 } 1059 buffer_set_limit(packet, msglen); 1060 1061 /* see if check on data fails: checks that we are not reading 1062 * random garbage */ 1063 if(!diff_read_32(in, &checklen) || checklen != msglen) { 1064 log_msg(LOG_ERR, "transfer part has incorrect checkvalue"); 1065 return 0; 1066 } 1067 *bytes += msglen; 1068 1069 dname_zone = dname_parse(region, zone); 1070 zone_db = find_or_create_zone(db, dname_zone, opt, zone, patname); 1071 if(!zone_db) { 1072 log_msg(LOG_ERR, "could not create zone %s %s", zone, patname); 1073 region_destroy(region); 1074 return 0; 1075 } 1076 *zone_res = zone_db; 1077 1078 /* only answer section is really used, question, additional and 1079 authority section RRs are skipped */ 1080 qcount = QDCOUNT(packet); 1081 ancount = ANCOUNT(packet); 1082 buffer_skip(packet, QHEADERSZ); 1083 /* qcount should be 0 or 1 really, ancount limited by 64k packet */ 1084 if(qcount > 64 || ancount > 65530) { 1085 log_msg(LOG_ERR, "RR count impossibly high"); 1086 region_destroy(region); 1087 return 0; 1088 } 1089 1090 /* skip queries */ 1091 for(i=0; i<qcount; ++i) 1092 if(!packet_skip_rr(packet, 1)) { 1093 log_msg(LOG_ERR, "bad RR in question section"); 1094 region_destroy(region); 1095 return 0; 1096 } 1097 1098 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "diff: started packet for zone %s", 1099 dname_to_string(dname_zone, 0))); 1100 /* first RR: check if SOA and correct zone & serialno */ 1101 if(*rr_count == 0) { 1102 size_t ttlpos; 1103 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "diff: %s parse first RR", 1104 dname_to_string(dname_zone, 0))); 1105 dname = dname_make_from_packet(region, packet, 1, 1); 1106 if(!dname) { 1107 log_msg(LOG_ERR, "could not parse dname"); 1108 region_destroy(region); 1109 return 0; 1110 } 1111 if(dname_compare(dname_zone, dname) != 0) { 1112 log_msg(LOG_ERR, "SOA dname %s not equal to zone", 1113 dname_to_string(dname,0)); 1114 log_msg(LOG_ERR, "zone dname is %s", 1115 dname_to_string(dname_zone,0)); 1116 region_destroy(region); 1117 return 0; 1118 } 1119 if(!buffer_available(packet, 10)) { 1120 log_msg(LOG_ERR, "bad SOA RR"); 1121 region_destroy(region); 1122 return 0; 1123 } 1124 if(buffer_read_u16(packet) != TYPE_SOA || 1125 buffer_read_u16(packet) != CLASS_IN) { 1126 log_msg(LOG_ERR, "first RR not SOA IN"); 1127 region_destroy(region); 1128 return 0; 1129 } 1130 ttlpos = buffer_position(packet); 1131 buffer_skip(packet, sizeof(uint32_t)); /* ttl */ 1132 if(!buffer_available(packet, buffer_read_u16(packet)) || 1133 !packet_skip_dname(packet) /* skip prim_ns */ || 1134 !packet_skip_dname(packet) /* skip email */) { 1135 log_msg(LOG_ERR, "bad SOA RR"); 1136 region_destroy(region); 1137 return 0; 1138 } 1139 if(buffer_read_u32(packet) != serialno) { 1140 buffer_skip(packet, -4); 1141 log_msg(LOG_ERR, "SOA serial %u different from commit %u", 1142 (unsigned)buffer_read_u32(packet), (unsigned)serialno); 1143 region_destroy(region); 1144 return 0; 1145 } 1146 buffer_skip(packet, sizeof(uint32_t)*4); 1147 counter = 1; 1148 *rr_count = 1; 1149 *is_axfr = 0; 1150 *delete_mode = 0; 1151 if(ixfr_store) 1152 ixfr_store_add_newsoa(ixfr_store, packet, ttlpos); 1153 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "diff: %s start count %d, ax %d, delmode %d", 1154 dname_to_string(dname_zone, 0), *rr_count, *is_axfr, *delete_mode)); 1155 } 1156 else counter = 0; 1157 1158 for(; counter < ancount; ++counter,++(*rr_count)) 1159 { 1160 uint16_t type, klass; 1161 uint32_t ttl; 1162 1163 if(!(dname=dname_make_from_packet(region, packet, 1,1))) { 1164 log_msg(LOG_ERR, "bad xfr RR dname %d", *rr_count); 1165 region_destroy(region); 1166 return 0; 1167 } 1168 if(!buffer_available(packet, 10)) { 1169 log_msg(LOG_ERR, "bad xfr RR format %d", *rr_count); 1170 region_destroy(region); 1171 return 0; 1172 } 1173 type = buffer_read_u16(packet); 1174 klass = buffer_read_u16(packet); 1175 ttl = buffer_read_u32(packet); 1176 rrlen = buffer_read_u16(packet); 1177 if(!buffer_available(packet, rrlen)) { 1178 log_msg(LOG_ERR, "bad xfr RR rdata %d, len %d have %d", 1179 *rr_count, rrlen, (int)buffer_remaining(packet)); 1180 region_destroy(region); 1181 return 0; 1182 } 1183 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "diff: %s parsed count %d, ax %d, delmode %d", 1184 dname_to_string(dname_zone, 0), *rr_count, *is_axfr, *delete_mode)); 1185 1186 if(*rr_count == 1 && type != TYPE_SOA) { 1187 /* second RR: if not SOA: this is an AXFR; delete all zone contents */ 1188 #ifdef NSEC3 1189 nsec3_clear_precompile(db, zone_db); 1190 zone_db->nsec3_param = NULL; 1191 #endif 1192 delete_zone_rrs(db, zone_db); 1193 if(db->udb) 1194 udb_zone_clear(db->udb, udbz); 1195 /* add everything else (incl end SOA) */ 1196 *delete_mode = 0; 1197 *is_axfr = 1; 1198 if(ixfr_store) { 1199 ixfr_store_cancel(ixfr_store); 1200 ixfr_store_delixfrs(zone_db); 1201 } 1202 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "diff: %s sawAXFR count %d, ax %d, delmode %d", 1203 dname_to_string(dname_zone, 0), *rr_count, *is_axfr, *delete_mode)); 1204 } 1205 if(*rr_count == 1 && type == TYPE_SOA) { 1206 /* if the serial no of the SOA equals the serialno, then AXFR */ 1207 size_t bufpos = buffer_position(packet); 1208 uint32_t thisserial; 1209 if(!packet_skip_dname(packet) || 1210 !packet_skip_dname(packet) || 1211 buffer_remaining(packet) < sizeof(uint32_t)*5) 1212 { 1213 log_msg(LOG_ERR, "bad xfr SOA RR formerr."); 1214 region_destroy(region); 1215 return 0; 1216 } 1217 thisserial = buffer_read_u32(packet); 1218 if(thisserial == serialno) { 1219 /* AXFR */ 1220 #ifdef NSEC3 1221 nsec3_clear_precompile(db, zone_db); 1222 zone_db->nsec3_param = NULL; 1223 #endif 1224 delete_zone_rrs(db, zone_db); 1225 if(db->udb) 1226 udb_zone_clear(db->udb, udbz); 1227 *delete_mode = 0; 1228 *is_axfr = 1; 1229 if(ixfr_store) 1230 ixfr_store_cancel(ixfr_store); 1231 } 1232 /* must have stuff in memory for a successful IXFR, 1233 * the serial number of the SOA has been checked 1234 * previously (by check_for_bad_serial) if it exists */ 1235 if(!*is_axfr && !domain_find_rrset(zone_db->apex, 1236 zone_db, TYPE_SOA)) { 1237 log_msg(LOG_ERR, "%s SOA serial %u is not " 1238 "in memory, skip IXFR", zone, serialno); 1239 region_destroy(region); 1240 /* break out and stop the IXFR, ignore it */ 1241 return 2; 1242 } 1243 buffer_set_position(packet, bufpos); 1244 if(!*is_axfr && ixfr_store) 1245 ixfr_store_add_oldsoa(ixfr_store, ttl, packet, 1246 rrlen); 1247 } 1248 if(type == TYPE_SOA && !*is_axfr) { 1249 /* switch from delete-part to add-part and back again, 1250 just before soa - so it gets deleted and added too */ 1251 /* this means we switch to delete mode for the final SOA */ 1252 *delete_mode = !*delete_mode; 1253 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "diff: %s IXFRswapdel count %d, ax %d, delmode %d", 1254 dname_to_string(dname_zone, 0), *rr_count, *is_axfr, *delete_mode)); 1255 } 1256 if(type == TYPE_TSIG || type == TYPE_OPT) { 1257 /* ignore pseudo RRs */ 1258 buffer_skip(packet, rrlen); 1259 continue; 1260 } 1261 1262 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "xfr %s RR dname is %s type %s", 1263 *delete_mode?"del":"add", 1264 dname_to_string(dname,0), rrtype_to_string(type))); 1265 if(*delete_mode) { 1266 /* delete this rr */ 1267 if(!*is_axfr && type == TYPE_SOA && counter==ancount-1 1268 && seq_nr == seq_total-1) { 1269 continue; /* do not delete final SOA RR for IXFR */ 1270 } 1271 if(ixfr_store) 1272 ixfr_store_delrr(ixfr_store, dname, type, 1273 klass, ttl, packet, rrlen, region); 1274 if(!delete_RR(db, dname, type, klass, packet, 1275 rrlen, zone_db, region, udbz, softfail)) { 1276 region_destroy(region); 1277 return 0; 1278 } 1279 } 1280 else 1281 { 1282 /* add this rr */ 1283 if(ixfr_store) 1284 ixfr_store_addrr(ixfr_store, dname, type, 1285 klass, ttl, packet, rrlen, region); 1286 if(!add_RR(db, dname, type, klass, ttl, packet, 1287 rrlen, zone_db, udbz, softfail)) { 1288 region_destroy(region); 1289 return 0; 1290 } 1291 } 1292 } 1293 region_destroy(region); 1294 return 1; 1295 } 1296 1297 static int 1298 check_for_bad_serial(namedb_type* db, const char* zone_str, uint32_t old_serial) 1299 { 1300 /* see if serial OK with in-memory serial */ 1301 domain_type* domain; 1302 region_type* region = region_create(xalloc, free); 1303 const dname_type* zone_name = dname_parse(region, zone_str); 1304 zone_type* zone = 0; 1305 domain = domain_table_find(db->domains, zone_name); 1306 if(domain) 1307 zone = domain_find_zone(db, domain); 1308 if(zone && zone->apex == domain && zone->soa_rrset && old_serial) 1309 { 1310 uint32_t memserial; 1311 memcpy(&memserial, rdata_atom_data(zone->soa_rrset->rrs[0].rdatas[2]), 1312 sizeof(uint32_t)); 1313 if(old_serial != ntohl(memserial)) { 1314 region_destroy(region); 1315 return 1; 1316 } 1317 } 1318 region_destroy(region); 1319 return 0; 1320 } 1321 1322 static int 1323 apply_ixfr_for_zone(nsd_type* nsd, zone_type* zonedb, FILE* in, 1324 struct nsd_options* opt, udb_base* taskudb, udb_ptr* last_task, 1325 uint32_t xfrfilenr) 1326 { 1327 char zone_buf[3072]; 1328 char log_buf[5120]; 1329 char patname_buf[2048]; 1330 1331 uint32_t old_serial, new_serial, num_parts, type; 1332 uint64_t time_end_0, time_start_0; 1333 uint32_t time_end_1, time_start_1; 1334 uint8_t committed; 1335 uint32_t i; 1336 int num_bytes = 0; 1337 (void)last_task; 1338 assert(zonedb); 1339 1340 /* read zone name and serial */ 1341 if(!diff_read_32(in, &type)) { 1342 log_msg(LOG_ERR, "diff file too short"); 1343 return 0; 1344 } 1345 if(type != DIFF_PART_XFRF) { 1346 log_msg(LOG_ERR, "xfr file has wrong format"); 1347 return 0; 1348 1349 } 1350 /* committed and num_parts are first because they need to be 1351 * updated once the rest is written. The log buf is not certain 1352 * until its done, so at end of file. The patname is in case a 1353 * new zone is created, we know what the options-pattern is */ 1354 if(!diff_read_8(in, &committed) || 1355 !diff_read_32(in, &num_parts) || 1356 !diff_read_64(in, &time_end_0) || 1357 !diff_read_32(in, &time_end_1) || 1358 !diff_read_32(in, &old_serial) || 1359 !diff_read_32(in, &new_serial) || 1360 !diff_read_64(in, &time_start_0) || 1361 !diff_read_32(in, &time_start_1) || 1362 !diff_read_str(in, zone_buf, sizeof(zone_buf)) || 1363 !diff_read_str(in, patname_buf, sizeof(patname_buf))) { 1364 log_msg(LOG_ERR, "diff file bad commit part"); 1365 return 0; 1366 } 1367 1368 /* has been read in completely */ 1369 if(strcmp(zone_buf, domain_to_string(zonedb->apex)) != 0) { 1370 log_msg(LOG_ERR, "file %s does not match task %s", 1371 zone_buf, domain_to_string(zonedb->apex)); 1372 return 0; 1373 } 1374 switch(committed) { 1375 case DIFF_NOT_COMMITTED: 1376 log_msg(LOG_ERR, "diff file %s was not committed", zone_buf); 1377 return 0; 1378 case DIFF_CORRUPT: 1379 log_msg(LOG_ERR, "diff file %s was corrupt", zone_buf); 1380 return 0; 1381 case DIFF_INCONSISTENT: 1382 log_msg(LOG_ERR, "diff file %s was inconsistent", zone_buf); 1383 return 0; 1384 case DIFF_VERIFIED: 1385 log_msg(LOG_INFO, "diff file %s already verified", zone_buf); 1386 break; 1387 default: 1388 break; 1389 } 1390 if(num_parts == 0) { 1391 log_msg(LOG_ERR, "diff file %s was not completed", zone_buf); 1392 return 0; 1393 } 1394 if(check_for_bad_serial(nsd->db, zone_buf, old_serial)) { 1395 DEBUG(DEBUG_XFRD,1, (LOG_ERR, 1396 "skipping diff file commit with bad serial")); 1397 return 1; 1398 } 1399 1400 if(!zonedb->is_skipped) 1401 { 1402 int is_axfr=0, delete_mode=0, rr_count=0, softfail=0; 1403 const dname_type* apex = domain_dname_const(zonedb->apex); 1404 udb_ptr z; 1405 struct ixfr_store* ixfr_store = NULL, ixfr_store_mem; 1406 1407 DEBUG(DEBUG_XFRD,1, (LOG_INFO, "processing xfr: %s", zone_buf)); 1408 if(zone_is_ixfr_enabled(zonedb)) 1409 ixfr_store = ixfr_store_start(zonedb, &ixfr_store_mem, 1410 old_serial, new_serial); 1411 memset(&z, 0, sizeof(z)); /* if udb==NULL, have &z defined */ 1412 if(nsd->db->udb) { 1413 if(udb_base_get_userflags(nsd->db->udb) != 0) { 1414 diff_update_commit( 1415 zone_buf, DIFF_CORRUPT, nsd, xfrfilenr); 1416 log_msg(LOG_ERR, "database corrupted, cannot update"); 1417 exit(1); 1418 } 1419 /* all parts were checked by xfrd before commit */ 1420 if(!udb_zone_search(nsd->db->udb, &z, dname_name(apex), 1421 apex->name_size)) { 1422 /* create it */ 1423 if(!udb_zone_create(nsd->db->udb, &z, dname_name(apex), 1424 apex->name_size)) { 1425 /* out of disk space perhaps */ 1426 log_msg(LOG_ERR, "could not udb_create_zone " 1427 "%s, disk space full?", zone_buf); 1428 ixfr_store_free(ixfr_store); 1429 return 0; 1430 } 1431 } 1432 /* set the udb dirty until we are finished applying changes */ 1433 udb_base_set_userflags(nsd->db->udb, 1); 1434 } 1435 /* read and apply all of the parts */ 1436 for(i=0; i<num_parts; i++) { 1437 int ret; 1438 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "processing xfr: apply part %d", (int)i)); 1439 ret = apply_ixfr(nsd->db, in, zone_buf, new_serial, opt, 1440 i, num_parts, &is_axfr, &delete_mode, 1441 &rr_count, (nsd->db->udb?&z:NULL), &zonedb, 1442 patname_buf, &num_bytes, &softfail, ixfr_store); 1443 assert(zonedb); 1444 if(ret == 0) { 1445 log_msg(LOG_ERR, "bad ixfr packet part %d in diff file for %s", (int)i, zone_buf); 1446 diff_update_commit( 1447 zone_buf, DIFF_CORRUPT, nsd, xfrfilenr); 1448 /* the udb is still dirty, it is bad */ 1449 exit(1); 1450 } else if(ret == 2) { 1451 break; 1452 } 1453 } 1454 if(nsd->db->udb) 1455 udb_base_set_userflags(nsd->db->udb, 0); 1456 /* read the final log_str: but do not fail on it */ 1457 if(!diff_read_str(in, log_buf, sizeof(log_buf))) { 1458 log_msg(LOG_ERR, "could not read log for transfer %s", 1459 zone_buf); 1460 snprintf(log_buf, sizeof(log_buf), "error reading log"); 1461 } 1462 #ifdef NSEC3 1463 if(zonedb) prehash_zone(nsd->db, zonedb); 1464 #endif /* NSEC3 */ 1465 zonedb->is_changed = 1; 1466 zonedb->is_updated = 1; 1467 zonedb->is_checked = (committed == DIFF_VERIFIED); 1468 if(nsd->db->udb) { 1469 assert(z.base); 1470 ZONE(&z)->is_changed = 1; 1471 /* FIXME: need to set is_updated here? */ 1472 ZONE(&z)->mtime = time_end_0; 1473 ZONE(&z)->mtime_nsec = time_end_1*1000; 1474 udb_zone_set_log_str(nsd->db->udb, &z, log_buf); 1475 udb_zone_set_file_str(nsd->db->udb, &z, NULL); 1476 udb_ptr_unlink(&z, nsd->db->udb); 1477 } else { 1478 zonedb->mtime.tv_sec = time_end_0; 1479 zonedb->mtime.tv_nsec = time_end_1*1000; 1480 if(zonedb->logstr) 1481 region_recycle(nsd->db->region, zonedb->logstr, 1482 strlen(zonedb->logstr)+1); 1483 zonedb->logstr = region_strdup(nsd->db->region, log_buf); 1484 if(zonedb->filename) 1485 region_recycle(nsd->db->region, zonedb->filename, 1486 strlen(zonedb->filename)+1); 1487 zonedb->filename = NULL; 1488 } 1489 if(softfail && taskudb && !is_axfr) { 1490 log_msg(LOG_ERR, "Failed to apply IXFR cleanly " 1491 "(deletes nonexistent RRs, adds existing RRs). " 1492 "Zone %s contents is different from master, " 1493 "starting AXFR. Transfer %s", zone_buf, log_buf); 1494 /* add/del failures in IXFR, get an AXFR */ 1495 diff_update_commit( 1496 zone_buf, DIFF_INCONSISTENT, nsd, xfrfilenr); 1497 exit(1); 1498 } 1499 if(ixfr_store) 1500 ixfr_store_finish(ixfr_store, nsd, log_buf); 1501 1502 if(1 <= verbosity) { 1503 double elapsed = (double)(time_end_0 - time_start_0)+ 1504 (double)((double)time_end_1 1505 -(double)time_start_1) / 1000000.0; 1506 VERBOSITY(1, (LOG_INFO, "zone %s %s of %d bytes in %g seconds", 1507 zone_buf, log_buf, num_bytes, elapsed)); 1508 } 1509 } 1510 else { 1511 DEBUG(DEBUG_XFRD,1, (LOG_INFO, "skipping xfr: %s", log_buf)); 1512 } 1513 return 1; 1514 } 1515 1516 struct udb_base* task_file_create(const char* file) 1517 { 1518 return udb_base_create_new(file, &namedb_walkfunc, NULL); 1519 } 1520 1521 static int 1522 task_create_new_elem(struct udb_base* udb, udb_ptr* last, udb_ptr* e, 1523 size_t sz, const dname_type* zname) 1524 { 1525 if(!udb_ptr_alloc_space(e, udb, udb_chunk_type_task, sz)) { 1526 return 0; 1527 } 1528 if(udb_ptr_is_null(last)) { 1529 udb_base_set_userdata(udb, e->data); 1530 } else { 1531 udb_rptr_set_ptr(&TASKLIST(last)->next, udb, e); 1532 } 1533 udb_ptr_set_ptr(last, udb, e); 1534 1535 /* fill in tasklist item */ 1536 udb_rel_ptr_init(&TASKLIST(e)->next); 1537 TASKLIST(e)->size = sz; 1538 TASKLIST(e)->oldserial = 0; 1539 TASKLIST(e)->newserial = 0; 1540 TASKLIST(e)->yesno = 0; 1541 1542 if(zname) { 1543 memmove(TASKLIST(e)->zname, zname, dname_total_size(zname)); 1544 } 1545 return 1; 1546 } 1547 1548 void task_new_soainfo(struct udb_base* udb, udb_ptr* last, struct zone* z, 1549 enum soainfo_hint hint) 1550 { 1551 /* calculate size */ 1552 udb_ptr e; 1553 size_t sz; 1554 const dname_type* apex, *ns, *em; 1555 if(!z || !z->apex || !domain_dname(z->apex)) 1556 return; /* safety check */ 1557 1558 DEBUG(DEBUG_IPC,1, (LOG_INFO, "nsd: add soa info for zone %s", 1559 domain_to_string(z->apex))); 1560 apex = domain_dname(z->apex); 1561 sz = sizeof(struct task_list_d) + dname_total_size(apex); 1562 if(z->soa_rrset && hint == soainfo_ok) { 1563 ns = domain_dname(rdata_atom_domain( 1564 z->soa_rrset->rrs[0].rdatas[0])); 1565 em = domain_dname(rdata_atom_domain( 1566 z->soa_rrset->rrs[0].rdatas[1])); 1567 sz += sizeof(uint32_t)*6 + sizeof(uint8_t)*2 1568 + ns->name_size + em->name_size; 1569 } else { 1570 ns = 0; 1571 em = 0; 1572 } 1573 1574 /* create new task_list item */ 1575 if(!task_create_new_elem(udb, last, &e, sz, apex)) { 1576 log_msg(LOG_ERR, "tasklist: out of space, cannot add SOAINFO"); 1577 return; 1578 } 1579 TASKLIST(&e)->task_type = task_soa_info; 1580 TASKLIST(&e)->yesno = (uint64_t)hint; 1581 1582 if(z->soa_rrset && hint == soainfo_ok) { 1583 uint32_t ttl = htonl(z->soa_rrset->rrs[0].ttl); 1584 uint8_t* p = (uint8_t*)TASKLIST(&e)->zname; 1585 p += dname_total_size(apex); 1586 memmove(p, &ttl, sizeof(uint32_t)); 1587 p += sizeof(uint32_t); 1588 memmove(p, &ns->name_size, sizeof(uint8_t)); 1589 p += sizeof(uint8_t); 1590 memmove(p, dname_name(ns), ns->name_size); 1591 p += ns->name_size; 1592 memmove(p, &em->name_size, sizeof(uint8_t)); 1593 p += sizeof(uint8_t); 1594 memmove(p, dname_name(em), em->name_size); 1595 p += em->name_size; 1596 memmove(p, rdata_atom_data(z->soa_rrset->rrs[0].rdatas[2]), 1597 sizeof(uint32_t)); 1598 p += sizeof(uint32_t); 1599 memmove(p, rdata_atom_data(z->soa_rrset->rrs[0].rdatas[3]), 1600 sizeof(uint32_t)); 1601 p += sizeof(uint32_t); 1602 memmove(p, rdata_atom_data(z->soa_rrset->rrs[0].rdatas[4]), 1603 sizeof(uint32_t)); 1604 p += sizeof(uint32_t); 1605 memmove(p, rdata_atom_data(z->soa_rrset->rrs[0].rdatas[5]), 1606 sizeof(uint32_t)); 1607 p += sizeof(uint32_t); 1608 memmove(p, rdata_atom_data(z->soa_rrset->rrs[0].rdatas[6]), 1609 sizeof(uint32_t)); 1610 } 1611 udb_ptr_unlink(&e, udb); 1612 } 1613 1614 void task_process_sync(struct udb_base* taskudb) 1615 { 1616 /* need to sync before other process uses the mmap? */ 1617 DEBUG(DEBUG_IPC,1, (LOG_INFO, "task procsync %s size %d", 1618 taskudb->fname, (int)taskudb->base_size)); 1619 (void)taskudb; 1620 } 1621 1622 void task_remap(struct udb_base* taskudb) 1623 { 1624 DEBUG(DEBUG_IPC,1, (LOG_INFO, "task remap %s size %d", 1625 taskudb->fname, (int)taskudb->glob_data->fsize)); 1626 udb_base_remap_process(taskudb); 1627 } 1628 1629 void task_clear(struct udb_base* taskudb) 1630 { 1631 udb_ptr t, n; 1632 udb_ptr_new(&t, taskudb, udb_base_get_userdata(taskudb)); 1633 udb_base_set_userdata(taskudb, 0); 1634 udb_ptr_init(&n, taskudb); 1635 while(!udb_ptr_is_null(&t)) { 1636 udb_ptr_set_rptr(&n, taskudb, &TASKLIST(&t)->next); 1637 udb_rptr_zero(&TASKLIST(&t)->next, taskudb); 1638 udb_ptr_free_space(&t, taskudb, TASKLIST(&t)->size); 1639 udb_ptr_set_ptr(&t, taskudb, &n); 1640 } 1641 udb_ptr_unlink(&t, taskudb); 1642 udb_ptr_unlink(&n, taskudb); 1643 } 1644 1645 void task_new_expire(struct udb_base* udb, udb_ptr* last, 1646 const struct dname* z, int expired) 1647 { 1648 udb_ptr e; 1649 if(!z) return; 1650 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add expire info for zone %s", 1651 dname_to_string(z,NULL))); 1652 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d)+ 1653 dname_total_size(z), z)) { 1654 log_msg(LOG_ERR, "tasklist: out of space, cannot add expire"); 1655 return; 1656 } 1657 TASKLIST(&e)->task_type = task_expire; 1658 TASKLIST(&e)->yesno = expired; 1659 udb_ptr_unlink(&e, udb); 1660 } 1661 1662 void task_new_check_zonefiles(udb_base* udb, udb_ptr* last, 1663 const dname_type* zone) 1664 { 1665 udb_ptr e; 1666 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task checkzonefiles")); 1667 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) + 1668 (zone?dname_total_size(zone):0), zone)) { 1669 log_msg(LOG_ERR, "tasklist: out of space, cannot add check_zones"); 1670 return; 1671 } 1672 TASKLIST(&e)->task_type = task_check_zonefiles; 1673 TASKLIST(&e)->yesno = (zone!=NULL); 1674 udb_ptr_unlink(&e, udb); 1675 } 1676 1677 void task_new_write_zonefiles(udb_base* udb, udb_ptr* last, 1678 const dname_type* zone) 1679 { 1680 udb_ptr e; 1681 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task writezonefiles")); 1682 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) + 1683 (zone?dname_total_size(zone):0), zone)) { 1684 log_msg(LOG_ERR, "tasklist: out of space, cannot add writezones"); 1685 return; 1686 } 1687 TASKLIST(&e)->task_type = task_write_zonefiles; 1688 TASKLIST(&e)->yesno = (zone!=NULL); 1689 udb_ptr_unlink(&e, udb); 1690 } 1691 1692 void task_new_set_verbosity(udb_base* udb, udb_ptr* last, int v) 1693 { 1694 udb_ptr e; 1695 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task set_verbosity")); 1696 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d), 1697 NULL)) { 1698 log_msg(LOG_ERR, "tasklist: out of space, cannot add set_v"); 1699 return; 1700 } 1701 TASKLIST(&e)->task_type = task_set_verbosity; 1702 TASKLIST(&e)->yesno = v; 1703 udb_ptr_unlink(&e, udb); 1704 } 1705 1706 #ifdef BIND8_STATS 1707 void* task_new_stat_info(udb_base* udb, udb_ptr* last, struct nsdst* stat, 1708 size_t child_count) 1709 { 1710 void* p; 1711 udb_ptr e; 1712 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task stat_info")); 1713 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d)+ 1714 sizeof(*stat) + sizeof(stc_type)*child_count, NULL)) { 1715 log_msg(LOG_ERR, "tasklist: out of space, cannot add stati"); 1716 return NULL; 1717 } 1718 TASKLIST(&e)->task_type = task_stat_info; 1719 p = TASKLIST(&e)->zname; 1720 memcpy(p, stat, sizeof(*stat)); 1721 udb_ptr_unlink(&e, udb); 1722 return (char*)p + sizeof(*stat); 1723 } 1724 #endif /* BIND8_STATS */ 1725 1726 void 1727 task_new_add_zone(udb_base* udb, udb_ptr* last, const char* zone, 1728 const char* pattern, unsigned zonestatid) 1729 { 1730 size_t zlen = strlen(zone); 1731 size_t plen = strlen(pattern); 1732 void *p; 1733 udb_ptr e; 1734 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task addzone %s %s", zone, pattern)); 1735 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d)+ 1736 zlen + 1 + plen + 1, NULL)) { 1737 log_msg(LOG_ERR, "tasklist: out of space, cannot add addz"); 1738 return; 1739 } 1740 TASKLIST(&e)->task_type = task_add_zone; 1741 TASKLIST(&e)->yesno = zonestatid; 1742 p = TASKLIST(&e)->zname; 1743 memcpy(p, zone, zlen+1); 1744 memmove((char*)p+zlen+1, pattern, plen+1); 1745 udb_ptr_unlink(&e, udb); 1746 } 1747 1748 void 1749 task_new_del_zone(udb_base* udb, udb_ptr* last, const dname_type* dname) 1750 { 1751 udb_ptr e; 1752 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task delzone %s", dname_to_string(dname, 0))); 1753 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) 1754 +dname_total_size(dname), dname)) { 1755 log_msg(LOG_ERR, "tasklist: out of space, cannot add delz"); 1756 return; 1757 } 1758 TASKLIST(&e)->task_type = task_del_zone; 1759 udb_ptr_unlink(&e, udb); 1760 } 1761 1762 void task_new_add_key(udb_base* udb, udb_ptr* last, struct key_options* key) 1763 { 1764 char* p; 1765 udb_ptr e; 1766 assert(key->name && key->algorithm && key->secret); 1767 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task addkey")); 1768 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) 1769 +strlen(key->name)+1+strlen(key->algorithm)+1+ 1770 strlen(key->secret)+1, NULL)) { 1771 log_msg(LOG_ERR, "tasklist: out of space, cannot add addk"); 1772 return; 1773 } 1774 TASKLIST(&e)->task_type = task_add_key; 1775 p = (char*)TASKLIST(&e)->zname; 1776 memmove(p, key->name, strlen(key->name)+1); 1777 p+=strlen(key->name)+1; 1778 memmove(p, key->algorithm, strlen(key->algorithm)+1); 1779 p+=strlen(key->algorithm)+1; 1780 memmove(p, key->secret, strlen(key->secret)+1); 1781 udb_ptr_unlink(&e, udb); 1782 } 1783 1784 void task_new_del_key(udb_base* udb, udb_ptr* last, const char* name) 1785 { 1786 char* p; 1787 udb_ptr e; 1788 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task delkey")); 1789 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) 1790 +strlen(name)+1, NULL)) { 1791 log_msg(LOG_ERR, "tasklist: out of space, cannot add delk"); 1792 return; 1793 } 1794 TASKLIST(&e)->task_type = task_del_key; 1795 p = (char*)TASKLIST(&e)->zname; 1796 memmove(p, name, strlen(name)+1); 1797 udb_ptr_unlink(&e, udb); 1798 } 1799 1800 void task_new_add_cookie_secret(udb_base* udb, udb_ptr* last, 1801 const char* secret) { 1802 udb_ptr e; 1803 char* p; 1804 size_t const secret_size = strlen(secret) + 1; 1805 1806 DEBUG(DEBUG_IPC, 1, (LOG_INFO, "add task add_cookie_secret")); 1807 1808 if(!task_create_new_elem(udb, last, &e, 1809 sizeof(struct task_list_d) + secret_size, NULL)) { 1810 log_msg(LOG_ERR, "tasklist: out of space, cannot add add_cookie_secret"); 1811 return; 1812 } 1813 TASKLIST(&e)->task_type = task_add_cookie_secret; 1814 p = (char*)TASKLIST(&e)->zname; 1815 memmove(p, secret, secret_size); 1816 udb_ptr_unlink(&e, udb); 1817 } 1818 1819 void task_new_drop_cookie_secret(udb_base* udb, udb_ptr* last) { 1820 udb_ptr e; 1821 DEBUG(DEBUG_IPC, 1, (LOG_INFO, "add task drop_cookie_secret")); 1822 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d), NULL)) { 1823 log_msg(LOG_ERR, "tasklist: out of space, cannot add drop_cookie_secret"); 1824 return; 1825 } 1826 TASKLIST(&e)->task_type = task_drop_cookie_secret; 1827 udb_ptr_unlink(&e, udb); 1828 } 1829 1830 void task_new_activate_cookie_secret(udb_base* udb, udb_ptr* last) { 1831 udb_ptr e; 1832 DEBUG(DEBUG_IPC, 1, (LOG_INFO, "add task activate_cookie_secret")); 1833 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d), NULL)) { 1834 log_msg(LOG_ERR, "tasklist: out of space, cannot add activate_cookie_secret"); 1835 return; 1836 } 1837 TASKLIST(&e)->task_type = task_activate_cookie_secret; 1838 udb_ptr_unlink(&e, udb); 1839 } 1840 1841 void task_new_add_pattern(udb_base* udb, udb_ptr* last, 1842 struct pattern_options* p) 1843 { 1844 region_type* temp; 1845 buffer_type* buffer; 1846 udb_ptr e; 1847 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task addpattern %s", p->pname)); 1848 temp = region_create(xalloc, free); 1849 buffer = buffer_create(temp, 4096); 1850 pattern_options_marshal(buffer, p); 1851 buffer_flip(buffer); 1852 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) 1853 + buffer_limit(buffer), NULL)) { 1854 log_msg(LOG_ERR, "tasklist: out of space, cannot add addp"); 1855 region_destroy(temp); 1856 return; 1857 } 1858 TASKLIST(&e)->task_type = task_add_pattern; 1859 TASKLIST(&e)->yesno = buffer_limit(buffer); 1860 memmove(TASKLIST(&e)->zname, buffer_begin(buffer), 1861 buffer_limit(buffer)); 1862 udb_ptr_unlink(&e, udb); 1863 region_destroy(temp); 1864 } 1865 1866 void task_new_del_pattern(udb_base* udb, udb_ptr* last, const char* name) 1867 { 1868 char* p; 1869 udb_ptr e; 1870 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task delpattern %s", name)); 1871 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) 1872 +strlen(name)+1, NULL)) { 1873 log_msg(LOG_ERR, "tasklist: out of space, cannot add delp"); 1874 return; 1875 } 1876 TASKLIST(&e)->task_type = task_del_pattern; 1877 p = (char*)TASKLIST(&e)->zname; 1878 memmove(p, name, strlen(name)+1); 1879 udb_ptr_unlink(&e, udb); 1880 } 1881 1882 void task_new_opt_change(udb_base* udb, udb_ptr* last, struct nsd_options* opt) 1883 { 1884 udb_ptr e; 1885 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task opt_change")); 1886 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d), 1887 NULL)) { 1888 log_msg(LOG_ERR, "tasklist: out of space, cannot add o_c"); 1889 return; 1890 } 1891 TASKLIST(&e)->task_type = task_opt_change; 1892 #ifdef RATELIMIT 1893 TASKLIST(&e)->oldserial = opt->rrl_ratelimit; 1894 TASKLIST(&e)->newserial = opt->rrl_whitelist_ratelimit; 1895 TASKLIST(&e)->yesno = (uint64_t) opt->rrl_slip; 1896 #else 1897 (void)opt; 1898 #endif 1899 udb_ptr_unlink(&e, udb); 1900 } 1901 1902 void task_new_zonestat_inc(udb_base* udb, udb_ptr* last, unsigned sz) 1903 { 1904 udb_ptr e; 1905 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task zonestat_inc")); 1906 if(sz == 0) 1907 return; /* no need to decrease to 0 */ 1908 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d), 1909 NULL)) { 1910 log_msg(LOG_ERR, "tasklist: out of space, cannot add z_i"); 1911 return; 1912 } 1913 TASKLIST(&e)->task_type = task_zonestat_inc; 1914 TASKLIST(&e)->oldserial = (uint32_t)sz; 1915 udb_ptr_unlink(&e, udb); 1916 } 1917 1918 int 1919 task_new_apply_xfr(udb_base* udb, udb_ptr* last, const dname_type* dname, 1920 uint32_t old_serial, uint32_t new_serial, uint64_t filenumber) 1921 { 1922 udb_ptr e; 1923 DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task apply_xfr")); 1924 if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) 1925 +dname_total_size(dname), dname)) { 1926 log_msg(LOG_ERR, "tasklist: out of space, cannot add applyxfr"); 1927 return 0; 1928 } 1929 TASKLIST(&e)->oldserial = old_serial; 1930 TASKLIST(&e)->newserial = new_serial; 1931 TASKLIST(&e)->yesno = filenumber; 1932 TASKLIST(&e)->task_type = task_apply_xfr; 1933 udb_ptr_unlink(&e, udb); 1934 return 1; 1935 } 1936 1937 void 1938 task_process_expire(namedb_type* db, struct task_list_d* task) 1939 { 1940 uint8_t ok; 1941 zone_type* z = namedb_find_zone(db, task->zname); 1942 assert(task->task_type == task_expire); 1943 if(!z) { 1944 DEBUG(DEBUG_IPC, 1, (LOG_WARNING, "zone %s %s but not in zonetree", 1945 dname_to_string(task->zname, NULL), 1946 task->yesno?"expired":"unexpired")); 1947 return; 1948 } 1949 DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: expire task zone %s %s", 1950 dname_to_string(task->zname,0), 1951 task->yesno?"expired":"unexpired")); 1952 /* find zone, set expire flag */ 1953 ok = !task->yesno; 1954 /* only update zone->is_ok if needed to minimize copy-on-write 1955 * of memory pages shared after fork() */ 1956 if(ok && !z->is_ok) 1957 z->is_ok = 1; 1958 else if(!ok && z->is_ok) 1959 z->is_ok = 0; 1960 } 1961 1962 static void 1963 task_process_set_verbosity(struct task_list_d* task) 1964 { 1965 DEBUG(DEBUG_IPC,1, (LOG_INFO, "verbosity task %d", (int)task->yesno)); 1966 verbosity = task->yesno; 1967 } 1968 1969 static void 1970 task_process_checkzones(struct nsd* nsd, udb_base* udb, udb_ptr* last_task, 1971 struct task_list_d* task) 1972 { 1973 /* on SIGHUP check if zone-text-files changed and if so, 1974 * reread. When from xfrd-reload, no need to fstat the files */ 1975 if(task->yesno) { 1976 struct zone_options* zo = zone_options_find(nsd->options, 1977 task->zname); 1978 if(zo) 1979 namedb_check_zonefile(nsd, udb, last_task, zo); 1980 } else { 1981 /* check all zones */ 1982 namedb_check_zonefiles(nsd, nsd->options, udb, last_task); 1983 } 1984 } 1985 1986 static void 1987 task_process_writezones(struct nsd* nsd, struct task_list_d* task) 1988 { 1989 if(task->yesno) { 1990 struct zone_options* zo = zone_options_find(nsd->options, 1991 task->zname); 1992 if(zo) 1993 namedb_write_zonefile(nsd, zo); 1994 } else { 1995 namedb_write_zonefiles(nsd, nsd->options); 1996 } 1997 } 1998 1999 static void 2000 task_process_add_zone(struct nsd* nsd, udb_base* udb, udb_ptr* last_task, 2001 struct task_list_d* task) 2002 { 2003 zone_type* z; 2004 const dname_type* zdname; 2005 const char* zname = (const char*)task->zname; 2006 const char* pname = zname + strlen(zname)+1; 2007 DEBUG(DEBUG_IPC,1, (LOG_INFO, "addzone task %s %s", zname, pname)); 2008 zdname = dname_parse(nsd->db->region, zname); 2009 if(!zdname) { 2010 log_msg(LOG_ERR, "can not parse zone name %s", zname); 2011 return; 2012 } 2013 /* create zone */ 2014 z = find_or_create_zone(nsd->db, zdname, nsd->options, zname, pname); 2015 if(!z) { 2016 region_recycle(nsd->db->region, (void*)zdname, 2017 dname_total_size(zdname)); 2018 log_msg(LOG_ERR, "can not add zone %s %s", zname, pname); 2019 return; 2020 } 2021 z->zonestatid = (unsigned)task->yesno; 2022 /* if zone is empty, attempt to read the zonefile from disk (if any) */ 2023 if(!z->soa_rrset && z->opts->pattern->zonefile) { 2024 namedb_read_zonefile(nsd, z, udb, last_task); 2025 } 2026 } 2027 2028 static void 2029 task_process_del_zone(struct nsd* nsd, struct task_list_d* task) 2030 { 2031 zone_type* zone; 2032 struct zone_options* zopt; 2033 DEBUG(DEBUG_IPC,1, (LOG_INFO, "delzone task %s", dname_to_string( 2034 task->zname, NULL))); 2035 zone = namedb_find_zone(nsd->db, task->zname); 2036 if(!zone) 2037 return; 2038 2039 #ifdef NSEC3 2040 nsec3_clear_precompile(nsd->db, zone); 2041 zone->nsec3_param = NULL; 2042 #endif 2043 delete_zone_rrs(nsd->db, zone); 2044 if(nsd->db->udb) { 2045 udb_ptr udbz; 2046 if(udb_zone_search(nsd->db->udb, &udbz, dname_name(task->zname), 2047 task->zname->name_size)) { 2048 udb_zone_delete(nsd->db->udb, &udbz); 2049 udb_ptr_unlink(&udbz, nsd->db->udb); 2050 } 2051 } 2052 2053 /* remove from zonetree, apex, soa */ 2054 zopt = zone->opts; 2055 namedb_zone_delete(nsd->db, zone); 2056 /* remove from options (zone_list already edited by xfrd) */ 2057 zone_options_delete(nsd->options, zopt); 2058 } 2059 2060 static void 2061 task_process_add_key(struct nsd* nsd, struct task_list_d* task) 2062 { 2063 struct key_options key; 2064 key.name = (char*)task->zname; 2065 DEBUG(DEBUG_IPC,1, (LOG_INFO, "addkey task %s", key.name)); 2066 key.algorithm = key.name + strlen(key.name)+1; 2067 key.secret = key.algorithm + strlen(key.algorithm)+1; 2068 key_options_add_modify(nsd->options, &key); 2069 memset(key.secret, 0xdd, strlen(key.secret)); /* wipe secret */ 2070 } 2071 2072 static void 2073 task_process_del_key(struct nsd* nsd, struct task_list_d* task) 2074 { 2075 char* name = (char*)task->zname; 2076 DEBUG(DEBUG_IPC,1, (LOG_INFO, "delkey task %s", name)); 2077 /* this is reload and nothing is using the TSIG key right now */ 2078 key_options_remove(nsd->options, name); 2079 } 2080 2081 static void 2082 task_process_add_cookie_secret(struct nsd* nsd, struct task_list_d* task) { 2083 uint8_t secret_tmp[NSD_COOKIE_SECRET_SIZE]; 2084 ssize_t decoded_len; 2085 char* secret = (char*)task->zname; 2086 2087 DEBUG(DEBUG_IPC, 1, (LOG_INFO, "add_cookie_secret task %s", secret)); 2088 2089 if( strlen(secret) != 32 ) { 2090 log_msg(LOG_ERR, "invalid cookie secret: %s", secret); 2091 explicit_bzero(secret, strlen(secret)); 2092 return; 2093 } 2094 2095 decoded_len = hex_pton(secret, secret_tmp, NSD_COOKIE_SECRET_SIZE); 2096 if( decoded_len != 16 ) { 2097 explicit_bzero(secret_tmp, NSD_COOKIE_SECRET_SIZE); 2098 log_msg(LOG_ERR, "unable to parse cookie secret: %s", secret); 2099 explicit_bzero(secret, strlen(secret)); 2100 return; 2101 } 2102 explicit_bzero(secret, strlen(secret)); 2103 add_cookie_secret(nsd, secret_tmp); 2104 explicit_bzero(secret_tmp, NSD_COOKIE_SECRET_SIZE); 2105 } 2106 2107 static void 2108 task_process_drop_cookie_secret(struct nsd* nsd, struct task_list_d* task) 2109 { 2110 (void)task; 2111 DEBUG(DEBUG_IPC, 1, (LOG_INFO, "drop_cookie_secret task")); 2112 if( nsd->cookie_count <= 1 ) { 2113 log_msg(LOG_ERR, "can not drop the only active cookie secret"); 2114 return; 2115 } 2116 drop_cookie_secret(nsd); 2117 } 2118 2119 static void 2120 task_process_activate_cookie_secret(struct nsd* nsd, struct task_list_d* task) 2121 { 2122 (void)task; 2123 DEBUG(DEBUG_IPC, 1, (LOG_INFO, "activate_cookie_secret task")); 2124 if( nsd->cookie_count <= 1 ) { 2125 log_msg(LOG_ERR, "can not activate the only active cookie secret"); 2126 return; 2127 } 2128 activate_cookie_secret(nsd); 2129 } 2130 2131 static void 2132 task_process_add_pattern(struct nsd* nsd, struct task_list_d* task) 2133 { 2134 region_type* temp = region_create(xalloc, free); 2135 buffer_type buffer; 2136 struct pattern_options *pat; 2137 buffer_create_from(&buffer, task->zname, task->yesno); 2138 pat = pattern_options_unmarshal(temp, &buffer); 2139 DEBUG(DEBUG_IPC,1, (LOG_INFO, "addpattern task %s", pat->pname)); 2140 pattern_options_add_modify(nsd->options, pat); 2141 region_destroy(temp); 2142 } 2143 2144 static void 2145 task_process_del_pattern(struct nsd* nsd, struct task_list_d* task) 2146 { 2147 char* name = (char*)task->zname; 2148 DEBUG(DEBUG_IPC,1, (LOG_INFO, "delpattern task %s", name)); 2149 pattern_options_remove(nsd->options, name); 2150 } 2151 2152 static void 2153 task_process_opt_change(struct nsd* nsd, struct task_list_d* task) 2154 { 2155 DEBUG(DEBUG_IPC,1, (LOG_INFO, "optchange task")); 2156 #ifdef RATELIMIT 2157 nsd->options->rrl_ratelimit = task->oldserial; 2158 nsd->options->rrl_whitelist_ratelimit = task->newserial; 2159 nsd->options->rrl_slip = task->yesno; 2160 rrl_set_limit(nsd->options->rrl_ratelimit, nsd->options->rrl_whitelist_ratelimit, 2161 nsd->options->rrl_slip); 2162 #else 2163 (void)nsd; (void)task; 2164 #endif 2165 } 2166 2167 #ifdef USE_ZONE_STATS 2168 static void 2169 task_process_zonestat_inc(struct nsd* nsd, udb_base* udb, udb_ptr *last_task, 2170 struct task_list_d* task) 2171 { 2172 DEBUG(DEBUG_IPC,1, (LOG_INFO, "zonestat_inc task %u", (unsigned)task->oldserial)); 2173 nsd->zonestatdesired = (unsigned)task->oldserial; 2174 /* send echo to xfrd to increment on its end */ 2175 task_new_zonestat_inc(udb, last_task, nsd->zonestatdesired); 2176 } 2177 #endif 2178 2179 static void 2180 task_process_apply_xfr(struct nsd* nsd, udb_base* udb, udb_ptr *last_task, 2181 udb_ptr* task) 2182 { 2183 /* we have to use an udb_ptr task here, because the apply_xfr procedure 2184 * appends soa_info which may remap and change the pointer. */ 2185 zone_type* zone; 2186 FILE* df; 2187 DEBUG(DEBUG_IPC,1, (LOG_INFO, "applyxfr task %s", dname_to_string( 2188 TASKLIST(task)->zname, NULL))); 2189 zone = namedb_find_zone(nsd->db, TASKLIST(task)->zname); 2190 if(!zone) { 2191 /* assume the zone has been deleted and a zone transfer was 2192 * still waiting to be processed */ 2193 return; 2194 } 2195 2196 /* apply the XFR */ 2197 /* oldserial, newserial, yesno is filenumber */ 2198 df = xfrd_open_xfrfile(nsd, TASKLIST(task)->yesno, "r"); 2199 if(!df) { 2200 /* could not open file to update */ 2201 /* soainfo_gone will be communicated from server_reload, unless 2202 preceding updates have been applied */ 2203 zone->is_skipped = 1; 2204 return; 2205 } 2206 /* read and apply zone transfer */ 2207 if(!apply_ixfr_for_zone(nsd, zone, df, nsd->options, udb, 2208 last_task, TASKLIST(task)->yesno)) { 2209 /* soainfo_gone will be communicated from server_reload, unless 2210 preceding updates have been applied */ 2211 zone->is_skipped = 1; 2212 } 2213 2214 fclose(df); 2215 } 2216 2217 2218 void task_process_in_reload(struct nsd* nsd, udb_base* udb, udb_ptr *last_task, 2219 udb_ptr* task) 2220 { 2221 switch(TASKLIST(task)->task_type) { 2222 case task_expire: 2223 task_process_expire(nsd->db, TASKLIST(task)); 2224 break; 2225 case task_check_zonefiles: 2226 task_process_checkzones(nsd, udb, last_task, TASKLIST(task)); 2227 break; 2228 case task_write_zonefiles: 2229 task_process_writezones(nsd, TASKLIST(task)); 2230 break; 2231 case task_set_verbosity: 2232 task_process_set_verbosity(TASKLIST(task)); 2233 break; 2234 case task_add_zone: 2235 task_process_add_zone(nsd, udb, last_task, TASKLIST(task)); 2236 break; 2237 case task_del_zone: 2238 task_process_del_zone(nsd, TASKLIST(task)); 2239 break; 2240 case task_add_key: 2241 task_process_add_key(nsd, TASKLIST(task)); 2242 break; 2243 case task_del_key: 2244 task_process_del_key(nsd, TASKLIST(task)); 2245 break; 2246 case task_add_pattern: 2247 task_process_add_pattern(nsd, TASKLIST(task)); 2248 break; 2249 case task_del_pattern: 2250 task_process_del_pattern(nsd, TASKLIST(task)); 2251 break; 2252 case task_opt_change: 2253 task_process_opt_change(nsd, TASKLIST(task)); 2254 break; 2255 #ifdef USE_ZONE_STATS 2256 case task_zonestat_inc: 2257 task_process_zonestat_inc(nsd, udb, last_task, TASKLIST(task)); 2258 break; 2259 #endif 2260 case task_apply_xfr: 2261 task_process_apply_xfr(nsd, udb, last_task, task); 2262 break; 2263 case task_add_cookie_secret: 2264 task_process_add_cookie_secret(nsd, TASKLIST(task)); 2265 break; 2266 case task_drop_cookie_secret: 2267 task_process_drop_cookie_secret(nsd, TASKLIST(task)); 2268 break; 2269 case task_activate_cookie_secret: 2270 task_process_activate_cookie_secret(nsd, TASKLIST(task)); 2271 break; 2272 default: 2273 log_msg(LOG_WARNING, "unhandled task in reload type %d", 2274 (int)TASKLIST(task)->task_type); 2275 break; 2276 } 2277 udb_ptr_free_space(task, udb, TASKLIST(task)->size); 2278 } 2279