OpenDNSSEC-signer  1.4.8.2
tools.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 "daemon/dnshandler.h"
34 #include "adapter/adapter.h"
35 #include "shared/log.h"
36 #include "signer/tools.h"
37 #include "signer/zone.h"
38 
39 #include <errno.h>
40 #include <sys/types.h>
41 #include <sys/wait.h>
42 #include <unistd.h>
43 
44 static const char* tools_str = "tools";
45 
46 
53 {
54  ods_status status = ODS_STATUS_OK;
55  signconf_type* new_signconf = NULL;
56 
57  ods_log_assert(zone);
58  ods_log_assert(zone->name);
59  status = zone_load_signconf(zone, &new_signconf);
60  if (status == ODS_STATUS_OK) {
61  ods_log_assert(new_signconf);
62  /* Denial of Existence Rollover? */
63  if (signconf_compare_denial(zone->signconf, new_signconf)
64  == TASK_NSECIFY) {
69  namedb_wipe_denial(zone->db);
71  namedb_init_denials(zone->db);
72  }
73  /* all ok, switch signer configuration */
75  ods_log_debug("[%s] zone %s switch to new signconf", tools_str,
76  zone->name);
77  zone->signconf = new_signconf;
78  signconf_log(zone->signconf, zone->name);
79  zone->default_ttl = (uint32_t) duration2time(zone->signconf->soa_min);
80  } else if (status != ODS_STATUS_UNCHANGED) {
81  ods_log_error("[%s] unable to load signconf for zone %s: %s",
82  tools_str, zone->name, ods_status2str(status));
83  }
84  return status;
85 }
86 
87 
94 {
95  ods_status status = ODS_STATUS_OK;
96  time_t start = 0;
97  time_t end = 0;
98 
99  ods_log_assert(zone);
100  ods_log_assert(zone->name);
101  ods_log_assert(zone->adinbound);
102  ods_log_assert(zone->signconf);
103  /* Key Rollover? */
104  status = zone_publish_dnskeys(zone);
105  if (status != ODS_STATUS_OK) {
106  ods_log_error("[%s] unable to read zone %s: failed to "
107  "publish dnskeys (%s)", tools_str, zone->name,
108  ods_status2str(status));
109  zone_rollback_dnskeys(zone);
111  namedb_rollback(zone->db, 0);
112  return status;
113  }
114  /* Denial of Existence Rollover? */
115  status = zone_publish_nsec3param(zone);
116  if (status != ODS_STATUS_OK) {
117  ods_log_error("[%s] unable to read zone %s: failed to "
118  "publish nsec3param (%s)", tools_str, zone->name,
119  ods_status2str(status));
120  zone_rollback_dnskeys(zone);
122  namedb_rollback(zone->db, 0);
123  return status;
124  }
125 
126  if (zone->stats) {
128  zone->stats->sort_done = 0;
129  zone->stats->sort_count = 0;
130  zone->stats->sort_time = 0;
132  }
133  /* Input Adapter */
134  start = time(NULL);
135  status = adapter_read((void*)zone);
136  if (status != ODS_STATUS_OK && status != ODS_STATUS_UNCHANGED) {
137  if (status == ODS_STATUS_XFRINCOMPLETE) {
138  ods_log_info("[%s] read zone %s: xfr in progress",
139  tools_str, zone->name);
140  } else {
141  ods_log_error("[%s] unable to read zone %s: adapter failed (%s)",
142  tools_str, zone->name, ods_status2str(status));
143  }
144  zone_rollback_dnskeys(zone);
146  namedb_rollback(zone->db, 0);
147  }
148  end = time(NULL);
149  if ((status == ODS_STATUS_OK || status == ODS_STATUS_UNCHANGED)
150  && zone->stats) {
152  zone->stats->start_time = start;
153  zone->stats->sort_time = (end-start);
154  zone->stats->sort_done = 1;
156  }
157  return status;
158 }
159 
160 
165 static void
166 ods_closeall(int fd)
167 {
168  int fdlimit = sysconf(_SC_OPEN_MAX);
169  while (fd < fdlimit) {
170  close(fd++);
171  }
172  return;
173 }
174 
175 
182 {
183  ods_status status = ODS_STATUS_OK;
184  ods_log_assert(engine);
185  ods_log_assert(engine->config);
186  ods_log_assert(zone);
187  ods_log_assert(zone->db);
188  ods_log_assert(zone->name);
189  ods_log_assert(zone->signconf);
190  ods_log_assert(zone->adoutbound);
191  /* prepare */
192  if (zone->stats) {
194  if (zone->stats->sort_done == 0 &&
195  (zone->stats->sig_count <= zone->stats->sig_soa_count)) {
196  ods_log_verbose("[%s] skip write zone %s serial %u (zone not "
197  "changed)", tools_str, zone->name?zone->name:"(null)",
198  zone->db->intserial);
199  stats_clear(zone->stats);
201  zone->db->intserial =
202  zone->db->outserial;
203  return ODS_STATUS_OK;
204  }
206  }
207  /* Output Adapter */
208  status = adapter_write((void*)zone);
209  if (status != ODS_STATUS_OK) {
210  ods_log_error("[%s] unable to write zone %s: adapter failed (%s)",
211  tools_str, zone->name, ods_status2str(status));
212  return status;
213  }
214  zone->db->outserial = zone->db->intserial;
215  zone->db->is_initialized = 1;
216  zone->db->have_serial = 1;
217  lock_basic_lock(&zone->ixfr->ixfr_lock);
218  ixfr_purge(zone->ixfr);
220  /* kick the nameserver */
221  if (zone->notify_ns) {
222  int status;
223  pid_t pid, wpid;
224  ods_log_verbose("[%s] notify nameserver: %s", tools_str,
225  zone->notify_ns);
227  switch ((pid = fork())) {
228  case -1: /* error */
229  ods_log_error("[%s] notify nameserver failed: unable to fork "
230  "(%s)", tools_str, strerror(errno));
231  return ODS_STATUS_FORK_ERR;
232  case 0: /* child */
234  ods_closeall(0);
236  execvp(zone->notify_ns, zone->notify_args);
238  ods_log_error("[%s] notify nameserver failed: execv() failed "
239  "(%s)", tools_str, strerror(errno));
240  exit(1);
241  break;
242  default: /* parent */
243  ods_log_debug("[%s] notify nameserver process forked",
244  tools_str);
246  while((wpid = waitpid(pid, &status, 0)) <= 0) {
247  if (errno != EINTR) {
248  break;
249  }
250  }
251  if (wpid == -1) {
252  ods_log_error("[%s] notify nameserver failed: waitpid() ",
253  "failed (%s)", tools_str, strerror(errno));
254  } else if (!WIFEXITED(status)) {
255  ods_log_error("[%s] notify nameserver failed: notify ",
256  "command did not terminate normally", tools_str);
257  } else {
258  ods_log_verbose("[%s] notify nameserver ok", tools_str);
259  }
260  break;
261  }
262  }
263  /* log stats */
264  if (zone->stats) {
266  zone->stats->end_time = time(NULL);
267  ods_log_debug("[%s] log stats for zone %s serial %u", tools_str,
268  zone->name?zone->name:"(null)", (unsigned) zone->db->outserial);
269  stats_log(zone->stats, zone->name, zone->db->outserial,
270  zone->signconf->nsec_type);
271  stats_clear(zone->stats);
273  }
274  if (engine->dnshandler) {
275  ods_log_debug("[%s] forward a notify", tools_str);
277  strlen(ODS_SE_NOTIFY_CMD));
278  }
279  return status;
280 }
uint32_t default_ttl
Definition: zone.h:70
void namedb_cleanup_denials(namedb_type *db)
Definition: namedb.c:1138
uint32_t intserial
Definition: namedb.h:52
int sort_done
Definition: stats.h:57
#define ODS_SE_NOTIFY_CMD
Definition: dnshandler.h:46
task_id signconf_compare_denial(signconf_type *a, signconf_type *b)
Definition: signconf.c:363
void ods_log_debug(const char *format,...)
Definition: log.c:270
duration_type * soa_min
Definition: signconf.h:74
ods_status adapter_read(void *zone)
Definition: adapter.c:164
void signconf_cleanup(signconf_type *sc)
Definition: signconf.c:564
ods_status tools_signconf(zone_type *zone)
Definition: tools.c:52
unsigned have_serial
Definition: namedb.h:59
void ods_log_info(const char *format,...)
Definition: log.c:302
enum ods_enum_status ods_status
Definition: status.h:90
void ods_log_error(const char *format,...)
Definition: log.c:334
uint32_t outserial
Definition: namedb.h:53
lock_basic_type stats_lock
Definition: stats.h:67
int32_t sort_count
Definition: stats.h:55
const char * ods_status2str(ods_status status)
Definition: status.c:111
void namedb_init_denials(namedb_type *db)
Definition: namedb.c:96
ldns_rr_type nsec_type
Definition: signconf.h:63
adapter_type * adoutbound
Definition: zone.h:82
int32_t sig_count
Definition: stats.h:60
ods_status zone_publish_nsec3param(zone_type *zone)
Definition: zone.c:335
void stats_log(stats_type *stats, const char *name, uint32_t serial, ldns_rr_type nsec_type)
Definition: stats.c:76
ods_status tools_input(zone_type *zone)
Definition: tools.c:93
#define lock_basic_lock(lock)
Definition: locks.h:94
engineconfig_type * config
Definition: engine.h:57
namedb_type * db
Definition: zone.h:86
ixfr_type * ixfr
Definition: zone.h:87
unsigned is_initialized
Definition: namedb.h:55
ods_status tools_output(zone_type *zone, engine_type *engine)
Definition: tools.c:181
signconf_type * signconf
Definition: zone.h:84
time_t start_time
Definition: stats.h:65
time_t sort_time
Definition: stats.h:56
adapter_type * adinbound
Definition: zone.h:81
void namedb_rollback(namedb_type *db, unsigned keepsc)
Definition: namedb.c:856
char ** notify_args
Definition: zone.h:74
void zone_rollback_dnskeys(zone_type *zone)
Definition: zone.c:305
ods_status zone_publish_dnskeys(zone_type *zone)
Definition: zone.c:231
time_t end_time
Definition: stats.h:66
const char * notify_ns
Definition: zone.h:73
time_t duration2time(duration_type *duration)
Definition: duration.c:371
void zone_rollback_nsec3param(zone_type *zone)
Definition: zone.c:403
void ods_log_verbose(const char *format,...)
Definition: log.c:286
lock_basic_type ixfr_lock
Definition: ixfr.h:62
void signconf_log(signconf_type *sc, const char *name)
Definition: signconf.c:488
const char * name
Definition: zone.h:76
void ixfr_purge(ixfr_type *ixfr)
Definition: ixfr.c:275
#define ods_log_assert(x)
Definition: log.h:154
ods_status zone_load_signconf(zone_type *zone, signconf_type **new_signconf)
Definition: zone.c:136
ods_status adapter_write(void *zone)
Definition: adapter.c:197
int32_t sig_soa_count
Definition: stats.h:61
void dnshandler_fwd_notify(dnshandler_type *dnshandler, uint8_t *pkt, size_t len)
Definition: dnshandler.c:247
void namedb_wipe_denial(namedb_type *db)
Definition: namedb.c:990
#define lock_basic_unlock(lock)
Definition: locks.h:95
stats_type * stats
Definition: zone.h:94
dnshandler_type * dnshandler
Definition: engine.h:64
void stats_clear(stats_type *stats)
Definition: stats.c:54