1 /*
2 * Copyright (c) 2009 NLNet Labs. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
19 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
21 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
23 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 */
26
27 /**
28 * Domain name database.
29 *
30 */
31
32 #include "config.h"
33 #include "status.h"
34 #include "file.h"
35 #include "log.h"
36 #include "util.h"
37 #include "signer/backup.h"
38 #include "signer/namedb.h"
39 #include "signer/zone.h"
40
41 const char* db_str = "namedb";
42
43 /**
44 * Convert a domain to a tree node.
45 *
46 */
47 static ldns_rbnode_t*
domain2node(domain_type * domain)48 domain2node(domain_type* domain)
49 {
50 ldns_rbnode_t* node = (ldns_rbnode_t*) malloc(sizeof(ldns_rbnode_t));
51 if (!node) {
52 return NULL;
53 }
54 node->key = domain->dname;
55 node->data = domain;
56 return node;
57 }
58
59
60 /**
61 * Convert a denial to a tree node.
62 *
63 */
64 static ldns_rbnode_t*
denial2node(denial_type * denial)65 denial2node(denial_type* denial)
66 {
67 ldns_rbnode_t* node = (ldns_rbnode_t*) malloc(sizeof(ldns_rbnode_t));
68 if (!node) {
69 return NULL;
70 }
71 node->key = denial->dname;
72 node->data = denial;
73 return node;
74 }
75
76
77 /**
78 * Compare domains.
79 *
80 */
81 static int
domain_compare(const void * a,const void * b)82 domain_compare(const void* a, const void* b)
83 {
84 ldns_rdf* x = (ldns_rdf*)a;
85 ldns_rdf* y = (ldns_rdf*)b;
86 return ldns_dname_compare(x, y);
87 }
88
89
90 /**
91 * Initialize denials.
92 *
93 */
94 void
namedb_init_denials(namedb_type * db)95 namedb_init_denials(namedb_type* db)
96 {
97 if (db) {
98 db->denials = ldns_rbtree_create(domain_compare);
99 }
100 }
101
102
103 /**
104 * Initialize domains.
105 *
106 */
107 static void
namedb_init_domains(namedb_type * db)108 namedb_init_domains(namedb_type* db)
109 {
110 if (db) {
111 db->domains = ldns_rbtree_create(domain_compare);
112 }
113 }
114
115
116 /**
117 * Create a new namedb.
118 *
119 */
120 namedb_type*
namedb_create(void * zone)121 namedb_create(void* zone)
122 {
123 namedb_type* db = NULL;
124 zone_type* z = (zone_type*) zone;
125
126 ods_log_assert(z);
127 ods_log_assert(z->name);
128 CHECKALLOC(db = (namedb_type*) malloc(sizeof(namedb_type)));
129 if (!db) {
130 ods_log_error("[%s] unable to create namedb for zone %s: "
131 "allocator_alloc() failed", db_str, z->name);
132 return NULL;
133 }
134 db->zone = zone;
135
136 namedb_init_domains(db);
137 if (!db->domains) {
138 ods_log_error("[%s] unable to create namedb for zone %s: "
139 "init domains failed", db_str, z->name);
140 namedb_cleanup(db);
141 return NULL;
142 }
143 namedb_init_denials(db);
144 if (!db->denials) {
145 ods_log_error("[%s] unable to create namedb for zone %s: "
146 "init denials failed", db_str, z->name);
147 namedb_cleanup(db);
148 return NULL;
149 }
150 db->inbserial = 0;
151 db->intserial = 0;
152 db->outserial = 0;
153 db->altserial = 0;
154 db->is_initialized = 0;
155 db->have_serial = 0;
156 db->serial_updated = 0;
157 db->force_serial = 0;
158 return db;
159 }
160
161
162 /**
163 * Internal lookup domain function.
164 *
165 */
166 static void*
namedb_domain_search(ldns_rbtree_t * tree,ldns_rdf * dname)167 namedb_domain_search(ldns_rbtree_t* tree, ldns_rdf* dname)
168 {
169 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
170 if (!tree || !dname) {
171 return NULL;
172 }
173 node = ldns_rbtree_search(tree, dname);
174 if (node && node != LDNS_RBTREE_NULL) {
175 return (void*) node->data;
176 }
177 return NULL;
178 }
179
180
181 static uint32_t
max(uint32_t a,uint32_t b)182 max(uint32_t a, uint32_t b)
183 {
184 return (a<b?b:a);
185 }
186
187
188 /**
189 * Determine new SOA SERIAL.
190 *
191 */
192 ods_status
namedb_update_serial(namedb_type * db,const char * zone_name,const char * format,uint32_t inbound_serial)193 namedb_update_serial(namedb_type* db, const char* zone_name, const char* format,
194 uint32_t inbound_serial)
195 {
196 uint32_t soa = 0;
197 uint32_t prev = 0;
198 uint32_t update = 0;
199 if (!db || !format || !zone_name) {
200 return ODS_STATUS_ASSERT_ERR;
201 }
202 prev = max(db->outserial, inbound_serial);
203 if (!db->have_serial) {
204 prev = inbound_serial;
205 }
206 ods_log_debug("[%s] zone %s update serial: format=%s in=%u internal=%u "
207 "out=%u now=%u", db_str, zone_name, format, db->inbserial,
208 db->intserial, db->outserial, (uint32_t) time_now());
209 if (db->force_serial) {
210 soa = db->altserial;
211 if (!util_serial_gt(soa, prev)) {
212 ods_log_warning("[%s] zone %s unable to enforce serial: %u does not "
213 " increase %u. Serial set to %u", db_str, zone_name, soa, prev,
214 (prev+1));
215 soa = prev + 1;
216 } else {
217 ods_log_info("[%s] zone %s enforcing serial %u", db_str, zone_name,
218 soa);
219 }
220 db->force_serial = 0;
221 } else if (ods_strcmp(format, "unixtime") == 0) {
222 soa = (uint32_t) time_now();
223 if (!util_serial_gt(soa, prev)) {
224 if (!db->have_serial) {
225 ods_log_warning("[%s] zone %s unable to use unixtime as serial: "
226 "%u does not increase %u. Serial set to %u", db_str,
227 zone_name, soa, prev, (prev+1));
228 }
229 soa = prev + 1;
230 }
231 } else if (ods_strcmp(format, "datecounter") == 0) {
232 soa = (uint32_t) time_datestamp(0, "%Y%m%d", NULL) * 100;
233 if (!util_serial_gt(soa, prev)) {
234 if (!db->have_serial) {
235 ods_log_info("[%s] zone %s unable to use datecounter as "
236 "serial: %u does not increase %u. Serial set to %u", db_str,
237 zone_name, soa, prev, (prev+1));
238 }
239 soa = prev + 1;
240 }
241 } else if (ods_strcmp(format, "counter") == 0) {
242 soa = inbound_serial + 1;
243 if (db->have_serial && !util_serial_gt(soa, prev)) {
244 soa = prev + 1;
245 }
246 } else if (ods_strcmp(format, "keep") == 0) {
247 prev = db->outserial;
248 soa = inbound_serial;
249 if (db->have_serial && !util_serial_gt(soa, prev)) {
250 ods_log_error("[%s] zone %s cannot keep SOA SERIAL from input zone "
251 " (%u): previous output SOA SERIAL is %u", db_str, zone_name,
252 soa, prev);
253 return ODS_STATUS_CONFLICT_ERR;
254 }
255 } else {
256 ods_log_error("[%s] zone %s unknown serial type %s", db_str, zone_name,
257 format);
258 return ODS_STATUS_ERR;
259 }
260 /* serial is stored in 32 bits */
261 update = soa - prev;
262 if (update > 0x7FFFFFFF) {
263 update = 0x7FFFFFFF;
264 }
265 if (!db->have_serial) {
266 db->intserial = soa;
267 } else {
268 db->intserial = prev + update; /* automatically does % 2^32 */
269 }
270 ods_log_debug("[%s] zone %s update serial: %u + %u = %u", db_str, zone_name,
271 prev, update, db->intserial);
272 return ODS_STATUS_OK;
273 }
274
275
276 /**
277 * Add empty non-terminals for domain.
278 *
279 */
280 ods_status
namedb_domain_entize(namedb_type * db,domain_type * domain,ldns_rdf * apex)281 namedb_domain_entize(namedb_type* db, domain_type* domain, ldns_rdf* apex)
282 {
283 ldns_rdf* parent_rdf = NULL;
284 domain_type* parent_domain = NULL;
285 ods_log_assert(apex);
286 ods_log_assert(domain);
287 ods_log_assert(domain->dname);
288 ods_log_assert(db);
289 ods_log_assert(db->domains);
290 if (domain->parent) {
291 /* domain already has parent */
292 return ODS_STATUS_OK;
293 }
294
295 while (domain && ldns_dname_is_subdomain(domain->dname, apex) &&
296 ldns_dname_compare(domain->dname, apex) != 0) {
297 /**
298 * RFC5155:
299 * 4. If the difference in number of labels between the apex and
300 * the original owner name is greater than 1, additional NSEC3
301 * RRs need to be added for every empty non-terminal between
302 * the apex and the original owner name.
303 */
304 parent_rdf = ldns_dname_left_chop(domain->dname);
305 if (!parent_rdf) {
306 ods_log_error("[%s] unable to entize domain: left chop failed",
307 db_str);
308 return ODS_STATUS_ERR;
309 }
310 parent_domain = namedb_lookup_domain(db, parent_rdf);
311 if (!parent_domain) {
312 parent_domain = namedb_add_domain(db, parent_rdf);
313 ldns_rdf_deep_free(parent_rdf);
314 if (!parent_domain) {
315 ods_log_error("[%s] unable to entize domain: failed to add "
316 "parent domain", db_str);
317 return ODS_STATUS_ERR;
318 }
319 domain->parent = parent_domain;
320 /* continue with the parent domain */
321 domain = parent_domain;
322 } else {
323 ldns_rdf_deep_free(parent_rdf);
324 domain->parent = parent_domain;
325 /* domain has parent, entize done */
326 domain = NULL;
327 }
328 }
329 return ODS_STATUS_OK;
330 }
331
332
333 /**
334 * Lookup domain.
335 *
336 */
337 domain_type*
namedb_lookup_domain(namedb_type * db,ldns_rdf * dname)338 namedb_lookup_domain(namedb_type* db, ldns_rdf* dname)
339 {
340 if (!db) {
341 return NULL;
342 }
343 return (domain_type*) namedb_domain_search(db->domains, dname);
344 }
345
346
347 /**
348 * Add domain to namedb.
349 *
350 */
351 domain_type*
namedb_add_domain(namedb_type * db,ldns_rdf * dname)352 namedb_add_domain(namedb_type* db, ldns_rdf* dname)
353 {
354 domain_type* domain = NULL;
355 ldns_rbnode_t* new_node = LDNS_RBTREE_NULL;
356 if (!dname || !db || !db->domains) {
357 return NULL;
358 }
359 domain = domain_create(db->zone, dname);
360 if (!domain) {
361 ods_log_error("[%s] unable to add domain: domain_create() failed",
362 db_str);
363 return NULL;
364 }
365 new_node = domain2node(domain);
366 if (!new_node) {
367 ods_log_error("[%s] unable to add domain: domain2node() failed",
368 db_str);
369 return NULL;
370 }
371 if (ldns_rbtree_insert(db->domains, new_node) == NULL) {
372 ods_log_error("[%s] unable to add domain: already present", db_str);
373 log_dname(domain->dname, "ERR +DOMAIN", LOG_ERR);
374 domain_cleanup(domain);
375 free((void*)new_node);
376 return NULL;
377 }
378 domain = (domain_type*) new_node->data;
379 domain->node = new_node;
380 domain->is_new = 1;
381 log_dname(domain->dname, "+DOMAIN", LOG_DEEEBUG);
382 return domain;
383 }
384
385
386 /**
387 * Delete domain from namedb
388 *
389 */
390 domain_type*
namedb_del_domain(namedb_type * db,domain_type * domain)391 namedb_del_domain(namedb_type* db, domain_type* domain)
392 {
393 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
394 if (!domain || !db || !db->domains) {
395 ods_log_error("[%s] unable to delete domain: !db || !domain", db_str);
396 return NULL;
397 }
398 if (domain->rrsets || domain->denial) {
399 ods_log_error("[%s] unable to delete domain: domain in use", db_str);
400 log_dname(domain->dname, "ERR -DOMAIN", LOG_ERR);
401 return NULL;
402 }
403 node = ldns_rbtree_delete(db->domains, (const void*)domain->dname);
404 if (node) {
405 ods_log_assert(domain->node == node);
406 ods_log_assert(!domain->rrsets);
407 ods_log_assert(!domain->denial);
408 free((void*)node);
409 domain->node = NULL;
410 log_dname(domain->dname, "-DOMAIN", LOG_DEEEBUG);
411 return domain;
412 }
413 ods_log_error("[%s] unable to delete domain: not found", db_str);
414 log_dname(domain->dname, "ERR -DOMAIN", LOG_ERR);
415 return NULL;
416 }
417
418
419 /**
420 * Lookup denial.
421 *
422 */
423 denial_type*
namedb_lookup_denial(namedb_type * db,ldns_rdf * dname)424 namedb_lookup_denial(namedb_type* db, ldns_rdf* dname)
425 {
426 if (!db) {
427 return NULL;
428 }
429 return (denial_type*) namedb_domain_search(db->denials, dname);
430 }
431
432
433 /**
434 * See if a domain is an empty terminal
435 *
436 */
437 static int
domain_is_empty_terminal(domain_type * domain)438 domain_is_empty_terminal(domain_type* domain)
439 {
440 ldns_rbnode_t* n = LDNS_RBTREE_NULL;
441 domain_type* d = NULL;
442 ods_log_assert(domain);
443 if (domain->is_apex) {
444 return 0;
445 }
446 if (domain->rrsets) {
447 return 0;
448 }
449 n = ldns_rbtree_next(domain->node);
450 if (n) {
451 d = (domain_type*) n->data;
452 }
453 /* if it has children domains, do not delete it */
454 if(d && ldns_dname_is_subdomain(d->dname, domain->dname)) {
455 return 0;
456 }
457 return 1;
458 }
459
460
461 /**
462 * See if a domain can be deleted
463 *
464 */
465 static int
domain_can_be_deleted(domain_type * domain)466 domain_can_be_deleted(domain_type* domain)
467 {
468 ods_log_assert(domain);
469 return (domain_is_empty_terminal(domain) && !domain->denial);
470 }
471
472
473 /**
474 * Add NSEC data point.
475 *
476 */
477 static void
namedb_add_nsec_trigger(namedb_type * db,domain_type * domain)478 namedb_add_nsec_trigger(namedb_type* db, domain_type* domain)
479 {
480 ldns_rr_type dstatus = LDNS_RR_TYPE_FIRST;
481 denial_type* denial = NULL;
482 ods_log_assert(db);
483 ods_log_assert(domain);
484 ods_log_assert(!domain->denial);
485 dstatus = domain_is_occluded(domain);
486 if (dstatus == LDNS_RR_TYPE_DNAME || dstatus == LDNS_RR_TYPE_A) {
487 return; /* don't do occluded/glue domain */
488 }
489 if (!domain->rrsets) {
490 return; /* don't do empty domain */
491 }
492 /* ok, nsecify this domain */
493 denial = namedb_add_denial(db, domain->dname, NULL);
494 ods_log_assert(denial);
495 denial->domain = (void*) domain;
496 domain->denial = (void*) denial;
497 domain->is_new = 0;
498 }
499
500
501 /**
502 * Add NSEC3 data point.
503 *
504 */
505 static void
namedb_add_nsec3_trigger(namedb_type * db,domain_type * domain,nsec3params_type * n3p)506 namedb_add_nsec3_trigger(namedb_type* db, domain_type* domain,
507 nsec3params_type* n3p)
508 {
509 ldns_rr_type dstatus = LDNS_RR_TYPE_FIRST;
510 denial_type* denial = NULL;
511 ods_log_assert(db);
512 ods_log_assert(n3p);
513 ods_log_assert(domain);
514 ods_log_assert(!domain->denial);
515 dstatus = domain_is_occluded(domain);
516 if (dstatus == LDNS_RR_TYPE_DNAME || dstatus == LDNS_RR_TYPE_A) {
517 return; /* don't do occluded/glue domain */
518 }
519 /* Opt-Out? */
520 if (n3p->flags) {
521 dstatus = domain_is_delegpt(domain);
522 /* If Opt-Out is being used, owner names of unsigned delegations
523 MAY be excluded. */
524 if (dstatus == LDNS_RR_TYPE_NS) {
525 return;
526 }
527 }
528 /* ok, nsecify3 this domain */
529 denial = namedb_add_denial(db, domain->dname, n3p);
530 ods_log_assert(denial);
531 denial->domain = (void*) domain;
532 domain->denial = (void*) denial;
533 domain->is_new = 0;
534 }
535
536
537 /**
538 * See if denials need to be added.
539 *
540 */
541 static void
namedb_add_denial_trigger(namedb_type * db,domain_type * domain)542 namedb_add_denial_trigger(namedb_type* db, domain_type* domain)
543 {
544 zone_type* zone = NULL;
545 ods_log_assert(db);
546 ods_log_assert(domain);
547 if (!domain->denial) {
548 zone = domain->zone;
549 ods_log_assert(zone);
550 ods_log_assert(zone->signconf);
551 if (!zone->signconf->passthrough) {
552 if (zone->signconf->nsec_type == LDNS_RR_TYPE_NSEC) {
553 namedb_add_nsec_trigger(db, domain);
554 } else {
555 ods_log_assert(zone->signconf->nsec_type == LDNS_RR_TYPE_NSEC3);
556 namedb_add_nsec3_trigger(db, domain, zone->signconf->nsec3params);
557 }
558 }
559 }
560 }
561
562
563 /**
564 * Delete NSEC data point.
565 *
566 */
567 static void
namedb_del_nsec_trigger(namedb_type * db,domain_type * domain)568 namedb_del_nsec_trigger(namedb_type* db, domain_type* domain)
569 {
570 ldns_rr_type dstatus = LDNS_RR_TYPE_FIRST;
571 denial_type* denial = NULL;
572 ods_log_assert(db);
573 ods_log_assert(domain);
574 ods_log_assert(domain->denial);
575 dstatus = domain_is_occluded(domain);
576 if (dstatus == LDNS_RR_TYPE_DNAME || dstatus == LDNS_RR_TYPE_A ||
577 domain_is_empty_terminal(domain) || !domain->rrsets) {
578 /* domain has become occluded/glue or empty non-terminal*/
579 denial_diff((denial_type*) domain->denial);
580 denial = namedb_del_denial(db, domain->denial);
581 denial_cleanup(denial);
582 domain->denial = NULL;
583 }
584 }
585
586
587 /**
588 * Delete NSEC3 data point.
589 *
590 */
591 static void
namedb_del_nsec3_trigger(namedb_type * db,domain_type * domain,nsec3params_type * n3p)592 namedb_del_nsec3_trigger(namedb_type* db, domain_type* domain,
593 nsec3params_type* n3p)
594 {
595 ldns_rr_type dstatus = LDNS_RR_TYPE_FIRST;
596 denial_type* denial = NULL;
597 ods_log_assert(db);
598 ods_log_assert(n3p);
599 ods_log_assert(domain);
600 ods_log_assert(domain->denial);
601 dstatus = domain_is_occluded(domain);
602 if (dstatus == LDNS_RR_TYPE_DNAME || dstatus == LDNS_RR_TYPE_A ||
603 domain_is_empty_terminal(domain)) {
604 /* domain has become occluded/glue */
605 denial_diff((denial_type*) domain->denial);
606 denial = namedb_del_denial(db, domain->denial);
607 denial_cleanup(denial);
608 domain->denial = NULL;
609 } else if (n3p->flags) {
610 dstatus = domain_is_delegpt(domain);
611 /* If Opt-Out is being used, owner names of unsigned delegations
612 MAY be excluded. */
613 if (dstatus == LDNS_RR_TYPE_NS) {
614 denial_diff((denial_type*) domain->denial);
615 denial = namedb_del_denial(db, domain->denial);
616 denial_cleanup(denial);
617 domain->denial = NULL;
618 }
619 }
620 }
621
622
623 /**
624 * See if domains/denials can be deleted.
625 *
626 */
627 static int
namedb_del_denial_trigger(namedb_type * db,domain_type * domain,int rollback)628 namedb_del_denial_trigger(namedb_type* db, domain_type* domain, int rollback)
629 {
630 domain_type* parent = NULL;
631 zone_type* zone = NULL;
632 unsigned is_deleted = 0;
633 ods_log_assert(db);
634 ods_log_assert(domain);
635 ods_log_assert(domain->dname);
636 zone = domain->zone;
637 ods_log_assert(zone);
638 ods_log_assert(zone->signconf);
639 while(domain) {
640 if (!rollback) {
641 if (domain->denial) {
642 if (zone->signconf->nsec_type == LDNS_RR_TYPE_NSEC) {
643 namedb_del_nsec_trigger(db, domain);
644 } else {
645 ods_log_assert(zone->signconf->nsec_type ==
646 LDNS_RR_TYPE_NSEC3);
647 namedb_del_nsec3_trigger(db, domain,
648 zone->signconf->nsec3params);
649 }
650 }
651 }
652 parent = domain->parent;
653 if (domain_can_be_deleted(domain)) {
654 /* -DOMAIN */
655 domain = namedb_del_domain(db, domain);
656 domain_cleanup(domain);
657 is_deleted = 1;
658 }
659 /* continue with parent */
660 domain = parent;
661 }
662 return is_deleted;
663 }
664
665
666 /**
667 * Hash domain name.
668 *
669 */
670 static ldns_rdf*
dname_hash(ldns_rdf * dname,ldns_rdf * apex,nsec3params_type * nsec3params)671 dname_hash(ldns_rdf* dname, ldns_rdf* apex, nsec3params_type* nsec3params)
672 {
673 ldns_rdf* hashed_ownername = NULL;
674 ldns_rdf* hashed_label = NULL;
675 ods_log_assert(dname);
676 ods_log_assert(apex);
677 ods_log_assert(nsec3params);
678 /**
679 * The owner name of the NSEC3 RR is the hash of the original owner
680 * name, prepended as a single label to the zone name.
681 */
682 hashed_label = ldns_nsec3_hash_name(dname, nsec3params->algorithm,
683 nsec3params->iterations, nsec3params->salt_len,
684 nsec3params->salt_data);
685 if (!hashed_label) {
686 return NULL;
687 }
688 hashed_ownername = ldns_dname_cat_clone((const ldns_rdf*) hashed_label,
689 (const ldns_rdf*) apex);
690 if (!hashed_ownername) {
691 return NULL;
692 }
693 ldns_rdf_deep_free(hashed_label);
694 return hashed_ownername;
695 }
696
697
698 /**
699 * Add denial to namedb.
700 *
701 */
702 denial_type*
namedb_add_denial(namedb_type * db,ldns_rdf * dname,nsec3params_type * n3p)703 namedb_add_denial(namedb_type* db, ldns_rdf* dname, nsec3params_type* n3p)
704 {
705 zone_type* z = NULL;
706 ldns_rbnode_t* new_node = LDNS_RBTREE_NULL;
707 ldns_rbnode_t* pnode = LDNS_RBTREE_NULL;
708 ldns_rdf* owner = NULL;
709 denial_type* denial = NULL;
710 denial_type* pdenial = NULL;
711
712 ods_log_assert(db);
713 ods_log_assert(db->denials);
714 ods_log_assert(dname);
715 /* nsec or nsec3 */
716 if (n3p) {
717 z = (zone_type*) db->zone;
718 owner = dname_hash(dname, z->apex, n3p);
719 } else {
720 owner = ldns_rdf_clone(dname);
721 }
722 if (!owner) {
723 ods_log_error("[%s] unable to add denial: create owner failed",
724 db_str);
725 return NULL;
726 }
727 denial = denial_create(db->zone, owner);
728 if (!denial) {
729 ods_log_error("[%s] unable to add denial: denial_create() failed",
730 db_str);
731 return NULL;
732 }
733 new_node = denial2node(denial);
734 if (!new_node) {
735 ods_log_error("[%s] unable to add denial: denial2node() failed",
736 db_str);
737 return NULL;
738 }
739 if (!ldns_rbtree_insert(db->denials, new_node)) {
740 ods_log_error("[%s] unable to add denial: already present", db_str);
741 log_dname(denial->dname, "ERR +DENIAL", LOG_ERR);
742 denial_cleanup(denial);
743 free((void*)new_node);
744 return NULL;
745 }
746 /* denial of existence data point added */
747 denial = (denial_type*) new_node->data;
748 denial->node = new_node;
749 denial->nxt_changed = 1;
750 pnode = ldns_rbtree_previous(new_node);
751 if (!pnode || pnode == LDNS_RBTREE_NULL) {
752 pnode = ldns_rbtree_last(db->denials);
753 }
754 ods_log_assert(pnode);
755 pdenial = (denial_type*) pnode->data;
756 ods_log_assert(pdenial);
757 pdenial->nxt_changed = 1;
758 log_dname(denial->dname, "+DENIAL", LOG_DEEEBUG);
759 return denial;
760 }
761
762
763 /**
764 * Delete denial from namedb
765 *
766 */
767 denial_type*
namedb_del_denial(namedb_type * db,denial_type * denial)768 namedb_del_denial(namedb_type* db, denial_type* denial)
769 {
770 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
771 ldns_rbnode_t* pnode = LDNS_RBTREE_NULL;
772 denial_type* pdenial = NULL;
773
774 if (!denial || !db || !db->denials) {
775 return NULL;
776 }
777 if (denial->rrset && denial->rrset->rr_count) {
778 ods_log_error("[%s] unable to delete denial: denial in use [#%lu]",
779 db_str, (unsigned long)denial->rrset->rr_count);
780 log_dname(denial->dname, "ERR -DENIAL", LOG_ERR);
781 return NULL;
782 }
783 pnode = ldns_rbtree_previous(denial->node);
784 if (!pnode || pnode == LDNS_RBTREE_NULL) {
785 pnode = ldns_rbtree_last(db->denials);
786 }
787 ods_log_assert(pnode);
788 pdenial = (denial_type*) pnode->data;
789 ods_log_assert(pdenial);
790 node = ldns_rbtree_delete(db->denials, (const void*)denial->dname);
791 if (!node) {
792 ods_log_error("[%s] unable to delete denial: not found", db_str);
793 log_dname(denial->dname, "ERR -DENIAL", LOG_ERR);
794 return NULL;
795 }
796 ods_log_assert(denial->node == node);
797 pdenial->nxt_changed = 1;
798 free((void*)node);
799 denial->domain = NULL;
800 denial->node = NULL;
801 log_dname(denial->dname, "-DENIAL", LOG_DEEEBUG);
802 return denial;
803 }
804
805
806 /**
807 * Apply differences in db.
808 *
809 */
810 void
namedb_diff(namedb_type * db,unsigned is_ixfr,unsigned more_coming)811 namedb_diff(namedb_type* db, unsigned is_ixfr, unsigned more_coming)
812 {
813 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
814 domain_type* domain = NULL;
815 if (!db || !db->domains) {
816 return;
817 }
818 node = ldns_rbtree_first(db->domains);
819 if (!node || node == LDNS_RBTREE_NULL) {
820 return;
821 }
822 while (node && node != LDNS_RBTREE_NULL) {
823 domain = (domain_type*) node->data;
824 node = ldns_rbtree_next(node);
825 domain_diff(domain, is_ixfr, more_coming);
826 }
827 node = ldns_rbtree_first(db->domains);
828 if (!node || node == LDNS_RBTREE_NULL) {
829 return;
830 }
831 while (node && node != LDNS_RBTREE_NULL) {
832 domain = (domain_type*) node->data;
833 node = ldns_rbtree_next(node);
834 if (!namedb_del_denial_trigger(db, domain, 0)) {
835 /* del_denial did not delete domain */
836 namedb_add_denial_trigger(db, domain);
837 }
838 }
839 }
840
841
842 /**
843 * Rollback differences in db.
844 *
845 */
846 void
namedb_rollback(namedb_type * db,unsigned keepsc)847 namedb_rollback(namedb_type* db, unsigned keepsc)
848 {
849 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
850 domain_type* domain = NULL;
851 if (!db || !db->domains) {
852 return;
853 }
854 node = ldns_rbtree_first(db->domains);
855 if (!node || node == LDNS_RBTREE_NULL) {
856 return;
857 }
858 while (node && node != LDNS_RBTREE_NULL) {
859 domain = (domain_type*) node->data;
860 node = ldns_rbtree_next(node);
861 domain_rollback(domain, keepsc);
862 (void) namedb_del_denial_trigger(db, domain, 1);
863 }
864 }
865
866
867 /**
868 * Nsecify db.
869 *
870 */
871 void
namedb_nsecify(namedb_type * db,uint32_t * num_added)872 namedb_nsecify(namedb_type* db, uint32_t* num_added)
873 {
874 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
875 ldns_rbnode_t* nxt_node = LDNS_RBTREE_NULL;
876 denial_type* denial = NULL;
877 denial_type* nxt = NULL;
878 uint32_t nsec_added = 0;
879 ods_log_assert(db);
880 node = ldns_rbtree_first(db->denials);
881 while (node && node != LDNS_RBTREE_NULL) {
882 denial = (denial_type*) node->data;
883 nxt_node = ldns_rbtree_next(node);
884 if (!nxt_node || nxt_node == LDNS_RBTREE_NULL) {
885 nxt_node = ldns_rbtree_first(db->denials);
886 }
887 nxt = (denial_type*) nxt_node->data;
888 denial_nsecify(denial, nxt, &nsec_added);
889 node = ldns_rbtree_next(node);
890 }
891 if (num_added) {
892 *num_added = nsec_added;
893 }
894 }
895
896
897 /**
898 * Examine updates to db.
899 *
900 */
901 ods_status
namedb_examine(namedb_type * db)902 namedb_examine(namedb_type* db)
903 {
904 ods_status status = ODS_STATUS_OK;
905 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
906 domain_type* domain = NULL;
907 rrset_type* rrset = NULL;
908 int soa_seen = 0;
909 /*
910 ldns_rr_type dstatus = LDNS_RR_TYPE_FIRST;
911 ldns_rr_type delegpt = LDNS_RR_TYPE_FIRST;
912 */
913
914 if (!db || !db->domains) {
915 /* no db, no error */
916 return ODS_STATUS_OK;
917 }
918 if (db->domains->root != LDNS_RBTREE_NULL) {
919 node = ldns_rbtree_first(db->domains);
920 }
921 while (node && node != LDNS_RBTREE_NULL) {
922 domain = (domain_type*) node->data;
923 rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_CNAME);
924 if (rrset) {
925 /* Thou shall not have other data next to CNAME */
926 if (domain_count_rrset_is_added(domain) > 1 &&
927 rrset_count_rr_is_added(rrset) > 0) {
928 log_rrset(domain->dname, rrset->rrtype,
929 "CNAME and other data at the same name", LOG_ERR);
930 return ODS_STATUS_CONFLICT_ERR;
931 }
932 /* Thou shall have at most one CNAME per name */
933 if (rrset_count_rr_is_added(rrset) > 1) {
934 log_rrset(domain->dname, rrset->rrtype,
935 "multiple CNAMEs at the same name", LOG_ERR);
936 return ODS_STATUS_CONFLICT_ERR;
937 }
938 }
939 rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_DNAME);
940 if (rrset) {
941 /* Thou shall have at most one DNAME per name */
942 if (rrset_count_rr_is_added(rrset) > 1) {
943 log_rrset(domain->dname, rrset->rrtype,
944 "multiple DNAMEs at the same name", LOG_ERR);
945 return ODS_STATUS_CONFLICT_ERR;
946 }
947 }
948 if (!soa_seen && domain->is_apex) {
949 rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_SOA);
950 if (rrset) {
951 /* Thou shall have one and only one SOA */
952 if (rrset_count_rr_is_added(rrset) != 1) {
953 log_rrset(domain->dname, rrset->rrtype,
954 "Wrong number of SOA records, should be 1", LOG_ERR);
955 return ODS_STATUS_CONFLICT_ERR;
956 }
957 } else {
958 log_rrset(domain->dname, LDNS_RR_TYPE_SOA, "missing SOA RRset",
959 LOG_ERR);
960 return ODS_STATUS_CONFLICT_ERR;
961 }
962 }
963 /*
964 dstatus = domain_is_occluded(domain);
965 delegpt = domain_is_delegpt(domain);
966 */
967 /* Thou shall not have occluded data in your zone file */
968 node = ldns_rbtree_next(node);
969 }
970 return status;
971 }
972
973
974 /**
975 * Wipe out all NSEC RRsets.
976 *
977 */
978 void
namedb_wipe_denial(namedb_type * db)979 namedb_wipe_denial(namedb_type* db)
980 {
981 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
982 denial_type* denial = NULL;
983 zone_type* zone = NULL;
984 size_t i = 0;
985
986 if (db && db->denials) {
987 zone = (zone_type*) db->zone;
988 ods_log_assert(zone);
989 ods_log_assert(zone->name);
990 ods_log_debug("[%s] wipe denial of existence space zone %s", db_str,
991 zone->name);
992 node = ldns_rbtree_first(db->denials);
993 while (node && node != LDNS_RBTREE_NULL) {
994 denial = (denial_type*) node->data;
995 if (!denial->rrset) {
996 node = ldns_rbtree_next(node);
997 continue;
998 }
999 for (i=0; i < denial->rrset->rr_count; i++) {
1000 if (denial->rrset->rrs[i].exists) {
1001 /* ixfr -RR */
1002 pthread_mutex_lock(&zone->ixfr->ixfr_lock);
1003 if (zone->db->is_initialized) {
1004 ixfr_del_rr(zone->ixfr, denial->rrset->rrs[i].rr);
1005 }
1006 pthread_mutex_unlock(&zone->ixfr->ixfr_lock);
1007 }
1008 denial->rrset->rrs[i].exists = 0;
1009 rrset_del_rr(denial->rrset, i);
1010 i--;
1011 }
1012 rrset_drop_rrsigs(zone, denial->rrset);
1013 rrset_cleanup(denial->rrset);
1014 denial->rrset = NULL;
1015 node = ldns_rbtree_next(node);
1016 }
1017 }
1018 }
1019
1020 /**
1021 * Export db to file.
1022 *
1023 */
1024 void
namedb_export(FILE * fd,namedb_type * db,ods_status * status)1025 namedb_export(FILE* fd, namedb_type* db, ods_status* status)
1026 {
1027 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
1028 domain_type* domain = NULL;
1029 if (!fd || !db || !db->domains) {
1030 if (status) {
1031 ods_log_error("[%s] unable to export namedb: file descriptor "
1032 "or name database missing", db_str);
1033 *status = ODS_STATUS_ASSERT_ERR;
1034 }
1035 return;
1036 }
1037 node = ldns_rbtree_first(db->domains);
1038 if (!node || node == LDNS_RBTREE_NULL) {
1039 fprintf(fd, "; empty zone\n");
1040 if (status) {
1041 *status = ODS_STATUS_OK;
1042 }
1043 return;
1044 }
1045 while (node && node != LDNS_RBTREE_NULL) {
1046 domain = (domain_type*) node->data;
1047 if (domain) {
1048 domain_print(fd, domain, status);
1049 }
1050 node = ldns_rbtree_next(node);
1051 }
1052 }
1053
1054
1055 /**
1056 * Clean up domains in namedb.
1057 *
1058 */
1059 static void
domain_delfunc(ldns_rbnode_t * elem)1060 domain_delfunc(ldns_rbnode_t* elem)
1061 {
1062 domain_type* domain = NULL;
1063 if (elem && elem != LDNS_RBTREE_NULL) {
1064 domain = (domain_type*) elem->data;
1065 domain_delfunc(elem->left);
1066 domain_delfunc(elem->right);
1067 domain_cleanup(domain);
1068 free((void*)elem);
1069 }
1070 }
1071
1072
1073 /**
1074 * Clean up denials.
1075 *
1076 */
1077 static void
denial_delfunc(ldns_rbnode_t * elem)1078 denial_delfunc(ldns_rbnode_t* elem)
1079 {
1080 denial_type* denial = NULL;
1081 domain_type* domain = NULL;
1082 if (elem && elem != LDNS_RBTREE_NULL) {
1083 denial = (denial_type*) elem->data;
1084 denial_delfunc(elem->left);
1085 denial_delfunc(elem->right);
1086 domain = (domain_type*) denial->domain;
1087 if (domain) {
1088 domain->denial = NULL;
1089 }
1090 denial_cleanup(denial);
1091 free((void*)elem);
1092 }
1093 }
1094
1095
1096 /**
1097 * Clean up domains.
1098 *
1099 */
1100 static void
namedb_cleanup_domains(namedb_type * db)1101 namedb_cleanup_domains(namedb_type* db)
1102 {
1103 if (db && db->domains) {
1104 domain_delfunc(db->domains->root);
1105 ldns_rbtree_free(db->domains);
1106 db->domains = NULL;
1107 }
1108 }
1109
1110
1111 /**
1112 * Clean up denials.
1113 *
1114 */
1115 void
namedb_cleanup_denials(namedb_type * db)1116 namedb_cleanup_denials(namedb_type* db)
1117 {
1118 if (db && db->denials) {
1119 denial_delfunc(db->denials->root);
1120 ldns_rbtree_free(db->denials);
1121 db->denials = NULL;
1122 }
1123 }
1124
1125
1126 /**
1127 * Clean up namedb.
1128 *
1129 */
1130 void
namedb_cleanup(namedb_type * db)1131 namedb_cleanup(namedb_type* db)
1132 {
1133 zone_type* z = NULL;
1134 if (!db) {
1135 return;
1136 }
1137 z = (zone_type*) db->zone;
1138 if (!z) {
1139 return;
1140 }
1141 namedb_cleanup_denials(db);
1142 namedb_cleanup_domains(db);
1143 free(db);
1144 }
1145
1146
1147 /**
1148 * Backup namedb.
1149 *
1150 */
1151 void
namedb_backup2(FILE * fd,namedb_type * db)1152 namedb_backup2(FILE* fd, namedb_type* db)
1153 {
1154 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
1155 domain_type* domain = NULL;
1156 denial_type* denial = NULL;
1157 if (!fd || !db) {
1158 return;
1159 }
1160 node = ldns_rbtree_first(db->domains);
1161 while (node && node != LDNS_RBTREE_NULL) {
1162 domain = (domain_type*) node->data;
1163 domain_backup2(fd, domain, 0);
1164 node = ldns_rbtree_next(node);
1165 }
1166 fprintf(fd, ";\n");
1167 node = ldns_rbtree_first(db->denials);
1168 while (node && node != LDNS_RBTREE_NULL) {
1169 denial = (denial_type*) node->data;
1170 if (denial->rrset) {
1171 rrset_print(fd, denial->rrset, 1, NULL);
1172 }
1173 node = ldns_rbtree_next(node);
1174 }
1175 fprintf(fd, ";\n");
1176 /* signatures */
1177 node = ldns_rbtree_first(db->domains);
1178 while (node && node != LDNS_RBTREE_NULL) {
1179 domain = (domain_type*) node->data;
1180 domain_backup2(fd, domain, 1);
1181 node = ldns_rbtree_next(node);
1182 }
1183 node = ldns_rbtree_first(db->denials);
1184 while (node && node != LDNS_RBTREE_NULL) {
1185 denial = (denial_type*) node->data;
1186 if (denial->rrset) {
1187 rrset_backup2(fd, denial->rrset);
1188 }
1189 node = ldns_rbtree_next(node);
1190 }
1191 fprintf(fd, ";\n");
1192 }
1193