OpenDNSSEC-signer 1.2.1

/build/buildd-opendnssec_1.2.1.dfsg-1-mips-p9AT07/opendnssec-1.2.1.dfsg/signer/src/signer/zonedata.c

Go to the documentation of this file.
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, &current_nxt,
00111                     &current_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 }