summaryrefslogtreecommitdiff
path: root/source4/rpc_server/dnsserver/dnsutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/rpc_server/dnsserver/dnsutils.c')
-rw-r--r--source4/rpc_server/dnsserver/dnsutils.c309
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;
+}