static isc_result_t find_listener(isc_sockaddr_t *address, ns_lwreslistener_t **listenerp) { ns_lwreslistener_t *listener; INSIST(listenerp != NULL && *listenerp == NULL); for (listener = ISC_LIST_HEAD(listeners); listener != NULL; listener = ISC_LIST_NEXT(listener, link)) { if (!isc_sockaddr_equal(address, &listener->address)) continue; *listenerp = listener; return (ISC_R_SUCCESS); } return (ISC_R_NOTFOUND); }
static void setup_listenon(ns_interfacemgr_t *mgr, isc_interface_t *interface, in_port_t port) { isc_sockaddr_t *addr; isc_sockaddr_t *old; addr = isc_mem_get(mgr->mctx, sizeof(*addr)); if (addr == NULL) return; isc_sockaddr_fromnetaddr(addr, &interface->address, port); for (old = ISC_LIST_HEAD(mgr->listenon); old != NULL; old = ISC_LIST_NEXT(old, link)) if (isc_sockaddr_equal(addr, old)) break; if (old != NULL) isc_mem_put(mgr->mctx, addr, sizeof(*addr)); else ISC_LIST_APPEND(mgr->listenon, addr, link); }
static void update_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) { 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; controlkeylist_t keys; isc_result_t result = ISC_R_SUCCESS; for (listener = ISC_LIST_HEAD(cp->listeners); listener != NULL; listener = ISC_LIST_NEXT(listener, link)) if (isc_sockaddr_equal(addr, &listener->address)) break; if (listener == NULL) { *listenerp = NULL; return; } /* * There is already a listener for this sockaddr. * Update the access list and key information. * * First try to deal with the key situation. There are a few * possibilities: * (a) It had an explicit keylist and still has an explicit keylist. * (b) It had an automagic key and now has an explicit keylist. * (c) It had an explicit keylist and now needs an automagic key. * (d) It has an automagic key and still needs the automagic key. * * (c) and (d) are the annoying ones. The caller needs to know * that it should use the automagic configuration for key information * in place of the named.conf configuration. * * XXXDCL There is one other hazard that has not been dealt with, * the problem that if a key change is being caused by a control * channel reload, then the response will be with the new key * and not able to be decrypted by the client. */ if (control != NULL) get_key_info(config, control, &global_keylist, &control_keylist); if (control_keylist != NULL) { INSIST(global_keylist != NULL); ISC_LIST_INIT(keys); 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, 0, &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; }