diff --git a/bind-96-dyndb.patch b/bind-96-dyndb.patch new file mode 100644 index 0000000..35397c9 --- /dev/null +++ b/bind-96-dyndb.patch @@ -0,0 +1,536 @@ +diff --git a/bin/named/main.c b/bin/named/main.c +index aa6575a..8030e3d 100644 +--- a/bin/named/main.c ++++ b/bin/named/main.c +@@ -44,6 +44,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -778,6 +779,8 @@ cleanup(void) { + dlz_drivers_clear(); + #endif + ++ dns_dynamic_db_cleanup(); ++ + dns_name_destroy(); + + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, +diff --git a/bin/named/server.c b/bin/named/server.c +index 31b2761..12ac597 100644 +--- a/bin/named/server.c ++++ b/bin/named/server.c +@@ -56,6 +56,7 @@ + #ifdef DLZ + #include + #endif ++#include + #include + #include + #include +@@ -849,6 +850,67 @@ configure_peer(const cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) { + } + + static isc_result_t ++configure_dynamic_db(const cfg_obj_t *dynamic_db, isc_mem_t *mctx, ++ dns_view_t *view) ++{ ++ isc_result_t result; ++ const cfg_obj_t *obj; ++ const cfg_obj_t *options; ++ const cfg_listelt_t *element; ++ const char *name; ++ const char *libname; ++ const char **argv = NULL; ++ unsigned int i; ++ unsigned int len; ++ ++ /* Get the name of the database. */ ++ obj = cfg_tuple_get(dynamic_db, "name"); ++ name = cfg_obj_asstring(obj); ++ ++ /* Get options. */ ++ options = cfg_tuple_get(dynamic_db, "options"); ++ ++ /* Get library name. */ ++ obj = NULL; ++ CHECK(cfg_map_get(options, "library", &obj)); ++ libname = cfg_obj_asstring(obj); ++ ++ /* Create a list of arguments. */ ++ obj = NULL; ++ CHECK(cfg_map_get(options, "arg", &obj)); ++ ++ len = cfg_list_length(obj, isc_boolean_false); ++ if (len == 0) { ++ argv = NULL; ++ } else { ++ len++; ++ argv = isc_mem_allocate(mctx, len * sizeof(const char *)); ++ if (argv == NULL) ++ CHECK(ISC_R_NOMEMORY); ++ } ++ for (element = cfg_list_first(obj), i = 0; ++ element != NULL; ++ element = cfg_list_next(element), i++) ++ { ++ REQUIRE(i < len); ++ ++ obj = cfg_listelt_value(element); ++ argv[i] = cfg_obj_asstring(obj); ++ } ++ REQUIRE(i < len); ++ argv[i] = NULL; ++ ++ CHECK(dns_dynamic_db_load(libname, name, mctx, argv, view)); ++ ++cleanup: ++ if (argv != NULL) ++ isc_mem_free(mctx, argv); ++ ++ return result; ++} ++ ++ ++static isc_result_t + disable_algorithms(const cfg_obj_t *disabled, dns_resolver_t *resolver) { + isc_result_t result; + const cfg_obj_t *algorithms; +@@ -999,6 +1061,7 @@ configure_view(dns_view_t *view, const cfg_obj_t *config, + unsigned int dlzargc; + char **dlzargv; + #endif ++ const cfg_obj_t *dynamic_db_list; + const cfg_obj_t *disabled; + const cfg_obj_t *obj; + const cfg_listelt_t *element; +@@ -1171,6 +1234,22 @@ configure_view(dns_view_t *view, const cfg_obj_t *config, + #endif + + /* ++ * Configure dynamic databases. ++ */ ++ dynamic_db_list = NULL; ++ if (voptions != NULL) ++ (void)cfg_map_get(voptions, "dynamic-db", &dynamic_db_list); ++ else ++ (void)cfg_map_get(config, "dynamic-db", &dynamic_db_list); ++ for (element = cfg_list_first(dynamic_db_list); ++ element != NULL; ++ element = cfg_list_next(element)) ++ { ++ obj = cfg_listelt_value(element); ++ CHECK(configure_dynamic_db(obj, mctx, view)); ++ } ++ ++ /* + * Configure the view's cache. Try to reuse an existing + * cache if possible, otherwise create a new cache. + * Note that the ADB is not preserved in either case. +diff --git a/lib/dns/Makefile.in b/lib/dns/Makefile.in +index ef5c12a..0f7abba 100644 +--- a/lib/dns/Makefile.in ++++ b/lib/dns/Makefile.in +@@ -57,7 +57,8 @@ DSTOBJS = @DST_EXTRA_OBJS@ \ + DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \ + cache.@O@ callbacks.@O@ compress.@O@ \ + db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \ +- dlz.@O@ dnssec.@O@ ds.@O@ forward.@O@ iptable.@O@ journal.@O@ \ ++ dlz.@O@ dnssec.@O@ ds.@O@ dynamic_db.@O@ forward.@O@ \ ++ iptable.@O@ journal.@O@ \ + keytable.@O@ lib.@O@ log.@O@ lookup.@O@ \ + master.@O@ masterdump.@O@ message.@O@ \ + name.@O@ ncache.@O@ nsec.@O@ nsec3.@O@ order.@O@ peer.@O@ portlist.@O@ \ +@@ -83,7 +84,7 @@ DSTSRCS = @DST_EXTRA_SRCS@ \ + DNSSRCS = acache.c acl.c adb.c byaddr.c \ + cache.c callbacks.c compress.c \ + db.c dbiterator.c dbtable.c diff.c dispatch.c \ +- dlz.c dnssec.c ds.c forward.c iptable.c journal.c \ ++ dlz.c dnssec.c ds.c dynamic_db.c forward.c iptable.c journal.c \ + keytable.c lib.c log.c lookup.c \ + master.c masterdump.c message.c \ + name.c ncache.c nsec.c nsec3.c order.c peer.c portlist.c \ +diff --git a/lib/dns/dynamic_db.c b/lib/dns/dynamic_db.c +new file mode 100644 +index 0000000..220db68 +--- /dev/null ++++ b/lib/dns/dynamic_db.c +@@ -0,0 +1,240 @@ ++/* ++ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") ++ * Copyright (C) 1996-2003 Internet Software Consortium. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ++ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ++ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ++ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ++ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ++ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++ * PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++ ++#if HAVE_DLFCN_H ++#include ++#endif ++ ++#define CHECK(op) \ ++ do { result = (op); \ ++ if (result != ISC_R_SUCCESS) goto cleanup; \ ++ } while (0) ++ ++ ++typedef isc_result_t (*register_func_t)(isc_mem_t *mctx, const char *name, ++ const char * const *argv, dns_view_t *view); ++typedef void (*destroy_func_t)(void); ++ ++typedef struct dyndb_implementation dyndb_implementation_t; ++ ++struct dyndb_implementation { ++ isc_mem_t *mctx; ++ void *handle; ++ register_func_t register_function; ++ destroy_func_t destroy_function; ++ LINK(dyndb_implementation_t) link; ++}; ++ ++/* List of implementations. Locked by dyndb_lock. */ ++static LIST(dyndb_implementation_t) dyndb_implementations; ++/* Locks dyndb_implementations. */ ++static isc_mutex_t dyndb_lock; ++static isc_once_t once = ISC_ONCE_INIT; ++ ++static void ++dyndb_initialize(void) { ++ RUNTIME_CHECK(isc_mutex_init(&dyndb_lock) == ISC_R_SUCCESS); ++ INIT_LIST(dyndb_implementations); ++} ++ ++ ++#if HAVE_DLFCN_H ++static isc_result_t ++load_symbol(void *handle, const char *symbol_name, void **symbolp) ++{ ++ const char *errmsg; ++ void *symbol; ++ ++ REQUIRE(handle != NULL); ++ REQUIRE(symbolp != NULL && *symbolp == NULL); ++ ++ symbol = dlsym(handle, symbol_name); ++ if (symbol == NULL) { ++ errmsg = dlerror(); ++ if (errmsg == NULL) ++ errmsg = "returned function pointer is NULL"; ++ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, ++ DNS_LOGMODULE_DYNDB, ISC_LOG_ERROR, ++ "failed to lookup symbol %s: %s", ++ symbol_name, errmsg); ++ return ISC_R_FAILURE; ++ } ++ dlerror(); ++ ++ *symbolp = symbol; ++ ++ return ISC_R_SUCCESS; ++} ++ ++static isc_result_t ++load_library(isc_mem_t *mctx, const char *filename, dyndb_implementation_t **impp) ++{ ++ isc_result_t result; ++ void *handle; ++ dyndb_implementation_t *imp; ++ register_func_t register_function = NULL; ++ destroy_func_t destroy_function = NULL; ++ ++ REQUIRE(impp != NULL && *impp == NULL); ++ ++ handle = dlopen(filename, RTLD_LAZY); ++ if (handle == NULL) { ++ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, ++ DNS_LOGMODULE_DYNDB, ISC_LOG_ERROR, ++ "failed to dynamically load driver '%s': %s", ++ filename, dlerror()); ++ result = ISC_R_FAILURE; ++ goto cleanup; ++ } ++ dlerror(); ++ ++ CHECK(load_symbol(handle, "dynamic_driver_init", ++ (void **)®ister_function)); ++ CHECK(load_symbol(handle, "dynamic_driver_destroy", ++ (void **)&destroy_function)); ++ ++ imp = isc_mem_get(mctx, sizeof(dyndb_implementation_t)); ++ if (imp == NULL) { ++ result = ISC_R_NOMEMORY; ++ goto cleanup; ++ } ++ ++ imp->mctx = NULL; ++ isc_mem_attach(mctx, &imp->mctx); ++ imp->handle = handle; ++ imp->register_function = register_function; ++ imp->destroy_function = destroy_function; ++ INIT_LINK(imp, link); ++ ++ *impp = imp; ++ ++ return ISC_R_SUCCESS; ++ ++cleanup: ++ if (handle != NULL) ++ dlclose(handle); ++ ++ return result; ++} ++ ++static void ++unload_library(dyndb_implementation_t **impp) ++{ ++ dyndb_implementation_t *imp; ++ ++ REQUIRE(impp != NULL && *impp != NULL); ++ ++ imp = *impp; ++ ++ dlclose(imp->handle); ++ ++ isc_mem_putanddetach(&imp->mctx, imp, sizeof(dyndb_implementation_t)); ++ ++ *impp = NULL; ++} ++ ++#else /* HAVE_DLFCN_H */ ++static isc_result_t ++load_library(isc_mem_t *mctx, const char *filename, dyndb_implementation_t **impp) ++{ ++ UNUSED(mctx); ++ UNUSED(filename); ++ UNUSED(impp); ++ ++ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DYNDB, ++ ISC_LOG_ERROR, ++ "dynamic database support is not implemented") ++ ++ return ISC_R_NOTIMPLEMENTED; ++} ++ ++static void ++unload_library(dyndb_implementation_t **impp) ++{ ++ dyndb_implementation_t *imp; ++ ++ REQUIRE(impp != NULL && *impp != NULL); ++ ++ imp = *impp; ++ ++ isc_mem_putanddetach(&imp->mctx, imp, sizeof(dyndb_implementation_t)); ++ ++ *impp = NULL; ++} ++#endif /* HAVE_DLFCN_H */ ++ ++isc_result_t ++dns_dynamic_db_load(const char *libname, const char *name, isc_mem_t *mctx, ++ const char * const *argv, dns_view_t *view) ++{ ++ isc_result_t result; ++ dyndb_implementation_t *implementation = NULL; ++ ++ RUNTIME_CHECK(isc_once_do(&once, dyndb_initialize) == ISC_R_SUCCESS); ++ ++ CHECK(load_library(mctx, libname, &implementation)); ++ CHECK(implementation->register_function(mctx, name, argv, view)); ++ ++ LOCK(&dyndb_lock); ++ APPEND(dyndb_implementations, implementation, link); ++ UNLOCK(&dyndb_lock); ++ ++ return ISC_R_SUCCESS; ++ ++cleanup: ++ if (implementation != NULL) ++ unload_library(&implementation); ++ ++ return result; ++} ++ ++isc_result_t ++dns_dynamic_db_cleanup(void) ++{ ++ dyndb_implementation_t *elem; ++ dyndb_implementation_t *next; ++ ++ RUNTIME_CHECK(isc_once_do(&once, dyndb_initialize) == ISC_R_SUCCESS); ++ ++ LOCK(&dyndb_lock); ++ elem = HEAD(dyndb_implementations); ++ while (elem != NULL) { ++ next = NEXT(elem, link); ++ UNLINK(dyndb_implementations, elem, link); ++ elem->destroy_function(); ++ unload_library(&elem); ++ elem = next; ++ } ++ UNLOCK(&dyndb_lock); ++ ++ isc_mutex_destroy(&dyndb_lock); ++} +diff --git a/lib/dns/include/dns/Makefile.in b/lib/dns/include/dns/Makefile.in +index e9e049e..27fdc45 100644 +--- a/lib/dns/include/dns/Makefile.in ++++ b/lib/dns/include/dns/Makefile.in +@@ -23,7 +23,7 @@ top_srcdir = @top_srcdir@ + + HEADERS = acl.h adb.h byaddr.h cache.h callbacks.h \ + cert.h compress.h \ +- db.h dbiterator.h dbtable.h diff.h dispatch.h dlz.h \ ++ db.h dbiterator.h dbtable.h diff.h dispatch.h dlz.h dynamic_db.h \ + dnssec.h ds.h events.h fixedname.h iptable.h journal.h keyflags.h \ + keytable.h keyvalues.h lib.h log.h master.h masterdump.h \ + message.h name.h ncache.h \ +diff --git a/lib/dns/include/dns/dynamic_db.h b/lib/dns/include/dns/dynamic_db.h +new file mode 100644 +index 0000000..151103f +--- /dev/null ++++ b/lib/dns/include/dns/dynamic_db.h +@@ -0,0 +1,31 @@ ++/* ++ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") ++ * Copyright (C) 1996-2003 Internet Software Consortium. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ++ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ++ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ++ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ++ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ++ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++ * PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++ ++#ifndef DYNAMIC_DB_H ++#define DYNAMIC_DB_H ++ ++#include ++#include ++ ++isc_result_t dns_dynamic_db_load(const char *libname, const char *name, ++ isc_mem_t *mctx, const char * const *argv, ++ dns_view_t *view); ++ ++isc_result_t dns_dynamic_db_cleanup(void); ++ ++#endif +diff --git a/lib/dns/include/dns/log.h b/lib/dns/include/dns/log.h +index 5adcedd..e171028 100644 +--- a/lib/dns/include/dns/log.h ++++ b/lib/dns/include/dns/log.h +@@ -73,6 +73,7 @@ LIBDNS_EXTERNAL_DATA extern isc_logmodule_t dns_modules[]; + #define DNS_LOGMODULE_HINTS (&dns_modules[24]) + #define DNS_LOGMODULE_ACACHE (&dns_modules[25]) + #define DNS_LOGMODULE_DLZ (&dns_modules[26]) ++#define DNS_LOGMODULE_DYNDB (&dns_modules[27]) + + ISC_LANG_BEGINDECLS + +diff --git a/lib/dns/log.c b/lib/dns/log.c +index 7551e15..b9864eb 100644 +--- a/lib/dns/log.c ++++ b/lib/dns/log.c +@@ -79,6 +79,7 @@ LIBDNS_EXTERNAL_DATA isc_logmodule_t dns_modules[] = { + { "dns/hints", 0 }, + { "dns/acache", 0 }, + { "dns/dlz", 0 }, ++ { "dns/dynamic_db", 0 }, + { NULL, 0 } + }; + +diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c +index 0610489..a1dba32 100644 +--- a/lib/isccfg/namedconf.c ++++ b/lib/isccfg/namedconf.c +@@ -78,6 +78,7 @@ static cfg_type_t cfg_type_controls; + static cfg_type_t cfg_type_controls_sockaddr; + static cfg_type_t cfg_type_destinationlist; + static cfg_type_t cfg_type_dialuptype; ++static cfg_type_t cfg_type_dynamic_db; + static cfg_type_t cfg_type_ixfrdifftype; + static cfg_type_t cfg_type_key; + static cfg_type_t cfg_type_logfile; +@@ -651,6 +652,7 @@ namedconf_or_view_clauses[] = { + { "zone", &cfg_type_zone, CFG_CLAUSEFLAG_MULTI }, + /* only 1 DLZ per view allowed */ + { "dlz", &cfg_type_dynamically_loadable_zones, 0 }, ++ { "dynamic-db", &cfg_type_dynamic_db, CFG_CLAUSEFLAG_MULTI }, + { "server", &cfg_type_server, CFG_CLAUSEFLAG_MULTI }, + { "trusted-keys", &cfg_type_trustedkeys, CFG_CLAUSEFLAG_MULTI }, + { NULL, NULL, 0 } +@@ -1365,6 +1367,40 @@ static cfg_type_t cfg_type_dialuptype = { + &cfg_rep_string, dialup_enums + }; + ++/* ++ * Dynamic database clauses. ++ */ ++ ++static cfg_clausedef_t ++dynamic_db_clauses[] = { ++ { "library", &cfg_type_qstring, 0 }, ++ { "arg", &cfg_type_qstring, CFG_CLAUSEFLAG_MULTI }, ++ { NULL, NULL, 0 } ++}; ++ ++static cfg_clausedef_t * ++dynamic_db_clausesets[] = { ++ dynamic_db_clauses, ++ NULL ++}; ++ ++static cfg_type_t cfg_type_dynamic_db_opts = { ++ "dynamically_loadable_zones_opts", cfg_parse_map, ++ cfg_print_map, cfg_doc_map, &cfg_rep_map, ++ dynamic_db_clausesets ++}; ++ ++static cfg_tuplefielddef_t dynamic_db_fields[] = { ++ { "name", &cfg_type_astring, 0 }, ++ { "options", &cfg_type_dynamic_db_opts, 0 }, ++ { NULL, NULL, 0 } ++}; ++ ++static cfg_type_t cfg_type_dynamic_db = { ++ "dynamic_db", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, ++ &cfg_rep_tuple, dynamic_db_fields ++}; ++ + static const char *notify_enums[] = { "explicit", "master-only", NULL }; + static isc_result_t + parse_notify_type(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { diff --git a/bind.spec b/bind.spec index b3b9986..7e0749d 100644 --- a/bind.spec +++ b/bind.spec @@ -18,7 +18,7 @@ Summary: The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) serv Name: bind License: ISC Version: 9.6.0 -Release: 0.5.1.%{PREVER}%{?dist} +Release: 0.6.%{PREVER}%{?dist} Epoch: 32 Url: http://www.isc.org/products/BIND/ Buildroot:%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -72,6 +72,7 @@ Patch62: bind-9.5-sdb-sqlite-bld.patch # needs inpection Patch17: bind-9.3.2b1-fix_sdb_ldap.patch +Patch104: bind-96-dyndb.patch # IDN paches Patch73: bind-9.5-libidn.patch @@ -185,6 +186,7 @@ sed -i 's/SUBDIRS\(.*\)/SUBDIRS\1 lib\/bind/' Makefile.in %patch5 -p1 -b .nonexec %patch10 -p1 -b .PIE %patch16 -p1 -b .redhat_doc +%patch104 -p1 -b .dyndb %if %{SDB} %patch101 -p1 -b .old-api mkdir bin/named-sdb @@ -599,6 +601,9 @@ rm -rf ${RPM_BUILD_ROOT} %ghost %{chroot_prefix}/etc/localtime %changelog +* Tue Dec 16 2008 Martin Nagy 32:9.6.0-0.6.rc1 +- add patch for dynamic loading of database backends + * Tue Dec 09 2008 Adam Tkac 32:9.6.0-0.5.1.rc1 - allow to reuse address for non-random query-source ports (#475120)