2 * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: nsecify.c,v 1.10 2009/09/02 23:48:01 tbox Exp $ */
25 #include <isc/print.h>
26 #include <isc/string.h>
29 #include <dns/dbiterator.h>
30 #include <dns/fixedname.h>
32 #include <dns/rdataset.h>
33 #include <dns/rdatasetiter.h>
34 #include <dns/result.h>
36 static isc_mem_t *mctx = NULL;
39 fatal(const char *message) {
40 fprintf(stderr, "%s\n", message);
45 check_result(isc_result_t result, const char *message) {
46 if (result != ISC_R_SUCCESS) {
47 fprintf(stderr, "%s: %s\n", message,
48 isc_result_totext(result));
53 static inline isc_boolean_t
54 active_node(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node) {
55 dns_rdatasetiter_t *rdsiter;
56 isc_boolean_t active = ISC_FALSE;
58 dns_rdataset_t rdataset;
60 dns_rdataset_init(&rdataset);
62 result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
63 check_result(result, "dns_db_allrdatasets()");
64 result = dns_rdatasetiter_first(rdsiter);
65 while (result == ISC_R_SUCCESS) {
66 dns_rdatasetiter_current(rdsiter, &rdataset);
67 if (rdataset.type != dns_rdatatype_nsec)
69 dns_rdataset_disassociate(&rdataset);
71 result = dns_rdatasetiter_next(rdsiter);
73 result = ISC_R_NOMORE;
75 if (result != ISC_R_NOMORE)
76 fatal("rdataset iteration failed");
77 dns_rdatasetiter_destroy(&rdsiter);
81 * Make sure there is no NSEC record for this node.
83 result = dns_db_deleterdataset(db, node, version,
84 dns_rdatatype_nsec, 0);
85 if (result == DNS_R_UNCHANGED)
86 result = ISC_R_SUCCESS;
87 check_result(result, "dns_db_deleterdataset");
93 static inline isc_result_t
94 next_active(dns_db_t *db, dns_dbversion_t *version, dns_dbiterator_t *dbiter,
95 dns_name_t *name, dns_dbnode_t **nodep)
102 result = dns_dbiterator_current(dbiter, nodep, name);
103 if (result == ISC_R_SUCCESS) {
104 active = active_node(db, version, *nodep);
106 dns_db_detachnode(db, nodep);
107 result = dns_dbiterator_next(dbiter);
110 } while (result == ISC_R_SUCCESS && !active);
116 nsecify(char *filename) {
119 dns_dbversion_t *wversion;
120 dns_dbnode_t *node, *nextnode;
122 dns_fixedname_t fname, fnextname;
123 dns_name_t *name, *nextname, *target;
126 dns_dbiterator_t *dbiter;
127 char newfilename[1024];
129 dns_fixedname_init(&fname);
130 name = dns_fixedname_name(&fname);
131 dns_fixedname_init(&fnextname);
132 nextname = dns_fixedname_name(&fnextname);
134 origintext = strrchr(filename, '/');
135 if (origintext == NULL)
136 origintext = filename;
138 origintext++; /* Skip '/'. */
139 len = strlen(origintext);
140 isc_buffer_init(&b, origintext, len);
141 isc_buffer_add(&b, len);
142 result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
143 check_result(result, "dns_name_fromtext()");
146 result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone,
147 dns_rdataclass_in, 0, NULL, &db);
148 check_result(result, "dns_db_create()");
149 result = dns_db_load(db, filename);
150 if (result == DNS_R_SEENINCLUDE)
151 result = ISC_R_SUCCESS;
152 check_result(result, "dns_db_load()");
154 result = dns_db_newversion(db, &wversion);
155 check_result(result, "dns_db_newversion()");
157 result = dns_db_createiterator(db, 0, &dbiter);
158 check_result(result, "dns_db_createiterator()");
159 result = dns_dbiterator_first(dbiter);
161 result = next_active(db, wversion, dbiter, name, &node);
162 while (result == ISC_R_SUCCESS) {
164 result = dns_dbiterator_next(dbiter);
165 if (result == ISC_R_SUCCESS)
166 result = next_active(db, wversion, dbiter, nextname,
168 if (result == ISC_R_SUCCESS)
170 else if (result == ISC_R_NOMORE)
171 target = dns_db_origin(db);
173 target = NULL; /* Make compiler happy. */
174 fatal("db iteration failed");
176 dns_nsec_build(db, wversion, node, target, 3600); /* XXX BEW */
177 dns_db_detachnode(db, &node);
180 if (result != ISC_R_NOMORE)
181 fatal("db iteration failed");
182 dns_dbiterator_destroy(&dbiter);
184 * XXXRTH For now, we don't increment the SOA serial.
186 dns_db_closeversion(db, &wversion, ISC_TRUE);
187 len = strlen(filename);
188 if (len + 4 + 1 > sizeof(newfilename))
189 fatal("filename too long");
190 sprintf(newfilename, "%s.new", filename);
191 result = dns_db_dump(db, NULL, newfilename);
192 check_result(result, "dns_db_dump");
197 main(int argc, char *argv[]) {
201 dns_result_register();
203 result = isc_mem_create(0, 0, &mctx);
204 check_result(result, "isc_mem_create()");
209 for (i = 0; i < argc; i++)
212 /* isc_mem_stats(mctx, stdout); */
213 isc_mem_destroy(&mctx);