isc_result_t irs_dnsconf_load(isc_mem_t *mctx, const char *filename, irs_dnsconf_t **confp) { irs_dnsconf_t *conf; cfg_parser_t *parser = NULL; cfg_obj_t *cfgobj = NULL; isc_result_t result = ISC_R_SUCCESS; REQUIRE(confp != NULL && *confp == NULL); conf = isc_mem_get(mctx, sizeof(*conf)); if (conf == NULL) return (ISC_R_NOMEMORY); conf->mctx = mctx; ISC_LIST_INIT(conf->trusted_keylist); /* * If the specified file does not exist, we'll simply with an empty * configuration. */ if (!isc_file_exists(filename)) goto cleanup; result = cfg_parser_create(mctx, NULL, &parser); if (result != ISC_R_SUCCESS) goto cleanup; result = cfg_parse_file(parser, filename, &cfg_type_dnsconf, &cfgobj); if (result != ISC_R_SUCCESS) goto cleanup; result = configure_dnsseckeys(conf, cfgobj, dns_rdataclass_in); cleanup: if (parser != NULL) { if (cfgobj != NULL) cfg_obj_destroy(parser, &cfgobj); cfg_parser_destroy(&parser); } conf->magic = IRS_DNSCONF_MAGIC; if (result == ISC_R_SUCCESS) *confp = conf; else irs_dnsconf_destroy(&conf); return (result); }
static isc_result_t get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) { isc_result_t result; cfg_parser_t *pctx = NULL; cfg_obj_t *config = NULL; const cfg_obj_t *key = NULL; const cfg_obj_t *algobj = NULL; const cfg_obj_t *secretobj = NULL; const char *algstr = NULL; const char *secretstr = NULL; controlkey_t *keyid = NULL; char secret[1024]; unsigned int algtype; isc_buffer_t b; isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_CONTROL, ISC_LOG_INFO, "configuring command channel from '%s'", ns_g_keyfile); if (! isc_file_exists(ns_g_keyfile)) return (ISC_R_FILENOTFOUND); CHECK(cfg_parser_create(mctx, ns_g_lctx, &pctx)); CHECK(cfg_parse_file(pctx, ns_g_keyfile, &cfg_type_rndckey, &config)); CHECK(cfg_map_get(config, "key", &key)); keyid = isc_mem_get(mctx, sizeof(*keyid)); if (keyid == NULL) CHECK(ISC_R_NOMEMORY); keyid->keyname = isc_mem_strdup(mctx, cfg_obj_asstring(cfg_map_getname(key))); keyid->secret.base = NULL; keyid->secret.length = 0; keyid->algorithm = DST_ALG_UNKNOWN; ISC_LINK_INIT(keyid, link); if (keyid->keyname == NULL) CHECK(ISC_R_NOMEMORY); CHECK(bind9_check_key(key, ns_g_lctx)); (void)cfg_map_get(key, "algorithm", &algobj); (void)cfg_map_get(key, "secret", &secretobj); INSIST(algobj != NULL && secretobj != NULL); algstr = cfg_obj_asstring(algobj); secretstr = cfg_obj_asstring(secretobj); if (ns_config_getkeyalgorithm2(algstr, NULL, &algtype, NULL) != ISC_R_SUCCESS) { cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, "unsupported algorithm '%s' in " "key '%s' for use with command " "channel", algstr, keyid->keyname); goto cleanup; } keyid->algorithm = algtype; isc_buffer_init(&b, secret, sizeof(secret)); result = isc_base64_decodestring(secretstr, &b); if (result != ISC_R_SUCCESS) { cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, "secret for key '%s' on command channel: %s", keyid->keyname, isc_result_totext(result)); goto cleanup; } keyid->secret.length = isc_buffer_usedlength(&b); keyid->secret.base = isc_mem_get(mctx, keyid->secret.length); if (keyid->secret.base == NULL) { cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, "couldn't register key '%s': " "out of memory", keyid->keyname); CHECK(ISC_R_NOMEMORY); } memmove(keyid->secret.base, isc_buffer_base(&b), keyid->secret.length); ISC_LIST_APPEND(*keyids, keyid, link); keyid = NULL; result = ISC_R_SUCCESS; cleanup: if (keyid != NULL) free_controlkey(keyid, mctx); if (config != NULL) cfg_obj_destroy(pctx, &config); if (pctx != NULL) cfg_parser_destroy(&pctx); return (result); }
/*% The main processing routine */ int main(int argc, char **argv) { int c; cfg_parser_t *parser = NULL; cfg_obj_t *config = NULL; const char *conffile = NULL; isc_mem_t *mctx = NULL; isc_result_t result; int exit_status = 0; isc_entropy_t *ectx = NULL; isc_boolean_t load_zones = ISC_FALSE; isc_boolean_t print = ISC_FALSE; unsigned int flags = 0; isc_commandline_errprint = ISC_FALSE; /* * Process memory debugging argument first. */ #define CMDLINE_FLAGS "dhjm:t:pvxz" while ((c = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (c) { case 'm': if (strcasecmp(isc_commandline_argument, "record") == 0) isc_mem_debugging |= ISC_MEM_DEBUGRECORD; if (strcasecmp(isc_commandline_argument, "trace") == 0) isc_mem_debugging |= ISC_MEM_DEBUGTRACE; if (strcasecmp(isc_commandline_argument, "usage") == 0) isc_mem_debugging |= ISC_MEM_DEBUGUSAGE; if (strcasecmp(isc_commandline_argument, "size") == 0) isc_mem_debugging |= ISC_MEM_DEBUGSIZE; if (strcasecmp(isc_commandline_argument, "mctx") == 0) isc_mem_debugging |= ISC_MEM_DEBUGCTX; break; default: break; } } isc_commandline_reset = ISC_TRUE; RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); while ((c = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != EOF) { switch (c) { case 'd': debug++; break; case 'j': nomerge = ISC_FALSE; break; case 'm': break; case 't': result = isc_dir_chroot(isc_commandline_argument); if (result != ISC_R_SUCCESS) { fprintf(stderr, "isc_dir_chroot: %s\n", isc_result_totext(result)); exit(1); } break; case 'p': print = ISC_TRUE; break; case 'v': printf(VERSION "\n"); exit(0); case 'x': flags |= CFG_PRINTER_XKEY; break; case 'z': load_zones = ISC_TRUE; docheckmx = ISC_FALSE; docheckns = ISC_FALSE; dochecksrv = ISC_FALSE; break; case '?': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); /* FALLTHROUGH */ case 'h': usage(); default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } if (((flags & CFG_PRINTER_XKEY) != 0) && !print) { fprintf(stderr, "%s: -x cannot be used without -p\n", program); exit(1); } if (isc_commandline_index + 1 < argc) usage(); if (argv[isc_commandline_index] != NULL) conffile = argv[isc_commandline_index]; if (conffile == NULL || conffile[0] == '\0') conffile = NAMED_CONFFILE; #ifdef _WIN32 InitSockets(); #endif RUNTIME_CHECK(setup_logging(mctx, stdout, &logc) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE) == ISC_R_SUCCESS); dns_result_register(); RUNTIME_CHECK(cfg_parser_create(mctx, logc, &parser) == ISC_R_SUCCESS); cfg_parser_setcallback(parser, directory_callback, NULL); if (cfg_parse_file(parser, conffile, &cfg_type_namedconf, &config) != ISC_R_SUCCESS) exit(1); result = bind9_check_namedconf(config, logc, mctx); if (result != ISC_R_SUCCESS) exit_status = 1; if (result == ISC_R_SUCCESS && load_zones) { result = load_zones_fromconfig(config, mctx); if (result != ISC_R_SUCCESS) exit_status = 1; } if (print && exit_status == 0) cfg_printx(config, flags, output, NULL); cfg_obj_destroy(parser, &config); cfg_parser_destroy(&parser); dns_name_destroy(); isc_log_destroy(&logc); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); #ifdef _WIN32 DestroySockets(); #endif return (exit_status); }
/*% The main processing routine */ int main(int argc, char **argv) { int c; cfg_parser_t *parser = NULL; cfg_obj_t *config = NULL; const char *conffile = NULL; isc_mem_t *mctx = NULL; isc_result_t result; int exit_status = 0; isc_entropy_t *ectx = NULL; isc_boolean_t load_zones = ISC_FALSE; isc_boolean_t print = ISC_FALSE; isc_commandline_errprint = ISC_FALSE; while ((c = isc_commandline_parse(argc, argv, "dhjt:pvz")) != EOF) { switch (c) { case 'd': debug++; break; case 'j': nomerge = ISC_FALSE; break; case 't': result = isc_dir_chroot(isc_commandline_argument); if (result != ISC_R_SUCCESS) { fprintf(stderr, "isc_dir_chroot: %s\n", isc_result_totext(result)); exit(1); } break; case 'p': print = ISC_TRUE; break; case 'v': printf(VERSION "\n"); exit(0); case 'z': load_zones = ISC_TRUE; docheckmx = ISC_FALSE; docheckns = ISC_FALSE; dochecksrv = ISC_FALSE; break; case '?': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); case 'h': usage(); default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } if (isc_commandline_index + 1 < argc) usage(); if (argv[isc_commandline_index] != NULL) conffile = argv[isc_commandline_index]; if (conffile == NULL || conffile[0] == '\0') conffile = NAMED_CONFFILE; #ifdef _WIN32 InitSockets(); #endif RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); RUNTIME_CHECK(setup_logging(mctx, stdout, &logc) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE) == ISC_R_SUCCESS); dns_result_register(); RUNTIME_CHECK(cfg_parser_create(mctx, logc, &parser) == ISC_R_SUCCESS); cfg_parser_setcallback(parser, directory_callback, NULL); if (cfg_parse_file(parser, conffile, &cfg_type_namedconf, &config) != ISC_R_SUCCESS) exit(1); result = bind9_check_namedconf(config, logc, mctx); if (result != ISC_R_SUCCESS) exit_status = 1; if (result == ISC_R_SUCCESS && load_zones) { result = load_zones_fromconfig(config, mctx); if (result != ISC_R_SUCCESS) exit_status = 1; } if (print && exit_status == 0) cfg_print(config, output, NULL); cfg_obj_destroy(parser, &config); cfg_parser_destroy(&parser); dns_name_destroy(); isc_log_destroy(&logc); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); #ifdef _WIN32 DestroySockets(); #endif return (exit_status); }
int main(int argc, char **argv) { isc_boolean_t show_final_mem = ISC_FALSE; isc_result_t result = ISC_R_SUCCESS; isc_taskmgr_t *taskmgr = NULL; isc_task_t *task = NULL; isc_log_t *log = NULL; isc_logconfig_t *logconfig = NULL; isc_logdestination_t logdest; cfg_parser_t *pctx = NULL; cfg_obj_t *config = NULL; const char *keyname = NULL; char *p; size_t argslen; int ch; int i; result = isc_file_progname(*argv, program, sizeof(program)); if (result != ISC_R_SUCCESS) memcpy(program, "rndc", 5); progname = program; admin_conffile = RNDC_CONFFILE; admin_keyfile = RNDC_KEYFILE; result = isc_app_start(); if (result != ISC_R_SUCCESS) fatal("isc_app_start() failed: %s", isc_result_totext(result)); while ((ch = isc_commandline_parse(argc, argv, "c:k:Mmp:s:Vy:")) != -1) { switch (ch) { case 'c': admin_conffile = isc_commandline_argument; break; case 'k': admin_keyfile = isc_commandline_argument; break; case 'M': isc_mem_debugging = ISC_MEM_DEBUGTRACE; break; case 'm': show_final_mem = ISC_TRUE; break; case 'p': remoteport = atoi(isc_commandline_argument); if (remoteport > 65535 || remoteport == 0) fatal("port '%s' out of range", isc_commandline_argument); break; case 's': servername = isc_commandline_argument; break; case 'V': verbose = ISC_TRUE; break; case 'y': keyname = isc_commandline_argument; break; case '?': usage(0); break; default: fatal("unexpected error parsing command arguments: " "got %c\n", ch); break; } } argc -= isc_commandline_index; argv += isc_commandline_index; if (argc < 1) usage(1); isc_random_get(&serial); DO("create memory context", isc_mem_create(0, 0, &mctx)); DO("create socket manager", isc_socketmgr_create(mctx, &socketmgr)); DO("create task manager", isc_taskmgr_create(mctx, 1, 0, &taskmgr)); DO("create task", isc_task_create(taskmgr, 0, &task)); DO("create logging context", isc_log_create(mctx, &log, &logconfig)); isc_log_setcontext(log); DO("setting log tag", isc_log_settag(logconfig, progname)); logdest.file.stream = stderr; logdest.file.name = NULL; logdest.file.versions = ISC_LOG_ROLLNEVER; logdest.file.maximum_size = 0; DO("creating log channel", isc_log_createchannel(logconfig, "stderr", ISC_LOG_TOFILEDESC, ISC_LOG_INFO, &logdest, ISC_LOG_PRINTTAG|ISC_LOG_PRINTLEVEL)); DO("enabling log channel", isc_log_usechannel(logconfig, "stderr", NULL, NULL)); parse_config(mctx, log, keyname, &pctx, &config); isccc_result_register(); command = *argv; /* * Convert argc/argv into a space-delimited command string * similar to what the user might enter in interactive mode * (if that were implemented). */ argslen = 0; for (i = 0; i < argc; i++) argslen += strlen(argv[i]) + 1; args = isc_mem_get(mctx, argslen); if (args == NULL) DO("isc_mem_get", ISC_R_NOMEMORY); p = args; for (i = 0; i < argc; i++) { size_t len = strlen(argv[i]); memcpy(p, argv[i], len); p += len; *p++ = ' '; } p--; *p++ = '\0'; INSIST(p == args + argslen); notify("%s", command); if (strcmp(command, "restart") == 0) fatal("'%s' is not implemented", command); DO("post event", isc_app_onrun(mctx, task, rndc_start, NULL)); result = isc_app_run(); if (result != ISC_R_SUCCESS) fatal("isc_app_run() failed: %s", isc_result_totext(result)); if (connects > 0 || sends > 0 || recvs > 0) isc_socket_cancel(sock, task, ISC_SOCKCANCEL_ALL); isc_task_detach(&task); isc_taskmgr_destroy(&taskmgr); isc_socketmgr_destroy(&socketmgr); isc_log_destroy(&log); isc_log_setcontext(NULL); cfg_obj_destroy(pctx, &config); cfg_parser_destroy(&pctx); isc_mem_put(mctx, args, argslen); isccc_ccmsg_invalidate(&ccmsg); if (show_final_mem) isc_mem_stats(mctx, stderr); isc_mem_destroy(&mctx); if (failed) return (1); return (0); }
int main(int argc, char **argv) { isc_result_t result; isc_mem_t *mctx = NULL; isc_log_t *lctx = NULL; isc_logconfig_t *lcfg = NULL; isc_logdestination_t destination; cfg_parser_t *pctx = NULL; cfg_obj_t *cfg = NULL; cfg_type_t *type = NULL; isc_boolean_t grammar = ISC_FALSE; isc_boolean_t memstats = ISC_FALSE; char *filename = NULL; RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); result = isc_log_create(mctx, &lctx, &lcfg); check_result(result, "isc_log_create()"); isc_log_setcontext(lctx); /* * Create and install the default channel. */ destination.file.stream = stderr; destination.file.name = NULL; destination.file.versions = ISC_LOG_ROLLNEVER; destination.file.maximum_size = 0; result = isc_log_createchannel(lcfg, "_default", ISC_LOG_TOFILEDESC, ISC_LOG_DYNAMIC, &destination, ISC_LOG_PRINTTIME); check_result(result, "isc_log_createchannel()"); result = isc_log_usechannel(lcfg, "_default", NULL, NULL); check_result(result, "isc_log_usechannel()"); /* * Set the initial debug level. */ isc_log_setdebuglevel(lctx, 2); if (argc < 3) usage(); while (argc > 1) { if (strcmp(argv[1], "--grammar") == 0) { grammar = ISC_TRUE; } else if (strcmp(argv[1], "--memstats") == 0) { memstats = ISC_TRUE; } else if (strcmp(argv[1], "--named") == 0) { type = &cfg_type_namedconf; } else if (strcmp(argv[1], "--rndc") == 0) { type = &cfg_type_rndcconf; } else if (argv[1][0] == '-') { usage(); } else { filename = argv[1]; } argv++, argc--; } if (grammar) { if (type == NULL) usage(); cfg_print_grammar(type, output, NULL); } else { if (type == NULL || filename == NULL) usage(); RUNTIME_CHECK(cfg_parser_create(mctx, lctx, &pctx) == ISC_R_SUCCESS); result = cfg_parse_file(pctx, filename, type, &cfg); fprintf(stderr, "read config: %s\n", isc_result_totext(result)); if (result != ISC_R_SUCCESS) exit(1); cfg_print(cfg, output, NULL); cfg_obj_destroy(pctx, &cfg); cfg_parser_destroy(&pctx); } isc_log_destroy(&lctx); if (memstats) isc_mem_stats(mctx, stderr); isc_mem_destroy(&mctx); fflush(stdout); if (ferror(stdout)) { fprintf(stderr, "write error\n"); return (1); } else return (0); }
isc_result_t acl_from_ldap(isc_mem_t *mctx, const char *aclstr, acl_type_t type, dns_acl_t **aclp) { dns_acl_t *acl = NULL; isc_result_t result; ld_string_t *new_aclstr = NULL; cfg_parser_t *parser = NULL; cfg_obj_t *aclobj = NULL; cfg_aclconfctx_t *aclctx = NULL; /* ACL parser requires "configuration context". The parser looks for * undefined names in this context. We create empty context ("map" type), * i.e. only built-in named lists "any", "none" etc. are supported. */ cfg_obj_t *cctx = NULL; cfg_parser_t *parser_empty = NULL; REQUIRE(aclp != NULL && *aclp == NULL); CHECK(bracket_str(mctx, aclstr, &new_aclstr)); CHECK(cfg_parser_create(mctx, dns_lctx, &parser)); CHECK(cfg_parser_create(mctx, dns_lctx, &parser_empty)); CHECK(cfg_parse_strbuf(parser_empty, "{}", &empty_map_p, &cctx)); switch (type) { case acl_type_query: CHECK(cfg_parse_strbuf(parser, str_buf(new_aclstr), &cfg_type_allow_query, &aclobj)); break; case acl_type_transfer: CHECK(cfg_parse_strbuf(parser, str_buf(new_aclstr), &cfg_type_allow_transfer, &aclobj)); break; default: /* This is a bug */ REQUIRE("Unhandled ACL type in acl_from_ldap" == NULL); } CHECK(cfg_aclconfctx_create(mctx, &aclctx)); CHECK(cfg_acl_fromconfig(aclobj, cctx, dns_lctx, aclctx, mctx, 0, &acl)); *aclp = acl; result = ISC_R_SUCCESS; cleanup: if (result != ISC_R_SUCCESS) log_error_r("%s ACL parsing failed: '%s'", type == acl_type_query ? "query" : "transfer", aclstr); if (aclctx != NULL) cfg_aclconfctx_detach(&aclctx); if (aclobj != NULL) cfg_obj_destroy(parser, &aclobj); if (parser != NULL) cfg_parser_destroy(&parser); if (cctx != NULL) cfg_obj_destroy(parser_empty, &cctx); if (parser_empty != NULL) cfg_parser_destroy(&parser_empty); str_destroy(&new_aclstr); return result; }
isc_result_t acl_configure_zone_ssutable(const char *policy_str, dns_zone_t *zone) { isc_result_t result = ISC_R_SUCCESS; cfg_parser_t *parser = NULL; const cfg_listelt_t *el; cfg_obj_t *policy = NULL; dns_ssutable_t *table = NULL; ld_string_t *new_policy_str = NULL; isc_mem_t *mctx; REQUIRE(zone != NULL); mctx = dns_zone_getmctx(zone); if (policy_str == NULL) goto cleanup; CHECK(bracket_str(mctx, policy_str, &new_policy_str)); CHECK(cfg_parser_create(mctx, dns_lctx, &parser)); result = cfg_parse_strbuf(parser, str_buf(new_policy_str), &cfg_type_update_policy, &policy); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "failed to parse policy string"); goto cleanup; } CHECK(dns_ssutable_create(mctx, &table)); for (el = cfg_list_first(policy); el != NULL; el = cfg_list_next(el)) { const cfg_obj_t *stmt; isc_boolean_t grant; unsigned int match_type; dns_fixedname_t fname, fident; dns_rdatatype_t *types; unsigned int n; types = NULL; stmt = cfg_listelt_value(el); CHECK(get_mode(stmt, &grant)); CHECK(get_match_type(stmt, &match_type)); CHECK(get_fixed_name(stmt, "identity", &fident)); /* Use zone name for 'zonesub' match type */ result = get_fixed_name(stmt, "name", &fname); if (result == ISC_R_NOTFOUND && match_type == DNS_SSUMATCHTYPE_SUBDOMAIN) { dns_fixedname_init(&fname); CHECK(dns_name_copy(dns_zone_getorigin(zone), dns_fixedname_name(&fname), &fname.buffer)); } else if (result != ISC_R_SUCCESS) goto cleanup; CHECK(get_types(mctx, stmt, &types, &n)); if (match_type == DNS_SSUMATCHTYPE_WILDCARD && !dns_name_iswildcard(dns_fixedname_name(&fname))) { char name[DNS_NAME_FORMATSIZE]; dns_name_format(dns_fixedname_name(&fname), name, DNS_NAME_FORMATSIZE); dns_zone_log(zone, ISC_LOG_ERROR, "invalid update policy: " "name '%s' is expected to be a wildcard", name); CLEANUP_WITH(DNS_R_BADNAME); } result = dns_ssutable_addrule(table, grant, dns_fixedname_name(&fident), match_type, dns_fixedname_name(&fname), n, types); SAFE_MEM_PUT(mctx, types, n * sizeof(dns_rdatatype_t)); if (result != ISC_R_SUCCESS) goto cleanup; } cleanup: if (result == ISC_R_SUCCESS) dns_zone_setssutable(zone, table); str_destroy(&new_policy_str); if (policy != NULL) cfg_obj_destroy(parser, &policy); if (parser != NULL) cfg_parser_destroy(&parser); if (table != NULL) dns_ssutable_detach(&table); return result; }
int main(int argc, char **argv) { isc_result_t result = ISC_R_SUCCESS; isc_boolean_t show_final_mem = ISC_FALSE; isc_taskmgr_t *taskmgr = NULL; isc_task_t *task = NULL; isc_log_t *log = NULL; isc_logconfig_t *logconfig = NULL; isc_logdestination_t logdest; cfg_parser_t *pctx = NULL; cfg_obj_t *config = NULL; const char *keyname = NULL; struct in_addr in; struct in6_addr in6; char *p; size_t argslen; int ch; int i; result = isc_file_progname(*argv, program, sizeof(program)); if (result != ISC_R_SUCCESS) memmove(program, "rndc", 5); progname = program; admin_conffile = RNDC_CONFFILE; admin_keyfile = RNDC_KEYFILE; isc_sockaddr_any(&local4); isc_sockaddr_any6(&local6); result = isc_app_start(); if (result != ISC_R_SUCCESS) fatal("isc_app_start() failed: %s", isc_result_totext(result)); isc_commandline_errprint = ISC_FALSE; while ((ch = isc_commandline_parse(argc, argv, "b:c:hk:Mmp:qrs:Vy:")) != -1) { switch (ch) { case 'b': if (inet_pton(AF_INET, isc_commandline_argument, &in) == 1) { isc_sockaddr_fromin(&local4, &in, 0); local4set = ISC_TRUE; } else if (inet_pton(AF_INET6, isc_commandline_argument, &in6) == 1) { isc_sockaddr_fromin6(&local6, &in6, 0); local6set = ISC_TRUE; } break; case 'c': admin_conffile = isc_commandline_argument; c_flag = ISC_TRUE; break; case 'k': admin_keyfile = isc_commandline_argument; break; case 'M': isc_mem_debugging = ISC_MEM_DEBUGTRACE; break; case 'm': show_final_mem = ISC_TRUE; break; case 'p': remoteport = atoi(isc_commandline_argument); if (remoteport > 65535 || remoteport == 0) fatal("port '%s' out of range", isc_commandline_argument); break; case 'q': quiet = ISC_TRUE; break; case 'r': showresult = ISC_TRUE; break; case 's': servername = isc_commandline_argument; break; case 'V': verbose = ISC_TRUE; break; case 'y': keyname = isc_commandline_argument; break; case '?': if (isc_commandline_option != '?') { fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); usage(1); } /* FALLTHROUGH */ case 'h': usage(0); break; default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } argc -= isc_commandline_index; argv += isc_commandline_index; if (argc < 1) usage(1); isc_random_get(&serial); DO("create memory context", isc_mem_create(0, 0, &rndc_mctx)); DO("create socket manager", isc_socketmgr_create(rndc_mctx, &socketmgr)); DO("create task manager", isc_taskmgr_create(rndc_mctx, 1, 0, &taskmgr)); DO("create task", isc_task_create(taskmgr, 0, &task)); DO("create logging context", isc_log_create(rndc_mctx, &log, &logconfig)); isc_log_setcontext(log); DO("setting log tag", isc_log_settag(logconfig, progname)); logdest.file.stream = stderr; logdest.file.name = NULL; logdest.file.versions = ISC_LOG_ROLLNEVER; logdest.file.maximum_size = 0; DO("creating log channel", isc_log_createchannel(logconfig, "stderr", ISC_LOG_TOFILEDESC, ISC_LOG_INFO, &logdest, ISC_LOG_PRINTTAG|ISC_LOG_PRINTLEVEL)); DO("enabling log channel", isc_log_usechannel(logconfig, "stderr", NULL, NULL)); parse_config(rndc_mctx, log, keyname, &pctx, &config); isccc_result_register(); command = *argv; DO("allocate data buffer", isc_buffer_allocate(rndc_mctx, &databuf, 2048)); /* * Convert argc/argv into a space-delimited command string * similar to what the user might enter in interactive mode * (if that were implemented). */ argslen = 0; for (i = 0; i < argc; i++) argslen += strlen(argv[i]) + 1; args = isc_mem_get(rndc_mctx, argslen); if (args == NULL) DO("isc_mem_get", ISC_R_NOMEMORY); p = args; for (i = 0; i < argc; i++) { size_t len = strlen(argv[i]); memmove(p, argv[i], len); p += len; *p++ = ' '; } p--; *p++ = '\0'; INSIST(p == args + argslen); notify("%s", command); if (strcmp(command, "restart") == 0) fatal("'%s' is not implemented", command); if (nserveraddrs == 0) get_addresses(servername, (in_port_t) remoteport); DO("post event", isc_app_onrun(rndc_mctx, task, rndc_start, NULL)); result = isc_app_run(); if (result != ISC_R_SUCCESS) fatal("isc_app_run() failed: %s", isc_result_totext(result)); if (connects > 0 || sends > 0 || recvs > 0) isc_socket_cancel(sock, task, ISC_SOCKCANCEL_ALL); isc_task_detach(&task); isc_taskmgr_destroy(&taskmgr); isc_socketmgr_destroy(&socketmgr); isc_log_destroy(&log); isc_log_setcontext(NULL); cfg_obj_destroy(pctx, &config); cfg_parser_destroy(&pctx); isc_mem_put(rndc_mctx, args, argslen); isccc_ccmsg_invalidate(&ccmsg); dns_name_destroy(); isc_buffer_free(&databuf); if (show_final_mem) isc_mem_stats(rndc_mctx, stderr); isc_mem_destroy(&rndc_mctx); if (failed) return (1); return (0); }
isc_result_t fwd_print_list_buff(isc_mem_t *mctx, dns_forwarders_t *fwdrs, isc_buffer_t **out_buf) { isc_result_t result; size_t list_len; isc_buffer_t *dummy_fwdr_buf = NULL; /* fully dynamic allocation */ isc_buffer_t tmp_buf; /* hack: only the base buffer is allocated */ cfg_parser_t *parser = NULL; cfg_obj_t *forwarders_cfg = NULL; const cfg_obj_t *faddresses; const cfg_listelt_t *fwdr_cfg; /* config representation */ /* internal representation */ #if LIBDNS_VERSION_MAJOR < 140 isc_sockaddr_t *fwdr_int; #else /* LIBDNS_VERSION_MAJOR >= 140 */ dns_forwarder_t *fwdr_int; #endif isc_buffer_initnull(&tmp_buf); tmp_buf.mctx = mctx; CHECK(cfg_parser_create(mctx, dns_lctx, &parser)); /* Create dummy string with list of IP addresses of the same length * as the original list of forwarders. Parse this string to obtain * nested cfg structures which will be filled with data for actual * forwarders. * * This is nasty hack but it is easiest way to create list of cfg_objs * I found. */ list_len = fwd_list_len(fwdrs); CHECK(fwd_list_gen_dummy_config_string(mctx, list_len, &dummy_fwdr_buf)); CHECK(cfg_parse_buffer(parser, dummy_fwdr_buf, cfg_type_forwarders, &forwarders_cfg)); /* Walk through internal representation and cfg representation and copy * data from the internal one to cfg data structures.*/ faddresses = cfg_tuple_get(forwarders_cfg, "addresses"); for (fwdr_int = ISC_LIST_HEAD( #if LIBDNS_VERSION_MAJOR < 140 fwdrs->addrs #else /* LIBDNS_VERSION_MAJOR >= 140 */ fwdrs->fwdrs #endif ), fwdr_cfg = cfg_list_first(faddresses); INSIST((fwdr_int == NULL) == (fwdr_cfg == NULL)), fwdr_int != NULL; fwdr_int = ISC_LIST_NEXT(fwdr_int, link), fwdr_cfg = cfg_list_next(fwdr_cfg)) { #if LIBDNS_VERSION_MAJOR < 140 fwdr_cfg->obj->value.sockaddr = *fwdr_int; #else /* LIBDNS_VERSION_MAJOR >= 140 */ fwdr_cfg->obj->value.sockaddrdscp.sockaddr = fwdr_int->addr; fwdr_cfg->obj->value.sockaddrdscp.dscp = fwdr_int->dscp; #endif } cfg_print(faddresses, buffer_append_str, &tmp_buf); /* create and copy string from tmp to output buffer */ CHECK(isc_buffer_allocate(mctx, out_buf, tmp_buf.used)); isc_buffer_putmem(*out_buf, isc_buffer_base(&tmp_buf), isc_buffer_usedlength(&tmp_buf)); cleanup: if (forwarders_cfg != NULL) cfg_obj_destroy(parser, &forwarders_cfg); if (parser != NULL) cfg_parser_destroy(&parser); if (dummy_fwdr_buf != NULL) { if (tmp_buf.base != NULL) isc_mem_put(mctx, tmp_buf.base, tmp_buf.length); isc_buffer_free(&dummy_fwdr_buf); } return result; }