2 Unix SMB/CIFS implementation.
6 Copyright (C) Amitay Isaacs 2011
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.
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.
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/>.
23 #include "dnsserver.h"
24 #include "rpc_server/common/common.h"
25 #include "dsdb/samdb/samdb.h"
26 #include "lib/socket/netif.h"
27 #include "lib/util/util_net.h"
29 static struct DNS_ADDR_ARRAY
*fill_dns_addr_array(TALLOC_CTX
*mem_ctx
,
30 struct loadparm_context
*lp_ctx
,
33 struct interface
*ifaces
;
34 int num_interfaces
, i
;
35 struct DNS_ADDR_ARRAY
*dns_addr_array
;
37 bool have_ipv4
, have_ipv6
;
40 have_ipv4
= have_ipv6
= false;
44 Return all interfaces from kernel
50 /* Only the used interfaces */
51 load_interface_list(mem_ctx
, lp_ctx
, &ifaces
);
52 num_interfaces
= iface_list_count(ifaces
);
54 dns_addr_array
= talloc_zero(mem_ctx
, struct DNS_ADDR_ARRAY
);
55 if (dns_addr_array
== NULL
) {
58 dns_addr_array
->MaxCount
= num_interfaces
;
59 dns_addr_array
->AddrCount
= num_interfaces
;
60 if (num_interfaces
== 0) {
64 dns_addr_array
->AddrArray
= talloc_zero_array(mem_ctx
, struct DNS_ADDR
,
66 if (!dns_addr_array
->AddrArray
) {
67 TALLOC_FREE(dns_addr_array
);
71 for (i
= 0; i
< num_interfaces
; i
++) {
72 ipstr
= iface_list_n_ip(ifaces
, i
);
73 if (is_ipaddress_v4(ipstr
)) {
75 dns_addr_array
->AddrArray
[i
].MaxSa
[0] = 0x02;
76 inet_pton(AF_INET
, ipstr
,
77 &dns_addr_array
->AddrArray
[i
].MaxSa
[4]);
80 dns_addr_array
->AddrArray
[i
].MaxSa
[0] = 0x17;
81 inet_pton(AF_INET6
, ipstr
,
82 &dns_addr_array
->AddrArray
[i
].MaxSa
[8]);
86 if (have_ipv4
&& have_ipv6
) {
87 family
= 0; /* mixed: MS-DNSP */
88 } else if (have_ipv4
&& !have_ipv6
) {
93 dns_addr_array
->Family
= family
;
97 return dns_addr_array
;
100 struct dnsserver_serverinfo
*dnsserver_init_serverinfo(TALLOC_CTX
*mem_ctx
,
101 struct loadparm_context
*lp_ctx
,
102 struct ldb_context
*samdb
)
104 struct dnsserver_serverinfo
*serverinfo
;
105 struct dcerpc_server_info
*dinfo
;
106 struct ldb_dn
*domain_dn
, *forest_dn
;
108 serverinfo
= talloc_zero(mem_ctx
, struct dnsserver_serverinfo
);
109 if (serverinfo
== NULL
) {
113 dinfo
= lpcfg_dcerpc_server_info(mem_ctx
, lp_ctx
);
115 serverinfo
->dwVersion
= (dinfo
->version_build
& 0x0000FFFF) << 16 |
116 (dinfo
->version_minor
& 0x000000FF) << 8 |
117 (dinfo
->version_major
& 0x000000FF);
120 serverinfo
->dwVersion
= 0x0ECE0205; /* build, os_minor, os_major */;
123 serverinfo
->fBootMethod
= DNS_BOOT_METHOD_DIRECTORY
;
124 serverinfo
->fAdminConfigured
= 0;
125 serverinfo
->fAllowUpdate
= 1;
126 serverinfo
->fDsAvailable
= 1;
128 serverinfo
->pszServerName
= talloc_asprintf(mem_ctx
, "%s.%s",
129 lpcfg_netbios_name(lp_ctx
),
130 lpcfg_dnsdomain(lp_ctx
));
132 domain_dn
= ldb_get_default_basedn(samdb
);
133 forest_dn
= ldb_get_root_basedn(samdb
);
135 serverinfo
->pszDsContainer
= talloc_asprintf(mem_ctx
,
136 "CN=MicrosoftDNS,DC=DomainDnsZones,%s",
137 ldb_dn_get_linearized(domain_dn
));
139 serverinfo
->dwDsForestVersion
= dsdb_forest_functional_level(samdb
);
140 serverinfo
->dwDsDomainVersion
= dsdb_functional_level(samdb
);
141 serverinfo
->dwDsDsaVersion
= 4; /* need to do ldb search here */
143 serverinfo
->pszDomainName
= samdb_dn_to_dns_domain(mem_ctx
, domain_dn
);
144 serverinfo
->pszForestName
= samdb_dn_to_dns_domain(mem_ctx
, forest_dn
);
146 serverinfo
->pszDomainDirectoryPartition
= talloc_asprintf(mem_ctx
,
147 "DC=DomainDnsZones,%s",
148 ldb_dn_get_linearized(domain_dn
));
149 serverinfo
->pszForestDirectoryPartition
= talloc_asprintf(mem_ctx
,
150 "DC=ForestDnsZones,%s",
151 ldb_dn_get_linearized(forest_dn
));
152 /* IP addresses on which the DNS server listens for DNS requests */
153 serverinfo
->aipListenAddrs
= fill_dns_addr_array(mem_ctx
, lp_ctx
, true);
155 /* All IP addresses available on the server
157 * Use same as listen addresses
159 serverinfo
->aipServerAddrs
= serverinfo
->aipListenAddrs
;
161 serverinfo
->aipForwarders
= NULL
;
163 serverinfo
->aipLogFilter
= NULL
;
164 serverinfo
->pwszLogFilePath
= NULL
;
166 serverinfo
->dwLogLevel
= 0;
167 serverinfo
->dwDebugLevel
= 0;
168 serverinfo
->dwEventLogLevel
= DNS_EVENT_LOG_INFORMATION_TYPE
;
169 serverinfo
->dwLogFileMaxSize
= 0;
171 serverinfo
->dwForwardTimeout
= 3; /* seconds (default) */
172 serverinfo
->dwRpcProtocol
= 5;
173 serverinfo
->dwNameCheckFlag
= DNS_ALLOW_MULTIBYTE_NAMES
;
174 serverinfo
->cAddressAnswerLimit
= 0;
175 serverinfo
->dwRecursionRetry
= 3 /* seconds (default) */;
176 serverinfo
->dwRecursionTimeout
= 8 /* seconds (default) */;
177 serverinfo
->dwMaxCacheTtl
= 0x00015180; /* 1 day (default) */;
178 serverinfo
->dwDsPollingInterval
= 0xB4; /* 3 minutes (default) */;
179 serverinfo
->dwLocalNetPriorityNetMask
= 0x000000FF;;
181 serverinfo
->dwScavengingInterval
= 0;
182 serverinfo
->dwDefaultRefreshInterval
= 0xA8; /* 7 days in hours */;
183 serverinfo
->dwDefaultNoRefreshInterval
= 0xA8; /* 7 days in hours */;;
184 serverinfo
->dwLastScavengeTime
= 0;
186 serverinfo
->fAutoReverseZones
= 0;
187 serverinfo
->fAutoCacheUpdate
= 0;
189 serverinfo
->fRecurseAfterForwarding
= 0;
190 serverinfo
->fForwardDelegations
= 1;
191 serverinfo
->fNoRecursion
= 0;
192 serverinfo
->fSecureResponses
= 0;
194 serverinfo
->fRoundRobin
= 1;
195 serverinfo
->fLocalNetPriority
= 0;
197 serverinfo
->fBindSecondaries
= 0;
198 serverinfo
->fWriteAuthorityNs
= 0;
200 serverinfo
->fStrictFileParsing
= 0;
201 serverinfo
->fLooseWildcarding
= 0 ;
202 serverinfo
->fDefaultAgingState
= 0;
208 struct dnsserver_zoneinfo
*dnsserver_init_zoneinfo(struct dnsserver_zone
*zone
,
209 struct dnsserver_serverinfo
*serverinfo
)
211 struct dnsserver_zoneinfo
*zoneinfo
;
213 const char *revzone
= "in-addr.arpa";
214 const char *revzone6
= "ip6.arpa";
217 zoneinfo
= talloc_zero(zone
, struct dnsserver_zoneinfo
);
218 if (zoneinfo
== NULL
) {
222 /* If the zone name ends with in-addr.arpa, it's reverse zone */
223 /* If the zone name ends with ip6.arpa, it's reverse zone (IPv6) */
225 len1
= strlen(zone
->name
);
226 len2
= strlen(revzone
);
227 if (len1
> len2
&& strcasecmp(&zone
->name
[len1
-len2
], revzone
) == 0) {
230 len2
= strlen(revzone6
);
231 if (len1
> len2
&& strcasecmp(&zone
->name
[len1
-len2
], revzone6
) == 0) {
236 zoneinfo
->Version
= 0x32;
237 zoneinfo
->Flags
= DNS_RPC_ZONE_DSINTEGRATED
;
239 if (strcmp(zone
->name
, ".") == 0) {
240 zoneinfo
->dwZoneType
= DNS_ZONE_TYPE_CACHE
;
241 zoneinfo
->fAllowUpdate
= DNS_ZONE_UPDATE_OFF
;
242 zoneinfo
->fSecureSecondaries
= DNS_ZONE_SECSECURE_NO_SECURITY
;
243 zoneinfo
->fNotifyLevel
= DNS_ZONE_NOTIFY_OFF
;
244 zoneinfo
->dwNoRefreshInterval
= 0;
245 zoneinfo
->dwRefreshInterval
= 0;
247 zoneinfo
->Flags
|= DNS_RPC_ZONE_UPDATE_SECURE
;
248 zoneinfo
->dwZoneType
= DNS_ZONE_TYPE_PRIMARY
;
249 zoneinfo
->fAllowUpdate
= DNS_ZONE_UPDATE_SECURE
;
250 zoneinfo
->fSecureSecondaries
= DNS_ZONE_SECSECURE_NO_XFER
;
251 zoneinfo
->fNotifyLevel
= DNS_ZONE_NOTIFY_LIST_ONLY
;
252 zoneinfo
->dwNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
253 zoneinfo
->dwRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
256 zoneinfo
->fReverse
= fReverse
;
257 zoneinfo
->fPaused
= 0;
258 zoneinfo
->fShutdown
= 0;
259 zoneinfo
->fAutoCreated
= 0;
260 zoneinfo
->fUseDatabase
= 1;
261 zoneinfo
->pszDataFile
= NULL
;
262 zoneinfo
->aipMasters
= NULL
;
263 zoneinfo
->aipSecondaries
= NULL
;
264 zoneinfo
->aipNotify
= NULL
;
265 zoneinfo
->fUseWins
= 0;
266 zoneinfo
->fUseNbstat
= 0;
267 zoneinfo
->fAging
= 0;
268 zoneinfo
->dwAvailForScavengeTime
= 0;
269 zoneinfo
->aipScavengeServers
= NULL
;
270 zoneinfo
->dwForwarderTimeout
= 0;
271 zoneinfo
->fForwarderSlave
= 0;
272 zoneinfo
->aipLocalMasters
= NULL
;
273 zoneinfo
->pwszZoneDn
= discard_const_p(char, ldb_dn_get_linearized(zone
->zone_dn
));
274 zoneinfo
->dwLastSuccessfulSoaCheck
= 0;
275 zoneinfo
->dwLastSuccessfulXfr
= 0;
276 zoneinfo
->fQueuedForBackgroundLoad
= 0;
277 zoneinfo
->fBackgroundLoadInProgress
= 0;
278 zoneinfo
->fReadOnlyZone
= 0;
279 zoneinfo
->dwLastXfrAttempt
= 0;
280 zoneinfo
->dwLastXfrResult
= 0;
285 struct dnsserver_partition
*dnsserver_find_partition(struct dnsserver_partition
*partitions
,
288 struct dnsserver_partition
*p
= NULL
;
290 for (p
= partitions
; p
; p
= p
->next
) {
291 if (strcasecmp(dp_fqdn
, p
->pszDpFqdn
) == 0) {
299 struct dnsserver_zone
*dnsserver_find_zone(struct dnsserver_zone
*zones
, const char *zone_name
)
301 struct dnsserver_zone
*z
= NULL
;
303 for (z
= zones
; z
; z
= z
->next
) {
304 if (strcasecmp(zone_name
, z
->name
) == 0) {
312 struct ldb_dn
*dnsserver_name_to_dn(TALLOC_CTX
*mem_ctx
, struct dnsserver_zone
*z
, const char *name
)
317 dn
= ldb_dn_copy(mem_ctx
, z
->zone_dn
);
321 if (strcasecmp(name
, z
->name
) == 0) {
322 ret
= ldb_dn_add_child_fmt(dn
, "DC=@");
324 ret
= ldb_dn_add_child_fmt(dn
, "DC=%s", name
);
334 uint32_t dnsserver_zone_to_request_filter(const char *zone_name
)
336 uint32_t request_filter
= 0;
338 if (strcmp(zone_name
, "..AllZones") == 0) {
339 request_filter
= DNS_ZONE_REQUEST_PRIMARY
340 | DNS_ZONE_REQUEST_SECONDARY
341 | DNS_ZONE_REQUEST_AUTO
342 | DNS_ZONE_REQUEST_FORWARD
343 | DNS_ZONE_REQUEST_REVERSE
344 | DNS_ZONE_REQUEST_FORWARDER
345 | DNS_ZONE_REQUEST_STUB
346 | DNS_ZONE_REQUEST_DS
347 | DNS_ZONE_REQUEST_NON_DS
348 | DNS_ZONE_REQUEST_DOMAIN_DP
349 | DNS_ZONE_REQUEST_FOREST_DP
350 | DNS_ZONE_REQUEST_CUSTOM_DP
351 | DNS_ZONE_REQUEST_LEGACY_DP
;
352 } else if (strcmp(zone_name
, "..AllZonesAndCache") == 0) {
353 request_filter
= DNS_ZONE_REQUEST_PRIMARY
354 | DNS_ZONE_REQUEST_SECONDARY
355 | DNS_ZONE_REQUEST_CACHE
356 | DNS_ZONE_REQUEST_AUTO
357 | DNS_ZONE_REQUEST_FORWARD
358 | DNS_ZONE_REQUEST_REVERSE
359 | DNS_ZONE_REQUEST_FORWARDER
360 | DNS_ZONE_REQUEST_STUB
361 | DNS_ZONE_REQUEST_DS
362 | DNS_ZONE_REQUEST_NON_DS
363 | DNS_ZONE_REQUEST_DOMAIN_DP
364 | DNS_ZONE_REQUEST_FOREST_DP
365 | DNS_ZONE_REQUEST_CUSTOM_DP
366 | DNS_ZONE_REQUEST_LEGACY_DP
;
367 } else if (strcmp(zone_name
, "..AllPrimaryZones") == 0) {
368 request_filter
= DNS_ZONE_REQUEST_PRIMARY
;
369 } else if (strcmp(zone_name
, "..AllSecondaryZones") == 0) {
370 request_filter
= DNS_ZONE_REQUEST_SECONDARY
;
371 } else if (strcmp(zone_name
, "..AllForwardZones") == 0) {
372 request_filter
= DNS_ZONE_REQUEST_FORWARD
;
373 } else if (strcmp(zone_name
, "..AllReverseZones") == 0) {
374 request_filter
= DNS_ZONE_REQUEST_REVERSE
;
375 } else if (strcmp(zone_name
, "..AllDsZones") == 0) {
376 request_filter
= DNS_ZONE_REQUEST_DS
;
377 } else if (strcmp(zone_name
, "..AllNonDsZones") == 0) {
378 request_filter
= DNS_ZONE_REQUEST_NON_DS
;
379 } else if (strcmp(zone_name
, "..AllPrimaryReverseZones") == 0) {
380 request_filter
= DNS_ZONE_REQUEST_PRIMARY
381 | DNS_ZONE_REQUEST_REVERSE
;
382 } else if (strcmp(zone_name
, "..AllPrimaryForwardZones") == 0) {
383 request_filter
= DNS_ZONE_REQUEST_PRIMARY
384 | DNS_ZONE_REQUEST_FORWARD
;
385 } else if (strcmp(zone_name
, "..AllSecondaryReverseZones") == 0) {
386 request_filter
= DNS_ZONE_REQUEST_SECONDARY
387 | DNS_ZONE_REQUEST_REVERSE
;
388 } else if (strcmp(zone_name
, "..AllSecondaryForwardZones") == 0) {
389 request_filter
= DNS_ZONE_REQUEST_SECONDARY
390 | DNS_ZONE_REQUEST_REVERSE
;
393 return request_filter
;