~andreserl/ubuntu/lucid/bind9/bind9-apport-533601

« back to all changes in this revision

Viewing changes to bin/named/server.c

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2009-01-26 10:33:42 UTC
  • mfrom: (1.4.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090126103342-zfv3z8v6jgci62tg
* New upstream patch release
  - supportable version of fix from 9.5.0.dfsg.P2-5.1
  - CVE-2009-0025:  Closes: #511936
  - 2475: Overly agressive cache entry removal.  Closes: #511768
  - other bug fixes worthy of patch-release inclusion

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 * PERFORMANCE OF THIS SOFTWARE.
16
16
 */
17
17
 
18
 
/* $Id: server.c,v 1.495.10.11.2.2 2008/07/23 23:48:45 tbox Exp $ */
 
18
/* $Id: server.c,v 1.495.10.21 2008/10/28 05:23:31 marka Exp $ */
19
19
 
20
20
/*! \file */
21
21
 
33
33
#include <isc/httpd.h>
34
34
#include <isc/lex.h>
35
35
#include <isc/parseint.h>
 
36
#include <isc/portset.h>
36
37
#include <isc/print.h>
37
38
#include <isc/resource.h>
 
39
#include <isc/socket.h>
38
40
#include <isc/stdio.h>
39
41
#include <isc/string.h>
40
42
#include <isc/task.h>
222
224
        { NULL, ISC_FALSE }
223
225
};
224
226
 
225
 
/*%
226
 
 * The default max-cache-size
227
 
 */
228
 
#define NS_MAXCACHESIZE_DEFAULT 33554432 /*%< Bytes.  33554432 = 32MB */
229
 
 
230
227
static void
231
228
fatal(const char *msg, isc_result_t result);
232
229
 
538
535
 */
539
536
static isc_result_t
540
537
get_view_querysource_dispatch(const cfg_obj_t **maps,
541
 
                              int af, dns_dispatch_t **dispatchp)
 
538
                              int af, dns_dispatch_t **dispatchp,
 
539
                              isc_boolean_t is_firstview)
