• Main Page
  • Data Structures
  • Files
  • File List
  • Globals

/build/buildd-opendnssec_1.3.2-1~bpo60+1-armel-4stS1W/opendnssec-1.3.2/signer/src/signer/tools.c

Go to the documentation of this file.
00001 /*
00002  * $Id: tools.c 5432 2011-08-22 12:55:04Z 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 "adapter/adapter.h"
00036 #include "shared/file.h"
00037 #include "shared/log.h"
00038 #include "signer/tools.h"
00039 #include "signer/zone.h"
00040 
00041 static const char* tools_str = "tools";
00042 
00043 
00048 ods_status
00049 tools_input(zone_type* zone)
00050 {
00051     ods_status status = ODS_STATUS_OK;
00052     char* tmpname = NULL;
00053     char* lockname = NULL;
00054     time_t start = 0;
00055     time_t end = 0;
00056     FILE* fd = NULL;
00057 
00058     if (!zone) {
00059         ods_log_error("[%s] unable to read zone: no zone", tools_str);
00060         return ODS_STATUS_ASSERT_ERR;
00061     }
00062     ods_log_assert(zone);
00063 
00064     if (!zone->zonedata) {
00065         ods_log_error("[%s] unable to read zone: no zone data", tools_str);
00066         return ODS_STATUS_ASSERT_ERR;
00067     }
00068     ods_log_assert(zone->zonedata);
00069 
00070     ods_log_assert(zone->adinbound);
00071     ods_log_assert(zone->signconf);
00072 
00073     if (zone->stats) {
00074         lock_basic_lock(&zone->stats->stats_lock);
00075         zone->stats->sort_done = 0;
00076         zone->stats->sort_count = 0;
00077         zone->stats->sort_time = 0;
00078         lock_basic_unlock(&zone->stats->stats_lock);
00079     }
00080 
00081     if (zone->adinbound->type == ADAPTER_FILE) {
00082         if (zone->fetch) {
00083             ods_log_verbose("[%s] fetch zone %s", tools_str,
00084                 zone->name?zone->name:"(null)");
00085             tmpname = ods_build_path(
00086                 zone->adinbound->configstr, ".axfr", 0);
00087             lockname = ods_build_path(
00088                 zone->adinbound->configstr, ".lock", 0);
00089 
00090 lock_fetch:
00091             if (access(lockname, F_OK) == 0) {
00092                 ods_log_deeebug("[%s] axfr file %s is locked, "
00093                     "waiting...", tools_str, tmpname);
00094                 sleep(1);
00095                 goto lock_fetch;
00096             } else {
00097                 fd = fopen(lockname, "w");
00098                 if (!fd) {
00099                     ods_log_error("[%s] cannot lock AXFR file %s",
00100                         tools_str, lockname);
00101                     free((void*)tmpname);
00102                     free((void*)lockname);
00103                     return ODS_STATUS_ERR;
00104                 }
00105             }
00106             ods_log_assert(fd); /* locked */
00107 
00108             status = ods_file_copy(tmpname, zone->adinbound->configstr);
00109 
00110             fclose(fd);
00111             (void) unlink(lockname); /* unlocked */
00112 
00113             if (status != ODS_STATUS_OK) {
00114                 ods_log_error("[%s] unable to copy axfr file %s to %s: %s",
00115                     tools_str, tmpname, zone->adinbound->configstr,
00116                     ods_status2str(status));
00117                 free((void*)tmpname);
00118                 free((void*)lockname);
00119                 return status;
00120             }
00121             free((void*)tmpname);
00122             free((void*)lockname);
00123         }
00124     }
00125 
00126     start = time(NULL);
00127     status = adapter_read(zone);
00128     if (status != ODS_STATUS_OK) {
00129         ods_log_error("[%s] unable to read from input adapter for zone %s: "
00130             "%s", tools_str, zone->name?zone->name:"(null)",
00131             ods_status2str(status));
00132     } else {
00133         tmpname = ods_build_path(zone->name, ".inbound", 0);
00134         status = ods_file_copy(zone->adinbound->configstr, tmpname);
00135         free((void*)tmpname);
00136         tmpname = NULL;
00137         if (status != ODS_STATUS_OK) {
00138             ods_log_error("[%s] unable to copy zone input file %s: %s",
00139                 tools_str, zone->name?zone->name:"(null)",
00140                 ods_status2str(status));
00141         }
00142     }
00143 
00144     if (status == ODS_STATUS_OK) {
00145         ods_log_verbose("[%s] commit updates for zone %s", tools_str,
00146             zone->name?zone->name:"(null)");
00147         status = zonedata_commit(zone->zonedata);
00148     } else {
00149         ods_log_warning("[%s] rollback updates for zone %s", tools_str,
00150             zone->name?zone->name:"(null)");
00151         zonedata_rollback(zone->zonedata);
00152     }
00153     end = time(NULL);
00154 
00155     if (status == ODS_STATUS_OK && zone->stats) {
00156         lock_basic_lock(&zone->stats->stats_lock);
00157         zone->stats->start_time = start;
00158         zone->stats->sort_time = (end-start);
00159         zone->stats->sort_done = 1;
00160         lock_basic_unlock(&zone->stats->stats_lock);
00161     }
00162     return status;
00163 }
00164 
00165 
00170 ods_status
00171 tools_nsecify(zone_type* zone)
00172 {
00173     ods_status status = ODS_STATUS_OK;
00174     time_t start = 0;
00175     time_t end = 0;
00176     uint32_t ttl = 0;
00177     uint32_t num_added = 0;
00178 
00179     if (!zone) {
00180         ods_log_error("[%s] unable to nsecify zone: no zone", tools_str);
00181         return ODS_STATUS_ASSERT_ERR;
00182     }
00183     ods_log_assert(zone);
00184 
00185     if (!zone->zonedata) {
00186         ods_log_error("[%s] unable to nsecify zone %s: no zonedata",
00187             tools_str, zone->name);
00188         return ODS_STATUS_ASSERT_ERR;
00189     }
00190     ods_log_assert(zone->zonedata);
00191 
00192     if (!zone->signconf) {
00193         ods_log_error("[%s] unable to nsecify zone %s: no signconf",
00194             tools_str, zone->name);
00195         return ODS_STATUS_ASSERT_ERR;
00196     }
00197     ods_log_assert(zone->signconf);
00198 
00199     if (zone->stats) {
00200         lock_basic_lock(&zone->stats->stats_lock);
00201         zone->stats->nsec_time = 0;
00202         zone->stats->nsec_count = 0;
00203         lock_basic_unlock(&zone->stats->stats_lock);
00204     }
00205 
00206     start = time(NULL);
00207     /* determine denial ttl */
00208     ttl = zone->zonedata->default_ttl;
00209     if (zone->signconf->soa_min) {
00210         ttl = (uint32_t) duration2time(zone->signconf->soa_min);
00211     }
00212     /* add missing empty non-terminals */
00213     status = zonedata_entize(zone->zonedata, zone->dname);
00214     if (status != ODS_STATUS_OK) {
00215         ods_log_error("[%s] unable to nsecify zone %s: failed to add empty ",
00216             "non-terminals", tools_str, zone->name);
00217         return status;
00218     }
00219     /* nsecify(3) */
00220     if (zone->signconf->nsec_type == LDNS_RR_TYPE_NSEC) {
00221         status = zonedata_nsecify(zone->zonedata, zone->klass, ttl,
00222             &num_added);
00223     } else if (zone->signconf->nsec_type == LDNS_RR_TYPE_NSEC3) {
00224         if (zone->signconf->nsec3_optout) {
00225             ods_log_debug("[%s] OptOut is being used for zone %s",
00226                 tools_str, zone->name);
00227         }
00228         ods_log_assert(zone->nsec3params);
00229         status = zonedata_nsecify3(zone->zonedata, zone->klass, ttl,
00230             zone->nsec3params, &num_added);
00231     } else {
00232         ods_log_error("[%s] unable to nsecify zone %s: unknown RRtype %u for ",
00233             "denial of existence", tools_str, zone->name,
00234             (unsigned) zone->signconf->nsec_type);
00235         return ODS_STATUS_ERR;
00236     }
00237     end = time(NULL);
00238     if (status == ODS_STATUS_OK && zone->stats) {
00239         lock_basic_lock(&zone->stats->stats_lock);
00240         if (!zone->stats->start_time) {
00241             zone->stats->start_time = start;
00242         }
00243         zone->stats->nsec_time = (end-start);
00244         zone->stats->nsec_count = num_added;
00245         lock_basic_unlock(&zone->stats->stats_lock);
00246     }
00247     return status;
00248 }
00249 
00250 
00255 ods_status
00256 tools_audit(zone_type* zone, char* working_dir, char* cfg_filename)
00257 {
00258     char* inbound = NULL;
00259     char* finalized = NULL;
00260     char str[SYSTEM_MAXLEN];
00261     ods_status status = ODS_STATUS_OK;
00262     int error = 0;
00263     time_t start = 0;
00264     time_t end = 0;
00265     if (!zone) {
00266         ods_log_error("[%s] unable to audit zone: no zone", tools_str);
00267         return ODS_STATUS_ASSERT_ERR;
00268     }
00269     ods_log_assert(zone);
00270 
00271     if (!zone->signconf) {
00272         ods_log_error("[%s] unable to audit zone %s: no signconf",
00273             tools_str, zone->name?zone->name:"(null)");
00274         return ODS_STATUS_ASSERT_ERR;
00275     }
00276     ods_log_assert(zone->signconf);
00277 
00278     if (zone->stats) {
00279         lock_basic_lock(&zone->stats->stats_lock);
00280         if (zone->stats->sort_done == 0 &&
00281             (zone->stats->sig_count <= zone->stats->sig_soa_count)) {
00282             lock_basic_unlock(&zone->stats->stats_lock);
00283             return ODS_STATUS_OK;
00284         }
00285         lock_basic_unlock(&zone->stats->stats_lock);
00286     }
00287 
00288     if (zone->signconf->audit) {
00289         inbound = ods_build_path(zone->name, ".inbound", 0);
00290         finalized = ods_build_path(zone->name, ".finalized", 0);
00291         status = adfile_write(zone, finalized);
00292         if (status != ODS_STATUS_OK) {
00293             ods_log_error("[%s] audit zone %s failed: unable to write zone",
00294                 tools_str, zone->name?zone->name:"(null)");
00295             free((void*)inbound);
00296             free((void*)finalized);
00297             return status;
00298         }
00299 
00300         snprintf(str, SYSTEM_MAXLEN, "%s -c %s -u %s/%s -s %s/%s -z %s > /dev/null",
00301             ODS_SE_AUDITOR,
00302             cfg_filename?cfg_filename:ODS_SE_CFGFILE,
00303             working_dir?working_dir:"",
00304             inbound?inbound:"(null)",
00305             working_dir?working_dir:"",
00306             finalized?finalized:"(null)",
00307             zone->name?zone->name:"(null)");
00308 
00309         start = time(NULL);
00310         ods_log_debug("system call: %s", str);
00311         error = system(str);
00312         if (finalized) {
00313             if (!error) {
00314                 unlink(finalized);
00315             }
00316             free((void*)finalized);
00317         }
00318         free((void*)inbound);
00319 
00320         if (error) {
00321             status = ODS_STATUS_ERR;
00322         }
00323         end = time(NULL);
00324         if (status == ODS_STATUS_OK && zone->stats) {
00325             lock_basic_lock(&zone->stats->stats_lock);
00326             zone->stats->audit_time = (end-start);
00327             lock_basic_unlock(&zone->stats->stats_lock);
00328         }
00329     }
00330     return status;
00331 }
00332 
00333 
00338 ods_status
00339 tools_output(zone_type* zone)
00340 {
00341     ods_status status = ODS_STATUS_OK;
00342     char str[SYSTEM_MAXLEN];
00343     int error = 0;
00344     uint32_t outbound_serial = 0;
00345 
00346     if (!zone) {
00347         ods_log_error("[%s] unable to write zone: no zone", tools_str);
00348         return ODS_STATUS_ASSERT_ERR;
00349     }
00350     ods_log_assert(zone);
00351 
00352     if (!zone->adoutbound) {
00353         ods_log_error("[%s] unable to write zone %s: no outbound adapter",
00354             tools_str, zone->name?zone->name:"(null)");
00355         return ODS_STATUS_ASSERT_ERR;
00356     }
00357     ods_log_assert(zone->adoutbound);
00358 
00359     if (zone->stats) {
00360         lock_basic_lock(&zone->stats->stats_lock);
00361         if (zone->stats->sort_done == 0 &&
00362             (zone->stats->sig_count <= zone->stats->sig_soa_count)) {
00363             ods_log_verbose("[%s] skip write zone %s serial %u (zone not "
00364                 "changed)", tools_str, zone->name?zone->name:"(null)",
00365                 zone->zonedata->internal_serial);
00366             stats_clear(zone->stats);
00367             lock_basic_unlock(&zone->stats->stats_lock);
00368             zone->zonedata->internal_serial =
00369                 zone->zonedata->outbound_serial;
00370             return ODS_STATUS_OK;
00371         }
00372         lock_basic_unlock(&zone->stats->stats_lock);
00373     }
00374 
00375     outbound_serial = zone->zonedata->outbound_serial;
00376     zone->zonedata->outbound_serial = zone->zonedata->internal_serial;
00377     status = adapter_write(zone);
00378     if (status != ODS_STATUS_OK) {
00379         ods_log_error("[%s] unable to write zone %s: adapter failed",
00380             tools_str, zone->name);
00381         zone->zonedata->outbound_serial = outbound_serial;
00382         return status;
00383     }
00384 
00385     /* initialize zonedata */
00386     zone->zonedata->initialized = 1;
00387 
00388     /* kick the nameserver */
00389     if (zone->notify_ns) {
00390         ods_log_verbose("[%s] notify nameserver: %s", tools_str,
00391             zone->notify_ns);
00392         snprintf(str, SYSTEM_MAXLEN, "%s > /dev/null",
00393             zone->notify_ns);
00394         error = system(str);
00395         if (error) {
00396            ods_log_error("[%s] failed to notify nameserver", tools_str);
00397            status = ODS_STATUS_ERR;
00398         }
00399     }
00400     /* log stats */
00401     if (zone->stats) {
00402         lock_basic_lock(&zone->stats->stats_lock);
00403         zone->stats->end_time = time(NULL);
00404         ods_log_debug("[%s] log stats for zone %s", tools_str,
00405             zone->name?zone->name:"(null)");
00406         stats_log(zone->stats, zone->name, zone->signconf->nsec_type);
00407         stats_clear(zone->stats);
00408         lock_basic_unlock(&zone->stats->stats_lock);
00409     }
00410     return status;
00411 }

Generated on Sat Dec 17 2011 10:09:51 for OpenDNSSEC-signer by  doxygen 1.7.1