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 "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"
33 static struct DNS_ADDR_ARRAY
*fill_dns_addr_array(TALLOC_CTX
*mem_ctx
,
34 struct loadparm_context
*lp_ctx
,
37 struct interface
*ifaces
;
38 int num_interfaces
, i
;
39 struct DNS_ADDR_ARRAY
*dns_addr_array
;
41 bool have_ipv4
, have_ipv6
;
44 have_ipv4
= have_ipv6
= false;
48 Return all interfaces from kernel
54 /* Only the used interfaces */
55 load_interface_list(mem_ctx
, lp_ctx
, &ifaces
);
56 num_interfaces
= iface_list_count(ifaces
);
58 dns_addr_array
= talloc_zero(mem_ctx
, struct DNS_ADDR_ARRAY
);
59 if (dns_addr_array
== NULL
) {
62 dns_addr_array
->MaxCount
= num_interfaces
;
63 dns_addr_array
->AddrCount
= num_interfaces
;
64 if (num_interfaces
== 0) {
68 dns_addr_array
->AddrArray
= talloc_zero_array(mem_ctx
, struct DNS_ADDR
,
70 if (!dns_addr_array
->AddrArray
) {
71 TALLOC_FREE(dns_addr_array
);
75 for (i
= 0; i
< num_interfaces
; i
++) {
77 ipstr
= iface_list_n_ip(ifaces
, i
);
78 if (is_ipaddress_v4(ipstr
)) {
80 dns_addr_array
->AddrArray
[i
].MaxSa
[0] = 0x02;
81 ret
= inet_pton(AF_INET
, ipstr
,
82 &dns_addr_array
->AddrArray
[i
].MaxSa
[4]);
85 dns_addr_array
->AddrArray
[i
].MaxSa
[0] = 0x17;
86 ret
= inet_pton(AF_INET6
, ipstr
,
87 &dns_addr_array
->AddrArray
[i
].MaxSa
[8]);
89 if (ret
!= 1) { /*yep, 1 means success for inet_pton */
90 DBG_ERR("Interface %d address (%s) is invalid\n",
96 if (have_ipv4
&& have_ipv6
) {
97 family
= 0; /* mixed: MS-DNSP */
98 } else if (have_ipv4
&& !have_ipv6
) {
103 dns_addr_array
->Family
= family
;
107 return dns_addr_array
;
110 struct dnsserver_serverinfo
*dnsserver_init_serverinfo(TALLOC_CTX
*mem_ctx
,
111 struct loadparm_context
*lp_ctx
,
112 struct ldb_context
*samdb
)
114 struct dnsserver_serverinfo
*serverinfo
;
115 struct dcerpc_server_info
*dinfo
;
116 struct ldb_dn
*domain_dn
, *forest_dn
;
118 serverinfo
= talloc_zero(mem_ctx
, struct dnsserver_serverinfo
);
119 if (serverinfo
== NULL
) {
123 dinfo
= lpcfg_dcerpc_server_info(mem_ctx
, lp_ctx
);
125 serverinfo
->dwVersion
= (dinfo
->version_build
& 0x0000FFFF) << 16 |
126 (dinfo
->version_minor
& 0x000000FF) << 8 |
127 (dinfo
->version_major
& 0x000000FF);
130 serverinfo
->dwVersion
= 0x0ECE0205; /* build, os_minor, os_major */;
133 serverinfo
->fBootMethod
= DNS_BOOT_METHOD_DIRECTORY
;
134 serverinfo
->fAdminConfigured
= 0;
135 serverinfo
->fAllowUpdate
= 1;
136 serverinfo
->fDsAvailable
= 1;
138 serverinfo
->pszServerName
= talloc_asprintf(mem_ctx
, "%s.%s",
139 lpcfg_netbios_name(lp_ctx
),
140 lpcfg_dnsdomain(lp_ctx
));
142 domain_dn
= ldb_get_default_basedn(samdb
);
143 forest_dn
= ldb_get_root_basedn(samdb
);
145 serverinfo
->pszDsContainer
= talloc_asprintf(mem_ctx
,
146 "CN=MicrosoftDNS,DC=DomainDnsZones,%s",
147 ldb_dn_get_linearized(domain_dn
));
149 serverinfo
->dwDsForestVersion
= dsdb_forest_functional_level(samdb
);
150 serverinfo
->dwDsDomainVersion
= dsdb_functional_level(samdb
);
151 serverinfo
->dwDsDsaVersion
= dsdb_dc_functional_level(samdb
);
153 serverinfo
->pszDomainName
= samdb_dn_to_dns_domain(mem_ctx
, domain_dn
);
154 serverinfo
->pszForestName
= samdb_dn_to_dns_domain(mem_ctx
, forest_dn
);
156 serverinfo
->pszDomainDirectoryPartition
= talloc_asprintf(mem_ctx
,
157 "DC=DomainDnsZones,%s",
158 ldb_dn_get_linearized(domain_dn
));
159 serverinfo
->pszForestDirectoryPartition
= talloc_asprintf(mem_ctx
,
160 "DC=ForestDnsZones,%s",
161 ldb_dn_get_linearized(forest_dn
));
162 /* IP addresses on which the DNS server listens for DNS requests */
163 serverinfo
->aipListenAddrs
= fill_dns_addr_array(mem_ctx
, lp_ctx
, true);
165 /* All IP addresses available on the server
167 * Use same as listen addresses
169 serverinfo
->aipServerAddrs
= serverinfo
->aipListenAddrs
;
171 serverinfo
->aipForwarders
= NULL
;
173 serverinfo
->aipLogFilter
= NULL
;
174 serverinfo
->pwszLogFilePath
= NULL
;
176 serverinfo
->dwLogLevel
= 0;
177 serverinfo
->dwDebugLevel
= 0;
178 serverinfo
->dwEventLogLevel
= DNS_EVENT_LOG_INFORMATION_TYPE
;
179 serverinfo
->dwLogFileMaxSize
= 0;
181 serverinfo
->dwForwardTimeout
= 3; /* seconds (default) */
182 serverinfo
->dwRpcProtocol
= 5;
183 serverinfo
->dwNameCheckFlag
= DNS_ALLOW_MULTIBYTE_NAMES
;
184 serverinfo
->cAddressAnswerLimit
= 0;
185 serverinfo
->dwRecursionRetry
= 3; /* seconds (default) */
186 serverinfo
->dwRecursionTimeout
= 8; /* seconds (default) */
187 serverinfo
->dwMaxCacheTtl
= 0x00015180; /* 1 day (default) */
188 serverinfo
->dwDsPollingInterval
= 0xB4; /* 3 minutes (default) */
189 serverinfo
->dwLocalNetPriorityNetMask
= 0x000000FF;
191 serverinfo
->dwScavengingInterval
= lpcfg_parm_int(
192 lp_ctx
, NULL
, "dnsserver", "ScavengingInterval", 24 * 7);
193 serverinfo
->dwDefaultRefreshInterval
= lpcfg_parm_int(
194 lp_ctx
, NULL
, "dnsserver", "DefaultRefreshInterval", 24 * 3);
195 serverinfo
->dwDefaultNoRefreshInterval
= lpcfg_parm_int(
196 lp_ctx
, NULL
, "dnsserver", "DefaultNoRefreshInterval", 24 * 3);
198 serverinfo
->dwLastScavengeTime
= 0;
200 serverinfo
->fAutoReverseZones
= 0;
201 serverinfo
->fAutoCacheUpdate
= 0;
203 serverinfo
->fRecurseAfterForwarding
= 0;
204 serverinfo
->fForwardDelegations
= 1;
205 serverinfo
->fNoRecursion
= 0;
206 serverinfo
->fSecureResponses
= 0;
208 serverinfo
->fRoundRobin
= 1;
209 serverinfo
->fLocalNetPriority
= 0;
211 serverinfo
->fBindSecondaries
= 0;
212 serverinfo
->fWriteAuthorityNs
= 0;
214 serverinfo
->fStrictFileParsing
= 0;
215 serverinfo
->fLooseWildcarding
= 0 ;
216 serverinfo
->fDefaultAgingState
= 0;
221 struct dnsserver_zoneinfo
*dnsserver_init_zoneinfo(struct dnsserver_zone
*zone
,
222 struct dnsserver_serverinfo
*serverinfo
)
224 struct dnsserver_zoneinfo
*zoneinfo
;
226 const char *revzone
= "in-addr.arpa";
227 const char *revzone6
= "ip6.arpa";
231 zoneinfo
= talloc_zero(zone
, struct dnsserver_zoneinfo
);
232 if (zoneinfo
== NULL
) {
236 /* If the zone name ends with in-addr.arpa, it's reverse zone */
237 /* If the zone name ends with ip6.arpa, it's reverse zone (IPv6) */
239 len1
= strlen(zone
->name
);
240 len2
= strlen(revzone
);
241 if (len1
> len2
&& strcasecmp(&zone
->name
[len1
-len2
], revzone
) == 0) {
244 len2
= strlen(revzone6
);
245 if (len1
> len2
&& strcasecmp(&zone
->name
[len1
-len2
], revzone6
) == 0) {
250 zoneinfo
->Version
= 0x32;
251 zoneinfo
->Flags
= DNS_RPC_ZONE_DSINTEGRATED
;
253 if (strcmp(zone
->name
, ".") == 0) {
254 zoneinfo
->dwZoneType
= DNS_ZONE_TYPE_CACHE
;
255 zoneinfo
->fAllowUpdate
= DNS_ZONE_UPDATE_OFF
;
256 zoneinfo
->fSecureSecondaries
= DNS_ZONE_SECSECURE_NO_SECURITY
;
257 zoneinfo
->fNotifyLevel
= DNS_ZONE_NOTIFY_OFF
;
258 zoneinfo
->dwNoRefreshInterval
= 0;
259 zoneinfo
->dwRefreshInterval
= 0;
261 zoneinfo
->Flags
|= DNS_RPC_ZONE_UPDATE_SECURE
;
262 zoneinfo
->dwZoneType
= DNS_ZONE_TYPE_PRIMARY
;
263 zoneinfo
->fAllowUpdate
= DNS_ZONE_UPDATE_SECURE
;
264 zoneinfo
->fSecureSecondaries
= DNS_ZONE_SECSECURE_NO_XFER
;
265 zoneinfo
->fNotifyLevel
= DNS_ZONE_NOTIFY_LIST_ONLY
;
266 zoneinfo
->dwNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
267 zoneinfo
->dwRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
270 zoneinfo
->fReverse
= fReverse
;
271 zoneinfo
->fPaused
= 0;
272 zoneinfo
->fShutdown
= 0;
273 zoneinfo
->fAutoCreated
= 0;
274 zoneinfo
->fUseDatabase
= 1;
275 zoneinfo
->pszDataFile
= NULL
;
276 zoneinfo
->aipMasters
= NULL
;
277 zoneinfo
->aipSecondaries
= NULL
;
278 zoneinfo
->aipNotify
= NULL
;
279 zoneinfo
->fUseWins
= 0;
280 zoneinfo
->fUseNbstat
= 0;
281 zoneinfo
->fAging
= 0;
282 zoneinfo
->dwAvailForScavengeTime
= 0;
283 zoneinfo
->aipScavengeServers
= NULL
;
284 zoneinfo
->dwForwarderTimeout
= 0;
285 zoneinfo
->fForwarderSlave
= 0;
286 zoneinfo
->aipLocalMasters
= NULL
;
287 zoneinfo
->pwszZoneDn
= discard_const_p(char, ldb_dn_get_linearized(zone
->zone_dn
));
288 zoneinfo
->dwLastSuccessfulSoaCheck
= 0;
289 zoneinfo
->dwLastSuccessfulXfr
= 0;
290 zoneinfo
->fQueuedForBackgroundLoad
= 0;
291 zoneinfo
->fBackgroundLoadInProgress
= 0;
292 zoneinfo
->fReadOnlyZone
= 0;
293 zoneinfo
->dwLastXfrAttempt
= 0;
294 zoneinfo
->dwLastXfrResult
= 0;
296 for(i
=0; i
<zone
->num_props
; i
++){
298 valid_property
= dns_zoneinfo_load_zone_property(
299 zoneinfo
, &zone
->tmp_props
[i
]);
300 if (!valid_property
) {
301 TALLOC_FREE(zoneinfo
);
309 struct dnsserver_zone
*dnsserver_find_zone(struct dnsserver_zone
*zones
, const char *zone_name
)
311 struct dnsserver_zone
*z
= NULL
;
313 for (z
= zones
; z
; z
= z
->next
) {
314 if (dns_name_equal(zone_name
, z
->name
)) {
322 struct ldb_dn
*dnsserver_name_to_dn(TALLOC_CTX
*mem_ctx
, struct dnsserver_zone
*z
, const char *name
)
326 struct ldb_val name_val
=
327 data_blob_string_const(name
);
329 dn
= ldb_dn_copy(mem_ctx
, z
->zone_dn
);
333 if (strcasecmp(name
, z
->name
) == 0) {
334 ret
= ldb_dn_add_child_fmt(dn
, "DC=@");
342 ret
= ldb_dn_add_child_val(dn
,
354 uint32_t dnsserver_zone_to_request_filter(const char *zone_name
)
356 uint32_t request_filter
= 0;
358 if (strcmp(zone_name
, "..AllZones") == 0) {
359 request_filter
= DNS_ZONE_REQUEST_PRIMARY
360 | DNS_ZONE_REQUEST_SECONDARY
361 | DNS_ZONE_REQUEST_AUTO
362 | DNS_ZONE_REQUEST_FORWARD
363 | DNS_ZONE_REQUEST_REVERSE
364 | DNS_ZONE_REQUEST_FORWARDER
365 | DNS_ZONE_REQUEST_STUB
366 | DNS_ZONE_REQUEST_DS
367 | DNS_ZONE_REQUEST_NON_DS
368 | DNS_ZONE_REQUEST_DOMAIN_DP
369 | DNS_ZONE_REQUEST_FOREST_DP
370 | DNS_ZONE_REQUEST_CUSTOM_DP
371 | DNS_ZONE_REQUEST_LEGACY_DP
;
372 } else if (strcmp(zone_name
, "..AllZonesAndCache") == 0) {
373 request_filter
= DNS_ZONE_REQUEST_PRIMARY
374 | DNS_ZONE_REQUEST_SECONDARY
375 | DNS_ZONE_REQUEST_CACHE
376 | DNS_ZONE_REQUEST_AUTO
377 | DNS_ZONE_REQUEST_FORWARD
378 | DNS_ZONE_REQUEST_REVERSE
379 | DNS_ZONE_REQUEST_FORWARDER
380 | DNS_ZONE_REQUEST_STUB
381 | DNS_ZONE_REQUEST_DS
382 | DNS_ZONE_REQUEST_NON_DS
383 | DNS_ZONE_REQUEST_DOMAIN_DP
384 | DNS_ZONE_REQUEST_FOREST_DP
385 | DNS_ZONE_REQUEST_CUSTOM_DP
386 | DNS_ZONE_REQUEST_LEGACY_DP
;
387 } else if (strcmp(zone_name
, "..AllPrimaryZones") == 0) {
388 request_filter
= DNS_ZONE_REQUEST_PRIMARY
;
389 } else if (strcmp(zone_name
, "..AllSecondaryZones") == 0) {
390 request_filter
= DNS_ZONE_REQUEST_SECONDARY
;
391 } else if (strcmp(zone_name
, "..AllForwardZones") == 0) {
392 request_filter
= DNS_ZONE_REQUEST_FORWARD
;
393 } else if (strcmp(zone_name
, "..AllReverseZones") == 0) {
394 request_filter
= DNS_ZONE_REQUEST_REVERSE
;
395 } else if (strcmp(zone_name
, "..AllDsZones") == 0) {
396 request_filter
= DNS_ZONE_REQUEST_DS
;
397 } else if (strcmp(zone_name
, "..AllNonDsZones") == 0) {
398 request_filter
= DNS_ZONE_REQUEST_NON_DS
;
399 } else if (strcmp(zone_name
, "..AllPrimaryReverseZones") == 0) {
400 request_filter
= DNS_ZONE_REQUEST_PRIMARY
401 | DNS_ZONE_REQUEST_REVERSE
;
402 } else if (strcmp(zone_name
, "..AllPrimaryForwardZones") == 0) {
403 request_filter
= DNS_ZONE_REQUEST_PRIMARY
404 | DNS_ZONE_REQUEST_FORWARD
;
405 } else if (strcmp(zone_name
, "..AllSecondaryReverseZones") == 0) {
406 request_filter
= DNS_ZONE_REQUEST_SECONDARY
407 | DNS_ZONE_REQUEST_REVERSE
;
408 } else if (strcmp(zone_name
, "..AllSecondaryForwardZones") == 0) {
409 request_filter
= DNS_ZONE_REQUEST_SECONDARY
410 | DNS_ZONE_REQUEST_REVERSE
;
413 return request_filter
;