smbd: Remove an unnecessary if-statement
[Samba.git] / source4 / rpc_server / dnsserver / dnsutils.c
blob56b2690aa959053cf076b62e4f0248ed174b0b0b
1 /*
2 Unix SMB/CIFS implementation.
4 DNS Server
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/>.
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"
31 #undef strcasecmp
33 static struct DNS_ADDR_ARRAY *fill_dns_addr_array(TALLOC_CTX *mem_ctx,
34 struct loadparm_context *lp_ctx,
35 bool listen_only)
37 struct interface *ifaces;
38 int num_interfaces, i;
39 struct DNS_ADDR_ARRAY *dns_addr_array;
40 const char *ipstr;
41 bool have_ipv4, have_ipv6;
42 uint16_t family;
44 have_ipv4 = have_ipv6 = false;
46 if (!listen_only) {
48 Return all interfaces from kernel
49 Not implemented!
51 return NULL;
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) {
60 goto nomem;
62 dns_addr_array->MaxCount = num_interfaces;
63 dns_addr_array->AddrCount = num_interfaces;
64 if (num_interfaces == 0) {
65 goto nomem;
68 dns_addr_array->AddrArray = talloc_zero_array(mem_ctx, struct DNS_ADDR,
69 num_interfaces);
70 if (!dns_addr_array->AddrArray) {
71 TALLOC_FREE(dns_addr_array);
72 goto nomem;
75 for (i = 0; i < num_interfaces; i++) {
76 int ret;
77 ipstr = iface_list_n_ip(ifaces, i);
78 if (is_ipaddress_v4(ipstr)) {
79 have_ipv4 = true;
80 dns_addr_array->AddrArray[i].MaxSa[0] = 0x02;
81 ret = inet_pton(AF_INET, ipstr,
82 &dns_addr_array->AddrArray[i].MaxSa[4]);
83 } else {
84 have_ipv6 = true;
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",
91 i, ipstr);
92 goto nomem;
96 if (have_ipv4 && have_ipv6) {
97 family = 0; /* mixed: MS-DNSP */
98 } else if (have_ipv4 && !have_ipv6) {
99 family = AF_INET;
100 } else {
101 family = AF_INET6;
103 dns_addr_array->Family = family;
105 nomem:
106 talloc_free(ifaces);
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) {
120 return NULL;
123 dinfo = lpcfg_dcerpc_server_info(mem_ctx, lp_ctx);
124 if (dinfo) {
125 serverinfo->dwVersion = (dinfo->version_build & 0x0000FFFF) << 16 |
126 (dinfo->version_minor & 0x000000FF) << 8 |
127 (dinfo->version_major & 0x000000FF);
128 talloc_free(dinfo);
129 } else {
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
166 * Not implemented!
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;
218 return serverinfo;
221 struct dnsserver_zoneinfo *dnsserver_init_zoneinfo(struct dnsserver_zone *zone,
222 struct dnsserver_serverinfo *serverinfo)
224 struct dnsserver_zoneinfo *zoneinfo;
225 uint32_t fReverse;
226 const char *revzone = "in-addr.arpa";
227 const char *revzone6 = "ip6.arpa";
228 int len1, len2;
229 unsigned int i = 0;
231 zoneinfo = talloc_zero(zone, struct dnsserver_zoneinfo);
232 if (zoneinfo == NULL) {
233 return 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) */
238 fReverse = 0;
239 len1 = strlen(zone->name);
240 len2 = strlen(revzone);
241 if (len1 > len2 && strcasecmp(&zone->name[len1-len2], revzone) == 0) {
242 fReverse = 1;
243 } else {
244 len2 = strlen(revzone6);
245 if (len1 > len2 && strcasecmp(&zone->name[len1-len2], revzone6) == 0) {
246 fReverse = 1;
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;
260 } else {
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++){
297 bool valid_property;
298 valid_property = dns_zoneinfo_load_zone_property(
299 zoneinfo, &zone->tmp_props[i]);
300 if (!valid_property) {
301 TALLOC_FREE(zoneinfo);
302 return NULL;
306 return 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)) {
315 break;
319 return z;
322 struct ldb_dn *dnsserver_name_to_dn(TALLOC_CTX *mem_ctx, struct dnsserver_zone *z, const char *name)
324 struct ldb_dn *dn;
325 bool ret;
326 struct ldb_val name_val =
327 data_blob_string_const(name);
329 dn = ldb_dn_copy(mem_ctx, z->zone_dn);
330 if (dn == NULL) {
331 return NULL;
333 if (strcasecmp(name, z->name) == 0) {
334 ret = ldb_dn_add_child_fmt(dn, "DC=@");
335 if (!ret) {
336 talloc_free(dn);
337 return NULL;
339 return dn;
342 ret = ldb_dn_add_child_val(dn,
343 "DC",
344 name_val);
346 if (!ret) {
347 talloc_free(dn);
348 return NULL;
351 return 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;