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);
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);
311 ods_status status = ODS_STATUS_OK;
314 return ODS_STATUS_ASSERT_ERR;
319 return ODS_STATUS_OK;
325 rr = ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAMS);
327 ods_log_error(
"[%s] unable to publish nsec3params for zone %s: "
328 "error creating rr (%s)", zone_str, zone->
name,
329 ods_status2str(status));
330 return ODS_STATUS_MALLOC_ERR;
332 ldns_rr_set_class(rr, zone->
klass);
333 ldns_rr_set_ttl(rr, paramttl);
334 ldns_rr_set_owner(rr, ldns_rdf_clone(zone->
apex));
335 ldns_nsec3_add_param_rdfs(rr,
344 ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(rr, 1)), 7, 0);
353 if (status == ODS_STATUS_UNCHANGED) {
354 status = ODS_STATUS_OK;
355 }
else if (status != ODS_STATUS_OK) {
356 ods_log_error(
"[%s] unable to publish nsec3params for zone %s: "
357 "error adding nsec3params (%s)", zone_str,
358 zone->
name, ods_status2str(status));
380 if (n3prr && !n3prr->
exists &&
395 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: error creating libhsm context", zone_str, zone->
name);
408 return ODS_STATUS_HSM_ERR;
417 if (status != ODS_STATUS_OK) {
418 ods_log_error(
"[%s] unable to prepare signing keys for zone %s: error getting dnskey", zone_str, zone->
name);
424 hsm_destroy_context(ctx);
436 ods_status status = ODS_STATUS_OK;
440 ldns_rdf* soa_rdata = NULL;
442 ods_log_assert(zone);
443 ods_log_assert(zone->
apex);
444 ods_log_assert(zone->
name);
445 ods_log_assert(zone->
db);
450 ods_log_debug(
"[%s] zone %s soa serial already up to date",
451 zone_str, zone->
name);
453 return ODS_STATUS_OK;
456 if (!rrset || !rrset->
rrs || !rrset->
rrs[0].
rr) {
457 ods_log_error(
"[%s] unable to update zone %s soa serial: failed to "
458 "find soa rrset", zone_str, zone->
name);
459 return ODS_STATUS_ERR;
461 ods_log_assert(rrset);
462 ods_log_assert(rrset->
rrs);
463 ods_log_assert(rrset->
rrs[0].
rr);
464 rr = ldns_rr_clone(rrset->
rrs[0].
rr);
466 ods_log_error(
"[%s] unable to update zone %s soa serial: failed to "
467 "clone soa rr", zone_str, zone->
name);
468 return ODS_STATUS_ERR;
472 if (status != ODS_STATUS_OK) {
473 ods_log_error(
"[%s] unable to update zone %s soa serial: %s",
474 zone_str, zone->
name, ods_status2str(status));
475 if (status == ODS_STATUS_CONFLICT_ERR) {
476 ods_log_error(
"[%s] If this is the result of a key rollover, "
477 "please increment the serial in the unsigned zone %s",
478 zone_str, zone->
name);
483 ods_log_verbose(
"[%s] zone %s set soa serial to %u", zone_str,
485 soa_rdata = ldns_rr_set_rdf(rr,
486 ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
489 ldns_rdf_deep_free(soa_rdata);
492 ods_log_error(
"[%s] unable to update zone %s soa serial: failed to "
493 "replace soa serial rdata", zone_str, zone->
name);
495 return ODS_STATUS_ERR;
501 return ODS_STATUS_OK;
513 if (!zone || !owner || !type) {
534 ods_status status = ODS_STATUS_OK;
537 ods_log_assert(zone);
538 ods_log_assert(zone->
name);
539 ods_log_assert(zone->
db);
546 ods_log_error(
"[%s] unable to add RR to zone %s: "
547 "failed to add domain", zone_str, zone->
name);
548 return ODS_STATUS_ERR;
550 if (ldns_dname_compare(domain->
dname, zone->
apex) == 0) {
554 if (status != ODS_STATUS_OK) {
555 ods_log_error(
"[%s] unable to add RR to zone %s: "
556 "failed to entize domain", zone_str, zone->
name);
557 return ODS_STATUS_ERR;
565 ods_log_error(
"[%s] unable to add RR to zone %s: "
566 "failed to add RRset", zone_str, zone->
name);
567 return ODS_STATUS_ERR;
573 uint32_t ttl_rr = ldns_rr_ttl(rr);
576 if (record && ttl_rr == ttl_rrset && ttl_rr == ldns_rr_ttl(record->
rr)) {
579 return ODS_STATUS_UNCHANGED;
582 ods_log_assert(record);
583 ods_log_assert(record->
rr);
585 if (ttl_rr != ttl_rrset) {
586 char *str = ldns_rr2str(rr);
587 str[(strlen(str)) - 1] =
'\0';
588 for (
int i = 0; i < strlen(str); i++) {
589 if (str[i] ==
'\t') {
593 ods_log_error(
"In zone file %s: TTL for the record '%s' (%d) not"
594 " equal to recordset TTL (%d)", zone->
name, str, ttl_rr, ttl_rrset);
599 if (do_stats && zone->
stats) {
602 return ODS_STATUS_OK;
617 ods_log_assert(zone);
618 ods_log_assert(zone->
name);
619 ods_log_assert(zone->
db);
623 ods_log_warning(
"[%s] unable to delete RR from zone %s: "
624 "domain not found", zone_str, zone->
name);
625 return ODS_STATUS_UNCHANGED;
629 ods_log_warning(
"[%s] unable to delete RR from zone %s: "
630 "RRset not found", zone_str, zone->
name);
631 return ODS_STATUS_UNCHANGED;
635 ods_log_error(
"[%s] unable to delete RR from zone %s: "
636 "RR not found", zone_str, zone->
name);
637 return ODS_STATUS_UNCHANGED;
643 if (do_stats && zone->
stats) {
646 return ODS_STATUS_OK;
661 ods_log_assert(zone);
662 ods_log_assert(zone->
name);
663 ods_log_assert(zone->
db);
667 ods_log_verbose(
"[%s] unable to delete RR from zone %s: "
668 "domain not found", zone_str, zone->
name);
669 return ODS_STATUS_UNCHANGED;
674 ods_log_verbose(
"[%s] NSEC3PARAM in zone %s not found: "
675 "skipping delete", zone_str, zone->
name);
676 return ODS_STATUS_UNCHANGED;
683 for (i=0; i < rrset->
rr_count; i++) {
686 return ODS_STATUS_OK;
707 ods_log_error(
"[%s] failed to merge policy %s name to zone "
725 ods_log_error(
"[%s] failed to merge signconf filename %s to "
765 ldns_rdf_deep_free(zone->
apex);
779 free((
void*)zone->
name);
780 collection_class_destroy(&zone->
rrstore);
781 pthread_mutex_destroy(&zone->
xfr_lock);
794 char* filename = NULL;
796 const char* token = NULL;
798 ods_status status = ODS_STATUS_OK;
801 uint32_t inbound = 0,
internal = 0, outbound = 0;
805 const char* salt = NULL;
807 ods_log_assert(zone);
808 ods_log_assert(zone->
name);
810 ods_log_assert(zone->
db);
812 filename = ods_build_path(zone->
name,
".backup2", 0, 1);
814 return ODS_STATUS_MALLOC_ERR;
816 fd = ods_fopen(filename, NULL,
"r");
820 ods_log_error(
"[%s] corrupted backup file zone %s: read magic "
821 "error", zone_str, zone->
name);
826 ods_log_error(
"[%s] corrupted backup file zone %s: read time "
827 "error", zone_str, zone->
name);
834 ods_log_error(
"[%s] corrupted backup file zone %s: read name "
835 "error", zone_str, zone->
name);
840 ods_log_error(
"[%s] corrupted backup file zone %s: read class "
841 "error", zone_str, zone->
name);
850 ods_log_error(
"[%s] corrupted backup file zone %s: read serial "
851 "error", zone_str, zone->
name);
854 zone->
klass = (ldns_rr_class) klass;
888 ods_log_error(
"[%s] corrupted backup file zone %s: read signconf "
889 "error", zone_str, zone->
name);
903 ods_log_error(
"[%s] corrupted backup file zone %s: read "
904 "nsec3parameters error", zone_str, zone->
name);
917 ods_log_error(
"[%s] corrupted backup file zone %s: unable to "
918 "create nsec3param", zone_str, zone->
name);
928 if (ods_strcmp(token,
";;Key:") == 0) {
930 ods_log_error(
"[%s] corrupted backup file zone %s: read "
931 "key error", zone_str, zone->
name);
934 }
else if (ods_strcmp(token,
";;") == 0) {
948 if (status != ODS_STATUS_OK) {
949 ods_log_error(
"[%s] corrupted backup file zone %s: unable to "
950 "publish dnskeys (%s)", zone_str, zone->
name,
951 ods_status2str(status));
957 if (status != ODS_STATUS_OK) {
958 ods_log_error(
"[%s] corrupted backup file zone %s: unable to "
959 "publish nsec3param (%s)", zone_str, zone->
name,
960 ods_status2str(status));
965 if (status != ODS_STATUS_OK) {
966 ods_log_error(
"[%s] corrupted backup file zone %s: unable to "
967 "read resource records (%s)", zone_str, zone->
name,
968 ods_status2str(status));
972 schedule_scheduletask(engine->
taskq, TASK_SIGN, zone->
name, zone, &zone->
zone_lock, schedule_PROMPTLY);
973 free((
void*)filename);
978 filename = ods_build_path(zone->
name,
".ixfr", 0, 1);
980 fd = ods_fopen(filename, NULL,
"r");
984 if (status != ODS_STATUS_OK) {
985 ods_log_warning(
"[%s] corrupted journal file zone %s, "
986 "skipping (%s)", zone_str, zone->
name,
987 ods_status2str(status));
988 (void)unlink(filename);
998 free((
void*)filename);
1007 return ODS_STATUS_OK;
1010 return ODS_STATUS_UNCHANGED;
1013 free((
void*)filename);
1024 ods_log_assert(zone->
db);
1031 return ODS_STATUS_ERR;
1042 char* filename = NULL;
1043 char* tmpfile = NULL;
1046 ods_status status = ODS_STATUS_OK;
1048 ods_log_assert(zone);
1049 ods_log_assert(zone->
name);
1050 ods_log_assert(zone->
db);
1053 tmpfile = ods_build_path(zone->
name,
".backup2.tmp", 0, 1);
1054 filename = ods_build_path(zone->
name,
".backup2", 0, 1);
1055 if (!tmpfile || !filename) {
1058 return ODS_STATUS_MALLOC_ERR;
1060 fd = ods_fopen(tmpfile, NULL,
"w");
1062 fprintf(fd,
"%s\n", ODS_SE_FILE_MAGIC_V3);
1063 fprintf(fd,
";;Time: %u\n", (
unsigned) nextResign);
1065 fprintf(fd,
";;Zone: name %s class %i inbound %u internal %u "
1066 "outbound %u\n", zone->
name, (
int) zone->
klass,
1080 ODS_SE_FILE_MAGIC_V3);
1084 fprintf(fd,
";;\n");
1088 fprintf(fd,
"%s\n", ODS_SE_FILE_MAGIC_V3);
1090 ret = rename(tmpfile, filename);
1092 ods_log_error(
"[%s] unable to rename zone %s backup %s to %s: %s",
1093 zone_str, zone->
name, tmpfile, filename, strerror(errno));
1094 status = ODS_STATUS_RENAME_ERR;
1097 status = ODS_STATUS_FOPEN_ERR;
1100 free((
void*) tmpfile);
1101 free((
void*) filename);
int adapter_compare(adapter_type *a1, adapter_type *a2)
void adapter_cleanup(adapter_type *adapter)
ods_status backup_read_namedb(FILE *in, void *zone)
int backup_read_uint32_t(FILE *in, uint32_t *v)
int backup_read_int(FILE *in, int *v)
ods_status backup_read_ixfr(FILE *in, void *zone)
int backup_read_rr_type(FILE *in, ldns_rr_type *v)
int backup_read_time_t(FILE *in, time_t *v)
int backup_read_check_str(FILE *in, const char *str)
int backup_read_duration(FILE *in, duration_type **v)
int backup_read_str(FILE *in, const char **str)
rrset_type * domain_lookup_rrset(domain_type *domain, ldns_rr_type rrtype)
void domain_add_rrset(domain_type *domain, rrset_type *rrset)
ods_status lhsm_get_key(hsm_ctx_t *ctx, ldns_rdf *owner, key_type *key_id, int skip_hsm_access)
void ixfr_purge(ixfr_type *ixfr, char const *zonename)
ixfr_type * ixfr_create()
void ixfr_cleanup(ixfr_type *ixfr)
keylist_type * keylist_create(signconf_type *signconf)
void keylist_backup(FILE *fd, keylist_type *kl, const char *version)
key_type * key_recover2(FILE *fd, keylist_type *kl)
domain_type * namedb_add_domain(namedb_type *db, ldns_rdf *dname)
domain_type * namedb_lookup_domain(namedb_type *db, ldns_rdf *dname)
void namedb_cleanup(namedb_type *db)
void namedb_backup2(FILE *fd, namedb_type *db)
ods_status namedb_domain_entize(namedb_type *db, domain_type *domain, ldns_rdf *apex)
namedb_type * namedb_create(void *zone)
ods_status namedb_update_serial(namedb_type *db, const char *zone_name, const char *format, uint32_t inbound_serial)
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)
nsec3params_type * nsec3params_create(void *sc, uint8_t algo, uint8_t flags, uint16_t iter, const char *salt)
rrset_type * rrset_create(zone_type *zone, ldns_rr_type type)
collection_class rrset_store_initialize()
ods_status rrset_getliteralrr(ldns_rr **dnskey, const char *resourcerecord, uint32_t ttl, ldns_rdf *apex)
rr_type * rrset_add_rr(rrset_type *rrset, ldns_rr *rr)
void rrset_diff(rrset_type *rrset, unsigned is_ixfr, unsigned more_coming)
rr_type * rrset_lookup_rr(rrset_type *rrset, ldns_rr *rr)
uint32_t rrset_lookup_ttl(rrset_type *rrset, uint32_t default_ttl)
signconf_type * signconf_create(void)
void signconf_backup(FILE *fd, signconf_type *sc, const char *version)
ods_status signconf_update(signconf_type **signconf, const char *scfile, time_t last_modified)
void signconf_cleanup(signconf_type *sc)
stats_type * stats_create(void)
void stats_clear(stats_type *stats)
void stats_cleanup(stats_type *stats)
pthread_mutex_t ixfr_lock
const char * resourcerecord
hsm_sign_params_t * params
duration_type * sig_jitter
duration_type * sig_refresh_interval
uint32_t nsec3_iterations
duration_type * nsec3param_ttl
duration_type * sig_resign_interval
nsec3params_type * nsec3params
duration_type * sig_inception_offset
const char ** dnskey_signature
duration_type * sig_validity_keyset
duration_type * sig_validity_denial
duration_type * dnskey_ttl
duration_type * sig_validity_default
pthread_mutex_t stats_lock
const char * signconf_filename
pthread_mutex_t zone_lock
adapter_type * adoutbound
void xfrd_cleanup(xfrd_type *xfrd, int backup)
ods_status zone_backup2(zone_type *zone, time_t nextResign)
void zone_rollback_nsec3param(zone_type *zone)
ods_status zone_update_serial(zone_type *zone)
ods_status zone_publish_dnskeys(zone_type *zone, int skip_hsm_access)
ods_status zone_add_rr(zone_type *zone, ldns_rr *rr, int do_stats)
void zone_rollback_dnskeys(zone_type *zone)
ods_status zone_del_nsec3params(zone_type *zone)
void zone_merge(zone_type *z1, zone_type *z2)
ods_status zone_load_signconf(zone_type *zone, signconf_type **new_signconf)
zone_type * zone_create(char *name, ldns_rr_class klass)
ods_status zone_del_rr(zone_type *zone, ldns_rr *rr, int do_stats)
rrset_type * zone_lookup_rrset(zone_type *zone, ldns_rdf *owner, ldns_rr_type type)
void zone_cleanup(zone_type *zone)
ods_status zone_prepare_keys(zone_type *zone)
ods_status zone_publish_nsec3param(zone_type *zone)
ods_status zone_recover2(engine_type *engine, zone_type *zone)