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