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