OpenDNSSEC-signer  1.4.3
adapi.c
Go to the documentation of this file.
1 /*
2  * $Id$
3  *
4  * Copyright (c) 2009-2011 NLNet Labs. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
34 #include "config.h"
35 #include "adapter/adapi.h"
36 #include "shared/duration.h"
37 #include "shared/log.h"
38 #include "shared/status.h"
39 #include "shared/util.h"
40 #include "signer/zone.h"
41 
42 #include <ldns/ldns.h>
43 
44 static const char* adapi_str = "adapter";
45 
46 
51 uint32_t
53 {
54  if (!zone || !zone->db) {
55  return 0;
56  }
57  return zone->db->inbserial;
58 }
59 
60 
65 void
66 adapi_set_serial(zone_type* zone, uint32_t serial)
67 {
68  if (!zone || !zone->db) {
69  return;
70  }
71  zone->db->inbserial = serial;
72  return;
73 }
74 
75 
80 ldns_rdf*
82 {
83  if (!zone) {
84  return NULL;
85  }
86  return zone->apex;
87 }
88 
89 
94 ldns_rr_class
96 {
97  if (!zone) {
98  return LDNS_RR_CLASS_IN;
99  }
100  return zone->klass;
101 }
102 
103 
108 uint32_t
110 {
111  if (!zone) {
112  return 0;
113  }
114  return zone->default_ttl;
115 }
116 
117 
118 /*
119  * Do full zone transaction.
120  *
121  */
122 void
123 adapi_trans_full(zone_type* zone, unsigned more_coming)
124 {
125  time_t start = 0;
126  time_t end = 0;
127  uint32_t num_added = 0;
128  if (!zone || !zone->db) {
129  return;
130  }
131  namedb_diff(zone->db, 0, more_coming);
132 
133  if (zone->stats) {
135  zone->stats->nsec_time = 0;
136  zone->stats->nsec_count = 0;
138  }
139  start = time(NULL);
140  /* nsecify(3) */
141  namedb_nsecify(zone->db, &num_added);
142  end = time(NULL);
143  if (zone->stats) {
145  if (!zone->stats->start_time) {
146  zone->stats->start_time = start;
147  }
148  zone->stats->nsec_time = (end-start);
149  zone->stats->nsec_count = num_added;
151  }
152  return;
153 }
154 
155 
156 /*
157  * Do incremental zone transaction.
158  *
159  */
160 void
161 adapi_trans_diff(zone_type* zone, unsigned more_coming)
162 {
163  time_t start = 0;
164  time_t end = 0;
165  uint32_t num_added = 0;
166  if (!zone || !zone->db) {
167  return;
168  }
169  namedb_diff(zone->db, 1, more_coming);
170 
171  if (zone->stats) {
173  zone->stats->nsec_time = 0;
174  zone->stats->nsec_count = 0;
176  }
177  start = time(NULL);
178  /* nsecify(3) */
179  namedb_nsecify(zone->db, &num_added);
180  end = time(NULL);
181  if (zone->stats) {
183  if (!zone->stats->start_time) {
184  zone->stats->start_time = start;
185  }
186  zone->stats->nsec_time = (end-start);
187  zone->stats->nsec_count = num_added;
189  }
190  return;
191 }
192 
193 
198 static ods_status
199 adapi_process_soa(zone_type* zone, ldns_rr* rr, int add, int backup)
200 {
201  uint32_t tmp = 0;
202  ldns_rdf* soa_rdata = NULL;
203  ods_status status = ODS_STATUS_OK;
204 
205  ods_log_assert(rr);
206  ods_log_assert(zone);
207  ods_log_assert(zone->name);
208  ods_log_assert(zone->signconf);
209 
210  if (backup) {
211  /* no need to do processing */
212  return ODS_STATUS_OK;
213  }
214  if (zone->signconf->soa_ttl) {
215  tmp = (uint32_t) duration2time(zone->signconf->soa_ttl);
216  ods_log_verbose("[%s] zone %s set soa ttl to %u",
217  adapi_str, zone->name, tmp);
218  ldns_rr_set_ttl(rr, tmp);
219  }
220  if (zone->signconf->soa_min) {
221  tmp = (uint32_t) duration2time(zone->signconf->soa_min);
222  ods_log_verbose("[%s] zone %s set soa minimum to %u",
223  adapi_str, zone->name, tmp);
224  soa_rdata = ldns_rr_set_rdf(rr,
225  ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, tmp),
227  if (soa_rdata) {
228  ldns_rdf_deep_free(soa_rdata);
229  soa_rdata = NULL;
230  } else {
231  ods_log_error("[%s] unable to %s soa to zone %s: failed to replace "
232  "soa minimum rdata", adapi_str, add?"add":"delete",
233  zone->name);
234  return ODS_STATUS_ASSERT_ERR;
235  }
236  }
237  if (!add) {
238  /* we are done */
239  return ODS_STATUS_OK;
240  }
241  tmp = ldns_rdf2native_int32(ldns_rr_rdf(rr, SE_SOA_RDATA_SERIAL));
242  status = namedb_update_serial(zone->db, zone->name,
243  zone->signconf->soa_serial, tmp);
244  if (status != ODS_STATUS_OK) {
245  ods_log_error("[%s] unable to add soa to zone %s: failed to replace "
246  "soa serial rdata (%s)", adapi_str, zone->name,
247  ods_status2str(status));
248  if (status == ODS_STATUS_CONFLICT_ERR) {
249  ods_log_error("[%s] If this is the result of a key rollover, "
250  "please increment the serial in the unsigned zone %s",
251  adapi_str, zone->name);
252  }
253  return status;
254  }
255  ods_log_verbose("[%s] zone %s set soa serial to %u", adapi_str,
256  zone->name, zone->db->intserial);
257  soa_rdata = ldns_rr_set_rdf(rr, ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
258  zone->db->intserial), SE_SOA_RDATA_SERIAL);
259  if (soa_rdata) {
260  ldns_rdf_deep_free(soa_rdata);
261  soa_rdata = NULL;
262  } else {
263  ods_log_error("[%s] unable to add soa to zone %s: failed to replace "
264  "soa serial rdata", adapi_str, zone->name);
265  return ODS_STATUS_ERR;
266  }
267  zone->db->serial_updated = 1;
268  return ODS_STATUS_OK;
269 }
270 
271 
276 static void
277 adapi_process_dnskey(zone_type* zone, ldns_rr* rr)
278 {
279  uint32_t tmp = 0;
280  ods_log_assert(rr);
281  ods_log_assert(zone);
282  ods_log_assert(zone->name);
283  ods_log_assert(zone->signconf);
284  tmp = (uint32_t) duration2time(zone->signconf->dnskey_ttl);
285  ods_log_verbose("[%s] zone %s set dnskey ttl to %u",
286  adapi_str, zone->name, tmp);
287  ldns_rr_set_ttl(rr, tmp);
288  return;
289 }
290 
291 
296 static ods_status
297 adapi_process_rr(zone_type* zone, ldns_rr* rr, int add, int backup)
298 {
299  ods_status status = ODS_STATUS_OK;
300  ods_log_assert(rr);
301  ods_log_assert(zone);
302  ods_log_assert(zone->name);
303  ods_log_assert(zone->db);
304  ods_log_assert(zone->signconf);
305  /* We only support IN class */
306  if (ldns_rr_get_class(rr) != LDNS_RR_CLASS_IN) {
307  ods_log_warning("[%s] only class in is supported, changing class "
308  "to in");
309  ldns_rr_set_class(rr, LDNS_RR_CLASS_IN);
310  }
311  /* RR processing */
312  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
313  if (ldns_dname_compare(ldns_rr_owner(rr), zone->apex)) {
314  ods_log_error("[%s] unable to %s rr to zone: soa record has "
315  "invalid owner name", adapi_str, add?"add":"delete");
316  return ODS_STATUS_ERR;
317  }
318  status = adapi_process_soa(zone, rr, add, backup);
319  if (status != ODS_STATUS_OK) {
320  ods_log_error("[%s] unable to %s rr: failed to process soa "
321  "record", adapi_str, add?"add":"delete");
322  return status;
323  }
324  } else {
325  if (ldns_dname_compare(ldns_rr_owner(rr), zone->apex) &&
326  !ldns_dname_is_subdomain(ldns_rr_owner(rr), zone->apex)) {
327  ods_log_warning("[%s] zone %s contains out-of-zone data, "
328  "skipping", adapi_str, zone->name);
329  return ODS_STATUS_UNCHANGED;
330  } else if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY) {
331  adapi_process_dnskey(zone, rr);
332  } else if (util_is_dnssec_rr(rr) && !backup) {
333  ods_log_warning("[%s] zone %s contains dnssec data (type=%u), "
334  "skipping", adapi_str, zone->name,
335  (unsigned) ldns_rr_get_type(rr));
336  return ODS_STATUS_UNCHANGED;
337  }
338  }
339 
340  /* TODO: DNAME and CNAME checks */
341  /* TODO: NS and DS checks */
342 
343  if (add) {
344  return zone_add_rr(zone, rr, 1);
345  } else {
346  return zone_del_rr(zone, rr, 1);
347  }
348  /* not reached */
349  return ODS_STATUS_ERR;
350 }
351 
352 
358 adapi_add_rr(zone_type* zone, ldns_rr* rr, int backup)
359 {
360  return adapi_process_rr(zone, rr, 1, backup);
361 }
362 
363 
369 adapi_del_rr(zone_type* zone, ldns_rr* rr, int backup)
370 {
371  return adapi_process_rr(zone, rr, 0, backup);
372 }
373 
374 
380 adapi_printzone(FILE* fd, zone_type* zone)
381 {
382  ods_status status = ODS_STATUS_OK;
383  if (!fd || !zone || !zone->db) {
384  ods_log_error("[%s] unable to print zone: file descriptor, zone or "
385  "name database missing", adapi_str);
386  return ODS_STATUS_ASSERT_ERR;
387  }
388  namedb_export(fd, zone->db, &status);
389  return status;
390 }
391 
392 
398 adapi_printaxfr(FILE* fd, zone_type* zone)
399 {
400  rrset_type* rrset = NULL;
401  ods_status status = ODS_STATUS_OK;
402  if (!fd || !zone || !zone->db) {
403  ods_log_error("[%s] unable to print axfr: file descriptor, zone or "
404  "name database missing", adapi_str);
405  return ODS_STATUS_ASSERT_ERR;
406  }
407  namedb_export(fd, zone->db, &status);
408  if (status == ODS_STATUS_OK) {
409  rrset = zone_lookup_rrset(zone, zone->apex, LDNS_RR_TYPE_SOA);
410  ods_log_assert(rrset);
411  rrset_print(fd, rrset, 1, &status);
412  }
413  return status;
414 }
415 
416 
422 adapi_printixfr(FILE* fd, zone_type* zone)
423 {
424  rrset_type* rrset = NULL;
425  ods_status status = ODS_STATUS_OK;
426  if (!fd || !zone || !zone->db || !zone->ixfr) {
427  ods_log_error("[%s] unable to print ixfr: file descriptor, zone or "
428  "name database missing", adapi_str);
429  return ODS_STATUS_ASSERT_ERR;
430  }
431  if (!zone->db->is_initialized) {
432  /* no ixfr yet */
433  return ODS_STATUS_OK;
434  }
435  rrset = zone_lookup_rrset(zone, zone->apex, LDNS_RR_TYPE_SOA);
436  ods_log_assert(rrset);
437  rrset_print(fd, rrset, 1, &status);
438  if (status != ODS_STATUS_OK) {
439  return status;
440  }
441  lock_basic_lock(&zone->ixfr->ixfr_lock);
442  ixfr_print(fd, zone->ixfr);
444  rrset_print(fd, rrset, 1, &status);
445  return status;
446 }
void ixfr_print(FILE *fd, ixfr_type *ixfr)
Definition: ixfr.c:257
uint32_t default_ttl
Definition: zone.h:72
uint32_t intserial
Definition: namedb.h:54
void namedb_export(FILE *fd, namedb_type *db, ods_status *status)
Definition: namedb.c:1029
uint32_t adapi_get_serial(zone_type *zone)
Definition: adapi.c:52
duration_type * soa_min
Definition: signconf.h:76
const char * soa_serial
Definition: signconf.h:77
duration_type * soa_ttl
Definition: signconf.h:75
enum ods_enum_status ods_status
Definition: status.h:91
void ods_log_error(const char *format,...)
Definition: log.c:336
lock_basic_type stats_lock
Definition: stats.h:69
const char * ods_status2str(ods_status status)
Definition: status.c:112
#define SE_SOA_RDATA_SERIAL
Definition: util.h:49
ods_status namedb_update_serial(namedb_type *db, const char *zone_name, const char *format, uint32_t inbound_serial)
Definition: namedb.c:200
void namedb_diff(namedb_type *db, unsigned is_ixfr, unsigned more_coming)
Definition: namedb.c:821
time_t nsec_time
Definition: stats.h:61
uint32_t nsec_count
Definition: stats.h:60
void namedb_nsecify(namedb_type *db, uint32_t *num_added)
Definition: namedb.c:884
#define lock_basic_lock(lock)
Definition: locks.h:93
void adapi_set_serial(zone_type *zone, uint32_t serial)
Definition: adapi.c:66
namedb_type * db
Definition: zone.h:88
ldns_rr_class adapi_get_class(zone_type *zone)
Definition: adapi.c:95
ixfr_type * ixfr
Definition: zone.h:89
uint32_t inbserial
Definition: namedb.h:53
unsigned serial_updated
Definition: namedb.h:59
unsigned is_initialized
Definition: namedb.h:57
#define SE_SOA_RDATA_MINIMUM
Definition: util.h:51
signconf_type * signconf
Definition: zone.h:86
time_t start_time
Definition: stats.h:67
ldns_rdf * adapi_get_origin(zone_type *zone)
Definition: adapi.c:81
ods_status zone_add_rr(zone_type *zone, ldns_rr *rr, int do_stats)
Definition: zone.c:561
ods_status adapi_printzone(FILE *fd, zone_type *zone)
Definition: adapi.c:380
ods_status adapi_del_rr(zone_type *zone, ldns_rr *rr, int backup)
Definition: adapi.c:369
time_t duration2time(duration_type *duration)
Definition: duration.c:373
ods_status zone_del_rr(zone_type *zone, ldns_rr *rr, int do_stats)
Definition: zone.c:631
void ods_log_verbose(const char *format,...)
Definition: log.c:288
lock_basic_type ixfr_lock
Definition: ixfr.h:64
ldns_rr_class klass
Definition: zone.h:71
rrset_type * zone_lookup_rrset(zone_type *zone, ldns_rdf *owner, ldns_rr_type type)
Definition: zone.c:542
void adapi_trans_full(zone_type *zone, unsigned more_coming)
Definition: adapi.c:123
ods_status adapi_printixfr(FILE *fd, zone_type *zone)
Definition: adapi.c:422
duration_type * dnskey_ttl
Definition: signconf.h:72
ods_status adapi_add_rr(zone_type *zone, ldns_rr *rr, int backup)
Definition: adapi.c:358
const char * name
Definition: zone.h:78
uint32_t adapi_get_ttl(zone_type *zone)
Definition: adapi.c:109
#define ods_log_assert(x)
Definition: log.h:156
ods_status adapi_printaxfr(FILE *fd, zone_type *zone)
Definition: adapi.c:398
int util_is_dnssec_rr(ldns_rr *rr)
Definition: util.c:55
#define lock_basic_unlock(lock)
Definition: locks.h:94
void ods_log_warning(const char *format,...)
Definition: log.c:320
ldns_rdf * apex
Definition: zone.h:70
void rrset_print(FILE *fd, rrset_type *rrset, int skip_rrsigs, ods_status *status)
Definition: rrset.c:799
stats_type * stats
Definition: zone.h:96
void adapi_trans_diff(zone_type *zone, unsigned more_coming)
Definition: adapi.c:161