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