xref: /minix3/external/bsd/bind/dist/lib/dns/private.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: private.c,v 1.7 2015/07/08 17:28:59 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2009, 2011, 2012, 2015  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  *
6*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
7*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
8*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
9*00b67f09SDavid van Moolenbroek  *
10*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
17*00b67f09SDavid van Moolenbroek  */
18*00b67f09SDavid van Moolenbroek 
19*00b67f09SDavid van Moolenbroek /* Id */
20*00b67f09SDavid van Moolenbroek 
21*00b67f09SDavid van Moolenbroek #include "config.h"
22*00b67f09SDavid van Moolenbroek 
23*00b67f09SDavid van Moolenbroek #include <isc/result.h>
24*00b67f09SDavid van Moolenbroek #include <isc/string.h>
25*00b67f09SDavid van Moolenbroek #include <isc/types.h>
26*00b67f09SDavid van Moolenbroek #include <isc/base64.h>
27*00b67f09SDavid van Moolenbroek 
28*00b67f09SDavid van Moolenbroek #include <dns/nsec3.h>
29*00b67f09SDavid van Moolenbroek #include <dns/private.h>
30*00b67f09SDavid van Moolenbroek 
31*00b67f09SDavid van Moolenbroek /*
32*00b67f09SDavid van Moolenbroek  * We need to build the relevant chain if there exists a NSEC/NSEC3PARAM
33*00b67f09SDavid van Moolenbroek  * at the apex; normally only one or the other of NSEC/NSEC3PARAM will exist.
34*00b67f09SDavid van Moolenbroek  *
35*00b67f09SDavid van Moolenbroek  * If a NSEC3PARAM RRset exists then we will need to build a NSEC chain
36*00b67f09SDavid van Moolenbroek  * if all the NSEC3PARAM records (and associated chains) are slated for
37*00b67f09SDavid van Moolenbroek  * destruction and we have not been told to NOT build the NSEC chain.
38*00b67f09SDavid van Moolenbroek  *
39*00b67f09SDavid van Moolenbroek  * If the NSEC set exist then check to see if there is a request to create
40*00b67f09SDavid van Moolenbroek  * a NSEC3 chain.
41*00b67f09SDavid van Moolenbroek  *
42*00b67f09SDavid van Moolenbroek  * If neither NSEC/NSEC3PARAM RRsets exist at the origin and the private
43*00b67f09SDavid van Moolenbroek  * type exists then we need to examine it to determine if NSEC3 chain has
44*00b67f09SDavid van Moolenbroek  * been requested to be built otherwise a NSEC chain needs to be built.
45*00b67f09SDavid van Moolenbroek  */
46*00b67f09SDavid van Moolenbroek 
47*00b67f09SDavid van Moolenbroek #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
48*00b67f09SDavid van Moolenbroek #define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0)
49*00b67f09SDavid van Moolenbroek #define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0)
50*00b67f09SDavid van Moolenbroek #define NONSEC(x) (((x) & DNS_NSEC3FLAG_NONSEC) != 0)
51*00b67f09SDavid van Moolenbroek 
52*00b67f09SDavid van Moolenbroek #define CHECK(x) do {					\
53*00b67f09SDavid van Moolenbroek 			 result = (x);			\
54*00b67f09SDavid van Moolenbroek 			 if (result != ISC_R_SUCCESS)	\
55*00b67f09SDavid van Moolenbroek 				goto failure;		\
56*00b67f09SDavid van Moolenbroek 		 } while (/*CONSTCOND*/0)
57*00b67f09SDavid van Moolenbroek 
58*00b67f09SDavid van Moolenbroek /*
59*00b67f09SDavid van Moolenbroek  * Work out if 'param' should be ignored or not (i.e. it is in the process
60*00b67f09SDavid van Moolenbroek  * of being removed).
61*00b67f09SDavid van Moolenbroek  *
62*00b67f09SDavid van Moolenbroek  * Note: we 'belt-and-braces' here by also checking for a CREATE private
63*00b67f09SDavid van Moolenbroek  * record and keep the param record in this case.
64*00b67f09SDavid van Moolenbroek  */
65*00b67f09SDavid van Moolenbroek 
66*00b67f09SDavid van Moolenbroek static isc_boolean_t
ignore(dns_rdata_t * param,dns_rdataset_t * privateset)67*00b67f09SDavid van Moolenbroek ignore(dns_rdata_t *param, dns_rdataset_t *privateset) {
68*00b67f09SDavid van Moolenbroek 	isc_result_t result;
69*00b67f09SDavid van Moolenbroek 
70*00b67f09SDavid van Moolenbroek 	for (result = dns_rdataset_first(privateset);
71*00b67f09SDavid van Moolenbroek 	     result == ISC_R_SUCCESS;
72*00b67f09SDavid van Moolenbroek 	     result = dns_rdataset_next(privateset)) {
73*00b67f09SDavid van Moolenbroek 		unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
74*00b67f09SDavid van Moolenbroek 		dns_rdata_t private = DNS_RDATA_INIT;
75*00b67f09SDavid van Moolenbroek 		dns_rdata_t rdata = DNS_RDATA_INIT;
76*00b67f09SDavid van Moolenbroek 
77*00b67f09SDavid van Moolenbroek 		dns_rdataset_current(privateset, &private);
78*00b67f09SDavid van Moolenbroek 		if (!dns_nsec3param_fromprivate(&private, &rdata,
79*00b67f09SDavid van Moolenbroek 						buf, sizeof(buf)))
80*00b67f09SDavid van Moolenbroek 			continue;
81*00b67f09SDavid van Moolenbroek 		/*
82*00b67f09SDavid van Moolenbroek 		 * We are going to create a new NSEC3 chain so it
83*00b67f09SDavid van Moolenbroek 		 * doesn't matter if we are removing this one.
84*00b67f09SDavid van Moolenbroek 		 */
85*00b67f09SDavid van Moolenbroek 		if (CREATE(rdata.data[1]))
86*00b67f09SDavid van Moolenbroek 			return (ISC_FALSE);
87*00b67f09SDavid van Moolenbroek 		if (rdata.data[0] != param->data[0] ||
88*00b67f09SDavid van Moolenbroek 		    rdata.data[2] != param->data[2] ||
89*00b67f09SDavid van Moolenbroek 		    rdata.data[3] != param->data[3] ||
90*00b67f09SDavid van Moolenbroek 		    rdata.data[4] != param->data[4] ||
91*00b67f09SDavid van Moolenbroek 		    memcmp(&rdata.data[5], &param->data[5], param->data[4]))
92*00b67f09SDavid van Moolenbroek 			continue;
93*00b67f09SDavid van Moolenbroek 		/*
94*00b67f09SDavid van Moolenbroek 		 * The removal of this NSEC3 chain does NOT cause a
95*00b67f09SDavid van Moolenbroek 		 * NSEC chain to be created so we don't need to tell
96*00b67f09SDavid van Moolenbroek 		 * the caller that it will be removed.
97*00b67f09SDavid van Moolenbroek 		 */
98*00b67f09SDavid van Moolenbroek 		if (NONSEC(rdata.data[1]))
99*00b67f09SDavid van Moolenbroek 			return (ISC_FALSE);
100*00b67f09SDavid van Moolenbroek 		return (ISC_TRUE);
101*00b67f09SDavid van Moolenbroek 	}
102*00b67f09SDavid van Moolenbroek 	return (ISC_FALSE);
103*00b67f09SDavid van Moolenbroek }
104*00b67f09SDavid van Moolenbroek 
105*00b67f09SDavid van Moolenbroek isc_result_t
dns_private_chains(dns_db_t * db,dns_dbversion_t * ver,dns_rdatatype_t privatetype,isc_boolean_t * build_nsec,isc_boolean_t * build_nsec3)106*00b67f09SDavid van Moolenbroek dns_private_chains(dns_db_t *db, dns_dbversion_t *ver,
107*00b67f09SDavid van Moolenbroek 		   dns_rdatatype_t privatetype,
108*00b67f09SDavid van Moolenbroek 		   isc_boolean_t *build_nsec, isc_boolean_t *build_nsec3)
109*00b67f09SDavid van Moolenbroek {
110*00b67f09SDavid van Moolenbroek 	dns_dbnode_t *node;
111*00b67f09SDavid van Moolenbroek 	dns_rdataset_t nsecset, nsec3paramset, privateset;
112*00b67f09SDavid van Moolenbroek 	isc_boolean_t nsec3chain;
113*00b67f09SDavid van Moolenbroek 	isc_boolean_t signing;
114*00b67f09SDavid van Moolenbroek 	isc_result_t result;
115*00b67f09SDavid van Moolenbroek 	unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
116*00b67f09SDavid van Moolenbroek 	unsigned int count;
117*00b67f09SDavid van Moolenbroek 
118*00b67f09SDavid van Moolenbroek 	node = NULL;
119*00b67f09SDavid van Moolenbroek 	dns_rdataset_init(&nsecset);
120*00b67f09SDavid van Moolenbroek 	dns_rdataset_init(&nsec3paramset);
121*00b67f09SDavid van Moolenbroek 	dns_rdataset_init(&privateset);
122*00b67f09SDavid van Moolenbroek 
123*00b67f09SDavid van Moolenbroek 	CHECK(dns_db_getoriginnode(db, &node));
124*00b67f09SDavid van Moolenbroek 
125*00b67f09SDavid van Moolenbroek 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
126*00b67f09SDavid van Moolenbroek 				     0, (isc_stdtime_t) 0, &nsecset, NULL);
127*00b67f09SDavid van Moolenbroek 
128*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
129*00b67f09SDavid van Moolenbroek 		goto failure;
130*00b67f09SDavid van Moolenbroek 
131*00b67f09SDavid van Moolenbroek 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
132*00b67f09SDavid van Moolenbroek 				     0, (isc_stdtime_t) 0, &nsec3paramset,
133*00b67f09SDavid van Moolenbroek 				     NULL);
134*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
135*00b67f09SDavid van Moolenbroek 		goto failure;
136*00b67f09SDavid van Moolenbroek 
137*00b67f09SDavid van Moolenbroek 	if (dns_rdataset_isassociated(&nsecset) &&
138*00b67f09SDavid van Moolenbroek 	    dns_rdataset_isassociated(&nsec3paramset)) {
139*00b67f09SDavid van Moolenbroek 		if (build_nsec != NULL)
140*00b67f09SDavid van Moolenbroek 			*build_nsec = ISC_TRUE;
141*00b67f09SDavid van Moolenbroek 		if (build_nsec3 != NULL)
142*00b67f09SDavid van Moolenbroek 			*build_nsec3 = ISC_TRUE;
143*00b67f09SDavid van Moolenbroek 		goto success;
144*00b67f09SDavid van Moolenbroek 	}
145*00b67f09SDavid van Moolenbroek 
146*00b67f09SDavid van Moolenbroek 	if (privatetype != (dns_rdatatype_t)0) {
147*00b67f09SDavid van Moolenbroek 		result = dns_db_findrdataset(db, node, ver, privatetype,
148*00b67f09SDavid van Moolenbroek 					     0, (isc_stdtime_t) 0,
149*00b67f09SDavid van Moolenbroek 					     &privateset, NULL);
150*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
151*00b67f09SDavid van Moolenbroek 			goto failure;
152*00b67f09SDavid van Moolenbroek 	}
153*00b67f09SDavid van Moolenbroek 
154*00b67f09SDavid van Moolenbroek 	/*
155*00b67f09SDavid van Moolenbroek 	 * Look to see if we also need to be creating a NSEC3 chain.
156*00b67f09SDavid van Moolenbroek 	 */
157*00b67f09SDavid van Moolenbroek 	if (dns_rdataset_isassociated(&nsecset)) {
158*00b67f09SDavid van Moolenbroek 		if (build_nsec != NULL)
159*00b67f09SDavid van Moolenbroek 			*build_nsec = ISC_TRUE;
160*00b67f09SDavid van Moolenbroek 		if (build_nsec3 != NULL)
161*00b67f09SDavid van Moolenbroek 			*build_nsec3 = ISC_FALSE;
162*00b67f09SDavid van Moolenbroek 		if (!dns_rdataset_isassociated(&privateset))
163*00b67f09SDavid van Moolenbroek 			goto success;
164*00b67f09SDavid van Moolenbroek 		for (result = dns_rdataset_first(&privateset);
165*00b67f09SDavid van Moolenbroek 		     result == ISC_R_SUCCESS;
166*00b67f09SDavid van Moolenbroek 		     result = dns_rdataset_next(&privateset)) {
167*00b67f09SDavid van Moolenbroek 			dns_rdata_t private = DNS_RDATA_INIT;
168*00b67f09SDavid van Moolenbroek 			dns_rdata_t rdata = DNS_RDATA_INIT;
169*00b67f09SDavid van Moolenbroek 
170*00b67f09SDavid van Moolenbroek 			dns_rdataset_current(&privateset, &private);
171*00b67f09SDavid van Moolenbroek 			if (!dns_nsec3param_fromprivate(&private, &rdata,
172*00b67f09SDavid van Moolenbroek 							buf, sizeof(buf)))
173*00b67f09SDavid van Moolenbroek 				continue;
174*00b67f09SDavid van Moolenbroek 			if (REMOVE(rdata.data[1]))
175*00b67f09SDavid van Moolenbroek 				continue;
176*00b67f09SDavid van Moolenbroek 			if (build_nsec3 != NULL)
177*00b67f09SDavid van Moolenbroek 				*build_nsec3 = ISC_TRUE;
178*00b67f09SDavid van Moolenbroek 			break;
179*00b67f09SDavid van Moolenbroek 		}
180*00b67f09SDavid van Moolenbroek 		goto success;
181*00b67f09SDavid van Moolenbroek 	}
182*00b67f09SDavid van Moolenbroek 
183*00b67f09SDavid van Moolenbroek 	if (dns_rdataset_isassociated(&nsec3paramset)) {
184*00b67f09SDavid van Moolenbroek 		if (build_nsec3 != NULL)
185*00b67f09SDavid van Moolenbroek 			*build_nsec3 = ISC_TRUE;
186*00b67f09SDavid van Moolenbroek 		if (build_nsec != NULL)
187*00b67f09SDavid van Moolenbroek 			*build_nsec = ISC_FALSE;
188*00b67f09SDavid van Moolenbroek 		if (!dns_rdataset_isassociated(&privateset))
189*00b67f09SDavid van Moolenbroek 			goto success;
190*00b67f09SDavid van Moolenbroek 		/*
191*00b67f09SDavid van Moolenbroek 		 * If we are in the process of building a new NSEC3 chain
192*00b67f09SDavid van Moolenbroek 		 * then we don't need to build a NSEC chain.
193*00b67f09SDavid van Moolenbroek 		 */
194*00b67f09SDavid van Moolenbroek 		for (result = dns_rdataset_first(&privateset);
195*00b67f09SDavid van Moolenbroek 		     result == ISC_R_SUCCESS;
196*00b67f09SDavid van Moolenbroek 		     result = dns_rdataset_next(&privateset)) {
197*00b67f09SDavid van Moolenbroek 			dns_rdata_t private = DNS_RDATA_INIT;
198*00b67f09SDavid van Moolenbroek 			dns_rdata_t rdata = DNS_RDATA_INIT;
199*00b67f09SDavid van Moolenbroek 
200*00b67f09SDavid van Moolenbroek 			dns_rdataset_current(&privateset, &private);
201*00b67f09SDavid van Moolenbroek 			if (!dns_nsec3param_fromprivate(&private, &rdata,
202*00b67f09SDavid van Moolenbroek 							buf, sizeof(buf)))
203*00b67f09SDavid van Moolenbroek 				continue;
204*00b67f09SDavid van Moolenbroek 			if (CREATE(rdata.data[1]))
205*00b67f09SDavid van Moolenbroek 				goto success;
206*00b67f09SDavid van Moolenbroek 		}
207*00b67f09SDavid van Moolenbroek 
208*00b67f09SDavid van Moolenbroek 		/*
209*00b67f09SDavid van Moolenbroek 		 * Check to see if there will be a active NSEC3CHAIN once
210*00b67f09SDavid van Moolenbroek 		 * the changes queued complete.
211*00b67f09SDavid van Moolenbroek 		 */
212*00b67f09SDavid van Moolenbroek 		count = 0;
213*00b67f09SDavid van Moolenbroek 		for (result = dns_rdataset_first(&nsec3paramset);
214*00b67f09SDavid van Moolenbroek 		     result == ISC_R_SUCCESS;
215*00b67f09SDavid van Moolenbroek 		     result = dns_rdataset_next(&nsec3paramset)) {
216*00b67f09SDavid van Moolenbroek 			dns_rdata_t rdata = DNS_RDATA_INIT;
217*00b67f09SDavid van Moolenbroek 
218*00b67f09SDavid van Moolenbroek 			/*
219*00b67f09SDavid van Moolenbroek 			 * If there is more that one NSEC3 chain present then
220*00b67f09SDavid van Moolenbroek 			 * we don't need to construct a NSEC chain.
221*00b67f09SDavid van Moolenbroek 			 */
222*00b67f09SDavid van Moolenbroek 			if (++count > 1)
223*00b67f09SDavid van Moolenbroek 				goto success;
224*00b67f09SDavid van Moolenbroek 			dns_rdataset_current(&nsec3paramset, &rdata);
225*00b67f09SDavid van Moolenbroek 			if (ignore(&rdata, &privateset))
226*00b67f09SDavid van Moolenbroek 				continue;
227*00b67f09SDavid van Moolenbroek 			/*
228*00b67f09SDavid van Moolenbroek 			 * We still have a good NSEC3 chain or we are
229*00b67f09SDavid van Moolenbroek 			 * not creating a NSEC chain as NONSEC is set.
230*00b67f09SDavid van Moolenbroek 			 */
231*00b67f09SDavid van Moolenbroek 			goto success;
232*00b67f09SDavid van Moolenbroek 		}
233*00b67f09SDavid van Moolenbroek 
234*00b67f09SDavid van Moolenbroek 		/*
235*00b67f09SDavid van Moolenbroek 		 * The last NSEC3 chain is being removed and does not have
236*00b67f09SDavid van Moolenbroek 		 * have NONSEC set.
237*00b67f09SDavid van Moolenbroek 		 */
238*00b67f09SDavid van Moolenbroek 		if (build_nsec != NULL)
239*00b67f09SDavid van Moolenbroek 			*build_nsec = ISC_TRUE;
240*00b67f09SDavid van Moolenbroek 		goto success;
241*00b67f09SDavid van Moolenbroek 	}
242*00b67f09SDavid van Moolenbroek 
243*00b67f09SDavid van Moolenbroek 	if (build_nsec != NULL)
244*00b67f09SDavid van Moolenbroek 		*build_nsec = ISC_FALSE;
245*00b67f09SDavid van Moolenbroek 	if (build_nsec3 != NULL)
246*00b67f09SDavid van Moolenbroek 		*build_nsec3 = ISC_FALSE;
247*00b67f09SDavid van Moolenbroek 	if (!dns_rdataset_isassociated(&privateset))
248*00b67f09SDavid van Moolenbroek 		goto success;
249*00b67f09SDavid van Moolenbroek 
250*00b67f09SDavid van Moolenbroek 	signing = ISC_FALSE;
251*00b67f09SDavid van Moolenbroek 	nsec3chain = ISC_FALSE;
252*00b67f09SDavid van Moolenbroek 
253*00b67f09SDavid van Moolenbroek 	for (result = dns_rdataset_first(&privateset);
254*00b67f09SDavid van Moolenbroek 	     result == ISC_R_SUCCESS;
255*00b67f09SDavid van Moolenbroek 	     result = dns_rdataset_next(&privateset)) {
256*00b67f09SDavid van Moolenbroek 		dns_rdata_t rdata = DNS_RDATA_INIT;
257*00b67f09SDavid van Moolenbroek 		dns_rdata_t private = DNS_RDATA_INIT;
258*00b67f09SDavid van Moolenbroek 
259*00b67f09SDavid van Moolenbroek 		dns_rdataset_current(&privateset, &private);
260*00b67f09SDavid van Moolenbroek 		if (!dns_nsec3param_fromprivate(&private, &rdata,
261*00b67f09SDavid van Moolenbroek 						buf, sizeof(buf))) {
262*00b67f09SDavid van Moolenbroek 			/*
263*00b67f09SDavid van Moolenbroek 			 * Look for record that says we are signing the
264*00b67f09SDavid van Moolenbroek 			 * zone with a key.
265*00b67f09SDavid van Moolenbroek 			 */
266*00b67f09SDavid van Moolenbroek 			if (private.length == 5 && private.data[0] != 0 &&
267*00b67f09SDavid van Moolenbroek 			    private.data[3] == 0 && private.data[4] == 0)
268*00b67f09SDavid van Moolenbroek 				signing = ISC_TRUE;
269*00b67f09SDavid van Moolenbroek 		} else {
270*00b67f09SDavid van Moolenbroek 			if (CREATE(rdata.data[1]))
271*00b67f09SDavid van Moolenbroek 				nsec3chain = ISC_TRUE;
272*00b67f09SDavid van Moolenbroek 		}
273*00b67f09SDavid van Moolenbroek 	}
274*00b67f09SDavid van Moolenbroek 
275*00b67f09SDavid van Moolenbroek 	if (signing) {
276*00b67f09SDavid van Moolenbroek 		if (nsec3chain) {
277*00b67f09SDavid van Moolenbroek 			if (build_nsec3 != NULL)
278*00b67f09SDavid van Moolenbroek 				*build_nsec3 = ISC_TRUE;
279*00b67f09SDavid van Moolenbroek 		} else {
280*00b67f09SDavid van Moolenbroek 			if (build_nsec != NULL)
281*00b67f09SDavid van Moolenbroek 				*build_nsec = ISC_TRUE;
282*00b67f09SDavid van Moolenbroek 		}
283*00b67f09SDavid van Moolenbroek 	}
284*00b67f09SDavid van Moolenbroek 
285*00b67f09SDavid van Moolenbroek  success:
286*00b67f09SDavid van Moolenbroek 	result = ISC_R_SUCCESS;
287*00b67f09SDavid van Moolenbroek  failure:
288*00b67f09SDavid van Moolenbroek 	if (dns_rdataset_isassociated(&nsecset))
289*00b67f09SDavid van Moolenbroek 		dns_rdataset_disassociate(&nsecset);
290*00b67f09SDavid van Moolenbroek 	if (dns_rdataset_isassociated(&nsec3paramset))
291*00b67f09SDavid van Moolenbroek 		dns_rdataset_disassociate(&nsec3paramset);
292*00b67f09SDavid van Moolenbroek 	if (dns_rdataset_isassociated(&privateset))
293*00b67f09SDavid van Moolenbroek 		dns_rdataset_disassociate(&privateset);
294*00b67f09SDavid van Moolenbroek 	if (node != NULL)
295*00b67f09SDavid van Moolenbroek 		dns_db_detachnode(db, &node);
296*00b67f09SDavid van Moolenbroek 	return (result);
297*00b67f09SDavid van Moolenbroek }
298*00b67f09SDavid van Moolenbroek 
299*00b67f09SDavid van Moolenbroek isc_result_t
dns_private_totext(dns_rdata_t * private,isc_buffer_t * buf)300*00b67f09SDavid van Moolenbroek dns_private_totext(dns_rdata_t *private, isc_buffer_t *buf) {
301*00b67f09SDavid van Moolenbroek 	isc_result_t result;
302*00b67f09SDavid van Moolenbroek 
303*00b67f09SDavid van Moolenbroek 	if (private->length < 5)
304*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTFOUND);
305*00b67f09SDavid van Moolenbroek 
306*00b67f09SDavid van Moolenbroek 	if (private->data[0] == 0) {
307*00b67f09SDavid van Moolenbroek 		unsigned char nsec3buf[DNS_NSEC3PARAM_BUFFERSIZE];
308*00b67f09SDavid van Moolenbroek 		unsigned char newbuf[DNS_NSEC3PARAM_BUFFERSIZE];
309*00b67f09SDavid van Moolenbroek 		dns_rdata_t rdata = DNS_RDATA_INIT;
310*00b67f09SDavid van Moolenbroek 		dns_rdata_nsec3param_t nsec3param;
311*00b67f09SDavid van Moolenbroek 		isc_boolean_t remove, init, nonsec;
312*00b67f09SDavid van Moolenbroek 		isc_buffer_t b;
313*00b67f09SDavid van Moolenbroek 
314*00b67f09SDavid van Moolenbroek 		if (!dns_nsec3param_fromprivate(private, &rdata, nsec3buf,
315*00b67f09SDavid van Moolenbroek 						sizeof(nsec3buf)))
316*00b67f09SDavid van Moolenbroek 			CHECK(ISC_R_FAILURE);
317*00b67f09SDavid van Moolenbroek 
318*00b67f09SDavid van Moolenbroek 		CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
319*00b67f09SDavid van Moolenbroek 
320*00b67f09SDavid van Moolenbroek 		remove = ISC_TF((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0);
321*00b67f09SDavid van Moolenbroek 		init = ISC_TF((nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0);
322*00b67f09SDavid van Moolenbroek 		nonsec = ISC_TF((nsec3param.flags & DNS_NSEC3FLAG_NONSEC) != 0);
323*00b67f09SDavid van Moolenbroek 
324*00b67f09SDavid van Moolenbroek 		nsec3param.flags &= ~(DNS_NSEC3FLAG_CREATE|
325*00b67f09SDavid van Moolenbroek 				      DNS_NSEC3FLAG_REMOVE|
326*00b67f09SDavid van Moolenbroek 				      DNS_NSEC3FLAG_INITIAL|
327*00b67f09SDavid van Moolenbroek 				      DNS_NSEC3FLAG_NONSEC);
328*00b67f09SDavid van Moolenbroek 
329*00b67f09SDavid van Moolenbroek 		if (init)
330*00b67f09SDavid van Moolenbroek 			isc_buffer_putstr(buf, "Pending NSEC3 chain ");
331*00b67f09SDavid van Moolenbroek 		else if (remove)
332*00b67f09SDavid van Moolenbroek 			isc_buffer_putstr(buf, "Removing NSEC3 chain ");
333*00b67f09SDavid van Moolenbroek 		else
334*00b67f09SDavid van Moolenbroek 			isc_buffer_putstr(buf, "Creating NSEC3 chain ");
335*00b67f09SDavid van Moolenbroek 
336*00b67f09SDavid van Moolenbroek 		dns_rdata_reset(&rdata);
337*00b67f09SDavid van Moolenbroek 		isc_buffer_init(&b, newbuf, sizeof(newbuf));
338*00b67f09SDavid van Moolenbroek 		CHECK(dns_rdata_fromstruct(&rdata, dns_rdataclass_in,
339*00b67f09SDavid van Moolenbroek 					   dns_rdatatype_nsec3param,
340*00b67f09SDavid van Moolenbroek 					   &nsec3param, &b));
341*00b67f09SDavid van Moolenbroek 
342*00b67f09SDavid van Moolenbroek 		CHECK(dns_rdata_totext(&rdata, NULL, buf));
343*00b67f09SDavid van Moolenbroek 
344*00b67f09SDavid van Moolenbroek 		if (remove && !nonsec)
345*00b67f09SDavid van Moolenbroek 			isc_buffer_putstr(buf, " / creating NSEC chain");
346*00b67f09SDavid van Moolenbroek 	} else if (private->length == 5) {
347*00b67f09SDavid van Moolenbroek 		unsigned char alg = private->data[0];
348*00b67f09SDavid van Moolenbroek 		dns_keytag_t keyid = (private->data[2] | private->data[1] << 8);
349*00b67f09SDavid van Moolenbroek 		char keybuf[BUFSIZ], algbuf[DNS_SECALG_FORMATSIZE];
350*00b67f09SDavid van Moolenbroek 		isc_boolean_t remove = ISC_TF(private->data[3] != 0);
351*00b67f09SDavid van Moolenbroek 		isc_boolean_t complete = ISC_TF(private->data[4] != 0);
352*00b67f09SDavid van Moolenbroek 
353*00b67f09SDavid van Moolenbroek 		if (remove && complete)
354*00b67f09SDavid van Moolenbroek 			isc_buffer_putstr(buf, "Done removing signatures for ");
355*00b67f09SDavid van Moolenbroek 		else if (remove)
356*00b67f09SDavid van Moolenbroek 			isc_buffer_putstr(buf, "Removing signatures for ");
357*00b67f09SDavid van Moolenbroek 		else if (complete)
358*00b67f09SDavid van Moolenbroek 			isc_buffer_putstr(buf, "Done signing with ");
359*00b67f09SDavid van Moolenbroek 		else
360*00b67f09SDavid van Moolenbroek 			isc_buffer_putstr(buf, "Signing with ");
361*00b67f09SDavid van Moolenbroek 
362*00b67f09SDavid van Moolenbroek 		dns_secalg_format(alg, algbuf, sizeof(algbuf));
363*00b67f09SDavid van Moolenbroek 		sprintf(keybuf, "key %d/%s", keyid, algbuf);
364*00b67f09SDavid van Moolenbroek 		isc_buffer_putstr(buf, keybuf);
365*00b67f09SDavid van Moolenbroek 	} else
366*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTFOUND);
367*00b67f09SDavid van Moolenbroek 
368*00b67f09SDavid van Moolenbroek 	isc_buffer_putuint8(buf, 0);
369*00b67f09SDavid van Moolenbroek 	result = ISC_R_SUCCESS;
370*00b67f09SDavid van Moolenbroek  failure:
371*00b67f09SDavid van Moolenbroek 	return (result);
372*00b67f09SDavid van Moolenbroek }
373