/*% configure the zone */ static isc_result_t configure_zone(const char *vclass, const char *view, const cfg_obj_t *zconfig, const cfg_obj_t *vconfig, const cfg_obj_t *config, isc_mem_t *mctx) { int i = 0; isc_result_t result; const char *zclass; const char *zname; const char *zfile = NULL; const cfg_obj_t *maps[4]; const cfg_obj_t *mastersobj = NULL; const cfg_obj_t *inviewobj = NULL; const cfg_obj_t *zoptions = NULL; const cfg_obj_t *classobj = NULL; const cfg_obj_t *typeobj = NULL; const cfg_obj_t *fileobj = NULL; const cfg_obj_t *dlzobj = NULL; const cfg_obj_t *dbobj = NULL; const cfg_obj_t *obj = NULL; const cfg_obj_t *fmtobj = NULL; dns_masterformat_t masterformat; dns_ttl_t maxttl = 0; zone_options = DNS_ZONEOPT_CHECKNS | DNS_ZONEOPT_MANYERRORS; zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); classobj = cfg_tuple_get(zconfig, "class"); if (!cfg_obj_isstring(classobj)) zclass = vclass; else zclass = cfg_obj_asstring(classobj); zoptions = cfg_tuple_get(zconfig, "options"); maps[i++] = zoptions; if (vconfig != NULL) maps[i++] = cfg_tuple_get(vconfig, "options"); if (config != NULL) { cfg_map_get(config, "options", &obj); if (obj != NULL) maps[i++] = obj; } maps[i] = NULL; cfg_map_get(zoptions, "in-view", &inviewobj); if (inviewobj != NULL) return (ISC_R_SUCCESS); cfg_map_get(zoptions, "type", &typeobj); if (typeobj == NULL) return (ISC_R_FAILURE); /* * Skip checks when using an alternate data source. */ cfg_map_get(zoptions, "database", &dbobj); if (dbobj != NULL && strcmp("rbt", cfg_obj_asstring(dbobj)) != 0 && strcmp("rbt64", cfg_obj_asstring(dbobj)) != 0) return (ISC_R_SUCCESS); cfg_map_get(zoptions, "dlz", &dlzobj); if (dlzobj != NULL) return (ISC_R_SUCCESS); cfg_map_get(zoptions, "file", &fileobj); if (fileobj != NULL) zfile = cfg_obj_asstring(fileobj); /* * Check hints files for hint zones. * Skip loading checks for any type other than * master and redirect */ if (strcasecmp(cfg_obj_asstring(typeobj), "hint") == 0) return (configure_hint(zfile, zclass, mctx)); else if ((strcasecmp(cfg_obj_asstring(typeobj), "master") != 0) && (strcasecmp(cfg_obj_asstring(typeobj), "redirect") != 0)) return (ISC_R_SUCCESS); /* * Is the redirect zone configured as a slave? */ if (strcasecmp(cfg_obj_asstring(typeobj), "redirect") == 0) { cfg_map_get(zoptions, "masters", &mastersobj); if (mastersobj != NULL) return (ISC_R_SUCCESS); } if (zfile == NULL) return (ISC_R_FAILURE); obj = NULL; if (get_maps(maps, "check-dup-records", &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_CHECKDUPRR; zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { zone_options |= DNS_ZONEOPT_CHECKDUPRR; zone_options |= DNS_ZONEOPT_CHECKDUPRRFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options &= ~DNS_ZONEOPT_CHECKDUPRR; zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_CHECKDUPRR; zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; } obj = NULL; if (get_maps(maps, "check-mx", &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_CHECKMX; zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { zone_options |= DNS_ZONEOPT_CHECKMX; zone_options |= DNS_ZONEOPT_CHECKMXFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options &= ~DNS_ZONEOPT_CHECKMX; zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_CHECKMX; zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; } obj = NULL; if (get_maps(maps, "check-integrity", &obj)) { if (cfg_obj_asboolean(obj)) zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; else zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY; } else zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; obj = NULL; if (get_maps(maps, "check-mx-cname", &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_WARNMXCNAME; zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { zone_options &= ~DNS_ZONEOPT_WARNMXCNAME; zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options |= DNS_ZONEOPT_WARNMXCNAME; zone_options |= DNS_ZONEOPT_IGNOREMXCNAME; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_WARNMXCNAME; zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; } obj = NULL; if (get_maps(maps, "check-srv-cname", &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_WARNSRVCNAME; zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME; zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options |= DNS_ZONEOPT_WARNSRVCNAME; zone_options |= DNS_ZONEOPT_IGNORESRVCNAME; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_WARNSRVCNAME; zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; } obj = NULL; if (get_maps(maps, "check-sibling", &obj)) { if (cfg_obj_asboolean(obj)) zone_options |= DNS_ZONEOPT_CHECKSIBLING; else zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; } obj = NULL; if (get_maps(maps, "check-spf", &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_CHECKSPF; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options &= ~DNS_ZONEOPT_CHECKSPF; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_CHECKSPF; } obj = NULL; if (get_checknames(maps, &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_CHECKNAMES; zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { zone_options |= DNS_ZONEOPT_CHECKNAMES; zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options &= ~DNS_ZONEOPT_CHECKNAMES; zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_CHECKNAMES; zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; } masterformat = dns_masterformat_text; fmtobj = NULL; if (get_maps(maps, "masterfile-format", &fmtobj)) { const char *masterformatstr = cfg_obj_asstring(fmtobj); if (strcasecmp(masterformatstr, "text") == 0) masterformat = dns_masterformat_text; else if (strcasecmp(masterformatstr, "raw") == 0) masterformat = dns_masterformat_raw; else if (strcasecmp(masterformatstr, "map") == 0) masterformat = dns_masterformat_map; else INSIST(0); } obj = NULL; if (get_maps(maps, "max-zone-ttl", &obj)) { maxttl = cfg_obj_asuint32(obj); zone_options2 |= DNS_ZONEOPT2_CHECKTTL; } result = load_zone(mctx, zname, zfile, masterformat, zclass, maxttl, NULL); if (result != ISC_R_SUCCESS) fprintf(stderr, "%s/%s/%s: %s\n", view, zname, zclass, dns_result_totext(result)); return (result); }
/*% * Set up a logging channel according to the named.conf data * in 'cchan' and add it to 'lctx'. */ static isc_result_t channel_fromconf(const cfg_obj_t *channel, isc_logconfig_t *lctx) { isc_result_t result; isc_logdestination_t dest; unsigned int type; unsigned int flags = 0; int level; const char *channelname; const cfg_obj_t *fileobj = NULL; const cfg_obj_t *syslogobj = NULL; const cfg_obj_t *nullobj = NULL; const cfg_obj_t *stderrobj = NULL; const cfg_obj_t *severity = NULL; int i; channelname = cfg_obj_asstring(cfg_map_getname(channel)); (void)cfg_map_get(channel, "file", &fileobj); (void)cfg_map_get(channel, "syslog", &syslogobj); (void)cfg_map_get(channel, "null", &nullobj); (void)cfg_map_get(channel, "stderr", &stderrobj); i = 0; if (fileobj != NULL) i++; if (syslogobj != NULL) i++; if (nullobj != NULL) i++; if (stderrobj != NULL) i++; if (i != 1) { cfg_obj_log(channel, ns_g_lctx, ISC_LOG_ERROR, "channel '%s': exactly one of file, syslog, " "null, and stderr must be present", channelname); return (ISC_R_FAILURE); } type = ISC_LOG_TONULL; if (fileobj != NULL) { const cfg_obj_t *pathobj = cfg_tuple_get(fileobj, "file"); const cfg_obj_t *sizeobj = cfg_tuple_get(fileobj, "size"); const cfg_obj_t *versionsobj = cfg_tuple_get(fileobj, "versions"); isc_int32_t versions = ISC_LOG_ROLLNEVER; isc_offset_t size = 0; type = ISC_LOG_TOFILE; if (versionsobj != NULL && cfg_obj_isuint32(versionsobj)) versions = cfg_obj_asuint32(versionsobj); if (versionsobj != NULL && cfg_obj_isstring(versionsobj) && strcasecmp(cfg_obj_asstring(versionsobj), "unlimited") == 0) versions = ISC_LOG_ROLLINFINITE; if (sizeobj != NULL && cfg_obj_isuint64(sizeobj) && cfg_obj_asuint64(sizeobj) < ISC_OFFSET_MAXIMUM) size = (isc_offset_t)cfg_obj_asuint64(sizeobj); dest.file.stream = NULL; dest.file.name = cfg_obj_asstring(pathobj); dest.file.versions = versions; dest.file.maximum_size = size; } else if (syslogobj != NULL) { int facility = LOG_DAEMON; type = ISC_LOG_TOSYSLOG; if (cfg_obj_isstring(syslogobj)) { const char *facilitystr = cfg_obj_asstring(syslogobj); (void)isc_syslog_facilityfromstring(facilitystr, &facility); } dest.facility = facility; } else if (stderrobj != NULL) { type = ISC_LOG_TOFILEDESC; dest.file.stream = stderr; dest.file.name = NULL; dest.file.versions = ISC_LOG_ROLLNEVER; dest.file.maximum_size = 0; } /* * Munge flags. */ { const cfg_obj_t *printcat = NULL; const cfg_obj_t *printsev = NULL; const cfg_obj_t *printtime = NULL; (void)cfg_map_get(channel, "print-category", &printcat); (void)cfg_map_get(channel, "print-severity", &printsev); (void)cfg_map_get(channel, "print-time", &printtime); if (printcat != NULL && cfg_obj_asboolean(printcat)) flags |= ISC_LOG_PRINTCATEGORY; if (printtime != NULL && cfg_obj_asboolean(printtime)) flags |= ISC_LOG_PRINTTIME; if (printsev != NULL && cfg_obj_asboolean(printsev)) flags |= ISC_LOG_PRINTLEVEL; } level = ISC_LOG_INFO; if (cfg_map_get(channel, "severity", &severity) == ISC_R_SUCCESS) { if (cfg_obj_isstring(severity)) { const char *str = cfg_obj_asstring(severity); if (strcasecmp(str, "critical") == 0) level = ISC_LOG_CRITICAL; else if (strcasecmp(str, "error") == 0) level = ISC_LOG_ERROR; else if (strcasecmp(str, "warning") == 0) level = ISC_LOG_WARNING; else if (strcasecmp(str, "notice") == 0) level = ISC_LOG_NOTICE; else if (strcasecmp(str, "info") == 0) level = ISC_LOG_INFO; else if (strcasecmp(str, "dynamic") == 0) level = ISC_LOG_DYNAMIC; } else /* debug */ level = cfg_obj_asuint32(severity); } result = isc_log_createchannel(lctx, channelname, type, level, &dest, flags); if (result == ISC_R_SUCCESS && type == ISC_LOG_TOFILE) { FILE *fp; /* * Test to make sure that file is a plain file. * Fix defect #22771 */ result = isc_file_isplainfile(dest.file.name); if (result == ISC_R_SUCCESS || result == ISC_R_FILENOTFOUND) { /* * Test that the file can be opened, since * isc_log_open() can't effectively report * failures when called in * isc_log_doit(). */ result = isc_stdio_open(dest.file.name, "a", &fp); if (result != ISC_R_SUCCESS) { syslog(LOG_ERR, "isc_stdio_open '%s' failed: %s", dest.file.name, isc_result_totext(result)); fprintf(stderr, "isc_stdio_open '%s' failed: %s", dest.file.name, isc_result_totext(result)); } else (void)isc_stdio_close(fp); } else { syslog(LOG_ERR, "isc_file_isplainfile '%s' failed: %s", dest.file.name, isc_result_totext(result)); fprintf(stderr, "isc_file_isplainfile '%s' failed: %s", dest.file.name, isc_result_totext(result)); } } return (result); }
/*% configure the zone */ static isc_result_t configure_zone(const char *vclass, const char *view, const cfg_obj_t *zconfig, const cfg_obj_t *vconfig, const cfg_obj_t *config, isc_mem_t *mctx) { int i = 0; isc_result_t result; const char *zclass; const char *zname; const char *zfile; const cfg_obj_t *maps[4]; const cfg_obj_t *zoptions = NULL; const cfg_obj_t *classobj = NULL; const cfg_obj_t *typeobj = NULL; const cfg_obj_t *fileobj = NULL; const cfg_obj_t *dbobj = NULL; const cfg_obj_t *obj = NULL; const cfg_obj_t *fmtobj = NULL; dns_masterformat_t masterformat; zone_options = DNS_ZONEOPT_CHECKNS | DNS_ZONEOPT_MANYERRORS; zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); classobj = cfg_tuple_get(zconfig, "class"); if (!cfg_obj_isstring(classobj)) zclass = vclass; else zclass = cfg_obj_asstring(classobj); zoptions = cfg_tuple_get(zconfig, "options"); maps[i++] = zoptions; if (vconfig != NULL) maps[i++] = cfg_tuple_get(vconfig, "options"); if (config != NULL) { cfg_map_get(config, "options", &obj); if (obj != NULL) maps[i++] = obj; } maps[i++] = NULL; cfg_map_get(zoptions, "type", &typeobj); if (typeobj == NULL) return (ISC_R_FAILURE); if (strcasecmp(cfg_obj_asstring(typeobj), "master") != 0) return (ISC_R_SUCCESS); cfg_map_get(zoptions, "database", &dbobj); if (dbobj != NULL) return (ISC_R_SUCCESS); cfg_map_get(zoptions, "file", &fileobj); if (fileobj == NULL) return (ISC_R_FAILURE); zfile = cfg_obj_asstring(fileobj); obj = NULL; if (get_maps(maps, "check-dup-records", &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_CHECKDUPRR; zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { zone_options |= DNS_ZONEOPT_CHECKDUPRR; zone_options |= DNS_ZONEOPT_CHECKDUPRRFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options &= ~DNS_ZONEOPT_CHECKDUPRR; zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_CHECKDUPRR; zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; } obj = NULL; if (get_maps(maps, "check-mx", &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_CHECKMX; zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { zone_options |= DNS_ZONEOPT_CHECKMX; zone_options |= DNS_ZONEOPT_CHECKMXFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options &= ~DNS_ZONEOPT_CHECKMX; zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_CHECKMX; zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; } obj = NULL; if (get_maps(maps, "check-integrity", &obj)) { if (cfg_obj_asboolean(obj)) zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; else zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY; } else zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; obj = NULL; if (get_maps(maps, "check-mx-cname", &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_WARNMXCNAME; zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { zone_options &= ~DNS_ZONEOPT_WARNMXCNAME; zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options |= DNS_ZONEOPT_WARNMXCNAME; zone_options |= DNS_ZONEOPT_IGNOREMXCNAME; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_WARNMXCNAME; zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; } obj = NULL; if (get_maps(maps, "check-srv-cname", &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_WARNSRVCNAME; zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME; zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options |= DNS_ZONEOPT_WARNSRVCNAME; zone_options |= DNS_ZONEOPT_IGNORESRVCNAME; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_WARNSRVCNAME; zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; } obj = NULL; if (get_maps(maps, "check-sibling", &obj)) { if (cfg_obj_asboolean(obj)) zone_options |= DNS_ZONEOPT_CHECKSIBLING; else zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; } obj = NULL; if (get_checknames(maps, &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_CHECKNAMES; zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { zone_options |= DNS_ZONEOPT_CHECKNAMES; zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options &= ~DNS_ZONEOPT_CHECKNAMES; zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_CHECKNAMES; zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; } masterformat = dns_masterformat_text; fmtobj = NULL; result = config_get(maps, "masterfile-format", &fmtobj); if (result == ISC_R_SUCCESS) { const char *masterformatstr = cfg_obj_asstring(fmtobj); if (strcasecmp(masterformatstr, "text") == 0) masterformat = dns_masterformat_text; else if (strcasecmp(masterformatstr, "raw") == 0) masterformat = dns_masterformat_raw; else INSIST(0); } result = load_zone(mctx, zname, zfile, masterformat, zclass, NULL); if (result != ISC_R_SUCCESS) fprintf(stderr, "%s/%s/%s: %s\n", view, zname, zclass, dns_result_totext(result)); return(result); }
isc_result_t ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac, dns_zone_t *zone) { isc_result_t result; const char *zname; dns_rdataclass_t zclass; dns_rdataclass_t vclass; const cfg_obj_t *maps[5]; const cfg_obj_t *zoptions = NULL; const cfg_obj_t *options = NULL; const cfg_obj_t *obj; const char *filename = NULL; dns_notifytype_t notifytype = dns_notifytype_yes; isc_sockaddr_t *addrs; dns_name_t **keynames; isc_uint32_t count; char *cpval; unsigned int dbargc; char **dbargv; static char default_dbtype[] = "rbt"; isc_mem_t *mctx = dns_zone_getmctx(zone); dns_dialuptype_t dialup = dns_dialuptype_no; dns_zonetype_t ztype; int i; isc_int32_t journal_size; isc_boolean_t multi; isc_boolean_t alt; dns_view_t *view; isc_boolean_t check = ISC_FALSE, fail = ISC_FALSE; isc_boolean_t warn = ISC_FALSE, ignore = ISC_FALSE; isc_boolean_t ixfrdiff; dns_masterformat_t masterformat; isc_stats_t *zoneqrystats; isc_boolean_t zonestats_on; int seconds; i = 0; if (zconfig != NULL) { zoptions = cfg_tuple_get(zconfig, "options"); maps[i++] = zoptions; } if (vconfig != NULL) maps[i++] = cfg_tuple_get(vconfig, "options"); if (config != NULL) { (void)cfg_map_get(config, "options", &options); if (options != NULL) maps[i++] = options; } maps[i++] = ns_g_defaults; maps[i] = NULL; if (vconfig != NULL) RETERR(ns_config_getclass(cfg_tuple_get(vconfig, "class"), dns_rdataclass_in, &vclass)); else vclass = dns_rdataclass_in; /* * Configure values common to all zone types. */ zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); RETERR(ns_config_getclass(cfg_tuple_get(zconfig, "class"), vclass, &zclass)); dns_zone_setclass(zone, zclass); ztype = zonetype_fromconfig(zoptions); dns_zone_settype(zone, ztype); obj = NULL; result = cfg_map_get(zoptions, "database", &obj); if (result == ISC_R_SUCCESS) cpval = isc_mem_strdup(mctx, cfg_obj_asstring(obj)); else cpval = default_dbtype; if (cpval == NULL) return(ISC_R_NOMEMORY); result = strtoargv(mctx, cpval, &dbargc, &dbargv); if (result != ISC_R_SUCCESS && cpval != default_dbtype) { isc_mem_free(mctx, cpval); return (result); } /* * ANSI C is strange here. There is no logical reason why (char **) * cannot be promoted automatically to (const char * const *) by the * compiler w/o generating a warning. */ result = dns_zone_setdbtype(zone, dbargc, (const char * const *)dbargv); isc_mem_put(mctx, dbargv, dbargc * sizeof(*dbargv)); if (cpval != default_dbtype) isc_mem_free(mctx, cpval); if (result != ISC_R_SUCCESS) return (result); obj = NULL; result = cfg_map_get(zoptions, "file", &obj); if (result == ISC_R_SUCCESS) filename = cfg_obj_asstring(obj); /* * Unless we're using some alternative database, a master zone * will be needing a master file. */ if (ztype == dns_zone_master && cpval == default_dbtype && filename == NULL) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "zone '%s': 'file' not specified", zname); return (ISC_R_FAILURE); } masterformat = dns_masterformat_text; obj = NULL; result= ns_config_get(maps, "masterfile-format", &obj); if (result == ISC_R_SUCCESS) { const char *masterformatstr = cfg_obj_asstring(obj); if (strcasecmp(masterformatstr, "text") == 0) masterformat = dns_masterformat_text; else if (strcasecmp(masterformatstr, "raw") == 0) masterformat = dns_masterformat_raw; else INSIST(0); } RETERR(dns_zone_setfile2(zone, filename, masterformat)); obj = NULL; result = cfg_map_get(zoptions, "journal", &obj); if (result == ISC_R_SUCCESS) RETERR(dns_zone_setjournal(zone, cfg_obj_asstring(obj))); if (ztype == dns_zone_slave) RETERR(configure_zone_acl(zconfig, vconfig, config, allow_notify, ac, zone, dns_zone_setnotifyacl, dns_zone_clearnotifyacl)); /* * XXXAG This probably does not make sense for stubs. */ RETERR(configure_zone_acl(zconfig, vconfig, config, allow_query, ac, zone, dns_zone_setqueryacl, dns_zone_clearqueryacl)); obj = NULL; result = ns_config_get(maps, "dialup", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); if (cfg_obj_isboolean(obj)) { if (cfg_obj_asboolean(obj)) dialup = dns_dialuptype_yes; else dialup = dns_dialuptype_no; } else { const char *dialupstr = cfg_obj_asstring(obj); if (strcasecmp(dialupstr, "notify") == 0) dialup = dns_dialuptype_notify; else if (strcasecmp(dialupstr, "notify-passive") == 0) dialup = dns_dialuptype_notifypassive; else if (strcasecmp(dialupstr, "refresh") == 0) dialup = dns_dialuptype_refresh; else if (strcasecmp(dialupstr, "passive") == 0) dialup = dns_dialuptype_passive; else INSIST(0); } dns_zone_setdialup(zone, dialup); obj = NULL; result = ns_config_get(maps, "zone-statistics", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); zonestats_on = cfg_obj_asboolean(obj); zoneqrystats = NULL; if (zonestats_on) { RETERR(isc_stats_create(mctx, &zoneqrystats, dns_nsstatscounter_max)); } dns_zone_setrequeststats(zone, zoneqrystats); if (zoneqrystats != NULL) isc_stats_detach(&zoneqrystats); /* * Configure master functionality. This applies * to primary masters (type "master") and slaves * acting as masters (type "slave"), but not to stubs. */ if (ztype != dns_zone_stub && ztype != dns_zone_staticstub) { obj = NULL; result = ns_config_get(maps, "notify", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); if (cfg_obj_isboolean(obj)) { if (cfg_obj_asboolean(obj)) notifytype = dns_notifytype_yes; else notifytype = dns_notifytype_no; } else { const char *notifystr = cfg_obj_asstring(obj); if (strcasecmp(notifystr, "explicit") == 0) notifytype = dns_notifytype_explicit; else if (strcasecmp(notifystr, "master-only") == 0) notifytype = dns_notifytype_masteronly; else INSIST(0); } dns_zone_setnotifytype(zone, notifytype); obj = NULL; result = ns_config_get(maps, "also-notify", &obj); if (result == ISC_R_SUCCESS) { isc_sockaddr_t *addrs = NULL; isc_uint32_t addrcount; result = ns_config_getiplist(config, obj, 0, mctx, &addrs, &addrcount); if (result != ISC_R_SUCCESS) return (result); result = dns_zone_setalsonotify(zone, addrs, addrcount); ns_config_putiplist(mctx, &addrs, addrcount); if (result != ISC_R_SUCCESS) return (result); } else RETERR(dns_zone_setalsonotify(zone, NULL, 0)); obj = NULL; result = ns_config_get(maps, "notify-source", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); RETERR(dns_zone_setnotifysrc4(zone, cfg_obj_assockaddr(obj))); ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); obj = NULL; result = ns_config_get(maps, "notify-source-v6", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); RETERR(dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj))); ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); obj = NULL; result = ns_config_get(maps, "notify-to-soa", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setoption(zone, DNS_ZONEOPT_NOTIFYTOSOA, cfg_obj_asboolean(obj)); dns_zone_setisself(zone, ns_client_isself, NULL); RETERR(configure_zone_acl(zconfig, vconfig, config, allow_transfer, ac, zone, dns_zone_setxfracl, dns_zone_clearxfracl)); obj = NULL; result = ns_config_get(maps, "max-transfer-time-out", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setmaxxfrout(zone, cfg_obj_asuint32(obj) * 60); obj = NULL; result = ns_config_get(maps, "max-transfer-idle-out", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setidleout(zone, cfg_obj_asuint32(obj) * 60); obj = NULL; result = ns_config_get(maps, "max-journal-size", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setjournalsize(zone, -1); if (cfg_obj_isstring(obj)) { const char *str = cfg_obj_asstring(obj); INSIST(strcasecmp(str, "unlimited") == 0); journal_size = ISC_UINT32_MAX / 2; } else { isc_resourcevalue_t value; value = cfg_obj_asuint64(obj); if (value > ISC_UINT32_MAX / 2) { cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, "'max-journal-size " "%" ISC_PRINT_QUADFORMAT "d' " "is too large", value); RETERR(ISC_R_RANGE); } journal_size = (isc_uint32_t)value; } dns_zone_setjournalsize(zone, journal_size); obj = NULL; result = ns_config_get(maps, "ixfr-from-differences", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); if (cfg_obj_isboolean(obj)) ixfrdiff = cfg_obj_asboolean(obj); else if (!strcasecmp(cfg_obj_asstring(obj), "master") && ztype == dns_zone_master) ixfrdiff = ISC_TRUE; else if (!strcasecmp(cfg_obj_asstring(obj), "slave") && ztype == dns_zone_slave) ixfrdiff = ISC_TRUE; else ixfrdiff = ISC_FALSE; dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS, ixfrdiff); checknames(ztype, maps, &obj); INSIST(obj != NULL); if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { fail = ISC_FALSE; check = ISC_TRUE; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { fail = check = ISC_TRUE; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { fail = check = ISC_FALSE; } else INSIST(0); dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES, check); dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL, fail); obj = NULL; result = ns_config_get(maps, "notify-delay", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setnotifydelay(zone, cfg_obj_asuint32(obj)); obj = NULL; result = ns_config_get(maps, "check-sibling", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSIBLING, cfg_obj_asboolean(obj)); obj = NULL; result = ns_config_get(maps, "zero-no-soa-ttl", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setzeronosoattl(zone, cfg_obj_asboolean(obj)); obj = NULL; result = ns_config_get(maps, "nsec3-test-zone", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setoption(zone, DNS_ZONEOPT_NSEC3TESTZONE, cfg_obj_asboolean(obj)); } /* * Configure update-related options. These apply to * primary masters only. */ if (ztype == dns_zone_master) { dns_acl_t *updateacl; RETERR(configure_zone_acl(zconfig, vconfig, config, allow_update, ac, zone, dns_zone_setupdateacl, dns_zone_clearupdateacl)); updateacl = dns_zone_getupdateacl(zone); if (updateacl != NULL && dns_acl_isinsecure(updateacl)) isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_SERVER, ISC_LOG_WARNING, "zone '%s' allows updates by IP " "address, which is insecure", zname); RETERR(configure_zone_ssutable(zoptions, zone, zname)); obj = NULL; result = ns_config_get(maps, "sig-validity-interval", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); { const cfg_obj_t *validity, *resign; validity = cfg_tuple_get(obj, "validity"); seconds = cfg_obj_asuint32(validity) * 86400; dns_zone_setsigvalidityinterval(zone, seconds); resign = cfg_tuple_get(obj, "re-sign"); if (cfg_obj_isvoid(resign)) { seconds /= 4; } else { if (seconds > 7 * 86400) seconds = cfg_obj_asuint32(resign) * 86400; else seconds = cfg_obj_asuint32(resign) * 3600; } dns_zone_setsigresigninginterval(zone, seconds); } obj = NULL; result = ns_config_get(maps, "key-directory", &obj); if (result == ISC_R_SUCCESS) { filename = cfg_obj_asstring(obj); RETERR(dns_zone_setkeydirectory(zone, filename)); } obj = NULL; result = ns_config_get(maps, "sig-signing-signatures", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setsignatures(zone, cfg_obj_asuint32(obj)); obj = NULL; result = ns_config_get(maps, "sig-signing-nodes", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setnodes(zone, cfg_obj_asuint32(obj)); obj = NULL; result = ns_config_get(maps, "sig-signing-type", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setprivatetype(zone, cfg_obj_asuint32(obj)); obj = NULL; result = ns_config_get(maps, "update-check-ksk", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setoption(zone, DNS_ZONEOPT_UPDATECHECKKSK, cfg_obj_asboolean(obj)); obj = NULL; result = ns_config_get(maps, "dnssec-dnskey-kskonly", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setoption(zone, DNS_ZONEOPT_DNSKEYKSKONLY, cfg_obj_asboolean(obj)); } else if (ztype == dns_zone_slave) { RETERR(configure_zone_acl(zconfig, vconfig, config, allow_update_forwarding, ac, zone, dns_zone_setforwardacl, dns_zone_clearforwardacl)); } /*% * Primary master functionality. */ if (ztype == dns_zone_master) { isc_boolean_t allow = ISC_FALSE, maint = ISC_FALSE; obj = NULL; result = ns_config_get(maps, "check-wildcard", &obj); if (result == ISC_R_SUCCESS) check = cfg_obj_asboolean(obj); else check = ISC_FALSE; dns_zone_setoption(zone, DNS_ZONEOPT_CHECKWILDCARD, check); obj = NULL; result = ns_config_get(maps, "check-dup-records", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { fail = ISC_FALSE; check = ISC_TRUE; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { fail = check = ISC_TRUE; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { fail = check = ISC_FALSE; } else INSIST(0); dns_zone_setoption(zone, DNS_ZONEOPT_CHECKDUPRR, check); dns_zone_setoption(zone, DNS_ZONEOPT_CHECKDUPRRFAIL, fail); obj = NULL; result = ns_config_get(maps, "check-mx", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { fail = ISC_FALSE; check = ISC_TRUE; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { fail = check = ISC_TRUE; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { fail = check = ISC_FALSE; } else INSIST(0); dns_zone_setoption(zone, DNS_ZONEOPT_CHECKMX, check); dns_zone_setoption(zone, DNS_ZONEOPT_CHECKMXFAIL, fail); obj = NULL; result = ns_config_get(maps, "check-integrity", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setoption(zone, DNS_ZONEOPT_CHECKINTEGRITY, cfg_obj_asboolean(obj)); obj = NULL; result = ns_config_get(maps, "check-mx-cname", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { warn = ISC_TRUE; ignore = ISC_FALSE; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { warn = ignore = ISC_FALSE; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { warn = ignore = ISC_TRUE; } else INSIST(0); dns_zone_setoption(zone, DNS_ZONEOPT_WARNMXCNAME, warn); dns_zone_setoption(zone, DNS_ZONEOPT_IGNOREMXCNAME, ignore); obj = NULL; result = ns_config_get(maps, "check-srv-cname", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { warn = ISC_TRUE; ignore = ISC_FALSE; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { warn = ignore = ISC_FALSE; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { warn = ignore = ISC_TRUE; } else INSIST(0); dns_zone_setoption(zone, DNS_ZONEOPT_WARNSRVCNAME, warn); dns_zone_setoption(zone, DNS_ZONEOPT_IGNORESRVCNAME, ignore); obj = NULL; result = ns_config_get(maps, "dnssec-secure-to-insecure", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setoption(zone, DNS_ZONEOPT_SECURETOINSECURE, cfg_obj_asboolean(obj)); obj = NULL; result = cfg_map_get(zoptions, "auto-dnssec", &obj); if (result == ISC_R_SUCCESS) { const char *arg = cfg_obj_asstring(obj); if (strcasecmp(arg, "allow") == 0) allow = ISC_TRUE; else if (strcasecmp(arg, "maintain") == 0) allow = maint = ISC_TRUE; else if (strcasecmp(arg, "off") == 0) ; else INSIST(0); dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, allow); dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, maint); } } /* * Configure slave functionality. */ switch (ztype) { case dns_zone_slave: case dns_zone_stub: count = 0; obj = NULL; (void)cfg_map_get(zoptions, "masters", &obj); if (obj != NULL) { addrs = NULL; keynames = NULL; RETERR(ns_config_getipandkeylist(config, obj, mctx, &addrs, &keynames, &count)); result = dns_zone_setmasterswithkeys(zone, addrs, keynames, count); ns_config_putipandkeylist(mctx, &addrs, &keynames, count); } else result = dns_zone_setmasters(zone, NULL, 0); RETERR(result); multi = ISC_FALSE; if (count > 1) { obj = NULL; result = ns_config_get(maps, "multi-master", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); multi = cfg_obj_asboolean(obj); } dns_zone_setoption(zone, DNS_ZONEOPT_MULTIMASTER, multi); obj = NULL; result = ns_config_get(maps, "max-transfer-time-in", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setmaxxfrin(zone, cfg_obj_asuint32(obj) * 60); obj = NULL; result = ns_config_get(maps, "max-transfer-idle-in", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setidlein(zone, cfg_obj_asuint32(obj) * 60); obj = NULL; result = ns_config_get(maps, "max-refresh-time", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setmaxrefreshtime(zone, cfg_obj_asuint32(obj)); obj = NULL; result = ns_config_get(maps, "min-refresh-time", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setminrefreshtime(zone, cfg_obj_asuint32(obj)); obj = NULL; result = ns_config_get(maps, "max-retry-time", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setmaxretrytime(zone, cfg_obj_asuint32(obj)); obj = NULL; result = ns_config_get(maps, "min-retry-time", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); dns_zone_setminretrytime(zone, cfg_obj_asuint32(obj)); obj = NULL; result = ns_config_get(maps, "transfer-source", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); RETERR(dns_zone_setxfrsource4(zone, cfg_obj_assockaddr(obj))); ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); obj = NULL; result = ns_config_get(maps, "transfer-source-v6", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); RETERR(dns_zone_setxfrsource6(zone, cfg_obj_assockaddr(obj))); ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); obj = NULL; result = ns_config_get(maps, "alt-transfer-source", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); RETERR(dns_zone_setaltxfrsource4(zone, cfg_obj_assockaddr(obj))); obj = NULL; result = ns_config_get(maps, "alt-transfer-source-v6", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); RETERR(dns_zone_setaltxfrsource6(zone, cfg_obj_assockaddr(obj))); obj = NULL; (void)ns_config_get(maps, "use-alt-transfer-source", &obj); if (obj == NULL) { /* * Default off when views are in use otherwise * on for BIND 8 compatibility. */ view = dns_zone_getview(zone); if (view != NULL && strcmp(view->name, "_default") == 0) alt = ISC_TRUE; else alt = ISC_FALSE; } else alt = cfg_obj_asboolean(obj); dns_zone_setoption(zone, DNS_ZONEOPT_USEALTXFRSRC, alt); obj = NULL; (void)ns_config_get(maps, "try-tcp-refresh", &obj); dns_zone_setoption(zone, DNS_ZONEOPT_TRYTCPREFRESH, cfg_obj_asboolean(obj)); break; case dns_zone_staticstub: RETERR(configure_staticstub(zoptions, zone, zname, default_dbtype)); break; default: break; } return (ISC_R_SUCCESS); }