2011-09-27 16:53:45 +10:00
/*
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 ;
}
2011-10-24 16:54:16 +11:00
dp_flags = DNS_DP_AUTOCREATED | DNS_DP_ENLISTED ;
2011-09-27 16:53:45 +10:00
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 ;
}