LCOV - code coverage report
Current view: top level - source4/rpc_server/dnsserver - dnsutils.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 185 236 78.4 %
Date: 2024-05-31 13:13:24 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    DNS Server
       5             : 
       6             :    Copyright (C) Amitay Isaacs 2011
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "dnsserver.h"
      24             : #include "rpc_server/common/common.h"
      25             : #include "dns_server/dnsserver_common.h"
      26             : #include "dsdb/samdb/samdb.h"
      27             : #include "lib/socket/netif.h"
      28             : #include "lib/util/util_net.h"
      29             : #include "dnsserver_common.h"
      30             : 
      31             : #undef strcasecmp
      32             : 
      33        1531 : static struct DNS_ADDR_ARRAY *fill_dns_addr_array(TALLOC_CTX *mem_ctx,
      34             :                                            struct loadparm_context *lp_ctx,
      35             :                                            bool listen_only)
      36             : {
      37           0 :         struct interface *ifaces;
      38           0 :         int num_interfaces, i;
      39           0 :         struct DNS_ADDR_ARRAY *dns_addr_array;
      40           0 :         const char *ipstr;
      41           0 :         bool have_ipv4, have_ipv6;
      42           0 :         uint16_t family;
      43             : 
      44        1531 :         have_ipv4 = have_ipv6 = false;
      45             : 
      46        1531 :         if (!listen_only) {
      47             :                 /*
      48             :                   Return all interfaces from kernel
      49             :                   Not implemented!
      50             :                 */
      51           0 :                 return NULL;
      52             :         }
      53             : 
      54             :         /* Only the used interfaces */
      55        1531 :         load_interface_list(mem_ctx, lp_ctx, &ifaces);
      56        1531 :         num_interfaces = iface_list_count(ifaces);
      57             : 
      58        1531 :         dns_addr_array = talloc_zero(mem_ctx, struct DNS_ADDR_ARRAY);
      59        1531 :         if (dns_addr_array == NULL) {
      60           0 :                 goto nomem;
      61             :         }
      62        1531 :         dns_addr_array->MaxCount = num_interfaces;
      63        1531 :         dns_addr_array->AddrCount = num_interfaces;
      64        1531 :         if (num_interfaces == 0) {
      65           0 :                 goto nomem;
      66             :         }
      67             : 
      68        1531 :         dns_addr_array->AddrArray = talloc_zero_array(mem_ctx, struct DNS_ADDR,
      69             :                                                       num_interfaces);
      70        1531 :         if (!dns_addr_array->AddrArray) {
      71           0 :                 TALLOC_FREE(dns_addr_array);
      72           0 :                 goto nomem;
      73             :         }
      74             : 
      75        4593 :         for (i = 0; i < num_interfaces; i++) {
      76           0 :                 int ret;
      77        3062 :                 ipstr = iface_list_n_ip(ifaces, i);
      78        3062 :                 if (is_ipaddress_v4(ipstr)) {
      79        1531 :                         have_ipv4 = true;
      80        1531 :                         dns_addr_array->AddrArray[i].MaxSa[0] = 0x02;
      81        1531 :                         ret = inet_pton(AF_INET, ipstr,
      82        1531 :                                         &dns_addr_array->AddrArray[i].MaxSa[4]);
      83             :                 } else {
      84        1531 :                         have_ipv6 = true;
      85        1531 :                         dns_addr_array->AddrArray[i].MaxSa[0] = 0x17;
      86        1531 :                         ret = inet_pton(AF_INET6, ipstr,
      87        1531 :                                         &dns_addr_array->AddrArray[i].MaxSa[8]);
      88             :                 }
      89        3062 :                 if (ret != 1) { /*yep, 1 means success for inet_pton */
      90           0 :                         DBG_ERR("Interface %d address (%s) is invalid\n",
      91             :                                 i, ipstr);
      92           0 :                         goto nomem;
      93             :                 }
      94             :         }
      95             : 
      96        1531 :         if (have_ipv4 && have_ipv6) {
      97        1531 :                 family = 0;   /* mixed: MS-DNSP */
      98           0 :         } else if (have_ipv4 && !have_ipv6) {
      99           0 :                 family = AF_INET;
     100             :         } else {
     101           0 :                 family = AF_INET6;
     102             :         }
     103        1531 :         dns_addr_array->Family = family;
     104             : 
     105        1531 : nomem:
     106        1531 :         talloc_free(ifaces);
     107        1531 :         return dns_addr_array;
     108             : }
     109             : 
     110        1531 : struct dnsserver_serverinfo *dnsserver_init_serverinfo(TALLOC_CTX *mem_ctx,
     111             :                                                         struct loadparm_context *lp_ctx,
     112             :                                                         struct ldb_context *samdb)
     113             : {
     114           0 :         struct dnsserver_serverinfo *serverinfo;
     115           0 :         struct dcerpc_server_info *dinfo;
     116           0 :         struct ldb_dn *domain_dn, *forest_dn;
     117        1531 :         const char *dns_hostname = NULL;
     118             : 
     119        1531 :         serverinfo = talloc_zero(mem_ctx, struct dnsserver_serverinfo);
     120        1531 :         if (serverinfo == NULL) {
     121           0 :                 return NULL;
     122             :         }
     123             : 
     124        1531 :         dinfo = lpcfg_dcerpc_server_info(mem_ctx, lp_ctx);
     125        1531 :         if (dinfo) {
     126        1531 :                 serverinfo->dwVersion = (dinfo->version_build & 0x0000FFFF) << 16 |
     127        1531 :                                 (dinfo->version_minor & 0x000000FF) << 8 |
     128        1531 :                                 (dinfo->version_major & 0x000000FF);
     129        1531 :                 talloc_free(dinfo);
     130             :         } else {
     131           0 :                 serverinfo->dwVersion = 0x0ECE0205; /* build, os_minor, os_major */;
     132             :         }
     133             : 
     134        1531 :         serverinfo->fBootMethod = DNS_BOOT_METHOD_DIRECTORY;
     135        1531 :         serverinfo->fAdminConfigured = 0;
     136        1531 :         serverinfo->fAllowUpdate = 1;
     137        1531 :         serverinfo->fDsAvailable = 1;
     138             : 
     139        1531 :         dns_hostname = lpcfg_dns_hostname(lp_ctx);
     140        1531 :         if (dns_hostname == NULL) {
     141           0 :                 TALLOC_FREE(serverinfo);
     142           0 :                 return NULL;
     143             :         }
     144        1531 :         serverinfo->pszServerName = discard_const_p(char, dns_hostname);
     145             : 
     146        1531 :         domain_dn = ldb_get_default_basedn(samdb);
     147        1531 :         forest_dn = ldb_get_root_basedn(samdb);
     148             : 
     149        1531 :         serverinfo->pszDsContainer = talloc_asprintf(mem_ctx,
     150             :                                         "CN=MicrosoftDNS,DC=DomainDnsZones,%s",
     151             :                                         ldb_dn_get_linearized(domain_dn));
     152             : 
     153        1531 :         serverinfo->dwDsForestVersion = dsdb_forest_functional_level(samdb);
     154        1531 :         serverinfo->dwDsDomainVersion = dsdb_functional_level(samdb);
     155        1531 :         serverinfo->dwDsDsaVersion = dsdb_dc_functional_level(samdb);
     156             : 
     157        1531 :         serverinfo->pszDomainName = samdb_dn_to_dns_domain(mem_ctx, domain_dn);
     158        1531 :         serverinfo->pszForestName = samdb_dn_to_dns_domain(mem_ctx, forest_dn);
     159             : 
     160        1531 :         serverinfo->pszDomainDirectoryPartition = talloc_asprintf(mem_ctx,
     161             :                                                         "DC=DomainDnsZones,%s",
     162             :                                                         ldb_dn_get_linearized(domain_dn));
     163        1531 :         serverinfo->pszForestDirectoryPartition = talloc_asprintf(mem_ctx,
     164             :                                                         "DC=ForestDnsZones,%s",
     165             :                                                         ldb_dn_get_linearized(forest_dn));
     166             :         /* IP addresses on which the DNS server listens for DNS requests */
     167        1531 :         serverinfo->aipListenAddrs = fill_dns_addr_array(mem_ctx, lp_ctx, true);
     168             : 
     169             :         /* All IP addresses available on the server
     170             :          * Not implemented!
     171             :          * Use same as listen addresses
     172             :          */
     173        1531 :         serverinfo->aipServerAddrs = serverinfo->aipListenAddrs;
     174             : 
     175        1531 :         serverinfo->aipForwarders = NULL;
     176             : 
     177        1531 :         serverinfo->aipLogFilter = NULL;
     178        1531 :         serverinfo->pwszLogFilePath = NULL;
     179             : 
     180        1531 :         serverinfo->dwLogLevel = 0;
     181        1531 :         serverinfo->dwDebugLevel = 0;
     182        1531 :         serverinfo->dwEventLogLevel = DNS_EVENT_LOG_INFORMATION_TYPE;
     183        1531 :         serverinfo->dwLogFileMaxSize = 0;
     184             : 
     185        1531 :         serverinfo->dwForwardTimeout = 3; /* seconds (default) */
     186        1531 :         serverinfo->dwRpcProtocol = 5;
     187        1531 :         serverinfo->dwNameCheckFlag = DNS_ALLOW_MULTIBYTE_NAMES;
     188        1531 :         serverinfo->cAddressAnswerLimit = 0;
     189        1531 :         serverinfo->dwRecursionRetry = 3;       /* seconds (default) */
     190        1531 :         serverinfo->dwRecursionTimeout = 8;     /* seconds (default) */
     191        1531 :         serverinfo->dwMaxCacheTtl = 0x00015180; /* 1 day (default) */
     192        1531 :         serverinfo->dwDsPollingInterval = 0xB4; /* 3 minutes (default) */
     193        1531 :         serverinfo->dwLocalNetPriorityNetMask = 0x000000FF;
     194             : 
     195        1531 :         serverinfo->dwScavengingInterval = lpcfg_parm_int(
     196             :             lp_ctx, NULL, "dnsserver", "ScavengingInterval", 24 * 7);
     197        1531 :         serverinfo->dwDefaultRefreshInterval = lpcfg_parm_int(
     198             :             lp_ctx, NULL, "dnsserver", "DefaultRefreshInterval", 24 * 3);
     199        1531 :         serverinfo->dwDefaultNoRefreshInterval = lpcfg_parm_int(
     200             :             lp_ctx, NULL, "dnsserver", "DefaultNoRefreshInterval", 24 * 3);
     201             : 
     202        1531 :         serverinfo->dwLastScavengeTime = 0;
     203             : 
     204        1531 :         serverinfo->fAutoReverseZones = 0;
     205        1531 :         serverinfo->fAutoCacheUpdate = 0;
     206             : 
     207        1531 :         serverinfo->fRecurseAfterForwarding = 0;
     208        1531 :         serverinfo->fForwardDelegations = 1;
     209        1531 :         serverinfo->fNoRecursion = 0;
     210        1531 :         serverinfo->fSecureResponses = 0;
     211             : 
     212        1531 :         serverinfo->fRoundRobin = 1;
     213        1531 :         serverinfo->fLocalNetPriority = 0;
     214             : 
     215        1531 :         serverinfo->fBindSecondaries = 0;
     216        1531 :         serverinfo->fWriteAuthorityNs = 0;
     217             : 
     218        1531 :         serverinfo->fStrictFileParsing = 0;
     219        1531 :         serverinfo->fLooseWildcarding = 0 ;
     220        1531 :         serverinfo->fDefaultAgingState = 0;
     221             : 
     222        1531 :         return serverinfo;
     223             : }
     224             : 
     225        5820 : struct dnsserver_zoneinfo *dnsserver_init_zoneinfo(struct dnsserver_zone *zone,
     226             :                                                 struct dnsserver_serverinfo *serverinfo)
     227             : {
     228           4 :         struct dnsserver_zoneinfo *zoneinfo;
     229           4 :         uint32_t fReverse;
     230        5820 :         const char *revzone = "in-addr.arpa";
     231        5820 :         const char *revzone6 = "ip6.arpa";
     232           4 :         int len1, len2;
     233        5820 :         unsigned int i = 0;
     234             : 
     235        5820 :         zoneinfo = talloc_zero(zone, struct dnsserver_zoneinfo);
     236        5820 :         if (zoneinfo == NULL) {
     237           0 :                 return NULL;
     238             :         }
     239             : 
     240             :         /* If the zone name ends with in-addr.arpa, it's reverse zone */
     241             :         /* If the zone name ends with ip6.arpa, it's reverse zone (IPv6) */
     242        5820 :         fReverse = 0;
     243        5820 :         len1 = strlen(zone->name);
     244        5820 :         len2 = strlen(revzone);
     245        5820 :         if (len1 > len2 && strcasecmp(&zone->name[len1-len2], revzone) == 0) {
     246           3 :                 fReverse = 1;
     247             :         } else {
     248        5817 :                 len2 = strlen(revzone6);
     249        5817 :                 if (len1 > len2 && strcasecmp(&zone->name[len1-len2], revzone6) == 0) {
     250           0 :                         fReverse = 1;
     251             :                 }
     252             :         }
     253             : 
     254        5820 :         zoneinfo->Version = 0x32;
     255        5820 :         zoneinfo->Flags = DNS_RPC_ZONE_DSINTEGRATED;
     256             : 
     257        5820 :         if (strcmp(zone->name, ".") == 0) {
     258        1531 :                 zoneinfo->dwZoneType = DNS_ZONE_TYPE_CACHE;
     259        1531 :                 zoneinfo->fAllowUpdate = DNS_ZONE_UPDATE_OFF;
     260        1531 :                 zoneinfo->fSecureSecondaries = DNS_ZONE_SECSECURE_NO_SECURITY;
     261        1531 :                 zoneinfo->fNotifyLevel = DNS_ZONE_NOTIFY_OFF;
     262        1531 :                 zoneinfo->dwNoRefreshInterval = 0;
     263        1531 :                 zoneinfo->dwRefreshInterval = 0;
     264             :         } else {
     265        4289 :                 zoneinfo->Flags |= DNS_RPC_ZONE_UPDATE_SECURE;
     266        4289 :                 zoneinfo->dwZoneType = DNS_ZONE_TYPE_PRIMARY;
     267        4289 :                 zoneinfo->fAllowUpdate = DNS_ZONE_UPDATE_SECURE;
     268        4289 :                 zoneinfo->fSecureSecondaries = DNS_ZONE_SECSECURE_NO_XFER;
     269        4289 :                 zoneinfo->fNotifyLevel = DNS_ZONE_NOTIFY_LIST_ONLY;
     270        4289 :                 zoneinfo->dwNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
     271        4289 :                 zoneinfo->dwRefreshInterval = serverinfo->dwDefaultRefreshInterval;
     272             :         }
     273             : 
     274        5820 :         zoneinfo->fReverse = fReverse;
     275        5820 :         zoneinfo->fPaused = 0;
     276        5820 :         zoneinfo->fShutdown = 0;
     277        5820 :         zoneinfo->fAutoCreated = 0;
     278        5820 :         zoneinfo->fUseDatabase = 1;
     279        5820 :         zoneinfo->pszDataFile = NULL;
     280        5820 :         zoneinfo->aipMasters = NULL;
     281        5820 :         zoneinfo->aipSecondaries = NULL;
     282        5820 :         zoneinfo->aipNotify = NULL;
     283        5820 :         zoneinfo->fUseWins = 0;
     284        5820 :         zoneinfo->fUseNbstat = 0;
     285        5820 :         zoneinfo->fAging = 0;
     286        5820 :         zoneinfo->dwAvailForScavengeTime = 0;
     287        5820 :         zoneinfo->aipScavengeServers = NULL;
     288        5820 :         zoneinfo->dwForwarderTimeout = 0;
     289        5820 :         zoneinfo->fForwarderSlave = 0;
     290        5820 :         zoneinfo->aipLocalMasters = NULL;
     291        5820 :         zoneinfo->pwszZoneDn = discard_const_p(char, ldb_dn_get_linearized(zone->zone_dn));
     292        5820 :         zoneinfo->dwLastSuccessfulSoaCheck = 0;
     293        5820 :         zoneinfo->dwLastSuccessfulXfr = 0;
     294        5820 :         zoneinfo->fQueuedForBackgroundLoad = 0;
     295        5820 :         zoneinfo->fBackgroundLoadInProgress = 0;
     296        5820 :         zoneinfo->fReadOnlyZone = 0;
     297        5820 :         zoneinfo->dwLastXfrAttempt = 0;
     298        5820 :         zoneinfo->dwLastXfrResult = 0;
     299             : 
     300       35819 :         for(i=0; i<zone->num_props; i++){
     301           4 :                 bool valid_property;
     302       30003 :                 valid_property = dns_zoneinfo_load_zone_property(
     303       29999 :                     zoneinfo, &zone->tmp_props[i]);
     304       29999 :                 if (!valid_property) {
     305           0 :                         TALLOC_FREE(zoneinfo);
     306           0 :                         return NULL;
     307             :                 }
     308             :         }
     309             : 
     310        5816 :         return zoneinfo;
     311             : }
     312             : 
     313       15190 : struct dnsserver_zone *dnsserver_find_zone(struct dnsserver_zone *zones, const char *zone_name)
     314             : {
     315       15190 :         struct dnsserver_zone *z = NULL;
     316             : 
     317       34094 :         for (z = zones; z; z = z->next) {
     318       27827 :                 if (samba_dns_name_equal(zone_name, z->name)) {
     319        8923 :                         break;
     320             :                 }
     321             :         }
     322             : 
     323       15190 :         return z;
     324             : }
     325             : 
     326        1161 : struct ldb_dn *dnsserver_name_to_dn(TALLOC_CTX *mem_ctx, struct dnsserver_zone *z, const char *name)
     327             : {
     328           0 :         struct ldb_dn *dn;
     329           0 :         bool ret;
     330           0 :         struct ldb_val name_val =
     331        1161 :                 data_blob_string_const(name);
     332             : 
     333        1161 :         dn = ldb_dn_copy(mem_ctx, z->zone_dn);
     334        1161 :         if (dn == NULL) {
     335           0 :                 return NULL;
     336             :         }
     337        1161 :         if (strcasecmp(name, z->name) == 0) {
     338           0 :                 ret = ldb_dn_add_child_fmt(dn, "DC=@");
     339           0 :                 if (!ret) {
     340           0 :                         talloc_free(dn);
     341           0 :                         return NULL;
     342             :                 }
     343           0 :                 return dn;
     344             :         }
     345             : 
     346        1161 :         ret = ldb_dn_add_child_val(dn,
     347             :                                    "DC",
     348             :                                    name_val);
     349             : 
     350        1161 :         if (!ret) {
     351           0 :                 talloc_free(dn);
     352           0 :                 return NULL;
     353             :         }
     354             : 
     355        1161 :         return dn;
     356             : }
     357             : 
     358        1220 : uint32_t dnsserver_zone_to_request_filter(const char *zone_name)
     359             : {
     360        1220 :         uint32_t request_filter = 0;
     361             : 
     362        1220 :         if (strcmp(zone_name, "..AllZones") == 0) {
     363           0 :                 request_filter = DNS_ZONE_REQUEST_PRIMARY
     364             :                         | DNS_ZONE_REQUEST_SECONDARY
     365             :                         | DNS_ZONE_REQUEST_AUTO
     366             :                         | DNS_ZONE_REQUEST_FORWARD
     367             :                         | DNS_ZONE_REQUEST_REVERSE
     368             :                         | DNS_ZONE_REQUEST_FORWARDER
     369             :                         | DNS_ZONE_REQUEST_STUB
     370             :                         | DNS_ZONE_REQUEST_DS
     371             :                         | DNS_ZONE_REQUEST_NON_DS
     372             :                         | DNS_ZONE_REQUEST_DOMAIN_DP
     373             :                         | DNS_ZONE_REQUEST_FOREST_DP
     374             :                         | DNS_ZONE_REQUEST_CUSTOM_DP
     375             :                         | DNS_ZONE_REQUEST_LEGACY_DP;
     376        1220 :         } else if (strcmp(zone_name, "..AllZonesAndCache") == 0) {
     377           0 :                 request_filter = DNS_ZONE_REQUEST_PRIMARY
     378             :                         | DNS_ZONE_REQUEST_SECONDARY
     379             :                         | DNS_ZONE_REQUEST_CACHE
     380             :                         | DNS_ZONE_REQUEST_AUTO
     381             :                         | DNS_ZONE_REQUEST_FORWARD
     382             :                         | DNS_ZONE_REQUEST_REVERSE
     383             :                         | DNS_ZONE_REQUEST_FORWARDER
     384             :                         | DNS_ZONE_REQUEST_STUB
     385             :                         | DNS_ZONE_REQUEST_DS
     386             :                         | DNS_ZONE_REQUEST_NON_DS
     387             :                         | DNS_ZONE_REQUEST_DOMAIN_DP
     388             :                         | DNS_ZONE_REQUEST_FOREST_DP
     389             :                         | DNS_ZONE_REQUEST_CUSTOM_DP
     390             :                         | DNS_ZONE_REQUEST_LEGACY_DP;
     391        1220 :         } else if (strcmp(zone_name, "..AllPrimaryZones") == 0) {
     392           0 :                 request_filter = DNS_ZONE_REQUEST_PRIMARY;
     393        1220 :         } else if (strcmp(zone_name, "..AllSecondaryZones") == 0) {
     394           0 :                 request_filter = DNS_ZONE_REQUEST_SECONDARY;
     395        1220 :         } else if (strcmp(zone_name, "..AllForwardZones") == 0) {
     396           0 :                 request_filter = DNS_ZONE_REQUEST_FORWARD;
     397        1220 :         } else if (strcmp(zone_name, "..AllReverseZones") == 0) {
     398           0 :                 request_filter = DNS_ZONE_REQUEST_REVERSE;
     399        1220 :         } else if (strcmp(zone_name, "..AllDsZones") == 0) {
     400           0 :                 request_filter = DNS_ZONE_REQUEST_DS;
     401        1220 :         } else if (strcmp(zone_name, "..AllNonDsZones") == 0) {
     402           0 :                 request_filter = DNS_ZONE_REQUEST_NON_DS;
     403        1220 :         } else if (strcmp(zone_name, "..AllPrimaryReverseZones") == 0) {
     404           0 :                 request_filter = DNS_ZONE_REQUEST_PRIMARY
     405             :                         | DNS_ZONE_REQUEST_REVERSE;
     406        1220 :         } else if (strcmp(zone_name, "..AllPrimaryForwardZones") == 0) {
     407           0 :                 request_filter = DNS_ZONE_REQUEST_PRIMARY
     408             :                         | DNS_ZONE_REQUEST_FORWARD;
     409        1220 :         } else if (strcmp(zone_name, "..AllSecondaryReverseZones") == 0) {
     410           0 :                 request_filter = DNS_ZONE_REQUEST_SECONDARY
     411             :                         | DNS_ZONE_REQUEST_REVERSE;
     412        1220 :         } else if (strcmp(zone_name, "..AllSecondaryForwardZones") == 0) {
     413           0 :                 request_filter = DNS_ZONE_REQUEST_SECONDARY
     414             :                         | DNS_ZONE_REQUEST_REVERSE;
     415             :         }
     416             : 
     417        1220 :         return request_filter;
     418             : }

Generated by: LCOV version 1.14