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/sdlz.h */ 50 51 #ifndef SDLZ_H 52 #define SDLZ_H 1 53 54 #include <inttypes.h> 55 #include <stdbool.h> 56 57 #include <dns/clientinfo.h> 58 #include <dns/dlz.h> 59 60 ISC_LANG_BEGINDECLS 61 62 #define DNS_SDLZFLAG_THREADSAFE 0x00000001U 63 #define DNS_SDLZFLAG_RELATIVEOWNER 0x00000002U 64 #define DNS_SDLZFLAG_RELATIVERDATA 0x00000004U 65 66 /* A simple DLZ database. */ 67 typedef struct dns_sdlz_db dns_sdlz_db_t; 68 69 /* A simple DLZ database lookup in progress. */ 70 typedef struct dns_sdlzlookup dns_sdlzlookup_t; 71 72 /* A simple DLZ database traversal in progress. */ 73 typedef struct dns_sdlzallnodes dns_sdlzallnodes_t; 74 75 typedef isc_result_t (*dns_sdlzallnodesfunc_t)(const char *zone, 76 void *driverarg, void *dbdata, 77 dns_sdlzallnodes_t *allnodes); 78 /*%< 79 * Method prototype. Drivers implementing the SDLZ interface may 80 * supply an all nodes method. This method is called when the DNS 81 * server is performing a zone transfer query, after the allow zone 82 * transfer method has been called. This method is only called if the 83 * allow zone transfer method returned ISC_R_SUCCESS. This method and 84 * the allow zone transfer method are both required for zone transfers 85 * to be supported. If the driver generates data dynamically (instead 86 * of searching in a database for it) it should not implement this 87 * function as a zone transfer would be meaningless. A SDLZ driver 88 * does not have to implement an all nodes method. 89 */ 90 91 typedef isc_result_t (*dns_sdlzallowzonexfr_t)(void *driverarg, void *dbdata, 92 const char *name, 93 const char *client); 94 95 /*%< 96 * Method prototype. Drivers implementing the SDLZ interface may 97 * supply an allow zone transfer method. This method is called when 98 * the DNS server is performing a zone transfer query, before the all 99 * nodes method can be called. This method and the all node method 100 * are both required for zone transfers to be supported. If the 101 * driver generates data dynamically (instead of searching in a 102 * database for it) it should not implement this function as a zone 103 * transfer would be meaningless. A SDLZ driver does not have to 104 * implement an allow zone transfer method. 105 * 106 * This method should return ISC_R_SUCCESS if the zone is supported by 107 * the database and a zone transfer is allowed for the specified 108 * client. If the zone is supported by the database, but zone 109 * transfers are not allowed for the specified client this method 110 * should return ISC_R_NOPERM.. Lastly the method should return 111 * ISC_R_NOTFOUND if the zone is not supported by the database. If an 112 * error occurs it should return a result code indicating the type of 113 * error. 114 */ 115 116 typedef isc_result_t (*dns_sdlzauthorityfunc_t)(const char *zone, 117 void *driverarg, void *dbdata, 118 dns_sdlzlookup_t *lookup); 119 120 /*%< 121 * Method prototype. Drivers implementing the SDLZ interface may 122 * supply an authority method. This method is called when the DNS 123 * server is performing a query, after both the find zone and lookup 124 * methods have been called. This method is required if the lookup 125 * function does not supply authority information for the dns 126 * record. A SDLZ driver does not have to implement an authority 127 * method. 128 */ 129 130 typedef isc_result_t (*dns_sdlzcreate_t)(const char *dlzname, unsigned int argc, 131 char *argv[], void *driverarg, 132 void **dbdata); 133 134 /*%< 135 * Method prototype. Drivers implementing the SDLZ interface may 136 * supply a create method. This method is called when the DNS server 137 * is starting up and creating drivers for use later. A SDLZ driver 138 * does not have to implement a create method. 139 */ 140 141 typedef void (*dns_sdlzdestroy_t)(void *driverarg, void *dbdata); 142 143 /*%< 144 * Method prototype. Drivers implementing the SDLZ interface may 145 * supply a destroy method. This method is called when the DNS server 146 * is shutting down and no longer needs the driver. A SDLZ driver does 147 * not have to implement a destroy method. 148 */ 149 150 typedef isc_result_t (*dns_sdlzfindzone_t)(void *driverarg, void *dbdata, 151 const char *name, 152 dns_clientinfomethods_t *methods, 153 dns_clientinfo_t *clientinfo); 154 /*%< 155 * Method prototype. Drivers implementing the SDLZ interface MUST 156 * supply a find zone method. This method is called when the DNS 157 * server is performing a query to to determine if 'name' is a 158 * supported dns zone. The find zone method will be called with the 159 * longest possible name first, and continue to be called with 160 * successively shorter domain names, until any of the following 161 * occur: 162 * 163 * \li 1) the function returns (ISC_R_SUCCESS) indicating a zone name 164 * match. 165 * 166 * \li 2) a problem occurs, and the functions returns anything other than 167 * (ISC_R_NOTFOUND) 168 * 169 * \li 3) we run out of domain name labels. I.E. we have tried the 170 * shortest domain name 171 * 172 * \li 4) the number of labels in the domain name is less than min_labels 173 * for dns_dlzfindzone 174 * 175 * The driver's find zone method should return ISC_R_SUCCESS if the 176 * zone is supported by the database. Otherwise it should return 177 * ISC_R_NOTFOUND, if the zone is not supported. If an error occurs 178 * it should return a result code indicating the type of error. 179 */ 180 181 typedef isc_result_t (*dns_sdlzlookupfunc_t)(const char *zone, const char *name, 182 void *driverarg, void *dbdata, 183 dns_sdlzlookup_t *lookup, 184 dns_clientinfomethods_t *methods, 185 dns_clientinfo_t *clientinfo); 186 187 /*%< 188 * Method prototype. Drivers implementing the SDLZ interface MUST 189 * supply a lookup method. This method is called when the 190 * DNS server is performing a query, after the find zone and before any 191 * other methods have been called. This function returns DNS record 192 * information using the dns_sdlz_putrr and dns_sdlz_putsoa functions. 193 * If this function supplies authority information for the DNS record 194 * the authority method is not required. If it does not, the 195 * authority function is required. 196 * 197 * The 'methods' and 'clientinfo' args allow an SDLZ driver to retrieve 198 * information about the querying client (such as source IP address) 199 * from the caller. 200 */ 201 202 typedef isc_result_t (*dns_sdlznewversion_t)(const char *zone, void *driverarg, 203 void *dbdata, void **versionp); 204 /*%< 205 * Method prototype. Drivers implementing the SDLZ interface may 206 * supply a newversion method. This method is called to start a 207 * write transaction on a zone and should only be implemented by 208 * writeable backends. 209 * When implemented, the driver should create a new transaction, and 210 * fill *versionp with a pointer to the transaction state. The 211 * closeversion function will be called to close the transaction. 212 */ 213 214 typedef void (*dns_sdlzcloseversion_t)(const char *zone, bool commit, 215 void *driverarg, void *dbdata, 216 void **versionp); 217 /*%< 218 * Method prototype. Drivers implementing the SDLZ interface must 219 * supply a closeversion method if they supply a newversion method. 220 * When implemented, the driver should close the given transaction, 221 * committing changes if 'commit' is true. If 'commit' is not true 222 * then all changes should be discarded and the database rolled back. 223 * If the call is successful then *versionp should be set to NULL 224 */ 225 226 typedef isc_result_t (*dns_sdlzconfigure_t)(dns_view_t *view, 227 dns_dlzdb_t *dlzdb, void *driverarg, 228 void *dbdata); 229 /*%< 230 * Method prototype. Drivers implementing the SDLZ interface may 231 * supply a configure method. When supplied, it will be called 232 * immediately after the create method to give the driver a chance 233 * to configure writeable zones 234 */ 235 236 typedef bool (*dns_sdlzssumatch_t)(const char *signer, const char *name, 237 const char *tcpaddr, const char *type, 238 const char *key, uint32_t keydatalen, 239 unsigned char *keydata, void *driverarg, 240 void *dbdata); 241 242 /*%< 243 * Method prototype. Drivers implementing the SDLZ interface may 244 * supply a ssumatch method. If supplied, then ssumatch will be 245 * called to authorize any zone updates. The driver should return 246 * true to allow the update, and false to deny it. For a DLZ 247 * controlled zone, this is the only access control on updates. 248 */ 249 250 typedef isc_result_t (*dns_sdlzmodrdataset_t)(const char *name, 251 const char *rdatastr, 252 void *driverarg, void *dbdata, 253 void *version); 254 /*%< 255 * Method prototype. Drivers implementing the SDLZ interface may 256 * supply addrdataset and subtractrdataset methods. If supplied, then these 257 * will be called when rdatasets are added/subtracted during 258 * updates. The version parameter comes from a call to the sdlz 259 * newversion() method from the driver. The rdataset parameter is a 260 * linearise string representation of the rdataset change. The format 261 * is the same as used by dig when displaying records. The fields are 262 * tab delimited. 263 */ 264 265 typedef isc_result_t (*dns_sdlzdelrdataset_t)(const char *name, 266 const char *type, void *driverarg, 267 void *dbdata, void *version); 268 /*%< 269 * Method prototype. Drivers implementing the SDLZ interface may 270 * supply a delrdataset method. If supplied, then this 271 * function will be called when rdatasets are deleted during 272 * updates. The call should remove all rdatasets of the given type for 273 * the specified name. 274 */ 275 276 typedef struct dns_sdlzmethods { 277 dns_sdlzcreate_t create; 278 dns_sdlzdestroy_t destroy; 279 dns_sdlzfindzone_t findzone; 280 dns_sdlzlookupfunc_t lookup; 281 dns_sdlzauthorityfunc_t authority; 282 dns_sdlzallnodesfunc_t allnodes; 283 dns_sdlzallowzonexfr_t allowzonexfr; 284 dns_sdlznewversion_t newversion; 285 dns_sdlzcloseversion_t closeversion; 286 dns_sdlzconfigure_t configure; 287 dns_sdlzssumatch_t ssumatch; 288 dns_sdlzmodrdataset_t addrdataset; 289 dns_sdlzmodrdataset_t subtractrdataset; 290 dns_sdlzdelrdataset_t delrdataset; 291 } dns_sdlzmethods_t; 292 293 isc_result_t 294 dns_sdlzregister(const char *drivername, const dns_sdlzmethods_t *methods, 295 void *driverarg, unsigned int flags, isc_mem_t *mctx, 296 dns_sdlzimplementation_t **sdlzimp); 297 /*%< 298 * Register a dynamically loadable zones (dlz) driver for the database 299 * type 'drivername', implemented by the functions in '*methods'. 300 * 301 * sdlzimp must point to a NULL dns_sdlzimplementation_t pointer. 302 * That is, sdlzimp != NULL && *sdlzimp == NULL. It will be assigned 303 * a value that will later be used to identify the driver when 304 * deregistering it. 305 */ 306 307 void 308 dns_sdlzunregister(dns_sdlzimplementation_t **sdlzimp); 309 310 /*%< 311 * Removes the sdlz driver from the list of registered sdlz drivers. 312 * There must be no active sdlz drivers of this type when this 313 * function is called. 314 */ 315 316 typedef isc_result_t 317 dns_sdlz_putnamedrr_t(dns_sdlzallnodes_t *allnodes, const char *name, 318 const char *type, dns_ttl_t ttl, const char *data); 319 dns_sdlz_putnamedrr_t dns_sdlz_putnamedrr; 320 321 /*%< 322 * Add a single resource record to the allnodes structure to be later 323 * parsed into a zone transfer response. 324 */ 325 326 typedef isc_result_t 327 dns_sdlz_putrr_t(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl, 328 const char *data); 329 dns_sdlz_putrr_t dns_sdlz_putrr; 330 /*%< 331 * Add a single resource record to the lookup structure to be later 332 * parsed into a query response. 333 */ 334 335 typedef isc_result_t 336 dns_sdlz_putsoa_t(dns_sdlzlookup_t *lookup, const char *mname, 337 const char *rname, uint32_t serial); 338 dns_sdlz_putsoa_t dns_sdlz_putsoa; 339 /*%< 340 * This function may optionally be called from the 'authority' 341 * callback to simplify construction of the SOA record for 'zone'. It 342 * will provide a SOA listing 'mname' as as the master server and 343 * 'rname' as the responsible person mailbox. It is the 344 * responsibility of the driver to increment the serial number between 345 * responses if necessary. All other SOA fields will have reasonable 346 * default values. 347 */ 348 349 typedef isc_result_t 350 dns_sdlz_setdb_t(dns_dlzdb_t *dlzdatabase, dns_rdataclass_t rdclass, 351 const dns_name_t *name, dns_db_t **dbp); 352 dns_sdlz_setdb_t dns_sdlz_setdb; 353 /*%< 354 * Create the database pointers for a writeable SDLZ zone 355 */ 356 357 ISC_LANG_ENDDECLS 358 359 #endif /* SDLZ_H */ 360