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