OpenDNSSEC-signer  1.3.4
/build/buildd/opendnssec-1.3.4/signer/src/signer/zone.c
Go to the documentation of this file.
00001 /*
00002  * $Id: zone.c 5802 2011-10-19 14:07:31Z 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 "adapter/adapi.h"
00035 #include "adapter/adapter.h"
00036 #include "scheduler/schedule.h"
00037 #include "scheduler/task.h"
00038 #include "shared/allocator.h"
00039 #include "shared/file.h"
00040 #include "shared/hsm.h"
00041 #include "shared/locks.h"
00042 #include "shared/log.h"
00043 #include "shared/status.h"
00044 #include "shared/util.h"
00045 #include "signer/backup.h"
00046 #include "signer/nsec3params.h"
00047 #include "signer/signconf.h"
00048 #include "signer/zone.h"
00049 #include "signer/zonedata.h"
00050 
00051 #include <ldns/ldns.h>
00052 
00053 static const char* zone_str = "zone";
00054 
00055 
00060 zone_type*
00061 zone_create(char* name, ldns_rr_class klass)
00062 {
00063     allocator_type* allocator = NULL;
00064     zone_type* zone = NULL;
00065 
00066     if (!name || !klass) {
00067         ods_log_error("[%s] unable to create zone: no name or class",
00068             zone_str);
00069         return NULL;
00070     }
00071 
00072     allocator = allocator_create(malloc, free);
00073     if (!allocator) {
00074         ods_log_error("[%s] unable to create zone %s: create allocator "
00075             "failed", zone_str, name);
00076         return NULL;
00077     }
00078     ods_log_assert(allocator);
00079 
00080     zone = (zone_type*) allocator_alloc(allocator, sizeof(zone_type));
00081     if (!zone) {
00082         ods_log_error("[%s] unable to create zone %s: allocator failed",
00083             zone_str, name);
00084         allocator_cleanup(allocator);
00085         return NULL;
00086     }
00087     ods_log_assert(zone);
00088 
00089     zone->allocator = allocator;
00090     /* [start] PS 9218653: Drop trailing dot in domain name */
00091     if (strlen(name) > 1 && name[strlen(name)-1] == '.') {
00092         name[strlen(name)-1] = '\0';
00093     }
00094     /* [end] PS 9218653 */
00095     zone->name = allocator_strdup(allocator, name);
00096     zone->klass = klass;
00097 
00098     zone->dname = ldns_dname_new_frm_str(name);
00099     ldns_dname2canonical(zone->dname);
00100     zone->notify_ns = NULL;
00101     zone->policy_name = NULL;
00102     zone->signconf_filename = NULL;
00103 
00104     zone->adinbound = NULL;
00105     zone->adoutbound = NULL;
00106     zone->nsec3params = NULL;
00107 
00108     zone->just_added = 0;
00109     zone->just_updated = 0;
00110     zone->tobe_removed = 0;
00111     zone->processed = 0;
00112     zone->prepared = 0;
00113     zone->fetch = 0;
00114 
00115     zone->zonedata = zonedata_create(zone->allocator);
00116     if (!zone->zonedata) {
00117         ods_log_error("[%s] unable to create zone %s: create zonedata "
00118             "failed", zone_str, name);
00119         zone_cleanup(zone);
00120         return NULL;
00121     }
00122 
00123     zone->signconf = signconf_create();
00124     if (!zone->signconf) {
00125         ods_log_error("[%s] unable to create zone %s: create signconf "
00126             "failed", zone_str, name);
00127         zone_cleanup(zone);
00128         return NULL;
00129     }
00130 
00131     zone->stats = stats_create();
00132     zone->task = NULL;
00133     lock_basic_init(&zone->zone_lock);
00134     return zone;
00135 }
00136 
00137 
00142 ods_status
00143 zone_add_rr(zone_type* zone, ldns_rr* rr, int do_stats)
00144 {
00145     domain_type* domain = NULL;
00146     rrset_type* rrset = NULL;
00147     ldns_rdf* soa_min = NULL;
00148     ldns_rr_type type = LDNS_RR_TYPE_FIRST;
00149     uint32_t tmp = 0;
00150 
00151     if (!rr) {
00152         ods_log_error("[%s] unable to add RR: no RR", zone_str);
00153         return ODS_STATUS_ASSERT_ERR;
00154     }
00155     ods_log_assert(rr);
00156 
00157     if (!zone || !zone->zonedata) {
00158         ods_log_error("[%s] unable to add RR: no storage", zone_str);
00159         return ODS_STATUS_ASSERT_ERR;
00160     }
00161     ods_log_assert(zone);
00162     ods_log_assert(zone->zonedata);
00163 
00164     if (!zone->signconf) {
00165         ods_log_error("[%s] unable to add RR: no signconf", zone_str);
00166         return ODS_STATUS_ASSERT_ERR;
00167     }
00168     ods_log_assert(zone->signconf);
00169 
00170     /* in-zone? */
00171     if (ldns_dname_compare(zone->dname, ldns_rr_owner(rr)) != 0 &&
00172         !ldns_dname_is_subdomain(ldns_rr_owner(rr), zone->dname)) {
00173         ods_log_warning("[%s] zone %s contains out-of-zone data, skipping",
00174             zone_str, zone->name?zone->name:"(null)");
00175         /* ok, just filter */
00176         ldns_rr_free(rr);
00177         return ODS_STATUS_OK;
00178     }
00179 
00180     /* type specific configuration */
00181     type = ldns_rr_get_type(rr);
00182     if (type == LDNS_RR_TYPE_DNSKEY && zone->signconf->dnskey_ttl) {
00183         tmp = (uint32_t) duration2time(zone->signconf->dnskey_ttl);
00184         ods_log_verbose("[%s] zone %s set DNSKEY TTL to %u",
00185             zone_str, zone->name?zone->name:"(null)", tmp);
00186         ldns_rr_set_ttl(rr, tmp);
00187     }
00188     if (type == LDNS_RR_TYPE_SOA) {
00189         if (zone->signconf->soa_ttl) {
00190             tmp = (uint32_t) duration2time(zone->signconf->soa_ttl);
00191             ods_log_verbose("[%s] zone %s set SOA TTL to %u",
00192                 zone_str, zone->name?zone->name:"(null)", tmp);
00193             ldns_rr_set_ttl(rr, tmp);
00194         }
00195         if (zone->signconf->soa_min) {
00196             tmp = (uint32_t) duration2time(zone->signconf->soa_min);
00197             ods_log_verbose("[%s] zone %s set SOA MINIMUM to %u",
00198                 zone_str, zone->name?zone->name:"(null)", tmp);
00199             soa_min = ldns_rr_set_rdf(rr,
00200                 ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, tmp),
00201                 SE_SOA_RDATA_MINIMUM);
00202             if (soa_min) {
00203                 ldns_rdf_deep_free(soa_min);
00204             } else {
00205                 ods_log_error("[%s] zone %s failed to replace SOA MINIMUM "
00206                     "rdata", zone_str, zone->name?zone->name:"(null)");
00207                 return ODS_STATUS_ASSERT_ERR;
00208             }
00209         }
00210     }
00211 
00212     /* lookup domain */
00213     domain = zonedata_lookup_domain(zone->zonedata, ldns_rr_owner(rr));
00214     if (!domain) {
00215         /* add domain */
00216         domain = domain_create(ldns_rr_owner(rr));
00217         if (!domain) {
00218             ods_log_error("[%s] unable to add RR: create domain failed",
00219                 zone_str);
00220             return ODS_STATUS_ERR;
00221         }
00222         if (zonedata_add_domain(zone->zonedata, domain) == NULL) {
00223             ods_log_error("[%s] unable to add RR: add domain failed",
00224                 zone_str);
00225             return ODS_STATUS_ERR;
00226         }
00227         if (ldns_dname_compare(domain->dname, zone->dname) == 0) {
00228             domain->dstatus = DOMAIN_STATUS_APEX;
00229         }
00230     }
00231     ods_log_assert(domain);
00232 
00233     /* lookup RRset */
00234     rrset = domain_lookup_rrset(domain, ldns_rr_get_type(rr));
00235     if (!rrset) {
00236         /* add RRset */
00237         rrset = rrset_create(ldns_rr_get_type(rr));
00238         if (!rrset) {
00239             ods_log_error("[%s] unable to add RR: create RRset failed",
00240                 zone_str);
00241             return ODS_STATUS_ERR;
00242         }
00243         if (domain_add_rrset(domain, rrset) == NULL) {
00244             ods_log_error("[%s] unable to add RR: add RRset failed",
00245                 zone_str);
00246             return ODS_STATUS_ERR;
00247         }
00248     }
00249     ods_log_assert(rrset);
00250 
00251     /* add RR */
00252     if (rrset_add_rr(rrset, rr) == NULL) {
00253         ods_log_error("[%s] unable to add RR: pend RR failed", zone_str);
00254         return ODS_STATUS_ERR;
00255     }
00256 
00257     /* update stats */
00258     if (zone->stats && do_stats) {
00259         zone->stats->sort_count += 1;
00260     }
00261     return ODS_STATUS_OK;
00262 }
00263 
00264 
00269 ods_status
00270 zone_del_rr(zone_type* zone, ldns_rr* rr, int do_stats)
00271 {
00272     domain_type* domain = NULL;
00273     rrset_type* rrset = NULL;
00274 
00275     if (!rr) {
00276         ods_log_error("[%s] unable to del RR: no RR", zone_str);
00277         return ODS_STATUS_ASSERT_ERR;
00278     }
00279     ods_log_assert(rr);
00280 
00281     if (!zone || !zone->zonedata) {
00282         ods_log_error("[%s] unable to del RR: no storage", zone_str);
00283         return ODS_STATUS_ASSERT_ERR;
00284     }
00285     ods_log_assert(zone);
00286     ods_log_assert(zone->zonedata);
00287 
00288     /* lookup domain */
00289     domain = zonedata_lookup_domain(zone->zonedata, ldns_rr_owner(rr));
00290     if (!domain) {
00291         /* no domain, no del */
00292         ods_log_warning("[%s] unable to del RR: no such domain", zone_str);
00293         return ODS_STATUS_UNCHANGED;
00294     }
00295     ods_log_assert(domain);
00296 
00297     /* lookup RRset */
00298     rrset = domain_lookup_rrset(domain, ldns_rr_get_type(rr));
00299     if (!rrset) {
00300         /* no RRset, no del */
00301         ods_log_warning("[%s] unable to del RR: no such RRset", zone_str);
00302         return ODS_STATUS_UNCHANGED;
00303     }
00304     ods_log_assert(rrset);
00305 
00306     /* del RR */
00307     if (rrset_del_rr(rrset, rr, (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY))
00308             == NULL) {
00309         ods_log_error("[%s] unable to del RR: pend RR failed", zone_str);
00310         return ODS_STATUS_ERR;
00311     }
00312 
00313     /* update stats */
00314     if (do_stats && zone->stats) {
00315         zone->stats->sort_count -= 1;
00316     }
00317     return ODS_STATUS_OK;
00318 }
00319 
00320 
00325 static ods_status
00326 dnskey_withdraw(zone_type* zone, ldns_rr_list* del)
00327 {
00328     ldns_rr* clone = NULL;
00329     ods_status status = ODS_STATUS_OK;
00330     size_t i = 0;
00331 
00332     for (i=0; i < ldns_rr_list_rr_count(del); i++) {
00333         clone = ldns_rr_clone(ldns_rr_list_rr(del, i));
00334         status = zone_del_rr(zone, clone, 0);
00335         if (status != ODS_STATUS_OK) {
00336             return status;
00337         }
00338     }
00339     return status;
00340 }
00341 
00342 
00347 static ods_status
00348 nsec3param_withdraw(zone_type* zone, ldns_rr* rr)
00349 {
00350     ldns_rr* clone = NULL;
00351     ods_status status = ODS_STATUS_OK;
00352 
00353     if (!rr) { /* no nsec3param, nothing to withdraw */
00354         return status;
00355     }
00356     clone = ldns_rr_clone(rr);
00357     status = zone_del_rr(zone, clone, 0);
00358     if (status != ODS_STATUS_OK) {
00359         return status;
00360     }
00361     return status;
00362 }
00363 
00364 
00369 ods_status
00370 zone_load_signconf(zone_type* zone, task_id* tbs)
00371 {
00372     ods_status status = ODS_STATUS_OK;
00373     signconf_type* signconf = NULL;
00374     ldns_rr_list* del = NULL;
00375     char* datestamp = NULL;
00376     uint32_t ustamp = 0;
00377     task_id denial_what;
00378     task_id keys_what;
00379     task_id what;
00380 
00381     if (!zone) {
00382         ods_log_error("[%s] unable to load signconf: no zone", zone_str);
00383         return ODS_STATUS_ASSERT_ERR;
00384     }
00385     ods_log_assert(zone);
00386     if (!zone->signconf_filename) {
00387         ods_log_warning("[%s] zone %s has no signconf filename, treat as "
00388             "insecure?", zone_str, zone->name);
00389         return ODS_STATUS_INSECURE;
00390     }
00391     ods_log_assert(zone->signconf_filename);
00392 
00393     status = signconf_update(&signconf, zone->signconf_filename,
00394         zone->signconf->last_modified);
00395     if (status == ODS_STATUS_OK) {
00396         if (!signconf) {
00397             /* this is unexpected */
00398             ods_log_error("[%s] unable to load signconf: zone %s signconf "
00399                 "%s: storage empty", zone_str, zone->name,
00400                 zone->signconf_filename);
00401             return ODS_STATUS_ASSERT_ERR;
00402         }
00403         ustamp = time_datestamp(signconf->last_modified, "%Y-%m-%d %T",
00404             &datestamp);
00405         ods_log_debug("[%s] zone %s signconf file %s is modified since %s",
00406             zone_str, zone->name, zone->signconf_filename,
00407             datestamp?datestamp:"Unknown");
00408         free((void*)datestamp);
00409 
00410         /* do stuff */
00411         del = ldns_rr_list_new();
00412         if (!del) {
00413             ods_log_error("[%s] unable to load signconf: zone %s "
00414                 "signconf %s: ldns_rr_list_new() failed",
00415                 zone_str, zone->name, zone->signconf_filename);
00416             return ODS_STATUS_MALLOC_ERR;
00417         }
00418         denial_what = signconf_compare_denial(zone->signconf, signconf);
00419         keys_what = signconf_compare_keys(zone->signconf, signconf, del);
00420 
00421         /* Key Rollover? */
00422         if (keys_what == TASK_READ) {
00423             status = dnskey_withdraw(zone, del);
00424         }
00425         ldns_rr_list_free(del);
00426         if (status != ODS_STATUS_OK) {
00427             ods_log_error("[%s] unable to load signconf: zone %s "
00428                 "signconf %s: failed to delete DNSKEY from RRset",
00429                 zone_str, zone->name, zone->signconf_filename);
00430             zonedata_rollback(zone->zonedata);
00431             return status;
00432         }
00433 
00434         /* Denial of Existence Rollover? */
00435         if (denial_what == TASK_NSECIFY) {
00436             status = ODS_STATUS_OK;
00437             if (denial_what == TASK_NSECIFY && zone->nsec3params) {
00438                 status = nsec3param_withdraw(zone, zone->nsec3params->rr);
00439             }
00440             if (status != ODS_STATUS_OK) {
00441                 ods_log_error("[%s] unable to load signconf: zone %s "
00442                     "signconf %s: failed to delete NSEC3PARAM RRset",
00443                     zone_str, zone->name, zone->signconf_filename);
00444                 zonedata_rollback(zone->zonedata);
00445                 return status;
00446             }
00447             /* or NSEC -> NSEC3, or NSEC3 -> NSEC, or NSEC3PARAM changed */
00448             nsec3params_cleanup(zone->nsec3params);
00449             zone->nsec3params = NULL;
00450             /* all NSEC(3)s become invalid */
00451             zonedata_wipe_denial(zone->zonedata);
00452             zonedata_cleanup_chain(zone->zonedata);
00453             zonedata_init_denial(zone->zonedata);
00454         }
00455 
00456         /* all ok, switch to new signconf */
00457         if (keys_what != TASK_NONE) {
00458             what = keys_what;
00459         } else {
00460             what = denial_what;
00461         }
00462         if (what == TASK_NONE) { /* no major changes, continue signing */
00463             what = TASK_SIGN;
00464         }
00465         *tbs = what;
00466         ods_log_debug("[%s] tbs for zone %s set to: %s", zone_str,
00467             zone->name, task_what2str(*tbs));
00468         signconf_cleanup(zone->signconf);
00469         ods_log_debug("[%s] zone %s switch to new signconf", zone_str,
00470             zone->name);
00471         zone->signconf = signconf;
00472         signconf_log(zone->signconf, zone->name);
00473         zone->zonedata->default_ttl =
00474             (uint32_t) duration2time(zone->signconf->soa_min);
00475     } else if (status == ODS_STATUS_UNCHANGED) {
00476         *tbs = TASK_READ;
00477         ods_log_debug("[%s] tbs for zone %s set to: %s", zone_str,
00478             zone->name, task_what2str(*tbs));
00479         ustamp = time_datestamp(zone->signconf->last_modified,
00480             "%Y-%m-%d %T", &datestamp);
00481         ods_log_verbose("[%s] zone %s signconf file %s is unchanged since "
00482             "%s", zone_str, zone->name, zone->signconf_filename,
00483             datestamp?datestamp:"Unknown");
00484         free((void*)datestamp);
00485     } else {
00486         ods_log_error("[%s] unable to load signconf: zone %s signconf %s: "
00487             "%s", zone_str, zone->name, zone->signconf_filename,
00488             ods_status2str(status));
00489     }
00490     return status;
00491 }
00492 
00493 
00498 ods_status
00499 zone_publish_dnskeys(zone_type* zone, int recover)
00500 {
00501     hsm_ctx_t* ctx = NULL;
00502     key_type* key = NULL;
00503     uint32_t ttl = 0;
00504     size_t count = 0;
00505     ods_status status = ODS_STATUS_OK;
00506     ldns_rr* dnskey = NULL;
00507     int do_publish = 0;
00508 
00509     if (!zone) {
00510         ods_log_error("[%s] unable to publish dnskeys: no zone", zone_str);
00511         return ODS_STATUS_ASSERT_ERR;
00512     }
00513     ods_log_assert(zone);
00514 
00515     if (!zone->signconf) {
00516         ods_log_error("[%s] unable to publish dnskeys zone %s: no signconf",
00517             zone_str, zone->name);
00518         return ODS_STATUS_ASSERT_ERR;
00519     }
00520     ods_log_assert(zone->signconf);
00521 
00522     if (!zone->signconf->keys) {
00523         ods_log_error("[%s] unable to publish dnskeys zone %s: no keys",
00524             zone_str, zone->name);
00525         return ODS_STATUS_ASSERT_ERR;
00526     }
00527     ods_log_assert(zone->signconf->keys);
00528 
00529     if (!zone->zonedata) {
00530         ods_log_error("[%s] unable to publish dnskeys zone %s: no zonedata",
00531             zone_str, zone->name);
00532         return ODS_STATUS_ASSERT_ERR;
00533     }
00534     ods_log_assert(zone->zonedata);
00535 
00536     ttl = zone->zonedata->default_ttl;
00537     if (zone->signconf->dnskey_ttl) {
00538         ttl = (uint32_t) duration2time(zone->signconf->dnskey_ttl);
00539     }
00540 
00541     ctx = hsm_create_context();
00542     if (ctx == NULL) {
00543         ods_log_error("[%s] unable to publish dnskeys for zone %s: error "
00544             "creating libhsm context", zone_str, zone->name);
00545         return ODS_STATUS_HSM_ERR;
00546     }
00547 
00548     key = zone->signconf->keys->first_key;
00549     for (count=0; count < zone->signconf->keys->count; count++) {
00550         if (key->publish) {
00551             do_publish = 0;
00552             if (!key->dnskey) {
00553                 do_publish = 1;
00554             }
00555 
00556             status = lhsm_get_key(ctx, zone->dname, key);
00557             if (status != ODS_STATUS_OK) {
00558                 ods_log_error("[%s] unable to publish dnskeys zone %s: "
00559                     "error creating DNSKEY for key %s", zone_str,
00560                     zone->name, key->locator?key->locator:"(null)");
00561                 break;
00562             }
00563             ods_log_assert(key->dnskey);
00564 
00565             if (recover) {
00566                 dnskey = ldns_rr_clone(key->dnskey);
00567                 status = zone_add_rr(zone, dnskey, 0);
00568             } else if (do_publish) {
00569                 ldns_rr_set_ttl(key->dnskey, ttl);
00570                 ldns_rr_set_class(key->dnskey, zone->klass);
00571                 ldns_rr2canonical(key->dnskey);
00572                 dnskey = ldns_rr_clone(key->dnskey);
00573                 status = zone_add_rr(zone, dnskey, 0);
00574             } else {
00575                 status = ODS_STATUS_OK;
00576             }
00577 
00578             if (status != ODS_STATUS_OK) {
00579                 ods_log_error("[%s] unable to publish dnskeys zone %s: "
00580                     "error adding DNSKEY[%u] for key %s", zone_str,
00581                     zone->name, ldns_calc_keytag(dnskey),
00582                     key->locator?key->locator:"(null)");
00583                 break;
00584             }
00585         }
00586         key = key->next;
00587     }
00588 
00589     if (status != ODS_STATUS_OK) {
00590         zonedata_rollback(zone->zonedata);
00591     }
00592 
00593     hsm_destroy_context(ctx);
00594     ctx = NULL;
00595     return status;
00596 }
00597 
00598 
00603 ods_status
00604 zone_prepare_nsec3(zone_type* zone, int recover)
00605 {
00606     ldns_rr* nsec3params_rr = NULL;
00607     domain_type* apex = NULL;
00608     rrset_type* rrset = NULL;
00609     ods_status status = ODS_STATUS_OK;
00610 
00611     if (!zone) {
00612         ods_log_error("[%s] unable to prepare NSEC3: no zone", zone_str);
00613         return ODS_STATUS_ASSERT_ERR;
00614     }
00615     ods_log_assert(zone);
00616 
00617     if (!zone->signconf) {
00618         ods_log_error("[%s] unable to prepare NSEC3: no signconf", zone_str);
00619         return ODS_STATUS_ASSERT_ERR;
00620     }
00621     ods_log_assert(zone->signconf);
00622 
00623     if (zone->signconf->nsec_type != LDNS_RR_TYPE_NSEC3) {
00624         /* no preparations needed */
00625         return ODS_STATUS_OK;
00626     }
00627 
00628     if (!zone->nsec3params) {
00629         ods_log_debug("[%s] prepare NSEC3 for zone %s", zone_str, zone->name);
00630 
00631         zone->nsec3params = nsec3params_create(
00632             (uint8_t) zone->signconf->nsec3_algo,
00633             (uint8_t) zone->signconf->nsec3_optout,
00634             (uint16_t) zone->signconf->nsec3_iterations,
00635             zone->signconf->nsec3_salt);
00636     }
00637     if (!zone->nsec3params) {
00638         ods_log_error("[%s] unable to prepare zone %s for NSEC3: failed "
00639             "to create NSEC3 parameters", zone_str, zone->name);
00640         return ODS_STATUS_MALLOC_ERR;
00641     }
00642     ods_log_assert(zone->nsec3params);
00643 
00644     if (recover) {
00645         nsec3params_rr = ldns_rr_clone(zone->nsec3params->rr);
00646         status = zone_add_rr(zone, nsec3params_rr, 0);
00647     } else {
00648         nsec3params_rr = ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAMS);
00649         if (!nsec3params_rr) {
00650             ods_log_error("[%s] unable to prepare zone %s for NSEC3: failed "
00651                 "to create NSEC3PARAM RR", zone_str, zone->name);
00652             nsec3params_cleanup(zone->nsec3params);
00653             return ODS_STATUS_MALLOC_ERR;
00654         }
00655         ods_log_assert(nsec3params_rr);
00656 
00657         ldns_rr_set_class(nsec3params_rr, zone->klass);
00658         ldns_rr_set_ttl(nsec3params_rr, zone->zonedata->default_ttl);
00659         ldns_rr_set_owner(nsec3params_rr, ldns_rdf_clone(zone->dname));
00660         ldns_nsec3_add_param_rdfs(nsec3params_rr,
00661             zone->nsec3params->algorithm, 0,
00662             zone->nsec3params->iterations,
00663             zone->nsec3params->salt_len,
00664             zone->nsec3params->salt_data);
00669         ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3params_rr, 1)), 7, 0);
00670 
00671         ldns_rr2canonical(nsec3params_rr);
00672         zone->nsec3params->rr = ldns_rr_clone(nsec3params_rr);
00673         status = zone_add_rr(zone, nsec3params_rr, 0);
00674     }
00675 
00676     if (status != ODS_STATUS_OK) {
00677         ods_log_error("[%s] unable to add NSEC3PARAM RR to zone %s",
00678             zone_str, zone->name);
00679         nsec3params_cleanup(zone->nsec3params);
00680         zone->nsec3params = NULL;
00681         ldns_rr_free(nsec3params_rr);
00682     } else if (!recover) {
00683         /* add ok, wipe out previous nsec3params */
00684         apex = zonedata_lookup_domain(zone->zonedata, zone->dname);
00685         if (!apex) {
00686             ods_log_crit("[%s] unable to delete previous NSEC3PARAM RR "
00687             "from zone %s: apex undefined", zone_str, zone->name);
00688             nsec3params_cleanup(zone->nsec3params);
00689             zone->nsec3params = NULL;
00690             zonedata_rollback(zone->zonedata);
00691             return ODS_STATUS_ASSERT_ERR;
00692         }
00693         ods_log_assert(apex);
00694 
00695         rrset = domain_lookup_rrset(apex, LDNS_RR_TYPE_NSEC3PARAMS);
00696         if (rrset) {
00697             status = rrset_wipe_out(rrset);
00698             if (status != ODS_STATUS_OK) {
00699                 ods_log_error("[%s] unable to wipe out previous "
00700                     "NSEC3PARAM RR from zone %s", zone_str, zone->name);
00701                 nsec3params_cleanup(zone->nsec3params);
00702                 zone->nsec3params = NULL;
00703                 rrset_rollback(rrset);
00704                 return status;
00705             }
00706         }
00707     }
00708     return status;
00709 }
00710 
00711 
00716 ods_status
00717 zone_backup(zone_type* zone)
00718 {
00719     char* filename = NULL;
00720     FILE* fd = NULL;
00721 
00722     ods_log_assert(zone);
00723     ods_log_assert(zone->zonedata);
00724     ods_log_assert(zone->signconf);
00725 
00726     filename = ods_build_path(zone->name, ".backup", 0);
00727     fd = ods_fopen(filename, NULL, "w");
00728     free((void*)filename);
00729 
00730     if (fd) {
00731         fprintf(fd, "%s\n", ODS_SE_FILE_MAGIC);
00733         fprintf(fd, ";;Zone: name %s class %i ttl %u inbound %u internal "
00734             "%u outbound %u\n",
00735             zone->name?zone->name:"(null)",
00736             (int) zone->klass,
00737             (unsigned) zone->zonedata->default_ttl,
00738             (unsigned) zone->zonedata->inbound_serial,
00739             (unsigned) zone->zonedata->internal_serial,
00740             (unsigned) zone->zonedata->outbound_serial);
00742         if (zone->task) {
00743             task_backup(fd, (task_type*) zone->task);
00744         }
00746         signconf_backup(fd, zone->signconf);
00747         fprintf(fd, ";;\n");
00749         if (zone->nsec3params) {
00750             nsec3params_backup(fd,
00751                 zone->signconf->nsec3_algo,
00752                 zone->signconf->nsec3_optout,
00753                 zone->signconf->nsec3_iterations,
00754                 zone->signconf->nsec3_salt,
00755                 zone->nsec3params->rr);
00756         }
00758         keylist_backup(fd, zone->signconf->keys);
00760         zonedata_backup(fd, zone->zonedata);
00762         fprintf(fd, "%s\n", ODS_SE_FILE_MAGIC);
00763         ods_fclose(fd);
00764     } else {
00765         return ODS_STATUS_FOPEN_ERR;
00766     }
00767     return ODS_STATUS_OK;
00768 }
00769 
00770 
00775 ods_status
00776 zone_recover(zone_type* zone)
00777 {
00778     char* filename = NULL;
00779     FILE* fd = NULL;
00780     const char* token = NULL;
00781     ods_status status = ODS_STATUS_OK;
00782     /* zone part */
00783     int klass = 0;
00784     uint32_t ttl = 0;
00785     uint32_t inbound = 0;
00786     uint32_t internal = 0;
00787     uint32_t outbound = 0;
00788     /* task part */
00789     task_type* task = NULL;
00790     time_t when = 0;
00791     time_t backoff = 0;
00792     int what = 0;
00793     int interrupt = 0;
00794     int halted = 0;
00795     int flush = 0;
00796     /* signconf part */
00797     time_t lastmod = 0;
00798     /* nsec3params part */
00799     const char* salt = NULL;
00800     ldns_rr* nsec3params_rr = NULL;
00801     nsec3params_type* nsec3params = NULL;
00802     /* keys part */
00803     key_type* key = NULL;
00804     /* zonedata part */
00805     int fetch = 0;
00806 
00807     ods_log_assert(zone);
00808     ods_log_assert(zone->signconf);
00809     ods_log_assert(zone->zonedata);
00810 
00811     filename = ods_build_path(zone->name, ".backup", 0);
00812     fd = ods_fopen(filename, NULL, "r");
00813     free((void*)filename);
00814     if (fd) {
00815         /* start recovery */
00816         if (!backup_read_check_str(fd, ODS_SE_FILE_MAGIC) ||
00817             /* zone part */
00818             !backup_read_check_str(fd, ";;Zone:") ||
00819             !backup_read_check_str(fd, "name") ||
00820             !backup_read_check_str(fd, zone->name) ||
00821             !backup_read_check_str(fd, "class") ||
00822             !backup_read_int(fd, &klass) ||
00823             !backup_read_check_str(fd, "ttl") ||
00824             !backup_read_uint32_t(fd, &ttl) ||
00825             !backup_read_check_str(fd, "inbound") ||
00826             !backup_read_uint32_t(fd, &inbound) ||
00827             !backup_read_check_str(fd, "internal") ||
00828             !backup_read_uint32_t(fd, &internal) ||
00829             !backup_read_check_str(fd, "outbound") ||
00830             !backup_read_uint32_t(fd, &outbound) ||
00831             /* task part */
00832             !backup_read_check_str(fd, ";;Task:") ||
00833             !backup_read_check_str(fd, "when") ||
00834             !backup_read_time_t(fd, &when) ||
00835             !backup_read_check_str(fd, "what") ||
00836             !backup_read_int(fd, &what) ||
00837             !backup_read_check_str(fd, "interrupt") ||
00838             !backup_read_int(fd, &interrupt) ||
00839             !backup_read_check_str(fd, "halted") ||
00840             !backup_read_int(fd, &halted) ||
00841             !backup_read_check_str(fd, "backoff") ||
00842             !backup_read_time_t(fd, &backoff) ||
00843             !backup_read_check_str(fd, "flush") ||
00844             !backup_read_int(fd, &flush) ||
00845             /* signconf part */
00846             !backup_read_check_str(fd, ";;Signconf:") ||
00847             !backup_read_check_str(fd, "lastmod") ||
00848             !backup_read_time_t(fd, &lastmod) ||
00849             !backup_read_check_str(fd, "resign") ||
00850             !backup_read_duration(fd,
00851                 &zone->signconf->sig_resign_interval) ||
00852             !backup_read_check_str(fd, "refresh") ||
00853             !backup_read_duration(fd,
00854                 &zone->signconf->sig_refresh_interval) ||
00855             !backup_read_check_str(fd, "valid") ||
00856             !backup_read_duration(fd,
00857                 &zone->signconf->sig_validity_default) ||
00858             !backup_read_check_str(fd, "denial") ||
00859             !backup_read_duration(fd,
00860                 &zone->signconf->sig_validity_denial) ||
00861             !backup_read_check_str(fd, "jitter") ||
00862             !backup_read_duration(fd, &zone->signconf->sig_jitter) ||
00863             !backup_read_check_str(fd, "offset") ||
00864             !backup_read_duration(fd,
00865                 &zone->signconf->sig_inception_offset) ||
00866             !backup_read_check_str(fd, "nsec") ||
00867             !backup_read_rr_type(fd, &zone->signconf->nsec_type) ||
00868             !backup_read_check_str(fd, "dnskeyttl") ||
00869             !backup_read_duration(fd, &zone->signconf->dnskey_ttl) ||
00870             !backup_read_check_str(fd, "soattl") ||
00871             !backup_read_duration(fd, &zone->signconf->soa_ttl) ||
00872             !backup_read_check_str(fd, "soamin") ||
00873             !backup_read_duration(fd, &zone->signconf->soa_min) ||
00874             !backup_read_check_str(fd, "serial") ||
00875             !backup_read_str(fd, &zone->signconf->soa_serial) ||
00876             !backup_read_check_str(fd, "audit") ||
00877             !backup_read_int(fd, &zone->signconf->audit) ||
00878             !backup_read_check_str(fd, ";;")) {
00879             goto recover_error;
00880         }
00881         /* nsec3params part */
00882         if (zone->signconf->nsec_type == LDNS_RR_TYPE_NSEC3) {
00883              if (!backup_read_check_str(fd, ";;Nsec3parameters:") ||
00884                  !backup_read_check_str(fd, "salt") ||
00885                  !backup_read_str(fd, &salt) ||
00886                  !backup_read_check_str(fd, "algorithm") ||
00887                  !backup_read_uint32_t(fd, &zone->signconf->nsec3_algo) ||
00888                  !backup_read_check_str(fd, "optout") ||
00889                  !backup_read_int(fd, &zone->signconf->nsec3_optout) ||
00890                  !backup_read_check_str(fd, "iterations") ||
00891                  !backup_read_uint32_t(fd,
00892                      &zone->signconf->nsec3_iterations) ||
00893                  ldns_rr_new_frm_fp(&nsec3params_rr, fd, NULL, NULL, NULL) ||
00894                  !backup_read_check_str(fd, ";;Nsec3done") ||
00895                  !backup_read_check_str(fd, ";;")) {
00896                  goto recover_error;
00897             }
00898         }
00899         /* keys part */
00900         zone->signconf->keys = keylist_create(zone->signconf->allocator);
00901         while (backup_read_str(fd, &token)) {
00902             if (ods_strcmp(token, ";;Key:") == 0) {
00903                 key = key_recover(fd, zone->signconf->allocator);
00904                 if (!key || keylist_push(zone->signconf->keys, key) !=
00905                     ODS_STATUS_OK) {
00906                     goto recover_error;
00907                 }
00908                 key = NULL;
00909             } else if (ods_strcmp(token, ";;") == 0) {
00910                 /* keylist done */
00911                 free((void*) token);
00912                 token = NULL;
00913                 break;
00914             } else {
00915                 /* keylist corrupted */
00916                 goto recover_error;
00917             }
00918             free((void*) token);
00919             token = NULL;
00920         }
00921         /* zonedata part */
00922         filename = ods_build_path(zone->name, ".inbound", 0);
00923         status = adbackup_read(zone, filename);
00924         free((void*)filename);
00925         if (status != ODS_STATUS_OK) {
00926             goto recover_error;
00927         }
00928 
00929         zone->klass = (ldns_rr_class) klass;
00930         zone->zonedata->default_ttl = ttl;
00931         zone->zonedata->inbound_serial = inbound;
00932         zone->zonedata->internal_serial = internal;
00933         zone->zonedata->outbound_serial = outbound;
00934         zone->signconf->nsec3_salt = allocator_strdup(
00935             zone->signconf->allocator, salt);
00936         free((void*) salt);
00937         salt = NULL;
00938         task = task_create((task_id) what, when, zone->name, (void*) zone);
00939         if (!task) {
00940             goto recover_error;
00941         }
00942         if (zone->signconf->nsec_type == LDNS_RR_TYPE_NSEC3) {
00943             nsec3params = nsec3params_create(zone->signconf->nsec3_algo,
00944                 zone->signconf->nsec3_optout,
00945                 zone->signconf->nsec3_iterations,
00946                 zone->signconf->nsec3_salt);
00947             if (!nsec3params) {
00948                 goto recover_error;
00949             }
00950             nsec3params->rr = nsec3params_rr;
00951             zone->nsec3params = nsec3params;
00952         }
00953         zone->task = (void*) task;
00954         zone->signconf->last_modified = lastmod;
00955 
00956         status = zone_publish_dnskeys(zone, 1);
00957         if (status != ODS_STATUS_OK) {
00958             zone->task = NULL;
00959             zone->nsec3params = NULL;
00960             goto recover_error;
00961         }
00962         status = zone_prepare_nsec3(zone, 1);
00963         if (status != ODS_STATUS_OK) {
00964             zone->task = NULL;
00965             zone->nsec3params = NULL;
00966             goto recover_error;
00967         }
00968         status = zonedata_commit(zone->zonedata);
00969         if (status != ODS_STATUS_OK) {
00970             zone->task = NULL;
00971             zone->nsec3params = NULL;
00972             goto recover_error;
00973         }
00974         status = zonedata_entize(zone->zonedata, zone->dname);
00975         if (status != ODS_STATUS_OK) {
00976             zone->task = NULL;
00977             zone->nsec3params = NULL;
00978             goto recover_error;
00979         }
00980         status = zonedata_recover(zone->zonedata, fd);
00981         if (status != ODS_STATUS_OK) {
00982             zone->task = NULL;
00983             zone->nsec3params = NULL;
00984             goto recover_error;
00985         }
00986         ods_fclose(fd);
00987 
00988         /* all ok */
00989         zone->zonedata->initialized = 1;
00990         zone->prepared = 1;
00991         if (zone->stats) {
00992             lock_basic_lock(&zone->stats->stats_lock);
00993             stats_clear(zone->stats);
00994             lock_basic_unlock(&zone->stats->stats_lock);
00995         }
00996         return ODS_STATUS_OK;
00997     } else {
00998         /* backwards compatible backup recovery (serial) */
00999         filename = ods_build_path(zone->name, ".state", 0);
01000         fd = ods_fopen(filename, NULL, "r");
01001         free((void*)filename);
01002         if (fd) {
01003             if (!backup_read_check_str(fd, ODS_SE_FILE_MAGIC_V1) ||
01004                 !backup_read_check_str(fd, ";name:") ||
01005                 !backup_read_check_str(fd, zone->name) ||
01006                 !backup_read_check_str(fd, ";class:") ||
01007                 !backup_read_int(fd, &klass) ||
01008                 !backup_read_check_str(fd, ";fetch:") ||
01009                 !backup_read_int(fd, &fetch) ||
01010                 !backup_read_check_str(fd, ";default_ttl:") ||
01011                 !backup_read_uint32_t(fd, &ttl) ||
01012                 !backup_read_check_str(fd, ";inbound_serial:") ||
01013                 !backup_read_uint32_t(fd, &inbound) ||
01014                 !backup_read_check_str(fd, ";internal_serial:") ||
01015                 !backup_read_uint32_t(fd, &internal) ||
01016                 !backup_read_check_str(fd, ";outbound_serial:") ||
01017                 !backup_read_uint32_t(fd, &outbound) ||
01018                 !backup_read_check_str(fd, ODS_SE_FILE_MAGIC_V1))
01019             {
01020                 goto recover_error;
01021             }
01022             zone->klass = (ldns_rr_class) klass;
01023             zone->zonedata->default_ttl = ttl;
01024             zone->zonedata->inbound_serial = inbound;
01025             zone->zonedata->internal_serial = internal;
01026             zone->zonedata->outbound_serial = outbound;
01027             /* all ok */
01028             zone->zonedata->initialized = 1;
01029             zone->prepared = 1;
01030             if (zone->stats) {
01031                 lock_basic_lock(&zone->stats->stats_lock);
01032                 stats_clear(zone->stats);
01033                 lock_basic_unlock(&zone->stats->stats_lock);
01034             }
01035             return ODS_STATUS_UNCHANGED;
01036         }
01037         ods_fclose(fd);
01038     }
01039 
01040     return ODS_STATUS_UNCHANGED;
01041 
01042 recover_error:
01043     ods_log_error("[%s] unable to recover zone %s: corrupted file",
01044         zone_str, zone->name);
01045     ods_fclose(fd);
01046 
01047     /* signconf cleanup */
01048     signconf_cleanup(zone->signconf);
01049     zone->signconf = signconf_create();
01050     ods_log_assert(zone->signconf);
01051 
01052     /* task cleanup */
01053     task_cleanup(task);
01054     task = NULL;
01055 
01056     /* nsec3params cleanup */
01057     free((void*)salt);
01058     salt = NULL;
01059 
01060     ldns_rr_free(nsec3params_rr);
01061     nsec3params_rr = NULL;
01062     if (nsec3params) {
01063         nsec3params->rr = NULL;
01064     }
01065     nsec3params_cleanup(nsec3params);
01066     nsec3params = NULL;
01067 
01068     /* zonedata cleanup */
01069     zonedata_cleanup(zone->zonedata);
01070     zone->zonedata = zonedata_create(zone->allocator);
01071     ods_log_assert(zone->zonedata);
01072 
01073     if (zone->stats) {
01074        lock_basic_lock(&zone->stats->stats_lock);
01075        stats_clear(zone->stats);
01076        lock_basic_unlock(&zone->stats->stats_lock);
01077     }
01078     return ODS_STATUS_ERR;
01079 }
01080 
01081 
01086 void
01087 zone_merge(zone_type* z1, zone_type* z2)
01088 {
01089     const char* str;
01090     adapter_type* adtmp = NULL;
01091 
01092     if (!z1 || !z2) {
01093         return;
01094     }
01095 
01096     /* policy name */
01097     if (ods_strcmp(z2->policy_name, z1->policy_name) != 0) {
01098         if (z2->policy_name) {
01099             str = strdup(z2->policy_name);
01100             if (!str) {
01101                 ods_log_error("[%s] failed to merge policy %s name to zone "
01102                     "%s", zone_str, z2->policy_name, z1->name);
01103             } else {
01104                 free((void*)z1->policy_name);
01105                 z1->policy_name = str;
01106                 z1->just_updated = 1;
01107             }
01108         } else {
01109             free((void*)z1->policy_name);
01110             z1->policy_name = NULL;
01111             z1->just_updated = 1;
01112         }
01113     }
01114 
01115     /* signconf filename */
01116     if (ods_strcmp(z2->signconf_filename, z1->signconf_filename) != 0) {
01117         if (z2->signconf_filename) {
01118             str = strdup(z2->signconf_filename);
01119             if (!str) {
01120                 ods_log_error("[%s] failed to merge signconf filename %s to "
01121                     "zone %s", zone_str, z2->policy_name, z1->name);
01122             } else {
01123                 free((void*)z1->signconf_filename);
01124                 z1->signconf_filename = str;
01125                 z1->just_updated = 1;
01126             }
01127         } else {
01128             free((void*)z1->signconf_filename);
01129             z1->signconf_filename = NULL;
01130             z1->just_updated = 1;
01131         }
01132     }
01133 
01134     /* adapters */
01135     if (adapter_compare(z2->adinbound, z1->adinbound) != 0) {
01136         adtmp = z2->adinbound;
01137         z2->adinbound = z1->adinbound;
01138         z1->adinbound = adtmp;
01139         adtmp = NULL;
01140     }
01141     if (adapter_compare(z2->adoutbound, z1->adoutbound) != 0) {
01142         adtmp = z2->adoutbound;
01143         z2->adoutbound = z1->adoutbound;
01144         z1->adoutbound = adtmp;
01145         adtmp = NULL;
01146     }
01147     return;
01148 }
01149 
01150 
01155 ods_status
01156 zone_update_serial(zone_type* zone)
01157 {
01158     ods_status status = ODS_STATUS_OK;
01159     domain_type* domain = NULL;
01160     rrset_type* rrset = NULL;
01161     ldns_rdf* serial = NULL;
01162 
01163     if (!zone) {
01164         ods_log_error("[%s] unable to update serial: no zone",
01165             zone_str);
01166         return ODS_STATUS_ASSERT_ERR;
01167     }
01168     ods_log_assert(zone);
01169 
01170     if (!zone->signconf) {
01171         ods_log_error("[%s] unable to update serial: no signconf",
01172             zone_str);
01173         return ODS_STATUS_ASSERT_ERR;
01174     }
01175     ods_log_assert(zone->signconf);
01176 
01177     if (!zone->zonedata) {
01178         ods_log_error("[%s] unable to update serial: no zonedata",
01179             zone_str);
01180         return ODS_STATUS_ASSERT_ERR;
01181     }
01182     ods_log_assert(zone->zonedata);
01183 
01184     status = zonedata_update_serial(zone->zonedata, zone->signconf);
01185     if (status != ODS_STATUS_OK) {
01186         ods_log_error("[%s] unable to update serial: failed to increment",
01187             zone_str);
01188         return status;
01189     }
01190 
01191     /* lookup domain */
01192     domain = zonedata_lookup_domain(zone->zonedata, zone->dname);
01193     if (!domain) {
01194         ods_log_error("[%s] unable to update serial: apex not found",
01195             zone_str);
01196         return ODS_STATUS_ERR;
01197     }
01198     ods_log_assert(domain);
01199 
01200     /* lookup RRset */
01201     rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_SOA);
01202     if (!rrset) {
01203         ods_log_error("[%s] unable to update serial: SOA RRset not found",
01204             zone_str);
01205         return ODS_STATUS_ERR;
01206     }
01207     ods_log_assert(rrset);
01208     ods_log_assert(rrset->rr_type == LDNS_RR_TYPE_SOA);
01209 
01210     if (rrset->rrs && rrset->rrs->rr) {
01211         serial = ldns_rr_set_rdf(rrset->rrs->rr,
01212             ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
01213             zone->zonedata->internal_serial), SE_SOA_RDATA_SERIAL);
01214         if (serial) {
01215             if (ldns_rdf2native_int32(serial) !=
01216                 zone->zonedata->internal_serial) {
01217                 rrset->needs_signing = 1;
01218             }
01219             ldns_rdf_deep_free(serial);
01220          } else {
01221             ods_log_error("[%s] unable to update serial: failed to replace "
01222                 "SOA SERIAL rdata", zone_str);
01223             return ODS_STATUS_ERR;
01224         }
01225     }
01226     return ODS_STATUS_OK;
01227 }
01228 
01229 
01234 ods_status
01235 zone_print(FILE* fd, zone_type* zone)
01236 {
01237     if (fd && zone && zone->zonedata) {
01238         return zonedata_print(fd, zone->zonedata);
01239     }
01240     return ODS_STATUS_ASSERT_ERR;
01241 }
01242 
01243 
01248 ods_status
01249 zone_examine(zone_type* zone)
01250 {
01251     if (zone && zone->zonedata && zone->adinbound) {
01252         return zonedata_examine(zone->zonedata, zone->dname,
01253             zone->adinbound->type);
01254     }
01255     return ODS_STATUS_ASSERT_ERR;
01256 }
01257 
01258 
01263 void
01264 zone_cleanup(zone_type* zone)
01265 {
01266     allocator_type* allocator;
01267     lock_basic_type zone_lock;
01268 
01269     if (!zone) {
01270         return;
01271     }
01272 
01273     allocator = zone->allocator;
01274     zone_lock = zone->zone_lock;
01275 
01276     ldns_rdf_deep_free(zone->dname);
01277     adapter_cleanup(zone->adinbound);
01278     adapter_cleanup(zone->adoutbound);
01279     zonedata_cleanup(zone->zonedata);
01280     signconf_cleanup(zone->signconf);
01281     nsec3params_cleanup(zone->nsec3params);
01282     stats_cleanup(zone->stats);
01283     allocator_deallocate(allocator, (void*) zone->notify_ns);
01284     allocator_deallocate(allocator, (void*) zone->policy_name);
01285     allocator_deallocate(allocator, (void*) zone->signconf_filename);
01286     allocator_deallocate(allocator, (void*) zone->name);
01287     allocator_deallocate(allocator, (void*) zone);
01288     allocator_cleanup(allocator);
01289     lock_basic_destroy(&zone_lock);
01290     return;
01291 }