xref: /netbsd-src/external/mpl/bind/dist/bin/tests/system/dyndb/driver/instance.c (revision 5dd36a3bc8bf2a9dec29ceb6349550414570c447)
1 /*	$NetBSD: instance.c,v 1.3 2019/01/09 16:55:02 christos Exp $	*/
2 
3 /*
4  * Driver instance object.
5  *
6  * One instance is equivalent to dynamic-db section in named.conf.
7  * This module parses arguments and provide high-level operations
8  * instance init/zone load/instance destroy.
9  *
10  * Copyright (C) 2008-2015  Red Hat ; see COPYRIGHT for license
11  */
12 
13 #include <config.h>
14 
15 #include <isc/task.h>
16 #include <isc/util.h>
17 
18 #include <dns/db.h>
19 #include <dns/dyndb.h>
20 #include <dns/fixedname.h>
21 #include <dns/name.h>
22 #include <dns/view.h>
23 #include <dns/zone.h>
24 
25 #include "db.h"
26 #include "util.h"
27 #include "instance.h"
28 #include "log.h"
29 #include "zone.h"
30 
31 /*
32  * Parse parameters and convert them to zone names. Caller has to deallocate
33  * resulting DNS names.
34  *
35  * @param[in]  argv NULL-terminated string array of length 2 (excluding NULL)
36  * 		    Each string has to be a valid DNS name.
37  * @param[out] z1   Zone name from argv[0]
38  * @param[out] z2   Zone name from argv[1]
39  */
40 static isc_result_t
41 parse_params(isc_mem_t *mctx, int argc, char **argv,
42 	     dns_name_t *z1, dns_name_t *z2)
43 {
44 	isc_result_t result;
45 	int i;
46 
47 	REQUIRE(argv != NULL);
48 	REQUIRE(z1 != NULL);
49 	REQUIRE(z2 != NULL);
50 
51 	for (i = 0; i < argc; i++) {
52 		log_info("param: '%s'", argv[i]);
53 	}
54 	log_info("number of params: %d", i);
55 
56 	if (argc != 2) {
57 		log_error("exactly two parameters "
58 			  "(absolute zone names) are required");
59 		result = ISC_R_FAILURE;
60 		goto cleanup;
61 	}
62 	result = dns_name_fromstring2(z1, argv[0], dns_rootname, 0, mctx);
63 	if (result != ISC_R_SUCCESS) {
64 		log_write(ISC_LOG_ERROR,
65 			 "parse_params: dns_name_fromstring2 -> %s",
66 			 isc_result_totext(result));
67 		goto cleanup;
68 	}
69 	result = dns_name_fromstring2(z2, argv[1], dns_rootname, 0, mctx);
70 	if (result != ISC_R_SUCCESS) {
71 		log_write(ISC_LOG_ERROR,
72 			 "parse_params: dns_name_fromstring2 -> %s",
73 			 isc_result_totext(result));
74 		goto cleanup;
75 	}
76 
77 	result = ISC_R_SUCCESS;
78 
79 cleanup:
80 	return (result);
81 }
82 
83 /*
84  * Initialize new driver instance. It will not create zones until
85  * load_sample_instance_zones() is called.
86  */
87 isc_result_t
88 new_sample_instance(isc_mem_t *mctx, const char *db_name,
89 		    int argc, char **argv, const dns_dyndbctx_t *dctx,
90 		    sample_instance_t **sample_instp)
91 {
92 	isc_result_t result;
93 	sample_instance_t *inst = NULL;
94 
95 	REQUIRE(sample_instp != NULL && *sample_instp == NULL);
96 
97 	CHECKED_MEM_GET_PTR(mctx, inst);
98 	ZERO_PTR(inst);
99 	isc_mem_attach(mctx, &inst->mctx);
100 
101 	inst->db_name = isc_mem_strdup(mctx, db_name);
102 	if (inst->db_name == NULL) {
103 		result = ISC_R_NOMEMORY;
104 		goto cleanup;
105 	}
106 
107 	inst->zone1_name = dns_fixedname_initname(&inst->zone1_fn);
108 	inst->zone2_name = dns_fixedname_initname(&inst->zone2_fn);
109 
110 	result = parse_params(mctx, argc, argv,
111 			      inst->zone1_name, inst->zone2_name);
112 	if (result != ISC_R_SUCCESS) {
113 		log_write(ISC_LOG_ERROR,
114 			 "new_sample_instance: parse_params -> %s",
115 			 isc_result_totext(result));
116 		goto cleanup;
117 	}
118 
119 	dns_view_attach(dctx->view, &inst->view);
120 	dns_zonemgr_attach(dctx->zmgr, &inst->zmgr);
121 	isc_task_attach(dctx->task, &inst->task);
122 
123 	/* Register new DNS DB implementation. */
124 	result = dns_db_register(db_name, create_db, inst, mctx, &inst->db_imp);
125 	if (result != ISC_R_SUCCESS) {
126 		log_write(ISC_LOG_ERROR,
127 			 "new_sample_instance: dns_db_register -> %s",
128 			 isc_result_totext(result));
129 		goto cleanup;
130 	}
131 
132 	*sample_instp = inst;
133 	result = ISC_R_SUCCESS;
134 
135 cleanup:
136 	if (result != ISC_R_SUCCESS)
137 		destroy_sample_instance(&inst);
138 	return (result);
139 }
140 
141 /*
142  * Create empty zones, add fake SOA, NS, and A records, load fake zones
143  * and add them to inst->view.
144  */
145 isc_result_t
146 load_sample_instance_zones(sample_instance_t *inst) {
147 	isc_result_t result;
148 
149 	result = create_zone(inst, inst->zone1_name, &inst->zone1);
150 	if (result != ISC_R_SUCCESS) {
151 		log_write(ISC_LOG_ERROR,
152 			 "load_sample_instance_zones: create_zone -> %s",
153 			 isc_result_totext(result));
154 		goto cleanup;
155 	}
156 	result = activate_zone(inst, inst->zone1);
157 	if (result != ISC_R_SUCCESS) {
158 		log_write(ISC_LOG_ERROR,
159 			 "load_sample_instance_zones: activate_zone -> %s",
160 			 isc_result_totext(result));
161 		goto cleanup;
162 	}
163 
164 	result = create_zone(inst, inst->zone2_name, &inst->zone2);
165 	if (result != ISC_R_SUCCESS) {
166 		log_write(ISC_LOG_ERROR,
167 			 "load_sample_instance_zones: create_zone -> %s",
168 			 isc_result_totext(result));
169 		goto cleanup;
170 	}
171 	result = activate_zone(inst, inst->zone2);
172 	if (result != ISC_R_SUCCESS) {
173 		log_write(ISC_LOG_ERROR,
174 			 "load_sample_instance_zones: activate_zone -> %s",
175 			 isc_result_totext(result));
176 		goto cleanup;
177 	}
178 
179 cleanup:
180 	return (result);
181 }
182 
183 void
184 destroy_sample_instance(sample_instance_t **instp) {
185 	sample_instance_t *inst;
186 	REQUIRE(instp != NULL);
187 
188 	inst = *instp;
189 	if (inst == NULL)
190 		return;
191 
192 	if (inst->db_name != NULL)
193 		isc_mem_free(inst->mctx, inst->db_name);
194 	if (inst->zone1 != NULL)
195 		dns_zone_detach(&inst->zone1);
196 	if (inst->zone2 != NULL)
197 		dns_zone_detach(&inst->zone2);
198 	if (inst->db_imp != NULL)
199 		dns_db_unregister(&inst->db_imp);
200 
201 	dns_view_detach(&inst->view);
202 	dns_zonemgr_detach(&inst->zmgr);
203 	isc_task_detach(&inst->task);
204 
205 	MEM_PUT_AND_DETACH(inst);
206 
207 	*instp = NULL;
208 }
209