diff options
Diffstat (limited to 'source4/rpc_server/dnsserver/dnsutils.c')
-rw-r--r-- | source4/rpc_server/dnsserver/dnsutils.c | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/source4/rpc_server/dnsserver/dnsutils.c b/source4/rpc_server/dnsserver/dnsutils.c new file mode 100644 index 0000000000..5449826061 --- /dev/null +++ b/source4/rpc_server/dnsserver/dnsutils.c @@ -0,0 +1,309 @@ +/* + Unix SMB/CIFS implementation. + + DNS Server + + Copyright (C) Amitay Isaacs 2011 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "dnsserver.h" +#include "rpc_server/common/common.h" +#include "dsdb/samdb/samdb.h" +#include "lib/socket/netif.h" + + +struct dnsserver_serverinfo *dnsserver_init_serverinfo(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + struct ldb_context *samdb) +{ + struct dnsserver_serverinfo *serverinfo; + struct dcerpc_server_info *dinfo; + struct ldb_dn *domain_dn, *forest_dn; + struct interface *ifaces; + int num_interfaces, i; + + serverinfo = talloc_zero(mem_ctx, struct dnsserver_serverinfo); + if (serverinfo == NULL) { + return NULL; + } + + dinfo = lpcfg_dcerpc_server_info(mem_ctx, lp_ctx); + if (dinfo) { + serverinfo->dwVersion = (dinfo->version_build & 0x0000FFFF) << 16 | + (dinfo->version_minor & 0x000000FF) << 8 | + (dinfo->version_major & 0x000000FF); + talloc_free(dinfo); + } else { + serverinfo->dwVersion = 0x0ECE0205; /* build, os_minor, os_major */; + } + + serverinfo->fBootMethod = DNS_BOOT_METHOD_DIRECTORY; + serverinfo->fAdminConfigured = 0; + serverinfo->fAllowUpdate = 1; + serverinfo->fDsAvailable = 1; + + serverinfo->pszServerName = talloc_asprintf(mem_ctx, "%s.%s", + lpcfg_netbios_name(lp_ctx), + lpcfg_dnsdomain(lp_ctx)); + + domain_dn = ldb_get_default_basedn(samdb); + forest_dn = ldb_get_root_basedn(samdb); + + serverinfo->pszDsContainer = talloc_asprintf(mem_ctx, + "CN=MicrosoftDNS,DC=DomainDnsZones,%s", + ldb_dn_get_linearized(domain_dn)); + + serverinfo->dwDsForestVersion = dsdb_forest_functional_level(samdb); + serverinfo->dwDsDomainVersion = dsdb_functional_level(samdb); + serverinfo->dwDsDsaVersion = 4; /* need to do ldb search here */ + + serverinfo->pszDomainName = samdb_dn_to_dns_domain(mem_ctx, domain_dn); + serverinfo->pszForestName = samdb_dn_to_dns_domain(mem_ctx, forest_dn); + + serverinfo->pszDomainDirectoryPartition = talloc_asprintf(mem_ctx, + "DC=DomainDnsZones,%s", + ldb_dn_get_linearized(domain_dn)); + serverinfo->pszForestDirectoryPartition = talloc_asprintf(mem_ctx, + "DC=ForestDnsZones,%s", + ldb_dn_get_linearized(forest_dn)); + + load_interface_list(mem_ctx, lp_ctx, &ifaces); + num_interfaces = iface_list_count(ifaces); + + serverinfo->aipServerAddrs = talloc_zero(mem_ctx, struct IP4_ARRAY); + + if (serverinfo->aipServerAddrs) { + serverinfo->aipServerAddrs->AddrCount = num_interfaces; + if (num_interfaces > 0) { + serverinfo->aipServerAddrs->AddrArray = talloc_zero_array(mem_ctx, + unsigned int, + num_interfaces); + if (serverinfo->aipServerAddrs->AddrArray) { + for (i=0; i<num_interfaces; i++) { + serverinfo->aipServerAddrs->AddrArray[i] = inet_addr(iface_list_n_ip(ifaces, i)); + } + } else { + serverinfo->aipServerAddrs->AddrCount = 0; + } + } + } + talloc_free(ifaces); + + /* Assume listen addresses are same as server addresses */ + serverinfo->aipListenAddrs = serverinfo->aipServerAddrs; + + serverinfo->aipForwarders = NULL; + + serverinfo->aipLogFilter = NULL; + serverinfo->pwszLogFilePath = NULL; + + serverinfo->dwLogLevel = 0; + serverinfo->dwDebugLevel = 0; + serverinfo->dwEventLogLevel = DNS_EVENT_LOG_INFORMATION_TYPE; + serverinfo->dwLogFileMaxSize = 0; + + serverinfo->dwForwardTimeout = 3; /* seconds (default) */ + serverinfo->dwRpcProtocol = 5; + serverinfo->dwNameCheckFlag = DNS_ALLOW_MULTIBYTE_NAMES; + serverinfo->cAddressAnswerLimit = 0; + serverinfo->dwRecursionRetry = 3 /* seconds (default) */; + serverinfo->dwRecursionTimeout = 8 /* seconds (default) */; + serverinfo->dwMaxCacheTtl = 0x00015180; /* 1 day (default) */; + serverinfo->dwDsPollingInterval = 0xB4; /* 3 minutes (default) */; + serverinfo->dwLocalNetPriorityNetMask = 0x000000FF;; + + serverinfo->dwScavengingInterval = 0; + serverinfo->dwDefaultRefreshInterval = 0xA8; /* 7 days in hours */; + serverinfo->dwDefaultNoRefreshInterval = 0xA8; /* 7 days in hours */;; + serverinfo->dwLastScavengeTime = 0; + + serverinfo->fAutoReverseZones = 0; + serverinfo->fAutoCacheUpdate = 0; + + serverinfo->fRecurseAfterForwarding = 0; + serverinfo->fForwardDelegations = 1; + serverinfo->fNoRecursion = 0; + serverinfo->fSecureResponses = 0; + + serverinfo->fRoundRobin = 1; + serverinfo->fLocalNetPriority = 0; + + serverinfo->fBindSecondaries = 0; + serverinfo->fWriteAuthorityNs = 0; + + serverinfo->fStrictFileParsing = 0; + serverinfo->fLooseWildcarding = 0 ; + serverinfo->fDefaultAgingState = 0; + + return serverinfo; +} + + +struct dnsserver_zoneinfo *dnsserver_init_zoneinfo(struct dnsserver_zone *zone, + struct dnsserver_serverinfo *serverinfo, + bool is_forest) +{ + struct dnsserver_zoneinfo *zoneinfo; + uint32_t dp_flags; + + zoneinfo = talloc_zero(zone, struct dnsserver_zoneinfo); + if (zoneinfo == NULL) { + return NULL; + } + + dp_flags = DNS_DP_ENLISTED; + if (is_forest) { + dp_flags |= DNS_DP_FOREST_DEFAULT; + } else { + dp_flags |= DNS_DP_DOMAIN_DEFAULT; + } + + zoneinfo->Version = 0x32; + zoneinfo->Flags = DNS_RPC_ZONE_DSINTEGRATED | DNS_RPC_ZONE_UPDATE_SECURE; + zoneinfo->dwZoneType = DNS_ZONE_TYPE_PRIMARY; + zoneinfo->fReverse = 0; /* We only support forward zones for now */ + zoneinfo->fAllowUpdate = DNS_ZONE_UPDATE_SECURE; + zoneinfo->fPaused = 0; + zoneinfo->fShutdown = 0; + zoneinfo->fAutoCreated = 0; + zoneinfo->fUseDatabase = 1; + zoneinfo->pszDataFile = NULL; + zoneinfo->aipMasters = NULL; + zoneinfo->fSecureSecondaries = DNS_ZONE_SECSECURE_NO_XFER; + zoneinfo->fNotifyLevel = DNS_ZONE_NOTIFY_LIST_ONLY; + zoneinfo->aipSecondaries = NULL; + zoneinfo->aipNotify = NULL; + zoneinfo->fUseWins = 0; + zoneinfo->fUseNbstat = 0; + zoneinfo->fAging = 0; + zoneinfo->dwNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval; + zoneinfo->dwRefreshInterval = serverinfo->dwDefaultRefreshInterval; + zoneinfo->dwAvailForScavengeTime = 0; + zoneinfo->aipScavengeServers = NULL; + zoneinfo->dwForwarderTimeout = 0; + zoneinfo->fForwarderSlave = 0; + zoneinfo->aipLocalMasters = NULL; + zoneinfo->dwDpFlags = dp_flags; + zoneinfo->pszDpFqdn = samdb_dn_to_dns_domain(zone, zone->partition_dn); + zoneinfo->pwszZoneDn = discard_const_p(char, ldb_dn_get_linearized(zone->zone_dn)); + zoneinfo->dwLastSuccessfulSoaCheck = 0; + zoneinfo->dwLastSuccessfulXfr = 0; + zoneinfo->fQueuedForBackgroundLoad = 0; + zoneinfo->fBackgroundLoadInProgress = 0; + zoneinfo->fReadOnlyZone = 0; + zoneinfo->dwLastXfrAttempt = 0; + zoneinfo->dwLastXfrResult = 0; + + return zoneinfo; +} + +struct dnsserver_zone *dnsserver_find_zone(struct dnsserver_zone *zones, const char *zone_name) +{ + struct dnsserver_zone *z = NULL; + + for (z = zones; z; z = z->next) { + if (strcmp(zone_name, z->name) == 0) { + break; + } + } + + return z; +} + +struct ldb_dn *dnsserver_name_to_dn(TALLOC_CTX *mem_ctx, struct dnsserver_zone *z, const char *name) +{ + struct ldb_dn *dn; + bool ret; + + dn = ldb_dn_copy(mem_ctx, z->zone_dn); + if (dn == NULL) { + return NULL; + } + if (strcmp(name, z->name) == 0) { + ret = ldb_dn_add_child_fmt(dn, "DC=@"); + } else { + ret = ldb_dn_add_child_fmt(dn, "DC=%s", name); + } + if (!ret) { + talloc_free(dn); + return NULL; + } + + return dn; +} + +uint32_t dnsserver_zone_to_request_filter(const char *zone_name) +{ + uint32_t request_filter; + + if (strcmp(zone_name, "..AllZones") == 0) { + request_filter = DNS_ZONE_REQUEST_PRIMARY + | DNS_ZONE_REQUEST_SECONDARY + | DNS_ZONE_REQUEST_AUTO + | DNS_ZONE_REQUEST_FORWARD + | DNS_ZONE_REQUEST_REVERSE + | DNS_ZONE_REQUEST_FORWARDER + | DNS_ZONE_REQUEST_STUB + | DNS_ZONE_REQUEST_DS + | DNS_ZONE_REQUEST_NON_DS + | DNS_ZONE_REQUEST_DOMAIN_DP + | DNS_ZONE_REQUEST_FOREST_DP + | DNS_ZONE_REQUEST_CUSTOM_DP + | DNS_ZONE_REQUEST_LEGACY_DP; + } else if (strcmp(zone_name, "..AllZonesAndCache") == 0) { + request_filter = DNS_ZONE_REQUEST_PRIMARY + | DNS_ZONE_REQUEST_SECONDARY + | DNS_ZONE_REQUEST_CACHE + | DNS_ZONE_REQUEST_AUTO + | DNS_ZONE_REQUEST_FORWARD + | DNS_ZONE_REQUEST_REVERSE + | DNS_ZONE_REQUEST_FORWARDER + | DNS_ZONE_REQUEST_STUB + | DNS_ZONE_REQUEST_DS + | DNS_ZONE_REQUEST_NON_DS + | DNS_ZONE_REQUEST_DOMAIN_DP + | DNS_ZONE_REQUEST_FOREST_DP + | DNS_ZONE_REQUEST_CUSTOM_DP + | DNS_ZONE_REQUEST_LEGACY_DP; + } else if (strcmp(zone_name, "..AllPrimaryZones") == 0) { + request_filter = DNS_ZONE_REQUEST_PRIMARY; + } else if (strcmp(zone_name, "..AllSecondaryZones") == 0) { + request_filter = DNS_ZONE_REQUEST_SECONDARY; + } else if (strcmp(zone_name, "..AllForwardZones") == 0) { + request_filter = DNS_ZONE_REQUEST_FORWARD; + } else if (strcmp(zone_name, "..AllReverseZones") == 0) { + request_filter = DNS_ZONE_REQUEST_REVERSE; + } else if (strcmp(zone_name, "..AllDsZones") == 0) { + request_filter = DNS_ZONE_REQUEST_DS; + } else if (strcmp(zone_name, "..AllNonDsZones") == 0) { + request_filter = DNS_ZONE_REQUEST_NON_DS; + } else if (strcmp(zone_name, "..AllPrimaryReverseZones") == 0) { + request_filter = DNS_ZONE_REQUEST_PRIMARY + | DNS_ZONE_REQUEST_REVERSE; + } else if (strcmp(zone_name, "..AllPrimaryForwardZones") == 0) { + request_filter = DNS_ZONE_REQUEST_PRIMARY + | DNS_ZONE_REQUEST_FORWARD; + } else if (strcmp(zone_name, "..AllSecondaryReverseZones") == 0) { + request_filter = DNS_ZONE_REQUEST_SECONDARY + | DNS_ZONE_REQUEST_REVERSE; + } else if (strcmp(zone_name, "..AllSecondaryForwardZones") == 0) { + request_filter = DNS_ZONE_REQUEST_SECONDARY + | DNS_ZONE_REQUEST_REVERSE; + } + + return request_filter; +} |