3ae47a8c5fb125a3458e1465150ee6015d659e2f
[ddiss/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 "dsdb/samdb/samdb.h"
26 #include "lib/socket/netif.h"
27
28
29 struct dnsserver_serverinfo *dnsserver_init_serverinfo(TALLOC_CTX *mem_ctx,
30                                                         struct loadparm_context *lp_ctx,
31                                                         struct ldb_context *samdb)
32 {
33         struct dnsserver_serverinfo *serverinfo;
34         struct dcerpc_server_info *dinfo;
35         struct ldb_dn *domain_dn, *forest_dn;
36         struct interface *ifaces;
37         int num_interfaces, i;
38
39         serverinfo = talloc_zero(mem_ctx, struct dnsserver_serverinfo);
40         if (serverinfo == NULL) {
41                 return NULL;
42         }
43
44         dinfo = lpcfg_dcerpc_server_info(mem_ctx, lp_ctx);
45         if (dinfo) {
46                 serverinfo->dwVersion = (dinfo->version_build & 0x0000FFFF) << 16 |
47                                 (dinfo->version_minor & 0x000000FF) << 8 |
48                                 (dinfo->version_major & 0x000000FF);
49                 talloc_free(dinfo);
50         } else {
51                 serverinfo->dwVersion = 0x0ECE0205; /* build, os_minor, os_major */;
52         }
53
54         serverinfo->fBootMethod = DNS_BOOT_METHOD_DIRECTORY;
55         serverinfo->fAdminConfigured = 0;
56         serverinfo->fAllowUpdate = 1;
57         serverinfo->fDsAvailable = 1;
58
59         serverinfo->pszServerName = talloc_asprintf(mem_ctx, "%s.%s",
60                                         lpcfg_netbios_name(lp_ctx),
61                                         lpcfg_dnsdomain(lp_ctx));
62
63         domain_dn = ldb_get_default_basedn(samdb);
64         forest_dn = ldb_get_root_basedn(samdb);
65
66         serverinfo->pszDsContainer = talloc_asprintf(mem_ctx,
67                                         "CN=MicrosoftDNS,DC=DomainDnsZones,%s",
68                                         ldb_dn_get_linearized(domain_dn));
69
70         serverinfo->dwDsForestVersion = dsdb_forest_functional_level(samdb);
71         serverinfo->dwDsDomainVersion = dsdb_functional_level(samdb);
72         serverinfo->dwDsDsaVersion = 4; /* need to do ldb search here */
73
74         serverinfo->pszDomainName = samdb_dn_to_dns_domain(mem_ctx, domain_dn);
75         serverinfo->pszForestName = samdb_dn_to_dns_domain(mem_ctx, forest_dn);
76
77         serverinfo->pszDomainDirectoryPartition = talloc_asprintf(mem_ctx,
78                                                         "DC=DomainDnsZones,%s",
79                                                         ldb_dn_get_linearized(domain_dn));
80         serverinfo->pszForestDirectoryPartition = talloc_asprintf(mem_ctx,
81                                                         "DC=ForestDnsZones,%s",
82                                                         ldb_dn_get_linearized(forest_dn));
83
84         load_interface_list(mem_ctx, lp_ctx, &ifaces);
85         num_interfaces = iface_list_count(ifaces);
86
87         serverinfo->aipServerAddrs = talloc_zero(mem_ctx, struct IP4_ARRAY);
88
89         if (serverinfo->aipServerAddrs) {
90                 serverinfo->aipServerAddrs->AddrCount = num_interfaces;
91                 if (num_interfaces > 0) {
92                         serverinfo->aipServerAddrs->AddrArray = talloc_zero_array(mem_ctx,
93                                                                         unsigned int,
94                                                                         num_interfaces);
95                         if (serverinfo->aipServerAddrs->AddrArray) {
96                                 for (i=0; i<num_interfaces; i++) {
97                                         serverinfo->aipServerAddrs->AddrArray[i] = inet_addr(iface_list_n_ip(ifaces, i));
98                                 }
99                         } else {
100                                 serverinfo->aipServerAddrs->AddrCount = 0;
101                         }
102                 }
103         }
104         talloc_free(ifaces);
105
106         /* Assume listen addresses are same as server addresses */
107         serverinfo->aipListenAddrs = serverinfo->aipServerAddrs;
108
109         serverinfo->aipForwarders = NULL;
110
111         serverinfo->aipLogFilter = NULL;
112         serverinfo->pwszLogFilePath = NULL;
113
114         serverinfo->dwLogLevel = 0;
115         serverinfo->dwDebugLevel = 0;
116         serverinfo->dwEventLogLevel = DNS_EVENT_LOG_INFORMATION_TYPE;
117         serverinfo->dwLogFileMaxSize = 0;
118
119         serverinfo->dwForwardTimeout = 3; /* seconds (default) */
120         serverinfo->dwRpcProtocol = 5;
121         serverinfo->dwNameCheckFlag = DNS_ALLOW_MULTIBYTE_NAMES;
122         serverinfo->cAddressAnswerLimit = 0;
123         serverinfo->dwRecursionRetry = 3 /* seconds (default) */;
124         serverinfo->dwRecursionTimeout = 8 /* seconds (default) */;
125         serverinfo->dwMaxCacheTtl = 0x00015180; /* 1 day (default) */;
126         serverinfo->dwDsPollingInterval = 0xB4; /* 3 minutes (default) */;
127         serverinfo->dwLocalNetPriorityNetMask = 0x000000FF;;
128
129         serverinfo->dwScavengingInterval = 0;
130         serverinfo->dwDefaultRefreshInterval = 0xA8; /* 7 days in hours */;
131         serverinfo->dwDefaultNoRefreshInterval = 0xA8; /* 7 days in hours */;;
132         serverinfo->dwLastScavengeTime = 0;
133
134         serverinfo->fAutoReverseZones = 0;
135         serverinfo->fAutoCacheUpdate = 0;
136
137         serverinfo->fRecurseAfterForwarding = 0;
138         serverinfo->fForwardDelegations = 1;
139         serverinfo->fNoRecursion = 0;
140         serverinfo->fSecureResponses = 0;
141
142         serverinfo->fRoundRobin = 1;
143         serverinfo->fLocalNetPriority = 0;
144
145         serverinfo->fBindSecondaries = 0;
146         serverinfo->fWriteAuthorityNs = 0;
147
148         serverinfo->fStrictFileParsing = 0;
149         serverinfo->fLooseWildcarding = 0 ;
150         serverinfo->fDefaultAgingState = 0;
151
152         return serverinfo;
153 }
154
155
156 struct dnsserver_zoneinfo *dnsserver_init_zoneinfo(struct dnsserver_zone *zone,
157                                                 struct dnsserver_serverinfo *serverinfo,
158                                                 bool is_forest)
159 {
160         struct dnsserver_zoneinfo *zoneinfo;
161         uint32_t dp_flags;
162         uint32_t fReverse;
163         const char *revzone = "in-addr.arpa";
164         int len1, len2;
165
166         zoneinfo = talloc_zero(zone, struct dnsserver_zoneinfo);
167         if (zoneinfo == NULL) {
168                 return NULL;
169         }
170
171         dp_flags = DNS_DP_AUTOCREATED | DNS_DP_ENLISTED;
172         if (is_forest) {
173                 dp_flags |= DNS_DP_FOREST_DEFAULT;
174         } else {
175                 dp_flags |= DNS_DP_DOMAIN_DEFAULT;
176         }
177
178         /* If the zone name ends with in-addr.arpa, it's reverse zone */
179         fReverse = 0;
180         len1 = strlen(zone->name);
181         len2 = strlen(revzone);
182         if (len1 > len2 && strcmp(&zone->name[len1-len2], revzone) == 0) {
183                 fReverse = 1;
184         }
185
186         zoneinfo->Version = 0x32;
187         zoneinfo->Flags = DNS_RPC_ZONE_DSINTEGRATED | DNS_RPC_ZONE_UPDATE_SECURE;
188         zoneinfo->dwZoneType = DNS_ZONE_TYPE_PRIMARY;
189         zoneinfo->fReverse = fReverse;
190         zoneinfo->fAllowUpdate = DNS_ZONE_UPDATE_SECURE;
191         zoneinfo->fPaused = 0;
192         zoneinfo->fShutdown = 0;
193         zoneinfo->fAutoCreated = 0;
194         zoneinfo->fUseDatabase = 1;
195         zoneinfo->pszDataFile = NULL;
196         zoneinfo->aipMasters = NULL;
197         zoneinfo->fSecureSecondaries = DNS_ZONE_SECSECURE_NO_XFER;
198         zoneinfo->fNotifyLevel = DNS_ZONE_NOTIFY_LIST_ONLY;
199         zoneinfo->aipSecondaries = NULL;
200         zoneinfo->aipNotify = NULL;
201         zoneinfo->fUseWins = 0;
202         zoneinfo->fUseNbstat = 0;
203         zoneinfo->fAging = 0;
204         zoneinfo->dwNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
205         zoneinfo->dwRefreshInterval = serverinfo->dwDefaultRefreshInterval;
206         zoneinfo->dwAvailForScavengeTime = 0;
207         zoneinfo->aipScavengeServers = NULL;
208         zoneinfo->dwForwarderTimeout = 0;
209         zoneinfo->fForwarderSlave = 0;
210         zoneinfo->aipLocalMasters = NULL;
211         zoneinfo->dwDpFlags = dp_flags;
212         zoneinfo->pszDpFqdn = samdb_dn_to_dns_domain(zone, zone->partition_dn);
213         zoneinfo->pwszZoneDn = discard_const_p(char, ldb_dn_get_linearized(zone->zone_dn));
214         zoneinfo->dwLastSuccessfulSoaCheck = 0;
215         zoneinfo->dwLastSuccessfulXfr = 0;
216         zoneinfo->fQueuedForBackgroundLoad = 0;
217         zoneinfo->fBackgroundLoadInProgress = 0;
218         zoneinfo->fReadOnlyZone = 0;
219         zoneinfo->dwLastXfrAttempt = 0;
220         zoneinfo->dwLastXfrResult = 0;
221
222         return zoneinfo;
223 }
224
225 struct dnsserver_zone *dnsserver_find_zone(struct dnsserver_zone *zones, const char *zone_name)
226 {
227         struct dnsserver_zone *z = NULL;
228
229         for (z = zones; z; z = z->next) {
230                 if (strcmp(zone_name, z->name) == 0) {
231                         break;
232                 }
233         }
234
235         return z;
236 }
237
238 struct ldb_dn *dnsserver_name_to_dn(TALLOC_CTX *mem_ctx, struct dnsserver_zone *z, const char *name)
239 {
240         struct ldb_dn *dn;
241         bool ret;
242
243         dn = ldb_dn_copy(mem_ctx, z->zone_dn);
244         if (dn == NULL) {
245                 return NULL;
246         }
247         if (strcmp(name, z->name) == 0) {
248                 ret = ldb_dn_add_child_fmt(dn, "DC=@");
249         } else {
250                 ret = ldb_dn_add_child_fmt(dn, "DC=%s", name);
251         }
252         if (!ret) {
253                 talloc_free(dn);
254                 return NULL;
255         }
256
257         return dn;
258 }
259
260 uint32_t dnsserver_zone_to_request_filter(const char *zone_name)
261 {
262         uint32_t request_filter;
263
264         if (strcmp(zone_name, "..AllZones") == 0) {
265                 request_filter = DNS_ZONE_REQUEST_PRIMARY
266                         | DNS_ZONE_REQUEST_SECONDARY
267                         | DNS_ZONE_REQUEST_AUTO
268                         | DNS_ZONE_REQUEST_FORWARD
269                         | DNS_ZONE_REQUEST_REVERSE
270                         | DNS_ZONE_REQUEST_FORWARDER
271                         | DNS_ZONE_REQUEST_STUB
272                         | DNS_ZONE_REQUEST_DS
273                         | DNS_ZONE_REQUEST_NON_DS
274                         | DNS_ZONE_REQUEST_DOMAIN_DP
275                         | DNS_ZONE_REQUEST_FOREST_DP
276                         | DNS_ZONE_REQUEST_CUSTOM_DP
277                         | DNS_ZONE_REQUEST_LEGACY_DP;
278         } else if (strcmp(zone_name, "..AllZonesAndCache") == 0) {
279                 request_filter = DNS_ZONE_REQUEST_PRIMARY
280                         | DNS_ZONE_REQUEST_SECONDARY
281                         | DNS_ZONE_REQUEST_CACHE
282                         | DNS_ZONE_REQUEST_AUTO
283                         | DNS_ZONE_REQUEST_FORWARD
284                         | DNS_ZONE_REQUEST_REVERSE
285                         | DNS_ZONE_REQUEST_FORWARDER
286                         | DNS_ZONE_REQUEST_STUB
287                         | DNS_ZONE_REQUEST_DS
288                         | DNS_ZONE_REQUEST_NON_DS
289                         | DNS_ZONE_REQUEST_DOMAIN_DP
290                         | DNS_ZONE_REQUEST_FOREST_DP
291                         | DNS_ZONE_REQUEST_CUSTOM_DP
292                         | DNS_ZONE_REQUEST_LEGACY_DP;
293         } else if (strcmp(zone_name, "..AllPrimaryZones") == 0) {
294                 request_filter = DNS_ZONE_REQUEST_PRIMARY;
295         } else if (strcmp(zone_name, "..AllSecondaryZones") == 0) {
296                 request_filter = DNS_ZONE_REQUEST_SECONDARY;
297         } else if (strcmp(zone_name, "..AllForwardZones") == 0) {
298                 request_filter = DNS_ZONE_REQUEST_FORWARD;
299         } else if (strcmp(zone_name, "..AllReverseZones") == 0) {
300                 request_filter = DNS_ZONE_REQUEST_REVERSE;
301         } else if (strcmp(zone_name, "..AllDsZones") == 0) {
302                 request_filter = DNS_ZONE_REQUEST_DS;
303         } else if (strcmp(zone_name, "..AllNonDsZones") == 0) {
304                 request_filter = DNS_ZONE_REQUEST_NON_DS;
305         } else if (strcmp(zone_name, "..AllPrimaryReverseZones") == 0) {
306                 request_filter = DNS_ZONE_REQUEST_PRIMARY
307                         | DNS_ZONE_REQUEST_REVERSE;
308         } else if (strcmp(zone_name, "..AllPrimaryForwardZones") == 0) {
309                 request_filter = DNS_ZONE_REQUEST_PRIMARY
310                         | DNS_ZONE_REQUEST_FORWARD;
311         } else if (strcmp(zone_name, "..AllSecondaryReverseZones") == 0) {
312                 request_filter = DNS_ZONE_REQUEST_SECONDARY
313                         | DNS_ZONE_REQUEST_REVERSE;
314         } else if (strcmp(zone_name, "..AllSecondaryForwardZones") == 0) {
315                 request_filter = DNS_ZONE_REQUEST_SECONDARY
316                         | DNS_ZONE_REQUEST_REVERSE;
317         }
318
319         return request_filter;
320 }