mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-11 03:29:59 -04:00
store the zone configuration object in the zone
when configuring a zone, we can now save the zone's configuration object in the zone itself by calling dns_zone_setcfg(). this can then be used by "rndc showzone" to print the zone's configuration, which is simpler than searching for it using the new-zones configuration, and allows it to work even if "allow-new-zones" is disabled.
This commit is contained in:
parent
6de1d0dbc4
commit
0191ba5540
4 changed files with 59 additions and 187 deletions
|
|
@ -7546,7 +7546,7 @@ cleanup:
|
|||
return result;
|
||||
}
|
||||
|
||||
#else /* HAVE_LMDB */
|
||||
#else /* HAVE_LMDB */
|
||||
|
||||
static isc_result_t
|
||||
data_to_cfg(dns_view_t *view, MDB_val *key, MDB_val *data, isc_buffer_t **text,
|
||||
|
|
@ -7786,70 +7786,6 @@ configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
get_newzone_config(dns_view_t *view, const char *zonename,
|
||||
cfg_obj_t **zoneconfig) {
|
||||
isc_result_t result;
|
||||
int status;
|
||||
cfg_obj_t *zoneconf = NULL;
|
||||
isc_buffer_t *text = NULL;
|
||||
MDB_txn *txn = NULL;
|
||||
MDB_dbi dbi;
|
||||
MDB_val key, data;
|
||||
char zname[DNS_NAME_FORMATSIZE];
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *name;
|
||||
isc_buffer_t b;
|
||||
|
||||
INSIST(zoneconfig != NULL && *zoneconfig == NULL);
|
||||
|
||||
LOCK(&view->new_zone_lock);
|
||||
|
||||
CHECK(nzd_open(view, MDB_RDONLY, &txn, &dbi));
|
||||
|
||||
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
|
||||
ISC_LOG_INFO,
|
||||
"loading NZD config from '%s' "
|
||||
"for zone '%s'",
|
||||
view->new_zone_db, zonename);
|
||||
|
||||
/* Normalize zone name */
|
||||
isc_buffer_constinit(&b, zonename, strlen(zonename));
|
||||
isc_buffer_add(&b, strlen(zonename));
|
||||
name = dns_fixedname_initname(&fname);
|
||||
CHECK(dns_name_fromtext(name, &b, dns_rootname, DNS_NAME_DOWNCASE));
|
||||
dns_name_format(name, zname, sizeof(zname));
|
||||
|
||||
key.mv_data = zname;
|
||||
key.mv_size = strlen(zname);
|
||||
|
||||
status = mdb_get(txn, dbi, &key, &data);
|
||||
if (status != MDB_SUCCESS) {
|
||||
CHECK(ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
CHECK(data_to_cfg(view, &key, &data, &text, &zoneconf));
|
||||
|
||||
*zoneconfig = zoneconf;
|
||||
zoneconf = NULL;
|
||||
result = ISC_R_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
(void)nzd_close(&txn, false);
|
||||
|
||||
UNLOCK(&view->new_zone_lock);
|
||||
|
||||
if (zoneconf != NULL) {
|
||||
cfg_obj_detach(&zoneconf);
|
||||
}
|
||||
if (text != NULL) {
|
||||
isc_buffer_free(&text);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* HAVE_LMDB */
|
||||
|
||||
#define APPLY_CONFIGURATION_SUBROUTINE_LOG \
|
||||
|
|
@ -14045,72 +13981,6 @@ cleanup:
|
|||
return result;
|
||||
}
|
||||
|
||||
static const cfg_obj_t *
|
||||
find_name_in_list_from_map(const cfg_obj_t *config,
|
||||
const char *map_key_for_list, const char *name,
|
||||
bool redirect) {
|
||||
const cfg_obj_t *list = NULL;
|
||||
const cfg_obj_t *obj = NULL;
|
||||
dns_fixedname_t fixed1, fixed2;
|
||||
dns_name_t *name1 = NULL, *name2 = NULL;
|
||||
isc_result_t result;
|
||||
|
||||
if (strcmp(map_key_for_list, "zone") == 0) {
|
||||
name1 = dns_fixedname_initname(&fixed1);
|
||||
name2 = dns_fixedname_initname(&fixed2);
|
||||
result = dns_name_fromstring(name1, name, dns_rootname, 0,
|
||||
NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
cfg_map_get(config, map_key_for_list, &list);
|
||||
CFG_LIST_FOREACH(list, element) {
|
||||
const char *vname = NULL;
|
||||
|
||||
obj = cfg_listelt_value(element);
|
||||
INSIST(obj != NULL);
|
||||
vname = cfg_obj_asstring(cfg_tuple_get(obj, "name"));
|
||||
if (vname == NULL) {
|
||||
obj = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (name1 != NULL) {
|
||||
result = dns_name_fromstring(name2, vname, dns_rootname,
|
||||
0, NULL);
|
||||
if (result == ISC_R_SUCCESS &&
|
||||
dns_name_equal(name1, name2))
|
||||
{
|
||||
const cfg_obj_t *zoptions =
|
||||
cfg_tuple_get(obj, "options");
|
||||
const cfg_obj_t *typeobj = NULL;
|
||||
|
||||
if (zoptions != NULL) {
|
||||
const cfg_obj_t *toptions =
|
||||
named_zone_templateopts(
|
||||
config, zoptions);
|
||||
named_config_findopt(zoptions, toptions,
|
||||
"type", &typeobj);
|
||||
}
|
||||
if (redirect && typeobj != NULL &&
|
||||
strcasecmp(cfg_obj_asstring(typeobj),
|
||||
"redirect") == 0)
|
||||
{
|
||||
break;
|
||||
} else if (!redirect) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (strcasecmp(vname, name) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void
|
||||
emitzone(void *arg, const char *buf, int len) {
|
||||
ns_dzarg_t *dzarg = arg;
|
||||
|
|
@ -14130,16 +14000,9 @@ isc_result_t
|
|||
named_server_showzone(named_server_t *server, isc_lex_t *lex,
|
||||
isc_buffer_t **text) {
|
||||
isc_result_t result;
|
||||
const cfg_obj_t *vconfig = NULL, *zconfig = NULL;
|
||||
const cfg_obj_t *zconfig = NULL;
|
||||
char zonename[DNS_NAME_FORMATSIZE];
|
||||
const cfg_obj_t *map;
|
||||
dns_view_t *view = NULL;
|
||||
dns_zone_t *zone = NULL;
|
||||
ns_cfgctx_t *cfg = NULL;
|
||||
#ifdef HAVE_LMDB
|
||||
cfg_obj_t *nzconfig = NULL;
|
||||
#endif /* HAVE_LMDB */
|
||||
bool added, redirect;
|
||||
ns_dzarg_t dzarg;
|
||||
|
||||
REQUIRE(text != NULL);
|
||||
|
|
@ -14151,51 +14014,9 @@ named_server_showzone(named_server_t *server, isc_lex_t *lex,
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
redirect = dns_zone_gettype(zone) == dns_zone_redirect;
|
||||
added = dns_zone_getadded(zone);
|
||||
view = dns_zone_getview(zone);
|
||||
zconfig = dns_zone_getcfg(zone);
|
||||
dns_zone_detach(&zone);
|
||||
|
||||
cfg = (ns_cfgctx_t *)view->new_zone_config;
|
||||
if (cfg == NULL) {
|
||||
result = ISC_R_FAILURE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!added) {
|
||||
/* Find the view statement */
|
||||
vconfig = find_name_in_list_from_map(cfg->config, "view",
|
||||
view->name, false);
|
||||
|
||||
/* Find the zone statement */
|
||||
if (vconfig != NULL) {
|
||||
map = cfg_tuple_get(vconfig, "options");
|
||||
} else {
|
||||
map = cfg->config;
|
||||
}
|
||||
|
||||
zconfig = find_name_in_list_from_map(map, "zone", zonename,
|
||||
redirect);
|
||||
}
|
||||
|
||||
#ifndef HAVE_LMDB
|
||||
if (zconfig == NULL && cfg->nzf_config != NULL) {
|
||||
zconfig = find_name_in_list_from_map(cfg->nzf_config, "zone",
|
||||
zonename, redirect);
|
||||
}
|
||||
#else /* HAVE_LMDB */
|
||||
if (zconfig == NULL) {
|
||||
const cfg_obj_t *zlist = NULL;
|
||||
CHECK(get_newzone_config(view, zonename, &nzconfig));
|
||||
CHECK(cfg_map_get(nzconfig, "zone", &zlist));
|
||||
if (!cfg_obj_islist(zlist)) {
|
||||
CHECK(ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
zconfig = cfg_listelt_value(cfg_list_first(zlist));
|
||||
}
|
||||
#endif /* HAVE_LMDB */
|
||||
|
||||
if (zconfig == NULL) {
|
||||
CHECK(ISC_R_NOTFOUND);
|
||||
}
|
||||
|
|
@ -14212,11 +14033,6 @@ named_server_showzone(named_server_t *server, isc_lex_t *lex,
|
|||
result = ISC_R_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
#ifdef HAVE_LMDB
|
||||
if (nzconfig != NULL) {
|
||||
cfg_obj_detach(&nzconfig);
|
||||
}
|
||||
#endif /* HAVE_LMDB */
|
||||
if (isc_buffer_usedlength(*text) > 0) {
|
||||
(void)putnull(text);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -869,6 +869,12 @@ process_notifytype(dns_notifytype_t ntype, dns_zonetype_t ztype,
|
|||
return dns_notifytype_explicit;
|
||||
}
|
||||
|
||||
static void
|
||||
detach_cfg(void *arg) {
|
||||
cfg_obj_t *cfg = (cfg_obj_t *)arg;
|
||||
cfg_obj_detach(&cfg);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
||||
const cfg_obj_t *zconfig, cfg_aclconfctx_t *aclctx,
|
||||
|
|
@ -1908,6 +1914,11 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
|||
break;
|
||||
}
|
||||
|
||||
/* Save the configuration for later use */
|
||||
cfg_obj_t *cfg = UNCONST(zconfig);
|
||||
cfg_obj_ref(cfg);
|
||||
dns_zone_setcfg(zone, (void *)cfg, detach_cfg);
|
||||
|
||||
result = ISC_R_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
|
|
|
|||
|
|
@ -2777,6 +2777,25 @@ dns_zone_unloadplugins(dns_zone_t *zone);
|
|||
* \li 'zone' to be a valid zone.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setcfg(dns_zone_t *zone, void *cfg, void (*cfg_detach)(void *));
|
||||
/*%<
|
||||
* Set a pointer to the configuration object for 'zone', which can be
|
||||
* used later to dump the configuration status.
|
||||
*
|
||||
* Requires:
|
||||
* \li 'zone' to be a valid zone.
|
||||
*/
|
||||
void *
|
||||
dns_zone_getcfg(dns_zone_t *zone);
|
||||
/*%<
|
||||
* Return a pointer to the configuration object for 'zone', that was
|
||||
* previously set using _setcfg().
|
||||
*
|
||||
* Requires:
|
||||
* \li 'zone' to be a valid zone.
|
||||
*/
|
||||
|
||||
#if DNS_ZONE_TRACE
|
||||
#define dns_zone_ref(ptr) dns_zone__ref(ptr, __func__, __FILE__, __LINE__)
|
||||
#define dns_zone_unref(ptr) dns_zone__unref(ptr, __func__, __FILE__, __LINE__)
|
||||
|
|
|
|||
|
|
@ -538,6 +538,10 @@ struct dns_zone {
|
|||
void (*plugins_free)(isc_mem_t *, void **);
|
||||
void *hooktable;
|
||||
void (*hooktable_free)(isc_mem_t *, void **);
|
||||
|
||||
/* Configuration object */
|
||||
void *cfg;
|
||||
void (*cfg_detach)(void *);
|
||||
};
|
||||
|
||||
#define zonediff_init(z, d) \
|
||||
|
|
@ -15343,6 +15347,9 @@ zone_shutdown(void *arg) {
|
|||
dns_zonemgr_releasezone(zone->zmgr, zone);
|
||||
}
|
||||
|
||||
/* Detach the zone configuration pointer */
|
||||
dns_zone_setcfg(zone, NULL, NULL);
|
||||
|
||||
LOCK_ZONE(zone);
|
||||
INSIST(zone != zone->raw);
|
||||
|
||||
|
|
@ -24908,3 +24915,22 @@ dns_zone_unloadplugins(dns_zone_t *zone) {
|
|||
zone->plugins_free = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setcfg(dns_zone_t *zone, void *cfg, void (*cfg_detach)(void *)) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
if (zone->cfg != NULL && zone->cfg_detach != NULL) {
|
||||
zone->cfg_detach(zone->cfg);
|
||||
zone->cfg = NULL;
|
||||
}
|
||||
zone->cfg = cfg;
|
||||
zone->cfg_detach = cfg_detach;
|
||||
}
|
||||
|
||||
void *
|
||||
dns_zone_getcfg(dns_zone_t *zone) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
return zone->cfg;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue