Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : DNS Server
5 :
6 : Copyright (C) Amitay Isaacs 2011
7 :
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.
12 :
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.
17 :
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/>.
20 : */
21 :
22 : #include "includes.h"
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"
30 :
31 : #undef strcasecmp
32 :
33 1531 : static struct DNS_ADDR_ARRAY *fill_dns_addr_array(TALLOC_CTX *mem_ctx,
34 : struct loadparm_context *lp_ctx,
35 : bool listen_only)
36 : {
37 0 : struct interface *ifaces;
38 0 : int num_interfaces, i;
39 0 : struct DNS_ADDR_ARRAY *dns_addr_array;
40 0 : const char *ipstr;
41 0 : bool have_ipv4, have_ipv6;
42 0 : uint16_t family;
43 :
44 1531 : have_ipv4 = have_ipv6 = false;
45 :
46 1531 : if (!listen_only) {
47 : /*
48 : Return all interfaces from kernel
49 : Not implemented!
50 : */
51 0 : return NULL;
52 : }
53 :
54 : /* Only the used interfaces */
55 1531 : load_interface_list(mem_ctx, lp_ctx, &ifaces);
56 1531 : num_interfaces = iface_list_count(ifaces);
57 :
58 1531 : dns_addr_array = talloc_zero(mem_ctx, struct DNS_ADDR_ARRAY);
59 1531 : if (dns_addr_array == NULL) {
60 0 : goto nomem;
61 : }
62 1531 : dns_addr_array->MaxCount = num_interfaces;
63 1531 : dns_addr_array->AddrCount = num_interfaces;
64 1531 : if (num_interfaces == 0) {
65 0 : goto nomem;
66 : }
67 :
68 1531 : dns_addr_array->AddrArray = talloc_zero_array(mem_ctx, struct DNS_ADDR,
69 : num_interfaces);
70 1531 : if (!dns_addr_array->AddrArray) {
71 0 : TALLOC_FREE(dns_addr_array);
72 0 : goto nomem;
73 : }
74 :
75 4593 : for (i = 0; i < num_interfaces; i++) {
76 0 : int ret;
77 3062 : ipstr = iface_list_n_ip(ifaces, i);
78 3062 : if (is_ipaddress_v4(ipstr)) {
79 1531 : have_ipv4 = true;
80 1531 : dns_addr_array->AddrArray[i].MaxSa[0] = 0x02;
81 1531 : ret = inet_pton(AF_INET, ipstr,
82 1531 : &dns_addr_array->AddrArray[i].MaxSa[4]);
83 : } else {
84 1531 : have_ipv6 = true;
85 1531 : dns_addr_array->AddrArray[i].MaxSa[0] = 0x17;
86 1531 : ret = inet_pton(AF_INET6, ipstr,
87 1531 : &dns_addr_array->AddrArray[i].MaxSa[8]);
88 : }
89 3062 : if (ret != 1) { /*yep, 1 means success for inet_pton */
90 0 : DBG_ERR("Interface %d address (%s) is invalid\n",
91 : i, ipstr);
92 0 : goto nomem;
93 : }
94 : }
95 :
96 1531 : if (have_ipv4 && have_ipv6) {
97 1531 : family = 0; /* mixed: MS-DNSP */
98 0 : } else if (have_ipv4 && !have_ipv6) {
99 0 : family = AF_INET;
100 : } else {
101 0 : family = AF_INET6;
102 : }
103 1531 : dns_addr_array->Family = family;
104 :
105 1531 : nomem:
106 1531 : talloc_free(ifaces);
107 1531 : return dns_addr_array;
108 : }
109 :
110 1531 : struct dnsserver_serverinfo *dnsserver_init_serverinfo(TALLOC_CTX *mem_ctx,
111 : struct loadparm_context *lp_ctx,
112 : struct ldb_context *samdb)
113 : {
114 0 : struct dnsserver_serverinfo *serverinfo;
115 0 : struct dcerpc_server_info *dinfo;
116 0 : struct ldb_dn *domain_dn, *forest_dn;
117 1531 : const char *dns_hostname = NULL;
118 :
119 1531 : serverinfo = talloc_zero(mem_ctx, struct dnsserver_serverinfo);
120 1531 : if (serverinfo == NULL) {
121 0 : return NULL;
122 : }
123 :
124 1531 : dinfo = lpcfg_dcerpc_server_info(mem_ctx, lp_ctx);
125 1531 : if (dinfo) {
126 1531 : serverinfo->dwVersion = (dinfo->version_build & 0x0000FFFF) << 16 |
127 1531 : (dinfo->version_minor & 0x000000FF) << 8 |
128 1531 : (dinfo->version_major & 0x000000FF);
129 1531 : talloc_free(dinfo);
130 : } else {
131 0 : serverinfo->dwVersion = 0x0ECE0205; /* build, os_minor, os_major */;
132 : }
133 :
134 1531 : serverinfo->fBootMethod = DNS_BOOT_METHOD_DIRECTORY;
135 1531 : serverinfo->fAdminConfigured = 0;
136 1531 : serverinfo->fAllowUpdate = 1;
137 1531 : serverinfo->fDsAvailable = 1;
138 :
139 1531 : dns_hostname = lpcfg_dns_hostname(lp_ctx);
140 1531 : if (dns_hostname == NULL) {
141 0 : TALLOC_FREE(serverinfo);
142 0 : return NULL;
143 : }
144 1531 : serverinfo->pszServerName = discard_const_p(char, dns_hostname);
145 :
146 1531 : domain_dn = ldb_get_default_basedn(samdb);
147 1531 : forest_dn = ldb_get_root_basedn(samdb);
148 :
149 1531 : serverinfo->pszDsContainer = talloc_asprintf(mem_ctx,
150 : "CN=MicrosoftDNS,DC=DomainDnsZones,%s",
151 : ldb_dn_get_linearized(domain_dn));
152 :
153 1531 : serverinfo->dwDsForestVersion = dsdb_forest_functional_level(samdb);
154 1531 : serverinfo->dwDsDomainVersion = dsdb_functional_level(samdb);
155 1531 : serverinfo->dwDsDsaVersion = dsdb_dc_functional_level(samdb);
156 :
157 1531 : serverinfo->pszDomainName = samdb_dn_to_dns_domain(mem_ctx, domain_dn);
158 1531 : serverinfo->pszForestName = samdb_dn_to_dns_domain(mem_ctx, forest_dn);
159 :
160 1531 : serverinfo->pszDomainDirectoryPartition = talloc_asprintf(mem_ctx,
161 : "DC=DomainDnsZones,%s",
162 : ldb_dn_get_linearized(domain_dn));
163 1531 : serverinfo->pszForestDirectoryPartition = talloc_asprintf(mem_ctx,
164 : "DC=ForestDnsZones,%s",
165 : ldb_dn_get_linearized(forest_dn));
166 : /* IP addresses on which the DNS server listens for DNS requests */
167 1531 : serverinfo->aipListenAddrs = fill_dns_addr_array(mem_ctx, lp_ctx, true);
168 :
169 : /* All IP addresses available on the server
170 : * Not implemented!
171 : * Use same as listen addresses
172 : */
173 1531 : serverinfo->aipServerAddrs = serverinfo->aipListenAddrs;
174 :
175 1531 : serverinfo->aipForwarders = NULL;
176 :
177 1531 : serverinfo->aipLogFilter = NULL;
178 1531 : serverinfo->pwszLogFilePath = NULL;
179 :
180 1531 : serverinfo->dwLogLevel = 0;
181 1531 : serverinfo->dwDebugLevel = 0;
182 1531 : serverinfo->dwEventLogLevel = DNS_EVENT_LOG_INFORMATION_TYPE;
183 1531 : serverinfo->dwLogFileMaxSize = 0;
184 :
185 1531 : serverinfo->dwForwardTimeout = 3; /* seconds (default) */
186 1531 : serverinfo->dwRpcProtocol = 5;
187 1531 : serverinfo->dwNameCheckFlag = DNS_ALLOW_MULTIBYTE_NAMES;
188 1531 : serverinfo->cAddressAnswerLimit = 0;
189 1531 : serverinfo->dwRecursionRetry = 3; /* seconds (default) */
190 1531 : serverinfo->dwRecursionTimeout = 8; /* seconds (default) */
191 1531 : serverinfo->dwMaxCacheTtl = 0x00015180; /* 1 day (default) */
192 1531 : serverinfo->dwDsPollingInterval = 0xB4; /* 3 minutes (default) */
193 1531 : serverinfo->dwLocalNetPriorityNetMask = 0x000000FF;
194 :
195 1531 : serverinfo->dwScavengingInterval = lpcfg_parm_int(
196 : lp_ctx, NULL, "dnsserver", "ScavengingInterval", 24 * 7);
197 1531 : serverinfo->dwDefaultRefreshInterval = lpcfg_parm_int(
198 : lp_ctx, NULL, "dnsserver", "DefaultRefreshInterval", 24 * 3);
199 1531 : serverinfo->dwDefaultNoRefreshInterval = lpcfg_parm_int(
200 : lp_ctx, NULL, "dnsserver", "DefaultNoRefreshInterval", 24 * 3);
201 :
202 1531 : serverinfo->dwLastScavengeTime = 0;
203 :
204 1531 : serverinfo->fAutoReverseZones = 0;
205 1531 : serverinfo->fAutoCacheUpdate = 0;
206 :
207 1531 : serverinfo->fRecurseAfterForwarding = 0;
208 1531 : serverinfo->fForwardDelegations = 1;
209 1531 : serverinfo->fNoRecursion = 0;
210 1531 : serverinfo->fSecureResponses = 0;
211 :
212 1531 : serverinfo->fRoundRobin = 1;
213 1531 : serverinfo->fLocalNetPriority = 0;
214 :
215 1531 : serverinfo->fBindSecondaries = 0;
216 1531 : serverinfo->fWriteAuthorityNs = 0;
217 :
218 1531 : serverinfo->fStrictFileParsing = 0;
219 1531 : serverinfo->fLooseWildcarding = 0 ;
220 1531 : serverinfo->fDefaultAgingState = 0;
221 :
222 1531 : return serverinfo;
223 : }
224 :
225 5820 : struct dnsserver_zoneinfo *dnsserver_init_zoneinfo(struct dnsserver_zone *zone,
226 : struct dnsserver_serverinfo *serverinfo)
227 : {
228 4 : struct dnsserver_zoneinfo *zoneinfo;
229 4 : uint32_t fReverse;
230 5820 : const char *revzone = "in-addr.arpa";
231 5820 : const char *revzone6 = "ip6.arpa";
232 4 : int len1, len2;
233 5820 : unsigned int i = 0;
234 :
235 5820 : zoneinfo = talloc_zero(zone, struct dnsserver_zoneinfo);
236 5820 : if (zoneinfo == NULL) {
237 0 : return NULL;
238 : }
239 :
240 : /* If the zone name ends with in-addr.arpa, it's reverse zone */
241 : /* If the zone name ends with ip6.arpa, it's reverse zone (IPv6) */
242 5820 : fReverse = 0;
243 5820 : len1 = strlen(zone->name);
244 5820 : len2 = strlen(revzone);
245 5820 : if (len1 > len2 && strcasecmp(&zone->name[len1-len2], revzone) == 0) {
246 3 : fReverse = 1;
247 : } else {
248 5817 : len2 = strlen(revzone6);
249 5817 : if (len1 > len2 && strcasecmp(&zone->name[len1-len2], revzone6) == 0) {
250 0 : fReverse = 1;
251 : }
252 : }
253 :
254 5820 : zoneinfo->Version = 0x32;
255 5820 : zoneinfo->Flags = DNS_RPC_ZONE_DSINTEGRATED;
256 :
257 5820 : if (strcmp(zone->name, ".") == 0) {
258 1531 : zoneinfo->dwZoneType = DNS_ZONE_TYPE_CACHE;
259 1531 : zoneinfo->fAllowUpdate = DNS_ZONE_UPDATE_OFF;
260 1531 : zoneinfo->fSecureSecondaries = DNS_ZONE_SECSECURE_NO_SECURITY;
261 1531 : zoneinfo->fNotifyLevel = DNS_ZONE_NOTIFY_OFF;
262 1531 : zoneinfo->dwNoRefreshInterval = 0;
263 1531 : zoneinfo->dwRefreshInterval = 0;
264 : } else {
265 4289 : zoneinfo->Flags |= DNS_RPC_ZONE_UPDATE_SECURE;
266 4289 : zoneinfo->dwZoneType = DNS_ZONE_TYPE_PRIMARY;
267 4289 : zoneinfo->fAllowUpdate = DNS_ZONE_UPDATE_SECURE;
268 4289 : zoneinfo->fSecureSecondaries = DNS_ZONE_SECSECURE_NO_XFER;
269 4289 : zoneinfo->fNotifyLevel = DNS_ZONE_NOTIFY_LIST_ONLY;
270 4289 : zoneinfo->dwNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
271 4289 : zoneinfo->dwRefreshInterval = serverinfo->dwDefaultRefreshInterval;
272 : }
273 :
274 5820 : zoneinfo->fReverse = fReverse;
275 5820 : zoneinfo->fPaused = 0;
276 5820 : zoneinfo->fShutdown = 0;
277 5820 : zoneinfo->fAutoCreated = 0;
278 5820 : zoneinfo->fUseDatabase = 1;
279 5820 : zoneinfo->pszDataFile = NULL;
280 5820 : zoneinfo->aipMasters = NULL;
281 5820 : zoneinfo->aipSecondaries = NULL;
282 5820 : zoneinfo->aipNotify = NULL;
283 5820 : zoneinfo->fUseWins = 0;
284 5820 : zoneinfo->fUseNbstat = 0;
285 5820 : zoneinfo->fAging = 0;
286 5820 : zoneinfo->dwAvailForScavengeTime = 0;
287 5820 : zoneinfo->aipScavengeServers = NULL;
288 5820 : zoneinfo->dwForwarderTimeout = 0;
289 5820 : zoneinfo->fForwarderSlave = 0;
290 5820 : zoneinfo->aipLocalMasters = NULL;
291 5820 : zoneinfo->pwszZoneDn = discard_const_p(char, ldb_dn_get_linearized(zone->zone_dn));
292 5820 : zoneinfo->dwLastSuccessfulSoaCheck = 0;
293 5820 : zoneinfo->dwLastSuccessfulXfr = 0;
294 5820 : zoneinfo->fQueuedForBackgroundLoad = 0;
295 5820 : zoneinfo->fBackgroundLoadInProgress = 0;
296 5820 : zoneinfo->fReadOnlyZone = 0;
297 5820 : zoneinfo->dwLastXfrAttempt = 0;
298 5820 : zoneinfo->dwLastXfrResult = 0;
299 :
300 35819 : for(i=0; i<zone->num_props; i++){
301 4 : bool valid_property;
302 30003 : valid_property = dns_zoneinfo_load_zone_property(
303 29999 : zoneinfo, &zone->tmp_props[i]);
304 29999 : if (!valid_property) {
305 0 : TALLOC_FREE(zoneinfo);
306 0 : return NULL;
307 : }
308 : }
309 :
310 5816 : return zoneinfo;
311 : }
312 :
313 15190 : struct dnsserver_zone *dnsserver_find_zone(struct dnsserver_zone *zones, const char *zone_name)
314 : {
315 15190 : struct dnsserver_zone *z = NULL;
316 :
317 34094 : for (z = zones; z; z = z->next) {
318 27827 : if (samba_dns_name_equal(zone_name, z->name)) {
319 8923 : break;
320 : }
321 : }
322 :
323 15190 : return z;
324 : }
325 :
326 1161 : struct ldb_dn *dnsserver_name_to_dn(TALLOC_CTX *mem_ctx, struct dnsserver_zone *z, const char *name)
327 : {
328 0 : struct ldb_dn *dn;
329 0 : bool ret;
330 0 : struct ldb_val name_val =
331 1161 : data_blob_string_const(name);
332 :
333 1161 : dn = ldb_dn_copy(mem_ctx, z->zone_dn);
334 1161 : if (dn == NULL) {
335 0 : return NULL;
336 : }
337 1161 : if (strcasecmp(name, z->name) == 0) {
338 0 : ret = ldb_dn_add_child_fmt(dn, "DC=@");
339 0 : if (!ret) {
340 0 : talloc_free(dn);
341 0 : return NULL;
342 : }
343 0 : return dn;
344 : }
345 :
346 1161 : ret = ldb_dn_add_child_val(dn,
347 : "DC",
348 : name_val);
349 :
350 1161 : if (!ret) {
351 0 : talloc_free(dn);
352 0 : return NULL;
353 : }
354 :
355 1161 : return dn;
356 : }
357 :
358 1220 : uint32_t dnsserver_zone_to_request_filter(const char *zone_name)
359 : {
360 1220 : uint32_t request_filter = 0;
361 :
362 1220 : if (strcmp(zone_name, "..AllZones") == 0) {
363 0 : request_filter = DNS_ZONE_REQUEST_PRIMARY
364 : | DNS_ZONE_REQUEST_SECONDARY
365 : | DNS_ZONE_REQUEST_AUTO
366 : | DNS_ZONE_REQUEST_FORWARD
367 : | DNS_ZONE_REQUEST_REVERSE
368 : | DNS_ZONE_REQUEST_FORWARDER
369 : | DNS_ZONE_REQUEST_STUB
370 : | DNS_ZONE_REQUEST_DS
371 : | DNS_ZONE_REQUEST_NON_DS
372 : | DNS_ZONE_REQUEST_DOMAIN_DP
373 : | DNS_ZONE_REQUEST_FOREST_DP
374 : | DNS_ZONE_REQUEST_CUSTOM_DP
375 : | DNS_ZONE_REQUEST_LEGACY_DP;
376 1220 : } else if (strcmp(zone_name, "..AllZonesAndCache") == 0) {
377 0 : request_filter = DNS_ZONE_REQUEST_PRIMARY
378 : | DNS_ZONE_REQUEST_SECONDARY
379 : | DNS_ZONE_REQUEST_CACHE
380 : | DNS_ZONE_REQUEST_AUTO
381 : | DNS_ZONE_REQUEST_FORWARD
382 : | DNS_ZONE_REQUEST_REVERSE
383 : | DNS_ZONE_REQUEST_FORWARDER
384 : | DNS_ZONE_REQUEST_STUB
385 : | DNS_ZONE_REQUEST_DS
386 : | DNS_ZONE_REQUEST_NON_DS
387 : | DNS_ZONE_REQUEST_DOMAIN_DP
388 : | DNS_ZONE_REQUEST_FOREST_DP
389 : | DNS_ZONE_REQUEST_CUSTOM_DP
390 : | DNS_ZONE_REQUEST_LEGACY_DP;
391 1220 : } else if (strcmp(zone_name, "..AllPrimaryZones") == 0) {
392 0 : request_filter = DNS_ZONE_REQUEST_PRIMARY;
393 1220 : } else if (strcmp(zone_name, "..AllSecondaryZones") == 0) {
394 0 : request_filter = DNS_ZONE_REQUEST_SECONDARY;
395 1220 : } else if (strcmp(zone_name, "..AllForwardZones") == 0) {
396 0 : request_filter = DNS_ZONE_REQUEST_FORWARD;
397 1220 : } else if (strcmp(zone_name, "..AllReverseZones") == 0) {
398 0 : request_filter = DNS_ZONE_REQUEST_REVERSE;
399 1220 : } else if (strcmp(zone_name, "..AllDsZones") == 0) {
400 0 : request_filter = DNS_ZONE_REQUEST_DS;
401 1220 : } else if (strcmp(zone_name, "..AllNonDsZones") == 0) {
402 0 : request_filter = DNS_ZONE_REQUEST_NON_DS;
403 1220 : } else if (strcmp(zone_name, "..AllPrimaryReverseZones") == 0) {
404 0 : request_filter = DNS_ZONE_REQUEST_PRIMARY
405 : | DNS_ZONE_REQUEST_REVERSE;
406 1220 : } else if (strcmp(zone_name, "..AllPrimaryForwardZones") == 0) {
407 0 : request_filter = DNS_ZONE_REQUEST_PRIMARY
408 : | DNS_ZONE_REQUEST_FORWARD;
409 1220 : } else if (strcmp(zone_name, "..AllSecondaryReverseZones") == 0) {
410 0 : request_filter = DNS_ZONE_REQUEST_SECONDARY
411 : | DNS_ZONE_REQUEST_REVERSE;
412 1220 : } else if (strcmp(zone_name, "..AllSecondaryForwardZones") == 0) {
413 0 : request_filter = DNS_ZONE_REQUEST_SECONDARY
414 : | DNS_ZONE_REQUEST_REVERSE;
415 : }
416 :
417 1220 : return request_filter;
418 : }
|