00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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);
00107
00108 status = ods_file_copy(tmpname, zone->adinbound->configstr);
00109
00110 fclose(fd);
00111 (void) unlink(lockname);
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
00208 ttl = zone->zonedata->default_ttl;
00209 if (zone->signconf->soa_min) {
00210 ttl = (uint32_t) duration2time(zone->signconf->soa_min);
00211 }
00212
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
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
00386 zone->zonedata->initialized = 1;
00387
00388
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
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 }