542
540
{
543
541
        isc_result_t result;
544
542
        dns_dispatch_t *disp;
545
543
        isc_sockaddr_t sa;
546
544
        unsigned int attrs, attrmask;
547
545
        const cfg_obj_t *obj = NULL;
 
546
        unsigned int maxdispatchbuffers;
548
547
 
549
548
        /*
550
549
         * Make compiler happy.
596
595
                attrs |= DNS_DISPATCHATTR_IPV6;
597
596
                break;
598
597
        }
599
 
 
600
 
        if (isc_sockaddr_getport(&sa) != 0) {
 
598
        if (isc_sockaddr_getport(&sa) == 0) {
 
599
                attrs |= DNS_DISPATCHATTR_EXCLUSIVE;
 
600
                maxdispatchbuffers = 4096;
 
601
        } else {
601
602
                INSIST(obj != NULL);
602
 
                cfg_obj_log(obj, ns_g_lctx, ISC_LOG_INFO,
603
 
                            "using specific query-source port suppresses port "
604
 
                            "randomization and can be insecure.");
 
603
                if (is_firstview) {
 
604
                        cfg_obj_log(obj, ns_g_lctx, ISC_LOG_INFO,
 
605
                                    "using specific query-source port "
 
606
                                    "suppresses port randomization and can be "
 
607
                                    "insecure.");
 
608
                }
 
609
                maxdispatchbuffers = 1000;
605
610
        }
606
611
 
607
612
        attrmask = 0;
613
618
        disp = NULL;
614
619
        result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr,
615
620
                                     ns_g_taskmgr, &sa, 4096,
616
 
                                     1024, 32768, 16411, 16433,
 
621
                                     maxdispatchbuffers, 32768, 16411, 16433,
617
622
                                     attrs, attrmask, &disp);
618
623
        if (result != ISC_R_SUCCESS) {
619
624
                isc_sockaddr_t any;
1224
1229
 
1225
1230
        obj = NULL;
1226
1231
        result = ns_config_get(maps, "max-cache-size", &obj);
1227
 
        INSIST(result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND);
1228
 
        if (result == ISC_R_NOTFOUND) {
1229
 
                max_cache_size = NS_MAXCACHESIZE_DEFAULT;
1230
 
                isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
1231
 
                              NS_LOGMODULE_SERVER, ISC_LOG_INFO,
1232
 
                              "default max-cache-size (%u) applies%s%s",
1233
 
                              max_cache_size, sep, viewname);
1234
 
        } else if (cfg_obj_isstring(obj)) {
 
1232
        INSIST(result == ISC_R_SUCCESS);
 
1233
        if (cfg_obj_isstring(obj)) {
1235
1234
                str = cfg_obj_asstring(obj);
1236
 
                INSIST(strcasecmp(str, "unlimited") == 0 ||
1237
 
                       strcasecmp(str, "default") == 0);
1238
 
                if (strcasecmp(str, "unlimited") == 0)
1239
 
                        max_cache_size = ISC_UINT32_MAX;
1240
 
                else
1241
 
                        max_cache_size = NS_MAXCACHESIZE_DEFAULT;
 
1235
                INSIST(strcasecmp(str, "unlimited") == 0);
 
1236
                max_cache_size = ISC_UINT32_MAX;
1242
1237
        } else {
1243
1238
                isc_resourcevalue_t value;
1244
1239
                value = cfg_obj_asuint64(obj);
1281
1276
         *
1282
1277
         * XXXRTH  Hardwired number of tasks.
1283
1278
         */
1284
 
        CHECK(get_view_querysource_dispatch(maps, AF_INET, &dispatch4));
1285
 
        CHECK(get_view_querysource_dispatch(maps, AF_INET6, &dispatch6));
 
1279
        CHECK(get_view_querysource_dispatch(maps, AF_INET, &dispatch4,
 
1280
                                            ISC_TF(ISC_LIST_PREV(view, link)
 
1281
                                                   == NULL)));
 
1282
        CHECK(get_view_querysource_dispatch(maps, AF_INET6, &dispatch6,
 
1283
                                            ISC_TF(ISC_LIST_PREV(view, link)
 
1284
                                                   == NULL)));
1286
1285
        if (dispatch4 == NULL && dispatch6 == NULL) {
1287
1286
                UNEXPECTED_ERROR(__FILE__, __LINE__,
1288
1287
                                 "unable to obtain neither an IPv4 nor"
1290
1289
                result = ISC_R_UNEXPECTED;
1291
1290
                goto cleanup;
1292
1291
        }
1293
 
 
1294
 
        obj = NULL;
1295
 
        (void)ns_config_get(maps, "use-queryport-pool", &obj);
1296
 
        if (obj == NULL || cfg_obj_asboolean(obj)) {
1297
 
                isc_sockaddr_t sa;
1298
 
                isc_boolean_t logit4 = ISC_FALSE, logit6 = ISC_FALSE;
1299
 
 
1300
 
                resopts |= (DNS_RESOLVER_USEDISPATCHPOOL4 |
1301
 
                            DNS_RESOLVER_USEDISPATCHPOOL6);
1302
 
 
1303
 
                /* Check consistency with query-source(-v6) */
1304
 
                if (dispatch4 == NULL)
1305
 
                        resopts &= ~DNS_RESOLVER_USEDISPATCHPOOL4;
1306
 
                else {
1307
 
                        result = dns_dispatch_getlocaladdress(dispatch4, &sa);
1308
 
                        INSIST(result == ISC_R_SUCCESS);
1309
 
                        if (isc_sockaddr_getport(&sa) != 0) {
1310
 
                                logit4 = ISC_TRUE;
1311
 
                                resopts &= ~DNS_RESOLVER_USEDISPATCHPOOL4;
1312
 
                        }
1313
 
                }
1314
 
 
1315
 
                if (dispatch6 == NULL)
1316
 
                        resopts &= ~DNS_RESOLVER_USEDISPATCHPOOL6;
1317
 
                else {
1318
 
                        result = dns_dispatch_getlocaladdress(dispatch6, &sa);
1319
 
                        INSIST(result == ISC_R_SUCCESS);
1320
 
                        if (isc_sockaddr_getport(&sa) != 0) {
1321
 
                                logit6 = ISC_TRUE;
1322
 
                                resopts &= ~DNS_RESOLVER_USEDISPATCHPOOL6;
1323
 
                        }
1324
 
                }
1325
 
                if (logit4 && obj != NULL)
1326
 
                        cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
1327
 
                                    "specific query-source port "
1328
 
                                    "cannot coexist with queryport-pool. "
1329
 
                                    "(Pool disabled)");
1330
 
                if (logit6 && obj != NULL)
1331
 
                        cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
1332
 
                                    "specific query-source-v6 port "
1333
 
                                    "cannot coexist with queryport-pool. "
1334
 
                                    "(Pool disabled)");
1335
 
        }
