OpenDNSSEC-signer  1.4.3
addns.c
Go to the documentation of this file.
1 /*
2  * $Id: addns.c 5237 2011-06-20 13:05:39Z matthijs $
3  *
4  * Copyright (c) 2009 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 "adapter/adapter.h"
37 #include "adapter/addns.h"
38 #include "adapter/adutil.h"
39 #include "parser/addnsparser.h"
40 #include "parser/confparser.h"
41 #include "shared/duration.h"
42 #include "shared/file.h"
43 #include "shared/log.h"
44 #include "shared/status.h"
45 #include "shared/util.h"
46 #include "signer/zone.h"
47 #include "wire/notify.h"
48 #include "wire/xfrd.h"
49 
50 #include <ldns/ldns.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 
54 static const char* adapter_str = "adapter";
55 static ods_status addns_read_pkt(FILE* fd, zone_type* zone);
56 static ods_status addns_read_file(FILE* fd, zone_type* zone);
57 
58 
63 ldns_rr*
64 addns_read_rr(FILE* fd, char* line, ldns_rdf** orig, ldns_rdf** prev,
65  uint32_t* ttl, ldns_status* status, unsigned int* l)
66 {
67  ldns_rr* rr = NULL;
68  int len = 0;
69  uint32_t new_ttl = 0;
70 
71 addns_read_line:
72  if (ttl) {
73  new_ttl = *ttl;
74  }
75  len = adutil_readline_frm_file(fd, line, l, 1);
76  adutil_rtrim_line(line, &len);
77  if (len >= 0) {
78  switch (line[0]) {
79  /* no directives */
80 
81  /* comments, empty lines */
82  case ';':
83  case '\n':
84  if (ods_strcmp(";;ENDPACKET", line) == 0) {
85  /* end of pkt */
86  *status = LDNS_STATUS_OK;
87  return NULL;
88  }
89  if (ods_strcmp(";;BEGINPACKET", line) == 0) {
90  /* begin packet but previous not ended, rollback */
91  *status = LDNS_STATUS_OK;
92  return NULL;
93  }
94  goto addns_read_line; /* perhaps next line is rr */
95  break;
96  /* let's hope its a RR */
97  default:
98  if (adutil_whitespace_line(line, len)) {
99  goto addns_read_line; /* perhaps next line is rr */
100  break;
101  }
102  *status = ldns_rr_new_frm_str(&rr, line, new_ttl, *orig, prev);
103  if (*status == LDNS_STATUS_OK) {
104  return rr;
105  } else if (*status == LDNS_STATUS_SYNTAX_EMPTY) {
106  if (rr) {
107  ldns_rr_free(rr);
108  rr = NULL;
109  }
110  *status = LDNS_STATUS_OK;
111  goto addns_read_line; /* perhaps next line is rr */
112  break;
113  } else {
114  ods_log_error("[%s] error parsing RR at line %i (%s): %s",
115  adapter_str, l&&*l?*l:0,
116  ldns_get_errorstr_by_id(*status), line);
117  while (len >= 0) {
118  len = adutil_readline_frm_file(fd, line, l, 0);
119  }
120  if (rr) {
121  ldns_rr_free(rr);
122  rr = NULL;
123  }
124  return NULL;
125  }
126  break;
127  }
128  }
129  /* -1, EOF */
130  *status = LDNS_STATUS_OK;
131  return NULL;
132 }
133 
134 
139 static ods_status
140 addns_read_pkt(FILE* fd, zone_type* zone)
141 {
142  ldns_rr* rr = NULL;
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 
162  ods_log_assert(fd);
163  ods_log_assert(zone);
164  ods_log_assert(zone->name);
165 
166  len = adutil_readline_frm_file(fd, line, &l, 1);
167  if (len < 0) {
168  /* -1 EOF */
169  return ODS_STATUS_EOF;
170  }
171  adutil_rtrim_line(line, &len);
172  if (ods_strcmp(";;BEGINPACKET", line) != 0) {
173  ods_log_error("[%s] bogus xfrd file zone %s, missing ;;BEGINPACKET (was %s)",
174  adapter_str, zone->name, line);
175  return ODS_STATUS_ERR;
176  }
177 
178 begin_pkt:
179  rr_count = 0;
180  is_axfr = 0;
181  del_mode = 0;
182  soa_seen = 0;
183  /* $ORIGIN <zone name> */
184  dname = adapi_get_origin(zone);
185  if (!dname) {
186  ods_log_error("[%s] error getting default value for $ORIGIN",
187  adapter_str);
188  return ODS_STATUS_ERR;
189  }
190  orig = ldns_rdf_clone(dname);
191  if (!orig) {
192  ods_log_error("[%s] error setting default value for $ORIGIN",
193  adapter_str);
194  return ODS_STATUS_ERR;
195  }
196  /* $TTL <default ttl> */
197  ttl = adapi_get_ttl(zone);
198 
199  /* read RRs */
200  while ((rr = addns_read_rr(fd, line, &orig, &prev, &ttl, &status, &l))
201  != NULL) {
202  /* check status */
203  if (status != LDNS_STATUS_OK) {
204  ods_log_error("[%s] error reading RR at line %i (%s): %s",
205  adapter_str, l, ldns_get_errorstr_by_id(status), line);
206  result = ODS_STATUS_ERR;
207  break;
208  }
209  /* debug update */
210  if (l > line_update) {
211  ods_log_debug("[%s] ...at line %i: %s", adapter_str, l, line);
212  line_update += line_update_interval;
213  }
214  /* first RR: check if SOA and correct zone & serialno */
215  if (rr_count == 0) {
216  rr_count++;
217  if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_SOA) {
218  ods_log_error("[%s] bad xfr, first rr is not soa",
219  adapter_str);
220  ldns_rr_free(rr);
221  rr = NULL;
222  result = ODS_STATUS_ERR;
223  break;
224  }
225  soa_seen++;
226  if (ldns_dname_compare(ldns_rr_owner(rr), zone->apex)) {
227  ods_log_error("[%s] bad xfr, soa dname not equal to zone "
228  "dname %s", adapter_str, zone->name);
229  ldns_rr_free(rr);
230  rr = NULL;
231  result = ODS_STATUS_ERR;
232  break;
233  }
234  tmp_serial =
235  ldns_rdf2native_int32(ldns_rr_rdf(rr, SE_SOA_RDATA_SERIAL));
236  old_serial = adapi_get_serial(zone);
237  if (!util_serial_gt(tmp_serial, old_serial)) {
238  ods_log_info("[%s] zone %s is already up to date, have "
239  "serial %u, got serial %u", adapter_str, zone->name,
240  old_serial, tmp_serial);
241  new_serial = tmp_serial;
242  ldns_rr_free(rr);
243  rr = NULL;
244  result = ODS_STATUS_UPTODATE;
245  while (len >= 0) {
246  len = adutil_readline_frm_file(fd, line, &l, 1);
247  if (len && ods_strcmp(";;ENDPACKET", line) == 0) {
248  /* end of pkt */
249  break;
250  }
251  }
252  break;
253  }
254  ldns_rr_free(rr);
255  rr = NULL;
256  result = ODS_STATUS_OK;
257  continue;
258  }
259  /* second RR: if not soa, this is an AXFR */
260  if (rr_count == 1) {
261  if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_SOA) {
262  ods_log_verbose("[%s] detected axfr serial=%u for zone %s",
263  adapter_str, tmp_serial, zone->name);
264  new_serial = tmp_serial;
265  is_axfr = 1;
266  del_mode = 0;
267  } else {
268  ods_log_verbose("[%s] detected ixfr serial=%u for zone %s",
269  adapter_str, tmp_serial, zone->name);
270  new_serial = tmp_serial;
271  tmp_serial =
272  ldns_rdf2native_int32(ldns_rr_rdf(rr, SE_SOA_RDATA_SERIAL));
273  ldns_rr_free(rr);
274  rr = NULL;
275  rr_count++;
276  if (tmp_serial < new_serial) {
277  del_mode = 1;
278  result = ODS_STATUS_OK;
279  continue;
280  } else {
281  ods_log_error("[%s] bad xfr for zone %s, bad soa serial",
282  adapter_str, zone->name);
283  result = ODS_STATUS_ERR;
284  break;
285  }
286  }
287  }
288  /* soa means swap */
289  rr_count++;
290  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
291  if (!is_axfr) {
292  tmp_serial =
293  ldns_rdf2native_int32(ldns_rr_rdf(rr, SE_SOA_RDATA_SERIAL));
294  if (tmp_serial <= new_serial) {
295  if (tmp_serial == new_serial) {
296  soa_seen++;
297  }
298  del_mode = !del_mode;
299  ldns_rr_free(rr);
300  rr = NULL;
301  result = ODS_STATUS_OK;
302  continue;
303  } else {
304  ods_log_assert(tmp_serial > new_serial);
305  ods_log_error("[%s] bad xfr for zone %s, bad soa serial",
306  adapter_str, zone->name);
307  ldns_rr_free(rr);
308  rr = NULL;
309  result = ODS_STATUS_ERR;
310  break;
311  }
312  } else {
313  /* for axfr */
314  soa_seen++;
315  }
316  }
317  /* [add to/remove from] the zone */
318  if (!is_axfr && del_mode) {
319  ods_log_deeebug("[%s] delete RR #%i at line %i: %s",
320  adapter_str, rr_count, l, line);
321  result = adapi_del_rr(zone, rr, 0);
322  ldns_rr_free(rr);
323  rr = NULL;
324  } else {
325  ods_log_deeebug("[%s] add RR #%i at line %i: %s",
326  adapter_str, rr_count, l, line);
327  result = adapi_add_rr(zone, rr, 0);
328  }
329  if (result == ODS_STATUS_UNCHANGED) {
330  ods_log_debug("[%s] skipping RR at line %i (%s): %s",
331  adapter_str, l, del_mode?"not found":"duplicate", line);
332  ldns_rr_free(rr);
333  rr = NULL;
334  result = ODS_STATUS_OK;
335  continue;
336  } else if (result != ODS_STATUS_OK) {
337  ods_log_error("[%s] error %s RR at line %i: %s",
338  adapter_str, del_mode?"deleting":"adding", l, line);
339  ldns_rr_free(rr);
340  rr = NULL;
341  break;
342  }
343  }
344  /* and done */
345  if (orig) {
346  ldns_rdf_deep_free(orig);
347  orig = NULL;
348  }
349  if (prev) {
350  ldns_rdf_deep_free(prev);
351  prev = NULL;
352  }
353  /* check again */
354  if (ods_strcmp(";;ENDPACKET", line) == 0) {
355  ods_log_verbose("[%s] xfr zone %s on disk complete, commit to db",
356  adapter_str, zone->name);
357  } else {
358  ods_log_warning("[%s] xfr zone %s on disk incomplete, rollback",
359  adapter_str, zone->name);
360  namedb_rollback(zone->db, 1);
361  if (ods_strcmp(";;BEGINPACKET", line) == 0) {
362  result = ODS_STATUS_OK;
363  goto begin_pkt;
364  } else {
365  result = ODS_STATUS_XFRINCOMPLETE;
366  }
367  }
368  /* otherwise EOF */
369  if (result == ODS_STATUS_OK && status != LDNS_STATUS_OK) {
370  ods_log_error("[%s] error reading RR at line %i (%s): %s",
371  adapter_str, l, ldns_get_errorstr_by_id(status), line);
372  result = ODS_STATUS_ERR;
373  }
374  /* check the number of SOAs seen */
375  if (result == ODS_STATUS_OK) {
376  if ((is_axfr && soa_seen != 2) || (!is_axfr && soa_seen != 3)) {
377  ods_log_error("[%s] bad %s, wrong number of SOAs (%u)",
378  adapter_str, is_axfr?"axfr":"ixfr", soa_seen);
379  result = ODS_STATUS_ERR;
380  }
381  }
382  /* input zone ok, set inbound serial and apply differences */
383  if (result == ODS_STATUS_OK) {
384  adapi_set_serial(zone, new_serial);
385  if (is_axfr) {
386  adapi_trans_full(zone, 1);
387  } else {
388  adapi_trans_diff(zone, 1);
389  }
390  }
391  if (result == ODS_STATUS_UPTODATE) {
392  /* do a transaction for DNSKEY and NSEC3PARAM */
393  adapi_trans_diff(zone, 1);
394  result = ODS_STATUS_OK;
395  }
396  return result;
397 }
398 
399 
404 static ods_status
405 addns_read_file(FILE* fd, zone_type* zone)
406 {
407  ods_status status = ODS_STATUS_OK;
408 
409  while (status == ODS_STATUS_OK) {
410  status = addns_read_pkt(fd, zone);
411  }
412  if (status == ODS_STATUS_EOF) {
413  status = ODS_STATUS_OK;
414  }
415  return status;
416 }
417 
418 
423 dnsin_type*
425 {
426  dnsin_type* addns = NULL;
427  allocator_type* allocator = allocator_create(malloc, free);
428  if (!allocator) {
429  ods_log_error("[%s] unable to create dnsin: allocator_create() "
430  " failed", adapter_str);
431  return NULL;
432  }
433  addns = (dnsin_type*) allocator_alloc(allocator, sizeof(dnsin_type));
434  if (!addns) {
435  ods_log_error("[%s] unable to create dnsin: allocator_alloc() "
436  " failed", adapter_str);
437  allocator_cleanup(allocator);
438  return NULL;
439  }
440  addns->allocator = allocator;
441  addns->request_xfr = NULL;
442  addns->allow_notify = NULL;
443  addns->tsig = NULL;
444  return addns;
445 }
446 
447 
454 {
455  dnsout_type* addns = NULL;
456  allocator_type* allocator = allocator_create(malloc, free);
457  if (!allocator) {
458  ods_log_error("[%s] unable to create dnsout: allocator_create() "
459  " failed", adapter_str);
460  return NULL;
461  }
462  addns = (dnsout_type*) allocator_alloc(allocator, sizeof(dnsout_type));
463  if (!addns) {
464  ods_log_error("[%s] unable to create dnsout: allocator_alloc() "
465  " failed", adapter_str);
466  allocator_cleanup(allocator);
467  return NULL;
468  }
469  addns->allocator = allocator;
470  addns->provide_xfr = NULL;
471  addns->do_notify = NULL;
472  addns->tsig = NULL;
473  return addns;
474 }
475 
476 
481 static ods_status
482 dnsin_read(dnsin_type* addns, const char* filename)
483 {
484  const char* rngfile = ODS_SE_RNGDIR "/addns.rng";
485  ods_status status = ODS_STATUS_OK;
486  FILE* fd = NULL;
487  if (!filename || !addns) {
488  return ODS_STATUS_ASSERT_ERR;
489  }
490  ods_log_debug("[%s] read dnsin file %s", adapter_str, filename);
491  status = parse_file_check(filename, rngfile);
492  if (status != ODS_STATUS_OK) {
493  ods_log_error("[%s] unable to read dnsin: parse error in "
494  "file %s (%s)", adapter_str, filename, ods_status2str(status));
495  return status;
496  }
497  fd = ods_fopen(filename, NULL, "r");
498  if (fd) {
499  addns->tsig = parse_addns_tsig(addns->allocator, filename);
501  filename, addns->tsig);
503  filename, addns->tsig);
504  ods_fclose(fd);
505  return ODS_STATUS_OK;
506  }
507  ods_log_error("[%s] unable to read dnsout: failed to open file %s",
508  adapter_str, filename);
509  return ODS_STATUS_ERR;
510 }
511 
512 
518 dnsin_update(dnsin_type** addns, const char* filename, time_t* last_mod)
519 {
520  dnsin_type* new_addns = NULL;
521  time_t st_mtime = 0;
522  ods_status status = ODS_STATUS_OK;
523 
524  if (!filename || !addns || !last_mod) {
525  return ODS_STATUS_UNCHANGED;
526  }
527  /* read the new signer configuration */
528  new_addns = dnsin_create();
529  if (!new_addns) {
530  ods_log_error("[%s] unable to update dnsin: dnsin_create() "
531  "failed", adapter_str);
532  return ODS_STATUS_ERR;
533  }
534  status = dnsin_read(new_addns, filename);
535  if (status == ODS_STATUS_OK) {
536  *addns = new_addns;
537  *last_mod = st_mtime;
538  } else {
539  ods_log_error("[%s] unable to update dnsin: dnsin_read(%s) "
540  "failed (%s)", adapter_str, filename, ods_status2str(status));
541  dnsin_cleanup(new_addns);
542  }
543  return status;
544 }
545 
550 static ods_status
551 dnsout_read(dnsout_type* addns, const char* filename)
552 {
553  const char* rngfile = ODS_SE_RNGDIR "/addns.rng";
554  ods_status status = ODS_STATUS_OK;
555  FILE* fd = NULL;
556  if (!filename || !addns) {
557  return ODS_STATUS_ASSERT_ERR;
558  }
559  ods_log_debug("[%s] read dnsout file %s", adapter_str, filename);
560  status = parse_file_check(filename, rngfile);
561  if (status != ODS_STATUS_OK) {
562  ods_log_error("[%s] unable to read dnsout: parse error in "
563  "file %s (%s)", adapter_str, filename, ods_status2str(status));
564  return status;
565  }
566  fd = ods_fopen(filename, NULL, "r");
567  if (fd) {
568  addns->tsig = parse_addns_tsig(addns->allocator, filename);
570  filename, addns->tsig);
571  addns->do_notify = parse_addns_do_notify(addns->allocator, filename,
572  addns->tsig);
573  ods_fclose(fd);
574  return ODS_STATUS_OK;
575  }
576  ods_log_error("[%s] unable to read dnsout: failed to open file %s",
577  adapter_str, filename);
578  return ODS_STATUS_ERR;
579 }
580 
581 
587 dnsout_update(dnsout_type** addns, const char* filename, time_t* last_mod)
588 {
589  dnsout_type* new_addns = NULL;
590  time_t st_mtime = 0;
591  ods_status status = ODS_STATUS_OK;
592 
593  if (!filename || !addns || !last_mod) {
594  return ODS_STATUS_UNCHANGED;
595  }
596  /* read the new signer configuration */
597  new_addns = dnsout_create();
598  if (!new_addns) {
599  ods_log_error("[%s] unable to update dnsout: dnsout_create() "
600  "failed", adapter_str);
601  return ODS_STATUS_ERR;
602  }
603  status = dnsout_read(new_addns, filename);
604  if (status == ODS_STATUS_OK) {
605  *addns = new_addns;
606  *last_mod = st_mtime;
607  } else {
608  ods_log_error("[%s] unable to update dnsout: dnsout_read(%s) "
609  "failed (%s)", adapter_str, filename, ods_status2str(status));
610  dnsout_cleanup(new_addns);
611  }
612  return status;
613 }
614 
615 
620 static void
621 dnsout_send_notify(void* zone)
622 {
623  zone_type* z = (zone_type*) zone;
624  rrset_type* rrset = NULL;
625  ldns_rr* soa = NULL;
626  if (!z->notify) {
627  ods_log_error("[%s] unable to send notify for zone %s: no notify "
628  "handler", adapter_str, z->name);
629  return;
630  }
634  ods_log_assert(z->db);
635  ods_log_assert(z->name);
636  ods_log_debug("[%s] enable notify for zone %s serial %u", adapter_str,
637  z->name, z->db->intserial);
638  rrset = zone_lookup_rrset(z, z->apex, LDNS_RR_TYPE_SOA);
639  ods_log_assert(rrset);
640  soa = ldns_rr_clone(rrset->rrs[0].rr);
641  notify_enable(z->notify, soa);
642  return;
643 }
644 
645 
651 addns_read(void* zone)
652 {
653  zone_type* z = (zone_type*) zone;
654  ods_status status = ODS_STATUS_OK;
655  char* xfrfile = NULL;
656  char* file = NULL;
657  FILE* fd = NULL;
658  ods_log_assert(z);
659  ods_log_assert(z->name);
660  ods_log_assert(z->xfrd);
661  ods_log_assert(z->db);
664 
667  /* did we already store a new zone transfer on disk? */
668  if (!z->xfrd->serial_disk_acquired ||
672  if (!z->xfrd->serial_disk_acquired) {
674  }
675  /* do a transaction for DNSKEY and NSEC3PARAM */
676  adapi_trans_diff(z, 0);
677  return ODS_STATUS_UNCHANGED;
678  }
679  /* copy zone transfers */
680  xfrfile = ods_build_path(z->name, ".xfrd", 0, 1);
681  file = ods_build_path(z->name, ".xfrd.tmp", 0, 1);
682  if (!xfrfile || !file) {
683  ods_log_error("[%s] unable to build paths to xfrd files", adapter_str);
684  return ODS_STATUS_MALLOC_ERR;
685  }
686  if (rename(xfrfile, file) != 0) {
689  ods_log_error("[%s] unable to rename file %s to %s: %s", adapter_str,
690  xfrfile, file, strerror(errno));
691  free((void*) xfrfile);
692  free((void*) file);
693  return ODS_STATUS_RENAME_ERR;
694  }
696  /* open copy of zone transfers to read */
697  fd = ods_fopen(file, NULL, "r");
698  free((void*) xfrfile);
699  if (!fd) {
701  free((void*) file);
702  return ODS_STATUS_FOPEN_ERR;
703  }
704 
705  status = addns_read_file(fd, z);
706  if (status == ODS_STATUS_OK) {
711  /* clean up copy of zone transfer */
712  if (unlink((const char*) file) != 0) {
713  ods_log_error("[%s] unable to unlink zone transfer copy file %s: "
714  " %s", adapter_str, strerror(errno));
715  /* should be no issue */
716  }
717  }
718  free((void*) file);
719  ods_fclose(fd);
721  return status;
722 }
723 
724 
730 addns_write(void* zone)
731 {
732  FILE* fd = NULL;
733  char* atmpfile = NULL;
734  char* axfrfile = NULL;
735  char* itmpfile = NULL;
736  char* ixfrfile = NULL;
737  zone_type* z = (zone_type*) zone;
738  int ret = 0;
739  ods_status status = ODS_STATUS_OK;
740  ods_log_assert(z);
741  ods_log_assert(z->name);
744 
745  atmpfile = ods_build_path(z->name, ".axfr.tmp", 0, 1);
746  if (!atmpfile) {
747  return ODS_STATUS_MALLOC_ERR;
748  }
749  fd = ods_fopen(atmpfile, NULL, "w");
750  if (!fd) {
751  free((void*) atmpfile);
752  return ODS_STATUS_FOPEN_ERR;
753  }
754  status = adapi_printaxfr(fd, z);
755  ods_fclose(fd);
756  if (status != ODS_STATUS_OK) {
757  free((void*) atmpfile);
758  return status;
759  }
760 
761  if (z->db->is_initialized) {
762  itmpfile = ods_build_path(z->name, ".ixfr.tmp", 0, 1);
763  if (!itmpfile) {
764  free((void*) atmpfile);
765  return ODS_STATUS_MALLOC_ERR;
766  }
767  fd = ods_fopen(itmpfile, NULL, "w");
768  if (!fd) {
769  free((void*) atmpfile);
770  free((void*) itmpfile);
771  return ODS_STATUS_FOPEN_ERR;
772  }
773  status = adapi_printixfr(fd, z);
774  ods_fclose(fd);
775  if (status != ODS_STATUS_OK) {
776  free((void*) atmpfile);
777  free((void*) itmpfile);
778  return status;
779  }
780  }
781 
782  if (status == ODS_STATUS_OK) {
783  if (z->adoutbound->error) {
784  ods_log_error("[%s] unable to write zone %s axfr: one or "
785  "more RR print failed", adapter_str, z->name);
786  /* clear error */
787  z->adoutbound->error = 0;
788  free((void*) atmpfile);
789  free((void*) itmpfile);
790  return ODS_STATUS_FWRITE_ERR;
791  }
792  }
793 
794  /* lock and move */
795  axfrfile = ods_build_path(z->name, ".axfr", 0, 1);
796  if (!axfrfile) {
797  free((void*) atmpfile);
798  free((void*) itmpfile);
799  return ODS_STATUS_MALLOC_ERR;
800  }
801 
803  ret = rename(atmpfile, axfrfile);
804  if (ret != 0) {
805  ods_log_error("[%s] unable to rename file %s to %s: %s", adapter_str,
806  atmpfile, axfrfile, strerror(errno));
808  free((void*) atmpfile);
809  free((void*) axfrfile);
810  free((void*) itmpfile);
811  return ODS_STATUS_RENAME_ERR;
812  }
813  free((void*) axfrfile);
814  free((void*) atmpfile);
815 
816  if (z->db->is_initialized) {
817  ixfrfile = ods_build_path(z->name, ".ixfr", 0, 1);
818  if (!ixfrfile) {
819  free((void*) axfrfile);
820  free((void*) atmpfile);
821  free((void*) itmpfile);
822  return ODS_STATUS_MALLOC_ERR;
823  }
824  ret = rename(itmpfile, ixfrfile);
825  if (ret != 0) {
826  ods_log_error("[%s] unable to rename file %s to %s: %s",
827  adapter_str, itmpfile, ixfrfile, strerror(errno));
829  free((void*) itmpfile);
830  free((void*) ixfrfile);
831  return ODS_STATUS_RENAME_ERR;
832  }
833  free((void*) ixfrfile);
834  }
835  free((void*) itmpfile);
837 
838  dnsout_send_notify(zone);
839  return ODS_STATUS_OK;
840 }
841 
842 
847 void
849 {
850  allocator_type* allocator = NULL;
851  if (!addns) {
852  return;
853  }
854  allocator = addns->allocator;
855  acl_cleanup(addns->request_xfr, allocator);
856  acl_cleanup(addns->allow_notify, allocator);
857  tsig_cleanup(addns->tsig, allocator);
858  allocator_deallocate(allocator, (void*) addns);
859  allocator_cleanup(allocator);
860  return;
861 }
862 
863 
868 void
870 {
871  allocator_type* allocator = NULL;
872  if (!addns) {
873  return;
874  }
875  allocator = addns->allocator;
876  acl_cleanup(addns->provide_xfr, allocator);
877  acl_cleanup(addns->do_notify, allocator);
878  tsig_cleanup(addns->tsig, allocator);
879  allocator_deallocate(allocator, (void*) addns);
880  allocator_cleanup(allocator);
881  return;
882 }
void acl_cleanup(acl_type *acl, allocator_type *allocator)
Definition: acl.c:466
uint32_t intserial
Definition: namedb.h:54
allocator_type * allocator
Definition: addns.h:66
uint32_t adapi_get_serial(zone_type *zone)
Definition: adapi.c:52
void notify_enable(notify_type *notify, ldns_rr *soa)
Definition: notify.c:525
tsig_type * parse_addns_tsig(allocator_type *allocator, const char *filename)
Definition: addnsparser.c:385
acl_type * parse_addns_provide_xfr(allocator_type *allocator, const char *filename, tsig_type *tsig)
Definition: addnsparser.c:357
void dnsout_cleanup(dnsout_type *addns)
Definition: addns.c:869
void * config
Definition: adapter.h:63
void ods_log_debug(const char *format,...)
Definition: log.c:272
void * allocator_alloc(allocator_type *allocator, size_t size)
Definition: allocator.c:68
time_t serial_xfr_acquired
Definition: xfrd.h:112
acl_type * parse_addns_request_xfr(allocator_type *allocator, const char *filename, tsig_type *tsig)
Definition: addnsparser.c:329
unsigned error
Definition: adapter.h:65
void ods_log_info(const char *format,...)
Definition: log.c:304
enum ods_enum_status ods_status
Definition: status.h:91
ods_status parse_file_check(const char *cfgfile, const char *rngfile)
Definition: confparser.c:55
void ods_log_error(const char *format,...)
Definition: log.c:336
const char * ods_status2str(ods_status status)
Definition: status.c:112
adapter_mode type
Definition: adapter.h:60
#define SE_SOA_RDATA_SERIAL
Definition: util.h:49
int ods_strcmp(const char *s1, const char *s2)
Definition: file.c:317
lock_basic_type serial_lock
Definition: xfrd.h:98
adapter_type * adoutbound
Definition: zone.h:84
FILE * ods_fopen(const char *file, const char *dir, const char *mode)
Definition: file.c:187
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:64
int util_serial_gt(uint32_t serial_new, uint32_t serial_old)
Definition: util.c:74
allocator_type * allocator
Definition: addns.h:53
void tsig_cleanup(tsig_type *tsig, allocator_type *allocator)
Definition: tsig.c:903
#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
void dnsin_cleanup(dnsin_type *addns)
Definition: addns.c:848
allocator_type * allocator_create(void *(*allocator)(size_t size), void(*deallocator)(void *))
Definition: allocator.c:49
acl_type * provide_xfr
Definition: addns.h:67
unsigned is_initialized
Definition: namedb.h:57
tsig_type * tsig
Definition: addns.h:69
ldns_rdf * adapi_get_origin(zone_type *zone)
Definition: adapi.c:81
int adutil_whitespace_line(char *line, int line_len)
Definition: adutil.c:224
adapter_type * adinbound
Definition: zone.h:83
void namedb_rollback(namedb_type *db, unsigned keepsc)
Definition: namedb.c:858
acl_type * allow_notify
Definition: addns.h:55
acl_type * parse_addns_allow_notify(allocator_type *allocator, const char *filename, tsig_type *tsig)
Definition: addnsparser.c:343
void adutil_rtrim_line(char *line, int *line_len)
Definition: adutil.c:194
ods_status addns_read(void *zone)
Definition: addns.c:651
tsig_type * tsig
Definition: addns.h:56
acl_type * request_xfr
Definition: addns.h:54
ods_status adapi_del_rr(zone_type *zone, ldns_rr *rr, int backup)
Definition: adapi.c:369
char * ods_build_path(const char *file, const char *suffix, int dir, int no_slash)
Definition: file.c:127
ods_status dnsout_update(dnsout_type **addns, const char *filename, time_t *last_mod)
Definition: addns.c:587
ldns_rr * rr
Definition: rrset.h:62
void ods_log_verbose(const char *format,...)
Definition: log.c:288
acl_type * do_notify
Definition: addns.h:68
rrset_type * zone_lookup_rrset(zone_type *zone, ldns_rdf *owner, ldns_rr_type type)
Definition: zone.c:542
acl_type * parse_addns_do_notify(allocator_type *allocator, const char *filename, tsig_type *tsig)
Definition: addnsparser.c:371
void adapi_trans_full(zone_type *zone, unsigned more_coming)
Definition: adapi.c:123
void ods_fclose(FILE *fd)
Definition: file.c:247
ods_status adapi_printixfr(FILE *fd, zone_type *zone)
Definition: adapi.c:422
void allocator_cleanup(allocator_type *allocator)
Definition: allocator.c:153
ods_status adapi_add_rr(zone_type *zone, ldns_rr *rr, int backup)
Definition: adapi.c:358
const char * name
Definition: zone.h:78
#define SE_ADFILE_MAXLINE
Definition: adutil.h:42
int adutil_readline_frm_file(FILE *fd, char *line, unsigned int *l, int keep_comments)
Definition: adutil.c:84
void ods_log_deeebug(const char *format,...)
Definition: log.c:256
uint32_t serial_xfr
Definition: xfrd.h:109
void allocator_deallocate(allocator_type *allocator, void *data)
Definition: allocator.c:137
uint32_t adapi_get_ttl(zone_type *zone)
Definition: adapi.c:109
lock_basic_type rw_lock
Definition: xfrd.h:99
ods_status addns_write(void *zone)
Definition: addns.c:730
notify_type * notify
Definition: zone.h:92
dnsin_type * dnsin_create(void)
Definition: addns.c:424
ods_status dnsin_update(dnsin_type **addns, const char *filename, time_t *last_mod)
Definition: addns.c:518
#define ods_log_assert(x)
Definition: log.h:156
ods_status adapi_printaxfr(FILE *fd, zone_type *zone)
Definition: adapi.c:398
xfrd_type * xfrd
Definition: zone.h:91
#define lock_basic_unlock(lock)
Definition: locks.h:94
dnsout_type * dnsout_create(void)
Definition: addns.c:453
void ods_log_warning(const char *format,...)
Definition: log.c:320
ldns_rdf * apex
Definition: zone.h:70
time_t serial_disk_acquired
Definition: xfrd.h:114
rr_type * rrs
Definition: rrset.h:79
lock_basic_type xfr_lock
Definition: zone.h:98
void adapi_trans_diff(zone_type *zone, unsigned more_coming)
Definition: adapi.c:161