OpenDNSSEC-signer  1.4.7
addns.c
Go to the documentation of this file.
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 
32 #include "config.h"
33 #include "adapter/adapi.h"
34 #include "adapter/adapter.h"
35 #include "adapter/addns.h"
36 #include "adapter/adutil.h"
37 #include "parser/addnsparser.h"
38 #include "parser/confparser.h"
39 #include "shared/duration.h"
40 #include "shared/file.h"
41 #include "shared/log.h"
42 #include "shared/status.h"
43 #include "shared/util.h"
44 #include "signer/zone.h"
45 #include "wire/notify.h"
46 #include "wire/xfrd.h"
47 
48 #include <ldns/ldns.h>
49 #include <stdio.h>
50 #include <stdlib.h>
51 
52 static const char* adapter_str = "adapter";
53 static ods_status addns_read_pkt(FILE* fd, zone_type* zone);
54 static ods_status addns_read_file(FILE* fd, zone_type* zone);
55 
56 
61 ldns_rr*
62 addns_read_rr(FILE* fd, char* line, ldns_rdf** orig, ldns_rdf** prev,
63  uint32_t* ttl, ldns_status* status, unsigned int* l)
64 {
65  ldns_rr* rr = NULL;
66  int len = 0;
67  uint32_t new_ttl = 0;
68 
69 addns_read_line:
70  if (ttl) {
71  new_ttl = *ttl;
72  }
73  len = adutil_readline_frm_file(fd, line, l, 1);
74  adutil_rtrim_line(line, &len);
75  if (len >= 0) {
76  switch (line[0]) {
77  /* no directives */
78 
79  /* comments, empty lines */
80  case ';':
81  case '\n':
82  if (ods_strcmp(";;ENDPACKET", line) == 0) {
83  /* end of pkt */
84  *status = LDNS_STATUS_OK;
85  return NULL;
86  }
87  if (ods_strcmp(";;BEGINPACKET", line) == 0) {
88  /* begin packet but previous not ended, rollback */
89  *status = LDNS_STATUS_OK;
90  return NULL;
91  }
92  goto addns_read_line; /* perhaps next line is rr */
93  break;
94  /* let's hope its a RR */
95  default:
96  if (adutil_whitespace_line(line, len)) {
97  goto addns_read_line; /* perhaps next line is rr */
98  break;
99  }
100  *status = ldns_rr_new_frm_str(&rr, line, new_ttl, *orig, prev);
101  if (*status == LDNS_STATUS_OK) {
102  return rr;
103  } else if (*status == LDNS_STATUS_SYNTAX_EMPTY) {
104  if (rr) {
105  ldns_rr_free(rr);
106  rr = NULL;
107  }
108  *status = LDNS_STATUS_OK;
109  goto addns_read_line; /* perhaps next line is rr */
110  break;
111  } else {
112  ods_log_error("[%s] error parsing RR at line %i (%s): %s",
113  adapter_str, l&&*l?*l:0,
114  ldns_get_errorstr_by_id(*status), line);
115  while (len >= 0) {
116  len = adutil_readline_frm_file(fd, line, l, 0);
117  }
118  if (rr) {
119  ldns_rr_free(rr);
120  rr = NULL;
121  }
122  return NULL;
123  }
124  break;
125  }
126  }
127  /* -1, EOF */
128  *status = LDNS_STATUS_OK;
129  return NULL;
130 }
131 
132 
137 static ods_status
138 addns_read_pkt(FILE* fd, zone_type* zone)
139 {
140  ldns_rr* rr = NULL;
141  long startpos = 0;
142  long fpos = 0;
143  int len = 0;
144  uint32_t new_serial = 0;
145  uint32_t old_serial = 0;
146  uint32_t tmp_serial = 0;
147  ldns_rdf* prev = NULL;
148  ldns_rdf* orig = NULL;
149  ldns_rdf* dname = NULL;
150  uint32_t ttl = 0;
151  size_t rr_count = 0;
152  ods_status result = ODS_STATUS_OK;
153  ldns_status status = LDNS_STATUS_OK;
154  char line[SE_ADFILE_MAXLINE];
155  unsigned is_axfr = 0;
156  unsigned del_mode = 0;
157  unsigned soa_seen = 0;
158  unsigned line_update_interval = 100000;
159  unsigned line_update = line_update_interval;
160  unsigned l = 0;
161  char* xfrd;
162  char* fin;
163  char* fout;
164 
165  ods_log_assert(fd);
166  ods_log_assert(zone);
167  ods_log_assert(zone->name);
168 
169 
170  fpos = ftell(fd);
171  len = adutil_readline_frm_file(fd, line, &l, 1);
172  if (len < 0) {
173  /* -1 EOF */
174  return ODS_STATUS_EOF;
175  }
176  adutil_rtrim_line(line, &len);
177  if (ods_strcmp(";;BEGINPACKET", line) != 0) {
178  ods_log_error("[%s] bogus xfrd file zone %s, missing ;;BEGINPACKET (was %s)",
179  adapter_str, zone->name, line);
180  return ODS_STATUS_ERR;
181  }
182  startpos = fpos;
183  fpos = ftell(fd);
184 
185 begin_pkt:
186  rr_count = 0;
187  is_axfr = 0;
188  del_mode = 0;
189  soa_seen = 0;
190  /* $ORIGIN <zone name> */
191  dname = adapi_get_origin(zone);
192  if (!dname) {
193  ods_log_error("[%s] error getting default value for $ORIGIN",
194  adapter_str);
195  return ODS_STATUS_ERR;
196  }
197  orig = ldns_rdf_clone(dname);
198  if (!orig) {
199  ods_log_error("[%s] error setting default value for $ORIGIN",
200  adapter_str);
201  return ODS_STATUS_ERR;
202  }
203  /* $TTL <default ttl> */
204  ttl = adapi_get_ttl(zone);
205 
206  /* read RRs */
207  while ((rr = addns_read_rr(fd, line, &orig, &prev, &ttl, &status, &l))
208  != NULL) {
209  /* update file position */
210  fpos = ftell(fd);
211  /* check status */
212  if (status != LDNS_STATUS_OK) {
213  ods_log_error("[%s] error reading RR at line %i (%s): %s",
214  adapter_str, l, ldns_get_errorstr_by_id(status), line);
215  result = ODS_STATUS_ERR;
216  break;
217  }
218  /* debug update */
219  if (l > line_update) {
220  ods_log_debug("[%s] ...at line %i: %s", adapter_str, l, line);
221  line_update += line_update_interval;
222  }
223  /* first RR: check if SOA and correct zone & serialno */
224  if (rr_count == 0) {
225  rr_count++;
226  if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_SOA) {
227  ods_log_error("[%s] bad xfr, first rr is not soa",
228  adapter_str);
229  ldns_rr_free(rr);
230  rr = NULL;
231  result = ODS_STATUS_ERR;
232  break;
233  }
234  soa_seen++;
235  if (ldns_dname_compare(ldns_rr_owner(rr), zone->apex)) {
236  ods_log_error("[%s] bad xfr, soa dname not equal to zone "
237  "dname %s", adapter_str, zone->name);
238  ldns_rr_free(rr);
239  rr = NULL;
240  result = ODS_STATUS_ERR;
241  break;
242  }
243 
244  tmp_serial =
245  ldns_rdf2native_int32(ldns_rr_rdf(rr, SE_SOA_RDATA_SERIAL));
246  old_serial = adapi_get_serial(zone);
247 
275  ldns_rr_free(rr);
276  rr = NULL;
277  result = ODS_STATUS_OK;
278  continue;
279  }
280  /* second RR: if not soa, this is an AXFR */
281  if (rr_count == 1) {
282  if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_SOA) {
283  ods_log_verbose("[%s] detected axfr serial=%u for zone %s",
284  adapter_str, tmp_serial, zone->name);
285  new_serial = tmp_serial;
286  is_axfr = 1;
287  del_mode = 0;
288  } else {
289  ods_log_verbose("[%s] detected ixfr serial=%u for zone %s",
290  adapter_str, tmp_serial, zone->name);
291 
292  if (!util_serial_gt(tmp_serial, old_serial) &&
293  zone->db->is_initialized) {
294  ods_log_error("[%s] bad ixfr for zone %s, bad start serial %u",
295  adapter_str, zone->name, tmp_serial);
296  result = ODS_STATUS_ERR;
297  }
298 
299  new_serial = tmp_serial;
300  tmp_serial =
301  ldns_rdf2native_int32(ldns_rr_rdf(rr, SE_SOA_RDATA_SERIAL));
302  ldns_rr_free(rr);
303  rr = NULL;
304  rr_count++;
305  if (tmp_serial < new_serial) {
306  del_mode = 1;
307  result = ODS_STATUS_OK;
308  continue;
309  } else {
310  ods_log_error("[%s] bad ixfr for zone %s, bad soa serial %u",
311  adapter_str, zone->name, tmp_serial);
312  result = ODS_STATUS_ERR;
313  break;
314  }
315  }
316  }
317  /* soa means swap */
318  rr_count++;
319  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
320  if (!is_axfr) {
321  tmp_serial =
322  ldns_rdf2native_int32(ldns_rr_rdf(rr, SE_SOA_RDATA_SERIAL));
323  if (tmp_serial <= new_serial) {
324  if (tmp_serial == new_serial) {
325  soa_seen++;
326  }
327  del_mode = !del_mode;
328  ldns_rr_free(rr);
329  rr = NULL;
330  result = ODS_STATUS_OK;
331  continue;
332  } else {
333  ods_log_assert(tmp_serial > new_serial);
334  ods_log_error("[%s] bad xfr for zone %s, bad soa serial",
335  adapter_str, zone->name);
336  ldns_rr_free(rr);
337  rr = NULL;
338  result = ODS_STATUS_ERR;
339  break;
340  }
341  } else {
342  /* for axfr */
343  soa_seen++;
344  }
345  }
346  /* [add to/remove from] the zone */
347  if (!is_axfr && del_mode) {
348  ods_log_deeebug("[%s] delete RR #%i at line %i: %s",
349  adapter_str, rr_count, l, line);
350  result = adapi_del_rr(zone, rr, 0);
351  ldns_rr_free(rr);
352  rr = NULL;
353  } else {
354  ods_log_deeebug("[%s] add RR #%i at line %i: %s",
355  adapter_str, rr_count, l, line);
356  result = adapi_add_rr(zone, rr, 0);
357  }
358  if (result == ODS_STATUS_UNCHANGED) {
359  ods_log_deeebug("[%s] skipping RR at line %i (%s): %s",
360  adapter_str, l, del_mode?"not found":"duplicate", line);
361  ldns_rr_free(rr);
362  rr = NULL;
363  result = ODS_STATUS_OK;
364  continue;
365  } else if (result != ODS_STATUS_OK) {
366  ods_log_error("[%s] error %s RR at line %i: %s",
367  adapter_str, del_mode?"deleting":"adding", l, line);
368  ldns_rr_free(rr);
369  rr = NULL;
370  break;
371  }
372  }
373  /* and done */
374  if (orig) {
375  ldns_rdf_deep_free(orig);
376  orig = NULL;
377  }
378  if (prev) {
379  ldns_rdf_deep_free(prev);
380  prev = NULL;
381  }
382  /* check again */
383  if (ods_strcmp(";;ENDPACKET", line) == 0) {
384  ods_log_verbose("[%s] xfr zone %s on disk complete, commit to db",
385  adapter_str, zone->name);
386  startpos = 0;
387  } else {
388  ods_log_warning("[%s] xfr zone %s on disk incomplete, rollback",
389  adapter_str, zone->name);
390  namedb_rollback(zone->db, 1);
391  if (ods_strcmp(";;BEGINPACKET", line) == 0) {
392  result = ODS_STATUS_OK;
393  startpos = fpos;
394  goto begin_pkt;
395  } else {
396  result = ODS_STATUS_XFRINCOMPLETE;
397  }
398  }
399  /* otherwise EOF */
400  if (result == ODS_STATUS_OK && status != LDNS_STATUS_OK) {
401  ods_log_error("[%s] error reading RR at line %i (%s): %s",
402  adapter_str, l, ldns_get_errorstr_by_id(status), line);
403  result = ODS_STATUS_ERR;
404  }
405  /* check the number of SOAs seen */
406  if (result == ODS_STATUS_OK) {
407  if ((is_axfr && soa_seen != 2) || (!is_axfr && soa_seen != 3)) {
408  ods_log_error("[%s] bad %s, wrong number of SOAs (%u)",
409  adapter_str, is_axfr?"axfr":"ixfr", soa_seen);
410  result = ODS_STATUS_ERR;
411  }
412  }
413  /* input zone ok, set inbound serial and apply differences */
414  if (result == ODS_STATUS_OK) {
415  adapi_set_serial(zone, new_serial);
416  if (is_axfr) {
417  adapi_trans_full(zone, 1);
418  } else {
419  adapi_trans_diff(zone, 1);
420  }
421  }
422  if (result == ODS_STATUS_UPTODATE) {
423  /* do a transaction for DNSKEY and NSEC3PARAM */
424  adapi_trans_diff(zone, 1);
425  result = ODS_STATUS_OK;
426  }
427  if (result == ODS_STATUS_XFRINCOMPLETE) {
431  xfrd = ods_build_path(zone->name, ".xfrd", 0, 1);
432  fin = ods_build_path(zone->name, ".xfrd.tmp", 0, 1);
433  fout = ods_build_path(zone->name, ".xfrd.bak", 0, 1);
434  if (!xfrd || !fin || !fout) {
435  return ODS_STATUS_MALLOC_ERR;
436  }
437  ods_log_debug("[%s] restore xfrd zone %s xfrd %s fin %s fout %s",
438  adapter_str, zone->name, xfrd, fin, fout);
439  result = ods_file_copy(fin, fout, startpos, 0);
440  if (result != ODS_STATUS_OK) {
441  ods_log_crit("[%s] unable to restore incomple xfr zone %s: %s",
442  adapter_str, zone->name, ods_status2str(result));
443  } else {
444  lock_basic_lock(&zone->xfrd->rw_lock);
445  if (ods_file_lastmodified(xfrd)) {
446  result = ods_file_copy(xfrd, fout, 0, 1);
447  if (result != ODS_STATUS_OK) {
448  ods_log_crit("[%s] unable to restore xfrd zone %s: %s",
449  adapter_str, zone->name, ods_status2str(result));
450  } else if (rename(fout, xfrd) != 0) {
451  result = ODS_STATUS_RENAME_ERR;
452  ods_log_crit("[%s] unable to restore xfrd zone %s: %s",
453  adapter_str, zone->name, ods_status2str(result));
454  }
455  } else if (rename(fout, xfrd) != 0) {
456  result = ODS_STATUS_RENAME_ERR;
457  ods_log_crit("[%s] unable to restore xfrd zone %s: %s",
458  adapter_str, zone->name, ods_status2str(result));
459 
460  }
461  lock_basic_unlock(&zone->xfrd->rw_lock);
462  }
463  free((void*) xfrd);
464  free((void*) fin);
465  free((void*) fout);
466  result = ODS_STATUS_XFRINCOMPLETE;
467  }
468  return result;
469 }
470 
471 
476 static ods_status
477 addns_read_file(FILE* fd, zone_type* zone)
478 {
479  ods_status status = ODS_STATUS_OK;
480 
481  while (status == ODS_STATUS_OK) {
482  status = addns_read_pkt(fd, zone);
483  if (status == ODS_STATUS_OK) {
485  zone->xfrd->serial_xfr = adapi_get_serial(zone);
488  }
489  }
490  if (status == ODS_STATUS_EOF) {
491  status = ODS_STATUS_OK;
492  }
493  return status;
494 }
495 
496 
501 dnsin_type*
503 {
504  dnsin_type* addns = NULL;
505  allocator_type* allocator = allocator_create(malloc, free);
506  if (!allocator) {
507  ods_log_error("[%s] unable to create dnsin: allocator_create() "
508  " failed", adapter_str);
509  return NULL;
510  }
511  addns = (dnsin_type*) allocator_alloc(allocator, sizeof(dnsin_type));
512  if (!addns) {
513  ods_log_error("[%s] unable to create dnsin: allocator_alloc() "
514  " failed", adapter_str);
515  allocator_cleanup(allocator);
516  return NULL;
517  }
518  addns->allocator = allocator;
519  addns->request_xfr = NULL;
520  addns->allow_notify = NULL;
521  addns->tsig = NULL;
522  return addns;
523 }
524 
525 
532 {
533  dnsout_type* addns = NULL;
534  allocator_type* allocator = allocator_create(malloc, free);
535  if (!allocator) {
536  ods_log_error("[%s] unable to create dnsout: allocator_create() "
537  " failed", adapter_str);
538  return NULL;
539  }
540  addns = (dnsout_type*) allocator_alloc(allocator, sizeof(dnsout_type));
541  if (!addns) {
542  ods_log_error("[%s] unable to create dnsout: allocator_alloc() "
543  " failed", adapter_str);
544  allocator_cleanup(allocator);
545  return NULL;
546  }
547  addns->allocator = allocator;
548  addns->provide_xfr = NULL;
549  addns->do_notify = NULL;
550  addns->tsig = NULL;
551  return addns;
552 }
553 
554 
559 static ods_status
560 dnsin_read(dnsin_type* addns, const char* filename)
561 {
562  const char* rngfile = ODS_SE_RNGDIR "/addns.rng";
563  ods_status status = ODS_STATUS_OK;
564  FILE* fd = NULL;
565  if (!filename || !addns) {
566  return ODS_STATUS_ASSERT_ERR;
567  }
568  ods_log_debug("[%s] read dnsin file %s", adapter_str, filename);
569  status = parse_file_check(filename, rngfile);
570  if (status != ODS_STATUS_OK) {
571  ods_log_error("[%s] unable to read dnsin: parse error in "
572  "file %s (%s)", adapter_str, filename, ods_status2str(status));
573  return status;
574  }
575  fd = ods_fopen(filename, NULL, "r");
576  if (fd) {
577  addns->tsig = parse_addns_tsig(addns->allocator, filename);
579  filename, addns->tsig);
581  filename, addns->tsig);
582  ods_fclose(fd);
583  return ODS_STATUS_OK;
584  }
585  ods_log_error("[%s] unable to read dnsout: failed to open file %s",
586  adapter_str, filename);
587  return ODS_STATUS_ERR;
588 }
589 
590 
596 dnsin_update(dnsin_type** addns, const char* filename, time_t* last_mod)
597 {
598  dnsin_type* new_addns = NULL;
599  time_t st_mtime = 0;
600  ods_status status = ODS_STATUS_OK;
601 
602  if (!filename || !addns || !last_mod) {
603  return ODS_STATUS_UNCHANGED;
604  }
605  /* read the new signer configuration */
606  new_addns = dnsin_create();
607  if (!new_addns) {
608  ods_log_error("[%s] unable to update dnsin: dnsin_create() "
609  "failed", adapter_str);
610  return ODS_STATUS_ERR;
611  }
612  status = dnsin_read(new_addns, filename);
613  if (status == ODS_STATUS_OK) {
614  *addns = new_addns;
615  *last_mod = st_mtime;
616  } else {
617  ods_log_error("[%s] unable to update dnsin: dnsin_read(%s) "
618  "failed (%s)", adapter_str, filename, ods_status2str(status));
619  dnsin_cleanup(new_addns);
620  }
621  return status;
622 }
623 
628 static ods_status
629 dnsout_read(dnsout_type* addns, const char* filename)
630 {
631  const char* rngfile = ODS_SE_RNGDIR "/addns.rng";
632  ods_status status = ODS_STATUS_OK;
633  FILE* fd = NULL;
634  if (!filename || !addns) {
635  return ODS_STATUS_ASSERT_ERR;
636  }
637  ods_log_debug("[%s] read dnsout file %s", adapter_str, filename);
638  status = parse_file_check(filename, rngfile);
639  if (status != ODS_STATUS_OK) {
640  ods_log_error("[%s] unable to read dnsout: parse error in "
641  "file %s (%s)", adapter_str, filename, ods_status2str(status));
642  return status;
643  }
644  fd = ods_fopen(filename, NULL, "r");
645  if (fd) {
646  addns->tsig = parse_addns_tsig(addns->allocator, filename);
648  filename, addns->tsig);
649  addns->do_notify = parse_addns_do_notify(addns->allocator, filename,
650  addns->tsig);
651  ods_fclose(fd);
652  return ODS_STATUS_OK;
653  }
654  ods_log_error("[%s] unable to read dnsout: failed to open file %s",
655  adapter_str, filename);
656  return ODS_STATUS_ERR;
657 }
658 
659 
665 dnsout_update(dnsout_type** addns, const char* filename, time_t* last_mod)
666 {
667  dnsout_type* new_addns = NULL;
668  time_t st_mtime = 0;
669  ods_status status = ODS_STATUS_OK;
670 
671  if (!filename || !addns || !last_mod) {
672  return ODS_STATUS_UNCHANGED;
673  }
674  /* read the new signer configuration */
675  new_addns = dnsout_create();
676  if (!new_addns) {
677  ods_log_error("[%s] unable to update dnsout: dnsout_create() "
678  "failed", adapter_str);
679  return ODS_STATUS_ERR;
680  }
681  status = dnsout_read(new_addns, filename);
682  if (status == ODS_STATUS_OK) {
683  *addns = new_addns;
684  *last_mod = st_mtime;
685  } else {
686  ods_log_error("[%s] unable to update dnsout: dnsout_read(%s) "
687  "failed (%s)", adapter_str, filename, ods_status2str(status));
688  dnsout_cleanup(new_addns);
689  }
690  return status;
691 }
692 
693 
698 static void
699 dnsout_send_notify(void* zone)
700 {
701  zone_type* z = (zone_type*) zone;
702  rrset_type* rrset = NULL;
703  ldns_rr* soa = NULL;
704  if (!z->notify) {
705  ods_log_error("[%s] unable to send notify for zone %s: no notify "
706  "handler", adapter_str, z->name);
707  return;
708  }
712  ods_log_assert(z->db);
713  ods_log_assert(z->name);
714  ods_log_debug("[%s] enable notify for zone %s serial %u", adapter_str,
715  z->name, z->db->intserial);
716  rrset = zone_lookup_rrset(z, z->apex, LDNS_RR_TYPE_SOA);
717  ods_log_assert(rrset);
718  soa = ldns_rr_clone(rrset->rrs[0].rr);
719  notify_enable(z->notify, soa);
720  return;
721 }
722 
723 
729 addns_read(void* zone)
730 {
731  zone_type* z = (zone_type*) zone;
732  ods_status status = ODS_STATUS_OK;
733  char* xfrfile = NULL;
734  char* file = NULL;
735  FILE* fd = NULL;
736  ods_log_assert(z);
737  ods_log_assert(z->name);
738  ods_log_assert(z->xfrd);
739  ods_log_assert(z->db);
742 
745  /* did we already store a new zone transfer on disk? */
746  if (!z->xfrd->serial_disk_acquired ||
750  if (!z->xfrd->serial_disk_acquired) {
752  }
753  /* do a transaction for DNSKEY and NSEC3PARAM */
754  adapi_trans_diff(z, 0);
755  ods_log_verbose("[%s] no new xfr ready for zone %s", adapter_str,
756  z->name);
757  return ODS_STATUS_UNCHANGED;
758  }
759  /* copy zone transfers */
760  xfrfile = ods_build_path(z->name, ".xfrd", 0, 1);
761  file = ods_build_path(z->name, ".xfrd.tmp", 0, 1);
762  if (!xfrfile || !file) {
763  ods_log_error("[%s] unable to build paths to xfrd files", adapter_str);
764  return ODS_STATUS_MALLOC_ERR;
765  }
766  if (rename(xfrfile, file) != 0) {
769  ods_log_error("[%s] unable to rename file %s to %s: %s", adapter_str,
770  xfrfile, file, strerror(errno));
771  free((void*) xfrfile);
772  free((void*) file);
773  return ODS_STATUS_RENAME_ERR;
774  }
776  /* open copy of zone transfers to read */
777  fd = ods_fopen(file, NULL, "r");
778  free((void*) xfrfile);
779  if (!fd) {
781  free((void*) file);
782  return ODS_STATUS_FOPEN_ERR;
783  }
785 
786  status = addns_read_file(fd, z);
787  if (status == ODS_STATUS_OK) {
788  /* clean up copy of zone transfer */
789  if (unlink((const char*) file) != 0) {
790  ods_log_error("[%s] unable to unlink zone transfer copy file %s: "
791  " %s", adapter_str, strerror(errno));
792  /* should be no issue */
793  }
794  }
795  free((void*) file);
796  ods_fclose(fd);
797  return status;
798 }
799 
800 
806 addns_write(void* zone)
807 {
808  FILE* fd = NULL;
809  char* atmpfile = NULL;
810  char* axfrfile = NULL;
811  char* itmpfile = NULL;
812  char* ixfrfile = NULL;
813  zone_type* z = (zone_type*) zone;
814  int ret = 0;
815  ods_status status = ODS_STATUS_OK;
816  ods_log_assert(z);
817  ods_log_assert(z->name);
820 
821  atmpfile = ods_build_path(z->name, ".axfr.tmp", 0, 1);
822  if (!atmpfile) {
823  return ODS_STATUS_MALLOC_ERR;
824  }
825  fd = ods_fopen(atmpfile, NULL, "w");
826  if (!fd) {
827  free((void*) atmpfile);
828  return ODS_STATUS_FOPEN_ERR;
829  }
830  status = adapi_printaxfr(fd, z);
831  ods_fclose(fd);
832  if (status != ODS_STATUS_OK) {
833  free((void*) atmpfile);
834  return status;
835  }
836 
837  if (z->db->is_initialized) {
838  itmpfile = ods_build_path(z->name, ".ixfr.tmp", 0, 1);
839  if (!itmpfile) {
840  free((void*) atmpfile);
841  return ODS_STATUS_MALLOC_ERR;
842  }
843  fd = ods_fopen(itmpfile, NULL, "w");
844  if (!fd) {
845  free((void*) atmpfile);
846  free((void*) itmpfile);
847  return ODS_STATUS_FOPEN_ERR;
848  }
849  status = adapi_printixfr(fd, z);
850  ods_fclose(fd);
851  if (status != ODS_STATUS_OK) {
852  free((void*) atmpfile);
853  free((void*) itmpfile);
854  return status;
855  }
856  }
857 
858  if (status == ODS_STATUS_OK) {
859  if (z->adoutbound->error) {
860  ods_log_error("[%s] unable to write zone %s axfr: one or "
861  "more RR print failed", adapter_str, z->name);
862  /* clear error */
863  z->adoutbound->error = 0;
864  free((void*) atmpfile);
865  free((void*) itmpfile);
866  return ODS_STATUS_FWRITE_ERR;
867  }
868  }
869 
870  /* lock and move */
871  axfrfile = ods_build_path(z->name, ".axfr", 0, 1);
872  if (!axfrfile) {
873  free((void*) atmpfile);
874  free((void*) itmpfile);
875  return ODS_STATUS_MALLOC_ERR;
876  }
877 
879  ret = rename(atmpfile, axfrfile);
880  if (ret != 0) {
881  ods_log_error("[%s] unable to rename file %s to %s: %s", adapter_str,
882  atmpfile, axfrfile, strerror(errno));
884  free((void*) atmpfile);
885  free((void*) axfrfile);
886  free((void*) itmpfile);
887  return ODS_STATUS_RENAME_ERR;
888  }
889  free((void*) axfrfile);
890  free((void*) atmpfile);
891 
892  if (z->db->is_initialized) {
893  ixfrfile = ods_build_path(z->name, ".ixfr", 0, 1);
894  if (!ixfrfile) {
895  free((void*) axfrfile);
896  free((void*) atmpfile);
897  free((void*) itmpfile);
898  return ODS_STATUS_MALLOC_ERR;
899  }
900  ret = rename(itmpfile, ixfrfile);
901  if (ret != 0) {
902  ods_log_error("[%s] unable to rename file %s to %s: %s",
903  adapter_str, itmpfile, ixfrfile, strerror(errno));
905  free((void*) itmpfile);
906  free((void*) ixfrfile);
907  return ODS_STATUS_RENAME_ERR;
908  }
909  free((void*) ixfrfile);
910  }
911  free((void*) itmpfile);
913 
914  dnsout_send_notify(zone);
915  return ODS_STATUS_OK;
916 }
917 
918 
923 void
925 {
926  allocator_type* allocator = NULL;
927  if (!addns) {
928  return;
929  }
930  allocator = addns->allocator;
931  acl_cleanup(addns->request_xfr, allocator);
932  acl_cleanup(addns->allow_notify, allocator);
933  tsig_cleanup(addns->tsig, allocator);
934  allocator_deallocate(allocator, (void*) addns);
935  allocator_cleanup(allocator);
936  return;
937 }
938 
939 
944 void
946 {
947  allocator_type* allocator = NULL;
948  if (!addns) {
949  return;
950  }
951  allocator = addns->allocator;
952  acl_cleanup(addns->provide_xfr, allocator);
953  acl_cleanup(addns->do_notify, allocator);
954  tsig_cleanup(addns->tsig, allocator);
955  allocator_deallocate(allocator, (void*) addns);
956  allocator_cleanup(allocator);
957  return;
958 }
void acl_cleanup(acl_type *acl, allocator_type *allocator)
Definition: acl.c:464
uint32_t intserial
Definition: namedb.h:52
allocator_type * allocator
Definition: addns.h:64
uint32_t adapi_get_serial(zone_type *zone)
Definition: adapi.c:50
void notify_enable(notify_type *notify, ldns_rr *soa)
Definition: notify.c:532
tsig_type * parse_addns_tsig(allocator_type *allocator, const char *filename)
Definition: addnsparser.c:383
acl_type * parse_addns_provide_xfr(allocator_type *allocator, const char *filename, tsig_type *tsig)
Definition: addnsparser.c:355
void dnsout_cleanup(dnsout_type *addns)
Definition: addns.c:945
void * config
Definition: adapter.h:61
void ods_log_debug(const char *format,...)
Definition: log.c:270
void * allocator_alloc(allocator_type *allocator, size_t size)
Definition: allocator.c:66
time_t serial_xfr_acquired
Definition: xfrd.h:110
acl_type * parse_addns_request_xfr(allocator_type *allocator, const char *filename, tsig_type *tsig)
Definition: addnsparser.c:327
unsigned error
Definition: adapter.h:63
enum ods_enum_status ods_status
Definition: status.h:90
ods_status parse_file_check(const char *cfgfile, const char *rngfile)
Definition: confparser.c:53
time_t ods_file_lastmodified(const char *file)
Definition: file.c:293
void ods_log_error(const char *format,...)
Definition: log.c:334
const char * ods_status2str(ods_status status)
Definition: status.c:111
adapter_mode type
Definition: adapter.h:58
#define SE_SOA_RDATA_SERIAL
Definition: util.h:47
int ods_strcmp(const char *s1, const char *s2)
Definition: file.c:320
lock_basic_type serial_lock
Definition: xfrd.h:96
adapter_type * adoutbound
Definition: zone.h:82
FILE * ods_fopen(const char *file, const char *dir, const char *mode)
Definition: file.c:190
ldns_rr * addns_read_rr(FILE *fd, char *line, ldns_rdf **orig, ldns_rdf **prev, uint32_t *ttl, ldns_status *status, unsigned int *l)
Definition: addns.c:62
int util_serial_gt(uint32_t serial_new, uint32_t serial_old)
Definition: util.c:72
allocator_type * allocator
Definition: addns.h:51
void ods_log_crit(const char *format,...)
Definition: log.c:350
void tsig_cleanup(tsig_type *tsig, allocator_type *allocator)
Definition: tsig.c:901
#define lock_basic_lock(lock)
Definition: locks.h:91
void adapi_set_serial(zone_type *zone, uint32_t serial)
Definition: adapi.c:64
namedb_type * db
Definition: zone.h:86
void dnsin_cleanup(dnsin_type *addns)
Definition: addns.c:924
allocator_type * allocator_create(void *(*allocator)(size_t size), void(*deallocator)(void *))
Definition: allocator.c:47
acl_type * provide_xfr
Definition: addns.h:65
unsigned is_initialized
Definition: namedb.h:55
tsig_type * tsig
Definition: addns.h:67
ldns_rdf * adapi_get_origin(zone_type *zone)
Definition: adapi.c:79
int adutil_whitespace_line(char *line, int line_len)
Definition: adutil.c:219
adapter_type * adinbound
Definition: zone.h:81
void namedb_rollback(namedb_type *db, unsigned keepsc)
Definition: namedb.c:856
acl_type * allow_notify
Definition: addns.h:53
acl_type * parse_addns_allow_notify(allocator_type *allocator, const char *filename, tsig_type *tsig)
Definition: addnsparser.c:341
void adutil_rtrim_line(char *line, int *line_len)
Definition: adutil.c:189
ods_status addns_read(void *zone)
Definition: addns.c:729
tsig_type * tsig
Definition: addns.h:54
acl_type * request_xfr
Definition: addns.h:52
ods_status adapi_del_rr(zone_type *zone, ldns_rr *rr, int backup)
Definition: adapi.c:367
char * ods_build_path(const char *file, const char *suffix, int dir, int no_slash)
Definition: file.c:125
ods_status dnsout_update(dnsout_type **addns, const char *filename, time_t *last_mod)
Definition: addns.c:665
ldns_rr * rr
Definition: rrset.h:60
void ods_log_verbose(const char *format,...)
Definition: log.c:286
acl_type * do_notify
Definition: addns.h:66
rrset_type * zone_lookup_rrset(zone_type *zone, ldns_rdf *owner, ldns_rr_type type)
Definition: zone.c:545
acl_type * parse_addns_do_notify(allocator_type *allocator, const char *filename, tsig_type *tsig)
Definition: addnsparser.c:369
void adapi_trans_full(zone_type *zone, unsigned more_coming)
Definition: adapi.c:121
void ods_fclose(FILE *fd)
Definition: file.c:250
ods_status adapi_printixfr(FILE *fd, zone_type *zone)
Definition: adapi.c:420
void allocator_cleanup(allocator_type *allocator)
Definition: allocator.c:151
ods_status adapi_add_rr(zone_type *zone, ldns_rr *rr, int backup)
Definition: adapi.c:356
const char * name
Definition: zone.h:76
#define SE_ADFILE_MAXLINE
Definition: adutil.h:40
int adutil_readline_frm_file(FILE *fd, char *line, unsigned int *l, int keep_comments)
Definition: adutil.c:82
void ods_log_deeebug(const char *format,...)
Definition: log.c:254
uint32_t serial_xfr
Definition: xfrd.h:107
void allocator_deallocate(allocator_type *allocator, void *data)
Definition: allocator.c:135
uint32_t adapi_get_ttl(zone_type *zone)
Definition: adapi.c:107
lock_basic_type rw_lock
Definition: xfrd.h:97
ods_status addns_write(void *zone)
Definition: addns.c:806
notify_type * notify
Definition: zone.h:90
dnsin_type * dnsin_create(void)
Definition: addns.c:502
ods_status dnsin_update(dnsin_type **addns, const char *filename, time_t *last_mod)
Definition: addns.c:596
#define ods_log_assert(x)
Definition: log.h:154
ods_status adapi_printaxfr(FILE *fd, zone_type *zone)
Definition: adapi.c:396
xfrd_type * xfrd
Definition: zone.h:89
dnsout_type * dnsout_create(void)
Definition: addns.c:531
#define lock_basic_unlock(lock)
Definition: locks.h:92
void ods_log_warning(const char *format,...)
Definition: log.c:318
ldns_rdf * apex
Definition: zone.h:68
time_t serial_disk_acquired
Definition: xfrd.h:112
rr_type * rrs
Definition: rrset.h:77
ods_status ods_file_copy(const char *file1, const char *file2, long startpos, int append)
Definition: file.c:431
lock_basic_type xfr_lock
Definition: zone.h:96
void adapi_trans_diff(zone_type *zone, unsigned more_coming)
Definition: adapi.c:159