1336
 
 
1337
1292
        CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31,
1338
1293
                                      ns_g_socketmgr, ns_g_timermgr,
1339
1294
                                      resopts, ns_g_dispatchmgr,
1340
1295
                                      dispatch4, dispatch6));
1341
1296
 
 
1297
        if (resstats == NULL) {
 
1298
                CHECK(dns_generalstats_create(mctx, &resstats,
 
1299
                                              dns_resstatscounter_max));
 
1300
        }
 
1301
        dns_view_setresstats(view, resstats);
 
1302
        if (resquerystats == NULL)
 
1303
                CHECK(dns_rdatatypestats_create(mctx, &resquerystats));
 
1304
        dns_view_setresquerystats(view, resquerystats);
 
1305
 
1342
1306
        /*
1343
1307
         * Set the ADB cache size to 1/8th of the max-cache-size.
1344
1308
         */
1646
1610
        CHECK(configure_view_sortlist(vconfig, config, actx, ns_g_mctx,
1647
1611
                                      &view->sortlist));
1648
1612
 
 
1613
        /*
 
1614
         * Configure default allow-transfer, allow-notify, allow-update
 
1615
         * and allow-update-forwarding ACLs, if set, so they can be
 
1616
         * inherited by zones.
 
1617
         */
 
1618
        if (view->notifyacl == NULL)
 
1619
                CHECK(configure_view_acl(NULL, ns_g_config,
 
1620
                                         "allow-notify", actx,
 
1621
                                         ns_g_mctx, &view->notifyacl));
 
1622
        if (view->transferacl == NULL)
 
1623
                CHECK(configure_view_acl(NULL, ns_g_config,
 
1624
                                         "allow-transfer", actx,
 
1625
                                         ns_g_mctx, &view->transferacl));
 
1626
        if (view->updateacl == NULL)
 
1627
                CHECK(configure_view_acl(NULL, ns_g_config,
 
1628
                                         "allow-update", actx,
 
1629
                                         ns_g_mctx, &view->updateacl));
 
1630
        if (view->upfwdacl == NULL)
 
1631
                CHECK(configure_view_acl(NULL, ns_g_config,
 
1632
                                         "allow-update-forwarding", actx,
 
1633
                                         ns_g_mctx, &view->upfwdacl));
 
1634
 
1649
1635
        obj = NULL;
1650
1636
        result = ns_config_get(maps, "request-ixfr", &obj);
1651
1637
        INSIST(result == ISC_R_SUCCESS);
2128
2114
        isc_result_t result;
2129
2115
        in_port_t port;
2130
2116
 
 
2117
        ISC_LIST_INIT(addresses);
 
2118
 
2131
2119
        /*
2132
2120
         * Determine which port to send forwarded requests to.
2133
2121
         */
2153
2141
        if (forwarders != NULL)
2154
2142
                faddresses = cfg_tuple_get(forwarders, "addresses");
2155
2143
 
2156
 
        ISC_LIST_INIT(addresses);
2157
 
 
2158
2144
        for (element = cfg_list_first(faddresses);
2159
2145
             element != NULL;
2160
2146
             element = cfg_list_next(element))
2831
2817
        SETLIMIT("files", openfiles, "open files");
2832
2818
}
2833
2819
 
2834
 
static isc_result_t
2835
 
portlist_fromconf(dns_portlist_t *portlist, unsigned int family,
2836
 
                  const cfg_obj_t *ports)
 
2820
static void
 
2821
portset_fromconf(isc_portset_t *portset, const cfg_obj_t *ports,
 
2822
                 isc_boolean_t positive)
2837
2823
{
2838
2824
        const cfg_listelt_t *element;
2839
 
        isc_result_t result = ISC_R_SUCCESS;
2840
2825
 
2841
2826
        for (element = cfg_list_first(ports);
2842
2827
             element != NULL;
2843
2828
             element = cfg_list_next(element)) {
2844
2829
                const cfg_obj_t *obj = cfg_listelt_value(element);
2845
 
                in_port_t port = (in_port_t)cfg_obj_asuint32(obj);
2846
 
 
2847
 
                result = dns_portlist_add(portlist, family, port);
2848
 
                if (result != ISC_R_SUCCESS)
2849
 
                        break;
 
2830
 
 
2831
                if (cfg_obj_isuint32(obj)) {
 
2832
                        in_port_t port = (in_port_t)cfg_obj_asuint32(obj);
 
2833
 
 
2834
                        if (positive)
 
2835
                                isc_portset_add(portset, port);
 
2836
                        else
 
2837
                                isc_portset_remove(portset, port);
 
2838
                } else {
 
2839
                        const cfg_obj_t *obj_loport, *obj_hiport;
 
2840
                        in_port_t loport, hiport;
 
2841
 
 
2842
                        obj_loport = cfg_tuple_get(obj, "loport");
 
2843
                        loport = (in_port_t)cfg_obj_asuint32(obj_loport);
 
2844
                        obj_hiport = cfg_tuple_get(obj, "hiport");
 
2845
                        hiport = (in_port_t)cfg_obj_asuint32(obj_hiport);
 
2846
 
 
2847
                        if (positive)
 
2848
                                isc_portset_addrange(portset, loport, hiport);
 
2849
                        else {
 
2850
                                isc_portset_removerange(portset, loport,
 
2851
                                                        hiport);
 
2852
                        }
 
2853
                }
2850
2854
        }
2851
 
        return (result);
2852
2855
}
2853
2856
 
2854
2857
static isc_result_t
2888
2891
        const cfg_obj_t *maps[3];
2889
2892
        const cfg_obj_t *obj;
2890
2893
        const cfg_obj_t *options;
2891
 
        const cfg_obj_t *v4ports, *v6ports;
 
2894
        const cfg_obj_t *usev4ports, *avoidv4ports, *usev6ports, *avoidv6ports;
2892
2895
        const cfg_obj_t *views;
2893
2896
        dns_view_t *view = NULL;
2894
2897
        dns_view_t *view_next;
2895
2898
        dns_viewlist_t tmpviewlist;
2896
2899
        dns_viewlist_t viewlist;
2897
 
        in_port_t listen_port;
 
2900
        in_port_t listen_port, udpport_low, udpport_high;
2898
2901
        int i;
2899
2902
        isc_interval_t interval;
2900
 
        isc_resourcevalue_t files;
 
2903
        isc_portset_t *v4portset = NULL;
 
2904
        isc_portset_t *v6portset = NULL;
 
2905
        isc_resourcevalue_t nfiles;
2901
2906
        isc_result_t result;
2902
2907
        isc_uint32_t heartbeat_interval;
2903
2908
        isc_uint32_t interface_interval;
2904
2909
        isc_uint32_t reserved;
2905
2910
        isc_uint32_t udpsize;
 
2911
        unsigned int maxsocks;
2906
2912
 
2907
2913
        cfg_aclconfctx_init(&aclconfctx);
2908
2914
        ISC_LIST_INIT(viewlist);
2962
2968
        CHECK(result);
2963
2969
 
2964
2970
        /*
2965
 
         * Check that the working directory is writable.
2966
 
         */
2967
 
        if (access(".", W_OK) != 0) {
2968
 
                isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
2969
 
                              NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
2970
 
                              "the working directory is not writable");
2971
 
        }
2972
 
 
2973
 
        /*
2974
2971
         * Check the validity of the configuration.
2975
2972
         */
2976
2973
        CHECK(bind9_check_namedconf(config, ns_g_lctx, ns_g_mctx));
2992
2989
        set_limits(maps);
2993
2990
 
2994
2991
        /*
2995
 
         * Sanity check on "files" limit.
 
2992
         * Check if max number of open sockets that the system allows is
 
2993
         * sufficiently large.  Failing this condition is not necessarily fatal,
 
2994
         * but may cause subsequent runtime failures for a busy recursive
 
2995
         * server.
2996
2996
         */
2997
 
        result = isc_resource_curlimit(isc_resource_openfiles, &files);
2998
 
        if (result == ISC_R_SUCCESS && files < FD_SETSIZE) {
 
2997
        result = isc_socketmgr_getmaxsockets(ns_g_socketmgr, &maxsocks);
 
2998
        if (result != ISC_R_SUCCESS)
 
2999
                maxsocks = 0;
 
3000
        result = isc_resource_getcurlimit(isc_resource_openfiles, &nfiles);
 
3001
        if (result == ISC_R_SUCCESS && (isc_resourcevalue_t)maxsocks > nfiles) {
2999
3002
                isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
3000
3003
                              NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
3001
 
                              "the 'files' limit (%" ISC_PRINT_QUADFORMAT "u) "
3002
 
                              "is less than FD_SETSIZE (%d), increase "
3003
 
                              "'files' in named.conf or recompile with a "
3004
 
                              "smaller FD_SETSIZE.", files, FD_SETSIZE);
3005
 
                if (files > FD_SETSIZE)
3006
 
                        files = FD_SETSIZE;
3007
 
        } else
3008
 
                files = FD_SETSIZE;
 
3004
                              "max open files (%" ISC_PRINT_QUADFORMAT "u)"
 
3005
                              " is smaller than max sockets (%u)",
 
3006
                              nfiles, maxsocks);
 
3007
        }
3009
3008
 
3010
3009
        /*
3011
3010
         * Set the number of socket reserved for TCP, stdio etc.
3014
3013
        result = ns_config_get(maps, "reserved-sockets", &obj);
3015
3014
        INSIST(result == ISC_R_SUCCESS);
3016
3015
        reserved = cfg_obj_asuint32(obj);
3017
 
        if (files < 128U)                       /* Prevent underflow. */
3018
 
                reserved = 0;
3019
 
        else if (reserved > files - 128U)       /* Mimimum UDP space. */
3020
 
                reserved = files - 128;
3021
 
        if (reserved < 128U)                    /* Mimimum TCP/stdio space. */
 
3016
        if (maxsocks != 0) {
 
3017
                if (maxsocks < 128U)                    /* Prevent underflow. */
 
3018
                        reserved = 0;
 
3019
                else if (reserved > maxsocks - 128U)    /* Minimum UDP space. */
 
3020
                        reserved = maxsocks - 128;
 
3021
        }
 
3022
        /* Minimum TCP/stdio space. */
 
3023
        if (reserved < 128U)
3022
3024
                reserved = 128;
3023
 
        if (reserved + 128U > files) {
 
3025
        if (reserved + 128U > maxsocks && maxsocks != 0) {
3024
3026
                isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
3025
3027
                              NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
3026
3028
                              "less than 128 UDP sockets available after "
3027
 
                              "applying 'reserved-sockets' and 'files'");
 
3029
                              "applying 'reserved-sockets' and 'maxsockets'");
3028
3030
        }
3029
3031
        isc__socketmgr_setreserved(ns_g_socketmgr, reserved);
3030
3032
 
3055
3057
        CHECKM(ns_statschannels_configure(ns_g_server, config, &aclconfctx),
3056
3058
               "configuring statistics server(s)");
3057
3059
 
3058
 
        v4ports = NULL;
3059
 
        v6ports = NULL;
3060
 
        (void)ns_config_get(maps, "avoid-v4-udp-ports", &v4ports);
3061
 
        (void)ns_config_get(maps, "avoid-v6-udp-ports", &v6ports);
3062
 
        if (v4ports != NULL || v6ports != NULL) {
3063
 
                dns_portlist_t *portlist = NULL;
3064
 
                result = dns_portlist_create(ns_g_mctx, &portlist);
3065
 
                if (result == ISC_R_SUCCESS && v4ports != NULL)
3066
 
                        result = portlist_fromconf(portlist, AF_INET, v4ports);
3067
 
                if (result == ISC_R_SUCCESS && v6ports != NULL)
3068
 
                        portlist_fromconf(portlist, AF_INET6, v6ports);
3069
 
                if (result == ISC_R_SUCCESS)
3070
 
                        dns_dispatchmgr_setblackportlist(ns_g_dispatchmgr, portlist);
3071
 
                if (portlist != NULL)
3072
 
                        dns_portlist_detach(&portlist);
3073
 
                CHECK(result);
3074
 
        } else
3075
 
                dns_dispatchmgr_setblackportlist(ns_g_dispatchmgr, NULL);
 
3060
        /*
 
3061
         * Configure sets of UDP query source ports.
 
3062
         */
 
3063
        CHECKM(isc_portset_create(ns_g_mctx, &v4portset),
 
3064
               "creating UDP port set");
 
3065
        CHECKM(isc_portset_create(ns_g_mctx, &v6portset),
 
3066
               "creating UDP port set");
 
3067
 
 
3068
        usev4ports = NULL;
 
3069
        usev6ports = NULL;
 
3070
        avoidv4ports = NULL;
 
3071
        avoidv6ports = NULL;
 
3072
 
 
3073
        (void)ns_config_get(maps, "use-v4-udp-ports", &usev4ports);
 
3074
        if (usev4ports != NULL)
 
3075
                portset_fromconf(v4portset, usev4ports, ISC_TRUE);
 
3076
        else {
 
3077
                CHECKM(isc_net_getudpportrange(AF_INET, &udpport_low,
 
3078
                                               &udpport_high),
 
3079
                       "get the default UDP/IPv4 port range");
 
3080
                if (udpport_low == udpport_high)
 
3081
                        isc_portset_add(v4portset, udpport_low);
 
3082
                else {
 
3083
                        isc_portset_addrange(v4portset, udpport_low,
 
3084
                                             udpport_high);
 
3085
                }
 
3086
                isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
 
3087
                              NS_LOGMODULE_SERVER, ISC_LOG_INFO,
 
3088
                              "using default UDP/IPv4 port range: [%d, %d]",
 
3089
                              udpport_low, udpport_high);
 
3090
        }
 
3091
        (void)ns_config_get(maps, "avoid-v4-udp-ports", &avoidv4ports);
 
3092
        if (avoidv4ports != NULL)
 
3093
                portset_fromconf(v4portset, avoidv4ports, ISC_FALSE);
 
3094
 
 
3095
        (void)ns_config_get(maps, "use-v6-udp-ports", &usev6ports);
 
3096
        if (usev6ports != NULL)
 
3097
                portset_fromconf(v6portset, usev6ports, ISC_TRUE);
 
3098
        else {
 
3099
                CHECKM(isc_net_getudpportrange(AF_INET6, &udpport_low,
 
3100
                                               &udpport_high),
 
3101
                       "get the default UDP/IPv6 port range");
 
3102
                if (udpport_low == udpport_high)
 
3103
                        isc_portset_add(v6portset, udpport_low);
 
3104
                else {
 
3105
                        isc_portset_addrange(v6portset, udpport_low,
 
3106
                                             udpport_high);
 
3107
                }
 
3108
                isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
 
3109
                              NS_LOGMODULE_SERVER, ISC_LOG_INFO,
 
3110
                              "using default UDP/IPv6 port range: [%d, %d]",
 
3111
                              udpport_low, udpport_high);
 
3112
        }
 
3113
        (void)ns_config_get(maps, "avoid-v6-udp-ports", &avoidv6ports);
 
3114
        if (avoidv6ports != NULL)
 
3115
                portset_fromconf(v6portset, avoidv6ports, ISC_FALSE);
 
3116
 
 
3117
        dns_dispatchmgr_setavailports(ns_g_dispatchmgr, v4portset, v6portset);
3076
3118
 
3077
3119
        /*
3078
3120
         * Set the EDNS UDP size when we don't match a view.
3381
3423
                ns_os_changeuser();
3382
3424
 
3383
3425
        /*
 
3426
         * Check that the working directory is writable.
 
3427
         */
 
3428
        if (access(".", W_OK) != 0) {
 
3429
                isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
 
3430
                              NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
 
3431
                              "the working directory is not writable");
 
3432
        }
 
3433
 
 
3434
        /*
3384
3435
         * Configure the logging system.
3385
3436
         *
3386
3437
         * Do this after changing UID to make sure that any log
3553
3604
        result = ISC_R_SUCCESS;
3554
3605
 
3555
3606
 cleanup:
 
3607
        if (v4portset != NULL)
 
3608
                isc_portset_destroy(ns_g_mctx, &v4portset);
 
3609
 
 
3610
        if (v6portset != NULL)
 
3611
                isc_portset_destroy(ns_g_mctx, &v6portset);
 
3612
 
3556
3613
        cfg_aclconfctx_destroy(&aclconfctx);
3557
3614
 
3558
3615
        if (parser != NULL) {