OpenDNSSEC-signer 1.2.1
|
00001 /* 00002 * $Id: zonedata.c 4527 2011-03-03 14:40:41Z matthijs $ 00003 * 00004 * Copyright (c) 2009 NLNet Labs. All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00016 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00017 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00018 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00019 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00020 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00021 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00023 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00024 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00025 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 * 00027 */ 00028 00034 #include "config.h" 00035 #include "signer/backup.h" 00036 #include "signer/denial.h" 00037 #include "signer/domain.h" 00038 #include "signer/nsec3params.h" 00039 #include "signer/zonedata.h" 00040 #include "util/file.h" 00041 #include "util/log.h" 00042 #include "util/se_malloc.h" 00043 #include "util/util.h" 00044 00045 #include <ldns/ldns.h> /* ldns_dname_*(), ldns_rbtree_*() */ 00046 00047 00052 static int 00053 domain_compare(const void* a, const void* b) 00054 { 00055 ldns_rdf* x = (ldns_rdf*)a; 00056 ldns_rdf* y = (ldns_rdf*)b; 00057 return ldns_dname_compare(x, y); 00058 } 00059 00060 00065 zonedata_type* 00066 zonedata_create(void) 00067 { 00068 zonedata_type* zd = (zonedata_type*) se_malloc(sizeof(zonedata_type)); 00069 zd->domains = ldns_rbtree_create(domain_compare); 00070 zd->denial_chain = ldns_rbtree_create(domain_compare); 00071 zd->initialized = 0; 00072 zd->inbound_serial = 0; 00073 zd->internal_serial = 0; 00074 zd->outbound_serial = 0; 00075 zd->default_ttl = 3600; /* configure --default-ttl option? */ 00076 return zd; 00077 } 00078 00079 00080 static ldns_rbnode_t* domain2node(domain_type* domain); 00081 static ldns_rbnode_t* denial2node(denial_type* denial); 00082 00087 int 00088 zonedata_recover_from_backup(zonedata_type* zd, FILE* fd) 00089 { 00090 int corrupted = 0; 00091 const char* token = NULL; 00092 domain_type* current_domain = NULL; 00093 ldns_rdf* parent_rdf = NULL; 00094 ldns_rr* rr = NULL; 00095 ldns_status status = LDNS_STATUS_OK; 00096 ldns_rbnode_t* new_node = LDNS_RBTREE_NULL; 00097 int current_nxt = 0; 00098 int current_bm = 0; 00099 00100 se_log_assert(zd); 00101 se_log_assert(fd); 00102 00103 if (!backup_read_check_str(fd, ODS_SE_FILE_MAGIC)) { 00104 corrupted = 1; 00105 } 00106 00107 while (!corrupted) { 00108 if (backup_read_str(fd, &token)) { 00109 if (se_strcmp(token, ";DNAME") == 0) { 00110 current_domain = domain_recover_from_backup(fd, ¤t_nxt, 00111 ¤t_bm); 00112 if (!current_domain) { 00113 se_log_error("error reading domain from backup file"); 00114 corrupted = 1; 00115 } else { 00116 parent_rdf = ldns_dname_left_chop(current_domain->name); 00117 if (!parent_rdf) { 00118 se_log_error("unable to create parent domain name (rdf)"); 00119 corrupted = 1; 00120 } else { 00121 current_domain->parent = 00122 zonedata_lookup_domain(zd, parent_rdf); 00123 ldns_rdf_deep_free(parent_rdf); 00124 se_log_assert(current_domain->parent || 00125 current_domain->domain_status == DOMAIN_STATUS_APEX); 00126 00127 new_node = domain2node(current_domain); 00128 if (!zd->domains) { 00129 zd->domains = ldns_rbtree_create(domain_compare); 00130 } 00131 if (ldns_rbtree_insert(zd->domains, new_node) == NULL) { 00132 se_log_error("error adding domain from backup file"); 00133 se_free((void*)new_node); 00134 corrupted = 1; 00135 } 00136 new_node = NULL; 00137 } 00138 } 00139 } else if (se_strcmp(token, ";DNAME3") == 0) { 00140 se_log_assert(current_domain); 00141 current_domain->denial = denial_recover_from_backup(fd); 00142 if (!current_domain->denial) { 00143 se_log_error("error reading nsec3 domain from backup file"); 00144 corrupted = 1; 00145 } else { 00146 current_domain->denial->domain = current_domain; 00147 new_node = denial2node(current_domain->denial); 00148 if (!zd->denial_chain) { 00149 zd->denial_chain = ldns_rbtree_create(domain_compare); 00150 } 00151 00152 if (ldns_rbtree_insert(zd->denial_chain, new_node) == NULL) { 00153 se_log_error("error adding nsec3 domain from backup file"); 00154 se_free((void*)new_node); 00155 corrupted = 1; 00156 } 00157 new_node = NULL; 00158 } 00159 } else if (se_strcmp(token, ";NSEC") == 0) { 00160 status = ldns_rr_new_frm_fp(&rr, fd, NULL, NULL, NULL); 00161 if (status != LDNS_STATUS_OK) { 00162 se_log_error("error reading NSEC RR from backup file"); 00163 if (rr) { 00164 ldns_rr_free(rr); 00165 } 00166 corrupted = 1; 00167 } else { 00168 se_log_assert(current_domain); 00169 current_domain->denial = denial_create(current_domain->name); 00170 if (!current_domain->denial) { 00171 se_log_error("error reading nsec domain from backup file"); 00172 corrupted = 1; 00173 } else { 00174 current_domain->denial->domain = current_domain; 00175 current_domain->denial->nxt_changed = current_nxt; 00176 current_domain->denial->bitmap_changed = current_bm; 00177 new_node = denial2node(current_domain->denial); 00178 if (!zd->denial_chain) { 00179 zd->denial_chain = ldns_rbtree_create(domain_compare); 00180 } 00181 if (ldns_rbtree_insert(zd->denial_chain, new_node) == NULL) { 00182 se_log_error("error adding nsec domain from backup file"); 00183 se_free((void*)new_node); 00184 corrupted = 1; 00185 } 00186 new_node = NULL; 00187 00188 current_domain->denial->rrset = rrset_create_frm_rr(rr); 00189 if (!current_domain->denial->rrset) { 00190 se_log_error("error adding NSEC RR from backup file"); 00191 corrupted = 1; 00192 } 00193 } 00194 } 00195 00196 rr = NULL; 00197 status = LDNS_STATUS_OK; 00198 } else if (se_strcmp(token, ";NSEC3") == 0) { 00199 status = ldns_rr_new_frm_fp(&rr, fd, NULL, NULL, NULL); 00200 if (status != LDNS_STATUS_OK) { 00201 se_log_error("error reading NSEC3 RR from backup file"); 00202 if (rr) { 00203 ldns_rr_free(rr); 00204 } 00205 corrupted = 1; 00206 } else { 00207 se_log_assert(current_domain); 00208 se_log_assert(current_domain->denial); 00209 current_domain->denial->rrset = rrset_create_frm_rr(rr); 00210 if (!current_domain->denial->rrset) { 00211 se_log_error("error adding NSEC3 RR from backup file"); 00212 corrupted = 1; 00213 } 00214 } 00215 rr = NULL; 00216 status = LDNS_STATUS_OK; 00217 } else if (se_strcmp(token, ODS_SE_FILE_MAGIC) == 0) { 00218 se_free((void*)token); 00219 token = NULL; 00220 break; 00221 } else { 00222 corrupted = 1; 00223 } 00224 se_free((void*)token); 00225 token = NULL; 00226 } else { 00227 corrupted = 1; 00228 } 00229 } 00230 00231 return corrupted; 00232 } 00233 00234 00239 static ldns_rbnode_t* 00240 domain2node(domain_type* domain) 00241 { 00242 ldns_rbnode_t* node = (ldns_rbnode_t*) se_malloc(sizeof(ldns_rbnode_t)); 00243 if (!node) { 00244 return NULL; 00245 } 00246 node->key = domain->name; 00247 node->data = domain; 00248 return node; 00249 } 00250 00251 00256 static domain_type* 00257 zonedata_domain_search(ldns_rbtree_t* tree, ldns_rdf* name) 00258 { 00259 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00260 00261 if (!tree || !name) { 00262 return NULL; 00263 } 00264 node = ldns_rbtree_search(tree, name); 00265 if (node && node != LDNS_RBTREE_NULL) { 00266 return (domain_type*) node->data; 00267 } 00268 return NULL; 00269 } 00270 00271 00276 domain_type* 00277 zonedata_lookup_domain(zonedata_type* zd, ldns_rdf* name) 00278 { 00279 if (!zd || !zd->domains | !name) { 00280 return NULL; 00281 } 00282 return zonedata_domain_search(zd->domains, name); 00283 } 00284 00285 00290 domain_type* 00291 zonedata_add_domain(zonedata_type* zd, domain_type* domain) 00292 { 00293 ldns_rbnode_t* new_node = LDNS_RBTREE_NULL; 00294 char* str = NULL; 00295 00296 if (!domain) { 00297 se_log_error("unable to add domain: no domain"); 00298 return NULL; 00299 } 00300 se_log_assert(domain); 00301 se_log_assert(domain->rrsets); 00302 00303 if (!zd || !zd->domains) { 00304 str = ldns_rdf2str(domain->name); 00305 se_log_error("unable to add domain %s: no storage", 00306 str?str:"(null)"); 00307 free((void*)str); 00308 return NULL; 00309 } 00310 se_log_assert(zd); 00311 se_log_assert(zd->domains); 00312 00313 new_node = domain2node(domain); 00314 if (ldns_rbtree_insert(zd->domains, new_node) == NULL) { 00315 str = ldns_rdf2str(domain->name); 00316 se_log_error("unable to add domain %s: already present", 00317 str?str:"(null)"); 00318 se_free((void*)str); 00319 se_free((void*)new_node); 00320 return NULL; 00321 } 00322 str = ldns_rdf2str(domain->name); 00323 se_log_debug("+DD %s", str?str:"(null)"); 00324 se_free((void*) str); 00325 return domain; 00326 } 00327 00328 00333 static domain_type* 00334 zonedata_del_domain_fixup(ldns_rbtree_t* tree, domain_type* domain) 00335 { 00336 domain_type* del_domain = NULL; 00337 ldns_rbnode_t* del_node = LDNS_RBTREE_NULL; 00338 char* str = NULL; 00339 00340 se_log_assert(tree); 00341 se_log_assert(domain); 00342 se_log_assert(domain->name); 00343 00344 del_node = ldns_rbtree_search(tree, (const void*)domain->name); 00345 if (del_node) { 00346 del_node = ldns_rbtree_delete(tree, (const void*)domain->name); 00347 del_domain = (domain_type*) del_node->data; 00348 domain_cleanup(del_domain); 00349 free((void*)del_node); 00350 return NULL; 00351 } else { 00352 str = ldns_rdf2str(domain->name); 00353 se_log_error("unable to del domain %s: not found", 00354 str?str:"(null)"); 00355 free((void*)str); 00356 } 00357 return domain; 00358 } 00359 00360 00365 domain_type* 00366 zonedata_del_domain(zonedata_type* zd, domain_type* domain) 00367 { 00368 char* str = NULL; 00369 00370 if (!domain) { 00371 se_log_error("unable to delete domain: no domain"); 00372 return NULL; 00373 } 00374 se_log_assert(domain); 00375 se_log_assert(domain->name); 00376 00377 if (!zd || !zd->domains) { 00378 str = ldns_rdf2str(domain->name); 00379 se_log_error("unable to delete domain %s: no zonedata", 00380 str?str:"(null)"); 00381 free((void*)str); 00382 return domain; 00383 } 00384 se_log_assert(zd); 00385 se_log_assert(zd->domains); 00386 00387 str = ldns_rdf2str(domain->name); 00388 se_log_deeebug("-DD %s", str?str:"(null)"); 00389 if (domain->denial && zonedata_del_denial(zd, domain->denial) != NULL) { 00390 str = ldns_rdf2str(domain->name); 00391 se_log_error("unable to delete domain %s: failed to delete " 00392 "denial of existence data point", str?str:"(null)"); 00393 free((void*)str); 00394 return domain; 00395 } 00396 domain->denial = NULL; 00397 free((void*) str); 00398 return zonedata_del_domain_fixup(zd->domains, domain); 00399 } 00400 00405 static ldns_rbnode_t* 00406 denial2node(denial_type* denial) 00407 { 00408 ldns_rbnode_t* node = (ldns_rbnode_t*) malloc(sizeof(ldns_rbnode_t)); 00409 if (!node) { 00410 return NULL; 00411 } 00412 node->key = denial->owner; 00413 node->data = denial; 00414 return node; 00415 } 00416 00417 00422 static denial_type* 00423 zonedata_denial_search(ldns_rbtree_t* tree, ldns_rdf* dname) 00424 { 00425 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00426 00427 if (!tree || !dname) { 00428 return NULL; 00429 } 00430 node = ldns_rbtree_search(tree, dname); 00431 if (node && node != LDNS_RBTREE_NULL) { 00432 return (denial_type*) node->data; 00433 } 00434 return NULL; 00435 } 00436 00437 00442 denial_type* 00443 zonedata_lookup_denial(zonedata_type* zd, ldns_rdf* dname) 00444 { 00445 if (!zd || !zd->denial_chain | !dname) { 00446 return NULL; 00447 } 00448 return zonedata_denial_search(zd->denial_chain, dname); 00449 } 00450 00451 00456 static ldns_rdf* 00457 dname_hash(ldns_rdf* dname, ldns_rdf* apex, nsec3params_type* nsec3params) 00458 { 00459 ldns_rdf* hashed_ownername = NULL; 00460 ldns_rdf* hashed_label = NULL; 00461 char* str = NULL; 00462 00463 se_log_assert(dname); 00464 se_log_assert(apex); 00465 se_log_assert(nsec3params); 00466 00471 hashed_label = ldns_nsec3_hash_name(dname, nsec3params->algorithm, 00472 nsec3params->iterations, nsec3params->salt_len, 00473 nsec3params->salt_data); 00474 if (!hashed_label) { 00475 str = ldns_rdf2str(dname); 00476 se_log_error("unable to hash dname %s: hash failed", 00477 str?str:"(null)"); 00478 free((void*)str); 00479 return NULL; 00480 } 00481 hashed_ownername = ldns_dname_cat_clone((const ldns_rdf*) hashed_label, 00482 (const ldns_rdf*) apex); 00483 if (!hashed_ownername) { 00484 str = ldns_rdf2str(dname); 00485 se_log_error("unable to hash dname %s: concat apex failed", 00486 str?str:"(null)"); 00487 free((void*)str); 00488 return NULL; 00489 } 00490 ldns_rdf_deep_free(hashed_label); 00491 return hashed_ownername; 00492 } 00493 00494 00499 int 00500 zonedata_add_denial(zonedata_type* zd, domain_type* domain, ldns_rdf* apex, 00501 nsec3params_type* nsec3params) 00502 { 00503 ldns_rbnode_t* new_node = LDNS_RBTREE_NULL; 00504 ldns_rbnode_t* prev_node = LDNS_RBTREE_NULL; 00505 ldns_rdf* owner = NULL; 00506 denial_type* denial = NULL; 00507 denial_type* prev_denial = NULL; 00508 char* str = NULL; 00509 00510 if (!domain) { 00511 se_log_error("unable to add denial of existence data point: " 00512 "no domain"); 00513 return 1; 00514 } 00515 se_log_assert(domain); 00516 00517 if (!zd || !zd->denial_chain) { 00518 str = ldns_rdf2str(domain->name); 00519 se_log_error("unable to add denial of existence data point " 00520 "for domain %s: no denial chain", str?str:"(null)"); 00521 free((void*)str); 00522 return 1; 00523 } 00524 se_log_assert(zd); 00525 se_log_assert(zd->denial_chain); 00526 00527 if (!apex) { 00528 str = ldns_rdf2str(domain->name); 00529 se_log_error("unable to add denial of existence data point " 00530 "for domain %s: apex unknown", str?str:"(null)"); 00531 free((void*)str); 00532 return 1; 00533 } 00534 se_log_assert(apex); 00535 00536 /* nsec or nsec3 */ 00537 if (nsec3params) { 00538 owner = dname_hash(domain->name, apex, nsec3params); 00539 if (!owner) { 00540 str = ldns_rdf2str(domain->name); 00541 se_log_error("unable to add denial of existence data point " 00542 "for domain %s: dname hash failed", str?str:"(null)"); 00543 free((void*)str); 00544 return 1; 00545 } 00546 } else { 00547 owner = ldns_rdf_clone(domain->name); 00548 } 00549 /* lookup */ 00550 if (zonedata_lookup_denial(zd, owner) != NULL) { 00551 str = ldns_rdf2str(domain->name); 00552 se_log_error("unable to add denial of existence for %s: " 00553 "data point exists", str?str:"(null)"); 00554 free((void*)str); 00555 return 1; 00556 } 00557 /* create */ 00558 denial = denial_create(owner); 00559 new_node = denial2node(denial); 00560 ldns_rdf_deep_free(owner); 00561 /* insert */ 00562 if (!ldns_rbtree_insert(zd->denial_chain, new_node)) { 00563 str = ldns_rdf2str(domain->name); 00564 se_log_error("unable to add denial of existence for %s: " 00565 "insert failed", str?str:"(null)"); 00566 free((void*)str); 00567 free((void*)new_node); 00568 denial_cleanup(denial); 00569 return 1; 00570 } 00571 /* denial of existence data point added */ 00572 denial->bitmap_changed = 1; 00573 denial->nxt_changed = 1; 00574 prev_node = ldns_rbtree_previous(new_node); 00575 if (!prev_node || prev_node == LDNS_RBTREE_NULL) { 00576 prev_node = ldns_rbtree_last(zd->denial_chain); 00577 } 00578 se_log_assert(prev_node); 00579 prev_denial = (denial_type*) prev_node->data; 00580 se_log_assert(prev_denial); 00581 prev_denial->nxt_changed = 1; 00582 domain->denial = denial; 00583 domain->denial->domain = domain; /* back reference */ 00584 return 0; 00585 } 00586 00587 00592 static denial_type* 00593 zonedata_del_denial_fixup(ldns_rbtree_t* tree, denial_type* denial) 00594 { 00595 denial_type* del_denial = NULL; 00596 denial_type* prev_denial = NULL; 00597 ldns_rbnode_t* prev_node = LDNS_RBTREE_NULL; 00598 ldns_rbnode_t* del_node = LDNS_RBTREE_NULL; 00599 int error = 0; 00600 char* str = NULL; 00601 00602 se_log_assert(tree); 00603 se_log_assert(denial); 00604 se_log_assert(denial->owner); 00605 00606 del_node = ldns_rbtree_search(tree, (const void*)denial->owner); 00607 if (del_node) { 00612 prev_node = ldns_rbtree_previous(del_node); 00613 if (!prev_node || prev_node == LDNS_RBTREE_NULL) { 00614 prev_node = ldns_rbtree_last(tree); 00615 } 00616 se_log_assert(prev_node); 00617 se_log_assert(prev_node->data); 00618 prev_denial = (denial_type*) prev_node->data; 00619 prev_denial->nxt_changed = 1; 00620 00621 /* delete old NSEC RR(s) */ 00622 if (denial->rrset) { 00623 error = rrset_del_rrs(denial->rrset); 00624 if (error) { 00625 se_log_alert("unable to del denial of existence data " 00626 "point: failed to wipe out NSEC RRset"); 00627 return denial; 00628 } 00629 denial->rrset->initialized = 0; /* hack */ 00630 error = rrset_update(denial->rrset, 0); 00631 if (error) { 00632 se_log_alert("unable to del denial of existence data " 00633 "point: failed to commit NSEC RRset"); 00634 return denial; 00635 } 00636 } 00637 00638 del_node = ldns_rbtree_delete(tree, (const void*)denial->owner); 00639 del_denial = (denial_type*) del_node->data; 00640 denial_cleanup(del_denial); 00641 free((void*)del_node); 00642 return NULL; 00643 } else { 00644 str = ldns_rdf2str(denial->owner); 00645 se_log_error("unable to del denial of existence data point %s: " 00646 "not found", str?str:"(null)"); 00647 free((void*)str); 00648 } 00649 return denial; 00650 } 00651 00652 00657 denial_type* 00658 zonedata_del_denial(zonedata_type* zd, denial_type* denial) 00659 { 00660 char* str = NULL; 00661 00662 if (!denial) { 00663 se_log_error("unable to delete denial of existence data point: " 00664 "no data point"); 00665 return NULL; 00666 } 00667 se_log_assert(denial); 00668 00669 if (!zd || !zd->denial_chain) { 00670 str = ldns_rdf2str(denial->owner); 00671 se_log_error("unable to delete denial of existence data point " 00672 "%s: no zone data", str?str:"(null)"); 00673 free((void*)str); 00674 return denial; 00675 } 00676 se_log_assert(zd); 00677 se_log_assert(zd->denial_chain); 00678 00679 return zonedata_del_denial_fixup(zd->denial_chain, denial); 00680 } 00681 00682 00687 static int 00688 zonedata_domain_entize(zonedata_type* zd, domain_type* domain, ldns_rdf* apex) 00689 { 00690 int ent2unsigned_deleg = 0; 00691 ldns_rdf* parent_rdf = NULL; 00692 domain_type* parent_domain = NULL; 00693 char* str = NULL; 00694 00695 se_log_assert(apex); 00696 se_log_assert(domain); 00697 se_log_assert(domain->name); 00698 se_log_assert(zd); 00699 se_log_assert(zd->domains); 00700 00701 if (domain->parent) { 00702 /* domain already has parent */ 00703 return 0; 00704 } 00705 00706 if (domain_lookup_rrset(domain, LDNS_RR_TYPE_NS) && 00707 !domain_lookup_rrset(domain, LDNS_RR_TYPE_DS)) { 00708 /* empty non-terminal to unsigned delegation */ 00709 ent2unsigned_deleg = 1; 00710 } 00711 00712 while (domain && ldns_dname_is_subdomain(domain->name, apex) && 00713 ldns_dname_compare(domain->name, apex) != 0) { 00714 00715 str = ldns_rdf2str(domain->name); 00716 00724 parent_rdf = ldns_dname_left_chop(domain->name); 00725 if (!parent_rdf) { 00726 se_log_error("entize: unable to create parent rdf for %s", str); 00727 se_free((void*)str); 00728 return 1; 00729 } 00730 00731 parent_domain = zonedata_lookup_domain(zd, parent_rdf); 00732 if (!parent_domain) { 00733 se_log_deeebug("create parent domain for %s", str); 00734 parent_domain = domain_create(parent_rdf); 00735 ldns_rdf_deep_free(parent_rdf); 00736 se_log_deeebug("add parent domain to %s", str); 00737 parent_domain = zonedata_add_domain(zd, parent_domain); 00738 if (!parent_domain) { 00739 se_log_error("unable to add parent domain to %s", str); 00740 se_free((void*)str); 00741 return 1; 00742 } 00743 parent_domain->domain_status = 00744 (ent2unsigned_deleg?DOMAIN_STATUS_ENT_NS: 00745 DOMAIN_STATUS_ENT_AUTH); 00746 parent_domain->subdomain_count = 1; 00747 if (!ent2unsigned_deleg) { 00748 parent_domain->subdomain_auth = 1; 00749 } 00750 parent_domain->internal_serial = domain->internal_serial; 00751 domain->parent = parent_domain; 00752 /* continue with the parent domain */ 00753 domain = parent_domain; 00754 } else { 00755 se_log_deeebug("entize domain %s", str); 00756 ldns_rdf_deep_free(parent_rdf); 00757 parent_domain->internal_serial = domain->internal_serial; 00758 parent_domain->subdomain_count += 1; 00759 if (!ent2unsigned_deleg) { 00760 parent_domain->subdomain_auth += 1; 00761 } 00762 domain->parent = parent_domain; 00763 if (domain_count_rrset(parent_domain) <= 0 && 00764 parent_domain->domain_status != DOMAIN_STATUS_ENT_AUTH) { 00765 parent_domain->domain_status = 00766 (ent2unsigned_deleg?DOMAIN_STATUS_ENT_NS: 00767 DOMAIN_STATUS_ENT_AUTH); 00768 } 00769 /* done */ 00770 domain = NULL; 00771 } 00772 se_free((void*)str); 00773 } 00774 return 0; 00775 } 00776 00777 00782 static void 00783 zonedata_domain_entize_revised(domain_type* domain, int status) 00784 { 00785 domain_type* parent = NULL; 00786 if (!domain) { 00787 return; 00788 } 00789 parent = domain->parent; 00790 while (parent) { 00791 if (parent->domain_status == DOMAIN_STATUS_ENT_AUTH || 00792 parent->domain_status == DOMAIN_STATUS_ENT_GLUE || 00793 parent->domain_status == DOMAIN_STATUS_ENT_NS) { 00794 parent->domain_status = status; 00795 } else { 00796 break; 00797 } 00798 parent = parent->parent; 00799 } 00800 return; 00801 } 00802 00803 00808 int 00809 zonedata_entize(zonedata_type* zd, ldns_rdf* apex) 00810 { 00811 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00812 domain_type* domain = NULL; 00813 int prev_status = DOMAIN_STATUS_NONE; 00814 00815 se_log_assert(apex); 00816 se_log_assert(zd); 00817 se_log_assert(zd->domains); 00818 00819 node = ldns_rbtree_first(zd->domains); 00820 while (node && node != LDNS_RBTREE_NULL) { 00821 domain = (domain_type*) node->data; 00822 if (zonedata_domain_entize(zd, domain, apex) != 0) { 00823 se_log_error("error adding enmpty non-terminals to domain"); 00824 return 1; 00825 } 00826 /* domain has parent now, check for glue */ 00827 prev_status = domain->domain_status; 00828 domain_update_status(domain); 00829 if (domain->domain_status == DOMAIN_STATUS_OCCLUDED && 00830 prev_status != DOMAIN_STATUS_OCCLUDED) { 00831 zonedata_domain_entize_revised(domain, DOMAIN_STATUS_ENT_GLUE); 00832 } 00833 node = ldns_rbtree_next(node); 00834 } 00835 return 0; 00836 } 00837 00842 int 00843 zonedata_nsecify(zonedata_type* zd, ldns_rr_class klass, stats_type* stats) 00844 { 00845 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00846 ldns_rbnode_t* nxt_node = LDNS_RBTREE_NULL; 00847 domain_type* domain = NULL; 00848 domain_type* apex = NULL; 00849 denial_type* denial = NULL; 00850 denial_type* nxt = NULL; 00851 size_t nsec_added = 0; 00852 int error = 0; 00853 00854 if (!zd || !zd->domains) { 00855 return 0; 00856 } 00857 se_log_assert(zd); 00858 se_log_assert(zd->domains); 00859 00860 node = ldns_rbtree_first(zd->domains); 00861 while (node && node != LDNS_RBTREE_NULL) { 00862 domain = (domain_type*) node->data; 00863 if (domain->domain_status == DOMAIN_STATUS_APEX) { 00864 apex = domain; 00865 } 00866 /* don't do glue-only or empty domains */ 00867 if (domain->domain_status == DOMAIN_STATUS_NONE || 00868 domain->domain_status == DOMAIN_STATUS_OCCLUDED || 00869 domain_count_rrset(domain) <= 0) { 00870 if (domain->denial) { 00871 if (zonedata_del_denial(zd, domain->denial) != NULL) { 00872 se_log_warning("unable to nsecify: failed to " 00873 "delete denial of existence data point"); 00874 return 1; 00875 } 00876 domain->denial = NULL; 00877 } 00878 node = ldns_rbtree_next(node); 00879 continue; 00880 } 00881 if (!apex) { 00882 se_log_alert("unable to nsecify: apex unknown"); 00883 return 1; 00884 } 00885 00886 /* add the denial of existence */ 00887 if (!domain->denial) { 00888 error = zonedata_add_denial(zd, domain, apex->name, NULL); 00889 if (error) { 00890 se_log_alert("unable to nsecify: failed to add denial " 00891 "of existence for domain"); 00892 return error; 00893 } 00894 nsec_added++; 00895 } 00896 node = ldns_rbtree_next(node); 00897 } 00898 00900 node = ldns_rbtree_first(zd->denial_chain); 00901 while (node && node != LDNS_RBTREE_NULL) { 00902 denial = (denial_type*) node->data; 00903 nxt_node = ldns_rbtree_next(node); 00904 if (!nxt_node || nxt_node == LDNS_RBTREE_NULL) { 00905 nxt_node = ldns_rbtree_first(zd->denial_chain); 00906 } 00907 nxt = (denial_type*) nxt_node->data; 00908 00909 error = denial_nsecify(denial, nxt, zd->default_ttl, klass); 00910 if (error) { 00911 se_log_error("unable to nsecify: failed to add NSEC record"); 00912 return error; 00913 } 00914 node = ldns_rbtree_next(node); 00915 } 00916 if (stats) { 00917 stats->nsec_count = nsec_added; 00918 } 00919 return 0; 00920 } 00921 00922 00927 int 00928 zonedata_nsecify3(zonedata_type* zd, ldns_rr_class klass, 00929 nsec3params_type* nsec3params, stats_type* stats) 00930 { 00931 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 00932 ldns_rbnode_t* nxt_node = LDNS_RBTREE_NULL; 00933 domain_type* domain = NULL; 00934 domain_type* apex = NULL; 00935 denial_type* denial = NULL; 00936 denial_type* nxt = NULL; 00937 char* str = NULL; 00938 size_t nsec3_added = 0; 00939 int error = 0; 00940 00941 if (!zd || !zd->domains) { 00942 return 0; 00943 } 00944 se_log_assert(zd); 00945 se_log_assert(zd->domains); 00946 00947 if (!nsec3params) { 00948 se_log_error("unable to nsecify3: no nsec3 paramaters"); 00949 return 1; 00950 } 00951 se_log_assert(nsec3params); 00952 00953 if (!zd->denial_chain) { 00954 se_log_debug("create new nsec3 domain tree"); 00955 zd->denial_chain = ldns_rbtree_create(domain_compare); 00956 } 00957 00958 node = ldns_rbtree_first(zd->domains); 00959 while (node && node != LDNS_RBTREE_NULL) { 00960 domain = (domain_type*) node->data; 00961 if (domain->domain_status == DOMAIN_STATUS_APEX) { 00962 apex = domain; 00963 } 00964 00965 /* don't do glue-only domains */ 00966 if (domain->domain_status == DOMAIN_STATUS_NONE || 00967 domain->domain_status == DOMAIN_STATUS_OCCLUDED || 00968 domain->domain_status == DOMAIN_STATUS_ENT_GLUE) { 00969 str = ldns_rdf2str(domain->name); 00970 se_log_debug("nsecify3: skip glue domain %s", str?str:"(null)"); 00971 se_free((void*) str); 00972 if (domain->denial) { 00973 if (zonedata_del_denial(zd, domain->denial) != NULL) { 00974 se_log_error("unable to nsecify3: failed to " 00975 "delete denial of existence data point"); 00976 return 1; 00977 } 00978 domain->denial = NULL; 00979 } 00980 node = ldns_rbtree_next(node); 00981 continue; 00982 } 00983 /* Opt-Out? */ 00984 if (nsec3params->flags) { 00985 /* If Opt-Out is being used, owner names of unsigned delegations 00986 MAY be excluded. */ 00987 if (domain->domain_status == DOMAIN_STATUS_NS || 00988 domain->domain_status == DOMAIN_STATUS_ENT_NS) { 00989 str = ldns_rdf2str(domain->name); 00990 se_log_debug("opt-out %s: %s", str?str:"(null)", 00991 domain->domain_status == DOMAIN_STATUS_NS ? 00992 "unsigned delegation" : "empty non-terminal (to unsigned " 00993 "delegation)"); 00994 se_free((void*) str); 00995 if (domain->denial) { 00996 if (zonedata_del_denial(zd, domain->denial) != NULL) { 00997 se_log_error("unable to nsecify3: failed to " 00998 "delete denial of existence data point"); 00999 return 1; 01000 } 01001 domain->denial = NULL; 01002 } 01003 node = ldns_rbtree_next(node); 01004 continue; 01005 } 01006 } 01007 01008 if (!apex) { 01009 se_log_alert("apex undefined!, aborting nsecify3"); 01010 return 1; 01011 } 01012 01013 /* add the denial of existence */ 01014 if (!domain->denial) { 01015 error = zonedata_add_denial(zd, domain, apex->name, nsec3params); 01016 if (error) { 01017 str = ldns_rdf2str(domain->name); 01018 se_log_alert("unable to nsecify3: failed to add denial " 01019 "of existence for domain %s", str?str:"(null)"); 01020 free((void*) str); 01021 return error; 01022 } 01023 nsec3_added++; 01024 } 01025 01026 /* The Next Hashed Owner Name field is left blank for the moment. */ 01027 01035 /* [TODO] */ 01045 node = ldns_rbtree_next(node); 01046 } 01047 01048 /* Now we have the complete NSEC3 tree */ 01049 01056 node = ldns_rbtree_first(zd->denial_chain); 01057 while (node && node != LDNS_RBTREE_NULL) { 01058 denial = (denial_type*) node->data; 01059 nxt_node = ldns_rbtree_next(node); 01060 if (!nxt_node || nxt_node == LDNS_RBTREE_NULL) { 01061 nxt_node = ldns_rbtree_first(zd->denial_chain); 01062 } 01063 nxt = (denial_type*) nxt_node->data; 01064 01065 error = denial_nsecify3(denial, nxt, zd->default_ttl, klass, 01066 nsec3params); 01067 if (error) { 01068 se_log_error("unable to nsecify3: failed to add NSEC3 " 01069 "record"); 01070 return error; 01071 } 01072 node = ldns_rbtree_next(node); 01073 } 01074 if (stats) { 01075 stats->nsec_count = nsec3_added; 01076 } 01077 return 0; 01078 } 01079 01080 01081 static int 01082 se_max(uint32_t a, uint32_t b) 01083 { 01084 return (a>b?a:b); 01085 } 01086 01087 01092 static int 01093 zonedata_update_serial(zonedata_type* zd, signconf_type* sc) 01094 { 01095 uint32_t soa = 0; 01096 uint32_t prev = 0; 01097 uint32_t update = 0; 01098 01099 se_log_assert(zd); 01100 se_log_assert(sc); 01101 01102 prev = zd->internal_serial; 01103 se_log_debug("update serial: inbound=%u internal=%u outbound=%u now=%u", 01104 zd->inbound_serial, zd->internal_serial, zd->outbound_serial, 01105 (uint32_t) time_now()); 01106 01107 if (!sc->soa_serial) { 01108 se_log_error("no serial type given"); 01109 return 1; 01110 } 01111 01112 if (se_strcmp(sc->soa_serial, "unixtime") == 0) { 01113 soa = se_max(zd->inbound_serial, (uint32_t) time_now()); 01114 if (!DNS_SERIAL_GT(soa, prev)) { 01115 soa = prev + 1; 01116 } 01117 update = soa - prev; 01118 } else if (strncmp(sc->soa_serial, "counter", 7) == 0) { 01119 soa = se_max(zd->inbound_serial, prev); 01120 if (!zd->initialized) { 01121 zd->internal_serial = soa + 1; 01122 zd->initialized = 1; 01123 return 0; 01124 } 01125 if (!DNS_SERIAL_GT(soa, prev)) { 01126 soa = prev + 1; 01127 } 01128 update = soa - prev; 01129 } else if (strncmp(sc->soa_serial, "datecounter", 11) == 0) { 01130 soa = (uint32_t) time_datestamp(0, "%Y%m%d", NULL) * 100; 01131 soa = se_max(zd->inbound_serial, soa); 01132 if (!DNS_SERIAL_GT(soa, prev)) { 01133 soa = prev + 1; 01134 } 01135 update = soa - prev; 01136 } else if (strncmp(sc->soa_serial, "keep", 4) == 0) { 01137 soa = zd->inbound_serial; 01138 if (zd->initialized && !DNS_SERIAL_GT(soa, prev)) { 01139 se_log_error("cannot keep SOA SERIAL from input zone " 01140 " (%u): output SOA SERIAL is %u", soa, prev); 01141 return 1; 01142 } 01143 prev = soa; 01144 update = 0; 01145 } else { 01146 se_log_error("unknown serial type %s", sc->soa_serial); 01147 return 1; 01148 } 01149 01150 if (!zd->initialized) { 01151 zd->initialized = 1; 01152 } 01153 01154 /* serial is stored in 32 bits */ 01155 if (update > 0x7FFFFFFF) { 01156 update = 0x7FFFFFFF; 01157 } 01158 zd->internal_serial = (prev + update); /* automatically does % 2^32 */ 01159 se_log_debug("update serial: previous=%u update=%u new=%u", 01160 prev, update, zd->internal_serial); 01161 return 0; 01162 } 01163 01164 01169 int 01170 zonedata_sign(zonedata_type* zd, ldns_rdf* owner, signconf_type* sc, 01171 stats_type* stats) 01172 { 01173 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01174 domain_type* domain = NULL; 01175 time_t now = 0; 01176 hsm_ctx_t* ctx = NULL; 01177 int error = 0; 01178 01179 se_log_assert(sc); 01180 se_log_assert(zd); 01181 se_log_assert(zd->domains); 01182 01183 if (!DNS_SERIAL_GT(zd->internal_serial, zd->outbound_serial)) { 01184 error = zonedata_update_serial(zd, sc); 01185 } 01186 if (error || !zd->internal_serial) { 01187 se_log_error("unable to sign zone data: failed to update serial"); 01188 return 1; 01189 } 01190 01191 now = time_now(); 01192 ctx = hsm_create_context(); 01193 if (!ctx) { 01194 se_log_error("error creating libhsm context"); 01195 return 2; 01196 } 01197 01198 se_log_debug("rrsig timers: offset=%u jitter=%u validity=%u", 01199 duration2time(sc->sig_inception_offset), 01200 duration2time(sc->sig_jitter), 01201 duration2time(sc->sig_validity_denial)); 01202 01203 node = ldns_rbtree_first(zd->domains); 01204 while (node && node != LDNS_RBTREE_NULL) { 01205 domain = (domain_type*) node->data; 01206 if (domain_sign(ctx, domain, owner, sc, now, zd->internal_serial, 01207 stats) != 0) { 01208 se_log_error("unable to sign zone data: failed to sign domain"); 01209 hsm_destroy_context(ctx); 01210 return 1; 01211 } 01212 node = ldns_rbtree_next(node); 01213 } 01214 hsm_destroy_context(ctx); 01215 return 0; 01216 } 01217 01218 01223 static int 01224 zonedata_examine_domain_is_occluded(zonedata_type* zd, domain_type* domain, 01225 ldns_rdf* apex) 01226 { 01227 ldns_rdf* parent_rdf = NULL; 01228 ldns_rdf* next_rdf = NULL; 01229 domain_type* parent_domain = NULL; 01230 char* str_name = NULL; 01231 char* str_parent = NULL; 01232 01233 se_log_assert(apex); 01234 se_log_assert(domain); 01235 se_log_assert(domain->name); 01236 se_log_assert(zd); 01237 se_log_assert(zd->domains); 01238 01239 if (ldns_dname_compare(domain->name, apex) == 0) { 01240 return 0; 01241 } 01242 01243 if (domain_examine_valid_zonecut(domain) != 0) { 01244 str_name = ldns_rdf2str(domain->name); 01245 se_log_error("occluded (non-glue non-DS) data at %s NS", str_name); 01246 se_free((void*)str_name); 01247 return 1; 01248 } 01249 01250 parent_rdf = ldns_dname_left_chop(domain->name); 01251 while (parent_rdf && ldns_dname_is_subdomain(parent_rdf, apex) && 01252 ldns_dname_compare(parent_rdf, apex) != 0) { 01253 01254 parent_domain = zonedata_lookup_domain(zd, parent_rdf); 01255 next_rdf = ldns_dname_left_chop(parent_rdf); 01256 ldns_rdf_deep_free(parent_rdf); 01257 01258 if (parent_domain) { 01259 /* check for DNAME or NS */ 01260 if (domain_examine_data_exists(parent_domain, LDNS_RR_TYPE_DNAME, 01261 0) == 0 && domain_examine_data_exists(domain, 0, 0) == 0) { 01262 /* data below DNAME */ 01263 str_name = ldns_rdf2str(domain->name); 01264 str_parent = ldns_rdf2str(parent_domain->name); 01265 se_log_error("occluded data at %s (below %s DNAME)", str_name, 01266 str_parent); 01267 se_free((void*)str_name); 01268 se_free((void*)str_parent); 01269 return 1; 01270 } else if (domain_examine_data_exists(parent_domain, 01271 LDNS_RR_TYPE_NS, 0) == 0 && 01272 domain_examine_data_exists(domain, 0, 1) == 0) { 01273 /* data (non-glue) below NS */ 01274 str_name = ldns_rdf2str(domain->name); 01275 str_parent = ldns_rdf2str(parent_domain->name); 01276 se_log_error("occluded (non-glue) data at %s (below %s NS)", 01277 str_name, str_parent); 01278 se_free((void*)str_name); 01279 se_free((void*)str_parent); 01280 return 1; 01281 } else if (domain_examine_data_exists(parent_domain, 01282 LDNS_RR_TYPE_NS, 0) == 0 && 01283 domain_examine_data_exists(domain, 0, 0) == 0 && 01284 domain_examine_ns_rdata(parent_domain, domain->name) != 0) { 01285 /* glue data not signalled by NS RDATA */ 01286 str_name = ldns_rdf2str(domain->name); 01287 str_parent = ldns_rdf2str(parent_domain->name); 01288 se_log_error("occluded data at %s (below %s NS)", 01289 str_name, str_parent); 01290 se_free((void*)str_name); 01291 se_free((void*)str_parent); 01292 return 1; 01293 } 01294 } 01295 01296 parent_rdf = next_rdf; 01297 } 01298 01299 if (parent_rdf) { 01300 ldns_rdf_deep_free(parent_rdf); 01301 } 01302 return 0; 01303 } 01304 01305 01310 int 01311 zonedata_examine(zonedata_type* zd, ldns_rdf* apex, int is_file) 01312 { 01313 int error = 0; 01314 int result = 0; 01315 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01316 domain_type* domain = NULL; 01317 01318 se_log_assert(zd); 01319 se_log_assert(zd->domains); 01320 01321 if (zd->domains->root != LDNS_RBTREE_NULL) { 01322 node = ldns_rbtree_first(zd->domains); 01323 } 01324 while (node && node != LDNS_RBTREE_NULL) { 01325 domain = (domain_type*) node->data; 01326 error = 01327 /* Thou shall not have other data next to CNAME */ 01328 domain_examine_rrset_is_alone(domain, LDNS_RR_TYPE_CNAME) || 01329 /* Thou shall have at most one CNAME per name */ 01330 domain_examine_rrset_is_singleton(domain, LDNS_RR_TYPE_CNAME) || 01331 /* Thou shall have at most one DNAME per name */ 01332 domain_examine_rrset_is_singleton(domain, LDNS_RR_TYPE_DNAME); 01333 if (error) { 01334 result = error; 01335 } 01336 01337 if (is_file) { 01338 error = 01339 /* Thou shall not have occluded data in your zone file */ 01340 zonedata_examine_domain_is_occluded(zd, domain, apex); 01341 if (error) { 01342 result = error; 01343 } 01344 } 01345 01346 node = ldns_rbtree_next(node); 01347 } 01348 01349 return result; 01350 } 01351 01352 01357 int 01358 zonedata_update(zonedata_type* zd, signconf_type* sc) 01359 { 01360 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01361 domain_type* domain = NULL; 01362 domain_type* parent = NULL; 01363 int error = 0; 01364 01365 se_log_assert(sc); 01366 se_log_assert(zd); 01367 se_log_assert(zd->domains); 01368 01369 error = zonedata_update_serial(zd, sc); 01370 if (error || !zd->internal_serial) { 01371 se_log_error("unable to update zonedata: failed to update serial"); 01372 zonedata_cancel_update(zd); 01373 return 1; 01374 } 01375 01376 if (zd->domains->root != LDNS_RBTREE_NULL) { 01377 node = ldns_rbtree_first(zd->domains); 01378 } 01379 while (node && node != LDNS_RBTREE_NULL) { 01380 domain = (domain_type*) node->data; 01381 error = domain_update(domain, zd->internal_serial); 01382 if (error != 0) { 01383 if (error == 1) { 01384 se_log_crit("unable to update zonedata to serial %u: rr " 01385 "compare function failed", zd->internal_serial); 01386 /* If this happens, the zone is partially updated. */ 01387 } else { 01388 se_log_error("unable to update zonedata to serial %u: " 01389 "serial too small", zd->internal_serial); 01390 zonedata_cancel_update(zd); 01391 return 1; 01392 } 01393 return 1; 01394 } 01395 node = ldns_rbtree_next(node); 01396 01397 /* delete memory of domain if no RRsets exists */ 01398 /* if this domain is now an empty non-terminal, don't delete */ 01399 01400 if (domain_count_rrset(domain) <= 0 && 01401 (domain->domain_status != DOMAIN_STATUS_ENT_AUTH && 01402 domain->domain_status != DOMAIN_STATUS_ENT_NS && 01403 domain->domain_status != DOMAIN_STATUS_ENT_GLUE)) { 01404 01405 parent = domain->parent; 01406 if (domain->subdomain_count <= 0) { 01407 se_log_deeebug("obsoleted domain: #rrset=%i, status=%i", 01408 domain_count_rrset(domain), domain->domain_status); 01409 domain = zonedata_del_domain(zd, domain); 01410 if (domain) { 01411 se_log_error("failed to delete obsoleted domain"); 01412 } 01413 } 01414 while (parent && domain_count_rrset(parent) <= 0) { 01415 domain = parent; 01416 parent = domain->parent; 01417 if (domain->subdomain_count <= 0) { 01418 domain = zonedata_del_domain(zd, domain); 01419 if (domain) { 01420 se_log_error("failed to delete obsoleted domain"); 01421 } 01422 } 01423 } 01424 } 01425 } 01426 return 0; 01427 } 01428 01429 01434 void 01435 zonedata_cancel_update(zonedata_type* zd) 01436 { 01437 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01438 domain_type* domain = NULL; 01439 01440 se_log_assert(zd); 01441 se_log_assert(zd->domains); 01442 01443 if (zd->domains->root != LDNS_RBTREE_NULL) { 01444 node = ldns_rbtree_first(zd->domains); 01445 } 01446 while (node && node != LDNS_RBTREE_NULL) { 01447 domain = (domain_type*) node->data; 01448 domain_cancel_update(domain); 01449 node = ldns_rbtree_next(node); 01450 } 01451 return; 01452 } 01453 01454 01459 int 01460 zonedata_add_rr(zonedata_type* zd, ldns_rr* rr, int at_apex) 01461 { 01462 domain_type* domain = NULL; 01463 01464 se_log_assert(zd); 01465 se_log_assert(zd->domains); 01466 se_log_assert(rr); 01467 01468 domain = zonedata_lookup_domain(zd, ldns_rr_owner(rr)); 01469 if (domain) { 01470 return domain_add_rr(domain, rr); 01471 } 01472 /* no domain with this name yet */ 01473 domain = domain_create(ldns_rr_owner(rr)); 01474 domain = zonedata_add_domain(zd, domain); 01475 if (!domain) { 01476 se_log_error("unable to add RR to zonedata: failed to add domain"); 01477 return 1; 01478 } 01479 if (at_apex) { 01480 domain->domain_status = DOMAIN_STATUS_APEX; 01481 } 01482 return domain_add_rr(domain, rr); 01483 } 01484 01485 01490 int 01491 zonedata_recover_rr_from_backup(zonedata_type* zd, ldns_rr* rr) 01492 { 01493 domain_type* domain = NULL; 01494 01495 se_log_assert(zd); 01496 se_log_assert(zd->domains); 01497 se_log_assert(rr); 01498 01499 domain = zonedata_lookup_domain(zd, ldns_rr_owner(rr)); 01500 if (domain) { 01501 return domain_recover_rr_from_backup(domain, rr); 01502 } 01503 01504 se_log_error("unable to recover RR to zonedata: domain does not exist"); 01505 return 1; 01506 } 01507 01508 01513 int 01514 zonedata_recover_rrsig_from_backup(zonedata_type* zd, ldns_rr* rrsig, 01515 const char* locator, uint32_t flags) 01516 { 01517 domain_type* domain = NULL; 01518 denial_type* denial = NULL; 01519 ldns_rr_type type_covered; 01520 01521 se_log_assert(zd); 01522 se_log_assert(zd->domains); 01523 se_log_assert(rrsig); 01524 01525 type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)); 01526 if (type_covered == LDNS_RR_TYPE_NSEC3 || 01527 type_covered == LDNS_RR_TYPE_NSEC) { 01528 denial = zonedata_lookup_denial(zd, ldns_rr_owner(rrsig)); 01529 if (denial) { 01530 return denial_recover_rrsig_from_backup(denial, rrsig, type_covered, 01531 locator, flags); 01532 } 01533 } else { 01534 domain = zonedata_lookup_domain(zd, ldns_rr_owner(rrsig)); 01535 if (domain) { 01536 return domain_recover_rrsig_from_backup(domain, rrsig, type_covered, 01537 locator, flags); 01538 } 01539 } 01540 se_log_error("unable to recover RRSIG to zonedata: domain does not exist"); 01541 return 1; 01542 } 01543 01544 01549 int 01550 zonedata_del_rr(zonedata_type* zd, ldns_rr* rr) 01551 { 01552 domain_type* domain = NULL; 01553 01554 se_log_assert(zd); 01555 se_log_assert(zd->domains); 01556 se_log_assert(rr); 01557 01558 domain = zonedata_lookup_domain(zd, ldns_rr_owner(rr)); 01559 if (domain) { 01560 return domain_del_rr(domain, rr); 01561 } 01562 /* no domain with this name yet */ 01563 se_log_warning("unable to delete RR from zonedata: no such domain"); 01564 return 0; 01565 } 01566 01567 01572 int 01573 zonedata_del_rrs(zonedata_type* zd) 01574 { 01575 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01576 domain_type* domain = NULL; 01577 01578 se_log_assert(zd); 01579 se_log_assert(zd->domains); 01580 01581 if (zd->domains->root != LDNS_RBTREE_NULL) { 01582 node = ldns_rbtree_first(zd->domains); 01583 } 01584 while (node && node != LDNS_RBTREE_NULL) { 01585 domain = (domain_type*) node->data; 01586 if (domain_del_rrs(domain) != 0) { 01587 return 1; 01588 } 01589 node = ldns_rbtree_next(node); 01590 } 01591 return 0; 01592 } 01593 01594 01599 void 01600 zonedata_cleanup_domains(ldns_rbtree_t* domain_tree) 01601 { 01602 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01603 domain_type* domain = NULL; 01604 01605 if (domain_tree && domain_tree->root != LDNS_RBTREE_NULL) { 01606 node = ldns_rbtree_first(domain_tree); 01607 } 01608 while (node && node != LDNS_RBTREE_NULL) { 01609 domain = (domain_type*) node->data; 01610 domain_cleanup(domain); 01611 node = ldns_rbtree_next(node); 01612 } 01613 if (domain_tree && domain_tree->root != LDNS_RBTREE_NULL) { 01614 se_rbnode_free(domain_tree->root); 01615 } 01616 if (domain_tree) { 01617 ldns_rbtree_free(domain_tree); 01618 } 01619 return; 01620 } 01621 01622 01627 void 01628 zonedata_cleanup_denials(ldns_rbtree_t* denial_tree) 01629 { 01630 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01631 denial_type* denial = NULL; 01632 01633 if (denial_tree && denial_tree->root != LDNS_RBTREE_NULL) { 01634 node = ldns_rbtree_first(denial_tree); 01635 } 01636 while (node && node != LDNS_RBTREE_NULL) { 01637 denial = (denial_type*) node->data; 01638 denial_cleanup(denial); 01639 node = ldns_rbtree_next(node); 01640 } 01641 if (denial_tree && denial_tree->root != LDNS_RBTREE_NULL) { 01642 se_rbnode_free(denial_tree->root); 01643 } 01644 if (denial_tree) { 01645 ldns_rbtree_free(denial_tree); 01646 } 01647 return; 01648 } 01649 01650 01655 void 01656 zonedata_cleanup(zonedata_type* zonedata) 01657 { 01658 /* destroy domains */ 01659 if (zonedata) { 01660 if (zonedata->domains) { 01661 zonedata_cleanup_domains(zonedata->domains); 01662 zonedata->domains = NULL; 01663 } 01664 if (zonedata->denial_chain) { 01665 zonedata_cleanup_denials(zonedata->denial_chain); 01666 zonedata->denial_chain = NULL; 01667 } 01668 se_free((void*) zonedata); 01669 } else { 01670 se_log_warning("cleanup empty zone data"); 01671 } 01672 return; 01673 } 01674 01675 01680 void 01681 zonedata_print(FILE* fd, zonedata_type* zd) 01682 { 01683 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01684 domain_type* domain = NULL; 01685 01686 se_log_assert(fd); 01687 se_log_assert(zd); 01688 se_log_assert(zd->domains); 01689 01690 node = ldns_rbtree_first(zd->domains); 01691 if (!node || node == LDNS_RBTREE_NULL) { 01692 fprintf(fd, "; zone empty\n"); 01693 return; 01694 } 01695 while (node && node != LDNS_RBTREE_NULL) { 01696 domain = (domain_type*) node->data; 01697 domain_print(fd, domain); 01698 node = ldns_rbtree_next(node); 01699 } 01700 01701 return; 01702 } 01703 01704 01709 void 01710 zonedata_print_nsec(FILE* fd, zonedata_type* zd) 01711 { 01712 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01713 domain_type* domain = NULL; 01714 01715 se_log_assert(fd); 01716 se_log_assert(zd); 01717 se_log_assert(zd->domains); 01718 01719 node = ldns_rbtree_first(zd->domains); 01720 if (!node || node == LDNS_RBTREE_NULL) { 01721 fprintf(fd, "; zone empty\n"); 01722 return; 01723 } 01724 01725 while (node && node != LDNS_RBTREE_NULL) { 01726 domain = (domain_type*) node->data; 01727 domain_print_nsec(fd, domain); 01728 node = ldns_rbtree_next(node); 01729 } 01730 return; 01731 } 01732 01733 01738 void 01739 zonedata_print_rrsig(FILE* fd, zonedata_type* zd) 01740 { 01741 ldns_rbnode_t* node = LDNS_RBTREE_NULL; 01742 domain_type* domain = NULL; 01743 01744 se_log_assert(fd); 01745 se_log_assert(zd); 01746 se_log_assert(zd->domains); 01747 01748 node = ldns_rbtree_first(zd->domains); 01749 if (!node || node == LDNS_RBTREE_NULL) { 01750 fprintf(fd, "; zone empty\n"); 01751 return; 01752 } 01753 01754 while (node && node != LDNS_RBTREE_NULL) { 01755 domain = (domain_type*) node->data; 01756 domain_print_rrsig(fd, domain); 01757 node = ldns_rbtree_next(node); 01758 } 01759 return; 01760 }