1 /*
2  * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  *
8  * See the COPYRIGHT file distributed with this work for additional
9  * information regarding copyright ownership.
10  */
11 
12 /*
13  * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl.
14  *
15  * Permission to use, copy, modify, and distribute this software for any
16  * purpose with or without fee is hereby granted, provided that the
17  * above copyright notice and this permission notice appear in all
18  * copies.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
21  * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
23  * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
24  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
25  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
26  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
27  * USE OR PERFORMANCE OF THIS SOFTWARE.
28  *
29  * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was
30  * conceived and contributed by Rob Butler.
31  *
32  * Permission to use, copy, modify, and distribute this software for any
33  * purpose with or without fee is hereby granted, provided that the
34  * above copyright notice and this permission notice appear in all
35  * copies.
36  *
37  * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER
38  * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
39  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
40  * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
41  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
42  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
43  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
44  * USE OR PERFORMANCE OF THIS SOFTWARE.
45  */
46 
47 /*! \file dns/dlz.h */
48 
49 #ifndef DLZ_H
50 #define DLZ_H 1
51 
52 /*****
53 ***** Module Info
54 *****/
55 
56 /*
57  * DLZ Interface
58  *
59  * The DLZ interface allows zones to be looked up using a driver instead of
60  * Bind's default in memory zone table.
61  *
62  *
63  * Reliability:
64  *	No anticipated impact.
65  *
66  * Resources:
67  *
68  * Security:
69  *	No anticipated impact.
70  *
71  * Standards:
72  *	None.
73  */
74 
75 /*****
76 ***** Imports
77 *****/
78 
79 #include <stdbool.h>
80 
81 #include <isc/lang.h>
82 
83 #include <dns/clientinfo.h>
84 #include <dns/name.h>
85 #include <dns/types.h>
86 #include <dns/view.h>
87 
88 #include <dst/dst.h>
89 
90 ISC_LANG_BEGINDECLS
91 
92 /***
93  *** Types
94  ***/
95 
96 #define DNS_DLZ_MAGIC	   ISC_MAGIC('D', 'L', 'Z', 'D')
97 #define DNS_DLZ_VALID(dlz) ISC_MAGIC_VALID(dlz, DNS_DLZ_MAGIC)
98 
99 typedef isc_result_t (*dns_dlzallowzonexfr_t)(void *driverarg, void *dbdata,
100 					      isc_mem_t *	    mctx,
101 					      dns_rdataclass_t	    rdclass,
102 					      const dns_name_t *    name,
103 					      const isc_sockaddr_t *clientaddr,
104 					      dns_db_t **	    dbp);
105 
106 /*%<
107  * Method prototype.  Drivers implementing the DLZ interface MUST
108  * supply an allow zone transfer method.  This method is called when
109  * the DNS server is performing a zone transfer query.  The driver's
110  * method should return ISC_R_SUCCESS and a database pointer to the
111  * name server if the zone is supported by the database, and zone
112  * transfer is allowed.  If the view's transfer acl should be used,
113  * then the driver's method should return ISC_R_DEFAULT.  Otherwise,
114  * it should return ISC_R_NOTFOUND if the zone is not supported by
115  * the database, or ISC_R_NOPERM if zone transfers are not allowed.
116  * If an error occurs, the result code should indicate the type of error.
117  */
118 
119 typedef isc_result_t (*dns_dlzcreate_t)(isc_mem_t *mctx, const char *dlzname,
120 					unsigned int argc, char *argv[],
121 					void *driverarg, void **dbdata);
122 
123 /*%<
124  * Method prototype.  Drivers implementing the DLZ interface MUST
125  * supply a create method.  This method is called when the DNS server
126  * is starting up and creating drivers for use later.
127  */
128 
129 typedef void (*dns_dlzdestroy_t)(void *driverarg, void **dbdata);
130 
131 /*%<
132  * Method prototype.  Drivers implementing the DLZ interface MUST
133  * supply a destroy method.  This method is called when the DNS server
134  * is shutting down and no longer needs the driver.
135  */
136 
137 typedef isc_result_t (*dns_dlzfindzone_t)(void *driverarg, void *dbdata,
138 					  isc_mem_t *		   mctx,
139 					  dns_rdataclass_t	   rdclass,
140 					  const dns_name_t *	   name,
141 					  dns_clientinfomethods_t *methods,
142 					  dns_clientinfo_t *	   clientinfo,
143 					  dns_db_t **		   dbp);
144 
145 /*%<
146  * Method prototype.  Drivers implementing the DLZ interface MUST
147  * supply a find zone method.  This method is called when the DNS
148  * server is performing a query.  The find zone method will be called
149  * with the longest possible name first, and continue to be called
150  * with successively shorter domain names, until any of the following
151  * occur:
152  *
153  * \li	1) a match is found, and the function returns (ISC_R_SUCCESS)
154  *
155  * \li	2) a problem occurs, and the functions returns anything other
156  *	   than (ISC_R_NOTFOUND)
157  * \li	3) we run out of domain name labels. I.E. we have tried the
158  *	   shortest domain name
159  * \li	4) the number of labels in the domain name is less than
160  *	   min_labels for dns_dlzfindzone
161  *
162  * The driver's find zone method should return ISC_R_SUCCESS and a
163  * database pointer to the name server if the zone is supported by the
164  * database.  Otherwise it will return ISC_R_NOTFOUND, and a null
165  * pointer if the zone is not supported.  If an error occurs it should
166  * return a result code indicating the type of error.
167  */
168 
169 typedef isc_result_t (*dns_dlzconfigure_t)(void *driverarg, void *dbdata,
170 					   dns_view_t * view,
171 					   dns_dlzdb_t *dlzdb);
172 /*%<
173  * Method prototype.  Drivers implementing the DLZ interface may
174  * optionally supply a configure method. If supplied, this will be
175  * called immediately after the create method is called. The driver
176  * may call configuration functions during the configure call
177  */
178 
179 typedef bool (*dns_dlzssumatch_t)(const dns_name_t *   signer,
180 				  const dns_name_t *   name,
181 				  const isc_netaddr_t *tcpaddr,
182 				  dns_rdatatype_t type, const dst_key_t *key,
183 				  void *driverarg, void *dbdata);
184 /*%<
185  * Method prototype.  Drivers implementing the DLZ interface may
186  * optionally supply a ssumatch method. If supplied, this will be
187  * called to authorize update requests
188  */
189 
190 /*% the methods supplied by a DLZ driver */
191 typedef struct dns_dlzmethods {
192 	dns_dlzcreate_t	      create;
193 	dns_dlzdestroy_t      destroy;
194 	dns_dlzfindzone_t     findzone;
195 	dns_dlzallowzonexfr_t allowzonexfr;
196 	dns_dlzconfigure_t    configure;
197 	dns_dlzssumatch_t     ssumatch;
198 } dns_dlzmethods_t;
199 
200 /*% information about a DLZ driver */
201 struct dns_dlzimplementation {
202 	const char *		name;
203 	const dns_dlzmethods_t *methods;
204 	isc_mem_t *		mctx;
205 	void *			driverarg;
206 	ISC_LINK(dns_dlzimplementation_t) link;
207 };
208 
209 typedef isc_result_t (*dlzconfigure_callback_t)(dns_view_t *, dns_dlzdb_t *,
210 						dns_zone_t *);
211 
212 /*% An instance of a DLZ driver */
213 struct dns_dlzdb {
214 	unsigned int		 magic;
215 	isc_mem_t *		 mctx;
216 	dns_dlzimplementation_t *implementation;
217 	void *			 dbdata;
218 	dlzconfigure_callback_t	 configure_callback;
219 	bool			 search;
220 	char *			 dlzname;
221 	ISC_LINK(dns_dlzdb_t) link;
222 	dns_ssutable_t *ssutable;
223 };
224 
225 /***
226  *** Method declarations
227  ***/
228 
229 isc_result_t
230 dns_dlzallowzonexfr(dns_view_t *view, const dns_name_t *name,
231 		    const isc_sockaddr_t *clientaddr, dns_db_t **dbp);
232 
233 /*%<
234  * This method is called when the DNS server is performing a zone
235  * transfer query.  It will call the DLZ driver's allow zone transfer
236  * method.
237  */
238 
239 isc_result_t
240 dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername,
241 	      unsigned int argc, char *argv[], dns_dlzdb_t **dbp);
242 
243 /*%<
244  * This method is called when the DNS server is starting up and
245  * creating drivers for use later.  It will search the DLZ driver list
246  * for 'drivername' and return a DLZ driver via dbp if a match is
247  * found.  If the DLZ driver supplies a create method, this function
248  * will call it.
249  */
250 
251 void
252 dns_dlzdestroy(dns_dlzdb_t **dbp);
253 
254 /*%<
255  * This method is called when the DNS server is shutting down and no
256  * longer needs the driver.  If the DLZ driver supplies a destroy
257  * methods, this function will call it.
258  */
259 
260 isc_result_t
261 dns_dlzregister(const char *drivername, const dns_dlzmethods_t *methods,
262 		void *driverarg, isc_mem_t *mctx,
263 		dns_dlzimplementation_t **dlzimp);
264 
265 /*%<
266  * Register a dynamically loadable zones (DLZ) driver for the database
267  * type 'drivername', implemented by the functions in '*methods'.
268  *
269  * dlzimp must point to a NULL dlz_implementation_t pointer.  That is,
270  * dlzimp != NULL && *dlzimp == NULL.  It will be assigned a value that
271  * will later be used to identify the driver when deregistering it.
272  */
273 
274 isc_result_t
275 dns_dlzstrtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp);
276 
277 /*%<
278  * This method is called when the name server is starting up to parse
279  * the DLZ driver command line from named.conf.  Basically it splits
280  * up a string into and argc / argv.  The primary difference of this
281  * method is items between braces { } are considered only 1 word.  for
282  * example the command line "this is { one grouped phrase } and this
283  * isn't" would be parsed into:
284  *
285  * \li	argv[0]: "this"
286  * \li	argv[1]: "is"
287  * \li	argv{2]: " one grouped phrase "
288  * \li	argv[3]: "and"
289  * \li	argv[4]: "this"
290  * \li	argv{5}: "isn't"
291  *
292  * braces should NOT be nested, more than one grouping in the command
293  * line is allowed.  Notice, argv[2] has an extra space at the
294  * beginning and end.  Extra spaces are not stripped between a
295  * grouping.  You can do so in your driver if needed, or be sure not
296  * to put extra spaces before / after the braces.
297  */
298 
299 void
300 dns_dlzunregister(dns_dlzimplementation_t **dlzimp);
301 
302 /*%<
303  * Removes the dlz driver from the list of registered dlz drivers.
304  * There must be no active dlz drivers of this type when this function
305  * is called.
306  */
307 
308 typedef isc_result_t
309 			dns_dlz_writeablezone_t(dns_view_t *view, dns_dlzdb_t *dlzdb,
310 						const char *zone_name);
311 dns_dlz_writeablezone_t dns_dlz_writeablezone;
312 /*%<
313  * creates a writeable DLZ zone. Must be called from within the
314  * configure() method of a DLZ driver.
315  */
316 
317 isc_result_t
318 dns_dlzconfigure(dns_view_t *view, dns_dlzdb_t *dlzdb,
319 		 dlzconfigure_callback_t callback);
320 /*%<
321  * call a DLZ drivers configure method, if supplied
322  */
323 
324 bool
325 dns_dlz_ssumatch(dns_dlzdb_t *dlzdatabase, const dns_name_t *signer,
326 		 const dns_name_t *name, const isc_netaddr_t *tcpaddr,
327 		 dns_rdatatype_t type, const dst_key_t *key);
328 /*%<
329  * call a DLZ drivers ssumatch method, if supplied. Otherwise return false
330  */
331 
332 ISC_LANG_ENDDECLS
333 
334 #endif /* DLZ_H */
335