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);
signconf_type * signconf_create(void)
ods_status zone_del_nsec3params(zone_type *zone)
void ixfr_cleanup(ixfr_type *ixfr)
rr_type * rrset_lookup_rr(rrset_type *rrset, ldns_rr *rr)
int backup_read_str(FILE *in, const char **str)
pthread_mutex_t ixfr_lock
uint32_t nsec3_iterations
void zone_cleanup(zone_type *zone)
duration_type * sig_inception_offset
ixfr_type * ixfr_create()
ods_status zone_recover2(engine_type *engine, zone_type *zone)
uint32_t rrset_lookup_ttl(rrset_type *rrset, uint32_t default_ttl)
void signconf_backup(FILE *fd, signconf_type *sc, const char *version)
int adapter_compare(adapter_type *a1, adapter_type *a2)
void domain_add_rrset(domain_type *domain, rrset_type *rrset)
rrset_type * domain_lookup_rrset(domain_type *domain, ldns_rr_type rrtype)
int backup_read_duration(FILE *in, duration_type **v)
void zone_merge(zone_type *z1, zone_type *z2)
stats_type * stats_create(void)
ods_status rrset_getliteralrr(ldns_rr **dnskey, const char *resourcerecord, uint32_t ttl, ldns_rdf *apex)
duration_type * sig_validity_default
void signconf_cleanup(signconf_type *sc)
void namedb_cleanup(namedb_type *db)
int backup_read_rr_type(FILE *in, ldns_rr_type *v)
duration_type * sig_validity_denial
duration_type * nsec3param_ttl
int backup_read_time_t(FILE *in, time_t *v)
collection_class rrset_store_initialize()
rr_type * rrset_add_rr(rrset_type *rrset, ldns_rr *rr)
ods_status namedb_update_serial(namedb_type *db, const char *zone_name, const char *format, uint32_t inbound_serial)
keylist_type * keylist_create(signconf_type *signconf)
int backup_read_int(FILE *in, int *v)
zone_type * zone_create(char *name, ldns_rr_class klass)
ods_status backup_read_ixfr(FILE *in, void *zone)
void namedb_backup2(FILE *fd, namedb_type *db)
void notify_cleanup(notify_type *notify)
void nsec3params_backup(FILE *fd, uint8_t algo, uint8_t flags, uint16_t iter, const char *salt, ldns_rr *rr, const char *version)
adapter_type * adoutbound
pthread_mutex_t zone_lock
nsec3params_type * nsec3params_create(void *sc, uint8_t algo, uint8_t flags, uint16_t iter, const char *salt)
ods_status backup_read_namedb(FILE *in, void *zone)
ods_status zone_publish_nsec3param(zone_type *zone)
duration_type * sig_refresh_interval
duration_type * sig_validity_keyset
const char ** dnskey_signature
ods_status namedb_domain_entize(namedb_type *db, domain_type *domain, ldns_rdf *apex)
ods_status zone_update_serial(zone_type *zone)
ods_status zone_add_rr(zone_type *zone, ldns_rr *rr, int do_stats)
void xfrd_cleanup(xfrd_type *xfrd, int backup)
domain_type * namedb_lookup_domain(namedb_type *db, ldns_rdf *dname)
void stats_cleanup(stats_type *stats)
const char * resourcerecord
const char * signconf_filename
void zone_rollback_dnskeys(zone_type *zone)
namedb_type * namedb_create(void *zone)
ods_status zone_del_rr(zone_type *zone, ldns_rr *rr, int do_stats)
void zone_rollback_nsec3param(zone_type *zone)
rrset_type * zone_lookup_rrset(zone_type *zone, ldns_rdf *owner, ldns_rr_type type)
ods_status zone_publish_dnskeys(zone_type *zone, int skip_hsm_access)
nsec3params_type * nsec3params
domain_type * namedb_add_domain(namedb_type *db, ldns_rdf *dname)
duration_type * dnskey_ttl
ods_status zone_prepare_keys(zone_type *zone)
int backup_read_check_str(FILE *in, const char *str)
duration_type * sig_jitter
hsm_sign_params_t * params
duration_type * sig_resign_interval
void ixfr_purge(ixfr_type *ixfr, char const *zonename)
ods_status zone_backup2(zone_type *zone, time_t nextResign)
void rrset_diff(rrset_type *rrset, unsigned is_ixfr, unsigned more_coming)
pthread_mutex_t stats_lock
ods_status zone_load_signconf(zone_type *zone, signconf_type **new_signconf)
rrset_type * rrset_create(zone_type *zone, ldns_rr_type type)
void adapter_cleanup(adapter_type *adapter)
key_type * key_recover2(FILE *fd, keylist_type *kl)
void keylist_backup(FILE *fd, keylist_type *kl, const char *version)
ods_status signconf_update(signconf_type **signconf, const char *scfile, time_t last_modified)
int backup_read_uint32_t(FILE *in, uint32_t *v)
ods_status lhsm_get_key(hsm_ctx_t *ctx, ldns_rdf *owner, key_type *key_id, int skip_hsm_access)
void stats_clear(stats_type *stats)