OpenDNSSEC-signer  1.4.3
tools.c
Go to the documentation of this file.
1 /*
2  * $Id: tools.c 7359 2013-10-11 11:55:08Z 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 "daemon/dnshandler.h"
36 #include "adapter/adapter.h"
37 #include "shared/log.h"
38 #include "signer/tools.h"
39 #include "signer/zone.h"
40 
41 #include <errno.h>
42 #include <sys/types.h>
43 #include <sys/wait.h>
44 #include <unistd.h>
45 
46 static const char* tools_str = "tools";
47 
48 
55 {
56  ods_status status = ODS_STATUS_OK;
57  signconf_type* new_signconf = NULL;
58 
59  ods_log_assert(zone);
60  ods_log_assert(zone->name);
61  status = zone_load_signconf(zone, &new_signconf);
62  if (status == ODS_STATUS_OK) {
63  ods_log_assert(new_signconf);
64  /* Denial of Existence Rollover? */
65  if (signconf_compare_denial(zone->signconf, new_signconf)
66  == TASK_NSECIFY) {
71  namedb_wipe_denial(zone->db);
73  namedb_init_denials(zone->db);
74  }
75  /* all ok, switch signer configuration */
77  ods_log_debug("[%s] zone %s switch to new signconf", tools_str,
78  zone->name);
79  zone->signconf = new_signconf;
80  signconf_log(zone->signconf, zone->name);
81  zone->default_ttl = (uint32_t) duration2time(zone->signconf->soa_min);
82  } else if (status != ODS_STATUS_UNCHANGED) {
83  ods_log_error("[%s] unable to load signconf for zone %s: %s",
84  tools_str, zone->name, ods_status2str(status));
85  }
86  return status;
87 }
88 
89 
96 {
97  ods_status status = ODS_STATUS_OK;
98  time_t start = 0;
99  time_t end = 0;
100 
101  ods_log_assert(zone);
102  ods_log_assert(zone->name);
103  ods_log_assert(zone->adinbound);
104  ods_log_assert(zone->signconf);
105  /* Key Rollover? */
106  status = zone_publish_dnskeys(zone);
107  if (status != ODS_STATUS_OK) {
108  ods_log_error("[%s] unable to read zone %s: failed to "
109  "publish dnskeys (%s)", tools_str, zone->name,
110  ods_status2str(status));
111  zone_rollback_dnskeys(zone);
113  namedb_rollback(zone->db, 0);
114  return status;
115  }
116  /* Denial of Existence Rollover? */
117  status = zone_publish_nsec3param(zone);
118  if (status != ODS_STATUS_OK) {
119  ods_log_error("[%s] unable to read zone %s: failed to "
120  "publish nsec3param (%s)", tools_str, zone->name,
121  ods_status2str(status));
122  zone_rollback_dnskeys(zone);
124  namedb_rollback(zone->db, 0);
125  return status;
126  }
127 
128  if (zone->stats) {
130  zone->stats->sort_done = 0;
131  zone->stats->sort_count = 0;
132  zone->stats->sort_time = 0;
134  }
135  /* Input Adapter */
136  start = time(NULL);
137  status = adapter_read((void*)zone);
138  if (status != ODS_STATUS_OK && status != ODS_STATUS_UNCHANGED) {
139  ods_log_error("[%s] unable to read zone %s: adapter failed (%s)",
140  tools_str, zone->name, ods_status2str(status));
141  zone_rollback_dnskeys(zone);
143  namedb_rollback(zone->db, 0);
144  }
145  end = time(NULL);
146  if ((status == ODS_STATUS_OK || status == ODS_STATUS_UNCHANGED)
147  && zone->stats) {
149  zone->stats->start_time = start;
150  zone->stats->sort_time = (end-start);
151  zone->stats->sort_done = 1;
153  }
154  return status;
155 }
156 
157 
162 static void
163 ods_closeall(int fd)
164 {
165  int fdlimit = sysconf(_SC_OPEN_MAX);
166  while (fd < fdlimit) {
167  close(fd++);
168  }
169  return;
170 }
171 
172 
179 {
180  ods_status status = ODS_STATUS_OK;
181  ods_log_assert(engine);
182  ods_log_assert(engine->config);
183  ods_log_assert(zone);
184  ods_log_assert(zone->db);
185  ods_log_assert(zone->name);
186  ods_log_assert(zone->signconf);
187  ods_log_assert(zone->adoutbound);
188  /* prepare */
189  if (zone->stats) {
191  if (zone->stats->sort_done == 0 &&
192  (zone->stats->sig_count <= zone->stats->sig_soa_count)) {
193  ods_log_verbose("[%s] skip write zone %s serial %u (zone not "
194  "changed)", tools_str, zone->name?zone->name:"(null)",
195  zone->db->intserial);
196  stats_clear(zone->stats);
198  zone->db->intserial =
199  zone->db->outserial;
200  return ODS_STATUS_OK;
201  }
203  }
204  /* Output Adapter */
205  status = adapter_write((void*)zone);
206  if (status != ODS_STATUS_OK) {
207  ods_log_error("[%s] unable to write zone %s: adapter failed (%s)",
208  tools_str, zone->name, ods_status2str(status));
209  return status;
210  }
211  zone->db->outserial = zone->db->intserial;
212  zone->db->is_initialized = 1;
213  zone->db->have_serial = 1;
214  lock_basic_lock(&zone->ixfr->ixfr_lock);
215  ixfr_purge(zone->ixfr);
217  /* kick the nameserver */
218  if (zone->notify_ns) {
219  int status;
220  pid_t pid, wpid;
221  ods_log_verbose("[%s] notify nameserver: %s", tools_str,
222  zone->notify_ns);
224  switch ((pid = fork())) {
225  case -1: /* error */
226  ods_log_error("[%s] notify nameserver failed: unable to fork "
227  "(%s)", tools_str, strerror(errno));
228  return ODS_STATUS_FORK_ERR;
229  case 0: /* child */
231  ods_closeall(0);
233  execvp(zone->notify_ns, zone->notify_args);
235  ods_log_error("[%s] notify nameserver failed: execv() failed "
236  "(%s)", tools_str, strerror(errno));
237  exit(1);
238  break;
239  default: /* parent */
240  ods_log_debug("[%s] notify nameserver process forked",
241  tools_str);
243  while((wpid = waitpid(pid, &status, 0)) <= 0) {
244  if (errno != EINTR) {
245  break;
246  }
247  }
248  if (wpid == -1) {
249  ods_log_error("[%s] notify nameserver failed: waitpid() ",
250  "failed (%s)", tools_str, strerror(errno));
251  } else if (!WIFEXITED(status)) {
252  ods_log_error("[%s] notify nameserver failed: notify ",
253  "command did not terminate normally", tools_str);
254  } else {
255  ods_log_verbose("[%s] notify nameserver ok", tools_str);
256  }
257  break;
258  }
259  }
260  if (engine->dnshandler) {
262  strlen(ODS_SE_NOTIFY_CMD));
263  }
264  /* log stats */
265  if (zone->stats) {
267  zone->stats->end_time = time(NULL);
268  ods_log_debug("[%s] log stats for zone %s", tools_str,
269  zone->name?zone->name:"(null)");
270  stats_log(zone->stats, zone->name, zone->signconf->nsec_type);
271  stats_clear(zone->stats);
273  }
274  return status;
275 }
uint32_t default_ttl
Definition: zone.h:72
void namedb_cleanup_denials(namedb_type *db)
Definition: namedb.c:1124
uint32_t intserial
Definition: namedb.h:54
int sort_done
Definition: stats.h:59
#define ODS_SE_NOTIFY_CMD
Definition: dnshandler.h:48
task_id signconf_compare_denial(signconf_type *a, signconf_type *b)
Definition: signconf.c:365
void ods_log_debug(const char *format,...)
Definition: log.c:272
duration_type * soa_min
Definition: signconf.h:76
void stats_log(stats_type *stats, const char *name, ldns_rr_type nsec_type)
Definition: stats.c:78
ods_status adapter_read(void *zone)
Definition: adapter.c:166
void signconf_cleanup(signconf_type *sc)
Definition: signconf.c:566
ods_status tools_signconf(zone_type *zone)
Definition: tools.c:54
unsigned have_serial
Definition: namedb.h:61
enum ods_enum_status ods_status
Definition: status.h:91
void ods_log_error(const char *format,...)
Definition: log.c:336
uint32_t outserial
Definition: namedb.h:55
lock_basic_type stats_lock
Definition: stats.h:69
const char * ods_status2str(ods_status status)
Definition: status.c:112
void namedb_init_denials(namedb_type *db)
Definition: namedb.c:98
ldns_rr_type nsec_type
Definition: signconf.h:65
adapter_type * adoutbound
Definition: zone.h:84
ods_status zone_publish_nsec3param(zone_type *zone)
Definition: zone.c:337
ods_status tools_input(zone_type *zone)
Definition: tools.c:95
#define lock_basic_lock(lock)
Definition: locks.h:93
engineconfig_type * config
Definition: engine.h:59
namedb_type * db
Definition: zone.h:88
ixfr_type * ixfr
Definition: zone.h:89
unsigned is_initialized
Definition: namedb.h:57
ods_status tools_output(zone_type *zone, engine_type *engine)
Definition: tools.c:178
signconf_type * signconf
Definition: zone.h:86
time_t start_time
Definition: stats.h:67
time_t sort_time
Definition: stats.h:58
adapter_type * adinbound
Definition: zone.h:83
void namedb_rollback(namedb_type *db, unsigned keepsc)
Definition: namedb.c:858
char ** notify_args
Definition: zone.h:76
void zone_rollback_dnskeys(zone_type *zone)
Definition: zone.c:307
ods_status zone_publish_dnskeys(zone_type *zone)
Definition: zone.c:233
time_t end_time
Definition: stats.h:68
const char * notify_ns
Definition: zone.h:75
time_t duration2time(duration_type *duration)
Definition: duration.c:373
void zone_rollback_nsec3param(zone_type *zone)
Definition: zone.c:405
void ods_log_verbose(const char *format,...)
Definition: log.c:288
lock_basic_type ixfr_lock
Definition: ixfr.h:64
uint32_t sort_count
Definition: stats.h:57
void signconf_log(signconf_type *sc, const char *name)
Definition: signconf.c:490
const char * name
Definition: zone.h:78
uint32_t sig_soa_count
Definition: stats.h:63
void ixfr_purge(ixfr_type *ixfr)
Definition: ixfr.c:277
uint32_t sig_count
Definition: stats.h:62
#define ods_log_assert(x)
Definition: log.h:156
ods_status zone_load_signconf(zone_type *zone, signconf_type **new_signconf)
Definition: zone.c:138
ods_status adapter_write(void *zone)
Definition: adapter.c:202
void dnshandler_fwd_notify(dnshandler_type *dnshandler, uint8_t *pkt, size_t len)
Definition: dnshandler.c:249
void namedb_wipe_denial(namedb_type *db)
Definition: namedb.c:976
#define lock_basic_unlock(lock)
Definition: locks.h:94
stats_type * stats
Definition: zone.h:96
dnshandler_type * dnshandler
Definition: engine.h:66
void stats_clear(stats_type *stats)
Definition: stats.c:56