00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <string.h>
00023
00024 #include <isc/lex.h>
00025 #include <isc/mem.h>
00026 #include <isc/result.h>
00027 #include <isc/string.h>
00028 #include <isc/util.h>
00029
00030 #include <dns/ttl.h>
00031 #include <dns/result.h>
00032
00033 #include <isccfg/cfg.h>
00034 #include <isccfg/grammar.h>
00035 #include <isccfg/log.h>
00036
00037 #define TOKEN_STRING(pctx) (pctx->token.value.as_textregion.base)
00038
00039
00040 #define CHECK(op) \
00041 do { result = (op); \
00042 if (result != ISC_R_SUCCESS) goto cleanup; \
00043 } while (0)
00044
00045
00046 #define CLEANUP_OBJ(obj) \
00047 do { if ((obj) != NULL) cfg_obj_destroy(pctx, &(obj)); } while (0)
00048
00049
00050
00051
00052
00053
00054 static isc_result_t
00055 parse_enum_or_other(cfg_parser_t *pctx, const cfg_type_t *enumtype,
00056 const cfg_type_t *othertype, cfg_obj_t **ret);
00057
00058 static void
00059 doc_enum_or_other(cfg_printer_t *pctx, const cfg_type_t *type);
00060
00061 static isc_result_t
00062 parse_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00063
00064 static isc_result_t
00065 parse_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type,
00066 cfg_obj_t **ret);
00067
00068 static isc_result_t
00069 parse_updatepolicy(cfg_parser_t *pctx, const cfg_type_t *type,
00070 cfg_obj_t **ret);
00071 static void
00072 print_updatepolicy(cfg_printer_t *pctx, const cfg_obj_t *obj);
00073
00074 static void
00075 doc_updatepolicy(cfg_printer_t *pctx, const cfg_type_t *type);
00076
00077 static void
00078 print_keyvalue(cfg_printer_t *pctx, const cfg_obj_t *obj);
00079
00080 static void
00081 doc_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type);
00082
00083 static void
00084 doc_optional_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type);
00085
00086 #ifdef HAVE_GEOIP
00087 static isc_result_t
00088 parse_geoip(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
00089
00090 static void
00091 print_geoip(cfg_printer_t *pctx, const cfg_obj_t *obj);
00092
00093 static void
00094 doc_geoip(cfg_printer_t *pctx, const cfg_type_t *type);
00095 #endif
00096
00097 static cfg_type_t cfg_type_acl;
00098 static cfg_type_t cfg_type_addrmatchelt;
00099 static cfg_type_t cfg_type_bracketed_aml;
00100 static cfg_type_t cfg_type_bracketed_namesockaddrkeylist;
00101 static cfg_type_t cfg_type_bracketed_dscpsockaddrlist;
00102 static cfg_type_t cfg_type_bracketed_sockaddrlist;
00103 static cfg_type_t cfg_type_bracketed_sockaddrnameportlist;
00104 static cfg_type_t cfg_type_controls;
00105 static cfg_type_t cfg_type_controls_sockaddr;
00106 static cfg_type_t cfg_type_destinationlist;
00107 static cfg_type_t cfg_type_dialuptype;
00108 static cfg_type_t cfg_type_ixfrdifftype;
00109 static cfg_type_t cfg_type_key;
00110 static cfg_type_t cfg_type_logfile;
00111 static cfg_type_t cfg_type_logging;
00112 static cfg_type_t cfg_type_logseverity;
00113 static cfg_type_t cfg_type_lwres;
00114 static cfg_type_t cfg_type_masterselement;
00115 static cfg_type_t cfg_type_maxttl;
00116 static cfg_type_t cfg_type_nameportiplist;
00117 static cfg_type_t cfg_type_negated;
00118 static cfg_type_t cfg_type_notifytype;
00119 static cfg_type_t cfg_type_optional_allow;
00120 static cfg_type_t cfg_type_optional_class;
00121 static cfg_type_t cfg_type_optional_facility;
00122 static cfg_type_t cfg_type_optional_keyref;
00123 static cfg_type_t cfg_type_optional_port;
00124 static cfg_type_t cfg_type_optional_dscp;
00125 static cfg_type_t cfg_type_options;
00126 static cfg_type_t cfg_type_portiplist;
00127 static cfg_type_t cfg_type_querysource4;
00128 static cfg_type_t cfg_type_querysource6;
00129 static cfg_type_t cfg_type_querysource;
00130 static cfg_type_t cfg_type_server;
00131 static cfg_type_t cfg_type_server_key_kludge;
00132 static cfg_type_t cfg_type_size;
00133 static cfg_type_t cfg_type_sizenodefault;
00134 static cfg_type_t cfg_type_sockaddr4wild;
00135 static cfg_type_t cfg_type_sockaddr6wild;
00136 static cfg_type_t cfg_type_statschannels;
00137 static cfg_type_t cfg_type_ttlval;
00138 static cfg_type_t cfg_type_view;
00139 static cfg_type_t cfg_type_viewopts;
00140 static cfg_type_t cfg_type_zone;
00141 static cfg_type_t cfg_type_zoneopts;
00142 static cfg_type_t cfg_type_filter_aaaa;
00143 static cfg_type_t cfg_type_dlz;
00144
00145
00146
00147 static cfg_tuplefielddef_t tkey_dhkey_fields[] = {
00148 { "name", &cfg_type_qstring, 0 },
00149 { "keyid", &cfg_type_uint32, 0 },
00150 { NULL, NULL, 0 }
00151 };
00152
00153 static cfg_type_t cfg_type_tkey_dhkey = {
00154 "tkey-dhkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple,
00155 tkey_dhkey_fields
00156 };
00157
00158
00159
00160 static cfg_tuplefielddef_t listenon_fields[] = {
00161 { "port", &cfg_type_optional_port, 0 },
00162 { "dscp", &cfg_type_optional_dscp, 0 },
00163 { "acl", &cfg_type_bracketed_aml, 0 },
00164 { NULL, NULL, 0 }
00165 };
00166
00167 static cfg_type_t cfg_type_listenon = {
00168 "listenon", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
00169 &cfg_rep_tuple, listenon_fields
00170 };
00171
00172
00173
00174 static cfg_tuplefielddef_t acl_fields[] = {
00175 { "name", &cfg_type_astring, 0 },
00176 { "value", &cfg_type_bracketed_aml, 0 },
00177 { NULL, NULL, 0 }
00178 };
00179
00180 static cfg_type_t cfg_type_acl = {
00181 "acl", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, acl_fields };
00182
00183
00184 static cfg_tuplefielddef_t masters_fields[] = {
00185 { "name", &cfg_type_astring, 0 },
00186 { "port", &cfg_type_optional_port, 0 },
00187 { "dscp", &cfg_type_optional_dscp, 0 },
00188 { "addresses", &cfg_type_bracketed_namesockaddrkeylist, 0 },
00189 { NULL, NULL, 0 }
00190 };
00191
00192 static cfg_type_t cfg_type_masters = {
00193 "masters", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, masters_fields };
00194
00195
00196
00197
00198
00199
00200
00201
00202 static cfg_tuplefielddef_t namesockaddrkey_fields[] = {
00203 { "masterselement", &cfg_type_masterselement, 0 },
00204 { "key", &cfg_type_optional_keyref, 0 },
00205 { NULL, NULL, 0 },
00206 };
00207
00208 static cfg_type_t cfg_type_namesockaddrkey = {
00209 "namesockaddrkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple,
00210 namesockaddrkey_fields
00211 };
00212
00213 static cfg_type_t cfg_type_bracketed_namesockaddrkeylist = {
00214 "bracketed_namesockaddrkeylist", cfg_parse_bracketed_list,
00215 cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_namesockaddrkey
00216 };
00217
00218 static cfg_tuplefielddef_t namesockaddrkeylist_fields[] = {
00219 { "port", &cfg_type_optional_port, 0 },
00220 { "dscp", &cfg_type_optional_dscp, 0 },
00221 { "addresses", &cfg_type_bracketed_namesockaddrkeylist, 0 },
00222 { NULL, NULL, 0 }
00223 };
00224 static cfg_type_t cfg_type_namesockaddrkeylist = {
00225 "sockaddrkeylist", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple,
00226 namesockaddrkeylist_fields
00227 };
00228
00229
00230
00231
00232
00233 static cfg_tuplefielddef_t portiplist_fields[] = {
00234 { "port", &cfg_type_optional_port, 0 },
00235 { "dscp", &cfg_type_optional_dscp, 0 },
00236 { "addresses", &cfg_type_bracketed_dscpsockaddrlist, 0 },
00237 { NULL, NULL, 0 }
00238 };
00239 static cfg_type_t cfg_type_portiplist = {
00240 "portiplist", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
00241 &cfg_rep_tuple, portiplist_fields
00242 };
00243
00244
00245
00246
00247 static cfg_tuplefielddef_t pubkey_fields[] = {
00248 { "flags", &cfg_type_uint32, 0 },
00249 { "protocol", &cfg_type_uint32, 0 },
00250 { "algorithm", &cfg_type_uint32, 0 },
00251 { "key", &cfg_type_qstring, 0 },
00252 { NULL, NULL, 0 }
00253 };
00254 static cfg_type_t cfg_type_pubkey = {
00255 "pubkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
00256 &cfg_rep_tuple, pubkey_fields };
00257
00258
00259
00260
00261
00262 static cfg_type_t cfg_type_rrtypelist = {
00263 "rrtypelist", cfg_parse_spacelist, cfg_print_spacelist,
00264 cfg_doc_terminal, &cfg_rep_list, &cfg_type_astring
00265 };
00266
00267 static const char *mode_enums[] = { "grant", "deny", NULL };
00268 static cfg_type_t cfg_type_mode = {
00269 "mode", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
00270 &cfg_rep_string, &mode_enums
00271 };
00272
00273 static isc_result_t
00274 parse_matchtype(cfg_parser_t *pctx, const cfg_type_t *type,
00275 cfg_obj_t **ret) {
00276 isc_result_t result;
00277
00278 CHECK(cfg_peektoken(pctx, 0));
00279 if (pctx->token.type == isc_tokentype_string &&
00280 strcasecmp(TOKEN_STRING(pctx), "zonesub") == 0) {
00281 pctx->flags |= CFG_PCTX_SKIP;
00282 }
00283 return (cfg_parse_enum(pctx, type, ret));
00284
00285 cleanup:
00286 return (result);
00287 }
00288
00289 static isc_result_t
00290 parse_matchname(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
00291 isc_result_t result;
00292 cfg_obj_t *obj = NULL;
00293
00294 if ((pctx->flags & CFG_PCTX_SKIP) != 0) {
00295 pctx->flags &= ~CFG_PCTX_SKIP;
00296 CHECK(cfg_parse_void(pctx, NULL, &obj));
00297 } else
00298 result = cfg_parse_astring(pctx, type, &obj);
00299
00300 *ret = obj;
00301 cleanup:
00302 return (result);
00303 }
00304
00305 static void
00306 doc_matchname(cfg_printer_t *pctx, const cfg_type_t *type) {
00307 cfg_print_cstr(pctx, "[ ");
00308 cfg_doc_obj(pctx, type->of);
00309 cfg_print_cstr(pctx, " ]");
00310 }
00311
00312 static const char *matchtype_enums[] = {
00313 "name", "subdomain", "wildcard", "self", "selfsub", "selfwild",
00314 "krb5-self", "ms-self", "krb5-subdomain", "ms-subdomain",
00315 "tcp-self", "6to4-self", "zonesub", "external", NULL };
00316
00317 static cfg_type_t cfg_type_matchtype = {
00318 "matchtype", parse_matchtype, cfg_print_ustring,
00319 cfg_doc_enum, &cfg_rep_string, &matchtype_enums
00320 };
00321
00322 static cfg_type_t cfg_type_matchname = {
00323 "optional_matchname", parse_matchname, cfg_print_ustring,
00324 &doc_matchname, &cfg_rep_tuple, &cfg_type_ustring
00325 };
00326
00327
00328
00329
00330 static cfg_tuplefielddef_t grant_fields[] = {
00331 { "mode", &cfg_type_mode, 0 },
00332 { "identity", &cfg_type_astring, 0 },
00333 { "matchtype", &cfg_type_matchtype, 0 },
00334 { "name", &cfg_type_matchname, 0 },
00335 { "types", &cfg_type_rrtypelist, 0 },
00336 { NULL, NULL, 0 }
00337 };
00338 static cfg_type_t cfg_type_grant = {
00339 "grant", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
00340 &cfg_rep_tuple, grant_fields
00341 };
00342
00343 static cfg_type_t cfg_type_updatepolicy = {
00344 "update_policy", parse_updatepolicy, print_updatepolicy,
00345 doc_updatepolicy, &cfg_rep_list, &cfg_type_grant
00346 };
00347
00348 static isc_result_t
00349 parse_updatepolicy(cfg_parser_t *pctx, const cfg_type_t *type,
00350 cfg_obj_t **ret) {
00351 isc_result_t result;
00352 CHECK(cfg_gettoken(pctx, 0));
00353 if (pctx->token.type == isc_tokentype_special &&
00354 pctx->token.value.as_char == '{') {
00355 cfg_ungettoken(pctx);
00356 return (cfg_parse_bracketed_list(pctx, type, ret));
00357 }
00358
00359 if (pctx->token.type == isc_tokentype_string &&
00360 strcasecmp(TOKEN_STRING(pctx), "local") == 0) {
00361 cfg_obj_t *obj = NULL;
00362 CHECK(cfg_create_obj(pctx, &cfg_type_ustring, &obj));
00363 obj->value.string.length = strlen("local");
00364 obj->value.string.base = isc_mem_get(pctx->mctx,
00365 obj->value.string.length + 1);
00366 if (obj->value.string.base == NULL) {
00367 isc_mem_put(pctx->mctx, obj, sizeof(*obj));
00368 return (ISC_R_NOMEMORY);
00369 }
00370 memmove(obj->value.string.base, "local", 5);
00371 obj->value.string.base[5] = '\0';
00372 *ret = obj;
00373 return (ISC_R_SUCCESS);
00374 }
00375
00376 cfg_ungettoken(pctx);
00377 return (ISC_R_UNEXPECTEDTOKEN);
00378
00379 cleanup:
00380 return (result);
00381 }
00382
00383 static void
00384 print_updatepolicy(cfg_printer_t *pctx, const cfg_obj_t *obj) {
00385 if (cfg_obj_isstring(obj))
00386 cfg_print_ustring(pctx, obj);
00387 else
00388 cfg_print_bracketed_list(pctx, obj);
00389 }
00390
00391 static void
00392 doc_updatepolicy(cfg_printer_t *pctx, const cfg_type_t *type) {
00393 cfg_print_cstr(pctx, "( local | { ");
00394 cfg_doc_obj(pctx, type->of);
00395 cfg_print_cstr(pctx, "; ... }");
00396 }
00397
00398
00399
00400
00401 static cfg_tuplefielddef_t view_fields[] = {
00402 { "name", &cfg_type_astring, 0 },
00403 { "class", &cfg_type_optional_class, 0 },
00404 { "options", &cfg_type_viewopts, 0 },
00405 { NULL, NULL, 0 }
00406 };
00407 static cfg_type_t cfg_type_view = {
00408 "view", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
00409 &cfg_rep_tuple, view_fields
00410 };
00411
00412
00413
00414
00415 static cfg_tuplefielddef_t zone_fields[] = {
00416 { "name", &cfg_type_astring, 0 },
00417 { "class", &cfg_type_optional_class, 0 },
00418 { "options", &cfg_type_zoneopts, 0 },
00419 { NULL, NULL, 0 }
00420 };
00421 static cfg_type_t cfg_type_zone = {
00422 "zone", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
00423 &cfg_rep_tuple, zone_fields
00424 };
00425
00426
00427
00428
00429 static cfg_tuplefielddef_t category_fields[] = {
00430 { "name", &cfg_type_astring, 0 },
00431 { "destinations", &cfg_type_destinationlist,0 },
00432 { NULL, NULL, 0 }
00433 };
00434 static cfg_type_t cfg_type_category = {
00435 "category", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
00436 &cfg_rep_tuple, category_fields
00437 };
00438
00439
00440
00441
00442
00443 static cfg_tuplefielddef_t dnsseckey_fields[] = {
00444 { "name", &cfg_type_astring, 0 },
00445 { "flags", &cfg_type_uint32, 0 },
00446 { "protocol", &cfg_type_uint32, 0 },
00447 { "algorithm", &cfg_type_uint32, 0 },
00448 { "key", &cfg_type_qstring, 0 },
00449 { NULL, NULL, 0 }
00450 };
00451 static cfg_type_t cfg_type_dnsseckey = {
00452 "dnsseckey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
00453 &cfg_rep_tuple, dnsseckey_fields
00454 };
00455
00456
00457
00458
00459
00460 static cfg_tuplefielddef_t managedkey_fields[] = {
00461 { "name", &cfg_type_astring, 0 },
00462 { "init", &cfg_type_ustring, 0 },
00463 { "flags", &cfg_type_uint32, 0 },
00464 { "protocol", &cfg_type_uint32, 0 },
00465 { "algorithm", &cfg_type_uint32, 0 },
00466 { "key", &cfg_type_qstring, 0 },
00467 { NULL, NULL, 0 }
00468 };
00469 static cfg_type_t cfg_type_managedkey = {
00470 "managedkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
00471 &cfg_rep_tuple, managedkey_fields
00472 };
00473
00474 static keyword_type_t wild_class_kw = { "class", &cfg_type_ustring };
00475
00476 static cfg_type_t cfg_type_optional_wild_class = {
00477 "optional_wild_class", parse_optional_keyvalue, print_keyvalue,
00478 doc_optional_keyvalue, &cfg_rep_string, &wild_class_kw
00479 };
00480
00481 static keyword_type_t wild_type_kw = { "type", &cfg_type_ustring };
00482
00483 static cfg_type_t cfg_type_optional_wild_type = {
00484 "optional_wild_type", parse_optional_keyvalue,
00485 print_keyvalue, doc_optional_keyvalue, &cfg_rep_string, &wild_type_kw
00486 };
00487
00488 static keyword_type_t wild_name_kw = { "name", &cfg_type_qstring };
00489
00490 static cfg_type_t cfg_type_optional_wild_name = {
00491 "optional_wild_name", parse_optional_keyvalue,
00492 print_keyvalue, doc_optional_keyvalue, &cfg_rep_string, &wild_name_kw
00493 };
00494
00495
00496
00497
00498 static cfg_tuplefielddef_t rrsetorderingelement_fields[] = {
00499 { "class", &cfg_type_optional_wild_class, 0 },
00500 { "type", &cfg_type_optional_wild_type, 0 },
00501 { "name", &cfg_type_optional_wild_name, 0 },
00502 { "order", &cfg_type_ustring, 0 },
00503 { "ordering", &cfg_type_ustring, 0 },
00504 { NULL, NULL, 0 }
00505 };
00506 static cfg_type_t cfg_type_rrsetorderingelement = {
00507 "rrsetorderingelement", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple,
00508 rrsetorderingelement_fields
00509 };
00510
00511
00512
00513
00514
00515
00516 static const char *checktype_enums[] = { "master", "slave", "response", NULL };
00517 static cfg_type_t cfg_type_checktype = {
00518 "checktype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
00519 &cfg_rep_string, &checktype_enums
00520 };
00521
00522 static const char *checkmode_enums[] = { "fail", "warn", "ignore", NULL };
00523 static cfg_type_t cfg_type_checkmode = {
00524 "checkmode", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
00525 &cfg_rep_string, &checkmode_enums
00526 };
00527
00528 static const char *warn_enums[] = { "warn", "ignore", NULL };
00529 static cfg_type_t cfg_type_warn = {
00530 "warn", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
00531 &cfg_rep_string, &warn_enums
00532 };
00533
00534 static cfg_tuplefielddef_t checknames_fields[] = {
00535 { "type", &cfg_type_checktype, 0 },
00536 { "mode", &cfg_type_checkmode, 0 },
00537 { NULL, NULL, 0 }
00538 };
00539
00540 static cfg_type_t cfg_type_checknames = {
00541 "checknames", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
00542 &cfg_rep_tuple, checknames_fields
00543 };
00544
00545 static cfg_type_t cfg_type_bracketed_dscpsockaddrlist = {
00546 "bracketed_sockaddrlist", cfg_parse_bracketed_list,
00547 cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list,
00548 &cfg_type_sockaddrdscp
00549 };
00550
00551 static cfg_type_t cfg_type_bracketed_sockaddrlist = {
00552 "bracketed_sockaddrlist", cfg_parse_bracketed_list,
00553 cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list,
00554 &cfg_type_sockaddr
00555 };
00556
00557 static const char *autodnssec_enums[] = { "allow", "maintain", "off", NULL };
00558 static cfg_type_t cfg_type_autodnssec = {
00559 "autodnssec", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
00560 &cfg_rep_string, &autodnssec_enums
00561 };
00562
00563 static const char *dnssecupdatemode_enums[] = { "maintain", "no-resign", NULL };
00564 static cfg_type_t cfg_type_dnssecupdatemode = {
00565 "dnssecupdatemode", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
00566 &cfg_rep_string, &dnssecupdatemode_enums
00567 };
00568
00569 static const char *updatemethods_enums[] = {
00570 "increment", "unixtime", "date", NULL };
00571 static cfg_type_t cfg_type_updatemethod = {
00572 "updatemethod", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
00573 &cfg_rep_string, &updatemethods_enums
00574 };
00575
00576
00577
00578
00579
00580
00581
00582
00583 static const char *zonestat_enums[] = { "full", "terse", "none", NULL };
00584 static isc_result_t
00585 parse_zonestat(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
00586 return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
00587 }
00588 static cfg_type_t cfg_type_zonestat = {
00589 "zonestat", parse_zonestat, cfg_print_ustring, doc_enum_or_other,
00590 &cfg_rep_string, zonestat_enums
00591 };
00592
00593 static cfg_type_t cfg_type_rrsetorder = {
00594 "rrsetorder", cfg_parse_bracketed_list, cfg_print_bracketed_list,
00595 cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_rrsetorderingelement
00596 };
00597
00598 static keyword_type_t dscp_kw = { "dscp", &cfg_type_uint32 };
00599
00600 static cfg_type_t cfg_type_optional_dscp = {
00601 "optional_dscp", parse_optional_keyvalue, print_keyvalue,
00602 doc_optional_keyvalue, &cfg_rep_uint32, &dscp_kw
00603 };
00604
00605 static keyword_type_t port_kw = { "port", &cfg_type_uint32 };
00606
00607 static cfg_type_t cfg_type_optional_port = {
00608 "optional_port", parse_optional_keyvalue, print_keyvalue,
00609 doc_optional_keyvalue, &cfg_rep_uint32, &port_kw
00610 };
00611
00612
00613 static cfg_type_t cfg_type_keylist = {
00614 "keylist", cfg_parse_bracketed_list, cfg_print_bracketed_list,
00615 cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring
00616 };
00617
00618
00619 static cfg_type_t cfg_type_dnsseckeys = {
00620 "dnsseckeys", cfg_parse_bracketed_list, cfg_print_bracketed_list,
00621 cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_dnsseckey
00622 };
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 static cfg_type_t cfg_type_managedkeys = {
00633 "managedkeys", cfg_parse_bracketed_list, cfg_print_bracketed_list,
00634 cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_managedkey
00635 };
00636
00637 static const char *forwardtype_enums[] = { "first", "only", NULL };
00638 static cfg_type_t cfg_type_forwardtype = {
00639 "forwardtype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string,
00640 &forwardtype_enums
00641 };
00642
00643 static const char *zonetype_enums[] = {
00644 "master", "slave", "stub", "static-stub", "hint", "forward",
00645 "delegation-only", "redirect", NULL };
00646 static cfg_type_t cfg_type_zonetype = {
00647 "zonetype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
00648 &cfg_rep_string, &zonetype_enums
00649 };
00650
00651 static const char *loglevel_enums[] = {
00652 "critical", "error", "warning", "notice", "info", "dynamic", NULL };
00653 static cfg_type_t cfg_type_loglevel = {
00654 "loglevel", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string,
00655 &loglevel_enums
00656 };
00657
00658 static const char *transferformat_enums[] = {
00659 "many-answers", "one-answer", NULL };
00660 static cfg_type_t cfg_type_transferformat = {
00661 "transferformat", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string,
00662 &transferformat_enums
00663 };
00664
00665
00666
00667
00668
00669 static void
00670 print_none(cfg_printer_t *pctx, const cfg_obj_t *obj) {
00671 UNUSED(obj);
00672 cfg_print_cstr(pctx, "none");
00673 }
00674
00675 static cfg_type_t cfg_type_none = {
00676 "none", NULL, print_none, NULL, &cfg_rep_void, NULL
00677 };
00678
00679
00680
00681
00682 static isc_result_t
00683 parse_qstringornone(cfg_parser_t *pctx, const cfg_type_t *type,
00684 cfg_obj_t **ret)
00685 {
00686 isc_result_t result;
00687
00688 CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING));
00689 if (pctx->token.type == isc_tokentype_string &&
00690 strcasecmp(TOKEN_STRING(pctx), "none") == 0)
00691 return (cfg_create_obj(pctx, &cfg_type_none, ret));
00692 cfg_ungettoken(pctx);
00693 return (cfg_parse_qstring(pctx, type, ret));
00694 cleanup:
00695 return (result);
00696 }
00697
00698 static void
00699 doc_qstringornone(cfg_printer_t *pctx, const cfg_type_t *type) {
00700 UNUSED(type);
00701 cfg_print_cstr(pctx, "( <quoted_string> | none )");
00702 }
00703
00704 static cfg_type_t cfg_type_qstringornone = {
00705 "qstringornone", parse_qstringornone, NULL, doc_qstringornone,
00706 NULL, NULL
00707 };
00708
00709
00710
00711
00712
00713 static void
00714 print_auto(cfg_printer_t *pctx, const cfg_obj_t *obj) {
00715 UNUSED(obj);
00716 cfg_print_cstr(pctx, "auto");
00717 }
00718
00719 static cfg_type_t cfg_type_auto = {
00720 "auto", NULL, print_auto, NULL, &cfg_rep_void, NULL
00721 };
00722
00723 static isc_result_t
00724 parse_boolorauto(cfg_parser_t *pctx, const cfg_type_t *type,
00725 cfg_obj_t **ret)
00726 {
00727 isc_result_t result;
00728
00729 CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING));
00730 if (pctx->token.type == isc_tokentype_string &&
00731 strcasecmp(TOKEN_STRING(pctx), "auto") == 0)
00732 return (cfg_create_obj(pctx, &cfg_type_auto, ret));
00733 cfg_ungettoken(pctx);
00734 return (cfg_parse_boolean(pctx, type, ret));
00735 cleanup:
00736 return (result);
00737 }
00738
00739 static void
00740 print_boolorauto(cfg_printer_t *pctx, const cfg_obj_t *obj) {
00741 if (obj->type->rep == &cfg_rep_void)
00742 cfg_print_cstr(pctx, "auto");
00743 else if (obj->value.boolean)
00744 cfg_print_cstr(pctx, "yes");
00745 else
00746 cfg_print_cstr(pctx, "no");
00747 }
00748
00749 static void
00750 doc_boolorauto(cfg_printer_t *pctx, const cfg_type_t *type) {
00751 UNUSED(type);
00752 cfg_print_cstr(pctx, "( yes | no | auto )");
00753 }
00754
00755 static cfg_type_t cfg_type_boolorauto = {
00756 "boolorauto", parse_boolorauto, print_boolorauto,
00757 doc_boolorauto, NULL, NULL
00758 };
00759
00760
00761
00762
00763 static void
00764 print_hostname(cfg_printer_t *pctx, const cfg_obj_t *obj) {
00765 UNUSED(obj);
00766 cfg_print_cstr(pctx, "hostname");
00767 }
00768
00769 static cfg_type_t cfg_type_hostname = {
00770 "hostname", NULL, print_hostname, NULL, &cfg_rep_boolean, NULL
00771 };
00772
00773
00774
00775
00776
00777 static isc_result_t
00778 parse_serverid(cfg_parser_t *pctx, const cfg_type_t *type,
00779 cfg_obj_t **ret)
00780 {
00781 isc_result_t result;
00782 CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING));
00783 if (pctx->token.type == isc_tokentype_string &&
00784 strcasecmp(TOKEN_STRING(pctx), "none") == 0)
00785 return (cfg_create_obj(pctx, &cfg_type_none, ret));
00786 if (pctx->token.type == isc_tokentype_string &&
00787 strcasecmp(TOKEN_STRING(pctx), "hostname") == 0) {
00788 result = cfg_create_obj(pctx, &cfg_type_hostname, ret);
00789 if (result == ISC_R_SUCCESS)
00790 (*ret)->value.boolean = ISC_TRUE;
00791 return (result);
00792 }
00793 cfg_ungettoken(pctx);
00794 return (cfg_parse_qstring(pctx, type, ret));
00795 cleanup:
00796 return (result);
00797 }
00798
00799 static void
00800 doc_serverid(cfg_printer_t *pctx, const cfg_type_t *type) {
00801 UNUSED(type);
00802 cfg_print_cstr(pctx, "( <quoted_string> | none | hostname )");
00803 }
00804
00805 static cfg_type_t cfg_type_serverid = {
00806 "serverid", parse_serverid, NULL, doc_serverid, NULL, NULL };
00807
00808
00809
00810
00811 static cfg_tuplefielddef_t porttuple_fields[] = {
00812 { "loport", &cfg_type_uint32, 0 },
00813 { "hiport", &cfg_type_uint32, 0 },
00814 { NULL, NULL, 0 }
00815 };
00816 static cfg_type_t cfg_type_porttuple = {
00817 "porttuple", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
00818 &cfg_rep_tuple, porttuple_fields
00819 };
00820
00821 static isc_result_t
00822 parse_port(cfg_parser_t *pctx, cfg_obj_t **ret) {
00823 isc_result_t result;
00824
00825 CHECK(cfg_parse_uint32(pctx, NULL, ret));
00826 if ((*ret)->value.uint32 > 0xffff) {
00827 cfg_parser_error(pctx, CFG_LOG_NEAR, "invalid port");
00828 cfg_obj_destroy(pctx, ret);
00829 result = ISC_R_RANGE;
00830 }
00831
00832 cleanup:
00833 return (result);
00834 }
00835
00836 static isc_result_t
00837 parse_portrange(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
00838 isc_result_t result;
00839 cfg_obj_t *obj = NULL;
00840
00841 UNUSED(type);
00842
00843 CHECK(cfg_peektoken(pctx, ISC_LEXOPT_NUMBER | ISC_LEXOPT_CNUMBER));
00844 if (pctx->token.type == isc_tokentype_number)
00845 CHECK(parse_port(pctx, ret));
00846 else {
00847 CHECK(cfg_gettoken(pctx, 0));
00848 if (pctx->token.type != isc_tokentype_string ||
00849 strcasecmp(TOKEN_STRING(pctx), "range") != 0) {
00850 cfg_parser_error(pctx, CFG_LOG_NEAR,
00851 "expected integer or 'range'");
00852 return (ISC_R_UNEXPECTEDTOKEN);
00853 }
00854 CHECK(cfg_create_tuple(pctx, &cfg_type_porttuple, &obj));
00855 CHECK(parse_port(pctx, &obj->value.tuple[0]));
00856 CHECK(parse_port(pctx, &obj->value.tuple[1]));
00857 if (obj->value.tuple[0]->value.uint32 >
00858 obj->value.tuple[1]->value.uint32) {
00859 cfg_parser_error(pctx, CFG_LOG_NOPREP,
00860 "low port '%u' must not be larger "
00861 "than high port",
00862 obj->value.tuple[0]->value.uint32);
00863 result = ISC_R_RANGE;
00864 goto cleanup;
00865 }
00866 *ret = obj;
00867 obj = NULL;
00868 }
00869
00870 cleanup:
00871 if (obj != NULL)
00872 cfg_obj_destroy(pctx, &obj);
00873 return (result);
00874 }
00875
00876 static cfg_type_t cfg_type_portrange = {
00877 "portrange", parse_portrange, NULL, cfg_doc_terminal,
00878 NULL, NULL
00879 };
00880
00881 static cfg_type_t cfg_type_bracketed_portlist = {
00882 "bracketed_sockaddrlist", cfg_parse_bracketed_list,
00883 cfg_print_bracketed_list, cfg_doc_bracketed_list,
00884 &cfg_rep_list, &cfg_type_portrange
00885 };
00886
00887
00888
00889
00890
00891 static cfg_clausedef_t
00892 namedconf_clauses[] = {
00893 { "options", &cfg_type_options, 0 },
00894 { "controls", &cfg_type_controls, CFG_CLAUSEFLAG_MULTI },
00895 { "acl", &cfg_type_acl, CFG_CLAUSEFLAG_MULTI },
00896 { "masters", &cfg_type_masters, CFG_CLAUSEFLAG_MULTI },
00897 { "logging", &cfg_type_logging, 0 },
00898 { "view", &cfg_type_view, CFG_CLAUSEFLAG_MULTI },
00899 { "lwres", &cfg_type_lwres, CFG_CLAUSEFLAG_MULTI },
00900 { "statistics-channels", &cfg_type_statschannels,
00901 CFG_CLAUSEFLAG_MULTI },
00902 { NULL, NULL, 0 }
00903 };
00904
00905
00906
00907
00908
00909 static cfg_clausedef_t
00910 namedconf_or_view_clauses[] = {
00911 { "key", &cfg_type_key, CFG_CLAUSEFLAG_MULTI },
00912 { "zone", &cfg_type_zone, CFG_CLAUSEFLAG_MULTI },
00913 { "dlz", &cfg_type_dlz, CFG_CLAUSEFLAG_MULTI },
00914 { "server", &cfg_type_server, CFG_CLAUSEFLAG_MULTI },
00915 { "trusted-keys", &cfg_type_dnsseckeys, CFG_CLAUSEFLAG_MULTI },
00916 { "managed-keys", &cfg_type_managedkeys, CFG_CLAUSEFLAG_MULTI },
00917 { NULL, NULL, 0 }
00918 };
00919
00920
00921
00922
00923 static cfg_clausedef_t
00924 bindkeys_clauses[] = {
00925 { "trusted-keys", &cfg_type_dnsseckeys, CFG_CLAUSEFLAG_MULTI },
00926 { "managed-keys", &cfg_type_managedkeys, CFG_CLAUSEFLAG_MULTI },
00927 { NULL, NULL, 0 }
00928 };
00929
00930
00931
00932
00933 static cfg_clausedef_t
00934 options_clauses[] = {
00935 { "automatic-interface-scan", &cfg_type_boolean, 0 },
00936 { "avoid-v4-udp-ports", &cfg_type_bracketed_portlist, 0 },
00937 { "avoid-v6-udp-ports", &cfg_type_bracketed_portlist, 0 },
00938 { "bindkeys-file", &cfg_type_qstring, 0 },
00939 { "blackhole", &cfg_type_bracketed_aml, 0 },
00940 { "coresize", &cfg_type_size, 0 },
00941 { "datasize", &cfg_type_size, 0 },
00942 { "session-keyfile", &cfg_type_qstringornone, 0 },
00943 { "session-keyname", &cfg_type_astring, 0 },
00944 { "session-keyalg", &cfg_type_astring, 0 },
00945 { "deallocate-on-exit", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
00946 { "directory", &cfg_type_qstring, CFG_CLAUSEFLAG_CALLBACK },
00947 { "dscp", &cfg_type_uint32, 0 },
00948 { "dump-file", &cfg_type_qstring, 0 },
00949 { "fake-iquery", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
00950 { "files", &cfg_type_size, 0 },
00951 { "flush-zones-on-shutdown", &cfg_type_boolean, 0 },
00952 #ifdef HAVE_GEOIP
00953 { "geoip-directory", &cfg_type_qstringornone, 0 },
00954 { "geoip-use-ecs", &cfg_type_boolean, 0 },
00955 #else
00956 { "geoip-directory", &cfg_type_qstringornone,
00957 CFG_CLAUSEFLAG_NOTCONFIGURED },
00958 { "geoip-use-ecs", &cfg_type_qstringornone,
00959 CFG_CLAUSEFLAG_NOTCONFIGURED },
00960 #endif
00961 { "has-old-clients", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
00962 { "heartbeat-interval", &cfg_type_uint32, 0 },
00963 { "host-statistics", &cfg_type_boolean, CFG_CLAUSEFLAG_NOTIMP },
00964 { "host-statistics-max", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTIMP },
00965 { "hostname", &cfg_type_qstringornone, 0 },
00966 { "interface-interval", &cfg_type_uint32, 0 },
00967 { "keep-response-order", &cfg_type_bracketed_aml, 0 },
00968 { "listen-on", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI },
00969 { "listen-on-v6", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI },
00970 { "lock-file", &cfg_type_qstringornone, 0 },
00971 #ifdef ISC_PLATFORM_USESIT
00972 { "sit-secret", &cfg_type_sstring, 0 },
00973 #else
00974 { "sit-secret", &cfg_type_sstring, CFG_CLAUSEFLAG_NOTCONFIGURED },
00975 #endif
00976 { "managed-keys-directory", &cfg_type_qstring, 0 },
00977 { "match-mapped-addresses", &cfg_type_boolean, 0 },
00978 { "max-rsa-exponent-size", &cfg_type_uint32, 0 },
00979 { "memstatistics-file", &cfg_type_qstring, 0 },
00980 { "memstatistics", &cfg_type_boolean, 0 },
00981 { "multiple-cnames", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
00982 { "named-xfer", &cfg_type_qstring, CFG_CLAUSEFLAG_OBSOLETE },
00983 { "notify-rate", &cfg_type_uint32, 0 },
00984 { "pid-file", &cfg_type_qstringornone, 0 },
00985 { "port", &cfg_type_uint32, 0 },
00986 { "querylog", &cfg_type_boolean, 0 },
00987 { "recursing-file", &cfg_type_qstring, 0 },
00988 { "random-device", &cfg_type_qstring, 0 },
00989 { "recursive-clients", &cfg_type_uint32, 0 },
00990 { "reserved-sockets", &cfg_type_uint32, 0 },
00991 { "secroots-file", &cfg_type_qstring, 0 },
00992 { "serial-queries", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE },
00993 { "serial-query-rate", &cfg_type_uint32, 0 },
00994 { "server-id", &cfg_type_serverid, 0 },
00995 { "stacksize", &cfg_type_size, 0 },
00996 { "startup-notify-rate", &cfg_type_uint32, 0 },
00997 { "statistics-file", &cfg_type_qstring, 0 },
00998 { "statistics-interval", &cfg_type_uint32, CFG_CLAUSEFLAG_NYI },
00999 { "tcp-clients", &cfg_type_uint32, 0 },
01000 { "tcp-listen-queue", &cfg_type_uint32, 0 },
01001 { "tkey-dhkey", &cfg_type_tkey_dhkey, 0 },
01002 { "tkey-gssapi-credential", &cfg_type_qstring, 0 },
01003 { "tkey-gssapi-keytab", &cfg_type_qstring, 0 },
01004 { "tkey-domain", &cfg_type_qstring, 0 },
01005 { "transfers-per-ns", &cfg_type_uint32, 0 },
01006 { "transfers-in", &cfg_type_uint32, 0 },
01007 { "transfers-out", &cfg_type_uint32, 0 },
01008 { "treat-cr-as-space", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
01009 { "use-id-pool", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
01010 { "use-ixfr", &cfg_type_boolean, 0 },
01011 { "use-v4-udp-ports", &cfg_type_bracketed_portlist, 0 },
01012 { "use-v6-udp-ports", &cfg_type_bracketed_portlist, 0 },
01013 { "version", &cfg_type_qstringornone, 0 },
01014 { NULL, NULL, 0 }
01015 };
01016
01017 static cfg_type_t cfg_type_namelist = {
01018 "namelist", cfg_parse_bracketed_list, cfg_print_bracketed_list,
01019 cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_qstring };
01020
01021 static keyword_type_t exclude_kw = { "exclude", &cfg_type_namelist };
01022
01023 static cfg_type_t cfg_type_optional_exclude = {
01024 "optional_exclude", parse_optional_keyvalue, print_keyvalue,
01025 doc_optional_keyvalue, &cfg_rep_list, &exclude_kw };
01026
01027 static keyword_type_t exceptionnames_kw = { "except-from", &cfg_type_namelist };
01028
01029 static cfg_type_t cfg_type_optional_exceptionnames = {
01030 "optional_allow", parse_optional_keyvalue, print_keyvalue,
01031 doc_optional_keyvalue, &cfg_rep_list, &exceptionnames_kw };
01032
01033 static cfg_tuplefielddef_t denyaddresses_fields[] = {
01034 { "acl", &cfg_type_bracketed_aml, 0 },
01035 { "except-from", &cfg_type_optional_exceptionnames, 0 },
01036 { NULL, NULL, 0 }
01037 };
01038
01039 static cfg_type_t cfg_type_denyaddresses = {
01040 "denyaddresses", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
01041 &cfg_rep_tuple, denyaddresses_fields
01042 };
01043
01044 static cfg_tuplefielddef_t denyaliases_fields[] = {
01045 { "name", &cfg_type_namelist, 0 },
01046 { "except-from", &cfg_type_optional_exceptionnames, 0 },
01047 { NULL, NULL, 0 }
01048 };
01049
01050 static cfg_type_t cfg_type_denyaliases = {
01051 "denyaliases", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
01052 &cfg_rep_tuple, denyaliases_fields
01053 };
01054
01055 static cfg_type_t cfg_type_algorithmlist = {
01056 "algorithmlist", cfg_parse_bracketed_list, cfg_print_bracketed_list,
01057 cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring };
01058
01059 static cfg_tuplefielddef_t disablealgorithm_fields[] = {
01060 { "name", &cfg_type_astring, 0 },
01061 { "algorithms", &cfg_type_algorithmlist, 0 },
01062 { NULL, NULL, 0 }
01063 };
01064
01065 static cfg_type_t cfg_type_disablealgorithm = {
01066 "disablealgorithm", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
01067 &cfg_rep_tuple, disablealgorithm_fields
01068 };
01069
01070 static cfg_type_t cfg_type_dsdigestlist = {
01071 "dsdigestlist", cfg_parse_bracketed_list, cfg_print_bracketed_list,
01072 cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring };
01073
01074 static cfg_tuplefielddef_t disabledsdigest_fields[] = {
01075 { "name", &cfg_type_astring, 0 },
01076 { "digests", &cfg_type_dsdigestlist, 0 },
01077 { NULL, NULL, 0 }
01078 };
01079
01080 static cfg_type_t cfg_type_disabledsdigest = {
01081 "disabledsdigest", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
01082 &cfg_rep_tuple, disabledsdigest_fields
01083 };
01084
01085 static cfg_tuplefielddef_t mustbesecure_fields[] = {
01086 { "name", &cfg_type_astring, 0 },
01087 { "value", &cfg_type_boolean, 0 },
01088 { NULL, NULL, 0 }
01089 };
01090
01091 static cfg_type_t cfg_type_mustbesecure = {
01092 "mustbesecure", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
01093 &cfg_rep_tuple, mustbesecure_fields
01094 };
01095
01096 static const char *masterformat_enums[] = { "text", "raw", "map", NULL };
01097 static cfg_type_t cfg_type_masterformat = {
01098 "masterformat", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
01099 &cfg_rep_string, &masterformat_enums
01100 };
01101
01102 static const char *masterstyle_enums[] = { "full", "relative", NULL };
01103 static cfg_type_t cfg_type_masterstyle = {
01104 "masterstyle", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
01105 &cfg_rep_string, &masterstyle_enums
01106 };
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119 static void
01120 doc_rpz_policy(cfg_printer_t *pctx, const cfg_type_t *type) {
01121 const char * const *p;
01122
01123
01124
01125 cfg_print_cstr(pctx, "( ");
01126 for (p = type->of; *p != NULL; p++) {
01127 cfg_print_cstr(pctx, *p);
01128 if (p[1] != NULL)
01129 cfg_print_cstr(pctx, " | ");
01130 }
01131 }
01132
01133 static void
01134 doc_rpz_cname(cfg_printer_t *pctx, const cfg_type_t *type) {
01135 cfg_doc_terminal(pctx, type);
01136 cfg_print_cstr(pctx, " )");
01137 }
01138
01139
01140
01141
01142
01143 static isc_result_t
01144 cfg_parse_rpz_policy(cfg_parser_t *pctx, const cfg_type_t *type,
01145 cfg_obj_t **ret)
01146 {
01147 isc_result_t result;
01148 cfg_obj_t *obj;
01149 const cfg_tuplefielddef_t *fields;
01150
01151 CHECK(cfg_create_tuple(pctx, type, &obj));
01152
01153 fields = type->of;
01154 CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));
01155
01156
01157
01158 if (strcasecmp("cname", cfg_obj_asstring(obj->value.tuple[0])) != 0) {
01159 CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[1]));
01160 } else {
01161 CHECK(cfg_parse_obj(pctx, fields[1].type,
01162 &obj->value.tuple[1]));
01163 }
01164
01165 *ret = obj;
01166 return (ISC_R_SUCCESS);
01167
01168 cleanup:
01169 CLEANUP_OBJ(obj);
01170 return (result);
01171 }
01172
01173
01174
01175
01176
01177 static isc_result_t
01178 cfg_parse_kv_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
01179 const cfg_tuplefielddef_t *fields, *f;
01180 cfg_obj_t *obj;
01181 int fn;
01182 isc_result_t result;
01183
01184 obj = NULL;
01185 CHECK(cfg_create_tuple(pctx, type, &obj));
01186
01187
01188
01189
01190 fields = type->of;
01191 CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));
01192
01193 for (;;) {
01194 CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING));
01195 if (pctx->token.type != isc_tokentype_string)
01196 break;
01197
01198 for (fn = 1, f = &fields[1]; ; ++fn, ++f) {
01199 if (f->name == NULL) {
01200 cfg_parser_error(pctx, 0, "unexpected '%s'",
01201 TOKEN_STRING(pctx));
01202 result = ISC_R_UNEXPECTEDTOKEN;
01203 goto cleanup;
01204 }
01205 if (obj->value.tuple[fn] == NULL &&
01206 strcasecmp(f->name, TOKEN_STRING(pctx)) == 0)
01207 break;
01208 }
01209
01210 CHECK(cfg_gettoken(pctx, 0));
01211 CHECK(cfg_parse_obj(pctx, f->type, &obj->value.tuple[fn]));
01212 }
01213
01214 for (fn = 1, f = &fields[1]; f->name != NULL; ++fn, ++f) {
01215 if (obj->value.tuple[fn] == NULL)
01216 CHECK(cfg_parse_void(pctx, NULL,
01217 &obj->value.tuple[fn]));
01218 }
01219
01220 *ret = obj;
01221 return (ISC_R_SUCCESS);
01222
01223 cleanup:
01224 CLEANUP_OBJ(obj);
01225 return (result);
01226 }
01227
01228 static void
01229 cfg_print_kv_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj) {
01230 unsigned int i;
01231 const cfg_tuplefielddef_t *fields, *f;
01232 const cfg_obj_t *fieldobj;
01233
01234 fields = obj->type->of;
01235 for (f = fields, i = 0; f->name != NULL; f++, i++) {
01236 fieldobj = obj->value.tuple[i];
01237 if (fieldobj->type->print == cfg_print_void)
01238 continue;
01239 if (i != 0) {
01240 cfg_print_cstr(pctx, " ");
01241 cfg_print_cstr(pctx, f->name);
01242 cfg_print_cstr(pctx, " ");
01243 }
01244 cfg_print_obj(pctx, fieldobj);
01245 }
01246 }
01247
01248 static void
01249 cfg_doc_kv_tuple(cfg_printer_t *pctx, const cfg_type_t *type) {
01250 const cfg_tuplefielddef_t *fields, *f;
01251
01252 fields = type->of;
01253 for (f = fields; f->name != NULL; f++) {
01254 if (f != fields) {
01255 cfg_print_cstr(pctx, " [ ");
01256 cfg_print_cstr(pctx, f->name);
01257 if (f->type->doc != cfg_doc_void)
01258 cfg_print_cstr(pctx, " ");
01259 }
01260 cfg_doc_obj(pctx, f->type);
01261 if (f != fields)
01262 cfg_print_cstr(pctx, " ]");
01263 }
01264 }
01265
01266 static keyword_type_t zone_kw = {"zone", &cfg_type_qstring};
01267 static cfg_type_t cfg_type_rpz_zone = {
01268 "zone", parse_keyvalue, print_keyvalue,
01269 doc_keyvalue, &cfg_rep_string,
01270 &zone_kw
01271 };
01272
01273
01274
01275 static const char *rpz_policies[] = {
01276 "given", "disabled", "passthru", "no-op", "drop", "tcp-only",
01277 "nxdomain", "nodata", "cname", NULL
01278 };
01279 static cfg_type_t cfg_type_rpz_policy_name = {
01280 "policy name", cfg_parse_enum, cfg_print_ustring,
01281 doc_rpz_policy, &cfg_rep_string,
01282 &rpz_policies
01283 };
01284 static cfg_type_t cfg_type_rpz_cname = {
01285 "quoted_string", cfg_parse_astring, NULL,
01286 doc_rpz_cname, &cfg_rep_string,
01287 NULL
01288 };
01289 static cfg_tuplefielddef_t rpz_policy_fields[] = {
01290 { "policy name", &cfg_type_rpz_policy_name, 0 },
01291 { "cname", &cfg_type_rpz_cname, 0 },
01292 { NULL, NULL, 0 }
01293 };
01294 static cfg_type_t cfg_type_rpz_policy = {
01295 "policy tuple", cfg_parse_rpz_policy,
01296 cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple,
01297 rpz_policy_fields
01298 };
01299 static cfg_tuplefielddef_t rpz_zone_fields[] = {
01300 { "zone name", &cfg_type_rpz_zone, 0 },
01301 { "policy", &cfg_type_rpz_policy, 0 },
01302 { "recursive-only", &cfg_type_boolean, 0 },
01303 { "max-policy-ttl", &cfg_type_uint32, 0 },
01304 { NULL, NULL, 0 }
01305 };
01306 static cfg_type_t cfg_type_rpz_tuple = {
01307 "rpz tuple", cfg_parse_kv_tuple,
01308 cfg_print_kv_tuple, cfg_doc_kv_tuple, &cfg_rep_tuple,
01309 rpz_zone_fields
01310 };
01311 static cfg_type_t cfg_type_rpz_list = {
01312 "zone list", cfg_parse_bracketed_list, cfg_print_bracketed_list,
01313 cfg_doc_bracketed_list, &cfg_rep_list,
01314 &cfg_type_rpz_tuple
01315 };
01316 static cfg_tuplefielddef_t rpz_fields[] = {
01317 { "zone list", &cfg_type_rpz_list, 0 },
01318 { "recursive-only", &cfg_type_boolean, 0 },
01319 { "break-dnssec", &cfg_type_boolean, 0 },
01320 { "max-policy-ttl", &cfg_type_uint32, 0 },
01321 { "min-ns-dots", &cfg_type_uint32, 0 },
01322 { "qname-wait-recurse", &cfg_type_boolean, 0 },
01323 { NULL, NULL, 0 }
01324 };
01325 static cfg_type_t cfg_type_rpz = {
01326 "rpz", cfg_parse_kv_tuple,
01327 cfg_print_kv_tuple, cfg_doc_kv_tuple, &cfg_rep_tuple,
01328 rpz_fields
01329 };
01330
01331
01332
01333
01334
01335 static cfg_clausedef_t rrl_clauses[] = {
01336 { "responses-per-second", &cfg_type_uint32, 0 },
01337 { "referrals-per-second", &cfg_type_uint32, 0 },
01338 { "nodata-per-second", &cfg_type_uint32, 0 },
01339 { "nxdomains-per-second", &cfg_type_uint32, 0 },
01340 { "errors-per-second", &cfg_type_uint32, 0 },
01341 { "all-per-second", &cfg_type_uint32, 0 },
01342 { "slip", &cfg_type_uint32, 0 },
01343 { "window", &cfg_type_uint32, 0 },
01344 { "log-only", &cfg_type_boolean, 0 },
01345 { "qps-scale", &cfg_type_uint32, 0 },
01346 { "ipv4-prefix-length", &cfg_type_uint32, 0 },
01347 { "ipv6-prefix-length", &cfg_type_uint32, 0 },
01348 { "exempt-clients", &cfg_type_bracketed_aml, 0 },
01349 { "max-table-size", &cfg_type_uint32, 0 },
01350 { "min-table-size", &cfg_type_uint32, 0 },
01351 { NULL, NULL, 0 }
01352 };
01353
01354 static cfg_clausedef_t *rrl_clausesets[] = {
01355 rrl_clauses,
01356 NULL
01357 };
01358
01359 static cfg_type_t cfg_type_rrl = {
01360 "rate-limit", cfg_parse_map, cfg_print_map, cfg_doc_map,
01361 &cfg_rep_map, rrl_clausesets
01362 };
01363
01364
01365
01366
01367
01368
01369
01370 static void
01371 print_lookaside(cfg_printer_t *pctx, const cfg_obj_t *obj)
01372 {
01373 const cfg_obj_t *domain = obj->value.tuple[0];
01374
01375 if (domain->value.string.length == 4 &&
01376 strncmp(domain->value.string.base, "auto", 4) == 0)
01377 cfg_print_cstr(pctx, "auto");
01378 else
01379 cfg_print_tuple(pctx, obj);
01380 }
01381
01382 static void
01383 doc_lookaside(cfg_printer_t *pctx, const cfg_type_t *type) {
01384 UNUSED(type);
01385 cfg_print_cstr(pctx, "( <string> trust-anchor <string> | auto | no )");
01386 }
01387
01388 static keyword_type_t trustanchor_kw = { "trust-anchor", &cfg_type_astring };
01389
01390 static cfg_type_t cfg_type_optional_trustanchor = {
01391 "optional_trustanchor", parse_optional_keyvalue, print_keyvalue,
01392 doc_keyvalue, &cfg_rep_string, &trustanchor_kw
01393 };
01394
01395 static cfg_tuplefielddef_t lookaside_fields[] = {
01396 { "domain", &cfg_type_astring, 0 },
01397 { "trust-anchor", &cfg_type_optional_trustanchor, 0 },
01398 { NULL, NULL, 0 }
01399 };
01400
01401 static cfg_type_t cfg_type_lookaside = {
01402 "lookaside", cfg_parse_tuple, print_lookaside, doc_lookaside,
01403 &cfg_rep_tuple, lookaside_fields
01404 };
01405
01406 static isc_result_t
01407 parse_optional_uint32(cfg_parser_t *pctx, const cfg_type_t *type,
01408 cfg_obj_t **ret)
01409 {
01410 isc_result_t result;
01411 UNUSED(type);
01412
01413 CHECK(cfg_peektoken(pctx, ISC_LEXOPT_NUMBER | ISC_LEXOPT_CNUMBER));
01414 if (pctx->token.type == isc_tokentype_number) {
01415 CHECK(cfg_parse_obj(pctx, &cfg_type_uint32, ret));
01416 } else {
01417 CHECK(cfg_parse_obj(pctx, &cfg_type_void, ret));
01418 }
01419 cleanup:
01420 return (result);
01421 }
01422
01423 static void
01424 doc_optional_uint32(cfg_printer_t *pctx, const cfg_type_t *type) {
01425 UNUSED(type);
01426 cfg_print_cstr(pctx, "[ <integer> ]");
01427 }
01428
01429 static cfg_type_t cfg_type_optional_uint32 = {
01430 "optional_uint32", parse_optional_uint32, NULL, doc_optional_uint32,
01431 NULL, NULL };
01432
01433 static cfg_tuplefielddef_t prefetch_fields[] = {
01434 { "trigger", &cfg_type_uint32, 0 },
01435 { "eligible", &cfg_type_optional_uint32, 0 },
01436 { NULL, NULL, 0 }
01437 };
01438
01439 static cfg_type_t cfg_type_prefetch = {
01440 "prefetch", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
01441 &cfg_rep_tuple, prefetch_fields
01442 };
01443
01444
01445
01446 static cfg_clausedef_t
01447 dns64_clauses[] = {
01448 { "clients", &cfg_type_bracketed_aml, 0 },
01449 { "mapped", &cfg_type_bracketed_aml, 0 },
01450 { "exclude", &cfg_type_bracketed_aml, 0 },
01451 { "suffix", &cfg_type_netaddr6, 0 },
01452 { "recursive-only", &cfg_type_boolean, 0 },
01453 { "break-dnssec", &cfg_type_boolean, 0 },
01454 { NULL, NULL, 0 },
01455 };
01456
01457 static cfg_clausedef_t *
01458 dns64_clausesets[] = {
01459 dns64_clauses,
01460 NULL
01461 };
01462
01463 static cfg_type_t cfg_type_dns64 = {
01464 "dns64", cfg_parse_netprefix_map, cfg_print_map, cfg_doc_map,
01465 &cfg_rep_map, dns64_clausesets
01466 };
01467
01468
01469
01470
01471
01472
01473 static cfg_clausedef_t
01474 view_clauses[] = {
01475 { "acache-cleaning-interval", &cfg_type_uint32, 0 },
01476 { "acache-enable", &cfg_type_boolean, 0 },
01477 { "additional-from-auth", &cfg_type_boolean, 0 },
01478 { "additional-from-cache", &cfg_type_boolean, 0 },
01479 { "allow-new-zones", &cfg_type_boolean, 0 },
01480 { "allow-query-cache", &cfg_type_bracketed_aml, 0 },
01481 { "allow-query-cache-on", &cfg_type_bracketed_aml, 0 },
01482 { "allow-recursion", &cfg_type_bracketed_aml, 0 },
01483 { "allow-recursion-on", &cfg_type_bracketed_aml, 0 },
01484 { "allow-v6-synthesis", &cfg_type_bracketed_aml,
01485 CFG_CLAUSEFLAG_OBSOLETE },
01486 { "attach-cache", &cfg_type_astring, 0 },
01487 { "auth-nxdomain", &cfg_type_boolean, CFG_CLAUSEFLAG_NEWDEFAULT },
01488 { "cache-file", &cfg_type_qstring, 0 },
01489 { "check-names", &cfg_type_checknames, CFG_CLAUSEFLAG_MULTI },
01490 { "cleaning-interval", &cfg_type_uint32, 0 },
01491 { "clients-per-query", &cfg_type_uint32, 0 },
01492 { "deny-answer-addresses", &cfg_type_denyaddresses, 0 },
01493 { "deny-answer-aliases", &cfg_type_denyaliases, 0 },
01494 { "disable-algorithms", &cfg_type_disablealgorithm,
01495 CFG_CLAUSEFLAG_MULTI },
01496 { "disable-ds-digests", &cfg_type_disabledsdigest,
01497 CFG_CLAUSEFLAG_MULTI },
01498 { "disable-empty-zone", &cfg_type_astring, CFG_CLAUSEFLAG_MULTI },
01499 { "dns64", &cfg_type_dns64, CFG_CLAUSEFLAG_MULTI },
01500 { "dns64-server", &cfg_type_astring, 0 },
01501 { "dns64-contact", &cfg_type_astring, 0 },
01502 { "dnssec-accept-expired", &cfg_type_boolean, 0 },
01503 { "dnssec-enable", &cfg_type_boolean, 0 },
01504 { "dnssec-lookaside", &cfg_type_lookaside, CFG_CLAUSEFLAG_MULTI },
01505 { "dnssec-must-be-secure", &cfg_type_mustbesecure,
01506 CFG_CLAUSEFLAG_MULTI },
01507 { "dnssec-validation", &cfg_type_boolorauto, 0 },
01508 { "dual-stack-servers", &cfg_type_nameportiplist, 0 },
01509 { "edns-udp-size", &cfg_type_uint32, 0 },
01510 { "empty-contact", &cfg_type_astring, 0 },
01511 { "empty-server", &cfg_type_astring, 0 },
01512 { "empty-zones-enable", &cfg_type_boolean, 0 },
01513 { "fetch-glue", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
01514 { "ixfr-from-differences", &cfg_type_ixfrdifftype, 0 },
01515 { "lame-ttl", &cfg_type_ttlval, 0 },
01516 #ifdef ISC_PLATFORM_USESIT
01517 { "nosit-udp-size", &cfg_type_uint32, 0 },
01518 #else
01519 { "nosit-udp-size", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTCONFIGURED },
01520 #endif
01521 { "max-acache-size", &cfg_type_sizenodefault, 0 },
01522 { "max-cache-size", &cfg_type_sizenodefault, 0 },
01523 { "max-cache-ttl", &cfg_type_uint32, 0 },
01524 { "max-clients-per-query", &cfg_type_uint32, 0 },
01525 { "max-ncache-ttl", &cfg_type_uint32, 0 },
01526 { "max-recursion-depth", &cfg_type_uint32, 0 },
01527 { "max-recursion-queries", &cfg_type_uint32, 0 },
01528 { "max-udp-size", &cfg_type_uint32, 0 },
01529 { "min-roots", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTIMP },
01530 { "minimal-responses", &cfg_type_boolean, 0 },
01531 { "nta-recheck", &cfg_type_ttlval, 0 },
01532 { "nta-lifetime", &cfg_type_ttlval, 0 },
01533 { "nxdomain-redirect", &cfg_type_astring, 0 },
01534 { "prefetch", &cfg_type_prefetch, 0 },
01535 { "preferred-glue", &cfg_type_astring, 0 },
01536 { "no-case-compress", &cfg_type_bracketed_aml, 0 },
01537 { "provide-ixfr", &cfg_type_boolean, 0 },
01538
01539
01540
01541
01542 { "query-source", &cfg_type_querysource4, 0 },
01543 { "query-source-v6", &cfg_type_querysource6, 0 },
01544 { "queryport-pool-ports", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE },
01545 { "queryport-pool-updateinterval", &cfg_type_uint32,
01546 CFG_CLAUSEFLAG_OBSOLETE },
01547 { "recursion", &cfg_type_boolean, 0 },
01548 #ifdef ISC_PLATFORM_USESIT
01549 { "request-sit", &cfg_type_boolean, 0 },
01550 #else
01551 { "request-sit", &cfg_type_boolean, CFG_CLAUSEFLAG_NOTCONFIGURED },
01552 #endif
01553 { "request-nsid", &cfg_type_boolean, 0 },
01554 { "resolver-query-timeout", &cfg_type_uint32, 0 },
01555 { "rfc2308-type1", &cfg_type_boolean, CFG_CLAUSEFLAG_NYI },
01556 { "root-delegation-only", &cfg_type_optional_exclude, 0 },
01557 { "rrset-order", &cfg_type_rrsetorder, 0 },
01558 { "servfail-ttl", &cfg_type_ttlval, 0 },
01559 { "sortlist", &cfg_type_bracketed_aml, 0 },
01560 { "suppress-initial-notify", &cfg_type_boolean, CFG_CLAUSEFLAG_NYI },
01561 { "topology", &cfg_type_bracketed_aml, CFG_CLAUSEFLAG_NOTIMP },
01562 { "transfer-format", &cfg_type_transferformat, 0 },
01563 { "use-queryport-pool", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
01564 { "zero-no-soa-ttl-cache", &cfg_type_boolean, 0 },
01565 #ifdef ALLOW_FILTER_AAAA
01566 { "filter-aaaa", &cfg_type_bracketed_aml, 0 },
01567 { "filter-aaaa-on-v4", &cfg_type_filter_aaaa, 0 },
01568 { "filter-aaaa-on-v6", &cfg_type_filter_aaaa, 0 },
01569 #else
01570 { "filter-aaaa", &cfg_type_bracketed_aml,
01571 CFG_CLAUSEFLAG_NOTCONFIGURED },
01572 { "filter-aaaa-on-v4", &cfg_type_filter_aaaa,
01573 CFG_CLAUSEFLAG_NOTCONFIGURED },
01574 { "filter-aaaa-on-v6", &cfg_type_filter_aaaa,
01575 CFG_CLAUSEFLAG_NOTCONFIGURED },
01576 #endif
01577 { "response-policy", &cfg_type_rpz, 0 },
01578 { "rate-limit", &cfg_type_rrl, 0 },
01579 { NULL, NULL, 0 }
01580 };
01581
01582
01583
01584
01585 static cfg_clausedef_t
01586 view_only_clauses[] = {
01587 { "match-clients", &cfg_type_bracketed_aml, 0 },
01588 { "match-destinations", &cfg_type_bracketed_aml, 0 },
01589 { "match-recursive-only", &cfg_type_boolean, 0 },
01590 { NULL, NULL, 0 }
01591 };
01592
01593
01594
01595
01596
01597 static cfg_tuplefielddef_t validityinterval_fields[] = {
01598 { "validity", &cfg_type_uint32, 0 },
01599 { "re-sign", &cfg_type_optional_uint32, 0 },
01600 { NULL, NULL, 0 }
01601 };
01602
01603 static cfg_type_t cfg_type_validityinterval = {
01604 "validityinterval", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
01605 &cfg_rep_tuple, validityinterval_fields
01606 };
01607
01608
01609
01610
01611
01612 static cfg_clausedef_t
01613 zone_clauses[] = {
01614 { "allow-notify", &cfg_type_bracketed_aml, 0 },
01615 { "allow-query", &cfg_type_bracketed_aml, 0 },
01616 { "allow-query-on", &cfg_type_bracketed_aml, 0 },
01617 { "allow-transfer", &cfg_type_bracketed_aml, 0 },
01618 { "allow-update", &cfg_type_bracketed_aml, 0 },
01619 { "allow-update-forwarding", &cfg_type_bracketed_aml, 0 },
01620 { "also-notify", &cfg_type_namesockaddrkeylist, 0 },
01621 { "alt-transfer-source", &cfg_type_sockaddr4wild, 0 },
01622 { "alt-transfer-source-v6", &cfg_type_sockaddr6wild, 0 },
01623 { "auto-dnssec", &cfg_type_autodnssec, 0 },
01624 { "check-dup-records", &cfg_type_checkmode, 0 },
01625 { "check-integrity", &cfg_type_boolean, 0 },
01626 { "check-mx", &cfg_type_checkmode, 0 },
01627 { "check-mx-cname", &cfg_type_checkmode, 0 },
01628 { "check-sibling", &cfg_type_boolean, 0 },
01629 { "check-spf", &cfg_type_warn, 0 },
01630 { "check-srv-cname", &cfg_type_checkmode, 0 },
01631 { "check-wildcard", &cfg_type_boolean, 0 },
01632 { "dialup", &cfg_type_dialuptype, 0 },
01633 { "dnssec-dnskey-kskonly", &cfg_type_boolean, 0 },
01634 { "dnssec-loadkeys-interval", &cfg_type_uint32, 0 },
01635 { "dnssec-secure-to-insecure", &cfg_type_boolean, 0 },
01636 { "dnssec-update-mode", &cfg_type_dnssecupdatemode, 0 },
01637 { "forward", &cfg_type_forwardtype, 0 },
01638 { "forwarders", &cfg_type_portiplist, 0 },
01639 { "inline-signing", &cfg_type_boolean, 0 },
01640 { "key-directory", &cfg_type_qstring, 0 },
01641 { "maintain-ixfr-base", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
01642 { "masterfile-format", &cfg_type_masterformat, 0 },
01643 { "masterfile-style", &cfg_type_masterstyle, 0 },
01644 { "max-ixfr-log-size", &cfg_type_size, CFG_CLAUSEFLAG_OBSOLETE },
01645 { "max-journal-size", &cfg_type_sizenodefault, 0 },
01646 { "max-refresh-time", &cfg_type_uint32, 0 },
01647 { "max-retry-time", &cfg_type_uint32, 0 },
01648 { "max-transfer-idle-in", &cfg_type_uint32, 0 },
01649 { "max-transfer-idle-out", &cfg_type_uint32, 0 },
01650 { "max-transfer-time-in", &cfg_type_uint32, 0 },
01651 { "max-transfer-time-out", &cfg_type_uint32, 0 },
01652 { "max-zone-ttl", &cfg_type_maxttl, 0 },
01653 { "min-refresh-time", &cfg_type_uint32, 0 },
01654 { "min-retry-time", &cfg_type_uint32, 0 },
01655 { "multi-master", &cfg_type_boolean, 0 },
01656 { "notify", &cfg_type_notifytype, 0 },
01657 { "notify-delay", &cfg_type_uint32, 0 },
01658 { "notify-source", &cfg_type_sockaddr4wild, 0 },
01659 { "notify-source-v6", &cfg_type_sockaddr6wild, 0 },
01660 { "notify-to-soa", &cfg_type_boolean, 0 },
01661 { "nsec3-test-zone", &cfg_type_boolean, CFG_CLAUSEFLAG_TESTONLY },
01662 { "request-expire", &cfg_type_boolean, 0 },
01663 { "request-ixfr", &cfg_type_boolean, 0 },
01664 { "serial-update-method", &cfg_type_updatemethod, 0 },
01665 { "sig-signing-nodes", &cfg_type_uint32, 0 },
01666 { "sig-signing-signatures", &cfg_type_uint32, 0 },
01667 { "sig-signing-type", &cfg_type_uint32, 0 },
01668 { "sig-validity-interval", &cfg_type_validityinterval, 0 },
01669 { "transfer-source", &cfg_type_sockaddr4wild, 0 },
01670 { "transfer-source-v6", &cfg_type_sockaddr6wild, 0 },
01671 { "try-tcp-refresh", &cfg_type_boolean, 0 },
01672 { "update-check-ksk", &cfg_type_boolean, 0 },
01673 { "use-alt-transfer-source", &cfg_type_boolean, 0 },
01674 { "zero-no-soa-ttl", &cfg_type_boolean, 0 },
01675 { "zone-statistics", &cfg_type_zonestat, 0 },
01676 { NULL, NULL, 0 }
01677 };
01678
01679
01680
01681
01682
01683 static cfg_clausedef_t
01684 zone_only_clauses[] = {
01685 { "type", &cfg_type_zonetype, 0 },
01686 { "file", &cfg_type_qstring, 0 },
01687 { "journal", &cfg_type_qstring, 0 },
01688 { "ixfr-base", &cfg_type_qstring, CFG_CLAUSEFLAG_OBSOLETE },
01689 { "ixfr-tmp-file", &cfg_type_qstring, CFG_CLAUSEFLAG_OBSOLETE },
01690 { "masters", &cfg_type_namesockaddrkeylist, 0 },
01691 { "pubkey", &cfg_type_pubkey,
01692 CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_OBSOLETE },
01693 { "update-policy", &cfg_type_updatepolicy, 0 },
01694 { "database", &cfg_type_astring, 0 },
01695 { "dlz", &cfg_type_astring, 0 },
01696 { "delegation-only", &cfg_type_boolean, 0 },
01697
01698
01699
01700
01701 { "check-names", &cfg_type_checkmode, 0 },
01702 { "in-view", &cfg_type_astring, 0 },
01703 { "ixfr-from-differences", &cfg_type_boolean, 0 },
01704 { "server-addresses", &cfg_type_bracketed_sockaddrlist, 0 },
01705 { "server-names", &cfg_type_namelist, 0 },
01706 { NULL, NULL, 0 }
01707 };
01708
01709
01710
01711
01712 static cfg_clausedef_t *
01713 namedconf_clausesets[] = {
01714 namedconf_clauses,
01715 namedconf_or_view_clauses,
01716 NULL
01717 };
01718 LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_namedconf = {
01719 "namedconf", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody,
01720 &cfg_rep_map, namedconf_clausesets
01721 };
01722
01723
01724 static cfg_clausedef_t *
01725 bindkeys_clausesets[] = {
01726 bindkeys_clauses,
01727 NULL
01728 };
01729 LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_bindkeys = {
01730 "bindkeys", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody,
01731 &cfg_rep_map, bindkeys_clausesets
01732 };
01733
01734
01735 static cfg_clausedef_t
01736 newzones_clauses[] = {
01737 { "zone", &cfg_type_zone, CFG_CLAUSEFLAG_MULTI },
01738 { NULL, NULL, 0 }
01739 };
01740
01741 static cfg_clausedef_t *
01742 newzones_clausesets[] = {
01743 newzones_clauses,
01744 NULL
01745 };
01746
01747 LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_newzones = {
01748 "newzones", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody,
01749 &cfg_rep_map, newzones_clausesets
01750 };
01751
01752
01753
01754 static cfg_clausedef_t *
01755 options_clausesets[] = {
01756 options_clauses,
01757 view_clauses,
01758 zone_clauses,
01759 NULL
01760 };
01761 static cfg_type_t cfg_type_options = {
01762 "options", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, options_clausesets };
01763
01764
01765
01766 static cfg_clausedef_t *
01767 view_clausesets[] = {
01768 view_only_clauses,
01769 namedconf_or_view_clauses,
01770 view_clauses,
01771 zone_clauses,
01772 NULL
01773 };
01774 static cfg_type_t cfg_type_viewopts = {
01775 "view", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, view_clausesets };
01776
01777
01778
01779 static cfg_clausedef_t *
01780 zone_clausesets[] = {
01781 zone_only_clauses,
01782 zone_clauses,
01783 NULL
01784 };
01785 static cfg_type_t cfg_type_zoneopts = {
01786 "zoneopts", cfg_parse_map, cfg_print_map,
01787 cfg_doc_map, &cfg_rep_map, zone_clausesets };
01788
01789
01790
01791 static cfg_clausedef_t
01792 dlz_clauses[] = {
01793 { "database", &cfg_type_astring, 0 },
01794 { "search", &cfg_type_boolean, 0 },
01795 { NULL, NULL, 0 }
01796 };
01797 static cfg_clausedef_t *
01798 dlz_clausesets[] = {
01799 dlz_clauses,
01800 NULL
01801 };
01802 static cfg_type_t cfg_type_dlz = {
01803 "dlz", cfg_parse_named_map, cfg_print_map, cfg_doc_map,
01804 &cfg_rep_map, dlz_clausesets
01805 };
01806
01807
01808
01809
01810 static cfg_clausedef_t
01811 key_clauses[] = {
01812 { "algorithm", &cfg_type_astring, 0 },
01813 { "secret", &cfg_type_sstring, 0 },
01814 { NULL, NULL, 0 }
01815 };
01816
01817 static cfg_clausedef_t *
01818 key_clausesets[] = {
01819 key_clauses,
01820 NULL
01821 };
01822 static cfg_type_t cfg_type_key = {
01823 "key", cfg_parse_named_map, cfg_print_map,
01824 cfg_doc_map, &cfg_rep_map, key_clausesets
01825 };
01826
01827
01828
01829
01830
01831 static cfg_clausedef_t
01832 server_clauses[] = {
01833 { "bogus", &cfg_type_boolean, 0 },
01834 { "edns", &cfg_type_boolean, 0 },
01835 { "edns-udp-size", &cfg_type_uint32, 0 },
01836 { "edns-version", &cfg_type_uint32, 0 },
01837 { "keys", &cfg_type_server_key_kludge, 0 },
01838 { "max-udp-size", &cfg_type_uint32, 0 },
01839 { "tcp-only", &cfg_type_boolean, 0 },
01840 { "notify-source", &cfg_type_sockaddr4wild, 0 },
01841 { "notify-source-v6", &cfg_type_sockaddr6wild, 0 },
01842 { "provide-ixfr", &cfg_type_boolean, 0 },
01843 { "query-source", &cfg_type_querysource4, 0 },
01844 { "query-source-v6", &cfg_type_querysource6, 0 },
01845 { "request-expire", &cfg_type_boolean, 0 },
01846 { "request-ixfr", &cfg_type_boolean, 0 },
01847 { "request-nsid", &cfg_type_boolean, 0 },
01848 #ifdef ISC_PLATFORM_USESIT
01849 { "request-sit", &cfg_type_boolean, 0 },
01850 #else
01851 { "request-sit", &cfg_type_boolean, CFG_CLAUSEFLAG_NOTCONFIGURED },
01852 #endif
01853 { "support-ixfr", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
01854 { "transfer-format", &cfg_type_transferformat, 0 },
01855 { "transfer-source", &cfg_type_sockaddr4wild, 0 },
01856 { "transfer-source-v6", &cfg_type_sockaddr6wild, 0 },
01857 { "transfers", &cfg_type_uint32, 0 },
01858 { NULL, NULL, 0 }
01859 };
01860 static cfg_clausedef_t *
01861 server_clausesets[] = {
01862 server_clauses,
01863 NULL
01864 };
01865 static cfg_type_t cfg_type_server = {
01866 "server", cfg_parse_netprefix_map, cfg_print_map, cfg_doc_map, &cfg_rep_map,
01867 server_clausesets
01868 };
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880 static cfg_clausedef_t
01881 channel_clauses[] = {
01882
01883 { "file", &cfg_type_logfile, 0 },
01884 { "syslog", &cfg_type_optional_facility, 0 },
01885 { "null", &cfg_type_void, 0 },
01886 { "stderr", &cfg_type_void, 0 },
01887
01888 { "severity", &cfg_type_logseverity, 0 },
01889 { "print-time", &cfg_type_boolean, 0 },
01890 { "print-severity", &cfg_type_boolean, 0 },
01891 { "print-category", &cfg_type_boolean, 0 },
01892 { "buffered", &cfg_type_boolean, 0 },
01893 { NULL, NULL, 0 }
01894 };
01895 static cfg_clausedef_t *
01896 channel_clausesets[] = {
01897 channel_clauses,
01898 NULL
01899 };
01900 static cfg_type_t cfg_type_channel = {
01901 "channel", cfg_parse_named_map, cfg_print_map, cfg_doc_map,
01902 &cfg_rep_map, channel_clausesets
01903 };
01904
01905
01906 static cfg_type_t cfg_type_destinationlist = {
01907 "destinationlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list,
01908 &cfg_rep_list, &cfg_type_astring };
01909
01910
01911
01912
01913 static cfg_clausedef_t
01914 logging_clauses[] = {
01915 { "channel", &cfg_type_channel, CFG_CLAUSEFLAG_MULTI },
01916 { "category", &cfg_type_category, CFG_CLAUSEFLAG_MULTI },
01917 { NULL, NULL, 0 }
01918 };
01919 static cfg_clausedef_t *
01920 logging_clausesets[] = {
01921 logging_clauses,
01922 NULL
01923 };
01924 static cfg_type_t cfg_type_logging = {
01925 "logging", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, logging_clausesets };
01926
01927
01928
01929
01930
01931
01932 static cfg_tuplefielddef_t addzone_fields[] = {
01933 { "name", &cfg_type_astring, 0 },
01934 { "class", &cfg_type_optional_class, 0 },
01935 { "view", &cfg_type_optional_class, 0 },
01936 { "options", &cfg_type_zoneopts, 0 },
01937 { NULL, NULL, 0 }
01938 };
01939 static cfg_type_t cfg_type_addzone = {
01940 "zone", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, addzone_fields };
01941
01942 static cfg_clausedef_t
01943 addzoneconf_clauses[] = {
01944 { "zone", &cfg_type_addzone, CFG_CLAUSEFLAG_MULTI },
01945 { NULL, NULL, 0 }
01946 };
01947
01948 static cfg_clausedef_t *
01949 addzoneconf_clausesets[] = {
01950 addzoneconf_clauses,
01951 NULL
01952 };
01953
01954 LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_addzoneconf = {
01955 "addzoneconf", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody,
01956 &cfg_rep_map, addzoneconf_clausesets
01957 };
01958
01959
01960 static isc_result_t
01961 parse_unitstring(char *str, isc_resourcevalue_t *valuep) {
01962 char *endp;
01963 unsigned int len;
01964 isc_uint64_t value;
01965 isc_uint64_t unit;
01966
01967 value = isc_string_touint64(str, &endp, 10);
01968 if (*endp == 0) {
01969 *valuep = value;
01970 return (ISC_R_SUCCESS);
01971 }
01972
01973 len = strlen(str);
01974 if (len < 2 || endp[1] != '\0')
01975 return (ISC_R_FAILURE);
01976
01977 switch (str[len - 1]) {
01978 case 'k':
01979 case 'K':
01980 unit = 1024;
01981 break;
01982 case 'm':
01983 case 'M':
01984 unit = 1024 * 1024;
01985 break;
01986 case 'g':
01987 case 'G':
01988 unit = 1024 * 1024 * 1024;
01989 break;
01990 default:
01991 return (ISC_R_FAILURE);
01992 }
01993 if (value > ISC_UINT64_MAX / unit)
01994 return (ISC_R_FAILURE);
01995 *valuep = value * unit;
01996 return (ISC_R_SUCCESS);
01997 }
01998
01999 static isc_result_t
02000 parse_sizeval(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
02001 isc_result_t result;
02002 cfg_obj_t *obj = NULL;
02003 isc_uint64_t val;
02004
02005 UNUSED(type);
02006
02007 CHECK(cfg_gettoken(pctx, 0));
02008 if (pctx->token.type != isc_tokentype_string) {
02009 result = ISC_R_UNEXPECTEDTOKEN;
02010 goto cleanup;
02011 }
02012 CHECK(parse_unitstring(TOKEN_STRING(pctx), &val));
02013
02014 CHECK(cfg_create_obj(pctx, &cfg_type_uint64, &obj));
02015 obj->value.uint64 = val;
02016 *ret = obj;
02017 return (ISC_R_SUCCESS);
02018
02019 cleanup:
02020 cfg_parser_error(pctx, CFG_LOG_NEAR, "expected integer and optional unit");
02021 return (result);
02022 }
02023
02024
02025
02026
02027 static cfg_type_t cfg_type_sizeval = {
02028 "sizeval", parse_sizeval, cfg_print_uint64, cfg_doc_terminal,
02029 &cfg_rep_uint64, NULL };
02030
02031
02032
02033
02034
02035 static isc_result_t
02036 parse_size(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
02037 return (parse_enum_or_other(pctx, type, &cfg_type_sizeval, ret));
02038 }
02039
02040 static const char *size_enums[] = { "unlimited", "default", NULL };
02041 static cfg_type_t cfg_type_size = {
02042 "size", parse_size, cfg_print_ustring, cfg_doc_terminal,
02043 &cfg_rep_string, size_enums
02044 };
02045
02046
02047
02048
02049 static const char *sizenodefault_enums[] = { "unlimited", NULL };
02050 static cfg_type_t cfg_type_sizenodefault = {
02051 "size_no_default", parse_size, cfg_print_ustring, cfg_doc_terminal,
02052 &cfg_rep_string, sizenodefault_enums
02053 };
02054
02055
02056
02057
02058 static isc_result_t
02059 parse_maybe_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type,
02060 isc_boolean_t optional, cfg_obj_t **ret)
02061 {
02062 isc_result_t result;
02063 cfg_obj_t *obj = NULL;
02064 const keyword_type_t *kw = type->of;
02065
02066 CHECK(cfg_peektoken(pctx, 0));
02067 if (pctx->token.type == isc_tokentype_string &&
02068 strcasecmp(TOKEN_STRING(pctx), kw->name) == 0) {
02069 CHECK(cfg_gettoken(pctx, 0));
02070 CHECK(kw->type->parse(pctx, kw->type, &obj));
02071 obj->type = type;
02072 } else {
02073 if (optional) {
02074 CHECK(cfg_parse_void(pctx, NULL, &obj));
02075 } else {
02076 cfg_parser_error(pctx, CFG_LOG_NEAR, "expected '%s'",
02077 kw->name);
02078 result = ISC_R_UNEXPECTEDTOKEN;
02079 goto cleanup;
02080 }
02081 }
02082 *ret = obj;
02083 cleanup:
02084 return (result);
02085 }
02086
02087 static isc_result_t
02088 parse_enum_or_other(cfg_parser_t *pctx, const cfg_type_t *enumtype,
02089 const cfg_type_t *othertype, cfg_obj_t **ret)
02090 {
02091 isc_result_t result;
02092 CHECK(cfg_peektoken(pctx, 0));
02093 if (pctx->token.type == isc_tokentype_string &&
02094 cfg_is_enum(TOKEN_STRING(pctx), enumtype->of)) {
02095 CHECK(cfg_parse_enum(pctx, enumtype, ret));
02096 } else {
02097 CHECK(cfg_parse_obj(pctx, othertype, ret));
02098 }
02099 cleanup:
02100 return (result);
02101 }
02102
02103 static void
02104 doc_enum_or_other(cfg_printer_t *pctx, const cfg_type_t *type) {
02105 cfg_doc_terminal(pctx, type);
02106 #if 0
02107 cfg_print_chars(pctx, "( ", 2);...
02108 #endif
02109
02110 }
02111
02112 static isc_result_t
02113 parse_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
02114 return (parse_maybe_optional_keyvalue(pctx, type, ISC_FALSE, ret));
02115 }
02116
02117 static isc_result_t
02118 parse_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type,
02119 cfg_obj_t **ret)
02120 {
02121 return (parse_maybe_optional_keyvalue(pctx, type, ISC_TRUE, ret));
02122 }
02123
02124 static void
02125 print_keyvalue(cfg_printer_t *pctx, const cfg_obj_t *obj) {
02126 const keyword_type_t *kw = obj->type->of;
02127 cfg_print_cstr(pctx, kw->name);
02128 cfg_print_cstr(pctx, " ");
02129 kw->type->print(pctx, obj);
02130 }
02131
02132 static void
02133 doc_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type) {
02134 const keyword_type_t *kw = type->of;
02135 cfg_print_cstr(pctx, kw->name);
02136 cfg_print_cstr(pctx, " ");
02137 cfg_doc_obj(pctx, kw->type);
02138 }
02139
02140 static void
02141 doc_optional_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type) {
02142 const keyword_type_t *kw = type->of;
02143 cfg_print_cstr(pctx, "[ ");
02144 cfg_print_cstr(pctx, kw->name);
02145 cfg_print_cstr(pctx, " ");
02146 cfg_doc_obj(pctx, kw->type);
02147 cfg_print_cstr(pctx, " ]");
02148 }
02149
02150 static const char *dialup_enums[] = {
02151 "notify", "notify-passive", "refresh", "passive", NULL };
02152 static isc_result_t
02153 parse_dialup_type(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
02154 return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
02155 }
02156 static cfg_type_t cfg_type_dialuptype = {
02157 "dialuptype", parse_dialup_type, cfg_print_ustring, doc_enum_or_other,
02158 &cfg_rep_string, dialup_enums
02159 };
02160
02161 static const char *notify_enums[] = { "explicit", "master-only", NULL };
02162 static isc_result_t
02163 parse_notify_type(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
02164 return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
02165 }
02166 static cfg_type_t cfg_type_notifytype = {
02167 "notifytype", parse_notify_type, cfg_print_ustring, doc_enum_or_other,
02168 &cfg_rep_string, notify_enums,
02169 };
02170
02171 static const char *ixfrdiff_enums[] = { "master", "slave", NULL };
02172 static isc_result_t
02173 parse_ixfrdiff_type(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
02174 return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
02175 }
02176 static cfg_type_t cfg_type_ixfrdifftype = {
02177 "ixfrdiff", parse_ixfrdiff_type, cfg_print_ustring, doc_enum_or_other,
02178 &cfg_rep_string, ixfrdiff_enums,
02179 };
02180
02181 static const char *filter_aaaa_enums[] = { "break-dnssec", NULL };
02182 static isc_result_t
02183 parse_filter_aaaa(cfg_parser_t *pctx, const cfg_type_t *type,
02184 cfg_obj_t **ret) {
02185 return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
02186 }
02187 static cfg_type_t cfg_type_filter_aaaa = {
02188 "filter_aaaa", parse_filter_aaaa, cfg_print_ustring,
02189 doc_enum_or_other, &cfg_rep_string, filter_aaaa_enums,
02190 };
02191
02192 static keyword_type_t key_kw = { "key", &cfg_type_astring };
02193
02194 LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_keyref = {
02195 "keyref", parse_keyvalue, print_keyvalue, doc_keyvalue,
02196 &cfg_rep_string, &key_kw
02197 };
02198
02199 static cfg_type_t cfg_type_optional_keyref = {
02200 "optional_keyref", parse_optional_keyvalue, print_keyvalue,
02201 doc_optional_keyvalue, &cfg_rep_string, &key_kw
02202 };
02203
02204 #ifdef HAVE_GEOIP
02205
02206
02207
02208
02209 static const char *geoiptype_enums[] = {
02210 "country", "country3", "countryname", "region", "regionname",
02211 "city", "postal", "metrocode", "areacode", "timezone", "continent",
02212 "isp", "domain", "asnum", "org", "netspeed", NULL
02213 };
02214 static cfg_type_t cfg_type_geoiptype = {
02215 "geoiptype", cfg_parse_enum, cfg_print_ustring,
02216 cfg_doc_enum, &cfg_rep_string, &geoiptype_enums
02217 };
02218
02219 static const char *geoipdb_enums[] = {
02220 "country", "region", "city",
02221 "isp", "domain", "asnum", "org", "netspeed", NULL
02222 };
02223 static cfg_type_t cfg_type_geoipdb = {
02224 "geoipdb", cfg_parse_enum, cfg_print_ustring,
02225 cfg_doc_enum, &cfg_rep_string, &geoipdb_enums
02226 };
02227
02228 static cfg_tuplefielddef_t geoip_fields[] = {
02229 { "negated", &cfg_type_void, 0 },
02230 { "db", &cfg_type_geoipdb, 0 },
02231 { "subtype", &cfg_type_geoiptype, 0 },
02232 { "search", &cfg_type_astring, 0 },
02233 { NULL, NULL, 0 }
02234 };
02235
02236 static cfg_type_t cfg_type_geoip = {
02237 "geoip", parse_geoip, print_geoip, doc_geoip,
02238 &cfg_rep_tuple, geoip_fields
02239 };
02240
02241 static isc_result_t
02242 parse_geoip(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
02243 isc_result_t result;
02244 cfg_obj_t *obj = NULL;
02245 const cfg_tuplefielddef_t *fields = type->of;
02246
02247 CHECK(cfg_create_tuple(pctx, type, &obj));
02248 CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[0]));
02249
02250
02251 CHECK(cfg_peektoken(pctx, 0));
02252 if (pctx->token.type == isc_tokentype_string) {
02253 CHECK(cfg_gettoken(pctx, 0));
02254 if (strcasecmp(TOKEN_STRING(pctx), "db") == 0 &&
02255 obj->value.tuple[1] == NULL) {
02256 CHECK(cfg_parse_obj(pctx, fields[1].type,
02257 &obj->value.tuple[1]));
02258 } else {
02259 CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[1]));
02260 cfg_ungettoken(pctx);
02261 }
02262 }
02263
02264 CHECK(cfg_parse_obj(pctx, fields[2].type, &obj->value.tuple[2]));
02265 CHECK(cfg_parse_obj(pctx, fields[3].type, &obj->value.tuple[3]));
02266
02267 *ret = obj;
02268 return (ISC_R_SUCCESS);
02269
02270 cleanup:
02271 CLEANUP_OBJ(obj);
02272 return (result);
02273 }
02274
02275 static void
02276 print_geoip(cfg_printer_t *pctx, const cfg_obj_t *obj) {
02277 if (obj->value.tuple[1]->type->print != cfg_print_void) {
02278 cfg_print_cstr(pctx, " db ");
02279 cfg_print_obj(pctx, obj->value.tuple[1]);
02280 }
02281 cfg_print_obj(pctx, obj->value.tuple[2]);
02282 cfg_print_obj(pctx, obj->value.tuple[3]);
02283 }
02284
02285
02286 static void
02287 doc_geoip(cfg_printer_t *pctx, const cfg_type_t *type) {
02288 UNUSED(type);
02289 cfg_print_cstr(pctx, "[ db ");
02290 cfg_doc_enum(pctx, &cfg_type_geoipdb);
02291 cfg_print_cstr(pctx, " ]");
02292 cfg_print_cstr(pctx, " ");
02293 cfg_doc_enum(pctx, &cfg_type_geoiptype);
02294 cfg_print_cstr(pctx, " ");
02295 cfg_print_cstr(pctx, "<quoted_string>");
02296 }
02297 #endif
02298
02299
02300
02301
02302
02303 static keyword_type_t ecs_kw = { "ecs", &cfg_type_netprefix };
02304 LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_ecsprefix = {
02305 "edns_client_subnet", parse_keyvalue, print_keyvalue, doc_keyvalue,
02306 &cfg_rep_netprefix, &ecs_kw
02307 };
02308
02309
02310
02311
02312
02313
02314 static keyword_type_t controls_allow_kw = {
02315 "allow", &cfg_type_bracketed_aml };
02316
02317 static cfg_type_t cfg_type_controls_allow = {
02318 "controls_allow", parse_keyvalue,
02319 print_keyvalue, doc_keyvalue,
02320 &cfg_rep_list, &controls_allow_kw
02321 };
02322
02323 static keyword_type_t controls_keys_kw = {
02324 "keys", &cfg_type_keylist };
02325
02326 static cfg_type_t cfg_type_controls_keys = {
02327 "controls_keys", parse_optional_keyvalue,
02328 print_keyvalue, doc_optional_keyvalue,
02329 &cfg_rep_list, &controls_keys_kw
02330 };
02331
02332 static cfg_tuplefielddef_t inetcontrol_fields[] = {
02333 { "address", &cfg_type_controls_sockaddr, 0 },
02334 { "allow", &cfg_type_controls_allow, 0 },
02335 { "keys", &cfg_type_controls_keys, 0 },
02336 { NULL, NULL, 0 }
02337 };
02338
02339 static cfg_type_t cfg_type_inetcontrol = {
02340 "inetcontrol", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple,
02341 inetcontrol_fields
02342 };
02343
02344 static keyword_type_t controls_perm_kw = {
02345 "perm", &cfg_type_uint32 };
02346
02347 static cfg_type_t cfg_type_controls_perm = {
02348 "controls_perm", parse_keyvalue,
02349 print_keyvalue, doc_keyvalue,
02350 &cfg_rep_uint32, &controls_perm_kw
02351 };
02352
02353 static keyword_type_t controls_owner_kw = {
02354 "owner", &cfg_type_uint32 };
02355
02356 static cfg_type_t cfg_type_controls_owner = {
02357 "controls_owner", parse_keyvalue,
02358 print_keyvalue, doc_keyvalue,
02359 &cfg_rep_uint32, &controls_owner_kw
02360 };
02361
02362 static keyword_type_t controls_group_kw = {
02363 "group", &cfg_type_uint32 };
02364
02365 static cfg_type_t cfg_type_controls_group = {
02366 "controls_allow", parse_keyvalue,
02367 print_keyvalue, doc_keyvalue,
02368 &cfg_rep_uint32, &controls_group_kw
02369 };
02370
02371 static cfg_tuplefielddef_t unixcontrol_fields[] = {
02372 { "path", &cfg_type_qstring, 0 },
02373 { "perm", &cfg_type_controls_perm, 0 },
02374 { "owner", &cfg_type_controls_owner, 0 },
02375 { "group", &cfg_type_controls_group, 0 },
02376 { "keys", &cfg_type_controls_keys, 0 },
02377 { NULL, NULL, 0 }
02378 };
02379
02380 static cfg_type_t cfg_type_unixcontrol = {
02381 "unixcontrol", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple,
02382 unixcontrol_fields
02383 };
02384
02385 static cfg_clausedef_t
02386 controls_clauses[] = {
02387 { "inet", &cfg_type_inetcontrol, CFG_CLAUSEFLAG_MULTI },
02388 { "unix", &cfg_type_unixcontrol, CFG_CLAUSEFLAG_MULTI },
02389 { NULL, NULL, 0 }
02390 };
02391
02392 static cfg_clausedef_t *
02393 controls_clausesets[] = {
02394 controls_clauses,
02395 NULL
02396 };
02397 static cfg_type_t cfg_type_controls = {
02398 "controls", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, &controls_clausesets
02399 };
02400
02401
02402
02403
02404
02405 static void
02406 doc_optional_bracketed_list(cfg_printer_t *pctx, const cfg_type_t *type) {
02407 const keyword_type_t *kw = type->of;
02408 cfg_print_cstr(pctx, "[ ");
02409 cfg_print_cstr(pctx, kw->name);
02410 cfg_print_cstr(pctx, " ");
02411 cfg_doc_obj(pctx, kw->type);
02412 cfg_print_cstr(pctx, " ]");
02413 }
02414
02415 static cfg_type_t cfg_type_optional_allow = {
02416 "optional_allow", parse_optional_keyvalue, print_keyvalue,
02417 doc_optional_bracketed_list, &cfg_rep_list, &controls_allow_kw
02418 };
02419
02420 static cfg_tuplefielddef_t statserver_fields[] = {
02421 { "address", &cfg_type_controls_sockaddr, 0 },
02422 { "allow", &cfg_type_optional_allow, 0 },
02423 { NULL, NULL, 0 }
02424 };
02425
02426 static cfg_type_t cfg_type_statschannel = {
02427 "statschannel", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
02428 &cfg_rep_tuple, statserver_fields
02429 };
02430
02431 static cfg_clausedef_t
02432 statservers_clauses[] = {
02433 { "inet", &cfg_type_statschannel, CFG_CLAUSEFLAG_MULTI },
02434 { NULL, NULL, 0 }
02435 };
02436
02437 static cfg_clausedef_t *
02438 statservers_clausesets[] = {
02439 statservers_clauses,
02440 NULL
02441 };
02442
02443 static cfg_type_t cfg_type_statschannels = {
02444 "statistics-channels", cfg_parse_map, cfg_print_map, cfg_doc_map,
02445 &cfg_rep_map, &statservers_clausesets
02446 };
02447
02448
02449
02450
02451 static isc_result_t
02452 parse_optional_class(cfg_parser_t *pctx, const cfg_type_t *type,
02453 cfg_obj_t **ret)
02454 {
02455 isc_result_t result;
02456 UNUSED(type);
02457 CHECK(cfg_peektoken(pctx, 0));
02458 if (pctx->token.type == isc_tokentype_string)
02459 CHECK(cfg_parse_obj(pctx, &cfg_type_ustring, ret));
02460 else
02461 CHECK(cfg_parse_obj(pctx, &cfg_type_void, ret));
02462 cleanup:
02463 return (result);
02464 }
02465
02466 static cfg_type_t cfg_type_optional_class = {
02467 "optional_class", parse_optional_class, NULL, cfg_doc_terminal,
02468 NULL, NULL
02469 };
02470
02471 static isc_result_t
02472 parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
02473 isc_result_t result;
02474 cfg_obj_t *obj = NULL;
02475 isc_netaddr_t netaddr;
02476 in_port_t port = 0;
02477 isc_dscp_t dscp = -1;
02478 unsigned int have_address = 0;
02479 unsigned int have_port = 0;
02480 unsigned int have_dscp = 0;
02481 const unsigned int *flagp = type->of;
02482
02483 if ((*flagp & CFG_ADDR_V4OK) != 0)
02484 isc_netaddr_any(&netaddr);
02485 else if ((*flagp & CFG_ADDR_V6OK) != 0)
02486 isc_netaddr_any6(&netaddr);
02487 else
02488 INSIST(0);
02489
02490 for (;;) {
02491 CHECK(cfg_peektoken(pctx, 0));
02492 if (pctx->token.type == isc_tokentype_string) {
02493 if (strcasecmp(TOKEN_STRING(pctx),
02494 "address") == 0)
02495 {
02496
02497 CHECK(cfg_gettoken(pctx, 0));
02498 CHECK(cfg_parse_rawaddr(pctx, *flagp,
02499 &netaddr));
02500 have_address++;
02501 } else if (strcasecmp(TOKEN_STRING(pctx), "port") == 0)
02502 {
02503
02504 CHECK(cfg_gettoken(pctx, 0));
02505 CHECK(cfg_parse_rawport(pctx,
02506 CFG_ADDR_WILDOK,
02507 &port));
02508 have_port++;
02509 } else if (strcasecmp(TOKEN_STRING(pctx), "dscp") == 0)
02510 {
02511
02512 CHECK(cfg_gettoken(pctx, 0));
02513 CHECK(cfg_parse_dscp(pctx, &dscp));
02514 have_dscp++;
02515 } else if (have_port == 0 && have_dscp == 0 &&
02516 have_address == 0)
02517 {
02518 return (cfg_parse_sockaddr(pctx, type, ret));
02519 } else {
02520 cfg_parser_error(pctx, CFG_LOG_NEAR,
02521 "expected 'address', 'port', "
02522 "or 'dscp'");
02523 return (ISC_R_UNEXPECTEDTOKEN);
02524 }
02525 } else
02526 break;
02527 }
02528 if (have_address > 1 || have_port > 1 ||
02529 have_address + have_port == 0) {
02530 cfg_parser_error(pctx, 0, "expected one address and/or port");
02531 return (ISC_R_UNEXPECTEDTOKEN);
02532 }
02533
02534 if (have_dscp > 1) {
02535 cfg_parser_error(pctx, 0, "expected at most one dscp");
02536 return (ISC_R_UNEXPECTEDTOKEN);
02537 }
02538
02539 CHECK(cfg_create_obj(pctx, &cfg_type_querysource, &obj));
02540 isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, port);
02541 obj->value.sockaddrdscp.dscp = dscp;
02542 *ret = obj;
02543 return (ISC_R_SUCCESS);
02544
02545 cleanup:
02546 cfg_parser_error(pctx, CFG_LOG_NEAR, "invalid query source");
02547 CLEANUP_OBJ(obj);
02548 return (result);
02549 }
02550
02551 static void
02552 print_querysource(cfg_printer_t *pctx, const cfg_obj_t *obj) {
02553 isc_netaddr_t na;
02554 isc_netaddr_fromsockaddr(&na, &obj->value.sockaddr);
02555 cfg_print_cstr(pctx, "address ");
02556 cfg_print_rawaddr(pctx, &na);
02557 cfg_print_cstr(pctx, " port ");
02558 cfg_print_rawuint(pctx, isc_sockaddr_getport(&obj->value.sockaddr));
02559 if (obj->value.sockaddrdscp.dscp != -1) {
02560 cfg_print_cstr(pctx, " dscp ");
02561 cfg_print_rawuint(pctx, obj->value.sockaddrdscp.dscp);
02562 }
02563 }
02564
02565 static unsigned int sockaddr4wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V4OK |
02566 CFG_ADDR_DSCPOK;
02567 static unsigned int sockaddr6wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V6OK |
02568 CFG_ADDR_DSCPOK;
02569
02570 static cfg_type_t cfg_type_querysource4 = {
02571 "querysource4", parse_querysource, NULL, cfg_doc_terminal,
02572 NULL, &sockaddr4wild_flags
02573 };
02574
02575 static cfg_type_t cfg_type_querysource6 = {
02576 "querysource6", parse_querysource, NULL, cfg_doc_terminal,
02577 NULL, &sockaddr6wild_flags
02578 };
02579
02580 static cfg_type_t cfg_type_querysource = {
02581 "querysource", NULL, print_querysource, NULL, &cfg_rep_sockaddr, NULL
02582 };
02583
02584
02585
02586 static isc_result_t
02587 parse_addrmatchelt(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
02588 isc_result_t result;
02589 UNUSED(type);
02590
02591 CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING));
02592
02593 if (pctx->token.type == isc_tokentype_string ||
02594 pctx->token.type == isc_tokentype_qstring) {
02595 if (pctx->token.type == isc_tokentype_string &&
02596 (strcasecmp(TOKEN_STRING(pctx), "key") == 0)) {
02597 CHECK(cfg_parse_obj(pctx, &cfg_type_keyref, ret));
02598 } else if (pctx->token.type == isc_tokentype_string &&
02599 (strcasecmp(TOKEN_STRING(pctx), "ecs") == 0)) {
02600 CHECK(cfg_parse_obj(pctx, &cfg_type_ecsprefix, ret));
02601 } else if (pctx->token.type == isc_tokentype_string &&
02602 (strcasecmp(TOKEN_STRING(pctx), "geoip") == 0)) {
02603 #ifdef HAVE_GEOIP
02604 CHECK(cfg_gettoken(pctx, 0));
02605 CHECK(cfg_parse_obj(pctx, &cfg_type_geoip, ret));
02606 #else
02607 cfg_parser_error(pctx, CFG_LOG_NEAR,
02608 "'geoip' not supported in this build");
02609 return (ISC_R_UNEXPECTEDTOKEN);
02610 #endif
02611 } else {
02612 if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK |
02613 CFG_ADDR_V4PREFIXOK |
02614 CFG_ADDR_V6OK))
02615 {
02616 CHECK(cfg_parse_netprefix(pctx, NULL, ret));
02617 } else {
02618 CHECK(cfg_parse_astring(pctx, NULL, ret));
02619 }
02620 }
02621 } else if (pctx->token.type == isc_tokentype_special) {
02622 if (pctx->token.value.as_char == '{') {
02623
02624 CHECK(cfg_parse_obj(pctx,
02625 &cfg_type_bracketed_aml, ret));
02626 } else if (pctx->token.value.as_char == '!') {
02627 CHECK(cfg_gettoken(pctx, 0));
02628 CHECK(cfg_parse_obj(pctx, &cfg_type_negated, ret));
02629 } else {
02630 goto bad;
02631 }
02632 } else {
02633 bad:
02634 cfg_parser_error(pctx, CFG_LOG_NEAR,
02635 "expected IP match list element");
02636 return (ISC_R_UNEXPECTEDTOKEN);
02637 }
02638 cleanup:
02639 return (result);
02640 }
02641
02642
02643
02644
02645
02646
02647
02648 static cfg_tuplefielddef_t negated_fields[] = {
02649 { "negated", &cfg_type_addrmatchelt, 0 },
02650 { NULL, NULL, 0 }
02651 };
02652
02653 static void
02654 print_negated(cfg_printer_t *pctx, const cfg_obj_t *obj) {
02655 cfg_print_cstr(pctx, "!");
02656 cfg_print_tuple(pctx, obj);
02657 }
02658
02659 static cfg_type_t cfg_type_negated = {
02660 "negated", cfg_parse_tuple, print_negated, NULL, &cfg_rep_tuple,
02661 &negated_fields
02662 };
02663
02664
02665
02666 static cfg_type_t cfg_type_addrmatchelt = {
02667 "address_match_element", parse_addrmatchelt, NULL, cfg_doc_terminal,
02668 NULL, NULL
02669 };
02670
02671
02672
02673 static cfg_type_t cfg_type_bracketed_aml = {
02674 "bracketed_aml", cfg_parse_bracketed_list, cfg_print_bracketed_list,
02675 cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_addrmatchelt
02676 };
02677
02678
02679
02680
02681
02682
02683 static unsigned int controls_sockaddr_flags =
02684 CFG_ADDR_V4OK | CFG_ADDR_V6OK | CFG_ADDR_WILDOK;
02685 static cfg_type_t cfg_type_controls_sockaddr = {
02686 "controls_sockaddr", cfg_parse_sockaddr, cfg_print_sockaddr,
02687 cfg_doc_sockaddr, &cfg_rep_sockaddr, &controls_sockaddr_flags
02688 };
02689
02690
02691
02692
02693
02694 static isc_result_t
02695 parse_server_key_kludge(cfg_parser_t *pctx, const cfg_type_t *type,
02696 cfg_obj_t **ret)
02697 {
02698 isc_result_t result;
02699 isc_boolean_t braces = ISC_FALSE;
02700 UNUSED(type);
02701
02702
02703 CHECK(cfg_peektoken(pctx, 0));
02704 if (pctx->token.type == isc_tokentype_special &&
02705 pctx->token.value.as_char == '{') {
02706 CHECK(cfg_gettoken(pctx, 0));
02707 braces = ISC_TRUE;
02708 }
02709
02710 CHECK(cfg_parse_obj(pctx, &cfg_type_astring, ret));
02711
02712 if (braces) {
02713
02714 CHECK(cfg_peektoken(pctx, 0));
02715 if (pctx->token.type == isc_tokentype_special &&
02716 pctx->token.value.as_char == ';')
02717 CHECK(cfg_gettoken(pctx, 0));
02718
02719 CHECK(cfg_parse_special(pctx, '}'));
02720 }
02721 cleanup:
02722 return (result);
02723 }
02724 static cfg_type_t cfg_type_server_key_kludge = {
02725 "server_key", parse_server_key_kludge, NULL, cfg_doc_terminal,
02726 NULL, NULL
02727 };
02728
02729
02730
02731
02732
02733
02734 static isc_result_t
02735 parse_optional_facility(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret)
02736 {
02737 isc_result_t result;
02738 UNUSED(type);
02739
02740 CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING));
02741 if (pctx->token.type == isc_tokentype_string ||
02742 pctx->token.type == isc_tokentype_qstring) {
02743 CHECK(cfg_parse_obj(pctx, &cfg_type_astring, ret));
02744 } else {
02745 CHECK(cfg_parse_obj(pctx, &cfg_type_void, ret));
02746 }
02747 cleanup:
02748 return (result);
02749 }
02750
02751 static cfg_type_t cfg_type_optional_facility = {
02752 "optional_facility", parse_optional_facility, NULL, cfg_doc_terminal,
02753 NULL, NULL };
02754
02755
02756
02757
02758
02759
02760
02761 static keyword_type_t debug_kw = { "debug", &cfg_type_uint32 };
02762 static cfg_type_t cfg_type_debuglevel = {
02763 "debuglevel", parse_keyvalue,
02764 print_keyvalue, doc_keyvalue,
02765 &cfg_rep_uint32, &debug_kw
02766 };
02767
02768 static isc_result_t
02769 parse_logseverity(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
02770 isc_result_t result;
02771 UNUSED(type);
02772
02773 CHECK(cfg_peektoken(pctx, 0));
02774 if (pctx->token.type == isc_tokentype_string &&
02775 strcasecmp(TOKEN_STRING(pctx), "debug") == 0) {
02776 CHECK(cfg_gettoken(pctx, 0));
02777 CHECK(cfg_peektoken(pctx, ISC_LEXOPT_NUMBER));
02778 if (pctx->token.type == isc_tokentype_number) {
02779 CHECK(cfg_parse_uint32(pctx, NULL, ret));
02780 } else {
02781
02782
02783
02784
02785
02786 CHECK(cfg_create_obj(pctx, &cfg_type_uint32, ret));
02787 (*ret)->value.uint32 = 1;
02788 }
02789 (*ret)->type = &cfg_type_debuglevel;
02790 } else {
02791 CHECK(cfg_parse_obj(pctx, &cfg_type_loglevel, ret));
02792 }
02793 cleanup:
02794 return (result);
02795 }
02796
02797 static cfg_type_t cfg_type_logseverity = {
02798 "log_severity", parse_logseverity, NULL, cfg_doc_terminal,
02799 NULL, NULL };
02800
02801
02802
02803
02804
02805
02806 static const char *logversions_enums[] = { "unlimited", NULL };
02807 static isc_result_t
02808 parse_logversions(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
02809 return (parse_enum_or_other(pctx, type, &cfg_type_uint32, ret));
02810 }
02811
02812 static cfg_type_t cfg_type_logversions = {
02813 "logversions", parse_logversions, cfg_print_ustring, cfg_doc_terminal,
02814 &cfg_rep_string, logversions_enums
02815 };
02816
02817 static cfg_tuplefielddef_t logfile_fields[] = {
02818 { "file", &cfg_type_qstring, 0 },
02819 { "versions", &cfg_type_logversions, 0 },
02820 { "size", &cfg_type_size, 0 },
02821 { NULL, NULL, 0 }
02822 };
02823
02824 static isc_result_t
02825 parse_logfile(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
02826 isc_result_t result;
02827 cfg_obj_t *obj = NULL;
02828 const cfg_tuplefielddef_t *fields = type->of;
02829
02830 CHECK(cfg_create_tuple(pctx, type, &obj));
02831
02832
02833 CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));
02834
02835
02836 for (;;) {
02837 CHECK(cfg_peektoken(pctx, 0));
02838 if (pctx->token.type == isc_tokentype_string) {
02839 CHECK(cfg_gettoken(pctx, 0));
02840 if (strcasecmp(TOKEN_STRING(pctx),
02841 "versions") == 0 &&
02842 obj->value.tuple[1] == NULL) {
02843 CHECK(cfg_parse_obj(pctx, fields[1].type,
02844 &obj->value.tuple[1]));
02845 } else if (strcasecmp(TOKEN_STRING(pctx),
02846 "size") == 0 &&
02847 obj->value.tuple[2] == NULL) {
02848 CHECK(cfg_parse_obj(pctx, fields[2].type,
02849 &obj->value.tuple[2]));
02850 } else {
02851 break;
02852 }
02853 } else {
02854 break;
02855 }
02856 }
02857
02858
02859 if (obj->value.tuple[1] == NULL)
02860 CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[1]));
02861 if (obj->value.tuple[2] == NULL)
02862 CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[2]));
02863
02864 *ret = obj;
02865 return (ISC_R_SUCCESS);
02866
02867 cleanup:
02868 CLEANUP_OBJ(obj);
02869 return (result);
02870 }
02871
02872 static void
02873 print_logfile(cfg_printer_t *pctx, const cfg_obj_t *obj) {
02874 cfg_print_obj(pctx, obj->value.tuple[0]);
02875 if (obj->value.tuple[1]->type->print != cfg_print_void) {
02876 cfg_print_cstr(pctx, " versions ");
02877 cfg_print_obj(pctx, obj->value.tuple[1]);
02878 }
02879 if (obj->value.tuple[2]->type->print != cfg_print_void) {
02880 cfg_print_cstr(pctx, " size ");
02881 cfg_print_obj(pctx, obj->value.tuple[2]);
02882 }
02883 }
02884
02885
02886 static void
02887 doc_logfile(cfg_printer_t *pctx, const cfg_type_t *type) {
02888 UNUSED(type);
02889 cfg_print_cstr(pctx, "<quoted_string>");
02890 cfg_print_cstr(pctx, " ");
02891 cfg_print_cstr(pctx, "[ versions ( \"unlimited\" | <integer> ) ]");
02892 cfg_print_cstr(pctx, " ");
02893 cfg_print_cstr(pctx, "[ size <size> ]");
02894 }
02895
02896 static cfg_type_t cfg_type_logfile = {
02897 "log_file", parse_logfile, print_logfile, doc_logfile,
02898 &cfg_rep_tuple, logfile_fields
02899 };
02900
02901
02902 static cfg_type_t cfg_type_sockaddr4wild = {
02903 "sockaddr4wild", cfg_parse_sockaddr, cfg_print_sockaddr,
02904 cfg_doc_sockaddr, &cfg_rep_sockaddr, &sockaddr4wild_flags
02905 };
02906
02907
02908 static cfg_type_t cfg_type_sockaddr6wild = {
02909 "v6addrportwild", cfg_parse_sockaddr, cfg_print_sockaddr,
02910 cfg_doc_sockaddr, &cfg_rep_sockaddr, &sockaddr6wild_flags
02911 };
02912
02913
02914
02915
02916
02917 static cfg_tuplefielddef_t lwres_view_fields[] = {
02918 { "name", &cfg_type_astring, 0 },
02919 { "class", &cfg_type_optional_class, 0 },
02920 { NULL, NULL, 0 }
02921 };
02922 static cfg_type_t cfg_type_lwres_view = {
02923 "lwres_view", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple,
02924 lwres_view_fields
02925 };
02926
02927 static cfg_type_t cfg_type_lwres_searchlist = {
02928 "lwres_searchlist", cfg_parse_bracketed_list, cfg_print_bracketed_list,
02929 cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring };
02930
02931 static cfg_clausedef_t
02932 lwres_clauses[] = {
02933 { "listen-on", &cfg_type_portiplist, 0 },
02934 { "view", &cfg_type_lwres_view, 0 },
02935 { "search", &cfg_type_lwres_searchlist, 0 },
02936 { "ndots", &cfg_type_uint32, 0 },
02937 { "lwres-tasks", &cfg_type_uint32, 0},
02938 { "lwres-clients", &cfg_type_uint32, 0},
02939 { NULL, NULL, 0 }
02940 };
02941
02942 static cfg_clausedef_t *
02943 lwres_clausesets[] = {
02944 lwres_clauses,
02945 NULL
02946 };
02947 static cfg_type_t cfg_type_lwres = {
02948 "lwres", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map,
02949 lwres_clausesets
02950 };
02951
02952
02953
02954
02955
02956 static cfg_clausedef_t
02957 rndcconf_options_clauses[] = {
02958 { "default-key", &cfg_type_astring, 0 },
02959 { "default-port", &cfg_type_uint32, 0 },
02960 { "default-server", &cfg_type_astring, 0 },
02961 { "default-source-address", &cfg_type_netaddr4wild, 0 },
02962 { "default-source-address-v6", &cfg_type_netaddr6wild, 0 },
02963 { NULL, NULL, 0 }
02964 };
02965
02966 static cfg_clausedef_t *
02967 rndcconf_options_clausesets[] = {
02968 rndcconf_options_clauses,
02969 NULL
02970 };
02971
02972 static cfg_type_t cfg_type_rndcconf_options = {
02973 "rndcconf_options", cfg_parse_map, cfg_print_map, cfg_doc_map,
02974 &cfg_rep_map, rndcconf_options_clausesets
02975 };
02976
02977 static cfg_clausedef_t
02978 rndcconf_server_clauses[] = {
02979 { "key", &cfg_type_astring, 0 },
02980 { "port", &cfg_type_uint32, 0 },
02981 { "source-address", &cfg_type_netaddr4wild, 0 },
02982 { "source-address-v6", &cfg_type_netaddr6wild, 0 },
02983 { "addresses", &cfg_type_bracketed_sockaddrnameportlist, 0 },
02984 { NULL, NULL, 0 }
02985 };
02986
02987 static cfg_clausedef_t *
02988 rndcconf_server_clausesets[] = {
02989 rndcconf_server_clauses,
02990 NULL
02991 };
02992
02993 static cfg_type_t cfg_type_rndcconf_server = {
02994 "rndcconf_server", cfg_parse_named_map, cfg_print_map, cfg_doc_map,
02995 &cfg_rep_map, rndcconf_server_clausesets
02996 };
02997
02998 static cfg_clausedef_t
02999 rndcconf_clauses[] = {
03000 { "key", &cfg_type_key, CFG_CLAUSEFLAG_MULTI },
03001 { "server", &cfg_type_rndcconf_server, CFG_CLAUSEFLAG_MULTI },
03002 { "options", &cfg_type_rndcconf_options, 0 },
03003 { NULL, NULL, 0 }
03004 };
03005
03006 static cfg_clausedef_t *
03007 rndcconf_clausesets[] = {
03008 rndcconf_clauses,
03009 NULL
03010 };
03011
03012 LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_rndcconf = {
03013 "rndcconf", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody,
03014 &cfg_rep_map, rndcconf_clausesets
03015 };
03016
03017 static cfg_clausedef_t
03018 rndckey_clauses[] = {
03019 { "key", &cfg_type_key, 0 },
03020 { NULL, NULL, 0 }
03021 };
03022
03023 static cfg_clausedef_t *
03024 rndckey_clausesets[] = {
03025 rndckey_clauses,
03026 NULL
03027 };
03028
03029 LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_rndckey = {
03030 "rndckey", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody,
03031 &cfg_rep_map, rndckey_clausesets
03032 };
03033
03034
03035
03036
03037
03038 LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_sessionkey = {
03039 "sessionkey", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody,
03040 &cfg_rep_map, rndckey_clausesets
03041 };
03042
03043 static cfg_tuplefielddef_t nameport_fields[] = {
03044 { "name", &cfg_type_astring, 0 },
03045 { "port", &cfg_type_optional_port, 0 },
03046 { "dscp", &cfg_type_optional_dscp, 0 },
03047 { NULL, NULL, 0 }
03048 };
03049
03050 static cfg_type_t cfg_type_nameport = {
03051 "nameport", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
03052 &cfg_rep_tuple, nameport_fields
03053 };
03054
03055 static void
03056 doc_sockaddrnameport(cfg_printer_t *pctx, const cfg_type_t *type) {
03057 UNUSED(type);
03058 cfg_print_cstr(pctx, "( ");
03059 cfg_print_cstr(pctx, "<quoted_string>");
03060 cfg_print_cstr(pctx, " ");
03061 cfg_print_cstr(pctx, "[ port <integer> ]");
03062 cfg_print_cstr(pctx, " ");
03063 cfg_print_cstr(pctx, "[ dscp <integer> ]");
03064 cfg_print_cstr(pctx, " | ");
03065 cfg_print_cstr(pctx, "<ipv4_address>");
03066 cfg_print_cstr(pctx, " ");
03067 cfg_print_cstr(pctx, "[ port <integer> ]");
03068 cfg_print_cstr(pctx, " ");
03069 cfg_print_cstr(pctx, "[ dscp <integer> ]");
03070 cfg_print_cstr(pctx, " | ");
03071 cfg_print_cstr(pctx, "<ipv6_address>");
03072 cfg_print_cstr(pctx, " ");
03073 cfg_print_cstr(pctx, "[ port <integer> ]");
03074 cfg_print_cstr(pctx, " ");
03075 cfg_print_cstr(pctx, "[ dscp <integer> ]");
03076 cfg_print_cstr(pctx, " )");
03077 }
03078
03079 static isc_result_t
03080 parse_sockaddrnameport(cfg_parser_t *pctx, const cfg_type_t *type,
03081 cfg_obj_t **ret)
03082 {
03083 isc_result_t result;
03084 cfg_obj_t *obj = NULL;
03085 UNUSED(type);
03086
03087 CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING));
03088 if (pctx->token.type == isc_tokentype_string ||
03089 pctx->token.type == isc_tokentype_qstring) {
03090 if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V6OK))
03091 CHECK(cfg_parse_sockaddr(pctx, &cfg_type_sockaddr, ret));
03092 else {
03093 const cfg_tuplefielddef_t *fields =
03094 cfg_type_nameport.of;
03095 CHECK(cfg_create_tuple(pctx, &cfg_type_nameport,
03096 &obj));
03097 CHECK(cfg_parse_obj(pctx, fields[0].type,
03098 &obj->value.tuple[0]));
03099 CHECK(cfg_parse_obj(pctx, fields[1].type,
03100 &obj->value.tuple[1]));
03101 CHECK(cfg_parse_obj(pctx, fields[2].type,
03102 &obj->value.tuple[2]));
03103 *ret = obj;
03104 obj = NULL;
03105 }
03106 } else {
03107 cfg_parser_error(pctx, CFG_LOG_NEAR,
03108 "expected IP address or hostname");
03109 return (ISC_R_UNEXPECTEDTOKEN);
03110 }
03111 cleanup:
03112 CLEANUP_OBJ(obj);
03113 return (result);
03114 }
03115
03116 static cfg_type_t cfg_type_sockaddrnameport = {
03117 "sockaddrnameport_element", parse_sockaddrnameport, NULL,
03118 doc_sockaddrnameport, NULL, NULL
03119 };
03120
03121 static cfg_type_t cfg_type_bracketed_sockaddrnameportlist = {
03122 "bracketed_sockaddrnameportlist", cfg_parse_bracketed_list,
03123 cfg_print_bracketed_list, cfg_doc_bracketed_list,
03124 &cfg_rep_list, &cfg_type_sockaddrnameport
03125 };
03126
03127
03128
03129
03130
03131
03132 static cfg_tuplefielddef_t nameportiplist_fields[] = {
03133 { "port", &cfg_type_optional_port, 0 },
03134 { "addresses", &cfg_type_bracketed_sockaddrnameportlist, 0 },
03135 { NULL, NULL, 0 }
03136 };
03137
03138 static cfg_type_t cfg_type_nameportiplist = {
03139 "nameportiplist", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
03140 &cfg_rep_tuple, nameportiplist_fields
03141 };
03142
03143
03144
03145
03146
03147 static void
03148 doc_masterselement(cfg_printer_t *pctx, const cfg_type_t *type) {
03149 UNUSED(type);
03150 cfg_print_cstr(pctx, "( ");
03151 cfg_print_cstr(pctx, "<masters>");
03152 cfg_print_cstr(pctx, " | ");
03153 cfg_print_cstr(pctx, "<ipv4_address>");
03154 cfg_print_cstr(pctx, " ");
03155 cfg_print_cstr(pctx, "[ port <integer> ]");
03156 cfg_print_cstr(pctx, " | ");
03157 cfg_print_cstr(pctx, "<ipv6_address>");
03158 cfg_print_cstr(pctx, " ");
03159 cfg_print_cstr(pctx, "[ port <integer> ]");
03160 cfg_print_cstr(pctx, " )");
03161 }
03162
03163 static isc_result_t
03164 parse_masterselement(cfg_parser_t *pctx, const cfg_type_t *type,
03165 cfg_obj_t **ret)
03166 {
03167 isc_result_t result;
03168 cfg_obj_t *obj = NULL;
03169 UNUSED(type);
03170
03171 CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING));
03172 if (pctx->token.type == isc_tokentype_string ||
03173 pctx->token.type == isc_tokentype_qstring) {
03174 if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V6OK))
03175 CHECK(cfg_parse_sockaddr(pctx, &cfg_type_sockaddr, ret));
03176 else
03177 CHECK(cfg_parse_astring(pctx, &cfg_type_astring, ret));
03178 } else {
03179 cfg_parser_error(pctx, CFG_LOG_NEAR,
03180 "expected IP address or masters name");
03181 return (ISC_R_UNEXPECTEDTOKEN);
03182 }
03183 cleanup:
03184 CLEANUP_OBJ(obj);
03185 return (result);
03186 }
03187
03188 static cfg_type_t cfg_type_masterselement = {
03189 "masters_element", parse_masterselement, NULL,
03190 doc_masterselement, NULL, NULL
03191 };
03192
03193 static isc_result_t
03194 parse_ttlval(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
03195 isc_result_t result;
03196 cfg_obj_t *obj = NULL;
03197 isc_uint32_t ttl;
03198
03199 UNUSED(type);
03200
03201 CHECK(cfg_gettoken(pctx, 0));
03202 if (pctx->token.type != isc_tokentype_string) {
03203 result = ISC_R_UNEXPECTEDTOKEN;
03204 goto cleanup;
03205 }
03206
03207 result = dns_ttl_fromtext(&pctx->token.value.as_textregion, &ttl);
03208 if (result == ISC_R_RANGE ) {
03209 cfg_parser_error(pctx, CFG_LOG_NEAR, "TTL out of range ");
03210 return (result);
03211 } else if (result != ISC_R_SUCCESS)
03212 goto cleanup;
03213
03214 CHECK(cfg_create_obj(pctx, &cfg_type_uint32, &obj));
03215 obj->value.uint32 = ttl;
03216 *ret = obj;
03217 return (ISC_R_SUCCESS);
03218
03219 cleanup:
03220 cfg_parser_error(pctx, CFG_LOG_NEAR, "expected integer and optional unit");
03221 return (result);
03222 }
03223
03224
03225
03226
03227 static cfg_type_t cfg_type_ttlval = {
03228 "ttlval", parse_ttlval, cfg_print_uint64, cfg_doc_terminal,
03229 &cfg_rep_uint64, NULL
03230 };
03231
03232 static isc_result_t
03233 parse_maxttl(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
03234 return (parse_enum_or_other(pctx, type, &cfg_type_ttlval, ret));
03235 }
03236
03237
03238
03239
03240 static const char *maxttl_enums[] = { "unlimited", NULL };
03241 static cfg_type_t cfg_type_maxttl = {
03242 "maxttl_no_default", parse_maxttl, cfg_print_ustring, cfg_doc_terminal,
03243 &cfg_rep_string, maxttl_enums
03244 };