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