📄 controlconf.c
字号:
result = controlkeylist_fromcfg(control_keylist, listener->mctx, &keys); if (result == ISC_R_SUCCESS) { free_controlkeylist(&listener->keys, listener->mctx); listener->keys = keys; register_keys(control, global_keylist, &listener->keys, listener->mctx, socktext); } } else { free_controlkeylist(&listener->keys, listener->mctx); result = get_rndckey(listener->mctx, &listener->keys); } if (result != ISC_R_SUCCESS && global_keylist != NULL) { /* * This message might be a little misleading since the * "new keys" might in fact be identical to the old ones, * but tracking whether they are identical just for the * sake of avoiding this message would be too much trouble. */ if (control != NULL) cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, "couldn't install new keys for " "command channel %s: %s", socktext, isc_result_totext(result)); else isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, "couldn't install new keys for " "command channel %s: %s", socktext, isc_result_totext(result)); } /* * Now, keep the old access list unless a new one can be made. */ if (control != NULL && type == isc_sockettype_tcp) { allow = cfg_tuple_get(control, "allow"); result = cfg_acl_fromconfig(allow, config, ns_g_lctx, aclconfctx, listener->mctx, &new_acl); } else { result = dns_acl_any(listener->mctx, &new_acl); } if (result == ISC_R_SUCCESS) { dns_acl_detach(&listener->acl); dns_acl_attach(new_acl, &listener->acl); dns_acl_detach(&new_acl); /* XXXDCL say the old acl is still used? */ } else if (control != NULL) cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, "couldn't install new acl for " "command channel %s: %s", socktext, isc_result_totext(result)); else isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, "couldn't install new acl for " "command channel %s: %s", socktext, isc_result_totext(result)); if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) { isc_uint32_t perm, owner, group; perm = cfg_obj_asuint32(cfg_tuple_get(control, "perm")); owner = cfg_obj_asuint32(cfg_tuple_get(control, "owner")); group = cfg_obj_asuint32(cfg_tuple_get(control, "group")); result = ISC_R_SUCCESS; if (listener->perm != perm || listener->owner != owner || listener->group != group) result = isc_socket_permunix(&listener->address, perm, owner, group); if (result == ISC_R_SUCCESS) { listener->perm = perm; listener->owner = owner; listener->group = group; } else if (control != NULL) cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, "couldn't update ownership/permission for " "command channel %s", socktext); } *listenerp = listener;}static voidadd_listener(ns_controls_t *cp, controllistener_t **listenerp, const cfg_obj_t *control, const cfg_obj_t *config, isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx, const char *socktext, isc_sockettype_t type){ isc_mem_t *mctx = cp->server->mctx; controllistener_t *listener; const cfg_obj_t *allow; const cfg_obj_t *global_keylist = NULL; const cfg_obj_t *control_keylist = NULL; dns_acl_t *new_acl = NULL; isc_result_t result = ISC_R_SUCCESS; listener = isc_mem_get(mctx, sizeof(*listener)); if (listener == NULL) result = ISC_R_NOMEMORY; if (result == ISC_R_SUCCESS) { listener->controls = cp; listener->mctx = mctx; listener->task = cp->server->task; listener->address = *addr; listener->sock = NULL; listener->listening = ISC_FALSE; listener->exiting = ISC_FALSE; listener->acl = NULL; listener->type = type; listener->perm = 0; listener->owner = 0; listener->group = 0; ISC_LINK_INIT(listener, link); ISC_LIST_INIT(listener->keys); ISC_LIST_INIT(listener->connections); /* * Make the acl. */ if (control != NULL && type == isc_sockettype_tcp) { allow = cfg_tuple_get(control, "allow"); result = cfg_acl_fromconfig(allow, config, ns_g_lctx, aclconfctx, mctx, &new_acl); } else { result = dns_acl_any(mctx, &new_acl); } } if (result == ISC_R_SUCCESS) { dns_acl_attach(new_acl, &listener->acl); dns_acl_detach(&new_acl); if (config != NULL) get_key_info(config, control, &global_keylist, &control_keylist); if (control_keylist != NULL) { result = controlkeylist_fromcfg(control_keylist, listener->mctx, &listener->keys); if (result == ISC_R_SUCCESS) register_keys(control, global_keylist, &listener->keys, listener->mctx, socktext); } else result = get_rndckey(mctx, &listener->keys); if (result != ISC_R_SUCCESS && control != NULL) cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, "couldn't install keys for " "command channel %s: %s", socktext, isc_result_totext(result)); } if (result == ISC_R_SUCCESS) { int pf = isc_sockaddr_pf(&listener->address); if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) ||#ifdef ISC_PLATFORM_HAVESYSUNH (pf == AF_UNIX && isc_net_probeunix() != ISC_R_SUCCESS) ||#endif (pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS)) result = ISC_R_FAMILYNOSUPPORT; } if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) isc_socket_cleanunix(&listener->address, ISC_FALSE); if (result == ISC_R_SUCCESS) result = isc_socket_create(ns_g_socketmgr, isc_sockaddr_pf(&listener->address), type, &listener->sock); if (result == ISC_R_SUCCESS) result = isc_socket_bind(listener->sock, &listener->address); if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) { listener->perm = cfg_obj_asuint32(cfg_tuple_get(control, "perm")); listener->owner = cfg_obj_asuint32(cfg_tuple_get(control, "owner")); listener->group = cfg_obj_asuint32(cfg_tuple_get(control, "group")); result = isc_socket_permunix(&listener->address, listener->perm, listener->owner, listener->group); } if (result == ISC_R_SUCCESS) result = control_listen(listener); if (result == ISC_R_SUCCESS) result = control_accept(listener); if (result == ISC_R_SUCCESS) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, "command channel listening on %s", socktext); *listenerp = listener; } else { if (listener != NULL) { listener->exiting = ISC_TRUE; free_listener(listener); } if (control != NULL) cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, "couldn't add command channel %s: %s", socktext, isc_result_totext(result)); else isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, "couldn't add command channel %s: %s", socktext, isc_result_totext(result)); *listenerp = NULL; } /* XXXDCL return error results? fail hard? */}isc_result_tns_controls_configure(ns_controls_t *cp, const cfg_obj_t *config, cfg_aclconfctx_t *aclconfctx){ controllistener_t *listener; controllistenerlist_t new_listeners; const cfg_obj_t *controlslist = NULL; const cfg_listelt_t *element, *element2; char socktext[ISC_SOCKADDR_FORMATSIZE]; ISC_LIST_INIT(new_listeners); /* * Get the list of named.conf 'controls' statements. */ (void)cfg_map_get(config, "controls", &controlslist); /* * Run through the new control channel list, noting sockets that * are already being listened on and moving them to the new list. * * Identifying duplicate addr/port combinations is left to either * the underlying config code, or to the bind attempt getting an * address-in-use error. */ if (controlslist != NULL) { for (element = cfg_list_first(controlslist); element != NULL; element = cfg_list_next(element)) { const cfg_obj_t *controls; const cfg_obj_t *inetcontrols = NULL; controls = cfg_listelt_value(element); (void)cfg_map_get(controls, "inet", &inetcontrols); if (inetcontrols == NULL) continue; for (element2 = cfg_list_first(inetcontrols); element2 != NULL; element2 = cfg_list_next(element2)) { const cfg_obj_t *control; const cfg_obj_t *obj; isc_sockaddr_t addr; /* * The parser handles BIND 8 configuration file * syntax, so it allows unix phrases as well * inet phrases with no keys{} clause. */ control = cfg_listelt_value(element2); obj = cfg_tuple_get(control, "address"); addr = *cfg_obj_assockaddr(obj); if (isc_sockaddr_getport(&addr) == 0) isc_sockaddr_setport(&addr, NS_CONTROL_PORT); isc_sockaddr_format(&addr, socktext, sizeof(socktext)); isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_CONTROL, ISC_LOG_DEBUG(9), "processing control channel %s", socktext); update_listener(cp, &listener, control, config, &addr, aclconfctx, socktext, isc_sockettype_tcp); if (listener != NULL) /* * Remove the listener from the old * list, so it won't be shut down. */ ISC_LIST_UNLINK(cp->listeners, listener, link); else /* * This is a new listener. */ add_listener(cp, &listener, control, config, &addr, aclconfctx, socktext, isc_sockettype_tcp); if (listener != NULL) ISC_LIST_APPEND(new_listeners, listener, link); } } for (element = cfg_list_first(controlslist); element != NULL; element = cfg_list_next(element)) { const cfg_obj_t *controls; const cfg_obj_t *unixcontrols = NULL; controls = cfg_listelt_value(element); (void)cfg_map_get(controls, "unix", &unixcontrols); if (unixcontrols == NULL) continue; for (element2 = cfg_list_first(unixcontrols); element2 != NULL; element2 = cfg_list_next(element2)) { const cfg_obj_t *control; const cfg_obj_t *path; isc_sockaddr_t addr; isc_result_t result; /* * The parser handles BIND 8 configuration file * syntax, so it allows unix phrases as well * inet phrases with no keys{} clause. */ control = cfg_listelt_value(element2); path = cfg_tuple_get(control, "path"); result = isc_sockaddr_frompath(&addr, cfg_obj_asstring(path)); if (result != ISC_R_SUCCESS) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_CONTROL, ISC_LOG_DEBUG(9), "control channel '%s': %s", cfg_obj_asstring(path), isc_result_totext(result)); continue; } isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_CONTROL, ISC_LOG_DEBUG(9), "processing control channel '%s'", cfg_obj_asstring(path)); update_listener(cp, &listener, control, config, &addr, aclconfctx, cfg_obj_asstring(path), isc_sockettype_unix); if (listener != NULL) /* * Remove the listener from the old * list, so it won't be shut down. */ ISC_LIST_UNLINK(cp->listeners, listener, link); else /* * This is a new listener. */ add_listener(cp, &listener, control, config, &addr, aclconfctx, cfg_obj_asstring(path), isc_sockettype_unix); if (listener != NULL) ISC_LIST_APPEND(new_listeners, listener, link); } } } else { int i; for (i = 0; i < 2; i++) { isc_sockaddr_t addr; if (i == 0) { struct in_addr localhost; if (isc_net_probeipv4() != ISC_R_SUCCESS) continue; localhost.s_addr = htonl(INADDR_LOOPBACK); isc_sockaddr_fromin(&addr, &localhost, 0); } else { if (isc_net_probeipv6() != ISC_R_SUCCESS) continue; isc_sockaddr_fromin6(&addr, &in6addr_loopback, 0); } isc_sockaddr_setport(&addr, NS_CONTROL_PORT); isc_sockaddr_format(&addr, socktext, sizeof(socktext)); update_listener(cp, &listener, NULL, NULL, &addr, NULL, socktext, isc_sockettype_tcp); if (listener != NULL) /* * Remove the listener from the old * list, so it won't be shut down. */ ISC_LIST_UNLINK(cp->listeners, listener, link); else /* * This is a new listener. */ add_listener(cp, &listener, NULL, NULL, &addr, NULL, socktext, isc_sockettype_tcp); if (listener != NULL) ISC_LIST_APPEND(new_listeners, listener, link); } } /* * ns_control_shutdown() will stop whatever is on the global * listeners list, which currently only has whatever sockaddrs * were in the previous configuration (if any) that do not * remain in the current configuration. */ controls_shutdown(cp); /* * Put all of the valid listeners on the listeners list. * Anything already on listeners in the process of shutting * down will be taken care of by listen_done(). */ ISC_LIST_APPENDLIST(cp->listeners, new_listeners, link); return (ISC_R_SUCCESS);}isc_result_tns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp) { isc_mem_t *mctx = server->mctx; isc_result_t result; ns_controls_t *controls = isc_mem_get(mctx, sizeof(*controls)); if (controls == NULL) return (ISC_R_NOMEMORY); controls->server = server; ISC_LIST_INIT(controls->listeners); controls->shuttingdown = ISC_FALSE; controls->symtab = NULL; result = isccc_cc_createsymtab(&controls->symtab); if (result != ISC_R_SUCCESS) { isc_mem_put(server->mctx, controls, sizeof(*controls)); return (result); } *ctrlsp = controls; return (ISC_R_SUCCESS);}voidns_controls_destroy(ns_controls_t **ctrlsp) { ns_controls_t *controls = *ctrlsp; REQUIRE(ISC_LIST_EMPTY(controls->listeners)); isccc_symtab_destroy(&controls->symtab); isc_mem_put(controls->server->mctx, controls, sizeof(*controls)); *ctrlsp = NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -