zoneconf.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004-2015  Internet Systems Consortium, Inc. ("ISC")
00003  * Copyright (C) 1999-2003  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00010  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00011  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00012  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00013  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00014  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00015  * PERFORMANCE OF THIS SOFTWARE.
00016  */
00017 
00018 #include <config.h>
00019 
00020 #include <isc/buffer.h>
00021 #include <isc/file.h>
00022 #include <isc/mem.h>
00023 #include <isc/print.h>
00024 #include <isc/stats.h>
00025 #include <isc/string.h>         /* Required for HP/UX (and others?) */
00026 #include <isc/util.h>
00027 
00028 #include <dns/acl.h>
00029 #include <dns/db.h>
00030 #include <dns/fixedname.h>
00031 #include <dns/log.h>
00032 #include <dns/name.h>
00033 #include <dns/masterdump.h>
00034 #include <dns/rdata.h>
00035 #include <dns/rdatatype.h>
00036 #include <dns/rdataset.h>
00037 #include <dns/rdatalist.h>
00038 #include <dns/result.h>
00039 #include <dns/sdlz.h>
00040 #include <dns/ssu.h>
00041 #include <dns/stats.h>
00042 #include <dns/view.h>
00043 #include <dns/zone.h>
00044 
00045 #include <named/client.h>
00046 #include <named/config.h>
00047 #include <named/globals.h>
00048 #include <named/log.h>
00049 #include <named/server.h>
00050 #include <named/zoneconf.h>
00051 
00052 /* ACLs associated with zone */
00053 typedef enum {
00054         allow_notify,
00055         allow_query,
00056         allow_query_on,
00057         allow_transfer,
00058         allow_update,
00059         allow_update_forwarding
00060 } acl_type_t;
00061 
00062 #define RETERR(x) do { \
00063         isc_result_t _r = (x); \
00064         if (_r != ISC_R_SUCCESS) \
00065                 return (_r); \
00066         } while (0)
00067 
00068 #define CHECK(x) do { \
00069         result = (x); \
00070         if (result != ISC_R_SUCCESS) \
00071                 goto cleanup; \
00072         } while (0)
00073 
00074 /*%
00075  * Convenience function for configuring a single zone ACL.
00076  */
00077 static isc_result_t
00078 configure_zone_acl(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig,
00079                    const cfg_obj_t *config, acl_type_t acltype,
00080                    cfg_aclconfctx_t *actx, dns_zone_t *zone,
00081                    void (*setzacl)(dns_zone_t *, dns_acl_t *),
00082                    void (*clearzacl)(dns_zone_t *))
00083 {
00084         isc_result_t result;
00085         const cfg_obj_t *maps[5] = {NULL, NULL, NULL, NULL, NULL};
00086         const cfg_obj_t *aclobj = NULL;
00087         int i = 0;
00088         dns_acl_t **aclp = NULL, *acl = NULL;
00089         const char *aclname;
00090         dns_view_t *view;
00091 
00092         view = dns_zone_getview(zone);
00093 
00094         switch (acltype) {
00095             case allow_notify:
00096                 if (view != NULL)
00097                         aclp = &view->notifyacl;
00098                 aclname = "allow-notify";
00099                 break;
00100             case allow_query:
00101                 if (view != NULL)
00102                         aclp = &view->queryacl;
00103                 aclname = "allow-query";
00104                 break;
00105             case allow_query_on:
00106                 if (view != NULL)
00107                         aclp = &view->queryonacl;
00108                 aclname = "allow-query-on";
00109                 break;
00110             case allow_transfer:
00111                 if (view != NULL)
00112                         aclp = &view->transferacl;
00113                 aclname = "allow-transfer";
00114                 break;
00115             case allow_update:
00116                 if (view != NULL)
00117                         aclp = &view->updateacl;
00118                 aclname = "allow-update";
00119                 break;
00120             case allow_update_forwarding:
00121                 if (view != NULL)
00122                         aclp = &view->upfwdacl;
00123                 aclname = "allow-update-forwarding";
00124                 break;
00125             default:
00126                 INSIST(0);
00127                 return (ISC_R_FAILURE);
00128         }
00129 
00130         /* First check to see if ACL is defined within the zone */
00131         if (zconfig != NULL) {
00132                 maps[0] = cfg_tuple_get(zconfig, "options");
00133                 (void)ns_config_get(maps, aclname, &aclobj);
00134                 if (aclobj != NULL) {
00135                         aclp = NULL;
00136                         goto parse_acl;
00137                 }
00138         }
00139 
00140         /* Failing that, see if there's a default ACL already in the view */
00141         if (aclp != NULL && *aclp != NULL) {
00142                 (*setzacl)(zone, *aclp);
00143                 return (ISC_R_SUCCESS);
00144         }
00145 
00146         /* Check for default ACLs that haven't been parsed yet */
00147         if (vconfig != NULL) {
00148                 const cfg_obj_t *options = cfg_tuple_get(vconfig, "options");
00149                 if (options != NULL)
00150                         maps[i++] = options;
00151         }
00152         if (config != NULL) {
00153                 const cfg_obj_t *options = NULL;
00154                 (void)cfg_map_get(config, "options", &options);
00155                 if (options != NULL)
00156                         maps[i++] = options;
00157         }
00158         maps[i++] = ns_g_defaults;
00159         maps[i] = NULL;
00160 
00161         (void)ns_config_get(maps, aclname, &aclobj);
00162         if (aclobj == NULL) {
00163                 (*clearzacl)(zone);
00164                 return (ISC_R_SUCCESS);
00165         }
00166 
00167 parse_acl:
00168         result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx, actx,
00169                                     dns_zone_getmctx(zone), 0, &acl);
00170         if (result != ISC_R_SUCCESS)
00171                 return (result);
00172         (*setzacl)(zone, acl);
00173 
00174         /* Set the view default now */
00175         if (aclp != NULL)
00176                 dns_acl_attach(acl, aclp);
00177 
00178         dns_acl_detach(&acl);
00179         return (ISC_R_SUCCESS);
00180 }
00181 
00182 /*%
00183  * Parse the zone update-policy statement.
00184  */
00185 static isc_result_t
00186 configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
00187                         const char *zname)
00188 {
00189         const cfg_obj_t *updatepolicy = NULL;
00190         const cfg_listelt_t *element, *element2;
00191         dns_ssutable_t *table = NULL;
00192         isc_mem_t *mctx = dns_zone_getmctx(zone);
00193         isc_boolean_t autoddns = ISC_FALSE;
00194         isc_result_t result;
00195 
00196         (void)cfg_map_get(zconfig, "update-policy", &updatepolicy);
00197 
00198         if (updatepolicy == NULL) {
00199                 dns_zone_setssutable(zone, NULL);
00200                 return (ISC_R_SUCCESS);
00201         }
00202 
00203         if (cfg_obj_isstring(updatepolicy) &&
00204             strcmp("local", cfg_obj_asstring(updatepolicy)) == 0) {
00205                 autoddns = ISC_TRUE;
00206                 updatepolicy = NULL;
00207         }
00208 
00209         result = dns_ssutable_create(mctx, &table);
00210         if (result != ISC_R_SUCCESS)
00211                 return (result);
00212 
00213         for (element = cfg_list_first(updatepolicy);
00214              element != NULL;
00215              element = cfg_list_next(element))
00216         {
00217                 const cfg_obj_t *stmt = cfg_listelt_value(element);
00218                 const cfg_obj_t *mode = cfg_tuple_get(stmt, "mode");
00219                 const cfg_obj_t *identity = cfg_tuple_get(stmt, "identity");
00220                 const cfg_obj_t *matchtype = cfg_tuple_get(stmt, "matchtype");
00221                 const cfg_obj_t *dname = cfg_tuple_get(stmt, "name");
00222                 const cfg_obj_t *typelist = cfg_tuple_get(stmt, "types");
00223                 const char *str;
00224                 isc_boolean_t grant = ISC_FALSE;
00225                 isc_boolean_t usezone = ISC_FALSE;
00226                 unsigned int mtype = DNS_SSUMATCHTYPE_NAME;
00227                 dns_fixedname_t fname, fident;
00228                 isc_buffer_t b;
00229                 dns_rdatatype_t *types;
00230                 unsigned int i, n;
00231 
00232                 str = cfg_obj_asstring(mode);
00233                 if (strcasecmp(str, "grant") == 0)
00234                         grant = ISC_TRUE;
00235                 else if (strcasecmp(str, "deny") == 0)
00236                         grant = ISC_FALSE;
00237                 else
00238                         INSIST(0);
00239 
00240                 str = cfg_obj_asstring(matchtype);
00241                 if (strcasecmp(str, "name") == 0)
00242                         mtype = DNS_SSUMATCHTYPE_NAME;
00243                 else if (strcasecmp(str, "subdomain") == 0)
00244                         mtype = DNS_SSUMATCHTYPE_SUBDOMAIN;
00245                 else if (strcasecmp(str, "wildcard") == 0)
00246                         mtype = DNS_SSUMATCHTYPE_WILDCARD;
00247                 else if (strcasecmp(str, "self") == 0)
00248                         mtype = DNS_SSUMATCHTYPE_SELF;
00249                 else if (strcasecmp(str, "selfsub") == 0)
00250                         mtype = DNS_SSUMATCHTYPE_SELFSUB;
00251                 else if (strcasecmp(str, "selfwild") == 0)
00252                         mtype = DNS_SSUMATCHTYPE_SELFWILD;
00253                 else if (strcasecmp(str, "ms-self") == 0)
00254                         mtype = DNS_SSUMATCHTYPE_SELFMS;
00255                 else if (strcasecmp(str, "krb5-self") == 0)
00256                         mtype = DNS_SSUMATCHTYPE_SELFKRB5;
00257                 else if (strcasecmp(str, "ms-subdomain") == 0)
00258                         mtype = DNS_SSUMATCHTYPE_SUBDOMAINMS;
00259                 else if (strcasecmp(str, "krb5-subdomain") == 0)
00260                         mtype = DNS_SSUMATCHTYPE_SUBDOMAINKRB5;
00261                 else if (strcasecmp(str, "tcp-self") == 0)
00262                         mtype = DNS_SSUMATCHTYPE_TCPSELF;
00263                 else if (strcasecmp(str, "6to4-self") == 0)
00264                         mtype = DNS_SSUMATCHTYPE_6TO4SELF;
00265                 else if (strcasecmp(str, "zonesub") == 0) {
00266                         mtype = DNS_SSUMATCHTYPE_SUBDOMAIN;
00267                         usezone = ISC_TRUE;
00268                 } else if (strcasecmp(str, "external") == 0)
00269                         mtype = DNS_SSUMATCHTYPE_EXTERNAL;
00270                 else
00271                         INSIST(0);
00272 
00273                 dns_fixedname_init(&fident);
00274                 str = cfg_obj_asstring(identity);
00275                 isc_buffer_constinit(&b, str, strlen(str));
00276                 isc_buffer_add(&b, strlen(str));
00277                 result = dns_name_fromtext(dns_fixedname_name(&fident), &b,
00278                                            dns_rootname, 0, NULL);
00279                 if (result != ISC_R_SUCCESS) {
00280                         cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
00281                                     "'%s' is not a valid name", str);
00282                         goto cleanup;
00283                 }
00284 
00285                 dns_fixedname_init(&fname);
00286                 if (usezone) {
00287                         result = dns_name_copy(dns_zone_getorigin(zone),
00288                                                dns_fixedname_name(&fname),
00289                                                NULL);
00290                         if (result != ISC_R_SUCCESS) {
00291                                 cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
00292                                             "error copying origin: %s",
00293                                             isc_result_totext(result));
00294                                 goto cleanup;
00295                         }
00296                 } else {
00297                         str = cfg_obj_asstring(dname);
00298                         isc_buffer_constinit(&b, str, strlen(str));
00299                         isc_buffer_add(&b, strlen(str));
00300                         result = dns_name_fromtext(dns_fixedname_name(&fname),
00301                                                    &b, dns_rootname, 0, NULL);
00302                         if (result != ISC_R_SUCCESS) {
00303                                 cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
00304                                             "'%s' is not a valid name", str);
00305                                 goto cleanup;
00306                         }
00307                 }
00308 
00309                 n = ns_config_listcount(typelist);
00310                 if (n == 0)
00311                         types = NULL;
00312                 else {
00313                         types = isc_mem_get(mctx, n * sizeof(dns_rdatatype_t));
00314                         if (types == NULL) {
00315                                 result = ISC_R_NOMEMORY;
00316                                 goto cleanup;
00317                         }
00318                 }
00319 
00320                 i = 0;
00321                 for (element2 = cfg_list_first(typelist);
00322                      element2 != NULL;
00323                      element2 = cfg_list_next(element2))
00324                 {
00325                         const cfg_obj_t *typeobj;
00326                         isc_textregion_t r;
00327 
00328                         INSIST(i < n);
00329 
00330                         typeobj = cfg_listelt_value(element2);
00331                         str = cfg_obj_asstring(typeobj);
00332                         DE_CONST(str, r.base);
00333                         r.length = strlen(str);
00334 
00335                         result = dns_rdatatype_fromtext(&types[i++], &r);
00336                         if (result != ISC_R_SUCCESS) {
00337                                 cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
00338                                             "'%s' is not a valid type", str);
00339                                 isc_mem_put(mctx, types,
00340                                             n * sizeof(dns_rdatatype_t));
00341                                 goto cleanup;
00342                         }
00343                 }
00344                 INSIST(i == n);
00345 
00346                 result = dns_ssutable_addrule(table, grant,
00347                                               dns_fixedname_name(&fident),
00348                                               mtype,
00349                                               dns_fixedname_name(&fname),
00350                                               n, types);
00351                 if (types != NULL)
00352                         isc_mem_put(mctx, types, n * sizeof(dns_rdatatype_t));
00353                 if (result != ISC_R_SUCCESS) {
00354                         goto cleanup;
00355                 }
00356         }
00357 
00358         /*
00359          * If "update-policy local;" and a session key exists,
00360          * then use the default policy, which is equivalent to:
00361          * update-policy { grant <session-keyname> zonesub any; };
00362          */
00363         if (autoddns) {
00364                 dns_rdatatype_t any = dns_rdatatype_any;
00365 
00366                 if (ns_g_server->session_keyname == NULL) {
00367                         isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
00368                                       NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
00369                                       "failed to enable auto DDNS policy "
00370                                       "for zone %s: session key not found",
00371                                       zname);
00372                         result = ISC_R_NOTFOUND;
00373                         goto cleanup;
00374                 }
00375 
00376                 result = dns_ssutable_addrule(table, ISC_TRUE,
00377                                               ns_g_server->session_keyname,
00378                                               DNS_SSUMATCHTYPE_SUBDOMAIN,
00379                                               dns_zone_getorigin(zone),
00380                                               1, &any);
00381 
00382                 if (result != ISC_R_SUCCESS)
00383                         goto cleanup;
00384         }
00385 
00386         result = ISC_R_SUCCESS;
00387         dns_zone_setssutable(zone, table);
00388 
00389  cleanup:
00390         dns_ssutable_detach(&table);
00391         return (result);
00392 }
00393 
00394 /*
00395  * This is the TTL used for internally generated RRsets for static-stub zones.
00396  * The value doesn't matter because the mapping is static, but needs to be
00397  * defined for the sake of implementation.
00398  */
00399 #define STATICSTUB_SERVER_TTL 86400
00400 
00401 /*%
00402  * Configure an apex NS with glues for a static-stub zone.
00403  * For example, for the zone named "example.com", the following RRs will be
00404  * added to the zone DB:
00405  * example.com. NS example.com.
00406  * example.com. A 192.0.2.1
00407  * example.com. AAAA 2001:db8::1
00408  */
00409 static isc_result_t
00410 configure_staticstub_serveraddrs(const cfg_obj_t *zconfig, dns_zone_t *zone,
00411                                  dns_rdatalist_t *rdatalist_ns,
00412                                  dns_rdatalist_t *rdatalist_a,
00413                                  dns_rdatalist_t *rdatalist_aaaa)
00414 {
00415         const cfg_listelt_t *element;
00416         isc_mem_t *mctx = dns_zone_getmctx(zone);
00417         isc_region_t region, sregion;
00418         dns_rdata_t *rdata;
00419         isc_result_t result = ISC_R_SUCCESS;
00420 
00421         for (element = cfg_list_first(zconfig);
00422              element != NULL;
00423              element = cfg_list_next(element))
00424         {
00425                 const isc_sockaddr_t* sa;
00426                 isc_netaddr_t na;
00427                 const cfg_obj_t *address = cfg_listelt_value(element);
00428                 dns_rdatalist_t *rdatalist;
00429 
00430                 sa = cfg_obj_assockaddr(address);
00431                 if (isc_sockaddr_getport(sa) != 0) {
00432                         cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
00433                                     "port is not configurable for "
00434                                     "static stub server-addresses");
00435                         return (ISC_R_FAILURE);
00436                 }
00437                 isc_netaddr_fromsockaddr(&na, sa);
00438                 if (isc_netaddr_getzone(&na) != 0) {
00439                         cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
00440                                             "scoped address is not allowed "
00441                                             "for static stub "
00442                                             "server-addresses");
00443                         return (ISC_R_FAILURE);
00444                 }
00445 
00446                 switch (na.family) {
00447                 case AF_INET:
00448                         region.length = sizeof(na.type.in);
00449                         rdatalist = rdatalist_a;
00450                         break;
00451                 default:
00452                         INSIST(na.family == AF_INET6);
00453                         region.length = sizeof(na.type.in6);
00454                         rdatalist = rdatalist_aaaa;
00455                         break;
00456                 }
00457 
00458                 rdata = isc_mem_get(mctx, sizeof(*rdata) + region.length);
00459                 if (rdata == NULL)
00460                         return (ISC_R_NOMEMORY);
00461                 region.base = (unsigned char *)(rdata + 1);
00462                 memmove(region.base, &na.type, region.length);
00463                 dns_rdata_init(rdata);
00464                 dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
00465                                      rdatalist->type, &region);
00466                 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
00467         }
00468 
00469         /*
00470          * If no address is specified (unlikely in this context, but possible),
00471          * there's nothing to do anymore.
00472          */
00473         if (ISC_LIST_EMPTY(rdatalist_a->rdata) &&
00474             ISC_LIST_EMPTY(rdatalist_aaaa->rdata)) {
00475                 return (ISC_R_SUCCESS);
00476         }
00477 
00478         /* Add to the list an apex NS with the ns name being the origin name */
00479         dns_name_toregion(dns_zone_getorigin(zone), &sregion);
00480         rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length);
00481         if (rdata == NULL) {
00482                 /*
00483                  * Already allocated data will be freed in the caller, so
00484                  * we can simply return here.
00485                  */
00486                 return (ISC_R_NOMEMORY);
00487         }
00488         region.length = sregion.length;
00489         region.base = (unsigned char *)(rdata + 1);
00490         memmove(region.base, sregion.base, region.length);
00491         dns_rdata_init(rdata);
00492         dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
00493                              dns_rdatatype_ns, &region);
00494         ISC_LIST_APPEND(rdatalist_ns->rdata, rdata, link);
00495 
00496         return (result);
00497 }
00498 
00499 /*%
00500  * Configure an apex NS with an out-of-zone NS names for a static-stub zone.
00501  * For example, for the zone named "example.com", something like the following
00502  * RRs will be added to the zone DB:
00503  * example.com. NS ns.example.net.
00504  */
00505 static isc_result_t
00506 configure_staticstub_servernames(const cfg_obj_t *zconfig, dns_zone_t *zone,
00507                                  dns_rdatalist_t *rdatalist, const char *zname)
00508 {
00509         const cfg_listelt_t *element;
00510         isc_mem_t *mctx = dns_zone_getmctx(zone);
00511         dns_rdata_t *rdata;
00512         isc_region_t sregion, region;
00513         isc_result_t result = ISC_R_SUCCESS;
00514 
00515         for (element = cfg_list_first(zconfig);
00516              element != NULL;
00517              element = cfg_list_next(element))
00518         {
00519                 const cfg_obj_t *obj;
00520                 const char *str;
00521                 dns_fixedname_t fixed_name;
00522                 dns_name_t *nsname;
00523                 isc_buffer_t b;
00524 
00525                 obj = cfg_listelt_value(element);
00526                 str = cfg_obj_asstring(obj);
00527 
00528                 dns_fixedname_init(&fixed_name);
00529                 nsname = dns_fixedname_name(&fixed_name);
00530 
00531                 isc_buffer_constinit(&b, str, strlen(str));
00532                 isc_buffer_add(&b, strlen(str));
00533                 result = dns_name_fromtext(nsname, &b, dns_rootname, 0, NULL);
00534                 if (result != ISC_R_SUCCESS) {
00535                         cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
00536                                             "server-name '%s' is not a valid "
00537                                             "name", str);
00538                         return (result);
00539                 }
00540                 if (dns_name_issubdomain(nsname, dns_zone_getorigin(zone))) {
00541                         cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
00542                                     "server-name '%s' must not be a "
00543                                     "subdomain of zone name '%s'",
00544                                     str, zname);
00545                         return (ISC_R_FAILURE);
00546                 }
00547 
00548                 dns_name_toregion(nsname, &sregion);
00549                 rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length);
00550                 if (rdata == NULL)
00551                         return (ISC_R_NOMEMORY);
00552                 region.length = sregion.length;
00553                 region.base = (unsigned char *)(rdata + 1);
00554                 memmove(region.base, sregion.base, region.length);
00555                 dns_rdata_init(rdata);
00556                 dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
00557                                      dns_rdatatype_ns, &region);
00558                 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
00559         }
00560 
00561         return (result);
00562 }
00563 
00564 /*%
00565  * Configure static-stub zone.
00566  */
00567 static isc_result_t
00568 configure_staticstub(const cfg_obj_t *zconfig, dns_zone_t *zone,
00569                      const char *zname, const char *dbtype)
00570 {
00571         int i = 0;
00572         const cfg_obj_t *obj;
00573         isc_mem_t *mctx = dns_zone_getmctx(zone);
00574         dns_db_t *db = NULL;
00575         dns_dbversion_t *dbversion = NULL;
00576         dns_dbnode_t *apexnode = NULL;
00577         dns_name_t apexname;
00578         isc_result_t result;
00579         dns_rdataset_t rdataset;
00580         dns_rdatalist_t rdatalist_ns, rdatalist_a, rdatalist_aaaa;
00581         dns_rdatalist_t* rdatalists[] = {
00582                 &rdatalist_ns, &rdatalist_a, &rdatalist_aaaa, NULL
00583         };
00584         dns_rdata_t *rdata;
00585         isc_region_t region;
00586 
00587         /* Create the DB beforehand */
00588         RETERR(dns_db_create(mctx, dbtype, dns_zone_getorigin(zone),
00589                              dns_dbtype_stub, dns_zone_getclass(zone),
00590                              0, NULL, &db));
00591         dns_zone_setdb(zone, db);
00592 
00593         dns_rdatalist_init(&rdatalist_ns);
00594         rdatalist_ns.rdclass = dns_zone_getclass(zone);
00595         rdatalist_ns.type = dns_rdatatype_ns;
00596         rdatalist_ns.ttl = STATICSTUB_SERVER_TTL;
00597 
00598         dns_rdatalist_init(&rdatalist_a);
00599         rdatalist_a.rdclass = dns_zone_getclass(zone);
00600         rdatalist_a.type = dns_rdatatype_a;
00601         rdatalist_a.ttl = STATICSTUB_SERVER_TTL;
00602 
00603         dns_rdatalist_init(&rdatalist_aaaa);
00604         rdatalist_aaaa.rdclass = dns_zone_getclass(zone);
00605         rdatalist_aaaa.type = dns_rdatatype_aaaa;
00606         rdatalist_aaaa.ttl = STATICSTUB_SERVER_TTL;
00607 
00608         /* Prepare zone RRs from the configuration */
00609         obj = NULL;
00610         result = cfg_map_get(zconfig, "server-addresses", &obj);
00611         if (result == ISC_R_SUCCESS) {
00612                 INSIST(obj != NULL);
00613                 result = configure_staticstub_serveraddrs(obj, zone,
00614                                                           &rdatalist_ns,
00615                                                           &rdatalist_a,
00616                                                           &rdatalist_aaaa);
00617                 if (result != ISC_R_SUCCESS)
00618                         goto cleanup;
00619         }
00620 
00621         obj = NULL;
00622         result = cfg_map_get(zconfig, "server-names", &obj);
00623         if (result == ISC_R_SUCCESS) {
00624                 INSIST(obj != NULL);
00625                 result = configure_staticstub_servernames(obj, zone,
00626                                                           &rdatalist_ns,
00627                                                           zname);
00628                 if (result != ISC_R_SUCCESS)
00629                         goto cleanup;
00630         }
00631 
00632         /*
00633          * Sanity check: there should be at least one NS RR at the zone apex
00634          * to trigger delegation.
00635          */
00636         if (ISC_LIST_EMPTY(rdatalist_ns.rdata)) {
00637                 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
00638                               NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
00639                               "No NS record is configured for a "
00640                               "static-stub zone '%s'", zname);
00641                 result = ISC_R_FAILURE;
00642                 goto cleanup;
00643         }
00644 
00645         /*
00646          * Now add NS and glue A/AAAA RRsets to the zone DB.
00647          * First open a new version for the add operation and get a pointer
00648          * to the apex node (all RRs are of the apex name).
00649          */
00650         result = dns_db_newversion(db, &dbversion);
00651         if (result != ISC_R_SUCCESS)
00652                 goto cleanup;
00653         dns_name_init(&apexname, NULL);
00654         dns_name_clone(dns_zone_getorigin(zone), &apexname);
00655         result = dns_db_findnode(db, &apexname, ISC_FALSE, &apexnode);
00656         if (result != ISC_R_SUCCESS)
00657                 goto cleanup;
00658 
00659         /* Add NS RRset */
00660         dns_rdataset_init(&rdataset);
00661         RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_ns, &rdataset)
00662                       == ISC_R_SUCCESS);
00663         result = dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset,
00664                                     0, NULL);
00665         dns_rdataset_disassociate(&rdataset);
00666         if (result != ISC_R_SUCCESS)
00667                 goto cleanup;
00668 
00669         /* Add glue A RRset, if any */
00670         if (!ISC_LIST_EMPTY(rdatalist_a.rdata)) {
00671                 RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_a, &rdataset)
00672                               == ISC_R_SUCCESS);
00673                 result = dns_db_addrdataset(db, apexnode, dbversion, 0,
00674                                             &rdataset, 0, NULL);
00675                 dns_rdataset_disassociate(&rdataset);
00676                 if (result != ISC_R_SUCCESS)
00677                         goto cleanup;
00678         }
00679 
00680         /* Add glue AAAA RRset, if any */
00681         if (!ISC_LIST_EMPTY(rdatalist_aaaa.rdata)) {
00682                 RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_aaaa,
00683                                                        &rdataset)
00684                               == ISC_R_SUCCESS);
00685                 result = dns_db_addrdataset(db, apexnode, dbversion, 0,
00686                                             &rdataset, 0, NULL);
00687                 dns_rdataset_disassociate(&rdataset);
00688                 if (result != ISC_R_SUCCESS)
00689                         goto cleanup;
00690         }
00691 
00692         result = ISC_R_SUCCESS;
00693 
00694   cleanup:
00695         if (apexnode != NULL)
00696                 dns_db_detachnode(db, &apexnode);
00697         if (dbversion != NULL)
00698                 dns_db_closeversion(db, &dbversion, ISC_TRUE);
00699         if (db != NULL)
00700                 dns_db_detach(&db);
00701         for (i = 0; rdatalists[i] != NULL; i++) {
00702                 while ((rdata = ISC_LIST_HEAD(rdatalists[i]->rdata)) != NULL) {
00703                         ISC_LIST_UNLINK(rdatalists[i]->rdata, rdata, link);
00704                         dns_rdata_toregion(rdata, &region);
00705                         isc_mem_put(mctx, rdata,
00706                                     sizeof(*rdata) + region.length);
00707                 }
00708         }
00709 
00710         INSIST(dbversion == NULL);
00711 
00712         return (result);
00713 }
00714 
00715 /*%
00716  * Convert a config file zone type into a server zone type.
00717  */
00718 static inline dns_zonetype_t
00719 zonetype_fromconfig(const cfg_obj_t *map) {
00720         const cfg_obj_t *obj = NULL;
00721         isc_result_t result;
00722 
00723         result = cfg_map_get(map, "type", &obj);
00724         INSIST(result == ISC_R_SUCCESS && obj != NULL);
00725         return (ns_config_getzonetype(obj));
00726 }
00727 
00728 /*%
00729  * Helper function for strtoargv().  Pardon the gratuitous recursion.
00730  */
00731 static isc_result_t
00732 strtoargvsub(isc_mem_t *mctx, char *s, unsigned int *argcp,
00733              char ***argvp, unsigned int n)
00734 {
00735         isc_result_t result;
00736 
00737         /* Discard leading whitespace. */
00738         while (*s == ' ' || *s == '\t')
00739                 s++;
00740 
00741         if (*s == '\0') {
00742                 /* We have reached the end of the string. */
00743                 *argcp = n;
00744                 *argvp = isc_mem_get(mctx, n * sizeof(char *));
00745                 if (*argvp == NULL)
00746                         return (ISC_R_NOMEMORY);
00747         } else {
00748                 char *p = s;
00749                 while (*p != ' ' && *p != '\t' && *p != '\0')
00750                         p++;
00751                 if (*p != '\0')
00752                         *p++ = '\0';
00753 
00754                 result = strtoargvsub(mctx, p, argcp, argvp, n + 1);
00755                 if (result != ISC_R_SUCCESS)
00756                         return (result);
00757                 (*argvp)[n] = s;
00758         }
00759         return (ISC_R_SUCCESS);
00760 }
00761 
00762 /*%
00763  * Tokenize the string "s" into whitespace-separated words,
00764  * return the number of words in '*argcp' and an array
00765  * of pointers to the words in '*argvp'.  The caller
00766  * must free the array using isc_mem_put().  The string
00767  * is modified in-place.
00768  */
00769 static isc_result_t
00770 strtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp) {
00771         return (strtoargvsub(mctx, s, argcp, argvp, 0));
00772 }
00773 
00774 static void
00775 checknames(dns_zonetype_t ztype, const cfg_obj_t **maps,
00776            const cfg_obj_t **objp)
00777 {
00778         const char *zone = NULL;
00779         isc_result_t result;
00780 
00781         switch (ztype) {
00782         case dns_zone_slave: zone = "slave"; break;
00783         case dns_zone_master: zone = "master"; break;
00784         default:
00785                 INSIST(0);
00786         }
00787         result = ns_checknames_get(maps, zone, objp);
00788         INSIST(result == ISC_R_SUCCESS && objp != NULL && *objp != NULL);
00789 }
00790 
00791 isc_result_t
00792 ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
00793                   const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac,
00794                   dns_zone_t *zone, dns_zone_t *raw)
00795 {
00796         isc_result_t result;
00797         const char *zname;
00798         dns_rdataclass_t zclass;
00799         dns_rdataclass_t vclass;
00800         const cfg_obj_t *maps[5];
00801         const cfg_obj_t *nodefault[4];
00802         const cfg_obj_t *zoptions = NULL;
00803         const cfg_obj_t *options = NULL;
00804         const cfg_obj_t *obj;
00805         const char *filename = NULL;
00806         const char *dupcheck;
00807         dns_notifytype_t notifytype = dns_notifytype_yes;
00808         isc_sockaddr_t *addrs;
00809         isc_dscp_t *dscps;
00810         dns_name_t **keynames;
00811         isc_uint32_t count;
00812         unsigned int dbargc;
00813         char **dbargv;
00814         static char default_dbtype[] = "rbt";
00815         static char dlz_dbtype[] = "dlz";
00816         char *cpval = default_dbtype;
00817         isc_mem_t *mctx = dns_zone_getmctx(zone);
00818         dns_dialuptype_t dialup = dns_dialuptype_no;
00819         dns_zonetype_t ztype;
00820         int i;
00821         isc_int32_t journal_size;
00822         isc_boolean_t multi;
00823         isc_boolean_t alt;
00824         dns_view_t *view;
00825         isc_boolean_t check = ISC_FALSE, fail = ISC_FALSE;
00826         isc_boolean_t warn = ISC_FALSE, ignore = ISC_FALSE;
00827         isc_boolean_t ixfrdiff;
00828         dns_masterformat_t masterformat;
00829         const dns_master_style_t *masterstyle = &dns_master_style_default;
00830         isc_stats_t *zoneqrystats;
00831         dns_stats_t *rcvquerystats;
00832         dns_zonestat_level_t statlevel;
00833         int seconds;
00834         dns_zone_t *mayberaw = (raw != NULL) ? raw : zone;
00835         isc_dscp_t dscp;
00836 
00837         i = 0;
00838         if (zconfig != NULL) {
00839                 zoptions = cfg_tuple_get(zconfig, "options");
00840                 nodefault[i] = maps[i] = zoptions;
00841                 i++;
00842         }
00843         if (vconfig != NULL) {
00844                 nodefault[i] = maps[i] = cfg_tuple_get(vconfig, "options");
00845                 i++;
00846         }
00847         if (config != NULL) {
00848                 (void)cfg_map_get(config, "options", &options);
00849                 if (options != NULL) {
00850                         nodefault[i] = maps[i] = options;
00851                         i++;
00852                 }
00853         }
00854         nodefault[i] = NULL;
00855         maps[i++] = ns_g_defaults;
00856         maps[i] = NULL;
00857 
00858         if (vconfig != NULL)
00859                 RETERR(ns_config_getclass(cfg_tuple_get(vconfig, "class"),
00860                                           dns_rdataclass_in, &vclass));
00861         else
00862                 vclass = dns_rdataclass_in;
00863 
00864         /*
00865          * Configure values common to all zone types.
00866          */
00867 
00868         zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
00869 
00870         RETERR(ns_config_getclass(cfg_tuple_get(zconfig, "class"),
00871                                   vclass, &zclass));
00872         dns_zone_setclass(zone, zclass);
00873         if (raw != NULL)
00874                 dns_zone_setclass(raw, zclass);
00875 
00876         ztype = zonetype_fromconfig(zoptions);
00877         if (raw != NULL) {
00878                 dns_zone_settype(raw, ztype);
00879                 dns_zone_settype(zone, dns_zone_master);
00880         } else
00881                 dns_zone_settype(zone, ztype);
00882 
00883         obj = NULL;
00884         result = cfg_map_get(zoptions, "database", &obj);
00885         if (result == ISC_R_SUCCESS)
00886                 cpval = isc_mem_strdup(mctx, cfg_obj_asstring(obj));
00887         if (cpval == NULL)
00888                 return(ISC_R_NOMEMORY);
00889 
00890         obj = NULL;
00891         result = cfg_map_get(zoptions, "dlz", &obj);
00892         if (result == ISC_R_SUCCESS) {
00893                 const char *dlzname = cfg_obj_asstring(obj);
00894                 size_t len;
00895 
00896                 if (cpval != default_dbtype) {
00897                        isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
00898                                      NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
00899                                      "zone '%s': both 'database' and 'dlz' "
00900                                      "specified", zname);
00901                        return (ISC_R_FAILURE);
00902                 }
00903 
00904                 len = strlen(dlzname) + 5;
00905                 cpval = isc_mem_allocate(mctx, len);
00906                 snprintf(cpval, len, "dlz %s", dlzname);
00907         }
00908 
00909         result = strtoargv(mctx, cpval, &dbargc, &dbargv);
00910         if (result != ISC_R_SUCCESS && cpval != default_dbtype) {
00911                 isc_mem_free(mctx, cpval);
00912                 return (result);
00913         }
00914 
00915         /*
00916          * ANSI C is strange here.  There is no logical reason why (char **)
00917          * cannot be promoted automatically to (const char * const *) by the
00918          * compiler w/o generating a warning.
00919          */
00920         result = dns_zone_setdbtype(zone, dbargc, (const char * const *)dbargv);
00921         isc_mem_put(mctx, dbargv, dbargc * sizeof(*dbargv));
00922         if (cpval != default_dbtype && cpval != dlz_dbtype)
00923                 isc_mem_free(mctx, cpval);
00924         if (result != ISC_R_SUCCESS)
00925                 return (result);
00926 
00927         obj = NULL;
00928         result = cfg_map_get(zoptions, "file", &obj);
00929         if (result == ISC_R_SUCCESS)
00930                 filename = cfg_obj_asstring(obj);
00931 
00932         /*
00933          * Unless we're using some alternative database, a master zone
00934          * will be needing a master file.
00935          */
00936         if (ztype == dns_zone_master && cpval == default_dbtype &&
00937             filename == NULL) {
00938                 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
00939                               NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
00940                               "zone '%s': 'file' not specified",
00941                               zname);
00942                 return (ISC_R_FAILURE);
00943         }
00944 
00945         if (ztype == dns_zone_slave)
00946                 masterformat = dns_masterformat_raw;
00947         else
00948                 masterformat = dns_masterformat_text;
00949         obj = NULL;
00950         result = ns_config_get(maps, "masterfile-format", &obj);
00951         if (result == ISC_R_SUCCESS) {
00952                 const char *masterformatstr = cfg_obj_asstring(obj);
00953 
00954                 if (strcasecmp(masterformatstr, "text") == 0)
00955                         masterformat = dns_masterformat_text;
00956                 else if (strcasecmp(masterformatstr, "raw") == 0)
00957                         masterformat = dns_masterformat_raw;
00958                 else if (strcasecmp(masterformatstr, "map") == 0)
00959                         masterformat = dns_masterformat_map;
00960                 else
00961                         INSIST(0);
00962         }
00963 
00964         obj = NULL;
00965         result = ns_config_get(maps, "masterfile-style", &obj);
00966         if (result == ISC_R_SUCCESS) {
00967                 const char *masterstylestr = cfg_obj_asstring(obj);
00968 
00969                 if (masterformat != dns_masterformat_text) {
00970                         cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
00971                                     "zone '%s': 'masterfile-style' "
00972                                     "can only be used with "
00973                                     "'masterfile-format text'", zname);
00974                         return (ISC_R_FAILURE);
00975                 }
00976 
00977                 if (strcasecmp(masterstylestr, "full") == 0)
00978                         masterstyle = &dns_master_style_full;
00979                 else if (strcasecmp(masterstylestr, "relative") == 0)
00980                         masterstyle = &dns_master_style_default;
00981                 else
00982                         INSIST(0);
00983         }
00984 
00985         obj = NULL;
00986         result = ns_config_get(maps, "max-zone-ttl", &obj);
00987         if (result == ISC_R_SUCCESS && masterformat == dns_masterformat_map) {
00988                 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
00989                               NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
00990                               "zone '%s': 'max-zone-ttl' is not compatible "
00991                               "with 'masterfile-format map'", zname);
00992                 return (ISC_R_FAILURE);
00993         } else if (result == ISC_R_SUCCESS) {
00994                 dns_ttl_t maxttl = cfg_obj_asuint32(obj);
00995                 dns_zone_setmaxttl(zone, maxttl);
00996                 if (raw != NULL)
00997                         dns_zone_setmaxttl(raw, maxttl);
00998         }
00999 
01000         if (raw != NULL && filename != NULL) {
01001 #define SIGNED ".signed"
01002                 size_t signedlen = strlen(filename) + sizeof(SIGNED);
01003                 char *signedname;
01004 
01005                 RETERR(dns_zone_setfile3(raw, filename,
01006                                          masterformat, masterstyle));
01007                 signedname = isc_mem_get(mctx, signedlen);
01008                 if (signedname == NULL)
01009                         return (ISC_R_NOMEMORY);
01010 
01011                 (void)snprintf(signedname, signedlen, "%s" SIGNED, filename);
01012                 result = dns_zone_setfile3(zone, signedname,
01013                                            dns_masterformat_raw, NULL);
01014                 isc_mem_put(mctx, signedname, signedlen);
01015                 if (result != ISC_R_SUCCESS)
01016                         return (result);
01017         } else
01018                 RETERR(dns_zone_setfile3(zone, filename,
01019                                          masterformat, masterstyle));
01020 
01021         obj = NULL;
01022         result = cfg_map_get(zoptions, "journal", &obj);
01023         if (result == ISC_R_SUCCESS)
01024                 RETERR(dns_zone_setjournal(mayberaw, cfg_obj_asstring(obj)));
01025 
01026         /*
01027          * Notify messages are processed by the raw zone if it exists.
01028          */
01029         if (ztype == dns_zone_slave)
01030                 RETERR(configure_zone_acl(zconfig, vconfig, config,
01031                                           allow_notify, ac, mayberaw,
01032                                           dns_zone_setnotifyacl,
01033                                           dns_zone_clearnotifyacl));
01034 
01035         /*
01036          * XXXAG This probably does not make sense for stubs.
01037          */
01038         RETERR(configure_zone_acl(zconfig, vconfig, config,
01039                                   allow_query, ac, zone,
01040                                   dns_zone_setqueryacl,
01041                                   dns_zone_clearqueryacl));
01042 
01043         RETERR(configure_zone_acl(zconfig, vconfig, config,
01044                                   allow_query_on, ac, zone,
01045                                   dns_zone_setqueryonacl,
01046                                   dns_zone_clearqueryonacl));
01047 
01048         obj = NULL;
01049         result = ns_config_get(maps, "dialup", &obj);
01050         INSIST(result == ISC_R_SUCCESS && obj != NULL);
01051         if (cfg_obj_isboolean(obj)) {
01052                 if (cfg_obj_asboolean(obj))
01053                         dialup = dns_dialuptype_yes;
01054                 else
01055                         dialup = dns_dialuptype_no;
01056         } else {
01057                 const char *dialupstr = cfg_obj_asstring(obj);
01058                 if (strcasecmp(dialupstr, "notify") == 0)
01059                         dialup = dns_dialuptype_notify;
01060                 else if (strcasecmp(dialupstr, "notify-passive") == 0)
01061                         dialup = dns_dialuptype_notifypassive;
01062                 else if (strcasecmp(dialupstr, "refresh") == 0)
01063                         dialup = dns_dialuptype_refresh;
01064                 else if (strcasecmp(dialupstr, "passive") == 0)
01065                         dialup = dns_dialuptype_passive;
01066                 else
01067                         INSIST(0);
01068         }
01069         if (raw != NULL)
01070                 dns_zone_setdialup(raw, dialup);
01071         dns_zone_setdialup(zone, dialup);
01072 
01073         obj = NULL;
01074         result = ns_config_get(maps, "zone-statistics", &obj);
01075         INSIST(result == ISC_R_SUCCESS && obj != NULL);
01076         if (cfg_obj_isboolean(obj)) {
01077                 if (cfg_obj_asboolean(obj))
01078                         statlevel = dns_zonestat_full;
01079                 else
01080                         statlevel = dns_zonestat_none;
01081         } else {
01082                 const char *levelstr = cfg_obj_asstring(obj);
01083                 if (strcasecmp(levelstr, "full") == 0)
01084                         statlevel = dns_zonestat_full;
01085                 else if (strcasecmp(levelstr, "terse") == 0)
01086                         statlevel = dns_zonestat_terse;
01087                 else if (strcasecmp(levelstr, "none") == 0)
01088                         statlevel = dns_zonestat_none;
01089                 else
01090                         INSIST(0);
01091         }
01092         dns_zone_setstatlevel(zone, statlevel);
01093 
01094         zoneqrystats  = NULL;
01095         rcvquerystats = NULL;
01096         if (statlevel == dns_zonestat_full) {
01097                 RETERR(isc_stats_create(mctx, &zoneqrystats,
01098                                         dns_nsstatscounter_max));
01099                 RETERR(dns_rdatatypestats_create(mctx,
01100                                         &rcvquerystats));
01101         }
01102         dns_zone_setrequeststats(zone,  zoneqrystats);
01103         dns_zone_setrcvquerystats(zone, rcvquerystats);
01104 
01105         if (zoneqrystats != NULL)
01106                 isc_stats_detach(&zoneqrystats);
01107 
01108         if(rcvquerystats != NULL)
01109                 dns_stats_detach(&rcvquerystats);
01110 
01111         /*
01112          * Configure master functionality.  This applies
01113          * to primary masters (type "master") and slaves
01114          * acting as masters (type "slave"), but not to stubs.
01115          */
01116         if (ztype != dns_zone_stub && ztype != dns_zone_staticstub &&
01117             ztype != dns_zone_redirect) {
01118                 obj = NULL;
01119                 result = ns_config_get(maps, "notify", &obj);
01120                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01121                 if (cfg_obj_isboolean(obj)) {
01122                         if (cfg_obj_asboolean(obj))
01123                                 notifytype = dns_notifytype_yes;
01124                         else
01125                                 notifytype = dns_notifytype_no;
01126                 } else {
01127                         const char *notifystr = cfg_obj_asstring(obj);
01128                         if (strcasecmp(notifystr, "explicit") == 0)
01129                                 notifytype = dns_notifytype_explicit;
01130                         else if (strcasecmp(notifystr, "master-only") == 0)
01131                                 notifytype = dns_notifytype_masteronly;
01132                         else
01133                                 INSIST(0);
01134                 }
01135                 if (raw != NULL)
01136                         dns_zone_setnotifytype(raw, dns_notifytype_no);
01137                 dns_zone_setnotifytype(zone, notifytype);
01138 
01139                 obj = NULL;
01140                 result = ns_config_get(maps, "also-notify", &obj);
01141                 if (result == ISC_R_SUCCESS &&
01142                     (notifytype == dns_notifytype_yes ||
01143                      notifytype == dns_notifytype_explicit ||
01144                      (notifytype == dns_notifytype_masteronly &&
01145                       ztype == dns_zone_master)))
01146                 {
01147                         isc_uint32_t addrcount;
01148                         addrs = NULL;
01149                         keynames = NULL;
01150                         dscps = NULL;
01151                         RETERR(ns_config_getipandkeylist(config, obj, mctx,
01152                                                          &addrs, &dscps,
01153                                                          &keynames,
01154                                                          &addrcount));
01155                         result = dns_zone_setalsonotifydscpkeys(zone, addrs,
01156                                                                 dscps, keynames,
01157                                                                 addrcount);
01158                         if (addrcount != 0)
01159                                 ns_config_putipandkeylist(mctx, &addrs, &dscps,
01160                                                           &keynames, addrcount);
01161                         else
01162                                 INSIST(addrs == NULL && dscps == NULL &&
01163                                        keynames == NULL);
01164                         RETERR(result);
01165                 } else
01166                         RETERR(dns_zone_setalsonotify(zone, NULL, 0));
01167 
01168                 obj = NULL;
01169                 result = ns_config_get(maps, "notify-source", &obj);
01170                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01171                 RETERR(dns_zone_setnotifysrc4(zone, cfg_obj_assockaddr(obj)));
01172                 dscp = cfg_obj_getdscp(obj);
01173                 if (dscp == -1)
01174                         dscp = ns_g_dscp;
01175                 RETERR(dns_zone_setnotifysrc4dscp(zone, dscp));
01176                 ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
01177 
01178                 obj = NULL;
01179                 result = ns_config_get(maps, "notify-source-v6", &obj);
01180                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01181                 RETERR(dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj)));
01182                 dscp = cfg_obj_getdscp(obj);
01183                 if (dscp == -1)
01184                         dscp = ns_g_dscp;
01185                 RETERR(dns_zone_setnotifysrc6dscp(zone, dscp));
01186                 ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
01187 
01188                 obj = NULL;
01189                 result = ns_config_get(maps, "notify-to-soa", &obj);
01190                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01191                 dns_zone_setoption(zone, DNS_ZONEOPT_NOTIFYTOSOA,
01192                                    cfg_obj_asboolean(obj));
01193 
01194                 dns_zone_setisself(zone, ns_client_isself, NULL);
01195 
01196                 RETERR(configure_zone_acl(zconfig, vconfig, config,
01197                                           allow_transfer, ac, zone,
01198                                           dns_zone_setxfracl,
01199                                           dns_zone_clearxfracl));
01200 
01201                 obj = NULL;
01202                 result = ns_config_get(maps, "max-transfer-time-out", &obj);
01203                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01204                 dns_zone_setmaxxfrout(zone, cfg_obj_asuint32(obj) * 60);
01205 
01206                 obj = NULL;
01207                 result = ns_config_get(maps, "max-transfer-idle-out", &obj);
01208                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01209                 dns_zone_setidleout(zone, cfg_obj_asuint32(obj) * 60);
01210 
01211                 obj = NULL;
01212                 result = ns_config_get(maps, "max-journal-size", &obj);
01213                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01214                 if (raw != NULL)
01215                         dns_zone_setjournalsize(raw, -1);
01216                 dns_zone_setjournalsize(zone, -1);
01217                 if (cfg_obj_isstring(obj)) {
01218                         const char *str = cfg_obj_asstring(obj);
01219                         INSIST(strcasecmp(str, "unlimited") == 0);
01220                         journal_size = ISC_UINT32_MAX / 2;
01221                 } else {
01222                         isc_resourcevalue_t value;
01223                         value = cfg_obj_asuint64(obj);
01224                         if (value > ISC_UINT32_MAX / 2) {
01225                                 cfg_obj_log(obj, ns_g_lctx,
01226                                             ISC_LOG_ERROR,
01227                                             "'max-journal-size "
01228                                             "%" ISC_PRINT_QUADFORMAT "d' "
01229                                             "is too large",
01230                                             value);
01231                                 RETERR(ISC_R_RANGE);
01232                         }
01233                         journal_size = (isc_uint32_t)value;
01234                 }
01235                 if (raw != NULL)
01236                         dns_zone_setjournalsize(raw, journal_size);
01237                 dns_zone_setjournalsize(zone, journal_size);
01238 
01239                 obj = NULL;
01240                 result = ns_config_get(maps, "ixfr-from-differences", &obj);
01241                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01242                 if (cfg_obj_isboolean(obj))
01243                         ixfrdiff = cfg_obj_asboolean(obj);
01244                 else if (!strcasecmp(cfg_obj_asstring(obj), "master") &&
01245                          ztype == dns_zone_master)
01246                         ixfrdiff = ISC_TRUE;
01247                 else if (!strcasecmp(cfg_obj_asstring(obj), "slave") &&
01248                         ztype == dns_zone_slave)
01249                         ixfrdiff = ISC_TRUE;
01250                 else
01251                         ixfrdiff = ISC_FALSE;
01252                 if (raw != NULL) {
01253                         dns_zone_setoption(raw, DNS_ZONEOPT_IXFRFROMDIFFS,
01254                                            ISC_TRUE);
01255                         dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS,
01256                                            ISC_TRUE);
01257                 } else
01258                         dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS,
01259                                            ixfrdiff);
01260 
01261                 obj = NULL;
01262                 result = ns_config_get(maps, "request-expire", &obj);
01263                 INSIST(result == ISC_R_SUCCESS);
01264                 dns_zone_setrequestexpire(zone, cfg_obj_asboolean(obj));
01265 
01266                 obj = NULL;
01267                 result = ns_config_get(maps, "request-ixfr", &obj);
01268                 INSIST(result == ISC_R_SUCCESS);
01269                 dns_zone_setrequestixfr(zone, cfg_obj_asboolean(obj));
01270 
01271                 checknames(ztype, maps, &obj);
01272                 INSIST(obj != NULL);
01273                 if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
01274                         fail = ISC_FALSE;
01275                         check = ISC_TRUE;
01276                 } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
01277                         fail = check = ISC_TRUE;
01278                 } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
01279                         fail = check = ISC_FALSE;
01280                 } else
01281                         INSIST(0);
01282                 if (raw != NULL) {
01283                         dns_zone_setoption(raw, DNS_ZONEOPT_CHECKNAMES,
01284                                            check);
01285                         dns_zone_setoption(raw, DNS_ZONEOPT_CHECKNAMESFAIL,
01286                                            fail);
01287                         dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES,
01288                                            ISC_FALSE);
01289                         dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL,
01290                                            ISC_FALSE);
01291                 } else {
01292                         dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES,
01293                                            check);
01294                         dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL,
01295                                            fail);
01296                 }
01297 
01298                 obj = NULL;
01299                 result = ns_config_get(maps, "notify-delay", &obj);
01300                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01301                 dns_zone_setnotifydelay(zone, cfg_obj_asuint32(obj));
01302 
01303                 obj = NULL;
01304                 result = ns_config_get(maps, "check-sibling", &obj);
01305                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01306                 dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSIBLING,
01307                                    cfg_obj_asboolean(obj));
01308 
01309                 obj = NULL;
01310                 result = ns_config_get(maps, "check-spf", &obj);
01311                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01312                 if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
01313                         check = ISC_TRUE;
01314                 } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
01315                         check = ISC_FALSE;
01316                 } else
01317                         INSIST(0);
01318                 dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSPF, check);
01319 
01320                 obj = NULL;
01321                 result = ns_config_get(maps, "zero-no-soa-ttl", &obj);
01322                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01323                 dns_zone_setzeronosoattl(zone, cfg_obj_asboolean(obj));
01324 
01325                 obj = NULL;
01326                 result = ns_config_get(maps, "nsec3-test-zone", &obj);
01327                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01328                 dns_zone_setoption(zone, DNS_ZONEOPT_NSEC3TESTZONE,
01329                                    cfg_obj_asboolean(obj));
01330         } else if (ztype == dns_zone_redirect) {
01331                 dns_zone_setnotifytype(zone, dns_notifytype_no);
01332 
01333                 obj = NULL;
01334                 result = ns_config_get(maps, "max-journal-size", &obj);
01335                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01336                 dns_zone_setjournalsize(zone, -1);
01337                 if (cfg_obj_isstring(obj)) {
01338                         const char *str = cfg_obj_asstring(obj);
01339                         INSIST(strcasecmp(str, "unlimited") == 0);
01340                         journal_size = ISC_UINT32_MAX / 2;
01341                 } else {
01342                         isc_resourcevalue_t value;
01343                         value = cfg_obj_asuint64(obj);
01344                         if (value > ISC_UINT32_MAX / 2) {
01345                                 cfg_obj_log(obj, ns_g_lctx,
01346                                             ISC_LOG_ERROR,
01347                                             "'max-journal-size "
01348                                             "%" ISC_PRINT_QUADFORMAT "d' "
01349                                             "is too large",
01350                                             value);
01351                                 RETERR(ISC_R_RANGE);
01352                         }
01353                         journal_size = (isc_uint32_t)value;
01354                 }
01355                 dns_zone_setjournalsize(zone, journal_size);
01356         }
01357 
01358         /*
01359          * Configure update-related options.  These apply to
01360          * primary masters only.
01361          */
01362         if (ztype == dns_zone_master) {
01363                 dns_acl_t *updateacl;
01364 
01365                 RETERR(configure_zone_acl(zconfig, vconfig, config,
01366                                           allow_update, ac, mayberaw,
01367                                           dns_zone_setupdateacl,
01368                                           dns_zone_clearupdateacl));
01369 
01370                 updateacl = dns_zone_getupdateacl(mayberaw);
01371                 if (updateacl != NULL  && dns_acl_isinsecure(updateacl))
01372                         isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY,
01373                                       NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
01374                                       "zone '%s' allows updates by IP "
01375                                       "address, which is insecure",
01376                                       zname);
01377 
01378                 RETERR(configure_zone_ssutable(zoptions, mayberaw, zname));
01379         }
01380 
01381         if (ztype == dns_zone_master || raw != NULL) {
01382                 isc_boolean_t allow = ISC_FALSE, maint = ISC_FALSE;
01383 
01384                 obj = NULL;
01385                 result = ns_config_get(maps, "sig-validity-interval", &obj);
01386                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01387                 {
01388                         const cfg_obj_t *validity, *resign;
01389 
01390                         validity = cfg_tuple_get(obj, "validity");
01391                         seconds = cfg_obj_asuint32(validity) * 86400;
01392                         dns_zone_setsigvalidityinterval(zone, seconds);
01393 
01394                         resign = cfg_tuple_get(obj, "re-sign");
01395                         if (cfg_obj_isvoid(resign)) {
01396                                 seconds /= 4;
01397                         } else {
01398                                 if (seconds > 7 * 86400)
01399                                         seconds = cfg_obj_asuint32(resign) *
01400                                                         86400;
01401                                 else
01402                                         seconds = cfg_obj_asuint32(resign) *
01403                                                         3600;
01404                         }
01405                         dns_zone_setsigresigninginterval(zone, seconds);
01406                 }
01407 
01408                 obj = NULL;
01409                 result = ns_config_get(maps, "key-directory", &obj);
01410                 if (result == ISC_R_SUCCESS) {
01411                         filename = cfg_obj_asstring(obj);
01412                         RETERR(dns_zone_setkeydirectory(zone, filename));
01413                 }
01414 
01415                 obj = NULL;
01416                 result = ns_config_get(maps, "sig-signing-signatures", &obj);
01417                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01418                 dns_zone_setsignatures(zone, cfg_obj_asuint32(obj));
01419 
01420                 obj = NULL;
01421                 result = ns_config_get(maps, "sig-signing-nodes", &obj);
01422                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01423                 dns_zone_setnodes(zone, cfg_obj_asuint32(obj));
01424 
01425                 obj = NULL;
01426                 result = ns_config_get(maps, "sig-signing-type", &obj);
01427                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01428                 dns_zone_setprivatetype(zone, cfg_obj_asuint32(obj));
01429 
01430                 obj = NULL;
01431                 result = ns_config_get(maps, "update-check-ksk", &obj);
01432                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01433                 dns_zone_setoption(zone, DNS_ZONEOPT_UPDATECHECKKSK,
01434                                    cfg_obj_asboolean(obj));
01435 
01436                 obj = NULL;
01437                 result = ns_config_get(maps, "dnssec-dnskey-kskonly", &obj);
01438                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01439                 dns_zone_setoption(zone, DNS_ZONEOPT_DNSKEYKSKONLY,
01440                                    cfg_obj_asboolean(obj));
01441 
01442                 obj = NULL;
01443                 result = ns_config_get(maps, "dnssec-loadkeys-interval", &obj);
01444                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01445                 RETERR(dns_zone_setrefreshkeyinterval(zone,
01446                                                       cfg_obj_asuint32(obj)));
01447 
01448                 obj = NULL;
01449                 result = cfg_map_get(zoptions, "auto-dnssec", &obj);
01450                 if (result == ISC_R_SUCCESS) {
01451                         const char *arg = cfg_obj_asstring(obj);
01452                         if (strcasecmp(arg, "allow") == 0)
01453                                 allow = ISC_TRUE;
01454                         else if (strcasecmp(arg, "maintain") == 0)
01455                                 allow = maint = ISC_TRUE;
01456                         else if (strcasecmp(arg, "off") == 0)
01457                                 ;
01458                         else
01459                                 INSIST(0);
01460                         dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, allow);
01461                         dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, maint);
01462                 }
01463         }
01464 
01465         if (ztype == dns_zone_slave) {
01466                 RETERR(configure_zone_acl(zconfig, vconfig, config,
01467                                           allow_update_forwarding, ac,
01468                                           mayberaw, dns_zone_setforwardacl,
01469                                           dns_zone_clearforwardacl));
01470         }
01471 
01472         /*%
01473          * Primary master functionality.
01474          */
01475         if (ztype == dns_zone_master) {
01476                 obj = NULL;
01477                 result = ns_config_get(maps, "check-wildcard", &obj);
01478                 if (result == ISC_R_SUCCESS)
01479                         check = cfg_obj_asboolean(obj);
01480                 else
01481                         check = ISC_FALSE;
01482                 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKWILDCARD, check);
01483 
01484                 /*
01485                  * With map files, the default is ignore duplicate
01486                  * records.  With other master formats, the default is
01487                  * taken from the global configuration.
01488                  */
01489                 obj = NULL;
01490                 if (masterformat != dns_masterformat_map) {
01491                         result = ns_config_get(maps, "check-dup-records", &obj);
01492                         INSIST(result == ISC_R_SUCCESS && obj != NULL);
01493                         dupcheck = cfg_obj_asstring(obj);
01494                 } else {
01495                         result = ns_config_get(nodefault, "check-dup-records",
01496                                                &obj);
01497                         if (result == ISC_R_SUCCESS)
01498                                 dupcheck = cfg_obj_asstring(obj);
01499                         else
01500                                 dupcheck = "ignore";
01501 
01502                 }
01503                 if (strcasecmp(dupcheck, "warn") == 0) {
01504                         fail = ISC_FALSE;
01505                         check = ISC_TRUE;
01506                 } else if (strcasecmp(dupcheck, "fail") == 0) {
01507                         fail = check = ISC_TRUE;
01508                 } else if (strcasecmp(dupcheck, "ignore") == 0) {
01509                         fail = check = ISC_FALSE;
01510                 } else
01511                         INSIST(0);
01512                 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKDUPRR, check);
01513                 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKDUPRRFAIL, fail);
01514 
01515                 obj = NULL;
01516                 result = ns_config_get(maps, "check-mx", &obj);
01517                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01518                 if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
01519                         fail = ISC_FALSE;
01520                         check = ISC_TRUE;
01521                 } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
01522                         fail = check = ISC_TRUE;
01523                 } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
01524                         fail = check = ISC_FALSE;
01525                 } else
01526                         INSIST(0);
01527                 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKMX, check);
01528                 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKMXFAIL, fail);
01529 
01530                 /*
01531                  * With map files, the default is *not* to check
01532                  * integrity.  With other master formats, the default is
01533                  * taken from the global configuration.
01534                  */
01535                 obj = NULL;
01536                 if (masterformat != dns_masterformat_map) {
01537                         result = ns_config_get(maps, "check-integrity", &obj);
01538                         INSIST(result == ISC_R_SUCCESS && obj != NULL);
01539                         dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKINTEGRITY,
01540                                            cfg_obj_asboolean(obj));
01541                 } else {
01542                         check = ISC_FALSE;
01543                         result = ns_config_get(nodefault, "check-integrity",
01544                                                &obj);
01545                         if (result == ISC_R_SUCCESS)
01546                                 check = cfg_obj_asboolean(obj);
01547                         dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKINTEGRITY,
01548                                            check);
01549                 }
01550 
01551                 obj = NULL;
01552                 result = ns_config_get(maps, "check-mx-cname", &obj);
01553                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01554                 if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
01555                         warn = ISC_TRUE;
01556                         ignore = ISC_FALSE;
01557                 } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
01558                         warn = ignore = ISC_FALSE;
01559                 } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
01560                         warn = ignore = ISC_TRUE;
01561                 } else
01562                         INSIST(0);
01563                 dns_zone_setoption(mayberaw, DNS_ZONEOPT_WARNMXCNAME, warn);
01564                 dns_zone_setoption(mayberaw, DNS_ZONEOPT_IGNOREMXCNAME, ignore);
01565 
01566                 obj = NULL;
01567                 result = ns_config_get(maps, "check-srv-cname", &obj);
01568                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01569                 if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
01570                         warn = ISC_TRUE;
01571                         ignore = ISC_FALSE;
01572                 } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
01573                         warn = ignore = ISC_FALSE;
01574                 } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
01575                         warn = ignore = ISC_TRUE;
01576                 } else
01577                         INSIST(0);
01578                 dns_zone_setoption(mayberaw, DNS_ZONEOPT_WARNSRVCNAME, warn);
01579                 dns_zone_setoption(mayberaw, DNS_ZONEOPT_IGNORESRVCNAME,
01580                                    ignore);
01581 
01582                 obj = NULL;
01583                 result = ns_config_get(maps, "dnssec-secure-to-insecure", &obj);
01584                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01585                 dns_zone_setoption(mayberaw, DNS_ZONEOPT_SECURETOINSECURE,
01586                                    cfg_obj_asboolean(obj));
01587 
01588                 obj = NULL;
01589                 result = cfg_map_get(zoptions, "dnssec-update-mode", &obj);
01590                 if (result == ISC_R_SUCCESS) {
01591                         const char *arg = cfg_obj_asstring(obj);
01592                         if (strcasecmp(arg, "no-resign") == 0)
01593                                 dns_zone_setkeyopt(zone, DNS_ZONEKEY_NORESIGN,
01594                                                    ISC_TRUE);
01595                         else if (strcasecmp(arg, "maintain") == 0)
01596                                 ;
01597                         else
01598                                 INSIST(0);
01599                 }
01600 
01601                 obj = NULL;
01602                 result = ns_config_get(maps, "serial-update-method", &obj);
01603                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01604                 if (strcasecmp(cfg_obj_asstring(obj), "unixtime") == 0)
01605                         dns_zone_setserialupdatemethod(zone,
01606                                                     dns_updatemethod_unixtime);
01607                 else if (strcasecmp(cfg_obj_asstring(obj), "date") == 0)
01608                         dns_zone_setserialupdatemethod(zone,
01609                                                        dns_updatemethod_date);
01610                 else
01611                         dns_zone_setserialupdatemethod(zone,
01612                                                   dns_updatemethod_increment);
01613         }
01614 
01615         /*
01616          * Configure slave functionality.
01617          */
01618         switch (ztype) {
01619         case dns_zone_slave:
01620         case dns_zone_stub:
01621         case dns_zone_redirect:
01622                 count = 0;
01623                 obj = NULL;
01624                 (void)cfg_map_get(zoptions, "masters", &obj);
01625                 if (obj != NULL) {
01626                         addrs = NULL;
01627                         dscps = NULL;
01628                         keynames = NULL;
01629                         RETERR(ns_config_getipandkeylist(config, obj, mctx,
01630                                                          &addrs, &dscps,
01631                                                          &keynames, &count));
01632                         result = dns_zone_setmasterswithkeys(mayberaw, addrs,
01633                                                              keynames, count);
01634                         if (count != 0)
01635                                 ns_config_putipandkeylist(mctx, &addrs, &dscps,
01636                                                           &keynames, count);
01637                         else
01638                                 INSIST(addrs == NULL && keynames == NULL);
01639                 } else
01640                         result = dns_zone_setmasters(mayberaw, NULL, 0);
01641                 RETERR(result);
01642 
01643                 multi = ISC_FALSE;
01644                 if (count > 1) {
01645                         obj = NULL;
01646                         result = ns_config_get(maps, "multi-master", &obj);
01647                         INSIST(result == ISC_R_SUCCESS && obj != NULL);
01648                         multi = cfg_obj_asboolean(obj);
01649                 }
01650                 dns_zone_setoption(mayberaw, DNS_ZONEOPT_MULTIMASTER, multi);
01651 
01652                 obj = NULL;
01653                 result = ns_config_get(maps, "max-transfer-time-in", &obj);
01654                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01655                 dns_zone_setmaxxfrin(mayberaw, cfg_obj_asuint32(obj) * 60);
01656 
01657                 obj = NULL;
01658                 result = ns_config_get(maps, "max-transfer-idle-in", &obj);
01659                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01660                 dns_zone_setidlein(mayberaw, cfg_obj_asuint32(obj) * 60);
01661 
01662                 obj = NULL;
01663                 result = ns_config_get(maps, "max-refresh-time", &obj);
01664                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01665                 dns_zone_setmaxrefreshtime(mayberaw, cfg_obj_asuint32(obj));
01666 
01667                 obj = NULL;
01668                 result = ns_config_get(maps, "min-refresh-time", &obj);
01669                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01670                 dns_zone_setminrefreshtime(mayberaw, cfg_obj_asuint32(obj));
01671 
01672                 obj = NULL;
01673                 result = ns_config_get(maps, "max-retry-time", &obj);
01674                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01675                 dns_zone_setmaxretrytime(mayberaw, cfg_obj_asuint32(obj));
01676 
01677                 obj = NULL;
01678                 result = ns_config_get(maps, "min-retry-time", &obj);
01679                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01680                 dns_zone_setminretrytime(mayberaw, cfg_obj_asuint32(obj));
01681 
01682                 obj = NULL;
01683                 result = ns_config_get(maps, "transfer-source", &obj);
01684                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01685                 RETERR(dns_zone_setxfrsource4(mayberaw,
01686                                               cfg_obj_assockaddr(obj)));
01687                 dscp = cfg_obj_getdscp(obj);
01688                 if (dscp == -1)
01689                         dscp = ns_g_dscp;
01690                 RETERR(dns_zone_setxfrsource4dscp(mayberaw, dscp));
01691                 ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
01692 
01693                 obj = NULL;
01694                 result = ns_config_get(maps, "transfer-source-v6", &obj);
01695                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01696                 RETERR(dns_zone_setxfrsource6(mayberaw,
01697                                               cfg_obj_assockaddr(obj)));
01698                 dscp = cfg_obj_getdscp(obj);
01699                 if (dscp == -1)
01700                         dscp = ns_g_dscp;
01701                 RETERR(dns_zone_setxfrsource6dscp(mayberaw, dscp));
01702                 ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
01703 
01704                 obj = NULL;
01705                 result = ns_config_get(maps, "alt-transfer-source", &obj);
01706                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01707                 RETERR(dns_zone_setaltxfrsource4(mayberaw,
01708                                                  cfg_obj_assockaddr(obj)));
01709                 dscp = cfg_obj_getdscp(obj);
01710                 if (dscp == -1)
01711                         dscp = ns_g_dscp;
01712                 RETERR(dns_zone_setaltxfrsource4dscp(mayberaw, dscp));
01713 
01714                 obj = NULL;
01715                 result = ns_config_get(maps, "alt-transfer-source-v6", &obj);
01716                 INSIST(result == ISC_R_SUCCESS && obj != NULL);
01717                 RETERR(dns_zone_setaltxfrsource6(mayberaw,
01718                                                  cfg_obj_assockaddr(obj)));
01719                 dscp = cfg_obj_getdscp(obj);
01720                 if (dscp == -1)
01721                         dscp = ns_g_dscp;
01722                 RETERR(dns_zone_setaltxfrsource6dscp(mayberaw, dscp));
01723 
01724                 obj = NULL;
01725                 (void)ns_config_get(maps, "use-alt-transfer-source", &obj);
01726                 if (obj == NULL) {
01727                         /*
01728                          * Default off when views are in use otherwise
01729                          * on for BIND 8 compatibility.
01730                          */
01731                         view = dns_zone_getview(zone);
01732                         if (view != NULL && strcmp(view->name, "_default") == 0)
01733                                 alt = ISC_TRUE;
01734                         else
01735                                 alt = ISC_FALSE;
01736                 } else
01737                         alt = cfg_obj_asboolean(obj);
01738                 dns_zone_setoption(mayberaw, DNS_ZONEOPT_USEALTXFRSRC, alt);
01739 
01740                 obj = NULL;
01741                 (void)ns_config_get(maps, "try-tcp-refresh", &obj);
01742                 dns_zone_setoption(mayberaw, DNS_ZONEOPT_TRYTCPREFRESH,
01743                                    cfg_obj_asboolean(obj));
01744                 break;
01745 
01746         case dns_zone_staticstub:
01747                 RETERR(configure_staticstub(zoptions, zone, zname,
01748                                             default_dbtype));
01749                 break;
01750 
01751         default:
01752                 break;
01753         }
01754 
01755         return (ISC_R_SUCCESS);
01756 }
01757 
01758 
01759 /*
01760  * Set up a DLZ zone as writeable
01761  */
01762 isc_result_t
01763 ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone,
01764                                 dns_rdataclass_t rdclass, dns_name_t *name)
01765 {
01766         dns_db_t *db = NULL;
01767         isc_time_t now;
01768         isc_result_t result;
01769 
01770         TIME_NOW(&now);
01771 
01772         dns_zone_settype(zone, dns_zone_dlz);
01773         result = dns_sdlz_setdb(dlzdatabase, rdclass, name, &db);
01774         if (result != ISC_R_SUCCESS)
01775                 return (result);
01776         result = dns_zone_dlzpostload(zone, db);
01777         dns_db_detach(&db);
01778         return (result);
01779 }
01780 
01781 isc_boolean_t
01782 ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) {
01783         const cfg_obj_t *zoptions = NULL;
01784         const cfg_obj_t *obj = NULL;
01785         const char *cfilename;
01786         const char *zfilename;
01787         dns_zone_t *raw = NULL;
01788         isc_boolean_t has_raw;
01789         dns_zonetype_t ztype;
01790 
01791         zoptions = cfg_tuple_get(zconfig, "options");
01792 
01793         /*
01794          * We always reconfigure a static-stub zone for simplicity, assuming
01795          * the amount of data to be loaded is small.
01796          */
01797         if (zonetype_fromconfig(zoptions) == dns_zone_staticstub) {
01798                 dns_zone_log(zone, ISC_LOG_DEBUG(1),
01799                              "not reusable: staticstub");
01800                 return (ISC_FALSE);
01801         }
01802 
01803         /* If there's a raw zone, use that for filename and type comparison */
01804         dns_zone_getraw(zone, &raw);
01805         if (raw != NULL) {
01806                 zfilename = dns_zone_getfile(raw);
01807                 ztype = dns_zone_gettype(raw);
01808                 dns_zone_detach(&raw);
01809                 has_raw = ISC_TRUE;
01810         } else {
01811                 zfilename = dns_zone_getfile(zone);
01812                 ztype = dns_zone_gettype(zone);
01813                 has_raw = ISC_FALSE;
01814         }
01815 
01816         obj = NULL;
01817         (void)cfg_map_get(zoptions, "inline-signing", &obj);
01818         if ((obj == NULL || !cfg_obj_asboolean(obj)) && has_raw) {
01819                 dns_zone_log(zone, ISC_LOG_DEBUG(1),
01820                              "not reusable: old zone was inline-signing");
01821                 return (ISC_FALSE);
01822         } else if ((obj != NULL && cfg_obj_asboolean(obj)) && !has_raw) {
01823                 dns_zone_log(zone, ISC_LOG_DEBUG(1),
01824                              "not reusable: old zone was not inline-signing");
01825                 return (ISC_FALSE);
01826         }
01827 
01828         if (zonetype_fromconfig(zoptions) != ztype) {
01829                 dns_zone_log(zone, ISC_LOG_DEBUG(1),
01830                              "not reusable: type mismatch");
01831                 return (ISC_FALSE);
01832         }
01833 
01834         obj = NULL;
01835         (void)cfg_map_get(zoptions, "file", &obj);
01836         if (obj != NULL)
01837                 cfilename = cfg_obj_asstring(obj);
01838         else
01839                 cfilename = NULL;
01840         if (!((cfilename == NULL && zfilename == NULL) ||
01841               (cfilename != NULL && zfilename != NULL &&
01842                strcmp(cfilename, zfilename) == 0)))
01843         {
01844                 dns_zone_log(zone, ISC_LOG_DEBUG(1),
01845                              "not reusable: filename mismatch");
01846                 return (ISC_FALSE);
01847         }
01848 
01849         return (ISC_TRUE);
01850 }

Generated on Tue Apr 28 17:40:55 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha