45 #include <ldns/ldns.h>
47 static const char* zone_str =
"zone";
60 if (!name || !klass) {
65 if (strlen(name) > 1 && name[strlen(name)-1] ==
'.') {
66 name[strlen(name)-1] =
'\0';
70 if (pthread_mutex_init(&zone->
zone_lock, NULL)) {
74 if (pthread_mutex_init(&zone->
xfr_lock, NULL)) {
75 (void)pthread_mutex_destroy(&zone->
zone_lock);
80 zone->
name = strdup(name);
82 ods_log_error(
"[%s] unable to create zone %s: allocator_strdup() "
83 "failed", zone_str, name);
89 zone->
apex = ldns_dname_new_frm_str(name);
103 ods_log_error(
"[%s] unable to create zone %s: namedb_create() "
104 "failed", zone_str, name);
110 ods_log_error(
"[%s] unable to create zone %s: ixfr_create() "
111 "failed", zone_str, name);
115 zone->zoneconfigvalid = 0;
117 if (!zone->signconf) {
118 ods_log_error(
"[%s] unable to create zone %s: signconf_create() "
119 "failed", zone_str, name);
135 ods_status status = ODS_STATUS_OK;
137 char* datestamp = NULL;
140 return ODS_STATUS_ASSERT_ERR;
143 ods_log_warning(
"[%s] zone %s has no signconf filename, treat as "
144 "insecure?", zone_str, zone->
name);
145 return ODS_STATUS_INSECURE;
149 if (status == ODS_STATUS_OK) {
152 ods_log_alert(
"[%s] unable to load signconf for zone %s: signconf "
153 "status ok but no signconf stored", zone_str, zone->
name);
154 return ODS_STATUS_ASSERT_ERR;
158 ods_log_debug(
"[%s] zone %s signconf file %s is modified since %s",
160 datestamp?datestamp:
"Unknown");
161 free((
void*)datestamp);
162 *new_signconf = signconf;
163 }
else if (status == ODS_STATUS_UNCHANGED) {
168 "%Y-%m-%d %T", &datestamp);
169 ods_log_verbose(
"[%s] zone %s signconf file %s is unchanged since "
171 datestamp?datestamp:
"Unknown");
172 free((
void*)datestamp);
174 ods_log_error(
"[%s] unable to load signconf for zone %s: signconf %s "
176 ods_status2str(status));
188 hsm_ctx_t* ctx = NULL;
191 ods_status status = ODS_STATUS_OK;
196 return ODS_STATUS_ASSERT_ERR;
198 ods_log_assert(zone->
name);
201 if (!skip_hsm_access) {
202 ctx = hsm_create_context();
204 ods_log_error(
"[%s] unable to publish keys for zone %s: "
205 "error creating libhsm context", zone_str, zone->
name);
206 return ODS_STATUS_HSM_ERR;
223 ods_log_error(
"[%s] unable to publish dnskeys for zone %s: "
224 "error decoding literal dnskey", zone_str, zone->
name);
225 if (!skip_hsm_access) {
226 hsm_destroy_context(ctx);
233 if (status != ODS_STATUS_OK) {
234 ods_log_error(
"[%s] unable to publish dnskeys for zone %s: "
235 "error creating dnskey", zone_str, zone->
name);
240 ods_log_debug(
"[%s] publish %s DNSKEY locator %s", zone_str,
242 if (!skip_hsm_access) {
247 if (status == ODS_STATUS_UNCHANGED) {
250 ods_log_assert(rrset);
253 ods_log_assert(dnskey);
258 status = ODS_STATUS_OK;
259 }
else if (status != ODS_STATUS_OK) {
260 ods_log_error(
"[%s] unable to publish dnskeys for zone %s: "
261 "error adding dnskey", zone_str, zone->
name);
267 if (!skip_hsm_access) {
268 hsm_destroy_context(ctx);
293 if (dnskey && !dnskey->
exists &&
312 ods_status status = ODS_STATUS_OK;
315 return ODS_STATUS_ASSERT_ERR;
320 return ODS_STATUS_OK;
326 rr = ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAMS);
328 ods_log_error(
"[%s] unable to publish nsec3params for zone %s: "
329 "error creating rr (%s)", zone_str, zone->
name,
330 ods_status2str(status));
331 return ODS_STATUS_MALLOC_ERR;
333 ldns_rr_set_class(rr, zone->
klass);
334 ldns_rr_set_ttl(rr, paramttl);
335 ldns_rr_set_owner(rr, ldns_rdf_clone(zone->
apex));
336 ldns_nsec3_add_param_rdfs(rr,
345 ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(rr, 1)), 7, 0);
354 if (status == ODS_STATUS_UNCHANGED) {
355 status = ODS_STATUS_OK;
356 }
else if (status != ODS_STATUS_OK) {
357 ods_log_error(
"[%s] unable to publish nsec3params for zone %s: "
358 "error adding nsec3params (%s)", zone_str,
359 zone->
name, ods_status2str(status));
381 if (n3prr && !n3prr->
exists &&
396 hsm_ctx_t* ctx = NULL;
398 ods_status status = ODS_STATUS_OK;
401 return ODS_STATUS_ASSERT_ERR;
403 ods_log_assert(zone->
name);
405 ctx = hsm_create_context();
407 ods_log_error(
"[%s] unable to prepare signing keys for zone %s: "
408 "error creating libhsm context", zone_str, zone->
name);
409 return ODS_STATUS_HSM_ERR;
417 if (status != ODS_STATUS_OK) {
418 ods_log_error(
"[%s] unable to prepare signing keys for zone %s: "
419 "error getting dnskey", zone_str, zone->
name);
426 hsm_destroy_context(ctx);
438 ods_status status = ODS_STATUS_OK;
442 ldns_rdf* soa_rdata = NULL;
444 ods_log_assert(zone);
445 ods_log_assert(zone->
apex);
446 ods_log_assert(zone->
name);
447 ods_log_assert(zone->
db);
452 ods_log_debug(
"[%s] zone %s soa serial already up to date",
453 zone_str, zone->
name);
455 return ODS_STATUS_OK;
458 if (!rrset || !rrset->
rrs || !rrset->
rrs[0].
rr) {
459 ods_log_error(
"[%s] unable to update zone %s soa serial: failed to "
460 "find soa rrset", zone_str, zone->
name);
461 return ODS_STATUS_ERR;
463 ods_log_assert(rrset);
464 ods_log_assert(rrset->
rrs);
465 ods_log_assert(rrset->
rrs[0].
rr);
466 rr = ldns_rr_clone(rrset->
rrs[0].
rr);
468 ods_log_error(
"[%s] unable to update zone %s soa serial: failed to "
469 "clone soa rr", zone_str, zone->
name);
470 return ODS_STATUS_ERR;
474 if (status != ODS_STATUS_OK) {
475 ods_log_error(
"[%s] unable to update zone %s soa serial: %s",
476 zone_str, zone->
name, ods_status2str(status));
477 if (status == ODS_STATUS_CONFLICT_ERR) {
478 ods_log_error(
"[%s] If this is the result of a key rollover, "
479 "please increment the serial in the unsigned zone %s",
480 zone_str, zone->
name);
485 ods_log_verbose(
"[%s] zone %s set soa serial to %u", zone_str,
487 soa_rdata = ldns_rr_set_rdf(rr,
488 ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
491 ldns_rdf_deep_free(soa_rdata);
494 ods_log_error(
"[%s] unable to update zone %s soa serial: failed to "
495 "replace soa serial rdata", zone_str, zone->
name);
497 return ODS_STATUS_ERR;
503 return ODS_STATUS_OK;
515 if (!zone || !owner || !type) {
536 ods_status status = ODS_STATUS_OK;
539 ods_log_assert(zone);
540 ods_log_assert(zone->
name);
541 ods_log_assert(zone->
db);
548 ods_log_error(
"[%s] unable to add RR to zone %s: "
549 "failed to add domain", zone_str, zone->
name);
550 return ODS_STATUS_ERR;
552 if (ldns_dname_compare(domain->
dname, zone->
apex) == 0) {
556 if (status != ODS_STATUS_OK) {
557 ods_log_error(
"[%s] unable to add RR to zone %s: "
558 "failed to entize domain", zone_str, zone->
name);
559 return ODS_STATUS_ERR;
567 ods_log_error(
"[%s] unable to add RR to zone %s: "
568 "failed to add RRset", zone_str, zone->
name);
569 return ODS_STATUS_ERR;
575 uint32_t ttl_rr = ldns_rr_ttl(rr);
578 if (record && ttl_rr == ttl_rrset && ttl_rr == ldns_rr_ttl(record->
rr)) {
581 return ODS_STATUS_UNCHANGED;
584 ods_log_assert(record);
585 ods_log_assert(record->
rr);
587 if (ttl_rr != ttl_rrset) {
588 char *str = ldns_rr2str(rr);
589 str[(strlen(str)) - 1] =
'\0';
590 for (
int i = 0; i < strlen(str); i++) {
591 if (str[i] ==
'\t') {
595 ods_log_error(
"In zone file %s: TTL for the record '%s' (%d) not"
596 " equal to recordset TTL (%d)", zone->
name, str, ttl_rr, ttl_rrset);
601 if (do_stats && zone->
stats) {
604 return ODS_STATUS_OK;
619 ods_log_assert(zone);
620 ods_log_assert(zone->
name);
621 ods_log_assert(zone->
db);
625 ods_log_warning(
"[%s] unable to delete RR from zone %s: "
626 "domain not found", zone_str, zone->
name);
627 return ODS_STATUS_UNCHANGED;
631 ods_log_warning(
"[%s] unable to delete RR from zone %s: "
632 "RRset not found", zone_str, zone->
name);
633 return ODS_STATUS_UNCHANGED;
637 ods_log_error(
"[%s] unable to delete RR from zone %s: "
638 "RR not found", zone_str, zone->
name);
639 return ODS_STATUS_UNCHANGED;
645 if (do_stats && zone->
stats) {
648 return ODS_STATUS_OK;
663 ods_log_assert(zone);
664 ods_log_assert(zone->
name);
665 ods_log_assert(zone->
db);
669 ods_log_verbose(
"[%s] unable to delete RR from zone %s: "
670 "domain not found", zone_str, zone->
name);
671 return ODS_STATUS_UNCHANGED;
676 ods_log_verbose(
"[%s] NSEC3PARAM in zone %s not found: "
677 "skipping delete", zone_str, zone->
name);
678 return ODS_STATUS_UNCHANGED;
685 for (i=0; i < rrset->
rr_count; i++) {
688 return ODS_STATUS_OK;
709 ods_log_error(
"[%s] failed to merge policy %s name to zone "
727 ods_log_error(
"[%s] failed to merge signconf filename %s to "
767 ldns_rdf_deep_free(zone->
apex);
781 free((
void*)zone->
name);
782 collection_class_destroy(&zone->
rrstore);
783 pthread_mutex_destroy(&zone->
xfr_lock);
796 char* filename = NULL;
798 const char* token = NULL;
800 ods_status status = ODS_STATUS_OK;
803 uint32_t inbound = 0,
internal = 0, outbound = 0;
807 const char* salt = NULL;
809 ods_log_assert(zone);
810 ods_log_assert(zone->
name);
812 ods_log_assert(zone->
db);
814 filename = ods_build_path(zone->
name,
".backup2", 0, 1);
816 return ODS_STATUS_MALLOC_ERR;
818 fd = ods_fopen(filename, NULL,
"r");
822 ods_log_error(
"[%s] corrupted backup file zone %s: read magic "
823 "error", zone_str, zone->
name);
828 ods_log_error(
"[%s] corrupted backup file zone %s: read time "
829 "error", zone_str, zone->
name);
836 ods_log_error(
"[%s] corrupted backup file zone %s: read name "
837 "error", zone_str, zone->
name);
842 ods_log_error(
"[%s] corrupted backup file zone %s: read class "
843 "error", zone_str, zone->
name);
852 ods_log_error(
"[%s] corrupted backup file zone %s: read serial "
853 "error", zone_str, zone->
name);
856 zone->
klass = (ldns_rr_class) klass;
890 ods_log_error(
"[%s] corrupted backup file zone %s: read signconf "
891 "error", zone_str, zone->
name);
905 ods_log_error(
"[%s] corrupted backup file zone %s: read "
906 "nsec3parameters error", zone_str, zone->
name);
919 ods_log_error(
"[%s] corrupted backup file zone %s: unable to "
920 "create nsec3param", zone_str, zone->
name);
930 if (ods_strcmp(token,
";;Key:") == 0) {
932 ods_log_error(
"[%s] corrupted backup file zone %s: read "
933 "key error", zone_str, zone->
name);
936 }
else if (ods_strcmp(token,
";;") == 0) {
950 if (status != ODS_STATUS_OK) {
951 ods_log_error(
"[%s] corrupted backup file zone %s: unable to "
952 "publish dnskeys (%s)", zone_str, zone->
name,
953 ods_status2str(status));
959 if (status != ODS_STATUS_OK) {
960 ods_log_error(
"[%s] corrupted backup file zone %s: unable to "
961 "publish nsec3param (%s)", zone_str, zone->
name,
962 ods_status2str(status));
967 if (status != ODS_STATUS_OK) {
968 ods_log_error(
"[%s] corrupted backup file zone %s: unable to "
969 "read resource records (%s)", zone_str, zone->
name,
970 ods_status2str(status));
974 schedule_scheduletask(engine->
taskq, TASK_SIGN, zone->
name, zone, &zone->
zone_lock, schedule_PROMPTLY);
975 free((
void*)filename);
980 filename = ods_build_path(zone->
name,
".ixfr", 0, 1);
982 fd = ods_fopen(filename, NULL,
"r");
986 if (status != ODS_STATUS_OK) {
987 ods_log_warning(
"[%s] corrupted journal file zone %s, "
988 "skipping (%s)", zone_str, zone->
name,
989 ods_status2str(status));
990 (void)unlink(filename);
1000 free((
void*)filename);
1009 return ODS_STATUS_OK;
1012 return ODS_STATUS_UNCHANGED;
1015 free((
void*)filename);
1026 ods_log_assert(zone->db);
1029 pthread_mutex_lock(&zone->stats->stats_lock);
1031 pthread_mutex_unlock(&zone->stats->stats_lock);
1033 return ODS_STATUS_ERR;
1044 char* filename = NULL;
1045 char* tmpfile = NULL;
1048 ods_status status = ODS_STATUS_OK;
1050 ods_log_assert(zone);
1051 ods_log_assert(zone->
name);
1052 ods_log_assert(zone->
db);
1055 tmpfile = ods_build_path(zone->
name,
".backup2.tmp", 0, 1);
1056 filename = ods_build_path(zone->
name,
".backup2", 0, 1);
1057 if (!tmpfile || !filename) {
1060 return ODS_STATUS_MALLOC_ERR;
1062 fd = ods_fopen(tmpfile, NULL,
"w");
1064 fprintf(fd,
"%s\n", ODS_SE_FILE_MAGIC_V3);
1065 fprintf(fd,
";;Time: %u\n", (
unsigned) nextResign);
1067 fprintf(fd,
";;Zone: name %s class %i inbound %u internal %u "
1068 "outbound %u\n", zone->
name, (
int) zone->
klass,
1082 ODS_SE_FILE_MAGIC_V3);
1086 fprintf(fd,
";;\n");
1090 fprintf(fd,
"%s\n", ODS_SE_FILE_MAGIC_V3);
1092 ret = rename(tmpfile, filename);
1094 ods_log_error(
"[%s] unable to rename zone %s backup %s to %s: %s",
1095 zone_str, zone->
name, tmpfile, filename, strerror(errno));
1096 status = ODS_STATUS_RENAME_ERR;
1099 status = ODS_STATUS_FOPEN_ERR;
1102 free((
void*) tmpfile);
1103 free((
void*) filename);