s4:selftest: correctly copy a python list into a temporary variable
[Samba.git] / source4 / rpc_server / dnsserver / dnsutils.c
blob72b47f72b4fdfb9f6e0e52b8ed3341e32497a992
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 "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,
31 bool listen_only)
33 struct interface *ifaces;
34 int num_interfaces, i;
35 struct DNS_ADDR_ARRAY *dns_addr_array;
36 const char *ipstr;
37 bool have_ipv4, have_ipv6;
38 uint16_t family;
40 have_ipv4 = have_ipv6 = false;
42 if (!listen_only) {
44 Return all interfaces from kernel
45 Not implemented!
47 return NULL;
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) {
56 goto nomem;
58 dns_addr_array->MaxCount = num_interfaces;
59 dns_addr_array->AddrCount = num_interfaces;
60 if (num_interfaces == 0) {
61 goto nomem;
64 dns_addr_array->AddrArray = talloc_zero_array(mem_ctx, struct DNS_ADDR,
65 num_interfaces);
66 if (!dns_addr_array->AddrArray) {
67 TALLOC_FREE(dns_addr_array);
68 goto nomem;
71 for (i = 0; i < num_interfaces; i++) {
72 ipstr = iface_list_n_ip(ifaces, i);
73 if (is_ipaddress_v4(ipstr)) {
74 have_ipv4 = true;
75 dns_addr_array->AddrArray[i].MaxSa[0] = 0x02;
76 inet_pton(AF_INET, ipstr,
77 &dns_addr_array->AddrArray[i].MaxSa[4]);
78 } else {
79 have_ipv6 = true;
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) {
89 family = AF_INET;
90 } else {
91 family = AF_INET6;
93 dns_addr_array->Family = family;
95 nomem:
96 talloc_free(ifaces);
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) {
110 return NULL;
113 dinfo = lpcfg_dcerpc_server_info(mem_ctx, lp_ctx);
114 if (dinfo) {
115 serverinfo->dwVersion = (dinfo->version_build & 0x0000FFFF) << 16 |
116 (dinfo->version_minor & 0x000000FF) << 8 |
117 (dinfo->version_major & 0x000000FF);
118 talloc_free(dinfo);
119 } else {
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
156 * Not implemented!
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;
204 return serverinfo;
208 struct dnsserver_zoneinfo *dnsserver_init_zoneinfo(struct dnsserver_zone *zone,
209 struct dnsserver_serverinfo *serverinfo)
211 struct dnsserver_zoneinfo *zoneinfo;
212 uint32_t fReverse;
213 const char *revzone = "in-addr.arpa";
214 const char *revzone6 = "ip6.arpa";
215 int len1, len2;
217 zoneinfo = talloc_zero(zone, struct dnsserver_zoneinfo);
218 if (zoneinfo == NULL) {
219 return 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) */
224 fReverse = 0;
225 len1 = strlen(zone->name);
226 len2 = strlen(revzone);
227 if (len1 > len2 && strcasecmp(&zone->name[len1-len2], revzone) == 0) {
228 fReverse = 1;
229 } else {
230 len2 = strlen(revzone6);
231 if (len1 > len2 && strcasecmp(&zone->name[len1-len2], revzone6) == 0) {
232 fReverse = 1;
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;
246 } else {
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;
282 return zoneinfo;
285 struct dnsserver_partition *dnsserver_find_partition(struct dnsserver_partition *partitions,
286 const char *dp_fqdn)
288 struct dnsserver_partition *p = NULL;
290 for (p = partitions; p; p = p->next) {
291 if (strcasecmp(dp_fqdn, p->pszDpFqdn) == 0) {
292 break;
296 return p;
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) {
305 break;
309 return z;
312 struct ldb_dn *dnsserver_name_to_dn(TALLOC_CTX *mem_ctx, struct dnsserver_zone *z, const char *name)
314 struct ldb_dn *dn;
315 bool ret;
317 dn = ldb_dn_copy(mem_ctx, z->zone_dn);
318 if (dn == NULL) {
319 return NULL;
321 if (strcasecmp(name, z->name) == 0) {
322 ret = ldb_dn_add_child_fmt(dn, "DC=@");
323 } else {
324 ret = ldb_dn_add_child_fmt(dn, "DC=%s", name);
326 if (!ret) {
327 talloc_free(dn);
328 return NULL;
331 return dn;
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;