📄 check.c
字号:
tresult = nameexist(zconfig, namebuf, ztype == HINTZONE ? 1 : 2, symtab, "zone '%s': already exists " "previous definition: %s:%u", logctx, mctx); if (tresult != ISC_R_SUCCESS) result = tresult; } /* * Look for inappropriate options for the given zone type. * Check that ACLs expand correctly. */ for (i = 0; i < sizeof(options) / sizeof(options[0]); i++) { obj = NULL; if ((options[i].allowed & ztype) == 0 && cfg_map_get(zoptions, options[i].name, &obj) == ISC_R_SUCCESS) { if (strcmp(options[i].name, "allow-update") != 0 || ztype != SLAVEZONE) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "option '%s' is not allowed " "in '%s' zone '%s'", options[i].name, typestr, zname); result = ISC_R_FAILURE; } else cfg_obj_log(obj, logctx, ISC_LOG_WARNING, "option '%s' is not allowed " "in '%s' zone '%s'", options[i].name, typestr, zname); } obj = NULL; if ((options[i].allowed & ztype) != 0 && (options[i].allowed & CHECKACL) != 0) { tresult = checkacl(options[i].name, actx, zconfig, voptions, config, logctx, mctx); if (tresult != ISC_R_SUCCESS) result = tresult; } } /* * Slave & stub zones must have a "masters" field. */ if (ztype == SLAVEZONE || ztype == STUBZONE) { obj = NULL; if (cfg_map_get(zoptions, "masters", &obj) != ISC_R_SUCCESS) { cfg_obj_log(zoptions, logctx, ISC_LOG_ERROR, "zone '%s': missing 'masters' entry", zname); result = ISC_R_FAILURE; } else { isc_uint32_t count; tresult = validate_masters(obj, config, &count, logctx, mctx); if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS) result = tresult; if (tresult == ISC_R_SUCCESS && count == 0) { cfg_obj_log(zoptions, logctx, ISC_LOG_ERROR, "zone '%s': empty 'masters' entry", zname); result = ISC_R_FAILURE; } } } /* * Master zones can't have both "allow-update" and "update-policy". */ if (ztype == MASTERZONE) { isc_result_t res1, res2; obj = NULL; res1 = cfg_map_get(zoptions, "allow-update", &obj); obj = NULL; res2 = cfg_map_get(zoptions, "update-policy", &obj); if (res1 == ISC_R_SUCCESS && res2 == ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "zone '%s': 'allow-update' is ignored " "when 'update-policy' is present", zname); result = ISC_R_FAILURE; } else if (res2 == ISC_R_SUCCESS && check_update_policy(obj, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; } /* * Check the excessively complicated "dialup" option. */ if (ztype == MASTERZONE || ztype == SLAVEZONE || ztype == STUBZONE) { const cfg_obj_t *dialup = NULL; (void)cfg_map_get(zoptions, "dialup", &dialup); if (dialup != NULL && cfg_obj_isstring(dialup)) { const char *str = cfg_obj_asstring(dialup); for (i = 0; i < sizeof(dialups) / sizeof(dialups[0]); i++) { if (strcasecmp(dialups[i].name, str) != 0) continue; if ((dialups[i].allowed & ztype) == 0) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "dialup type '%s' is not " "allowed in '%s' " "zone '%s'", str, typestr, zname); result = ISC_R_FAILURE; } break; } if (i == sizeof(dialups) / sizeof(dialups[0])) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "invalid dialup type '%s' in zone " "'%s'", str, zname); result = ISC_R_FAILURE; } } } /* * Check that forwarding is reasonable. */ if (check_forward(zoptions, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; /* * Check various options. */ tresult = check_options(zoptions, logctx, mctx); if (tresult != ISC_R_SUCCESS) result = tresult; /* * If the zone type is rbt/rbt64 then master/hint zones * require file clauses. */ obj = NULL; tresult = cfg_map_get(zoptions, "database", &obj); if (tresult == ISC_R_NOTFOUND || (tresult == ISC_R_SUCCESS && (strcmp("rbt", cfg_obj_asstring(obj)) == 0 || strcmp("rbt64", cfg_obj_asstring(obj)) == 0))) { obj = NULL; tresult = cfg_map_get(zoptions, "file", &obj); if (tresult != ISC_R_SUCCESS && (ztype == MASTERZONE || ztype == HINTZONE)) { cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR, "zone '%s': missing 'file' entry", zname); result = tresult; } } return (result);}typedef struct keyalgorithms { const char *name; isc_uint16_t size;} algorithmtable;isc_result_tbind9_check_key(const cfg_obj_t *key, isc_log_t *logctx) { const cfg_obj_t *algobj = NULL; const cfg_obj_t *secretobj = NULL; const char *keyname = cfg_obj_asstring(cfg_map_getname(key)); const char *algorithm; int i; size_t len = 0; static const algorithmtable algorithms[] = { { "hmac-md5", 128 }, { "hmac-md5.sig-alg.reg.int", 0 }, { "hmac-md5.sig-alg.reg.int.", 0 }, { "hmac-sha1", 160 }, { "hmac-sha224", 224 }, { "hmac-sha256", 256 }, { "hmac-sha384", 384 }, { "hmac-sha512", 512 }, { NULL, 0 } }; (void)cfg_map_get(key, "algorithm", &algobj); (void)cfg_map_get(key, "secret", &secretobj); if (secretobj == NULL || algobj == NULL) { cfg_obj_log(key, logctx, ISC_LOG_ERROR, "key '%s' must have both 'secret' and " "'algorithm' defined", keyname); return (ISC_R_FAILURE); } algorithm = cfg_obj_asstring(algobj); for (i = 0; algorithms[i].name != NULL; i++) { len = strlen(algorithms[i].name); if (strncasecmp(algorithms[i].name, algorithm, len) == 0 && (algorithm[len] == '\0' || (algorithms[i].size != 0 && algorithm[len] == '-'))) break; } if (algorithms[i].name == NULL) { cfg_obj_log(algobj, logctx, ISC_LOG_ERROR, "unknown algorithm '%s'", algorithm); return (ISC_R_NOTFOUND); } if (algorithm[len] == '-') { isc_uint16_t digestbits; isc_result_t result; result = isc_parse_uint16(&digestbits, algorithm + len + 1, 10); if (result == ISC_R_SUCCESS || result == ISC_R_RANGE) { if (result == ISC_R_RANGE || digestbits > algorithms[i].size) { cfg_obj_log(algobj, logctx, ISC_LOG_ERROR, "key '%s' digest-bits too large " "[%u..%u]", keyname, algorithms[i].size / 2, algorithms[i].size); return (ISC_R_RANGE); } if ((digestbits % 8) != 0) { cfg_obj_log(algobj, logctx, ISC_LOG_ERROR, "key '%s' digest-bits not multiple" " of 8", keyname); return (ISC_R_RANGE); } /* * Recommended minima for hmac algorithms. */ if ((digestbits < (algorithms[i].size / 2U) || (digestbits < 80U))) cfg_obj_log(algobj, logctx, ISC_LOG_WARNING, "key '%s' digest-bits too small " "[<%u]", keyname, algorithms[i].size/2); } else { cfg_obj_log(algobj, logctx, ISC_LOG_ERROR, "key '%s': unable to parse digest-bits", keyname); return (result); } } return (ISC_R_SUCCESS);}static isc_result_tcheck_keylist(const cfg_obj_t *keys, isc_symtab_t *symtab, isc_log_t *logctx) { isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; const cfg_listelt_t *element; for (element = cfg_list_first(keys); element != NULL; element = cfg_list_next(element)) { const cfg_obj_t *key = cfg_listelt_value(element); const char *keyname = cfg_obj_asstring(cfg_map_getname(key)); isc_symvalue_t symvalue; tresult = bind9_check_key(key, logctx); if (tresult != ISC_R_SUCCESS) return (tresult); symvalue.as_cpointer = key; tresult = isc_symtab_define(symtab, keyname, 1, symvalue, isc_symexists_reject); if (tresult == ISC_R_EXISTS) { const char *file; unsigned int line; RUNTIME_CHECK(isc_symtab_lookup(symtab, keyname, 1, &symvalue) == ISC_R_SUCCESS); file = cfg_obj_file(symvalue.as_cpointer); line = cfg_obj_line(symvalue.as_cpointer); if (file == NULL) file = "<unknown file>"; cfg_obj_log(key, logctx, ISC_LOG_ERROR, "key '%s': already exists " "previous definition: %s:%u", keyname, file, line); result = tresult; } else if (tresult != ISC_R_SUCCESS) return (tresult); } return (result);}static struct { const char *v4; const char *v6;} sources[] = { { "transfer-source", "transfer-source-v6" }, { "notify-source", "notify-source-v6" }, { "query-source", "query-source-v6" }, { NULL, NULL }};static isc_result_tcheck_servers(const cfg_obj_t *servers, isc_log_t *logctx) { isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; const cfg_listelt_t *e1, *e2; const cfg_obj_t *v1, *v2; isc_netaddr_t n1, n2; unsigned int p1, p2; const cfg_obj_t *obj; char buf[ISC_NETADDR_FORMATSIZE]; const char *xfr; int source; for (e1 = cfg_list_first(servers); e1 != NULL; e1 = cfg_list_next(e1)) { v1 = cfg_listelt_value(e1); cfg_obj_asnetprefix(cfg_map_getname(v1), &n1, &p1); /* * Check that unused bits are zero. */ tresult = isc_netaddr_prefixok(&n1, p1); if (tresult != ISC_R_SUCCESS) { INSIST(tresult == ISC_R_FAILURE); isc_netaddr_format(&n1, buf, sizeof(buf)); cfg_obj_log(v1, logctx, ISC_LOG_ERROR, "server '%s/%u': invalid prefix " "(extra bits specified)", buf, p1); result = tresult; } source = 0; do { obj = NULL; if (n1.family == AF_INET) xfr = sources[source].v6; else xfr = sources[source].v4; (void)cfg_map_get(v1, xfr, &obj); if (obj != NULL) { isc_netaddr_format(&n1, buf, sizeof(buf)); cfg_obj_log(v1, logctx, ISC_LOG_ERROR, "server '%s': %s not legal", buf, xfr); result = ISC_R_FAILURE; } } while (sources[++source].v4 != NULL); e2 = e1; while ((e2 = cfg_list_next(e2)) != NULL) { v2 = cfg_listelt_value(e2); cfg_obj_asnetprefix(cfg_map_getname(v2), &n2, &p2); if (p1 == p2 && isc_netaddr_equal(&n1, &n2)) { const char *file = cfg_obj_file(v1); unsigned int line = cfg_obj_line(v1); if (file == NULL) file = "<unknown file>"; isc_netaddr_format(&n2, buf, sizeof(buf)); cfg_obj_log(v2, logctx, ISC_LOG_ERROR, "server '%s/%u': already exists " "previous definition: %s:%u", buf, p2, file, line); result = ISC_R_FAILURE; } } } return (result);} static isc_result_tcheck_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, dns_rdataclass_t vclass, isc_log_t *logctx, isc_mem_t *mctx){ const cfg_obj_t *servers = NULL; const cfg_obj_t *zones = NULL; const cfg_obj_t *keys = NULL; const cfg_listelt_t *element; isc_symtab_t *symtab = NULL; isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult = ISC_R_SUCCESS; cfg_aclconfctx_t actx; const cfg_obj_t *obj; isc_boolean_t enablednssec, enablevalidation; /* * Check that all zone statements are syntactically correct and * there are no duplicate zones. */ tresult = isc_symtab_create(mctx, 100, freekey, mctx, ISC_FALSE, &symtab); if (tresult != ISC_R_SUCCESS) return (ISC_R_NOMEMORY); cfg_aclconfctx_init(&actx); if (voptions != NULL) (void)cfg_map_get(voptions, "zone", &zones); else (void)cfg_map_get(config, "zone", &zones); for (element = cfg_list_first(zones); element != NULL; element = cfg_list_next(element)) { isc_result_t tresult; const cfg_obj_t *zone = cfg_listelt_value(element); tresult = check_zoneconf(zone, voptions, config, symtab, vclass, &actx, logctx, mctx); if (tresult != ISC_R_SUCCESS) result = ISC_R_FAILURE; } isc_symtab_destroy(&symtab); /* * Check that all key statements are syntactically correct and * there are no duplicate keys. */ tresult = isc_symtab_create(mctx, 100, NULL, NULL, ISC_TRUE, &symtab); if (tresult != ISC_R_SUCCESS) return (ISC_R_NOMEMORY); (void)cfg_map_get(config, "key", &keys); tresult = check_keylist(keys, symtab, logctx); if (tresult == ISC_R_EXISTS) result = ISC_R_FAILURE; else if (tresult != ISC_R_SUCCESS) { isc_symtab_destroy(&symtab); return (tresult); } if (voptions != NULL) { keys = NULL; (void)cfg_map_get(voptions, "key", &keys); tresult = check_keylist(keys, symtab, logctx); if (tresult == ISC_R_EXISTS) result = ISC_R_FAILURE; else if (tresult != ISC_R_SUCCESS) { isc_symtab_destroy(&symtab); return (tresult); } } isc_symtab_destroy(&symtab); /* * Check that forwarding is reasonable. */ if (voptions == NULL) { const cfg_obj_t *options = NULL; (void)cfg_map_get(config, "options", &options); if (options != NULL) if (check_forward(options, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; } else { if (check_forward(voptions, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; } /* * Check that dual-stack-servers is reasonable. */ if (voptions == NULL) { const cfg_obj_t *options = NULL; (void)cfg_map_get(config, "options", &options); if (options != NULL) if (check_dual_stack(options, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; } else { if (check_dual_stack(voptions, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; } /* * Check that rrset-order is reasonable. */ if (voptions != NULL) { if (check_order(voptions, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; } if (voptions != NULL) { (void)cfg_map_get(voptions, "server", &servers); if (servers != NULL && check_servers(servers, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; } /* * Check that dnssec-enable/dnssec-validation are sensible. */ obj = NULL; if (voptions != NULL) (void)cfg_map_get(voptions, "dnssec-enable", &obj); if (obj == NULL) (void)cfg_map_get(config, "dnssec-enable", &obj); if (obj == NULL) enablednssec = ISC_TRUE; else enablednssec = cfg_obj_asboolean(obj); obj = NULL; if (voptions != NULL) (void)cfg_map_get(voptions, "dnssec-validation", &obj); if (obj == NULL) (void)cfg_map_get(config, "dnssec-validation", &obj); if (obj == NULL) enablevalidation = ISC_FALSE; /* XXXMPA Change for 9.5. */ else enablevalidation = cfg_obj_asboolean(obj); if (enablevalidation && !enablednssec)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -