bool redirect, isc_buffer_t **text) {
isc_result_t result, tresult;
dns_zone_t *zone = NULL;
+ const cfg_obj_t *voptions = NULL;
#ifndef HAVE_LMDB
FILE *fp = NULL;
bool cleanup_config = false;
}
#endif /* HAVE_LMDB */
+ /* Check zone syntax */
+ if (cfg->vconfig != NULL) {
+ voptions = cfg_tuple_get(cfg->vconfig, "options");
+ }
+ result = isccfg_check_zoneconf(zoneobj, voptions, cfg->config, NULL,
+ NULL, NULL, NULL, view->name,
+ view->rdclass, cfg->actx, cfg->mctx);
+ if (result != ISC_R_SUCCESS) {
+ isc_loopmgr_resume(named_g_loopmgr);
+ goto cleanup;
+ }
+
/* Mark view unfrozen and configure zone */
dns_view_thaw(view);
result = configure_zone(cfg->config, zoneobj, cfg->vconfig, view,
bool redirect, isc_buffer_t **text) {
isc_result_t result, tresult;
dns_zone_t *zone = NULL;
+ const cfg_obj_t *voptions = NULL;
bool added;
#ifndef HAVE_LMDB
FILE *fp = NULL;
}
#endif /* HAVE_LMDB */
+ /* Check zone syntax */
+ if (cfg->vconfig != NULL) {
+ voptions = cfg_tuple_get(cfg->vconfig, "options");
+ }
+ result = isccfg_check_zoneconf(zoneobj, voptions, cfg->config, NULL,
+ NULL, NULL, NULL, view->name,
+ view->rdclass, cfg->actx, cfg->mctx);
+ if (result != ISC_R_SUCCESS) {
+ isc_loopmgr_resume(named_g_loopmgr);
+ goto cleanup;
+ }
+
/* Reconfigure the zone */
dns_view_thaw(view);
result = configure_zone(cfg->config, zoneobj, cfg->vconfig, view,
view, cfg->conf_parser, cfg->config,
dns_zone_getorigin(zone), NULL);
} else {
- const cfg_obj_t *voptions = cfg_tuple_get(cfg->vconfig,
- "options");
+ voptions = cfg_tuple_get(cfg->vconfig, "options");
result = delete_zoneconf(
view, cfg->conf_parser, voptions,
dns_zone_getorigin(zone), NULL);
/*
* Check send-report-channel. (Skip for zone level because we
- * have an additional check in check_zoneconf() for that.)
+ * have an additional check in isccfg_check_zoneconf() for that.)
*/
if (optlevel != optlevel_zone) {
obj = NULL;
return result;
}
-static isc_result_t
-check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
- const cfg_obj_t *config, isc_symtab_t *symtab,
- isc_symtab_t *files, isc_symtab_t *keydirs, isc_symtab_t *inview,
- const char *viewname, dns_rdataclass_t defclass,
- cfg_aclconfctx_t *actx, isc_mem_t *mctx) {
+isc_result_t
+isccfg_check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
+ const cfg_obj_t *config, isc_symtab_t *symtab,
+ isc_symtab_t *files, isc_symtab_t *keydirs,
+ isc_symtab_t *inview, const char *viewname,
+ dns_rdataclass_t defclass, cfg_aclconfctx_t *actx,
+ isc_mem_t *mctx) {
const char *znamestr = NULL;
const char *typestr = NULL;
const char *target = NULL;
cfg_obj_log(zconfig, ISC_LOG_ERROR,
"zone '%s': is not a valid name", znamestr);
result = ISC_R_FAILURE;
- } else {
+ } else if (symtab != NULL && inview != NULL) {
char namebuf[DNS_NAME_FORMATSIZE];
char classbuf[DNS_RDATACLASS_FORMATSIZE];
char *key = NULL;
* Make sure there is no other zone with the same key directory (from
* (key-directory or key-store/directory) and a different dnssec-policy.
*/
- if (zname != NULL) {
+ if (zname != NULL && keydirs != NULL) {
if (has_dnssecpolicy) {
tresult = check_keydir(config, zconfig, zname, kaspname,
dir, keydirs, mctx);
"zone '%s': missing 'file' entry",
znamestr);
result = tresult;
- } else if (tresult == ISC_R_SUCCESS &&
+ } else if (tresult == ISC_R_SUCCESS && files != NULL &&
(ztype == CFG_ZONE_SECONDARY ||
ztype == CFG_ZONE_MIRROR || ddns ||
has_dnssecpolicy))
if (tresult != ISC_R_SUCCESS) {
result = tresult;
}
- } else if (tresult == ISC_R_SUCCESS &&
+ } else if (tresult == ISC_R_SUCCESS && files != NULL &&
(ztype == CFG_ZONE_PRIMARY ||
ztype == CFG_ZONE_HINT))
{
CFG_LIST_FOREACH (zones, element) {
const cfg_obj_t *zone = cfg_listelt_value(element);
- tresult = check_zoneconf(zone, voptions, config, symtab, files,
- keydirs, inview, viewname, vclass,
- actx, mctx);
+ tresult = isccfg_check_zoneconf(zone, voptions, config, symtab,
+ files, keydirs, inview,
+ viewname, vclass, actx, mctx);
if (tresult != ISC_R_SUCCESS) {
result = ISC_R_FAILURE;
}
#include <isc/types.h>
+#include <isccfg/aclconf.h>
#include <isccfg/cfg.h>
#ifndef MAX_MIN_CACHE_TTL
/*%<
* Same as isccfg_check_namedconf(), but for a single 'key' statement.
*/
+
+isc_result_t
+isccfg_check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
+ const cfg_obj_t *config, isc_symtab_t *symtab,
+ isc_symtab_t *files, isc_symtab_t *keydirs,
+ isc_symtab_t *inview, const char *viewname,
+ dns_rdataclass_t defclass, cfg_aclconfctx_t *actx,
+ isc_mem_t *mctx);
+/*%<
+ * Check the syntactic validity of a zone statement, either in a
+ * named.conf file or in an "rndc addzone" or "rndc modzone" command.
+ *
+ * The various isc_symtab_t parameters are used when parsing named.conf
+ * to ensure that names are not duplicated within the file. When
+ * checking syntax of an "rndc addzone" command, these are passed
+ * as NULL and the duplication checks are skipped.
+ */