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