Commit c3703059 authored by Evan Hunt's avatar Evan Hunt
Browse files

[master] 4754. [bug] dns_zone_setview needs a two stage commit to properly

                        handle errors. [RT #45841]
parent abaa9755
4754. [bug] dns_zone_setview needs a two stage commit to properly
handle errors. [RT #45841]
4753. [contrib] Software obtainable from known upstream locations
(i.e., zkt, nslint, query-loc) has been removed.
Links to these and other packages can be found at
......
......@@ -7112,6 +7112,59 @@ setup_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
return (result);
}
static void
configure_zone_setviewcommit(isc_result_t result, const cfg_obj_t *zconfig,
dns_view_t *view)
{
const char *zname;
dns_fixedname_t fixorigin;
dns_name_t *origin;
isc_result_t result2;
dns_view_t *pview = NULL;
dns_zone_t *zone = NULL;
dns_zone_t *raw = NULL;
zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
dns_fixedname_init(&fixorigin);
origin = dns_fixedname_name(&fixorigin);
result2 = dns_name_fromstring(origin, zname, 0, NULL);
if (result2 != ISC_R_SUCCESS) {
return;
}
result2 = dns_viewlist_find(&named_g_server->viewlist, view->name,
view->rdclass, &pview);
if (result2 != ISC_R_SUCCESS) {
return;
}
result2 = dns_view_findzone(pview, origin, &zone);
if (result2 != ISC_R_SUCCESS) {
dns_view_detach(&pview);
return;
}
dns_zone_getraw(zone, &raw);
if (result == ISC_R_SUCCESS) {
dns_zone_setviewcommit(zone);
if (raw != NULL)
dns_zone_setviewcommit(raw);
} else {
dns_zone_setviewrevert(zone);
if (raw != NULL)
dns_zone_setviewrevert(raw);
}
if (raw != NULL) {
dns_zone_detach(&raw);
}
dns_zone_detach(&zone);
dns_view_detach(&pview);
}
#ifndef HAVE_LMDB
static isc_result_t
......@@ -7124,8 +7177,9 @@ configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
const cfg_listelt_t *element;
nzctx = view->new_zone_config;
if (nzctx == NULL || nzctx->nzf_config == NULL)
if (nzctx == NULL || nzctx->nzf_config == NULL) {
return (ISC_R_SUCCESS);
}
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
......@@ -7148,6 +7202,14 @@ configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
result = ISC_R_SUCCESS;
cleanup:
for (element = cfg_list_first(zonelist);
element != NULL;
element = cfg_list_next(element))
{
const cfg_obj_t *zconfig = cfg_listelt_value(element);
configure_zone_setviewcommit(result, zconfig, view);
}
return (result);
}
......@@ -7189,8 +7251,9 @@ data_to_cfg(dns_view_t *view, MDB_val *key, MDB_val *data,
/* zone zonename { config; }; */
result = isc_buffer_reserve(text, 5 + zone_name_len + 1 +
zone_config_len + 2);
if (result != ISC_R_SUCCESS)
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
putstr(text, "zone ");
putmem(text, (const void *) zone_name, zone_name_len);
......@@ -7216,8 +7279,9 @@ data_to_cfg(dns_view_t *view, MDB_val *key, MDB_val *data,
result = ISC_R_SUCCESS;
cleanup:
if (zoneconf != NULL)
if (zoneconf != NULL) {
cfg_obj_destroy(named_g_addparser, &zoneconf);
}
return (result);
}
......@@ -7235,13 +7299,13 @@ configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
MDB_dbi dbi;
MDB_val key, data;
if (view->new_zone_config == NULL)
if (view->new_zone_config == NULL) {
return (ISC_R_SUCCESS);
}
result = nzd_open(view, MDB_RDONLY, &txn, &dbi);
if (result != ISC_R_SUCCESS) {
result = ISC_R_SUCCESS;
goto cleanup;
return (ISC_R_SUCCESS);
}
isc_log_write(named_g_lctx,
......@@ -7261,12 +7325,14 @@ configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
const cfg_obj_t *zoneobj = NULL;
result = data_to_cfg(view, &key, &data, &text, &zoneconf);
if (result != ISC_R_SUCCESS)
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
CHECK(cfg_map_get(zoneconf, "zone", &zlist));
if (!cfg_obj_islist(zlist))
if (!cfg_obj_islist(zlist)) {
CHECK(ISC_R_FAILURE);
}
zoneobj = cfg_listelt_value(cfg_list_first(zlist));
CHECK(configure_zone(config, zoneobj, vconfig, mctx,
......@@ -7279,14 +7345,52 @@ configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
result = ISC_R_SUCCESS;
cleanup:
if (cursor != NULL)
mdb_cursor_close(cursor);
(void) nzd_close(&txn, ISC_FALSE);
if (zoneconf != NULL)
if (zoneconf != NULL) {
cfg_obj_destroy(named_g_addparser, &zoneconf);
if (text != NULL)
isc_buffer_free(&text);
}
if (cursor != NULL) {
mdb_cursor_close(cursor);
cursor = NULL;
}
if (result != ISC_R_SUCCESS) {
status = mdb_cursor_open(txn, dbi, &cursor);
if (status != 0) {
goto cleanup2;
}
while (mdb_cursor_get(cursor, &key, &data, MDB_NEXT) == 0) {
const cfg_obj_t *zlist = NULL;
const cfg_obj_t *zconfig = NULL;
isc_result_t result2;
result2 = data_to_cfg(view, &key, &data, &text,
&zoneconf);
if (result2 != ISC_R_SUCCESS) {
goto cleanup2;
}
result2 = cfg_map_get(zoneconf, "zone", &zlist);
if (result2 != ISC_R_SUCCESS) {
goto cleanup2;
}
zconfig = cfg_listelt_value(cfg_list_first(zlist));
configure_zone_setviewcommit(result, zconfig, view);
cfg_obj_destroy(named_g_addparser, &zoneconf);
}
}
cleanup2:
if (text != NULL) {
isc_buffer_free(&text);
}
if (zoneconf != NULL) {
cfg_obj_destroy(named_g_addparser, &zoneconf);
}
if (cursor != NULL) {
mdb_cursor_close(cursor);
}
(void) nzd_close(&txn, ISC_FALSE);
return (result);
}
......@@ -7495,8 +7599,9 @@ load_configuration(const char *filename, named_server_t *server,
ISC_LIST_INIT(altsecrets);
/* Create the ACL configuration context */
if (named_g_aclconfctx != NULL)
if (named_g_aclconfctx != NULL) {
cfg_aclconfctx_detach(&named_g_aclconfctx);
}
CHECK(cfg_aclconfctx_create(named_g_mctx, &named_g_aclconfctx));
/*
......@@ -7510,10 +7615,11 @@ load_configuration(const char *filename, named_server_t *server,
if (first_time) {
result = named_config_parsedefaults(named_g_parser,
&named_g_config);
if (result != ISC_R_SUCCESS)
if (result != ISC_R_SUCCESS) {
named_main_earlyfatal("unable to load "
"internal defaults: %s",
isc_result_totext(result));
}
RUNTIME_CHECK(cfg_map_get(named_g_config, "options",
&named_g_defaults) == ISC_R_SUCCESS);
}
......@@ -7545,8 +7651,9 @@ load_configuration(const char *filename, named_server_t *server,
i = 0;
options = NULL;
result = cfg_map_get(config, "options", &options);
if (result == ISC_R_SUCCESS)
if (result == ISC_R_SUCCESS) {
maps[i++] = options;
}
maps[i++] = named_g_defaults;
maps[i] = NULL;
......@@ -7604,8 +7711,9 @@ load_configuration(const char *filename, named_server_t *server,
* server.
*/
result = isc_socketmgr_getmaxsockets(named_g_socketmgr, &maxsocks);
if (result != ISC_R_SUCCESS)
if (result != ISC_R_SUCCESS) {
maxsocks = 0;
}
result = isc_resource_getcurlimit(isc_resource_openfiles, &nfiles);
if (result == ISC_R_SUCCESS && (isc_resourcevalue_t)maxsocks > nfiles) {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
......@@ -7623,14 +7731,16 @@ load_configuration(const char *filename, named_server_t *server,
INSIST(result == ISC_R_SUCCESS);
reserved = cfg_obj_asuint32(obj);
if (maxsocks != 0) {
if (maxsocks < 128U) /* Prevent underflow. */
if (maxsocks < 128U) { /* Prevent underflow. */
reserved = 0;
else if (reserved > maxsocks - 128U) /* Minimum UDP space. */
} else if (reserved > maxsocks - 128U) { /* Minimum UDP space. */
reserved = maxsocks - 128;
}
}
/* Minimum TCP/stdio space. */
if (reserved < 128U)
if (reserved < 128U) {
reserved = 128;
}
if (reserved + 128U > maxsocks && maxsocks != 0) {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
......@@ -7652,8 +7762,9 @@ load_configuration(const char *filename, named_server_t *server,
char *dir;
DE_CONST(cfg_obj_asstring(obj), dir);
named_geoip_load(dir);
} else
} else {
named_geoip_load(NULL);
}
named_g_aclconfctx->geoip = named_g_geoip;
obj = NULL;
......@@ -7683,17 +7794,19 @@ load_configuration(const char *filename, named_server_t *server,
CHECK(ISC_R_RANGE);
}
softquota = server->sctx->recursionquota.max - margin;
} else
} else {
softquota = (server->sctx->recursionquota.max * 90) / 100;
}
isc_quota_soft(&server->sctx->recursionquota, softquota);
CHECK(configure_view_acl(NULL, config, "blackhole", NULL,
named_g_aclconfctx, named_g_mctx,
&server->sctx->blackholeacl));
if (server->sctx->blackholeacl != NULL)
if (server->sctx->blackholeacl != NULL) {
dns_dispatchmgr_setblackhole(named_g_dispatchmgr,
server->sctx->blackholeacl);
}
CHECK(configure_view_acl(NULL, config, "keep-response-order", NULL,
named_g_aclconfctx, named_g_mctx,
......@@ -7784,15 +7897,15 @@ load_configuration(const char *filename, named_server_t *server,
avoidv6ports = NULL;
(void)named_config_get(maps, "use-v4-udp-ports", &usev4ports);
if (usev4ports != NULL)
if (usev4ports != NULL) {
portset_fromconf(v4portset, usev4ports, ISC_TRUE);
else {
} else {
CHECKM(isc_net_getudpportrange(AF_INET, &udpport_low,
&udpport_high),
"get the default UDP/IPv4 port range");
if (udpport_low == udpport_high)
if (udpport_low == udpport_high) {
isc_portset_add(v4portset, udpport_low);
else {
} else {
isc_portset_addrange(v4portset, udpport_low,
udpport_high);
}
......@@ -7804,19 +7917,20 @@ load_configuration(const char *filename, named_server_t *server,
}
}
(void)named_config_get(maps, "avoid-v4-udp-ports", &avoidv4ports);
if (avoidv4ports != NULL)
if (avoidv4ports != NULL) {
portset_fromconf(v4portset, avoidv4ports, ISC_FALSE);
}
(void)named_config_get(maps, "use-v6-udp-ports", &usev6ports);
if (usev6ports != NULL)
if (usev6ports != NULL) {
portset_fromconf(v6portset, usev6ports, ISC_TRUE);
else {
} else {
CHECKM(isc_net_getudpportrange(AF_INET6, &udpport_low,
&udpport_high),
"get the default UDP/IPv6 port range");
if (udpport_low == udpport_high)
if (udpport_low == udpport_high) {
isc_portset_add(v6portset, udpport_low);
else {
} else {
isc_portset_addrange(v6portset, udpport_low,
udpport_high);
}
......@@ -7828,8 +7942,9 @@ load_configuration(const char *filename, named_server_t *server,
}
}
(void)named_config_get(maps, "avoid-v6-udp-ports", &avoidv6ports);
if (avoidv6ports != NULL)
if (avoidv6ports != NULL) {
portset_fromconf(v6portset, avoidv6ports, ISC_FALSE);
}
dns_dispatchmgr_setavailports(named_g_dispatchmgr, v4portset,
v6portset);
......@@ -7841,10 +7956,12 @@ load_configuration(const char *filename, named_server_t *server,
result = named_config_get(maps, "edns-udp-size", &obj);
INSIST(result == ISC_R_SUCCESS);
udpsize = cfg_obj_asuint32(obj);
if (udpsize < 512)
if (udpsize < 512) {
udpsize = 512;
if (udpsize > 4096)
}
if (udpsize > 4096) {
udpsize = 4096;
}
server->sctx->udpsize = (isc_uint16_t)udpsize;
/* Set the transfer message size for TCP */
......@@ -7852,10 +7969,11 @@ load_configuration(const char *filename, named_server_t *server,
result = named_config_get(maps, "transfer-message-size", &obj);
INSIST(result == ISC_R_SUCCESS);
transfer_message_size = cfg_obj_asuint32(obj);
if (transfer_message_size < 512)
if (transfer_message_size < 512) {
transfer_message_size = 512;
else if (transfer_message_size > 65535)
} else if (transfer_message_size > 65535) {
transfer_message_size = 65535;
}
server->sctx->transfer_tcp_message_size =
(isc_uint16_t) transfer_message_size;
......@@ -7891,10 +8009,11 @@ load_configuration(const char *filename, named_server_t *server,
/*
* Determine which port to use for listening for incoming connections.
*/
if (named_g_port != 0)
if (named_g_port != 0) {
listen_port = named_g_port;
else
} else {
CHECKM(named_config_getport(config, &listen_port), "port");
}
/*
* Determing the default DSCP code point.
......@@ -7908,8 +8027,9 @@ load_configuration(const char *filename, named_server_t *server,
result = named_config_get(maps, "tcp-listen-queue", &obj);
INSIST(result == ISC_R_SUCCESS);
backlog = cfg_obj_asuint32(obj);
if ((backlog > 0) && (backlog < 10))
if ((backlog > 0) && (backlog < 10)) {
backlog = 10;
}
ns_interfacemgr_setbacklog(server->interfacemgr, backlog);
/*
......@@ -7925,8 +8045,9 @@ load_configuration(const char *filename, named_server_t *server,
* Even though listen-on is present in the default
* configuration, this way is easier.
*/
if (options != NULL)
if (options != NULL) {
(void)cfg_map_get(options, "listen-on", &clistenon);
}
if (clistenon != NULL) {
/* check return code? */
(void)ns_listenlist_fromconfig(clistenon, config,
......@@ -7953,8 +8074,9 @@ load_configuration(const char *filename, named_server_t *server,
const cfg_obj_t *clistenon = NULL;
ns_listenlist_t *listenon = NULL;
if (options != NULL)
if (options != NULL) {
(void)cfg_map_get(options, "listen-on-v6", &clistenon);
}
if (clistenon != NULL) {
/* check return code? */
(void)ns_listenlist_fromconfig(clistenon, config,
......@@ -8056,11 +8178,12 @@ load_configuration(const char *filename, named_server_t *server,
*/
obj = NULL;
if (named_config_get(maps, "pid-file", &obj) == ISC_R_SUCCESS) {
if (cfg_obj_isvoid(obj))
if (cfg_obj_isvoid(obj)) {
named_os_writepidfile(NULL, first_time);
else
} else {
named_os_writepidfile(cfg_obj_asstring(obj),
first_time);
}
} else {
named_os_writepidfile(named_g_defaultpidfile, first_time);
}
......@@ -8200,6 +8323,17 @@ load_configuration(const char *filename, named_server_t *server,
/* Now combine the two viewlists into one */
ISC_LIST_APPENDLIST(viewlist, builtin_viewlist, link);
/*
* Commit any dns_zone_setview() calls on all zones in the new
* view.
*/
for (view = ISC_LIST_HEAD(viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link))
{
dns_view_setviewcommit(view);
}
/* Swap our new view list with the production one. */
tmpviewlist = server->viewlist;
server->viewlist = viewlist;
......@@ -8223,8 +8357,9 @@ load_configuration(const char *filename, named_server_t *server,
CHECKM(named_tkeyctx_fromconfig(options, named_g_mctx,
named_g_entropy, &t),
"configuring TKEY");
if (server->sctx->tkeyctx != NULL)
if (server->sctx->tkeyctx != NULL) {
dns_tkeyctx_destroy(&server->sctx->tkeyctx);
}
server->sctx->tkeyctx = t;
}
......@@ -8321,8 +8456,9 @@ load_configuration(const char *filename, named_server_t *server,
/*
* Relinquish root privileges.
*/
if (first_time)
if (first_time) {
named_os_changeuser();
}
/*
* Check that the working directory is writable.
......@@ -8452,18 +8588,22 @@ load_configuration(const char *filename, named_server_t *server,
obj = NULL;
if (options != NULL &&
cfg_map_get(options, "memstatistics", &obj) == ISC_R_SUCCESS)
{
named_g_memstatistics = cfg_obj_asboolean(obj);
else
} else {
named_g_memstatistics =
ISC_TF((isc_mem_debugging & ISC_MEM_DEBUGRECORD) != 0);
}
obj = NULL;
if (named_config_get(maps, "memstatistics-file", &obj) == ISC_R_SUCCESS)
{
named_main_setmemstats(cfg_obj_asstring(obj));
else if (named_g_memstatistics)
} else if (named_g_memstatistics) {
named_main_setmemstats("named.memstats");
else
} else {
named_main_setmemstats(NULL);
}
obj = NULL;
result = named_config_get(maps, "statistics-file", &obj);
......@@ -8534,18 +8674,19 @@ load_configuration(const char *filename, named_server_t *server,
obj = NULL;
result = named_config_get(maps, "cookie-algorithm", &obj);
INSIST(result == ISC_R_SUCCESS);
if (strcasecmp(cfg_obj_asstring(obj), "aes") == 0)
if (strcasecmp(cfg_obj_asstring(obj), "aes") == 0) {
#if defined(HAVE_OPENSSL_AES) || defined(HAVE_OPENSSL_EVP_AES)
server->sctx->cookiealg = ns_cookiealg_aes;
#else
INSIST(0);
#endif
else if (strcasecmp(cfg_obj_asstring(obj), "sha1") == 0)
} else if (strcasecmp(cfg_obj_asstring(obj), "sha1") == 0) {
server->sctx->cookiealg = ns_cookiealg_sha1;
else if (strcasecmp(cfg_obj_asstring(obj), "sha256") == 0)
} else if (strcasecmp(cfg_obj_asstring(obj), "sha256") == 0) {
server->sctx->cookiealg = ns_cookiealg_sha256;
else
} else {
INSIST(0);
}
obj = NULL;
result = named_config_get(maps, "cookie-secret", &obj);
......@@ -8570,7 +8711,9 @@ load_configuration(const char *filename, named_server_t *server,
result = isc_hex_decodestring(str, &b);
if (result != ISC_R_SUCCESS &&
result != ISC_R_NOSPACE)
{
goto cleanup;
}
first = ISC_FALSE;
} else {
altsecret = isc_mem_get(server->sctx->mctx,
......@@ -8583,7 +8726,8 @@ load_configuration(const char *filename, named_server_t *server,
sizeof(altsecret->secret));
result = isc_hex_decodestring(str, &b);
if (result != ISC_R_SUCCESS &&
result != ISC_R_NOSPACE) {
result != ISC_R_NOSPACE)
{
isc_mem_put(server->sctx->mctx,
altsecret,
sizeof(*altsecret));
......@@ -8624,8 +8768,9 @@ load_configuration(const char *filename, named_server_t *server,
sizeof(server->sctx->secret),
NULL,
0);
if (result != ISC_R_SUCCESS)
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
}
/*
......@@ -8656,29 +8801,35 @@ load_configuration(const char *filename, named_server_t *server,
result = ISC_R_SUCCESS;
cleanup:
if (logc != NULL)
if (logc != NULL) {
isc_logconfig_destroy(&logc);
}
if (v4portset != NULL)
if (v4portset != NULL) {
isc_portset_destroy(named_g_mctx, &v4portset);
}
if (v6portset != NULL)
if (v6portset != NULL) {
isc_portset_destroy(named_g_mctx, &v6portset);
}
if (conf_parser != NULL) {
if (config != NULL)
if (config != NULL) {
cfg_obj_destroy(conf_parser, &config);
}
cfg_parser_destroy(&conf_parser);
}
if (bindkeys_parser != NULL) {
if (bindkeys != NULL)
if (bindkeys != NULL) {
cfg_obj_destroy(bindkeys_parser, &bindkeys);
}
cfg_parser_destroy(&bindkeys_parser);
}
if (view != NULL)
if (view != NULL) {
dns_view_detach(&view);
}
ISC_LIST_APPENDLIST(viewlist, builtin_viewlist, link);
......@@ -8694,8 +8845,11 @@ load_configuration(const char *filename, named_server_t *server,
ISC_LIST_UNLINK(viewlist, view, link);
if (result == ISC_R_SUCCESS &&
strcmp(view->name, "_bind") != 0)
{
dns_view_setviewrevert(view);
(void)dns_zt_apply(view->zonetable, ISC_FALSE,
removed, view);
}
dns_view_detach(&view);
}
......@@ -8716,20 +8870,23 @@ load_configuration(const char *filename, named_server_t *server,
* Adjust the listening interfaces in accordance with the source
* addresses specified in views and zones.
*/
if (isc_net_probeipv6() == ISC_R_SUCCESS)
if (isc_net_probeipv6() == ISC_R_SUCCESS) {
adjust_interfaces(server, named_g_mctx);
}
/*
* Record the time of most recent configuration
*/
tresult = isc_time_now(&named_g_configtime);
if (tresult != ISC_R_SUCCESS)
if (tresult != ISC_R_SUCCESS) {
named_main_earlyfatal("isc_time_now() failed: %s",
isc_result_totext(result));
}
/* Relinquish exclusive access to configuration data. */
if (exclusive)
if (exclusive) {
isc_task_endexclusive(server->task);
}
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_DEBUG(1),
......
......@@ -476,7 +476,7 @@ dlopen_dlz_configure(dns_view_t *view, dns_dlzdb_t *dlzdb,
/*
* Check for authority to change a name
* Check for authority to change a name.
*/
static isc_boolean_t
dlopen_dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr,
......@@ -501,7 +501,7 @@ dlopen_dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr,
/*
* Add an rdataset
* Add an rdataset.
*/
static isc_result_t
dlopen_dlz_addrdataset(const char *name, const char *rdatastr,
......@@ -523,7 +523,7 @@ dlopen_dlz_addrdataset(const char *name, const char *rdatastr,
}
/*
* Subtract an rdataset
* Subtract an rdataset.
*/
static isc_result_t
dlopen_dlz_subrdataset(const char *name, const char *rdatastr,
......@@ -545,7 +545,7 @@ dlopen_dlz_subrdataset(const char *name, const char *rdatastr,
}