xref: /netbsd-src/external/mpl/bind/dist/bin/tests/system/dyndb/driver/instance.c (revision d16b7486a53dcb8072b60ec6fcb4373a2d0c27b7)
1 /*	$NetBSD: instance.c,v 1.5 2022/09/23 12:15:25 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * SPDX-License-Identifier: MPL-2.0 AND ISC
7  *
8  * This Source Code Form is subject to the terms of the Mozilla Public
9  * License, v. 2.0. If a copy of the MPL was not distributed with this
10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11  *
12  * See the COPYRIGHT file distributed with this work for additional
13  * information regarding copyright ownership.
14  */
15 
16 /*
17  * Copyright (C) 2009-2015 Red Hat
18  *
19  * Permission to use, copy, modify, and/or distribute this software for any
20  * purpose with or without fee is hereby granted, provided that the above
21  * copyright notice and this permission notice appear in all copies.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS" AND AUTHORS DISCLAIMS ALL WARRANTIES WITH
24  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
25  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
26  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
27  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
28  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29  * PERFORMANCE OF THIS SOFTWARE.
30  */
31 
32 /*
33  * Driver instance object.
34  *
35  * One instance is equivalent to dynamic-db section in named.conf.
36  * This module parses arguments and provide high-level operations
37  * instance init/zone load/instance destroy.
38  */
39 
40 #include "instance.h"
41 
42 #include <isc/task.h>
43 #include <isc/util.h>
44 
45 #include <dns/db.h>
46 #include <dns/dyndb.h>
47 #include <dns/fixedname.h>
48 #include <dns/name.h>
49 #include <dns/view.h>
50 #include <dns/zone.h>
51 
52 #include "db.h"
53 #include "log.h"
54 #include "util.h"
55 #include "zone.h"
56 
57 /*
58  * Parse parameters and convert them to zone names. Caller has to deallocate
59  * resulting DNS names.
60  *
61  * @param[in]  argv NULL-terminated string array of length 2 (excluding NULL)
62  * 		    Each string has to be a valid DNS name.
63  * @param[out] z1   Zone name from argv[0]
64  * @param[out] z2   Zone name from argv[1]
65  */
66 static isc_result_t
67 parse_params(isc_mem_t *mctx, int argc, char **argv, dns_name_t *z1,
68 	     dns_name_t *z2) {
69 	isc_result_t result;
70 	int i;
71 
72 	REQUIRE(argv != NULL);
73 	REQUIRE(z1 != NULL);
74 	REQUIRE(z2 != NULL);
75 
76 	for (i = 0; i < argc; i++) {
77 		log_info("param: '%s'", argv[i]);
78 	}
79 	log_info("number of params: %d", i);
80 
81 	if (argc != 2) {
82 		log_error("exactly two parameters "
83 			  "(absolute zone names) are required");
84 		result = ISC_R_FAILURE;
85 		goto cleanup;
86 	}
87 	result = dns_name_fromstring2(z1, argv[0], dns_rootname, 0, mctx);
88 	if (result != ISC_R_SUCCESS) {
89 		log_write(ISC_LOG_ERROR,
90 			  "parse_params: dns_name_fromstring2 -> %s",
91 			  isc_result_totext(result));
92 		goto cleanup;
93 	}
94 	result = dns_name_fromstring2(z2, argv[1], dns_rootname, 0, mctx);
95 	if (result != ISC_R_SUCCESS) {
96 		log_write(ISC_LOG_ERROR,
97 			  "parse_params: dns_name_fromstring2 -> %s",
98 			  isc_result_totext(result));
99 		goto cleanup;
100 	}
101 
102 	result = ISC_R_SUCCESS;
103 
104 cleanup:
105 	return (result);
106 }
107 
108 /*
109  * Initialize new driver instance. It will not create zones until
110  * load_sample_instance_zones() is called.
111  */
112 isc_result_t
113 new_sample_instance(isc_mem_t *mctx, const char *db_name, int argc, char **argv,
114 		    const dns_dyndbctx_t *dctx,
115 		    sample_instance_t **sample_instp) {
116 	isc_result_t result;
117 	sample_instance_t *inst = NULL;
118 
119 	REQUIRE(sample_instp != NULL && *sample_instp == NULL);
120 
121 	CHECKED_MEM_GET_PTR(mctx, inst);
122 	ZERO_PTR(inst);
123 	isc_mem_attach(mctx, &inst->mctx);
124 
125 	inst->db_name = isc_mem_strdup(mctx, db_name);
126 
127 	inst->zone1_name = dns_fixedname_initname(&inst->zone1_fn);
128 	inst->zone2_name = dns_fixedname_initname(&inst->zone2_fn);
129 
130 	result = parse_params(mctx, argc, argv, inst->zone1_name,
131 			      inst->zone2_name);
132 	if (result != ISC_R_SUCCESS) {
133 		log_write(ISC_LOG_ERROR,
134 			  "new_sample_instance: parse_params -> %s",
135 			  isc_result_totext(result));
136 		goto cleanup;
137 	}
138 
139 	dns_view_attach(dctx->view, &inst->view);
140 	dns_zonemgr_attach(dctx->zmgr, &inst->zmgr);
141 	isc_task_attach(dctx->task, &inst->task);
142 
143 	/* Register new DNS DB implementation. */
144 	result = dns_db_register(db_name, create_db, inst, mctx, &inst->db_imp);
145 	if (result != ISC_R_SUCCESS) {
146 		log_write(ISC_LOG_ERROR,
147 			  "new_sample_instance: dns_db_register -> %s",
148 			  isc_result_totext(result));
149 		goto cleanup;
150 	}
151 
152 	*sample_instp = inst;
153 	result = ISC_R_SUCCESS;
154 
155 cleanup:
156 	if (result != ISC_R_SUCCESS) {
157 		destroy_sample_instance(&inst);
158 	}
159 	return (result);
160 }
161 
162 /*
163  * Create empty zones, add fake SOA, NS, and A records, load fake zones
164  * and add them to inst->view.
165  */
166 isc_result_t
167 load_sample_instance_zones(sample_instance_t *inst) {
168 	isc_result_t result;
169 
170 	result = create_zone(inst, inst->zone1_name, &inst->zone1);
171 	if (result != ISC_R_SUCCESS) {
172 		log_write(ISC_LOG_ERROR,
173 			  "load_sample_instance_zones: create_zone -> %s",
174 			  isc_result_totext(result));
175 		goto cleanup;
176 	}
177 	result = activate_zone(inst, inst->zone1);
178 	if (result != ISC_R_SUCCESS) {
179 		log_write(ISC_LOG_ERROR,
180 			  "load_sample_instance_zones: activate_zone -> %s",
181 			  isc_result_totext(result));
182 		goto cleanup;
183 	}
184 
185 	result = create_zone(inst, inst->zone2_name, &inst->zone2);
186 	if (result != ISC_R_SUCCESS) {
187 		log_write(ISC_LOG_ERROR,
188 			  "load_sample_instance_zones: create_zone -> %s",
189 			  isc_result_totext(result));
190 		goto cleanup;
191 	}
192 	result = activate_zone(inst, inst->zone2);
193 	if (result != ISC_R_SUCCESS) {
194 		log_write(ISC_LOG_ERROR,
195 			  "load_sample_instance_zones: activate_zone -> %s",
196 			  isc_result_totext(result));
197 		goto cleanup;
198 	}
199 
200 cleanup:
201 	return (result);
202 }
203 
204 void
205 destroy_sample_instance(sample_instance_t **instp) {
206 	sample_instance_t *inst;
207 	REQUIRE(instp != NULL);
208 
209 	inst = *instp;
210 	*instp = NULL;
211 	if (inst == NULL) {
212 		return;
213 	}
214 
215 	if (inst->db_name != NULL) {
216 		isc_mem_free(inst->mctx, inst->db_name);
217 	}
218 	if (inst->zone1 != NULL) {
219 		dns_zone_detach(&inst->zone1);
220 	}
221 	if (inst->zone2 != NULL) {
222 		dns_zone_detach(&inst->zone2);
223 	}
224 	if (inst->db_imp != NULL) {
225 		dns_db_unregister(&inst->db_imp);
226 	}
227 
228 	dns_view_detach(&inst->view);
229 	dns_zonemgr_detach(&inst->zmgr);
230 	isc_task_detach(&inst->task);
231 
232 	MEM_PUT_AND_DETACH(inst);
233 }
234