OpenDNSSEC-signer
1.3.15
Main Page
Data Structures
Files
File List
Globals
signer
src
signer
tools.c
Go to the documentation of this file.
1
/*
2
* $Id: tools.c 7295 2013-09-11 10:18:25Z 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/adapter.h
"
36
#include "
shared/file.h
"
37
#include "
shared/log.h
"
38
#include "
signer/tools.h
"
39
#include "
signer/zone.h
"
40
41
static
const
char
* tools_str =
"tools"
;
42
43
48
ods_status
49
tools_input
(
zone_type
* zone)
50
{
51
ods_status
status =
ODS_STATUS_OK
;
52
char
* tmpname = NULL;
53
char
* lockname = NULL;
54
time_t start = 0;
55
time_t end = 0;
56
FILE* fd = NULL;
57
58
if
(!zone) {
59
ods_log_error
(
"[%s] unable to read zone: no zone"
, tools_str);
60
return
ODS_STATUS_ASSERT_ERR
;
61
}
62
ods_log_assert
(zone);
63
64
if
(!zone->
zonedata
) {
65
ods_log_error
(
"[%s] unable to read zone: no zone data"
, tools_str);
66
return
ODS_STATUS_ASSERT_ERR
;
67
}
68
ods_log_assert
(zone->
zonedata
);
69
70
ods_log_assert
(zone->
adinbound
);
71
ods_log_assert
(zone->
signconf
);
72
73
if
(zone->
stats
) {
74
lock_basic_lock
(&zone->
stats
->
stats_lock
);
75
zone->
stats
->
stats_locked
=
LOCKED_STATS_TOOLS_INPUT_START
;
76
zone->
stats
->
sort_done
= 0;
77
zone->
stats
->
sort_count
= 0;
78
zone->
stats
->
sort_time
= 0;
79
zone->
stats
->
stats_locked
= 0;
80
lock_basic_unlock
(&zone->
stats
->
stats_lock
);
81
}
82
83
if
(zone->
adinbound
->
type
==
ADAPTER_FILE
) {
84
if
(zone->
fetch
) {
85
ods_log_verbose
(
"[%s] fetch zone %s"
, tools_str,
86
zone->
name
?zone->
name
:
"(null)"
);
87
tmpname =
ods_build_path
(
88
zone->
adinbound
->
configstr
,
".axfr"
, 0, 0);
89
lockname =
ods_build_path
(
90
zone->
adinbound
->
configstr
,
".lock"
, 0, 0);
91
92
lock_fetch:
93
if
(access(lockname, F_OK) == 0) {
94
ods_log_deeebug
(
"[%s] axfr file %s is locked, "
95
"waiting..."
, tools_str, tmpname);
96
sleep(1);
97
goto
lock_fetch;
98
}
else
{
99
fd = fopen(lockname,
"w"
);
100
if
(!fd) {
101
ods_log_error
(
"[%s] cannot lock AXFR file %s"
,
102
tools_str, lockname);
103
free((
void
*)tmpname);
104
free((
void
*)lockname);
105
return
ODS_STATUS_ERR
;
106
}
107
}
108
ods_log_assert
(fd);
/* locked */
109
110
status =
ods_file_copy
(tmpname, zone->
adinbound
->
configstr
);
111
112
fclose(fd);
113
(void) unlink(lockname);
/* unlocked */
114
115
if
(status !=
ODS_STATUS_OK
) {
116
ods_log_error
(
"[%s] unable to copy axfr file %s to %s: %s"
,
117
tools_str, tmpname, zone->
adinbound
->
configstr
,
118
ods_status2str
(status));
119
free((
void
*)tmpname);
120
free((
void
*)lockname);
121
return
status;
122
}
123
free((
void
*)tmpname);
124
free((
void
*)lockname);
125
}
126
}
127
128
start = time(NULL);
129
status =
adapter_read
(zone);
130
if
(status !=
ODS_STATUS_OK
) {
131
ods_log_error
(
"[%s] unable to read from input adapter for zone %s: "
132
"%s"
, tools_str, zone->
name
?zone->
name
:
"(null)"
,
133
ods_status2str
(status));
134
}
else
{
135
tmpname =
ods_build_path
(zone->
name
,
".inbound"
, 0, 1);
136
status =
ods_file_copy
(zone->
adinbound
->
configstr
, tmpname);
137
if
(status !=
ODS_STATUS_OK
) {
138
ods_log_error
(
"[%s] unable to copy zone input file %s: %s"
,
139
tools_str, tmpname,
ods_status2str
(status));
140
}
141
free((
void
*)tmpname);
142
tmpname = NULL;
143
}
144
145
if
(status ==
ODS_STATUS_OK
) {
146
ods_log_verbose
(
"[%s] commit updates for zone %s"
, tools_str,
147
zone->
name
?zone->
name
:
"(null)"
);
148
status =
zonedata_commit
(zone->
zonedata
);
149
}
else
{
150
ods_log_warning
(
"[%s] rollback updates for zone %s"
, tools_str,
151
zone->
name
?zone->
name
:
"(null)"
);
152
zonedata_rollback
(zone->
zonedata
);
153
}
154
end = time(NULL);
155
156
if
(status ==
ODS_STATUS_OK
&& zone->
stats
) {
157
lock_basic_lock
(&zone->
stats
->
stats_lock
);
158
zone->
stats
->
stats_locked
=
LOCKED_STATS_TOOLS_INPUT_STOP
;
159
zone->
stats
->
start_time
= start;
160
zone->
stats
->
sort_time
= (end-start);
161
zone->
stats
->
sort_done
= 1;
162
zone->
stats
->
stats_locked
= 0;
163
lock_basic_unlock
(&zone->
stats
->
stats_lock
);
164
}
165
return
status;
166
}
167
168
173
ods_status
174
tools_nsecify
(
zone_type
* zone)
175
{
176
ods_status
status =
ODS_STATUS_OK
;
177
time_t start = 0;
178
time_t end = 0;
179
uint32_t ttl = 0;
180
uint32_t num_added = 0;
181
182
if
(!zone) {
183
ods_log_error
(
"[%s] unable to nsecify zone: no zone"
, tools_str);
184
return
ODS_STATUS_ASSERT_ERR
;
185
}
186
ods_log_assert
(zone);
187
188
if
(!zone->
zonedata
) {
189
ods_log_error
(
"[%s] unable to nsecify zone %s: no zonedata"
,
190
tools_str, zone->
name
);
191
return
ODS_STATUS_ASSERT_ERR
;
192
}
193
ods_log_assert
(zone->
zonedata
);
194
195
if
(!zone->
signconf
) {
196
ods_log_error
(
"[%s] unable to nsecify zone %s: no signconf"
,
197
tools_str, zone->
name
);
198
return
ODS_STATUS_ASSERT_ERR
;
199
}
200
ods_log_assert
(zone->
signconf
);
201
202
if
(zone->
stats
) {
203
lock_basic_lock
(&zone->
stats
->
stats_lock
);
204
zone->
stats
->
stats_locked
=
LOCKED_STATS_TOOLS_NSECIFY_START
;
205
zone->
stats
->
nsec_time
= 0;
206
zone->
stats
->
nsec_count
= 0;
207
zone->
stats
->
stats_locked
= 0;
208
lock_basic_unlock
(&zone->
stats
->
stats_lock
);
209
}
210
211
start = time(NULL);
212
/* determine denial ttl */
213
ttl = zone->
zonedata
->
default_ttl
;
214
if
(zone->
signconf
->
soa_min
) {
215
ttl = (uint32_t)
duration2time
(zone->
signconf
->
soa_min
);
216
}
217
/* add missing empty non-terminals */
218
status =
zonedata_entize
(zone->
zonedata
, zone->
dname
);
219
if
(status !=
ODS_STATUS_OK
) {
220
ods_log_error
(
"[%s] unable to nsecify zone %s: failed to add empty "
,
221
"non-terminals"
, tools_str, zone->
name
);
222
return
status;
223
}
224
/* nsecify(3) */
225
if
(zone->
signconf
->
nsec_type
== LDNS_RR_TYPE_NSEC) {
226
status =
zonedata_nsecify
(zone->
zonedata
, zone->
klass
, ttl,
227
&num_added);
228
}
else
if
(zone->
signconf
->
nsec_type
== LDNS_RR_TYPE_NSEC3) {
229
if
(zone->
signconf
->
nsec3_optout
) {
230
ods_log_debug
(
"[%s] OptOut is being used for zone %s"
,
231
tools_str, zone->
name
);
232
}
233
ods_log_assert
(zone->
nsec3params
);
234
status =
zonedata_nsecify3
(zone->
zonedata
, zone->
klass
, ttl,
235
zone->
nsec3params
, &num_added);
236
}
else
{
237
ods_log_error
(
"[%s] unable to nsecify zone %s: unknown RRtype %u for "
,
238
"denial of existence"
, tools_str, zone->
name
,
239
(
unsigned
) zone->
signconf
->
nsec_type
);
240
return
ODS_STATUS_ERR
;
241
}
242
end = time(NULL);
243
if
(status ==
ODS_STATUS_OK
&& zone->
stats
) {
244
lock_basic_lock
(&zone->
stats
->
stats_lock
);
245
zone->
stats
->
stats_locked
=
LOCKED_STATS_TOOLS_NSECIFY_STOP
;
246
if
(!zone->
stats
->
start_time
) {
247
zone->
stats
->
start_time
= start;
248
}
249
zone->
stats
->
nsec_time
= (end-start);
250
zone->
stats
->
nsec_count
= num_added;
251
zone->
stats
->
stats_locked
= 0;
252
lock_basic_unlock
(&zone->
stats
->
stats_lock
);
253
}
254
return
status;
255
}
256
257
262
ods_status
263
tools_audit
(
zone_type
* zone,
char
* working_dir,
char
* cfg_filename)
264
{
265
ods_status
status =
ODS_STATUS_OK
;
266
#ifdef HAVE_AUDITOR
267
char
* inbound = NULL;
268
char
* finalized = NULL;
269
char
str[
SYSTEM_MAXLEN
];
270
int
error = 0;
271
time_t start = 0;
272
time_t end = 0;
273
274
if
(!zone) {
275
ods_log_error
(
"[%s] unable to audit zone: no zone"
, tools_str);
276
return
ODS_STATUS_ASSERT_ERR
;
277
}
278
ods_log_assert
(zone);
279
280
if
(!zone->
signconf
) {
281
ods_log_error
(
"[%s] unable to audit zone %s: no signconf"
,
282
tools_str, zone->
name
?zone->
name
:
"(null)"
);
283
return
ODS_STATUS_ASSERT_ERR
;
284
}
285
ods_log_assert
(zone->
signconf
);
286
287
if
(zone->
stats
) {
288
lock_basic_lock
(&zone->
stats
->
stats_lock
);
289
zone->
stats
->
stats_locked
=
LOCKED_STATS_TOOLS_AUDIT_START
;
290
if
(zone->
stats
->
sort_done
== 0 &&
291
(zone->
stats
->
sig_count
<= zone->
stats
->
sig_soa_count
)) {
292
lock_basic_unlock
(&zone->
stats
->
stats_lock
);
293
return
ODS_STATUS_OK
;
294
}
295
zone->
stats
->
stats_locked
= 0;
296
lock_basic_unlock
(&zone->
stats
->
stats_lock
);
297
}
298
299
if
(zone->
signconf
->
audit
) {
300
inbound =
ods_build_path
(zone->
name
,
".inbound"
, 0, 1);
301
finalized =
ods_build_path
(zone->
name
,
".finalized"
, 0, 1);
302
status =
adfile_write
(zone, finalized);
303
if
(status !=
ODS_STATUS_OK
) {
304
ods_log_error
(
"[%s] audit zone %s failed: unable to write zone"
,
305
tools_str, finalized);
306
free((
void
*)inbound);
307
free((
void
*)finalized);
308
return
status;
309
}
310
311
snprintf(str,
SYSTEM_MAXLEN
,
"%s -c %s -u %s/%s -s %s/%s -z %s > /dev/null"
,
312
ODS_SE_AUDITOR,
313
cfg_filename?cfg_filename:ODS_SE_CFGFILE,
314
working_dir?working_dir:
""
,
315
inbound?inbound:
"(null)"
,
316
working_dir?working_dir:
""
,
317
finalized?finalized:
"(null)"
,
318
zone->
name
?zone->
name
:
"(null)"
);
319
320
start = time(NULL);
321
ods_log_debug
(
"system call: %s"
, str);
322
error = system(str);
323
if
(finalized) {
324
if
(!error) {
325
unlink(finalized);
326
}
327
free((
void
*)finalized);
328
}
329
free((
void
*)inbound);
330
331
if
(error) {
332
ods_log_error
(
"[%s] audit failed for zone %s"
, tools_str,
333
zone->
name
);
334
status =
ODS_STATUS_ERR
;
335
}
else
{
336
ods_log_info
(
"[%s] audit passed for zone %s"
, tools_str,
337
zone->
name
);
338
}
339
end = time(NULL);
340
if
(status ==
ODS_STATUS_OK
&& zone->
stats
) {
341
lock_basic_lock
(&zone->
stats
->
stats_lock
);
342
zone->
stats
->
stats_locked
=
LOCKED_STATS_TOOLS_AUDIT_STOP
;
343
zone->
stats
->
audit_time
= (end-start);
344
zone->
stats
->
stats_locked
= 0;
345
lock_basic_unlock
(&zone->
stats
->
stats_lock
);
346
}
347
}
348
#else
349
ods_log_error
(
"[%s] unable to audit zone %s: ods-auditor not installed"
,
350
tools_str, zone->
name
?zone->
name
:
"(null)"
);
351
status =
ODS_STATUS_ERR
;
352
#endif
353
return
status;
354
}
355
356
361
ods_status
362
tools_output
(
zone_type
* zone)
363
{
364
ods_status
status =
ODS_STATUS_OK
;
365
char
str[
SYSTEM_MAXLEN
];
366
int
error = 0;
367
uint32_t outbound_serial = 0;
368
369
if
(!zone) {
370
ods_log_error
(
"[%s] unable to write zone: no zone"
, tools_str);
371
return
ODS_STATUS_ASSERT_ERR
;
372
}
373
ods_log_assert
(zone);
374
375
if
(!zone->
adoutbound
) {
376
ods_log_error
(
"[%s] unable to write zone %s: no outbound adapter"
,
377
tools_str, zone->
name
?zone->
name
:
"(null)"
);
378
return
ODS_STATUS_ASSERT_ERR
;
379
}
380
ods_log_assert
(zone->
adoutbound
);
381
382
if
(zone->
stats
) {
383
lock_basic_lock
(&zone->
stats
->
stats_lock
);
384
zone->
stats
->
stats_locked
=
LOCKED_STATS_TOOLS_OUTPUT_START
;
385
if
(zone->
stats
->
sort_done
== 0 &&
386
(zone->
stats
->
sig_count
<= zone->
stats
->
sig_soa_count
)) {
387
ods_log_verbose
(
"[%s] skip write zone %s serial %u (zone not "
388
"changed)"
, tools_str, zone->
name
?zone->
name
:
"(null)"
,
389
zone->
zonedata
->
internal_serial
);
390
stats_clear
(zone->
stats
);
391
zone->
stats
->
stats_locked
= 0;
392
lock_basic_unlock
(&zone->
stats
->
stats_lock
);
393
zone->
zonedata
->
internal_serial
=
394
zone->
zonedata
->
outbound_serial
;
395
return
ODS_STATUS_OK
;
396
}
397
zone->
stats
->
stats_locked
= 0;
398
lock_basic_unlock
(&zone->
stats
->
stats_lock
);
399
}
400
401
outbound_serial = zone->
zonedata
->
outbound_serial
;
402
zone->
zonedata
->
outbound_serial
= zone->
zonedata
->
internal_serial
;
403
status =
adapter_write
(zone);
404
if
(status !=
ODS_STATUS_OK
) {
405
ods_log_error
(
"[%s] unable to write zone %s: adapter failed (%s)"
,
406
tools_str, zone->
name
,
ods_status2str
(status));
407
zone->
zonedata
->
outbound_serial
= outbound_serial;
408
return
status;
409
}
410
411
/* initialize zonedata */
412
zone->
zonedata
->
initialized
= 1;
413
414
/* kick the nameserver */
415
if
(zone->
notify_ns
) {
416
ods_log_verbose
(
"[%s] notify nameserver: %s"
, tools_str,
417
zone->
notify_ns
);
418
snprintf(str,
SYSTEM_MAXLEN
,
"%s > /dev/null"
,
419
zone->
notify_ns
);
420
error = system(str);
421
if
(error) {
422
ods_log_error
(
"[%s] failed to notify nameserver"
, tools_str);
423
status =
ODS_STATUS_ERR
;
424
}
425
}
426
/* log stats */
427
if
(zone->
stats
) {
428
lock_basic_lock
(&zone->
stats
->
stats_lock
);
429
zone->
stats
->
stats_locked
=
LOCKED_STATS_TOOLS_LOG
;
430
zone->
stats
->
end_time
= time(NULL);
431
ods_log_debug
(
"[%s] log stats for zone %s"
, tools_str,
432
zone->
name
?zone->
name
:
"(null)"
);
433
stats_log
(zone->
stats
, zone->
name
, zone->
signconf
->
nsec_type
);
434
stats_clear
(zone->
stats
);
435
zone->
stats
->
stats_locked
= 0;
436
lock_basic_unlock
(&zone->
stats
->
stats_lock
);
437
}
438
return
status;
439
}
Generated on Fri Sep 27 2013 06:39:28 for OpenDNSSEC-signer by
1.8.4