dns: prevent self-referencing CNAME
[Samba.git] / source4 / rpc_server / dnsserver / dcerpc_dnsserver.c
blobedea2b33f2d2fdb0354f6aa6ee2574e467a08b41
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 "talloc.h"
24 #include "rpc_server/dcerpc_server.h"
25 #include "dsdb/samdb/samdb.h"
26 #include "lib/util/dlinklist.h"
27 #include "librpc/gen_ndr/ndr_dnsserver.h"
28 #include "dns_server/dnsserver_common.h"
29 #include "dnsserver.h"
31 #define DCESRV_INTERFACE_DNSSERVER_BIND(call, iface) \
32 dcesrv_interface_dnsserver_bind(call, iface)
33 static NTSTATUS dcesrv_interface_dnsserver_bind(struct dcesrv_call_state *dce_call,
34 const struct dcesrv_interface *iface)
36 return dcesrv_interface_bind_require_integrity(dce_call, iface);
39 struct dnsserver_state {
40 struct loadparm_context *lp_ctx;
41 struct ldb_context *samdb;
42 struct dnsserver_partition *partitions;
43 struct dnsserver_zone *zones;
44 int zones_count;
45 struct dnsserver_serverinfo *serverinfo;
49 /* Utility functions */
51 static void dnsserver_reload_zones(struct dnsserver_state *dsstate)
53 struct dnsserver_partition *p;
54 struct dnsserver_zone *zones, *z, *znext, *zmatch;
55 struct dnsserver_zone *old_list, *new_list;
57 old_list = dsstate->zones;
58 new_list = NULL;
60 for (p = dsstate->partitions; p; p = p->next) {
61 zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, p);
62 if (zones == NULL) {
63 continue;
65 for (z = zones; z; ) {
66 znext = z->next;
67 zmatch = dnsserver_find_zone(old_list, z->name);
68 if (zmatch == NULL) {
69 /* Missing zone */
70 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
71 if (z->zoneinfo == NULL) {
72 continue;
74 DLIST_ADD_END(new_list, z);
75 p->zones_count++;
76 dsstate->zones_count++;
77 } else {
78 /* Existing zone */
79 talloc_free(z);
80 DLIST_REMOVE(old_list, zmatch);
81 DLIST_ADD_END(new_list, zmatch);
83 z = znext;
87 if (new_list == NULL) {
88 return;
91 /* Deleted zones */
92 for (z = old_list; z; ) {
93 znext = z->next;
94 z->partition->zones_count--;
95 dsstate->zones_count--;
96 talloc_free(z);
97 z = znext;
100 dsstate->zones = new_list;
104 static struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_call)
106 struct dnsserver_state *dsstate;
107 struct dnsserver_zone *zones, *z, *znext;
108 struct dnsserver_partition *partitions, *p;
110 dsstate = talloc_get_type(dce_call->context->private_data, struct dnsserver_state);
111 if (dsstate != NULL) {
112 return dsstate;
115 dsstate = talloc_zero(dce_call->context, struct dnsserver_state);
116 if (dsstate == NULL) {
117 return NULL;
120 dsstate->lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
122 /* FIXME: create correct auth_session_info for connecting user */
123 dsstate->samdb = samdb_connect(dsstate,
124 dce_call->event_ctx,
125 dsstate->lp_ctx,
126 dce_call->conn->auth_state.session_info,
127 dce_call->conn->remote_address,
129 if (dsstate->samdb == NULL) {
130 DEBUG(0,("dnsserver: Failed to open samdb"));
131 goto failed;
134 /* Initialize server info */
135 dsstate->serverinfo = dnsserver_init_serverinfo(dsstate,
136 dsstate->lp_ctx,
137 dsstate->samdb);
138 if (dsstate->serverinfo == NULL) {
139 goto failed;
142 /* Search for DNS partitions */
143 partitions = dnsserver_db_enumerate_partitions(dsstate, dsstate->serverinfo, dsstate->samdb);
144 if (partitions == NULL) {
145 goto failed;
147 dsstate->partitions = partitions;
149 /* Search for DNS zones */
150 for (p = partitions; p; p = p->next) {
151 zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, p);
152 if (zones == NULL) {
153 goto failed;
155 for (z = zones; z; ) {
156 znext = z->next;
157 if (dnsserver_find_zone(dsstate->zones, z->name) == NULL) {
158 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
159 if (z->zoneinfo == NULL) {
160 goto failed;
162 DLIST_ADD_END(dsstate->zones, z);
163 p->zones_count++;
164 dsstate->zones_count++;
165 } else {
166 /* Ignore duplicate zone */
167 DEBUG(3,("dnsserver: Ignoring duplicate zone '%s' from '%s'",
168 z->name, ldb_dn_get_linearized(z->zone_dn)));
170 z = znext;
174 dce_call->context->private_data = dsstate;
176 return dsstate;
178 failed:
179 talloc_free(dsstate);
180 dsstate = NULL;
181 return NULL;
185 /* dnsserver query functions */
187 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
188 static WERROR dnsserver_query_server(struct dnsserver_state *dsstate,
189 TALLOC_CTX *mem_ctx,
190 const char *operation,
191 const unsigned int client_version,
192 enum DNS_RPC_TYPEID *typeid,
193 union DNSSRV_RPC_UNION *r)
195 uint8_t is_integer, is_addresses, is_string, is_wstring, is_stringlist;
196 uint32_t answer_integer;
197 struct IP4_ARRAY *answer_iparray;
198 struct DNS_ADDR_ARRAY *answer_addrarray;
199 char *answer_string;
200 struct DNS_RPC_UTF8_STRING_LIST *answer_stringlist;
201 struct dnsserver_serverinfo *serverinfo;
203 serverinfo = dsstate->serverinfo;
205 if (strcasecmp(operation, "ServerInfo") == 0) {
206 if (client_version == DNS_CLIENT_VERSION_W2K) {
207 *typeid = DNSSRV_TYPEID_SERVER_INFO_W2K;
208 r->ServerInfoW2K = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_W2K);
210 r->ServerInfoW2K->dwVersion = serverinfo->dwVersion;
211 r->ServerInfoW2K->fBootMethod = serverinfo->fBootMethod;
212 r->ServerInfoW2K->fAdminConfigured = serverinfo->fAdminConfigured;
213 r->ServerInfoW2K->fAllowUpdate = serverinfo->fAllowUpdate;
214 r->ServerInfoW2K->fDsAvailable = serverinfo->fDsAvailable;
215 r->ServerInfoW2K->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
216 r->ServerInfoW2K->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
217 r->ServerInfoW2K->aipServerAddrs = dns_addr_array_to_ip4_array(mem_ctx,
218 serverinfo->aipServerAddrs);
219 r->ServerInfoW2K->aipListenAddrs = dns_addr_array_to_ip4_array(mem_ctx,
220 serverinfo->aipListenAddrs);
221 r->ServerInfoW2K->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
222 r->ServerInfoW2K->dwLogLevel = serverinfo->dwLogLevel;
223 r->ServerInfoW2K->dwDebugLevel = serverinfo->dwDebugLevel;
224 r->ServerInfoW2K->dwForwardTimeout = serverinfo->dwForwardTimeout;
225 r->ServerInfoW2K->dwRpcProtocol = serverinfo->dwRpcProtocol;
226 r->ServerInfoW2K->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
227 r->ServerInfoW2K->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
228 r->ServerInfoW2K->dwRecursionRetry = serverinfo->dwRecursionRetry;
229 r->ServerInfoW2K->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
230 r->ServerInfoW2K->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
231 r->ServerInfoW2K->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
232 r->ServerInfoW2K->dwScavengingInterval = serverinfo->dwScavengingInterval;
233 r->ServerInfoW2K->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
234 r->ServerInfoW2K->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
235 r->ServerInfoW2K->fAutoReverseZones = serverinfo->fAutoReverseZones;
236 r->ServerInfoW2K->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
237 r->ServerInfoW2K->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
238 r->ServerInfoW2K->fForwardDelegations = serverinfo->fForwardDelegations;
239 r->ServerInfoW2K->fNoRecursion = serverinfo->fNoRecursion;
240 r->ServerInfoW2K->fSecureResponses = serverinfo->fSecureResponses;
241 r->ServerInfoW2K->fRoundRobin = serverinfo->fRoundRobin;
242 r->ServerInfoW2K->fLocalNetPriority = serverinfo->fLocalNetPriority;
243 r->ServerInfoW2K->fBindSecondaries = serverinfo->fBindSecondaries;
244 r->ServerInfoW2K->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
245 r->ServerInfoW2K->fStrictFileParsing = serverinfo->fStrictFileParsing;
246 r->ServerInfoW2K->fLooseWildcarding = serverinfo->fLooseWildcarding;
247 r->ServerInfoW2K->fDefaultAgingState = serverinfo->fDefaultAgingState;
249 } else if (client_version == DNS_CLIENT_VERSION_DOTNET) {
250 *typeid = DNSSRV_TYPEID_SERVER_INFO_DOTNET;
251 r->ServerInfoDotNet = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_DOTNET);
253 r->ServerInfoDotNet->dwRpcStructureVersion = 0x01;
254 r->ServerInfoDotNet->dwVersion = serverinfo->dwVersion;
255 r->ServerInfoDotNet->fBootMethod = serverinfo->fBootMethod;
256 r->ServerInfoDotNet->fAdminConfigured = serverinfo->fAdminConfigured;
257 r->ServerInfoDotNet->fAllowUpdate = serverinfo->fAllowUpdate;
258 r->ServerInfoDotNet->fDsAvailable = serverinfo->fDsAvailable;
259 r->ServerInfoDotNet->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
260 r->ServerInfoDotNet->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
261 r->ServerInfoDotNet->aipServerAddrs = dns_addr_array_to_ip4_array(mem_ctx,
262 serverinfo->aipServerAddrs);
263 r->ServerInfoDotNet->aipListenAddrs = dns_addr_array_to_ip4_array(mem_ctx,
264 serverinfo->aipListenAddrs);
265 r->ServerInfoDotNet->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
266 r->ServerInfoDotNet->aipLogFilter = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
267 r->ServerInfoDotNet->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
268 r->ServerInfoDotNet->pszDomainName = talloc_strdup(mem_ctx, serverinfo->pszDomainName);
269 r->ServerInfoDotNet->pszForestName = talloc_strdup(mem_ctx, serverinfo->pszForestName);
270 r->ServerInfoDotNet->pszDomainDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszDomainDirectoryPartition);
271 r->ServerInfoDotNet->pszForestDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszForestDirectoryPartition);
272 r->ServerInfoDotNet->dwLogLevel = serverinfo->dwLogLevel;
273 r->ServerInfoDotNet->dwDebugLevel = serverinfo->dwDebugLevel;
274 r->ServerInfoDotNet->dwForwardTimeout = serverinfo->dwForwardTimeout;
275 r->ServerInfoDotNet->dwRpcProtocol = serverinfo->dwRpcProtocol;
276 r->ServerInfoDotNet->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
277 r->ServerInfoDotNet->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
278 r->ServerInfoDotNet->dwRecursionRetry = serverinfo->dwRecursionRetry;
279 r->ServerInfoDotNet->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
280 r->ServerInfoDotNet->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
281 r->ServerInfoDotNet->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
282 r->ServerInfoDotNet->dwLocalNetPriorityNetMask = serverinfo->dwLocalNetPriorityNetMask;
283 r->ServerInfoDotNet->dwScavengingInterval = serverinfo->dwScavengingInterval;
284 r->ServerInfoDotNet->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
285 r->ServerInfoDotNet->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
286 r->ServerInfoDotNet->dwLastScavengeTime = serverinfo->dwLastScavengeTime;
287 r->ServerInfoDotNet->dwEventLogLevel = serverinfo->dwEventLogLevel;
288 r->ServerInfoDotNet->dwLogFileMaxSize = serverinfo->dwLogFileMaxSize;
289 r->ServerInfoDotNet->dwDsForestVersion = serverinfo->dwDsForestVersion;
290 r->ServerInfoDotNet->dwDsDomainVersion = serverinfo->dwDsDomainVersion;
291 r->ServerInfoDotNet->dwDsDsaVersion = serverinfo->dwDsDsaVersion;
292 r->ServerInfoDotNet->fAutoReverseZones = serverinfo->fAutoReverseZones;
293 r->ServerInfoDotNet->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
294 r->ServerInfoDotNet->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
295 r->ServerInfoDotNet->fForwardDelegations = serverinfo->fForwardDelegations;
296 r->ServerInfoDotNet->fNoRecursion = serverinfo->fNoRecursion;
297 r->ServerInfoDotNet->fSecureResponses = serverinfo->fSecureResponses;
298 r->ServerInfoDotNet->fRoundRobin = serverinfo->fRoundRobin;
299 r->ServerInfoDotNet->fLocalNetPriority = serverinfo->fLocalNetPriority;
300 r->ServerInfoDotNet->fBindSecondaries = serverinfo->fBindSecondaries;
301 r->ServerInfoDotNet->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
302 r->ServerInfoDotNet->fStrictFileParsing = serverinfo->fStrictFileParsing;
303 r->ServerInfoDotNet->fLooseWildcarding = serverinfo->fLooseWildcarding;
304 r->ServerInfoDotNet->fDefaultAgingState = serverinfo->fDefaultAgingState;
306 } else if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
307 *typeid = DNSSRV_TYPEID_SERVER_INFO;
308 r->ServerInfo = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_LONGHORN);
310 r->ServerInfo->dwRpcStructureVersion = 0x02;
311 r->ServerInfo->dwVersion = serverinfo->dwVersion;
312 r->ServerInfo->fBootMethod = serverinfo->fBootMethod;
313 r->ServerInfo->fAdminConfigured = serverinfo->fAdminConfigured;
314 r->ServerInfo->fAllowUpdate = serverinfo->fAllowUpdate;
315 r->ServerInfo->fDsAvailable = serverinfo->fDsAvailable;
316 r->ServerInfo->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
317 r->ServerInfo->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
318 r->ServerInfo->aipServerAddrs = serverinfo->aipServerAddrs;
319 r->ServerInfo->aipListenAddrs = serverinfo->aipListenAddrs;
320 r->ServerInfo->aipForwarders = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders);
321 r->ServerInfo->aipLogFilter = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter);
322 r->ServerInfo->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
323 r->ServerInfo->pszDomainName = talloc_strdup(mem_ctx, serverinfo->pszDomainName);
324 r->ServerInfo->pszForestName = talloc_strdup(mem_ctx, serverinfo->pszForestName);
325 r->ServerInfo->pszDomainDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszDomainDirectoryPartition);
326 r->ServerInfo->pszForestDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszForestDirectoryPartition);
327 r->ServerInfo->dwLogLevel = serverinfo->dwLogLevel;
328 r->ServerInfo->dwDebugLevel = serverinfo->dwDebugLevel;
329 r->ServerInfo->dwForwardTimeout = serverinfo->dwForwardTimeout;
330 r->ServerInfo->dwRpcProtocol = serverinfo->dwRpcProtocol;
331 r->ServerInfo->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
332 r->ServerInfo->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
333 r->ServerInfo->dwRecursionRetry = serverinfo->dwRecursionRetry;
334 r->ServerInfo->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
335 r->ServerInfo->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
336 r->ServerInfo->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
337 r->ServerInfo->dwLocalNetPriorityNetMask = serverinfo->dwLocalNetPriorityNetMask;
338 r->ServerInfo->dwScavengingInterval = serverinfo->dwScavengingInterval;
339 r->ServerInfo->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
340 r->ServerInfo->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
341 r->ServerInfo->dwLastScavengeTime = serverinfo->dwLastScavengeTime;
342 r->ServerInfo->dwEventLogLevel = serverinfo->dwEventLogLevel;
343 r->ServerInfo->dwLogFileMaxSize = serverinfo->dwLogFileMaxSize;
344 r->ServerInfo->dwDsForestVersion = serverinfo->dwDsForestVersion;
345 r->ServerInfo->dwDsDomainVersion = serverinfo->dwDsDomainVersion;
346 r->ServerInfo->dwDsDsaVersion = serverinfo->dwDsDsaVersion;
347 r->ServerInfo->fReadOnlyDC = serverinfo->fReadOnlyDC;
348 r->ServerInfo->fAutoReverseZones = serverinfo->fAutoReverseZones;
349 r->ServerInfo->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
350 r->ServerInfo->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
351 r->ServerInfo->fForwardDelegations = serverinfo->fForwardDelegations;
352 r->ServerInfo->fNoRecursion = serverinfo->fNoRecursion;
353 r->ServerInfo->fSecureResponses = serverinfo->fSecureResponses;
354 r->ServerInfo->fRoundRobin = serverinfo->fRoundRobin;
355 r->ServerInfo->fLocalNetPriority = serverinfo->fLocalNetPriority;
356 r->ServerInfo->fBindSecondaries = serverinfo->fBindSecondaries;
357 r->ServerInfo->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
358 r->ServerInfo->fStrictFileParsing = serverinfo->fStrictFileParsing;
359 r->ServerInfo->fLooseWildcarding = serverinfo->fLooseWildcarding;
360 r->ServerInfo->fDefaultAgingState = serverinfo->fDefaultAgingState;
362 return WERR_OK;
365 is_integer = 0;
367 if (strcasecmp(operation, "AddressAnswerLimit") == 0) {
368 answer_integer = serverinfo->cAddressAnswerLimit;
369 is_integer = 1;
370 } else if (strcasecmp(operation, "AdminConfigured") == 0) {
371 answer_integer = serverinfo->fAdminConfigured;
372 is_integer = 1;
373 } else if (strcasecmp(operation, "AllowCNAMEAtNS") == 0) {
374 answer_integer = 0;
375 is_integer = 1;
376 } else if (strcasecmp(operation, "AllowUpdate") == 0) {
377 answer_integer = serverinfo->fAllowUpdate;
378 is_integer = 1;
379 } else if (strcasecmp(operation, "AutoCacheUpdate") == 0) {
380 answer_integer = serverinfo->fAutoCacheUpdate;
381 is_integer = 1;
382 } else if (strcasecmp(operation, "AutoConfigFileZones") == 0) {
383 answer_integer = 1;
384 is_integer = 1;
385 } else if (strcasecmp(operation, "BindSecondaries") == 0) {
386 answer_integer = serverinfo->fBindSecondaries;
387 is_integer = 1;
388 } else if (strcasecmp(operation, "BootMethod") == 0) {
389 answer_integer = serverinfo->fBootMethod;
390 is_integer = 1;
391 } else if (strcasecmp(operation, "DebugLevel") == 0) {
392 answer_integer = serverinfo->dwDebugLevel;
393 is_integer = 1;
394 } else if (strcasecmp(operation, "DefaultAgingState") == 0) {
395 answer_integer = serverinfo->fDefaultAgingState;
396 is_integer = 1;
397 } else if (strcasecmp(operation, "DefaultNoRefreshInterval") == 0) {
398 answer_integer = serverinfo->dwDefaultNoRefreshInterval;
399 is_integer = 1;
400 } else if (strcasecmp(operation, "DefaultRefreshInterval") == 0) {
401 answer_integer = serverinfo->dwDefaultRefreshInterval;
402 is_integer = 1;
403 } else if (strcasecmp(operation, "DeleteOutsideGlue") == 0) {
404 answer_integer = 0;
405 is_integer = 1;
406 } else if (strcasecmp(operation, "DisjointNets") == 0) {
407 answer_integer = 0;
408 is_integer = 1;
409 } else if (strcasecmp(operation, "DsLazyUpdateInterval") == 0) {
410 answer_integer = 3; /* seconds */
411 is_integer = 1;
412 } else if (strcasecmp(operation, "DsPollingInterval") == 0) {
413 answer_integer = serverinfo->dwDsPollingInterval;
414 is_integer = 1;
415 } else if (strcasecmp(operation, "DsTombstoneInterval") == 0) {
416 answer_integer = 0x00127500; /* 14 days */
417 is_integer = 1;
418 } else if (strcasecmp(operation, "EnableRegistryBoot") == 0) {
419 answer_integer = 0;
420 is_integer = 1;
421 } else if (strcasecmp(operation, "EventLogLevel") == 0) {
422 answer_integer = serverinfo->dwEventLogLevel;
423 is_integer = 1;
424 } else if (strcasecmp(operation, "ForceSoaSerial") == 0) {
425 answer_integer = 0;
426 is_integer = 1;
427 } else if (strcasecmp(operation, "ForceSaoRetry") == 0) {
428 answer_integer = 0;
429 is_integer = 1;
430 } else if (strcasecmp(operation, "ForceSoaRefresh") == 0) {
431 answer_integer = 0;
432 is_integer = 1;
433 } else if (strcasecmp(operation, "ForceSoaMinimumTtl") == 0) {
434 answer_integer = 0;
435 is_integer = 1;
436 } else if (strcasecmp(operation, "ForwardDelegations") == 0) {
437 answer_integer = 1;
438 is_integer = 1;
439 } else if (strcasecmp(operation, "ForwardingTimeout") == 0) {
440 answer_integer = serverinfo->dwForwardTimeout;
441 is_integer = 1;
442 } else if (strcasecmp(operation, "IsSlave") == 0) {
443 answer_integer = 0;
444 is_integer = 1;
445 } else if (strcasecmp(operation, "LocalNetPriority") == 0) {
446 answer_integer = serverinfo->fLocalNetPriority;
447 is_integer = 1;
448 } else if (strcasecmp(operation, "LogFileMaxSize") == 0) {
449 answer_integer = serverinfo->dwLogFileMaxSize;
450 is_integer = 1;
451 } else if (strcasecmp(operation, "LogLevel") == 0) {
452 answer_integer = serverinfo->dwLogLevel;
453 is_integer = 1;
454 } else if (strcasecmp(operation, "LooseWildcarding") == 0) {
455 answer_integer = serverinfo->fLooseWildcarding;
456 is_integer = 1;
457 } else if (strcasecmp(operation, "MaxCacheTtl") == 0) {
458 answer_integer = serverinfo->dwMaxCacheTtl;
459 is_integer = 1;
460 } else if (strcasecmp(operation, "MaxNegativeCacheTtl") == 0) {
461 answer_integer = 0x00000384; /* 15 minutes */
462 is_integer = 1;
463 } else if (strcasecmp(operation, "NameCheckFlag") == 0) {
464 answer_integer = serverinfo->dwNameCheckFlag;
465 is_integer = 1;
466 } else if (strcasecmp(operation, "NoRecursion") == 0) {
467 answer_integer = serverinfo->fNoRecursion;
468 is_integer = 1;
469 } else if (strcasecmp(operation, "NoUpdateDelegations") == 0) {
470 answer_integer = 1;
471 is_integer = 1;
472 } else if (strcasecmp(operation, "PublishAutonet") == 0) {
473 answer_integer = 0;
474 is_integer = 1;
475 } else if (strcasecmp(operation, "QuietRecvFaultInterval") == 0) {
476 answer_integer = 0;
477 is_integer = 1;
478 } else if (strcasecmp(operation, "QuietRecvLogInterval") == 0) {
479 answer_integer = 0;
480 is_integer = 1;
481 } else if (strcasecmp(operation, "RecursionRetry") == 0) {
482 answer_integer = serverinfo->dwRecursionRetry;
483 is_integer = 1;
484 } else if (strcasecmp(operation, "RecursionTimeout") == 0) {
485 answer_integer = serverinfo->dwRecursionTimeout;
486 is_integer = 1;
487 } else if (strcasecmp(operation, "ReloadException") == 0) {
488 answer_integer = 0;
489 is_integer = 1;
490 } else if (strcasecmp(operation, "RoundRobin") == 0) {
491 answer_integer = serverinfo->fRoundRobin;
492 is_integer = 1;
493 } else if (strcasecmp(operation, "RpcProtocol") == 0) {
494 answer_integer = serverinfo->dwRpcProtocol;
495 is_integer = 1;
496 } else if (strcasecmp(operation, "SecureResponses") == 0) {
497 answer_integer = serverinfo->fSecureResponses;
498 is_integer = 1;
499 } else if (strcasecmp(operation, "SendPort") == 0) {
500 answer_integer = 0;
501 is_integer = 1;
502 } else if (strcasecmp(operation, "ScavengingInterval") == 0) {
503 answer_integer = serverinfo->dwScavengingInterval;
504 is_integer = 1;
505 } else if (strcasecmp(operation, "SocketPoolSize") == 0) {
506 answer_integer = 0x000009C4;
507 is_integer = 1;
508 } else if (strcasecmp(operation, "StrictFileParsing") == 0) {
509 answer_integer = serverinfo->fStrictFileParsing;
510 is_integer = 1;
511 } else if (strcasecmp(operation, "SyncDnsZoneSerial") == 0) {
512 answer_integer = 2; /* ZONE_SERIAL_SYNC_XFER */
513 is_integer = 1;
514 } else if (strcasecmp(operation, "UpdateOptions") == 0) {
515 answer_integer = 0x0000030F; /* DNS_DEFAULT_UPDATE_OPTIONS */
516 is_integer = 1;
517 } else if (strcasecmp(operation, "UseSystemEvengLog") == 0) {
518 answer_integer = 0;
519 is_integer = 1;
520 } else if (strcasecmp(operation, "Version") == 0) {
521 answer_integer = serverinfo->dwVersion;
522 is_integer = 1;
523 } else if (strcasecmp(operation, "XfrConnectTimeout") == 0) {
524 answer_integer = 0x0000001E;
525 is_integer = 1;
526 } else if (strcasecmp(operation, "WriteAuthorityNs") == 0) {
527 answer_integer = serverinfo->fWriteAuthorityNs;
528 is_integer = 1;
529 } else if (strcasecmp(operation, "AdditionalRecursionTimeout") == 0) {
530 answer_integer = 0x00000004;
531 is_integer = 1;
532 } else if (strcasecmp(operation, "AppendMsZoneTransferFlag") == 0) {
533 answer_integer = 0;
534 is_integer = 1;
535 } else if (strcasecmp(operation, "AutoCreateDelegations") == 0) {
536 answer_integer = 0; /* DNS_ACD_DONT_CREATE */
537 is_integer = 1;
538 } else if (strcasecmp(operation, "BreakOnAscFailure") == 0) {
539 answer_integer = 0;
540 is_integer = 1;
541 } else if (strcasecmp(operation, "CacheEmptyAuthResponses") == 0) {
542 answer_integer = 0;
543 is_integer = 1;
544 } else if (strcasecmp(operation, "DirectoryPartitionAutoEnlistInterval") == 0) {
545 answer_integer = 0x00015180; /* 1 day */
546 is_integer = 1;
547 } else if (strcasecmp(operation, "DisableAutoReverseZones") == 0) {
548 answer_integer = ~serverinfo->fAutoReverseZones;
549 is_integer = 1;
550 } else if (strcasecmp(operation, "EDnsCacheTimeout") == 0) {
551 answer_integer = 0x00000384; /* 15 minutes */
552 is_integer = 1;
553 } else if (strcasecmp(operation, "EnableDirectoryPartitions") == 0) {
554 answer_integer = serverinfo->fDsAvailable;
555 is_integer = 1;
556 } else if (strcasecmp(operation, "EnableDnsSec") == 0) {
557 answer_integer = 0;
558 is_integer = 1;
559 } else if (strcasecmp(operation, "EnableEDnsProbes") == 0) {
560 answer_integer = 0;
561 is_integer = 1;
562 } else if (strcasecmp(operation, "EnableEDnsReception") == 0) {
563 answer_integer = 0;
564 is_integer = 1;
565 } else if (strcasecmp(operation, "EnableIPv6") == 0) {
566 answer_integer = 0;
567 is_integer = 1;
568 } else if (strcasecmp(operation, "EnableIQueryResponseGeneration") == 0) {
569 answer_integer = 0;
570 is_integer = 1;
571 } else if (strcasecmp(operation, "EnableSendErrorSuppression") == 0) {
572 answer_integer = 0;
573 is_integer = 1;
574 } else if (strcasecmp(operation, "EnableUpdateForwarding") == 0) {
575 answer_integer = 0;
576 is_integer = 1;
577 } else if (strcasecmp(operation, "EnableWinsR") == 0) {
578 answer_integer = 0;
579 is_integer = 1;
580 } else if (strcasecmp(operation, "ForceDsaBehaviorVersion") == 0) {
581 answer_integer = serverinfo->dwDsDsaVersion;
582 is_integer = 1;
583 } else if (strcasecmp(operation, "ForceDomainBehaviorVersion") == 0) {
584 answer_integer = serverinfo->dwDsDsaVersion;
585 is_integer = 1;
586 } else if (strcasecmp(operation, "ForceForestBehaviorVersion") == 0) {
587 answer_integer = serverinfo->dwDsDsaVersion;
588 is_integer = 1;
589 } else if (strcasecmp(operation, "HeapDebug") == 0) {
590 answer_integer = 0;
591 is_integer = 1;
592 } else if (strcasecmp(operation, "LameDelegationTtl") == 0) {
593 answer_integer = 0; /* seconds */
594 is_integer = 1;
595 } else if (strcasecmp(operation, "LocalNetPriorityNetMask") == 0) {
596 answer_integer = serverinfo->dwLocalNetPriorityNetMask;
597 is_integer = 1;
598 } else if (strcasecmp(operation, "MaxCacheSize") == 0) {
599 answer_integer = 0;
600 is_integer = 1;
601 } else if (strcasecmp(operation, "MaxResourceRecordsInNonSecureUpdate") == 0) {
602 answer_integer = 0x0000001E;
603 is_integer = 1;
604 } else if (strcasecmp(operation, "OperationsLogLevel") == 0) {
605 answer_integer = 0;
606 is_integer = 1;
607 } else if (strcasecmp(operation, "OperationsLogLevel2") == 0) {
608 answer_integer = 0;
609 is_integer = 1;
610 } else if (strcasecmp(operation, "MaximumUdpPacketSize") == 0) {
611 answer_integer = 0x00004000; /* maximum possible */
612 is_integer = 1;
613 } else if (strcasecmp(operation, "RecurseToInternetRootMask") == 0) {
614 answer_integer = 0;
615 is_integer = 1;
616 } else if (strcasecmp(operation, "SelfTest") == 0) {
617 answer_integer = 0;
618 is_integer = 1;
619 } else if (strcasecmp(operation, "SilentlyIgnoreCNameUpdateConflicts") == 0) {
620 answer_integer = 1;
621 is_integer = 1;
622 } else if (strcasecmp(operation, "TcpReceivePacketSize") == 0) {
623 answer_integer = 0x00010000;
624 is_integer = 1;
625 } else if (strcasecmp(operation, "XfrThrottleMultiplier") == 0) {
626 answer_integer = 0x0000000A;
627 is_integer = 1;
628 } else if (strcasecmp(operation, "AllowMsdcsLookupRetry") == 0) {
629 answer_integer = 1;
630 is_integer = 1;
631 } else if (strcasecmp(operation, "AllowReadOnlyZoneTransfer") == 0) {
632 answer_integer = 0;
633 is_integer = 1;
634 } else if (strcasecmp(operation, "DsBackGroundLoadPaused") == 0) {
635 answer_integer = 0;
636 is_integer = 1;
637 } else if (strcasecmp(operation, "DsMinimumBackgroundLoadThreads") == 0) {
638 answer_integer = 0;
639 is_integer = 1;
640 } else if (strcasecmp(operation, "DsRemoteReplicationDelay") == 0) {
641 answer_integer = 0x0000001E; /* 30 seconds */
642 is_integer = 1;
643 } else if (strcasecmp(operation, "EnableDuplicateQuerySuppresion") == 0) {
644 answer_integer = 0;
645 is_integer = 1;
646 } else if (strcasecmp(operation, "EnableGlobalNamesSupport") == 0) {
647 answer_integer = 0;
648 is_integer = 1;
649 } else if (strcasecmp(operation, "EnableVersionQuery") == 0) {
650 answer_integer = 1; /* DNS_VERSION_QUERY_FULL */
651 is_integer = 1;
652 } else if (strcasecmp(operation, "EnableRsoForRodc") == 0) {
653 answer_integer = 0;
654 is_integer = 1;
655 } else if (strcasecmp(operation, "ForceRODCMode") == 0) {
656 answer_integer = 0;
657 is_integer = 1;
658 } else if (strcasecmp(operation, "GlobalNamesAlwaysQuerySrv") == 0) {
659 answer_integer = 1;
660 is_integer = 1;
661 } else if (strcasecmp(operation, "GlobalNamesBlockUpdates") == 0) {
662 answer_integer = 0;
663 is_integer = 1;
664 } else if (strcasecmp(operation, "GlobalNamesEnableEDnsProbes") == 0) {
665 answer_integer = 0;
666 is_integer = 1;
667 } else if (strcasecmp(operation, "GlobalNamesPreferAAAA") == 0) {
668 answer_integer = 0;
669 is_integer = 1;
670 } else if (strcasecmp(operation, "GlobalNamesQueryOrder") == 0) {
671 answer_integer = 1;
672 is_integer = 1;
673 } else if (strcasecmp(operation, "GlobalNamesSendTimeout") == 0) {
674 answer_integer = 3; /* seconds */
675 is_integer = 1;
676 } else if (strcasecmp(operation, "GlobalNamesServerQueryInterval") == 0) {
677 answer_integer = 0x00005460; /* 6 hours */
678 is_integer = 1;
679 } else if (strcasecmp(operation, "RemoteIPv4RankBoost") == 0) {
680 answer_integer = 0;
681 is_integer = 1;
682 } else if (strcasecmp(operation, "RemoteIPv6RankBoost") == 0) {
683 answer_integer = 0;
684 is_integer = 1;
685 } else if (strcasecmp(operation, "MaximumRodcRsoAttemptsPerCycle") == 0) {
686 answer_integer = 0x00000064;
687 is_integer = 1;
688 } else if (strcasecmp(operation, "MaximumRodcRsoQueueLength") == 0) {
689 answer_integer = 0x0000012C;
690 is_integer = 1;
691 } else if (strcasecmp(operation, "EnableGlobalQueryBlockList") == 0) {
692 answer_integer = 0;
693 is_integer = 1;
694 } else if (strcasecmp(operation, "OpenACLOnProxyUpdates") == 0) {
695 answer_integer = 0;
696 is_integer = 1;
697 } else if (strcasecmp(operation, "CacheLockingPercent") == 0) {
698 answer_integer = 0x00000064;
699 is_integer = 1;
702 if (is_integer == 1) {
703 *typeid = DNSSRV_TYPEID_DWORD;
704 r->Dword = answer_integer;
705 return WERR_OK;
708 is_addresses = 0;
710 if (strcasecmp(operation, "Forwarders") == 0) {
711 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
712 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders);
713 } else {
714 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
716 is_addresses = 1;
717 } else if (strcasecmp(operation, "ListenAddresses") == 0) {
718 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
719 answer_addrarray = serverinfo->aipListenAddrs;
720 } else {
721 answer_iparray = dns_addr_array_to_ip4_array(mem_ctx, serverinfo->aipListenAddrs);
723 is_addresses = 1;
724 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
725 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
726 answer_addrarray = NULL;
727 } else {
728 answer_iparray = NULL;
730 is_addresses = 1;
731 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
732 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
733 answer_addrarray = NULL;
734 } else {
735 answer_iparray = NULL;
737 is_addresses = 1;
738 } else if (strcasecmp(operation, "LogIPFilterList") == 0) {
739 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
740 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter);
741 } else {
742 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
744 is_addresses = 1;
747 if (is_addresses == 1) {
748 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
749 *typeid = DNSSRV_TYPEID_ADDRARRAY;
750 r->AddrArray = answer_addrarray;
751 } else {
752 *typeid = DNSSRV_TYPEID_IPARRAY;
753 r->IpArray = answer_iparray;
755 return WERR_OK;
758 is_string = is_wstring = 0;
760 if (strcasecmp(operation, "DomainDirectoryPartitionBaseName") == 0) {
761 answer_string = talloc_strdup(mem_ctx, "DomainDnsZones");
762 if (! answer_string) {
763 return WERR_OUTOFMEMORY;
765 is_string = 1;
766 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
767 answer_string = talloc_strdup(mem_ctx, "ForestDnsZones");
768 if (! answer_string) {
769 return WERR_OUTOFMEMORY;
771 is_string = 1;
772 } else if (strcasecmp(operation, "LogFilePath") == 0) {
773 answer_string = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
774 is_wstring = 1;
775 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
776 answer_string = NULL;
777 is_wstring = 1;
778 } else if (strcasecmp(operation, "DsBackgroundPauseName") == 0) {
779 answer_string = NULL;
780 is_string = 1;
781 } else if (strcasecmp(operation, "DsNotRoundRobinTypes") == 0) {
782 answer_string = NULL;
783 is_string = 1;
786 if (is_string == 1) {
787 *typeid = DNSSRV_TYPEID_LPSTR;
788 r->String = answer_string;
789 return WERR_OK;
790 } else if (is_wstring == 1) {
791 *typeid = DNSSRV_TYPEID_LPWSTR;
792 r->WideString = answer_string;
793 return WERR_OK;
796 is_stringlist = 0;
798 if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
799 answer_stringlist = NULL;
800 is_stringlist = 1;
801 } else if (strcasecmp(operation, "SocketPoolExcludedPortRanges") == 0) {
802 answer_stringlist = NULL;
803 is_stringlist = 1;
806 if (is_stringlist == 1) {
807 *typeid = DNSSRV_TYPEID_UTF8_STRING_LIST;
808 r->Utf8StringList = answer_stringlist;
809 return WERR_OK;
812 DEBUG(0,("dnsserver: Invalid server operation %s", operation));
813 return WERR_DNS_ERROR_INVALID_PROPERTY;
816 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
817 static WERROR dnsserver_query_zone(struct dnsserver_state *dsstate,
818 TALLOC_CTX *mem_ctx,
819 struct dnsserver_zone *z,
820 const char *operation,
821 const unsigned int client_version,
822 enum DNS_RPC_TYPEID *typeid,
823 union DNSSRV_RPC_UNION *r)
825 uint8_t is_integer, is_addresses, is_string;
826 uint32_t answer_integer;
827 struct IP4_ARRAY *answer_iparray;
828 struct DNS_ADDR_ARRAY *answer_addrarray;
829 char *answer_string;
830 struct dnsserver_zoneinfo *zoneinfo;
832 zoneinfo = z->zoneinfo;
834 if (strcasecmp(operation, "Zone") == 0) {
835 if (client_version == DNS_CLIENT_VERSION_W2K) {
836 *typeid = DNSSRV_TYPEID_ZONE_W2K;
837 r->ZoneW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
839 r->ZoneW2K->pszZoneName = talloc_strdup(mem_ctx, z->name);
840 r->ZoneW2K->Flags = zoneinfo->Flags;
841 r->ZoneW2K->ZoneType = zoneinfo->dwZoneType;
842 r->ZoneW2K->Version = zoneinfo->Version;
843 } else {
844 *typeid = DNSSRV_TYPEID_ZONE;
845 r->Zone = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
847 r->Zone->dwRpcStructureVersion = 0x01;
848 r->Zone->pszZoneName = talloc_strdup(mem_ctx, z->name);
849 r->Zone->Flags = zoneinfo->Flags;
850 r->Zone->ZoneType = zoneinfo->dwZoneType;
851 r->Zone->Version = zoneinfo->Version;
852 r->Zone->dwDpFlags = z->partition->dwDpFlags;
853 r->Zone->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
855 return WERR_OK;
858 if (strcasecmp(operation, "ZoneInfo") == 0) {
859 if (client_version == DNS_CLIENT_VERSION_W2K) {
860 *typeid = DNSSRV_TYPEID_ZONE_INFO_W2K;
861 r->ZoneInfoW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_W2K);
863 r->ZoneInfoW2K->pszZoneName = talloc_strdup(mem_ctx, z->name);
864 r->ZoneInfoW2K->dwZoneType = zoneinfo->dwZoneType;
865 r->ZoneInfoW2K->fReverse = zoneinfo->fReverse;
866 r->ZoneInfoW2K->fAllowUpdate = zoneinfo->fAllowUpdate;
867 r->ZoneInfoW2K->fPaused = zoneinfo->fPaused;
868 r->ZoneInfoW2K->fShutdown = zoneinfo->fShutdown;
869 r->ZoneInfoW2K->fAutoCreated = zoneinfo->fAutoCreated;
870 r->ZoneInfoW2K->fUseDatabase = zoneinfo->fUseDatabase;
871 r->ZoneInfoW2K->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
872 r->ZoneInfoW2K->aipMasters = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
873 r->ZoneInfoW2K->fSecureSecondaries = zoneinfo->fSecureSecondaries;
874 r->ZoneInfoW2K->fNotifyLevel = zoneinfo->fNotifyLevel;
875 r->ZoneInfoW2K->aipSecondaries = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
876 r->ZoneInfoW2K->aipNotify = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
877 r->ZoneInfoW2K->fUseWins = zoneinfo->fUseWins;
878 r->ZoneInfoW2K->fUseNbstat = zoneinfo->fUseNbstat;
879 r->ZoneInfoW2K->fAging = zoneinfo->fAging;
880 r->ZoneInfoW2K->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
881 r->ZoneInfoW2K->dwRefreshInterval = zoneinfo->dwRefreshInterval;
882 r->ZoneInfoW2K->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
883 r->ZoneInfoW2K->aipScavengeServers = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
885 } else if (client_version == DNS_CLIENT_VERSION_DOTNET) {
886 *typeid = DNSSRV_TYPEID_ZONE_INFO_DOTNET;
887 r->ZoneInfoDotNet = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_DOTNET);
889 r->ZoneInfoDotNet->dwRpcStructureVersion = 0x01;
890 r->ZoneInfoDotNet->pszZoneName = talloc_strdup(mem_ctx, z->name);
891 r->ZoneInfoDotNet->dwZoneType = zoneinfo->dwZoneType;
892 r->ZoneInfoDotNet->fReverse = zoneinfo->fReverse;
893 r->ZoneInfoDotNet->fAllowUpdate = zoneinfo->fAllowUpdate;
894 r->ZoneInfoDotNet->fPaused = zoneinfo->fPaused;
895 r->ZoneInfoDotNet->fShutdown = zoneinfo->fShutdown;
896 r->ZoneInfoDotNet->fAutoCreated = zoneinfo->fAutoCreated;
897 r->ZoneInfoDotNet->fUseDatabase = zoneinfo->fUseDatabase;
898 r->ZoneInfoDotNet->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
899 r->ZoneInfoDotNet->aipMasters = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
900 r->ZoneInfoDotNet->fSecureSecondaries = zoneinfo->fSecureSecondaries;
901 r->ZoneInfoDotNet->fNotifyLevel = zoneinfo->fNotifyLevel;
902 r->ZoneInfoDotNet->aipSecondaries = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
903 r->ZoneInfoDotNet->aipNotify = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
904 r->ZoneInfoDotNet->fUseWins = zoneinfo->fUseWins;
905 r->ZoneInfoDotNet->fUseNbstat = zoneinfo->fUseNbstat;
906 r->ZoneInfoDotNet->fAging = zoneinfo->fAging;
907 r->ZoneInfoDotNet->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
908 r->ZoneInfoDotNet->dwRefreshInterval = zoneinfo->dwRefreshInterval;
909 r->ZoneInfoDotNet->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
910 r->ZoneInfoDotNet->aipScavengeServers = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
911 r->ZoneInfoDotNet->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
912 r->ZoneInfoDotNet->fForwarderSlave = zoneinfo->fForwarderSlave;
913 r->ZoneInfoDotNet->aipLocalMasters = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
914 r->ZoneInfoDotNet->dwDpFlags = z->partition->dwDpFlags;
915 r->ZoneInfoDotNet->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
916 r->ZoneInfoDotNet->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
917 r->ZoneInfoDotNet->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
918 r->ZoneInfoDotNet->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
920 } else {
921 *typeid = DNSSRV_TYPEID_ZONE_INFO;
922 r->ZoneInfo = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_LONGHORN);
924 r->ZoneInfo->dwRpcStructureVersion = 0x02;
925 r->ZoneInfo->pszZoneName = talloc_strdup(mem_ctx, z->name);
926 r->ZoneInfo->dwZoneType = zoneinfo->dwZoneType;
927 r->ZoneInfo->fReverse = zoneinfo->fReverse;
928 r->ZoneInfo->fAllowUpdate = zoneinfo->fAllowUpdate;
929 r->ZoneInfo->fPaused = zoneinfo->fPaused;
930 r->ZoneInfo->fShutdown = zoneinfo->fShutdown;
931 r->ZoneInfo->fAutoCreated = zoneinfo->fAutoCreated;
932 r->ZoneInfo->fUseDatabase = zoneinfo->fUseDatabase;
933 r->ZoneInfo->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
934 r->ZoneInfo->aipMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipMasters);
935 r->ZoneInfo->fSecureSecondaries = zoneinfo->fSecureSecondaries;
936 r->ZoneInfo->fNotifyLevel = zoneinfo->fNotifyLevel;
937 r->ZoneInfo->aipSecondaries = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipSecondaries);
938 r->ZoneInfo->aipNotify = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipNotify);
939 r->ZoneInfo->fUseWins = zoneinfo->fUseWins;
940 r->ZoneInfo->fUseNbstat = zoneinfo->fUseNbstat;
941 r->ZoneInfo->fAging = zoneinfo->fAging;
942 r->ZoneInfo->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
943 r->ZoneInfo->dwRefreshInterval = zoneinfo->dwRefreshInterval;
944 r->ZoneInfo->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
945 r->ZoneInfo->aipScavengeServers = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipScavengeServers);
946 r->ZoneInfo->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
947 r->ZoneInfo->fForwarderSlave = zoneinfo->fForwarderSlave;
948 r->ZoneInfo->aipLocalMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
949 r->ZoneInfo->dwDpFlags = z->partition->dwDpFlags;
950 r->ZoneInfo->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
951 r->ZoneInfo->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
952 r->ZoneInfo->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
953 r->ZoneInfo->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
955 r->ZoneInfo->fQueuedForBackgroundLoad = zoneinfo->fQueuedForBackgroundLoad;
956 r->ZoneInfo->fBackgroundLoadInProgress = zoneinfo->fBackgroundLoadInProgress;
957 r->ZoneInfo->fReadOnlyZone = zoneinfo->fReadOnlyZone;
958 r->ZoneInfo->dwLastXfrAttempt = zoneinfo->dwLastXfrAttempt;
959 r->ZoneInfo->dwLastXfrResult = zoneinfo->dwLastXfrResult;
962 return WERR_OK;
965 is_integer = 0;
967 if (strcasecmp(operation, "AllowUpdate") == 0) {
968 answer_integer = zoneinfo->fAllowUpdate;
969 is_integer = 1;
970 } else if (strcasecmp(operation, "Secured") == 0) {
971 answer_integer = 0;
972 is_integer = 1;
973 } else if (strcasecmp(operation, "DsIntegrated") == 0) {
974 answer_integer = zoneinfo->fUseDatabase;
975 is_integer = 1;
976 } else if (strcasecmp(operation, "LogUpdates") == 0) {
977 answer_integer = 0;
978 is_integer = 1;
979 } else if (strcasecmp(operation, "NoRefreshInterval") == 0) {
980 answer_integer = zoneinfo->dwNoRefreshInterval;
981 is_integer = 1;
982 } else if (strcasecmp(operation, "NotifyLevel") == 0) {
983 answer_integer = zoneinfo->fNotifyLevel;
984 is_integer = 1;
985 } else if (strcasecmp(operation, "RefreshInterval") == 0) {
986 answer_integer = zoneinfo->dwRefreshInterval;
987 is_integer = 1;
988 } else if (strcasecmp(operation, "SecureSecondaries") == 0) {
989 answer_integer = zoneinfo->fSecureSecondaries;
990 is_integer = 1;
991 } else if (strcasecmp(operation, "Type") == 0) {
992 answer_integer = zoneinfo->dwZoneType;
993 is_integer = 1;
994 } else if (strcasecmp(operation, "Aging") == 0) {
995 answer_integer = zoneinfo->fAging;
996 is_integer = 1;
997 } else if (strcasecmp(operation, "ForwarderSlave") == 0) {
998 answer_integer = zoneinfo->fForwarderSlave;
999 is_integer = 1;
1000 } else if (strcasecmp(operation, "ForwarderTimeout") == 0) {
1001 answer_integer = zoneinfo->dwForwarderTimeout;
1002 is_integer = 1;
1003 } else if (strcasecmp(operation, "Unicode") == 0) {
1004 answer_integer = 0;
1005 is_integer = 1;
1008 if (is_integer == 1) {
1009 *typeid = DNSSRV_TYPEID_DWORD;
1010 r->Dword = answer_integer;
1011 return WERR_OK;
1014 is_addresses = 0;
1016 if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
1017 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1018 answer_addrarray = NULL;
1019 } else {
1020 answer_iparray = NULL;
1022 is_addresses = 1;
1023 } else if (strcasecmp(operation, "ScavengeServers") == 0) {
1024 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1025 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipScavengeServers);
1026 } else {
1027 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
1029 is_addresses = 1;
1030 } else if (strcasecmp(operation, "MasterServers") == 0) {
1031 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1032 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipMasters);
1033 } else {
1034 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
1036 is_addresses = 1;
1037 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
1038 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1039 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
1040 } else {
1041 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
1043 is_addresses = 1;
1044 } else if (strcasecmp(operation, "NotifyServers") == 0) {
1045 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1046 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipNotify);
1047 } else {
1048 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
1050 is_addresses = 1;
1051 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
1052 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1053 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipSecondaries);
1054 } else {
1055 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
1057 is_addresses = 1;
1060 if (is_addresses == 1) {
1061 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1062 *typeid = DNSSRV_TYPEID_ADDRARRAY;
1063 r->AddrArray = answer_addrarray;
1064 } else {
1065 *typeid = DNSSRV_TYPEID_IPARRAY;
1066 r->IpArray = answer_iparray;
1068 return WERR_OK;
1071 is_string = 0;
1073 if (strcasecmp(operation, "DatabaseFile") == 0) {
1074 answer_string = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
1075 is_string = 1;
1076 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1077 answer_string = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
1078 is_string = 1;
1079 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1080 answer_string = NULL;
1081 is_string = 1;
1084 if (is_string == 1) {
1085 *typeid = DNSSRV_TYPEID_LPSTR;
1086 r->String = answer_string;
1087 return WERR_OK;
1090 DEBUG(0,("dnsserver: Invalid zone operation %s", operation));
1091 return WERR_DNS_ERROR_INVALID_PROPERTY;
1095 /* dnsserver operation functions */
1097 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
1098 static WERROR dnsserver_operate_server(struct dnsserver_state *dsstate,
1099 TALLOC_CTX *mem_ctx,
1100 const char *operation,
1101 const unsigned int client_version,
1102 enum DNS_RPC_TYPEID typeid,
1103 union DNSSRV_RPC_UNION *r)
1105 bool valid_operation = false;
1107 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1108 valid_operation = true;
1109 } else if (strcasecmp(operation, "Restart") == 0) {
1110 valid_operation = true;
1111 } else if (strcasecmp(operation, "ClearDebugLog") == 0) {
1112 valid_operation = true;
1113 } else if (strcasecmp(operation, "ClearCache") == 0) {
1114 valid_operation = true;
1115 } else if (strcasecmp(operation, "WriteDirtyZones") == 0) {
1116 valid_operation = true;
1117 } else if (strcasecmp(operation, "ZoneCreate") == 0) {
1118 struct dnsserver_zone *z, *z2;
1119 WERROR status;
1121 z = talloc_zero(mem_ctx, struct dnsserver_zone);
1122 W_ERROR_HAVE_NO_MEMORY(z);
1123 z->partition = talloc_zero(z, struct dnsserver_partition);
1124 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z->partition, z);
1125 z->zoneinfo = talloc_zero(z, struct dnsserver_zoneinfo);
1126 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z->zoneinfo, z);
1128 if (typeid == DNSSRV_TYPEID_ZONE_CREATE_W2K) {
1129 z->name = talloc_strdup(z, r->ZoneCreateW2K->pszZoneName);
1130 z->zoneinfo->dwZoneType = r->ZoneCreateW2K->dwZoneType;
1131 z->zoneinfo->fAllowUpdate = r->ZoneCreateW2K->fAllowUpdate;
1132 z->zoneinfo->fAging = r->ZoneCreateW2K->fAging;
1133 z->zoneinfo->Flags = r->ZoneCreateW2K->dwFlags;
1134 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE_DOTNET) {
1135 z->name = talloc_strdup(z, r->ZoneCreateDotNet->pszZoneName);
1136 z->zoneinfo->dwZoneType = r->ZoneCreateDotNet->dwZoneType;
1137 z->zoneinfo->fAllowUpdate = r->ZoneCreateDotNet->fAllowUpdate;
1138 z->zoneinfo->fAging = r->ZoneCreateDotNet->fAging;
1139 z->zoneinfo->Flags = r->ZoneCreateDotNet->dwFlags;
1140 z->partition->dwDpFlags = r->ZoneCreateDotNet->dwDpFlags;
1141 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE) {
1142 z->name = talloc_strdup(z, r->ZoneCreate->pszZoneName);
1143 z->zoneinfo->dwZoneType = r->ZoneCreate->dwZoneType;
1144 z->zoneinfo->fAllowUpdate = r->ZoneCreate->fAllowUpdate;
1145 z->zoneinfo->fAging = r->ZoneCreate->fAging;
1146 z->zoneinfo->Flags = r->ZoneCreate->dwFlags;
1147 z->partition->dwDpFlags = r->ZoneCreate->dwDpFlags;
1148 } else {
1149 talloc_free(z);
1150 return WERR_DNS_ERROR_INVALID_PROPERTY;
1153 z2 = dnsserver_find_zone(dsstate->zones, z->name);
1154 if (z2 != NULL) {
1155 talloc_free(z);
1156 return WERR_DNS_ERROR_ZONE_ALREADY_EXISTS;
1159 status = dnsserver_db_create_zone(dsstate->samdb, dsstate->partitions, z,
1160 dsstate->lp_ctx);
1161 talloc_free(z);
1163 if (W_ERROR_IS_OK(status)) {
1164 dnsserver_reload_zones(dsstate);
1166 return status;
1167 } else if (strcasecmp(operation, "ClearStatistics") == 0) {
1168 valid_operation = true;
1169 } else if (strcasecmp(operation, "EnlistDirectoryPartition") == 0) {
1170 valid_operation = true;
1171 } else if (strcasecmp(operation, "StartScavenging") == 0) {
1172 valid_operation = true;
1173 } else if (strcasecmp(operation, "AbortScavenging") == 0) {
1174 valid_operation = true;
1175 } else if (strcasecmp(operation, "AutoConfigure") == 0) {
1176 valid_operation = true;
1177 } else if (strcasecmp(operation, "ExportSettings") == 0) {
1178 valid_operation = true;
1179 } else if (strcasecmp(operation, "PrepareForDemotion") == 0) {
1180 valid_operation = true;
1181 } else if (strcasecmp(operation, "PrepareForUninstall") == 0) {
1182 valid_operation = true;
1183 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1184 valid_operation = true;
1185 } else if (strcasecmp(operation, "DeleteRecord") == 0) {
1186 valid_operation = true;
1187 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1188 valid_operation = true;
1189 } else if (strcasecmp(operation, "ListenAddresses") == 0) {
1190 valid_operation = true;
1191 } else if (strcasecmp(operation, "Forwarders") == 0) {
1192 valid_operation = true;
1193 } else if (strcasecmp(operation, "LogFilePath") == 0) {
1194 valid_operation = true;
1195 } else if (strcasecmp(operation, "LogIpFilterList") == 0) {
1196 valid_operation = true;
1197 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
1198 valid_operation = true;
1199 } else if (strcasecmp(operation, "DomainDirectoryPartitionBaseName") == 0) {
1200 valid_operation = true;
1201 } else if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
1202 valid_operation = true;
1203 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
1204 valid_operation = true;
1205 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
1206 valid_operation = true;
1207 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
1208 valid_operation = true;
1211 if (valid_operation) {
1212 DEBUG(0, ("dnsserver: server operation '%s' not implemented", operation));
1213 return WERR_CALL_NOT_IMPLEMENTED;
1216 DEBUG(0, ("dnsserver: invalid server operation '%s'", operation));
1217 return WERR_DNS_ERROR_INVALID_PROPERTY;
1220 static WERROR dnsserver_complex_operate_server(struct dnsserver_state *dsstate,
1221 TALLOC_CTX *mem_ctx,
1222 const char *operation,
1223 const unsigned int client_version,
1224 enum DNS_RPC_TYPEID typeid_in,
1225 union DNSSRV_RPC_UNION *rin,
1226 enum DNS_RPC_TYPEID *typeid_out,
1227 union DNSSRV_RPC_UNION *rout)
1229 int valid_operation = 0;
1230 struct dnsserver_zone *z, **zlist;
1231 size_t zcount;
1232 bool found1, found2, found3, found4;
1233 size_t i;
1235 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1236 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1237 return dnsserver_query_server(dsstate, mem_ctx,
1238 rin->String,
1239 client_version,
1240 typeid_out,
1241 rout);
1243 } else if (strcasecmp(operation, "EnumZones") == 0) {
1244 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1245 return WERR_DNS_ERROR_INVALID_PROPERTY;
1248 zcount = 0;
1249 zlist = talloc_zero_array(mem_ctx, struct dnsserver_zone *, 0);
1250 for (z = dsstate->zones; z; z = z->next) {
1252 /* Match the flags in groups
1254 * Group1 : PRIMARY, SECONDARY, CACHE, AUTO
1255 * Group2 : FORWARD, REVERSE, FORWARDER, STUB
1256 * Group3 : DS, NON_DS, DOMAIN_DP, FOREST_DP
1257 * Group4 : CUSTOM_DP, LEGACY_DP
1260 /* Group 1 */
1261 found1 = false;
1262 if (rin->Dword & 0x0000000f) {
1263 if (rin->Dword & DNS_ZONE_REQUEST_PRIMARY) {
1264 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_PRIMARY) {
1265 found1 = true;
1268 if (rin->Dword & DNS_ZONE_REQUEST_SECONDARY) {
1269 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_SECONDARY) {
1270 found1 = true;
1273 if (rin->Dword & DNS_ZONE_REQUEST_CACHE) {
1274 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_CACHE) {
1275 found1 = true;
1278 if (rin->Dword & DNS_ZONE_REQUEST_AUTO) {
1279 if (z->zoneinfo->fAutoCreated
1280 || z->partition->dwDpFlags & DNS_DP_AUTOCREATED) {
1281 found1 = true;
1284 } else {
1285 found1 = true;
1288 /* Group 2 */
1289 found2 = false;
1290 if (rin->Dword & 0x000000f0) {
1291 if (rin->Dword & DNS_ZONE_REQUEST_FORWARD) {
1292 if (!(z->zoneinfo->fReverse)) {
1293 found2 = true;
1296 if (rin->Dword & DNS_ZONE_REQUEST_REVERSE) {
1297 if (z->zoneinfo->fReverse) {
1298 found2 = true;
1301 if (rin->Dword & DNS_ZONE_REQUEST_FORWARDER) {
1302 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_FORWARDER) {
1303 found2 = true;
1306 if (rin->Dword & DNS_ZONE_REQUEST_STUB) {
1307 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_STUB) {
1308 found2 = true;
1311 } else {
1312 found2 = true;
1315 /* Group 3 */
1316 found3 = false;
1317 if (rin->Dword & 0x00000f00) {
1318 if (rin->Dword & DNS_ZONE_REQUEST_DS) {
1319 if (z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED) {
1320 found3 = true;
1323 if (rin->Dword & DNS_ZONE_REQUEST_NON_DS) {
1324 if (!(z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED)) {
1325 found3 = true;
1328 if (rin->Dword & DNS_ZONE_REQUEST_DOMAIN_DP) {
1329 if (!(z->partition->dwDpFlags & DNS_DP_DOMAIN_DEFAULT)) {
1330 found3 = true;
1333 if (rin->Dword & DNS_ZONE_REQUEST_FOREST_DP) {
1334 if (!(z->partition->dwDpFlags & DNS_DP_FOREST_DEFAULT)) {
1335 found3 = true;
1338 } else {
1339 found3 = true;
1342 /* Group 4 */
1343 if (rin->Dword & 0x0000f000) {
1344 found4 = false;
1345 } else {
1346 found4 = true;
1349 if (found1 && found2 && found3 && found4) {
1350 zlist = talloc_realloc(mem_ctx, zlist, struct dnsserver_zone *, zcount+1);
1351 zlist[zcount] = z;
1352 zcount++;
1356 if (client_version == DNS_CLIENT_VERSION_W2K) {
1357 *typeid_out = DNSSRV_TYPEID_ZONE_LIST_W2K;
1358 rout->ZoneListW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_W2K);
1360 if (zcount == 0) {
1361 rout->ZoneListW2K->dwZoneCount = 0;
1362 rout->ZoneListW2K->ZoneArray = NULL;
1364 return WERR_OK;
1367 rout->ZoneListW2K->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_W2K *, zcount);
1368 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout->ZoneListW2K->ZoneArray, zlist);
1370 for (i=0; i<zcount; i++) {
1371 rout->ZoneListW2K->ZoneArray[i] = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
1373 rout->ZoneListW2K->ZoneArray[i]->pszZoneName = talloc_strdup(mem_ctx, zlist[i]->name);
1374 rout->ZoneListW2K->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
1375 rout->ZoneListW2K->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
1376 rout->ZoneListW2K->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
1378 rout->ZoneListW2K->dwZoneCount = zcount;
1380 } else {
1381 *typeid_out = DNSSRV_TYPEID_ZONE_LIST;
1382 rout->ZoneList = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_DOTNET);
1384 if (zcount == 0) {
1385 rout->ZoneList->dwRpcStructureVersion = 1;
1386 rout->ZoneList->dwZoneCount = 0;
1387 rout->ZoneList->ZoneArray = NULL;
1389 return WERR_OK;
1392 rout->ZoneList->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_DOTNET *, zcount);
1393 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout->ZoneList->ZoneArray, zlist);
1395 for (i=0; i<zcount; i++) {
1396 rout->ZoneList->ZoneArray[i] = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
1398 rout->ZoneList->ZoneArray[i]->dwRpcStructureVersion = 1;
1399 rout->ZoneList->ZoneArray[i]->pszZoneName = talloc_strdup(mem_ctx, zlist[i]->name);
1400 rout->ZoneList->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
1401 rout->ZoneList->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
1402 rout->ZoneList->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
1403 rout->ZoneList->ZoneArray[i]->dwDpFlags = zlist[i]->partition->dwDpFlags;
1404 rout->ZoneList->ZoneArray[i]->pszDpFqdn = talloc_strdup(mem_ctx, zlist[i]->partition->pszDpFqdn);
1406 rout->ZoneList->dwRpcStructureVersion = 1;
1407 rout->ZoneList->dwZoneCount = zcount;
1409 talloc_free(zlist);
1410 return WERR_OK;
1411 } else if (strcasecmp(operation, "EnumZones2") == 0) {
1412 valid_operation = true;
1413 } else if (strcasecmp(operation, "EnumDirectoryPartitions") == 0) {
1414 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1415 return WERR_DNS_ERROR_INVALID_PROPERTY;
1418 *typeid_out = DNSSRV_TYPEID_DP_LIST;
1419 rout->DirectoryPartitionList = talloc_zero(mem_ctx, struct DNS_RPC_DP_LIST);
1421 if (rin->Dword != 0) {
1422 rout->DirectoryPartitionList->dwDpCount = 0;
1423 rout->DirectoryPartitionList->DpArray = NULL;
1424 } else {
1425 struct DNS_RPC_DP_ENUM **dplist;
1426 struct dnsserver_partition *p;
1427 int pcount = 2;
1429 dplist = talloc_zero_array(mem_ctx, struct DNS_RPC_DP_ENUM *, pcount);
1430 W_ERROR_HAVE_NO_MEMORY(dplist);
1432 p = dsstate->partitions;
1433 for (i=0; i<pcount; i++) {
1434 dplist[i] = talloc_zero(dplist, struct DNS_RPC_DP_ENUM);
1436 dplist[i]->pszDpFqdn = talloc_strdup(mem_ctx, p->pszDpFqdn);
1437 dplist[i]->dwFlags = p->dwDpFlags;
1438 dplist[i]->dwZoneCount = p->zones_count;
1439 p = p->next;
1442 rout->DirectoryPartitionList->dwDpCount = pcount;
1443 rout->DirectoryPartitionList->DpArray = dplist;
1445 return WERR_OK;
1446 } else if (strcasecmp(operation, "DirectoryPartitionInfo") == 0) {
1447 struct dnsserver_partition *p;
1448 struct dnsserver_partition_info *partinfo;
1449 struct DNS_RPC_DP_INFO *dpinfo = NULL;
1451 if (typeid_in != DNSSRV_TYPEID_LPSTR) {
1452 return WERR_DNS_ERROR_INVALID_PROPERTY;
1455 *typeid_out = DNSSRV_TYPEID_DP_INFO;
1457 for (p = dsstate->partitions; p; p = p->next) {
1458 if (strcasecmp(p->pszDpFqdn, rin->String) == 0) {
1459 dpinfo = talloc_zero(mem_ctx, struct DNS_RPC_DP_INFO);
1460 W_ERROR_HAVE_NO_MEMORY(dpinfo);
1462 partinfo = dnsserver_db_partition_info(mem_ctx, dsstate->samdb, p);
1463 W_ERROR_HAVE_NO_MEMORY(partinfo);
1465 dpinfo->pszDpFqdn = talloc_strdup(dpinfo, p->pszDpFqdn);
1466 dpinfo->pszDpDn = talloc_strdup(dpinfo, ldb_dn_get_linearized(p->partition_dn));
1467 dpinfo->pszCrDn = talloc_steal(dpinfo, partinfo->pszCrDn);
1468 dpinfo->dwFlags = p->dwDpFlags;
1469 dpinfo->dwZoneCount = p->zones_count;
1470 dpinfo->dwState = partinfo->dwState;
1471 dpinfo->dwReplicaCount = partinfo->dwReplicaCount;
1472 if (partinfo->dwReplicaCount > 0) {
1473 dpinfo->ReplicaArray = talloc_steal(dpinfo,
1474 partinfo->ReplicaArray);
1475 } else {
1476 dpinfo->ReplicaArray = NULL;
1478 break;
1482 if (dpinfo == NULL) {
1483 return WERR_DNS_ERROR_DP_DOES_NOT_EXIST;
1486 rout->DirectoryPartition = dpinfo;
1487 return WERR_OK;
1488 } else if (strcasecmp(operation, "Statistics") == 0) {
1489 valid_operation = true;
1490 } else if (strcasecmp(operation, "IpValidate") == 0) {
1491 valid_operation = true;
1494 if (valid_operation) {
1495 DEBUG(0, ("dnsserver: server complex operation '%s' not implemented", operation));
1496 return WERR_CALL_NOT_IMPLEMENTED;
1499 DEBUG(0, ("dnsserver: invalid server complex operation '%s'", operation));
1500 return WERR_DNS_ERROR_INVALID_PROPERTY;
1503 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
1504 static WERROR dnsserver_operate_zone(struct dnsserver_state *dsstate,
1505 TALLOC_CTX *mem_ctx,
1506 struct dnsserver_zone *z,
1507 unsigned int request_filter,
1508 const char *operation,
1509 const unsigned int client_version,
1510 enum DNS_RPC_TYPEID typeid,
1511 union DNSSRV_RPC_UNION *r)
1513 bool valid_operation = false;
1515 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1517 if (typeid != DNSSRV_TYPEID_NAME_AND_PARAM) {
1518 return WERR_DNS_ERROR_INVALID_PROPERTY;
1521 return dnsserver_db_do_reset_dword(dsstate->samdb, z,
1522 r->NameAndParam);
1524 } else if (strcasecmp(operation, "ZoneTypeReset") == 0) {
1525 valid_operation = true;
1526 } else if (strcasecmp(operation, "PauseZone") == 0) {
1527 valid_operation = true;
1528 } else if (strcasecmp(operation, "ResumeZone") == 0) {
1529 valid_operation = true;
1530 } else if (strcasecmp(operation, "DeleteZone") == 0) {
1531 valid_operation = true;
1532 } else if (strcasecmp(operation, "ReloadZone") == 0) {
1533 valid_operation = true;
1534 } else if (strcasecmp(operation, "RefreshZone") == 0) {
1535 valid_operation = true;
1536 } else if (strcasecmp(operation, "ExpireZone") == 0) {
1537 valid_operation = true;
1538 } else if (strcasecmp(operation, "IncrementVersion") == 0) {
1539 valid_operation = true;
1540 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1541 valid_operation = true;
1542 } else if (strcasecmp(operation, "DeleteZoneFromDs") == 0) {
1543 WERROR status;
1544 if (z == NULL) {
1545 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1547 status = dnsserver_db_delete_zone(dsstate->samdb, z);
1548 if (W_ERROR_IS_OK(status)) {
1549 dnsserver_reload_zones(dsstate);
1551 return status;
1552 } else if (strcasecmp(operation, "UpdateZoneFromDs") == 0) {
1553 valid_operation = true;
1554 } else if (strcasecmp(operation, "ZoneExport") == 0) {
1555 valid_operation = true;
1556 } else if (strcasecmp(operation, "ZoneChangeDirectoryPartition") == 0) {
1557 valid_operation = true;
1558 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1559 valid_operation = true;
1560 } else if (strcasecmp(operation, "DeleteRecordSet") == 0) {
1561 valid_operation = true;
1562 } else if (strcasecmp(operation, "ForceAgingOnNode") == 0) {
1563 valid_operation = true;
1564 } else if (strcasecmp(operation, "DatabaseFile") == 0) {
1565 valid_operation = true;
1566 } else if (strcasecmp(operation, "MasterServers") == 0) {
1567 valid_operation = true;
1568 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
1569 valid_operation = true;
1570 } else if (strcasecmp(operation, "NotifyServers") == 0) {
1571 valid_operation = true;
1572 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
1573 valid_operation = true;
1574 } else if (strcasecmp(operation, "ScavengingServers") == 0) {
1575 valid_operation = true;
1576 } else if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
1577 valid_operation = true;
1578 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1579 valid_operation = true;
1580 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1581 valid_operation = true;
1584 if (valid_operation) {
1585 DEBUG(0, ("dnsserver: zone operation '%s' not implemented", operation));
1586 return WERR_CALL_NOT_IMPLEMENTED;
1589 DEBUG(0, ("dnsserver: invalid zone operation '%s'", operation));
1590 return WERR_DNS_ERROR_INVALID_PROPERTY;
1593 static WERROR dnsserver_complex_operate_zone(struct dnsserver_state *dsstate,
1594 TALLOC_CTX *mem_ctx,
1595 struct dnsserver_zone *z,
1596 const char *operation,
1597 const unsigned int client_version,
1598 enum DNS_RPC_TYPEID typeid_in,
1599 union DNSSRV_RPC_UNION *rin,
1600 enum DNS_RPC_TYPEID *typeid_out,
1601 union DNSSRV_RPC_UNION *rout)
1603 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1604 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1605 return dnsserver_query_zone(dsstate, mem_ctx, z,
1606 rin->String,
1607 client_version,
1608 typeid_out,
1609 rout);
1614 DEBUG(0,("dnsserver: Invalid zone operation %s", operation));
1615 return WERR_DNS_ERROR_INVALID_PROPERTY;
1618 /* dnsserver enumerate function */
1620 static WERROR dnsserver_enumerate_root_records(struct dnsserver_state *dsstate,
1621 TALLOC_CTX *mem_ctx,
1622 unsigned int client_version,
1623 const char *node_name,
1624 enum dns_record_type record_type,
1625 unsigned int select_flag,
1626 unsigned int *buffer_length,
1627 struct DNS_RPC_RECORDS_ARRAY **buffer)
1629 TALLOC_CTX *tmp_ctx;
1630 struct dnsserver_zone *z;
1631 const char * const attrs[] = { "name", "dnsRecord", NULL };
1632 struct ldb_result *res;
1633 struct DNS_RPC_RECORDS_ARRAY *recs;
1634 char **add_names;
1635 char *rname;
1636 int add_count;
1637 int i, ret, len;
1638 WERROR status;
1640 tmp_ctx = talloc_new(mem_ctx);
1641 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1643 z = dnsserver_find_zone(dsstate->zones, ".");
1644 if (z == NULL) {
1645 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1648 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1649 LDB_SCOPE_ONELEVEL, attrs,
1650 "(&(objectClass=dnsNode)(name=@)(!(dNSTombstoned=TRUE)))");
1651 if (ret != LDB_SUCCESS) {
1652 talloc_free(tmp_ctx);
1653 return WERR_INTERNAL_DB_ERROR;
1655 if (res->count == 0) {
1656 talloc_free(tmp_ctx);
1657 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1660 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1661 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1663 add_names = NULL;
1664 add_count = 0;
1666 for (i=0; i<res->count; i++) {
1667 status = dns_fill_records_array(tmp_ctx, NULL, record_type,
1668 select_flag, NULL,
1669 res->msgs[i], 0, recs,
1670 &add_names, &add_count);
1671 if (!W_ERROR_IS_OK(status)) {
1672 talloc_free(tmp_ctx);
1673 return status;
1676 talloc_free(res);
1678 /* Add any additional records */
1679 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1680 for (i=0; i<add_count; i++) {
1681 char *encoded_name
1682 = ldb_binary_encode_string(tmp_ctx,
1683 add_names[i]);
1684 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1685 LDB_SCOPE_ONELEVEL, attrs,
1686 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1687 encoded_name);
1688 if (ret != LDB_SUCCESS || res->count == 0) {
1689 talloc_free(res);
1690 continue;
1693 len = strlen(add_names[i]);
1694 if (add_names[i][len-1] == '.') {
1695 rname = talloc_strdup(tmp_ctx, add_names[i]);
1696 } else {
1697 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1699 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1700 select_flag, rname,
1701 res->msgs[0], 0, recs,
1702 NULL, NULL);
1703 talloc_free(rname);
1704 talloc_free(res);
1708 talloc_free(tmp_ctx);
1710 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1711 *buffer = recs;
1713 return WERR_OK;
1717 static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
1718 TALLOC_CTX *mem_ctx,
1719 struct dnsserver_zone *z,
1720 unsigned int client_version,
1721 const char *node_name,
1722 const char *start_child,
1723 enum dns_record_type record_type,
1724 unsigned int select_flag,
1725 const char *filter_start,
1726 const char *filter_stop,
1727 unsigned int *buffer_length,
1728 struct DNS_RPC_RECORDS_ARRAY **buffer)
1730 TALLOC_CTX *tmp_ctx;
1731 char *name;
1732 const char * const attrs[] = { "name", "dnsRecord", NULL };
1733 struct ldb_result *res;
1734 struct DNS_RPC_RECORDS_ARRAY *recs;
1735 char **add_names = NULL;
1736 char *rname;
1737 int add_count = 0;
1738 int i, ret, len;
1739 WERROR status;
1740 struct dns_tree *tree, *base, *node;
1742 tmp_ctx = talloc_new(mem_ctx);
1743 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1745 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1746 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1748 /* search all records under parent tree */
1749 if (strcasecmp(name, z->name) == 0) {
1750 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1751 LDB_SCOPE_ONELEVEL, attrs,
1752 "(&(objectClass=dnsNode)(!(dNSTombstoned=TRUE)))");
1753 } else {
1754 char *encoded_name
1755 = ldb_binary_encode_string(tmp_ctx, name);
1756 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1757 LDB_SCOPE_ONELEVEL, attrs,
1758 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s))(!(dNSTombstoned=TRUE)))",
1759 encoded_name, encoded_name);
1761 if (ret != LDB_SUCCESS) {
1762 talloc_free(tmp_ctx);
1763 return WERR_INTERNAL_DB_ERROR;
1765 if (res->count == 0) {
1766 talloc_free(tmp_ctx);
1767 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1770 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1771 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1773 /* Sort the names, so that the first record is the parent record */
1774 ldb_qsort(res->msgs, res->count, sizeof(struct ldb_message *), name,
1775 (ldb_qsort_cmp_fn_t)dns_name_compare);
1777 /* Build a tree of name components from dns name */
1778 if (strcasecmp(name, z->name) == 0) {
1779 tree = dns_build_tree(tmp_ctx, "@", res);
1780 } else {
1781 tree = dns_build_tree(tmp_ctx, name, res);
1783 W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree, tmp_ctx);
1785 /* Find the parent record in the tree */
1786 base = tree;
1787 while (base->level != -1) {
1788 base = base->children[0];
1791 /* Add the parent record with blank name */
1792 if (!(select_flag & DNS_RPC_VIEW_ONLY_CHILDREN)) {
1793 status = dns_fill_records_array(tmp_ctx, z, record_type,
1794 select_flag, NULL,
1795 base->data, 0,
1796 recs, &add_names, &add_count);
1797 if (!W_ERROR_IS_OK(status)) {
1798 talloc_free(tmp_ctx);
1799 return status;
1803 /* Add all the children records */
1804 if (!(select_flag & DNS_RPC_VIEW_NO_CHILDREN)) {
1805 for (i=0; i<base->num_children; i++) {
1806 node = base->children[i];
1808 status = dns_fill_records_array(tmp_ctx, z, record_type,
1809 select_flag, node->name,
1810 node->data, node->num_children,
1811 recs, &add_names, &add_count);
1812 if (!W_ERROR_IS_OK(status)) {
1813 talloc_free(tmp_ctx);
1814 return status;
1819 talloc_free(res);
1820 talloc_free(tree);
1821 talloc_free(name);
1823 /* Add any additional records */
1824 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1825 for (i=0; i<add_count; i++) {
1826 struct dnsserver_zone *z2;
1828 /* Search all the available zones for additional name */
1829 for (z2 = dsstate->zones; z2; z2 = z2->next) {
1830 char *encoded_name;
1831 name = dns_split_node_name(tmp_ctx, add_names[i], z2->name);
1832 encoded_name
1833 = ldb_binary_encode_string(tmp_ctx,
1834 name);
1835 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z2->zone_dn,
1836 LDB_SCOPE_ONELEVEL, attrs,
1837 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1838 encoded_name);
1839 talloc_free(name);
1840 if (ret != LDB_SUCCESS) {
1841 continue;
1843 if (res->count == 1) {
1844 break;
1845 } else {
1846 talloc_free(res);
1847 continue;
1851 len = strlen(add_names[i]);
1852 if (add_names[i][len-1] == '.') {
1853 rname = talloc_strdup(tmp_ctx, add_names[i]);
1854 } else {
1855 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1857 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1858 select_flag, rname,
1859 res->msgs[0], 0, recs,
1860 NULL, NULL);
1861 talloc_free(rname);
1862 talloc_free(res);
1866 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1867 *buffer = recs;
1869 return WERR_OK;
1873 * Check str1 + '.' + str2 = name, for example:
1874 * ("dc0", "example.com", "dc0.example.com") = true
1876 static bool cname_self_reference(const char* node_name,
1877 const char* zone_name,
1878 struct DNS_RPC_NAME name) {
1879 size_t node_len, zone_len;
1881 if (node_name == NULL || zone_name == NULL) {
1882 return false;
1885 node_len = strlen(node_name);
1886 zone_len = strlen(zone_name);
1888 if (node_len == 0 ||
1889 zone_len == 0 ||
1890 (name.len != node_len + zone_len + 1)) {
1891 return false;
1894 if (strncmp(node_name, name.str, node_len) == 0 &&
1895 name.str[node_len] == '.' &&
1896 strncmp(zone_name, name.str + node_len + 1, zone_len) == 0) {
1897 return true;
1900 return false;
1903 /* dnsserver update function */
1905 static WERROR dnsserver_update_record(struct dnsserver_state *dsstate,
1906 TALLOC_CTX *mem_ctx,
1907 struct dnsserver_zone *z,
1908 unsigned int client_version,
1909 const char *node_name,
1910 struct DNS_RPC_RECORD_BUF *add_buf,
1911 struct DNS_RPC_RECORD_BUF *del_buf)
1913 TALLOC_CTX *tmp_ctx;
1914 char *name;
1915 WERROR status;
1917 tmp_ctx = talloc_new(mem_ctx);
1918 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1920 /* If node_name is @ or zone name, dns record is @ */
1921 if (strcmp(node_name, "@") == 0 ||
1922 strcmp(node_name, ".") == 0 ||
1923 strcasecmp(node_name, z->name) == 0) {
1924 name = talloc_strdup(tmp_ctx, "@");
1925 } else {
1926 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1928 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1930 /* CNAMEs can't point to themselves */
1931 if (add_buf != NULL && add_buf->rec.wType == DNS_TYPE_CNAME) {
1932 if (cname_self_reference(node_name, z->name, add_buf->rec.data.name)) {
1933 return WERR_DNS_ERROR_CNAME_LOOP;
1937 if (add_buf != NULL) {
1938 if (del_buf == NULL) {
1939 /* Add record */
1940 status = dnsserver_db_add_record(tmp_ctx, dsstate->samdb,
1941 z, name,
1942 &add_buf->rec);
1943 } else {
1944 /* Update record */
1945 status = dnsserver_db_update_record(tmp_ctx, dsstate->samdb,
1946 z, name,
1947 &add_buf->rec,
1948 &del_buf->rec);
1950 } else {
1951 if (del_buf == NULL) {
1952 /* Add empty node */
1953 status = dnsserver_db_add_empty_node(tmp_ctx, dsstate->samdb,
1954 z, name);
1955 } else {
1956 /* Delete record */
1957 status = dnsserver_db_delete_record(tmp_ctx, dsstate->samdb,
1958 z, name,
1959 &del_buf->rec);
1963 talloc_free(tmp_ctx);
1964 return status;
1968 /* dnsserver interface functions */
1970 static WERROR dcesrv_DnssrvOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation *r)
1972 struct dnsserver_state *dsstate;
1973 struct dnsserver_zone *z = NULL;
1974 uint32_t request_filter = 0;
1975 WERROR ret;
1977 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1978 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1981 if (r->in.dwContext == 0) {
1982 if (r->in.pszZone != NULL) {
1983 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
1985 } else {
1986 request_filter = r->in.dwContext;
1989 if (r->in.pszZone == NULL) {
1990 ret = dnsserver_operate_server(dsstate, mem_ctx,
1991 r->in.pszOperation,
1992 DNS_CLIENT_VERSION_W2K,
1993 r->in.dwTypeId,
1994 &r->in.pData);
1995 } else {
1996 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1997 if (z == NULL && request_filter == 0) {
1998 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2001 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
2002 request_filter,
2003 r->in.pszOperation,
2004 DNS_CLIENT_VERSION_W2K,
2005 r->in.dwTypeId,
2006 &r->in.pData);
2009 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2010 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation, NDR_IN, r);
2012 return ret;
2015 static WERROR dcesrv_DnssrvQuery(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery *r)
2017 struct dnsserver_state *dsstate;
2018 struct dnsserver_zone *z;
2019 WERROR ret;
2021 ZERO_STRUCTP(r->out.pdwTypeId);
2022 ZERO_STRUCTP(r->out.ppData);
2024 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2025 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2028 if (r->in.pszZone == NULL) {
2029 /* FIXME: DNS Server Configuration Access Control List */
2030 ret = dnsserver_query_server(dsstate, mem_ctx,
2031 r->in.pszOperation,
2032 DNS_CLIENT_VERSION_W2K,
2033 r->out.pdwTypeId,
2034 r->out.ppData);
2035 } else {
2036 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2037 if (z == NULL) {
2038 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2041 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
2042 r->in.pszOperation,
2043 DNS_CLIENT_VERSION_W2K,
2044 r->out.pdwTypeId,
2045 r->out.ppData);
2048 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2049 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery, NDR_IN, r);
2051 return ret;
2054 static WERROR dcesrv_DnssrvComplexOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation *r)
2056 struct dnsserver_state *dsstate;
2057 struct dnsserver_zone *z;
2058 WERROR ret;
2060 ZERO_STRUCTP(r->out.pdwTypeOut);
2061 ZERO_STRUCTP(r->out.ppDataOut);
2063 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2064 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2067 if (r->in.pszZone == NULL) {
2068 /* Server operation */
2069 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
2070 r->in.pszOperation,
2071 DNS_CLIENT_VERSION_W2K,
2072 r->in.dwTypeIn,
2073 &r->in.pDataIn,
2074 r->out.pdwTypeOut,
2075 r->out.ppDataOut);
2076 } else {
2077 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2078 if (z == NULL) {
2079 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2082 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2083 r->in.pszOperation,
2084 DNS_CLIENT_VERSION_W2K,
2085 r->in.dwTypeIn,
2086 &r->in.pDataIn,
2087 r->out.pdwTypeOut,
2088 r->out.ppDataOut);
2091 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2092 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation, NDR_IN, r);
2094 return ret;
2097 static WERROR dcesrv_DnssrvEnumRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords *r)
2099 struct dnsserver_state *dsstate;
2100 struct dnsserver_zone *z;
2101 WERROR ret;
2103 ZERO_STRUCTP(r->out.pdwBufferLength);
2104 ZERO_STRUCTP(r->out.pBuffer);
2106 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2107 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2110 if (r->in.pszZone == NULL) {
2111 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2114 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
2115 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
2116 DNS_CLIENT_VERSION_W2K,
2117 r->in.pszNodeName,
2118 r->in.wRecordType,
2119 r->in.fSelectFlag,
2120 r->out.pdwBufferLength,
2121 r->out.pBuffer);
2122 } else {
2123 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2124 if (z == NULL) {
2125 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2128 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2129 DNS_CLIENT_VERSION_W2K,
2130 r->in.pszNodeName,
2131 r->in.pszStartChild,
2132 r->in.wRecordType,
2133 r->in.fSelectFlag,
2134 r->in.pszFilterStart,
2135 r->in.pszFilterStop,
2136 r->out.pdwBufferLength,
2137 r->out.pBuffer);
2140 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2141 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords, NDR_IN, r);
2143 return ret;
2146 static WERROR dcesrv_DnssrvUpdateRecord(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord *r)
2148 struct dnsserver_state *dsstate;
2149 struct dnsserver_zone *z;
2150 WERROR ret;
2152 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2153 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2156 if (r->in.pszZone == NULL) {
2157 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2160 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2161 if (z == NULL) {
2162 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2165 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2166 DNS_CLIENT_VERSION_W2K,
2167 r->in.pszNodeName,
2168 r->in.pAddRecord,
2169 r->in.pDeleteRecord);
2171 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2172 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord, NDR_IN, r);
2174 return ret;
2177 static WERROR dcesrv_DnssrvOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation2 *r)
2179 struct dnsserver_state *dsstate;
2180 struct dnsserver_zone *z = NULL;
2181 uint32_t request_filter = 0;
2182 WERROR ret;
2184 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2185 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2188 if (r->in.dwContext == 0) {
2189 if (r->in.pszZone != NULL) {
2190 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
2192 } else {
2193 request_filter = r->in.dwContext;
2196 if (r->in.pszZone == NULL) {
2197 ret = dnsserver_operate_server(dsstate, mem_ctx,
2198 r->in.pszOperation,
2199 r->in.dwClientVersion,
2200 r->in.dwTypeId,
2201 &r->in.pData);
2202 } else {
2203 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2204 if (z == NULL && request_filter == 0) {
2205 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2208 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
2209 request_filter,
2210 r->in.pszOperation,
2211 r->in.dwClientVersion,
2212 r->in.dwTypeId,
2213 &r->in.pData);
2216 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2217 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation2, NDR_IN, r);
2219 return ret;
2222 static WERROR dcesrv_DnssrvQuery2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery2 *r)
2224 struct dnsserver_state *dsstate;
2225 struct dnsserver_zone *z;
2226 WERROR ret;
2228 ZERO_STRUCTP(r->out.pdwTypeId);
2229 ZERO_STRUCTP(r->out.ppData);
2231 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2232 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2235 if (r->in.pszZone == NULL) {
2236 /* FIXME: DNS Server Configuration Access Control List */
2237 ret = dnsserver_query_server(dsstate, mem_ctx,
2238 r->in.pszOperation,
2239 r->in.dwClientVersion,
2240 r->out.pdwTypeId,
2241 r->out.ppData);
2242 } else {
2243 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2244 if (z == NULL) {
2245 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2248 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
2249 r->in.pszOperation,
2250 r->in.dwClientVersion,
2251 r->out.pdwTypeId,
2252 r->out.ppData);
2255 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2256 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery2, NDR_IN, r);
2258 return ret;
2261 static WERROR dcesrv_DnssrvComplexOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation2 *r)
2263 struct dnsserver_state *dsstate;
2264 struct dnsserver_zone *z;
2265 WERROR ret;
2267 ZERO_STRUCTP(r->out.pdwTypeOut);
2268 ZERO_STRUCTP(r->out.ppDataOut);
2270 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2271 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2274 if (r->in.pszZone == NULL) {
2275 /* Server operation */
2276 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
2277 r->in.pszOperation,
2278 r->in.dwClientVersion,
2279 r->in.dwTypeIn,
2280 &r->in.pDataIn,
2281 r->out.pdwTypeOut,
2282 r->out.ppDataOut);
2283 } else {
2285 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2286 if (z == NULL) {
2287 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2290 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2291 r->in.pszOperation,
2292 r->in.dwClientVersion,
2293 r->in.dwTypeIn,
2294 &r->in.pDataIn,
2295 r->out.pdwTypeOut,
2296 r->out.ppDataOut);
2299 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2300 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation2, NDR_IN, r);
2302 return ret;
2305 static WERROR dcesrv_DnssrvEnumRecords2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords2 *r)
2307 struct dnsserver_state *dsstate;
2308 struct dnsserver_zone *z;
2309 WERROR ret;
2311 ZERO_STRUCTP(r->out.pdwBufferLength);
2312 ZERO_STRUCTP(r->out.pBuffer);
2314 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2315 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2318 if (r->in.pszZone == NULL) {
2319 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2322 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
2323 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
2324 r->in.dwClientVersion,
2325 r->in.pszNodeName,
2326 r->in.wRecordType,
2327 r->in.fSelectFlag,
2328 r->out.pdwBufferLength,
2329 r->out.pBuffer);
2330 } else {
2331 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2332 if (z == NULL) {
2333 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2336 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2337 r->in.dwClientVersion,
2338 r->in.pszNodeName,
2339 r->in.pszStartChild,
2340 r->in.wRecordType,
2341 r->in.fSelectFlag,
2342 r->in.pszFilterStart,
2343 r->in.pszFilterStop,
2344 r->out.pdwBufferLength,
2345 r->out.pBuffer);
2349 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2350 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords2, NDR_IN, r);
2352 return ret;
2355 static WERROR dcesrv_DnssrvUpdateRecord2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord2 *r)
2357 struct dnsserver_state *dsstate;
2358 struct dnsserver_zone *z;
2359 WERROR ret;
2361 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2362 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2365 if (r->in.pszZone == NULL) {
2366 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2369 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2370 if (z == NULL) {
2371 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2374 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2375 r->in.dwClientVersion,
2376 r->in.pszNodeName,
2377 r->in.pAddRecord,
2378 r->in.pDeleteRecord);
2380 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2381 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord2, NDR_IN, r);
2383 return ret;
2386 /* include the generated boilerplate */
2387 #include "librpc/gen_ndr/ndr_dnsserver_s.c"