s4-rpc: dnsserver: Fix enumeration of IPv4 and IPv6 addresses
[Samba.git] / source4 / rpc_server / dnsserver / dcerpc_dnsserver.c
blobbe315001ee2cd9d0eb42ce068277e2e5fab62522
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 "dnsserver.h"
29 #include "lib/ldb/include/ldb_private.h"
31 struct dnsserver_state {
32 struct loadparm_context *lp_ctx;
33 struct ldb_context *samdb;
34 struct dnsserver_partition *partitions;
35 struct dnsserver_zone *zones;
36 int zones_count;
37 struct dnsserver_serverinfo *serverinfo;
41 /* Utility functions */
43 static void dnsserver_reload_zones(struct dnsserver_state *dsstate)
45 struct dnsserver_partition *p;
46 struct dnsserver_zone *zones, *z, *znext, *zmatch;
47 struct dnsserver_zone *old_list, *new_list;
49 old_list = dsstate->zones;
50 new_list = NULL;
52 for (p = dsstate->partitions; p; p = p->next) {
53 zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, p);
54 if (zones == NULL) {
55 continue;
57 for (z = zones; z; ) {
58 znext = z->next;
59 zmatch = dnsserver_find_zone(old_list, z->name);
60 if (zmatch == NULL) {
61 /* Missing zone */
62 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
63 if (z->zoneinfo == NULL) {
64 continue;
66 DLIST_ADD_END(new_list, z, NULL);
67 p->zones_count++;
68 dsstate->zones_count++;
69 } else {
70 /* Existing zone */
71 talloc_free(z);
72 DLIST_REMOVE(old_list, zmatch);
73 DLIST_ADD_END(new_list, zmatch, NULL);
75 z = znext;
79 if (new_list == NULL) {
80 return;
83 /* Deleted zones */
84 for (z = old_list; z; ) {
85 znext = z->next;
86 z->partition->zones_count--;
87 dsstate->zones_count--;
88 talloc_free(z);
89 z = znext;
92 dsstate->zones = new_list;
96 static struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_call)
98 struct dnsserver_state *dsstate;
99 struct dnsserver_zone *zones, *z, *znext;
100 struct dnsserver_partition *partitions, *p;
102 dsstate = talloc_get_type(dce_call->context->private_data, struct dnsserver_state);
103 if (dsstate != NULL) {
104 return dsstate;
107 dsstate = talloc_zero(dce_call->context, struct dnsserver_state);
108 if (dsstate == NULL) {
109 return NULL;
112 dsstate->lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
114 /* FIXME: create correct auth_session_info for connecting user */
115 dsstate->samdb = samdb_connect(dsstate, dce_call->event_ctx, dsstate->lp_ctx,
116 dce_call->conn->auth_state.session_info, 0);
117 if (dsstate->samdb == NULL) {
118 DEBUG(0,("dnsserver: Failed to open samdb"));
119 goto failed;
122 /* Initialize server info */
123 dsstate->serverinfo = dnsserver_init_serverinfo(dsstate,
124 dsstate->lp_ctx,
125 dsstate->samdb);
126 if (dsstate->serverinfo == NULL) {
127 goto failed;
130 /* Search for DNS partitions */
131 partitions = dnsserver_db_enumerate_partitions(dsstate, dsstate->serverinfo, dsstate->samdb);
132 if (partitions == NULL) {
133 goto failed;
135 dsstate->partitions = partitions;
137 /* Search for DNS zones */
138 for (p = partitions; p; p = p->next) {
139 zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, p);
140 if (zones == NULL) {
141 goto failed;
143 for (z = zones; z; ) {
144 znext = z->next;
145 if (dnsserver_find_zone(dsstate->zones, z->name) == NULL) {
146 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
147 if (z->zoneinfo == NULL) {
148 goto failed;
150 DLIST_ADD_END(dsstate->zones, z, NULL);
151 p->zones_count++;
152 dsstate->zones_count++;
153 } else {
154 /* Ignore duplicate zone */
155 DEBUG(3,("dnsserver: Ignoring duplicate zone '%s' from '%s'",
156 z->name, ldb_dn_get_linearized(z->zone_dn)));
158 z = znext;
162 dce_call->context->private_data = dsstate;
164 return dsstate;
166 failed:
167 talloc_free(dsstate);
168 dsstate = NULL;
169 return NULL;
173 /* dnsserver query functions */
175 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
176 static WERROR dnsserver_query_server(struct dnsserver_state *dsstate,
177 TALLOC_CTX *mem_ctx,
178 const char *operation,
179 const unsigned int client_version,
180 enum DNS_RPC_TYPEID *typeid,
181 union DNSSRV_RPC_UNION *r)
183 uint8_t is_integer, is_addresses, is_string, is_wstring, is_stringlist;
184 uint32_t answer_integer;
185 struct IP4_ARRAY *answer_iparray;
186 struct DNS_ADDR_ARRAY *answer_addrarray;
187 char *answer_string;
188 struct DNS_RPC_UTF8_STRING_LIST *answer_stringlist;
189 struct dnsserver_serverinfo *serverinfo;
191 serverinfo = dsstate->serverinfo;
193 if (strcasecmp(operation, "ServerInfo") == 0) {
194 if (client_version == DNS_CLIENT_VERSION_W2K) {
195 *typeid = DNSSRV_TYPEID_SERVER_INFO_W2K;
196 r->ServerInfoW2K = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_W2K);
198 r->ServerInfoW2K->dwVersion = serverinfo->dwVersion;
199 r->ServerInfoW2K->fBootMethod = serverinfo->fBootMethod;
200 r->ServerInfoW2K->fAdminConfigured = serverinfo->fAdminConfigured;
201 r->ServerInfoW2K->fAllowUpdate = serverinfo->fAllowUpdate;
202 r->ServerInfoW2K->fDsAvailable = serverinfo->fDsAvailable;
203 r->ServerInfoW2K->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
204 r->ServerInfoW2K->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
205 r->ServerInfoW2K->aipServerAddrs = dns_addr_array_to_ip4_array(mem_ctx,
206 serverinfo->aipServerAddrs);
207 r->ServerInfoW2K->aipListenAddrs = dns_addr_array_to_ip4_array(mem_ctx,
208 serverinfo->aipListenAddrs);
209 r->ServerInfoW2K->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
210 r->ServerInfoW2K->dwLogLevel = serverinfo->dwLogLevel;
211 r->ServerInfoW2K->dwDebugLevel = serverinfo->dwDebugLevel;
212 r->ServerInfoW2K->dwForwardTimeout = serverinfo->dwForwardTimeout;
213 r->ServerInfoW2K->dwRpcProtocol = serverinfo->dwRpcProtocol;
214 r->ServerInfoW2K->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
215 r->ServerInfoW2K->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
216 r->ServerInfoW2K->dwRecursionRetry = serverinfo->dwRecursionRetry;
217 r->ServerInfoW2K->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
218 r->ServerInfoW2K->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
219 r->ServerInfoW2K->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
220 r->ServerInfoW2K->dwScavengingInterval = serverinfo->dwScavengingInterval;
221 r->ServerInfoW2K->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
222 r->ServerInfoW2K->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
223 r->ServerInfoW2K->fAutoReverseZones = serverinfo->fAutoReverseZones;
224 r->ServerInfoW2K->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
225 r->ServerInfoW2K->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
226 r->ServerInfoW2K->fForwardDelegations = serverinfo->fForwardDelegations;
227 r->ServerInfoW2K->fNoRecursion = serverinfo->fNoRecursion;
228 r->ServerInfoW2K->fSecureResponses = serverinfo->fSecureResponses;
229 r->ServerInfoW2K->fRoundRobin = serverinfo->fRoundRobin;
230 r->ServerInfoW2K->fLocalNetPriority = serverinfo->fLocalNetPriority;
231 r->ServerInfoW2K->fBindSecondaries = serverinfo->fBindSecondaries;
232 r->ServerInfoW2K->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
233 r->ServerInfoW2K->fStrictFileParsing = serverinfo->fStrictFileParsing;
234 r->ServerInfoW2K->fLooseWildcarding = serverinfo->fLooseWildcarding;
235 r->ServerInfoW2K->fDefaultAgingState = serverinfo->fDefaultAgingState;
237 } else if (client_version == DNS_CLIENT_VERSION_DOTNET) {
238 *typeid = DNSSRV_TYPEID_SERVER_INFO_DOTNET;
239 r->ServerInfoDotNet = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_DOTNET);
241 r->ServerInfoDotNet->dwRpcStructureVersion = 0x01;
242 r->ServerInfoDotNet->dwVersion = serverinfo->dwVersion;
243 r->ServerInfoDotNet->fBootMethod = serverinfo->fBootMethod;
244 r->ServerInfoDotNet->fAdminConfigured = serverinfo->fAdminConfigured;
245 r->ServerInfoDotNet->fAllowUpdate = serverinfo->fAllowUpdate;
246 r->ServerInfoDotNet->fDsAvailable = serverinfo->fDsAvailable;
247 r->ServerInfoDotNet->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
248 r->ServerInfoDotNet->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
249 r->ServerInfoDotNet->aipServerAddrs = dns_addr_array_to_ip4_array(mem_ctx,
250 serverinfo->aipServerAddrs);
251 r->ServerInfoDotNet->aipListenAddrs = dns_addr_array_to_ip4_array(mem_ctx,
252 serverinfo->aipListenAddrs);
253 r->ServerInfoDotNet->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
254 r->ServerInfoDotNet->aipLogFilter = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
255 r->ServerInfoDotNet->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
256 r->ServerInfoDotNet->pszDomainName = talloc_strdup(mem_ctx, serverinfo->pszDomainName);
257 r->ServerInfoDotNet->pszForestName = talloc_strdup(mem_ctx, serverinfo->pszForestName);
258 r->ServerInfoDotNet->pszDomainDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszDomainDirectoryPartition);
259 r->ServerInfoDotNet->pszForestDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszForestDirectoryPartition);
260 r->ServerInfoDotNet->dwLogLevel = serverinfo->dwLogLevel;
261 r->ServerInfoDotNet->dwDebugLevel = serverinfo->dwDebugLevel;
262 r->ServerInfoDotNet->dwForwardTimeout = serverinfo->dwForwardTimeout;
263 r->ServerInfoDotNet->dwRpcProtocol = serverinfo->dwRpcProtocol;
264 r->ServerInfoDotNet->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
265 r->ServerInfoDotNet->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
266 r->ServerInfoDotNet->dwRecursionRetry = serverinfo->dwRecursionRetry;
267 r->ServerInfoDotNet->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
268 r->ServerInfoDotNet->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
269 r->ServerInfoDotNet->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
270 r->ServerInfoDotNet->dwLocalNetPriorityNetMask = serverinfo->dwLocalNetPriorityNetMask;
271 r->ServerInfoDotNet->dwScavengingInterval = serverinfo->dwScavengingInterval;
272 r->ServerInfoDotNet->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
273 r->ServerInfoDotNet->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
274 r->ServerInfoDotNet->dwLastScavengeTime = serverinfo->dwLastScavengeTime;
275 r->ServerInfoDotNet->dwEventLogLevel = serverinfo->dwEventLogLevel;
276 r->ServerInfoDotNet->dwLogFileMaxSize = serverinfo->dwLogFileMaxSize;
277 r->ServerInfoDotNet->dwDsForestVersion = serverinfo->dwDsForestVersion;
278 r->ServerInfoDotNet->dwDsDomainVersion = serverinfo->dwDsDomainVersion;
279 r->ServerInfoDotNet->dwDsDsaVersion = serverinfo->dwDsDsaVersion;
280 r->ServerInfoDotNet->fAutoReverseZones = serverinfo->fAutoReverseZones;
281 r->ServerInfoDotNet->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
282 r->ServerInfoDotNet->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
283 r->ServerInfoDotNet->fForwardDelegations = serverinfo->fForwardDelegations;
284 r->ServerInfoDotNet->fNoRecursion = serverinfo->fNoRecursion;
285 r->ServerInfoDotNet->fSecureResponses = serverinfo->fSecureResponses;
286 r->ServerInfoDotNet->fRoundRobin = serverinfo->fRoundRobin;
287 r->ServerInfoDotNet->fLocalNetPriority = serverinfo->fLocalNetPriority;
288 r->ServerInfoDotNet->fBindSecondaries = serverinfo->fBindSecondaries;
289 r->ServerInfoDotNet->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
290 r->ServerInfoDotNet->fStrictFileParsing = serverinfo->fStrictFileParsing;
291 r->ServerInfoDotNet->fLooseWildcarding = serverinfo->fLooseWildcarding;
292 r->ServerInfoDotNet->fDefaultAgingState = serverinfo->fDefaultAgingState;
294 } else if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
295 *typeid = DNSSRV_TYPEID_SERVER_INFO;
296 r->ServerInfo = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_LONGHORN);
298 r->ServerInfo->dwRpcStructureVersion = 0x02;
299 r->ServerInfo->dwVersion = serverinfo->dwVersion;
300 r->ServerInfo->fBootMethod = serverinfo->fBootMethod;
301 r->ServerInfo->fAdminConfigured = serverinfo->fAdminConfigured;
302 r->ServerInfo->fAllowUpdate = serverinfo->fAllowUpdate;
303 r->ServerInfo->fDsAvailable = serverinfo->fDsAvailable;
304 r->ServerInfo->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
305 r->ServerInfo->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
306 r->ServerInfo->aipServerAddrs = serverinfo->aipServerAddrs;
307 r->ServerInfo->aipListenAddrs = serverinfo->aipListenAddrs;
308 r->ServerInfo->aipForwarders = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders);
309 r->ServerInfo->aipLogFilter = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter);
310 r->ServerInfo->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
311 r->ServerInfo->pszDomainName = talloc_strdup(mem_ctx, serverinfo->pszDomainName);
312 r->ServerInfo->pszForestName = talloc_strdup(mem_ctx, serverinfo->pszForestName);
313 r->ServerInfo->pszDomainDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszDomainDirectoryPartition);
314 r->ServerInfo->pszForestDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszForestDirectoryPartition);
315 r->ServerInfo->dwLogLevel = serverinfo->dwLogLevel;
316 r->ServerInfo->dwDebugLevel = serverinfo->dwDebugLevel;
317 r->ServerInfo->dwForwardTimeout = serverinfo->dwForwardTimeout;
318 r->ServerInfo->dwRpcProtocol = serverinfo->dwRpcProtocol;
319 r->ServerInfo->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
320 r->ServerInfo->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
321 r->ServerInfo->dwRecursionRetry = serverinfo->dwRecursionRetry;
322 r->ServerInfo->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
323 r->ServerInfo->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
324 r->ServerInfo->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
325 r->ServerInfo->dwLocalNetPriorityNetMask = serverinfo->dwLocalNetPriorityNetMask;
326 r->ServerInfo->dwScavengingInterval = serverinfo->dwScavengingInterval;
327 r->ServerInfo->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
328 r->ServerInfo->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
329 r->ServerInfo->dwLastScavengeTime = serverinfo->dwLastScavengeTime;
330 r->ServerInfo->dwEventLogLevel = serverinfo->dwEventLogLevel;
331 r->ServerInfo->dwLogFileMaxSize = serverinfo->dwLogFileMaxSize;
332 r->ServerInfo->dwDsForestVersion = serverinfo->dwDsForestVersion;
333 r->ServerInfo->dwDsDomainVersion = serverinfo->dwDsDomainVersion;
334 r->ServerInfo->dwDsDsaVersion = serverinfo->dwDsDsaVersion;
335 r->ServerInfo->fReadOnlyDC = serverinfo->fReadOnlyDC;
336 r->ServerInfo->fAutoReverseZones = serverinfo->fAutoReverseZones;
337 r->ServerInfo->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
338 r->ServerInfo->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
339 r->ServerInfo->fForwardDelegations = serverinfo->fForwardDelegations;
340 r->ServerInfo->fNoRecursion = serverinfo->fNoRecursion;
341 r->ServerInfo->fSecureResponses = serverinfo->fSecureResponses;
342 r->ServerInfo->fRoundRobin = serverinfo->fRoundRobin;
343 r->ServerInfo->fLocalNetPriority = serverinfo->fLocalNetPriority;
344 r->ServerInfo->fBindSecondaries = serverinfo->fBindSecondaries;
345 r->ServerInfo->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
346 r->ServerInfo->fStrictFileParsing = serverinfo->fStrictFileParsing;
347 r->ServerInfo->fLooseWildcarding = serverinfo->fLooseWildcarding;
348 r->ServerInfo->fDefaultAgingState = serverinfo->fDefaultAgingState;
350 return WERR_OK;
353 is_integer = 0;
355 if (strcasecmp(operation, "AddressAnswerLimit") == 0) {
356 answer_integer = serverinfo->cAddressAnswerLimit;
357 is_integer = 1;
358 } else if (strcasecmp(operation, "AdminConfigured") == 0) {
359 answer_integer = serverinfo->fAdminConfigured;
360 is_integer = 1;
361 } else if (strcasecmp(operation, "AllowCNAMEAtNS") == 0) {
362 answer_integer = 0;
363 is_integer = 1;
364 } else if (strcasecmp(operation, "AllowUpdate") == 0) {
365 answer_integer = serverinfo->fAllowUpdate;
366 is_integer = 1;
367 } else if (strcasecmp(operation, "AutoCacheUpdate") == 0) {
368 answer_integer = serverinfo->fAutoCacheUpdate;
369 is_integer = 1;
370 } else if (strcasecmp(operation, "AutoConfigFileZones") == 0) {
371 answer_integer = 1;
372 is_integer = 1;
373 } else if (strcasecmp(operation, "BindSecondaries") == 0) {
374 answer_integer = serverinfo->fBindSecondaries;
375 is_integer = 1;
376 } else if (strcasecmp(operation, "BootMethod") == 0) {
377 answer_integer = serverinfo->fBootMethod;
378 is_integer = 1;
379 } else if (strcasecmp(operation, "DebugLevel") == 0) {
380 answer_integer = serverinfo->dwDebugLevel;
381 is_integer = 1;
382 } else if (strcasecmp(operation, "DefaultAgingState") == 0) {
383 answer_integer = serverinfo->fDefaultAgingState;
384 is_integer = 1;
385 } else if (strcasecmp(operation, "DefaultNoRefreshInterval") == 0) {
386 answer_integer = serverinfo->dwDefaultNoRefreshInterval;
387 is_integer = 1;
388 } else if (strcasecmp(operation, "DefaultRefreshInterval") == 0) {
389 answer_integer = serverinfo->dwDefaultRefreshInterval;
390 is_integer = 1;
391 } else if (strcasecmp(operation, "DeleteOutsideGlue") == 0) {
392 answer_integer = 0;
393 is_integer = 1;
394 } else if (strcasecmp(operation, "DisjointNets") == 0) {
395 answer_integer = 0;
396 is_integer = 1;
397 } else if (strcasecmp(operation, "DsLazyUpdateInterval") == 0) {
398 answer_integer = 3; /* seconds */
399 is_integer = 1;
400 } else if (strcasecmp(operation, "DsPollingInterval") == 0) {
401 answer_integer = serverinfo->dwDsPollingInterval;
402 is_integer = 1;
403 } else if (strcasecmp(operation, "DsTombstoneInterval") == 0) {
404 answer_integer = 0x00127500; /* 14 days */
405 is_integer = 1;
406 } else if (strcasecmp(operation, "EnableRegistryBoot") == 0) {
407 answer_integer = 0;
408 is_integer = 1;
409 } else if (strcasecmp(operation, "EventLogLevel") == 0) {
410 answer_integer = serverinfo->dwEventLogLevel;
411 is_integer = 1;
412 } else if (strcasecmp(operation, "ForceSoaSerial") == 0) {
413 answer_integer = 0;
414 is_integer = 1;
415 } else if (strcasecmp(operation, "ForceSaoRetry") == 0) {
416 answer_integer = 0;
417 is_integer = 1;
418 } else if (strcasecmp(operation, "ForceSoaRefresh") == 0) {
419 answer_integer = 0;
420 is_integer = 1;
421 } else if (strcasecmp(operation, "ForceSoaMinimumTtl") == 0) {
422 answer_integer = 0;
423 is_integer = 1;
424 } else if (strcasecmp(operation, "ForwardDelegations") == 0) {
425 answer_integer = 1;
426 is_integer = 1;
427 } else if (strcasecmp(operation, "ForwardingTimeout") == 0) {
428 answer_integer = serverinfo->dwForwardTimeout;
429 is_integer = 1;
430 } else if (strcasecmp(operation, "IsSlave") == 0) {
431 answer_integer = 0;
432 is_integer = 1;
433 } else if (strcasecmp(operation, "LocalNetPriority") == 0) {
434 answer_integer = serverinfo->fLocalNetPriority;
435 is_integer = 1;
436 } else if (strcasecmp(operation, "LogFileMaxSize") == 0) {
437 answer_integer = serverinfo->dwLogFileMaxSize;
438 is_integer = 1;
439 } else if (strcasecmp(operation, "LogLevel") == 0) {
440 answer_integer = serverinfo->dwLogLevel;
441 is_integer = 1;
442 } else if (strcasecmp(operation, "LooseWildcarding") == 0) {
443 answer_integer = serverinfo->fLooseWildcarding;
444 is_integer = 1;
445 } else if (strcasecmp(operation, "MaxCacheTtl") == 0) {
446 answer_integer = serverinfo->dwMaxCacheTtl;
447 is_integer = 1;
448 } else if (strcasecmp(operation, "MaxNegativeCacheTtl") == 0) {
449 answer_integer = 0x00000384; /* 15 minutes */
450 is_integer = 1;
451 } else if (strcasecmp(operation, "NameCheckFlag") == 0) {
452 answer_integer = serverinfo->dwNameCheckFlag;
453 is_integer = 1;
454 } else if (strcasecmp(operation, "NoRecursion") == 0) {
455 answer_integer = serverinfo->fNoRecursion;
456 is_integer = 1;
457 } else if (strcasecmp(operation, "NoUpdateDelegations") == 0) {
458 answer_integer = 1;
459 is_integer = 1;
460 } else if (strcasecmp(operation, "PublishAutonet") == 0) {
461 answer_integer = 0;
462 is_integer = 1;
463 } else if (strcasecmp(operation, "QuietRecvFaultInterval") == 0) {
464 answer_integer = 0;
465 is_integer = 1;
466 } else if (strcasecmp(operation, "QuietRecvLogInterval") == 0) {
467 answer_integer = 0;
468 is_integer = 1;
469 } else if (strcasecmp(operation, "RecursionRetry") == 0) {
470 answer_integer = serverinfo->dwRecursionRetry;
471 is_integer = 1;
472 } else if (strcasecmp(operation, "RecursionTimeout") == 0) {
473 answer_integer = serverinfo->dwRecursionTimeout;
474 is_integer = 1;
475 } else if (strcasecmp(operation, "ReloadException") == 0) {
476 answer_integer = 0;
477 is_integer = 1;
478 } else if (strcasecmp(operation, "RoundRobin") == 0) {
479 answer_integer = serverinfo->fRoundRobin;
480 is_integer = 1;
481 } else if (strcasecmp(operation, "RpcProtocol") == 0) {
482 answer_integer = serverinfo->dwRpcProtocol;
483 is_integer = 1;
484 } else if (strcasecmp(operation, "SecureResponses") == 0) {
485 answer_integer = serverinfo->fSecureResponses;
486 is_integer = 1;
487 } else if (strcasecmp(operation, "SendPort") == 0) {
488 answer_integer = 0;
489 is_integer = 1;
490 } else if (strcasecmp(operation, "ScavengingInterval") == 0) {
491 answer_integer = serverinfo->dwScavengingInterval;
492 is_integer = 1;
493 } else if (strcasecmp(operation, "SocketPoolSize") == 0) {
494 answer_integer = 0x000009C4;
495 is_integer = 1;
496 } else if (strcasecmp(operation, "StrictFileParsing") == 0) {
497 answer_integer = serverinfo->fStrictFileParsing;
498 is_integer = 1;
499 } else if (strcasecmp(operation, "SyncDnsZoneSerial") == 0) {
500 answer_integer = 2; /* ZONE_SERIAL_SYNC_XFER */
501 is_integer = 1;
502 } else if (strcasecmp(operation, "UpdateOptions") == 0) {
503 answer_integer = 0x0000030F; /* DNS_DEFAULT_UPDATE_OPTIONS */
504 is_integer = 1;
505 } else if (strcasecmp(operation, "UseSystemEvengLog") == 0) {
506 answer_integer = 0;
507 is_integer = 1;
508 } else if (strcasecmp(operation, "Version") == 0) {
509 answer_integer = serverinfo->dwVersion;
510 is_integer = 1;
511 } else if (strcasecmp(operation, "XfrConnectTimeout") == 0) {
512 answer_integer = 0x0000001E;
513 is_integer = 1;
514 } else if (strcasecmp(operation, "WriteAuthorityNs") == 0) {
515 answer_integer = serverinfo->fWriteAuthorityNs;
516 is_integer = 1;
517 } else if (strcasecmp(operation, "AdditionalRecursionTimeout") == 0) {
518 answer_integer = 0x00000004;
519 is_integer = 1;
520 } else if (strcasecmp(operation, "AppendMsZoneTransferFlag") == 0) {
521 answer_integer = 0;
522 is_integer = 1;
523 } else if (strcasecmp(operation, "AutoCreateDelegations") == 0) {
524 answer_integer = 0; /* DNS_ACD_DONT_CREATE */
525 is_integer = 1;
526 } else if (strcasecmp(operation, "BreakOnAscFailure") == 0) {
527 answer_integer = 0;
528 is_integer = 1;
529 } else if (strcasecmp(operation, "CacheEmptyAuthResponses") == 0) {
530 answer_integer = 0;
531 is_integer = 1;
532 } else if (strcasecmp(operation, "DirectoryPartitionAutoEnlistInterval") == 0) {
533 answer_integer = 0x00015180; /* 1 day */
534 is_integer = 1;
535 } else if (strcasecmp(operation, "DisableAutoReverseZones") == 0) {
536 answer_integer = ~serverinfo->fAutoReverseZones;
537 is_integer = 1;
538 } else if (strcasecmp(operation, "EDnsCacheTimeout") == 0) {
539 answer_integer = 0x00000384; /* 15 minutes */
540 is_integer = 1;
541 } else if (strcasecmp(operation, "EnableDirectoryPartitions") == 0) {
542 answer_integer = serverinfo->fDsAvailable;
543 is_integer = 1;
544 } else if (strcasecmp(operation, "EnableDnsSec") == 0) {
545 answer_integer = 0;
546 is_integer = 1;
547 } else if (strcasecmp(operation, "EnableEDnsProbes") == 0) {
548 answer_integer = 0;
549 is_integer = 1;
550 } else if (strcasecmp(operation, "EnableEDnsReception") == 0) {
551 answer_integer = 0;
552 is_integer = 1;
553 } else if (strcasecmp(operation, "EnableIPv6") == 0) {
554 answer_integer = 0;
555 is_integer = 1;
556 } else if (strcasecmp(operation, "EnableIQueryResponseGeneration") == 0) {
557 answer_integer = 0;
558 is_integer = 1;
559 } else if (strcasecmp(operation, "EnableSendErrorSuppression") == 0) {
560 answer_integer = 0;
561 is_integer = 1;
562 } else if (strcasecmp(operation, "EnableUpdateForwarding") == 0) {
563 answer_integer = 0;
564 is_integer = 1;
565 } else if (strcasecmp(operation, "EnableWinsR") == 0) {
566 answer_integer = 0;
567 is_integer = 1;
568 } else if (strcasecmp(operation, "ForceDsaBehaviorVersion") == 0) {
569 answer_integer = serverinfo->dwDsDsaVersion;
570 is_integer = 1;
571 } else if (strcasecmp(operation, "ForceDomainBehaviorVersion") == 0) {
572 answer_integer = serverinfo->dwDsDsaVersion;
573 is_integer = 1;
574 } else if (strcasecmp(operation, "ForceForestBehaviorVersion") == 0) {
575 answer_integer = serverinfo->dwDsDsaVersion;
576 is_integer = 1;
577 } else if (strcasecmp(operation, "HeapDebug") == 0) {
578 answer_integer = 0;
579 is_integer = 1;
580 } else if (strcasecmp(operation, "LameDelegationTtl") == 0) {
581 answer_integer = 0; /* seconds */
582 is_integer = 1;
583 } else if (strcasecmp(operation, "LocalNetPriorityNetMask") == 0) {
584 answer_integer = serverinfo->dwLocalNetPriorityNetMask;
585 is_integer = 1;
586 } else if (strcasecmp(operation, "MaxCacheSize") == 0) {
587 answer_integer = 0;
588 is_integer = 1;
589 } else if (strcasecmp(operation, "MaxResourceRecordsInNonSecureUpdate") == 0) {
590 answer_integer = 0x0000001E;
591 is_integer = 1;
592 } else if (strcasecmp(operation, "OperationsLogLevel") == 0) {
593 answer_integer = 0;
594 is_integer = 1;
595 } else if (strcasecmp(operation, "OperationsLogLevel2") == 0) {
596 answer_integer = 0;
597 is_integer = 1;
598 } else if (strcasecmp(operation, "MaximumUdpPacketSize") == 0) {
599 answer_integer = 0x00004000; /* maximum possible */
600 is_integer = 1;
601 } else if (strcasecmp(operation, "RecurseToInternetRootMask") == 0) {
602 answer_integer = 0;
603 is_integer = 1;
604 } else if (strcasecmp(operation, "SelfTest") == 0) {
605 answer_integer = 0;
606 is_integer = 1;
607 } else if (strcasecmp(operation, "SilentlyIgnoreCNameUpdateConflicts") == 0) {
608 answer_integer = 1;
609 is_integer = 1;
610 } else if (strcasecmp(operation, "TcpReceivePacketSize") == 0) {
611 answer_integer = 0x00010000;
612 is_integer = 1;
613 } else if (strcasecmp(operation, "XfrThrottleMultiplier") == 0) {
614 answer_integer = 0x0000000A;
615 is_integer = 1;
616 } else if (strcasecmp(operation, "AllowMsdcsLookupRetry") == 0) {
617 answer_integer = 1;
618 is_integer = 1;
619 } else if (strcasecmp(operation, "AllowReadOnlyZoneTransfer") == 0) {
620 answer_integer = 0;
621 is_integer = 1;
622 } else if (strcasecmp(operation, "DsBackGroundLoadPaused") == 0) {
623 answer_integer = 0;
624 is_integer = 1;
625 } else if (strcasecmp(operation, "DsMinimumBackgroundLoadThreads") == 0) {
626 answer_integer = 0;
627 is_integer = 1;
628 } else if (strcasecmp(operation, "DsRemoteReplicationDelay") == 0) {
629 answer_integer = 0x0000001E; /* 30 seconds */
630 is_integer = 1;
631 } else if (strcasecmp(operation, "EnableDuplicateQuerySuppresion") == 0) {
632 answer_integer = 0;
633 is_integer = 1;
634 } else if (strcasecmp(operation, "EnableGlobalNamesSupport") == 0) {
635 answer_integer = 0;
636 is_integer = 1;
637 } else if (strcasecmp(operation, "EnableVersionQuery") == 0) {
638 answer_integer = 1; /* DNS_VERSION_QUERY_FULL */
639 is_integer = 1;
640 } else if (strcasecmp(operation, "EnableRsoForRodc") == 0) {
641 answer_integer = 0;
642 is_integer = 1;
643 } else if (strcasecmp(operation, "ForceRODCMode") == 0) {
644 answer_integer = 0;
645 is_integer = 1;
646 } else if (strcasecmp(operation, "GlobalNamesAlwaysQuerySrv") == 0) {
647 answer_integer = 1;
648 is_integer = 1;
649 } else if (strcasecmp(operation, "GlobalNamesBlockUpdates") == 0) {
650 answer_integer = 0;
651 is_integer = 1;
652 } else if (strcasecmp(operation, "GlobalNamesEnableEDnsProbes") == 0) {
653 answer_integer = 0;
654 is_integer = 1;
655 } else if (strcasecmp(operation, "GlobalNamesPreferAAAA") == 0) {
656 answer_integer = 0;
657 is_integer = 1;
658 } else if (strcasecmp(operation, "GlobalNamesQueryOrder") == 0) {
659 answer_integer = 1;
660 is_integer = 1;
661 } else if (strcasecmp(operation, "GlobalNamesSendTimeout") == 0) {
662 answer_integer = 3; /* seconds */
663 is_integer = 1;
664 } else if (strcasecmp(operation, "GlobalNamesServerQueryInterval") == 0) {
665 answer_integer = 0x00005460; /* 6 hours */
666 is_integer = 1;
667 } else if (strcasecmp(operation, "RemoteIPv4RankBoost") == 0) {
668 answer_integer = 0;
669 is_integer = 1;
670 } else if (strcasecmp(operation, "RemoteIPv6RankBoost") == 0) {
671 answer_integer = 0;
672 is_integer = 1;
673 } else if (strcasecmp(operation, "MaximumRodcRsoAttemptsPerCycle") == 0) {
674 answer_integer = 0x00000064;
675 is_integer = 1;
676 } else if (strcasecmp(operation, "MaximumRodcRsoQueueLength") == 0) {
677 answer_integer = 0x0000012C;
678 is_integer = 1;
679 } else if (strcasecmp(operation, "EnableGlobalQueryBlockList") == 0) {
680 answer_integer = 0;
681 is_integer = 1;
682 } else if (strcasecmp(operation, "OpenACLOnProxyUpdates") == 0) {
683 answer_integer = 0;
684 is_integer = 1;
685 } else if (strcasecmp(operation, "CacheLockingPercent") == 0) {
686 answer_integer = 0x00000064;
687 is_integer = 1;
690 if (is_integer == 1) {
691 *typeid = DNSSRV_TYPEID_DWORD;
692 r->Dword = answer_integer;
693 return WERR_OK;
696 is_addresses = 0;
698 if (strcasecmp(operation, "Forwarders") == 0) {
699 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
700 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders);
701 } else {
702 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
704 is_addresses = 1;
705 } else if (strcasecmp(operation, "ListenAddresses") == 0) {
706 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
707 answer_addrarray = serverinfo->aipListenAddrs;
708 } else {
709 answer_iparray = dns_addr_array_to_ip4_array(mem_ctx, serverinfo->aipListenAddrs);
711 is_addresses = 1;
712 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
713 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
714 answer_addrarray = NULL;
715 } else {
716 answer_iparray = NULL;
718 is_addresses = 1;
719 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
720 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
721 answer_addrarray = NULL;
722 } else {
723 answer_iparray = NULL;
725 is_addresses = 1;
726 } else if (strcasecmp(operation, "LogIPFilterList") == 0) {
727 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
728 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter);
729 } else {
730 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
732 is_addresses = 1;
735 if (is_addresses == 1) {
736 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
737 *typeid = DNSSRV_TYPEID_ADDRARRAY;
738 r->AddrArray = answer_addrarray;
739 } else {
740 *typeid = DNSSRV_TYPEID_IPARRAY;
741 r->IpArray = answer_iparray;
743 return WERR_OK;
746 is_string = is_wstring = 0;
748 if (strcasecmp(operation, "DomainDirectoryPartitionBaseName") == 0) {
749 answer_string = talloc_strdup(mem_ctx, "DomainDnsZones");
750 if (! answer_string) {
751 return WERR_OUTOFMEMORY;
753 is_string = 1;
754 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
755 answer_string = talloc_strdup(mem_ctx, "ForestDnsZones");
756 if (! answer_string) {
757 return WERR_OUTOFMEMORY;
759 is_string = 1;
760 } else if (strcasecmp(operation, "LogFilePath") == 0) {
761 answer_string = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
762 is_wstring = 1;
763 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
764 answer_string = NULL;
765 is_wstring = 1;
766 } else if (strcasecmp(operation, "DsBackgroundPauseName") == 0) {
767 answer_string = NULL;
768 is_string = 1;
769 } else if (strcasecmp(operation, "DsNotRoundRobinTypes") == 0) {
770 answer_string = NULL;
771 is_string = 1;
774 if (is_string == 1) {
775 *typeid = DNSSRV_TYPEID_LPSTR;
776 r->String = answer_string;
777 return WERR_OK;
778 } else if (is_wstring == 1) {
779 *typeid = DNSSRV_TYPEID_LPWSTR;
780 r->WideString = answer_string;
781 return WERR_OK;
784 is_stringlist = 0;
786 if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
787 answer_stringlist = NULL;
788 is_stringlist = 1;
789 } else if (strcasecmp(operation, "SocketPoolExcludedPortRanges") == 0) {
790 answer_stringlist = NULL;
791 is_stringlist = 1;
794 if (is_stringlist == 1) {
795 *typeid = DNSSRV_TYPEID_UTF8_STRING_LIST;
796 r->Utf8StringList = answer_stringlist;
797 return WERR_OK;
800 DEBUG(0,("dnsserver: Invalid server operation %s", operation));
801 return WERR_DNS_ERROR_INVALID_PROPERTY;
804 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
805 static WERROR dnsserver_query_zone(struct dnsserver_state *dsstate,
806 TALLOC_CTX *mem_ctx,
807 struct dnsserver_zone *z,
808 const char *operation,
809 const unsigned int client_version,
810 enum DNS_RPC_TYPEID *typeid,
811 union DNSSRV_RPC_UNION *r)
813 uint8_t is_integer, is_addresses, is_string;
814 uint32_t answer_integer;
815 struct IP4_ARRAY *answer_iparray;
816 struct DNS_ADDR_ARRAY *answer_addrarray;
817 char *answer_string;
818 struct dnsserver_zoneinfo *zoneinfo;
820 zoneinfo = z->zoneinfo;
822 if (strcasecmp(operation, "Zone") == 0) {
823 if (client_version == DNS_CLIENT_VERSION_W2K) {
824 *typeid = DNSSRV_TYPEID_ZONE_W2K;
825 r->ZoneW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
827 r->ZoneW2K->pszZoneName = talloc_strdup(mem_ctx, z->name);
828 r->ZoneW2K->Flags = zoneinfo->Flags;
829 r->ZoneW2K->ZoneType = zoneinfo->dwZoneType;
830 r->ZoneW2K->Version = zoneinfo->Version;
831 } else {
832 *typeid = DNSSRV_TYPEID_ZONE;
833 r->Zone = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
835 r->Zone->dwRpcStructureVersion = 0x01;
836 r->Zone->pszZoneName = talloc_strdup(mem_ctx, z->name);
837 r->Zone->Flags = zoneinfo->Flags;
838 r->Zone->ZoneType = zoneinfo->dwZoneType;
839 r->Zone->Version = zoneinfo->Version;
840 r->Zone->dwDpFlags = z->partition->dwDpFlags;
841 r->Zone->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
843 return WERR_OK;
846 if (strcasecmp(operation, "ZoneInfo") == 0) {
847 if (client_version == DNS_CLIENT_VERSION_W2K) {
848 *typeid = DNSSRV_TYPEID_ZONE_INFO_W2K;
849 r->ZoneInfoW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_W2K);
851 r->ZoneInfoW2K->pszZoneName = talloc_strdup(mem_ctx, z->name);
852 r->ZoneInfoW2K->dwZoneType = zoneinfo->dwZoneType;
853 r->ZoneInfoW2K->fReverse = zoneinfo->fReverse;
854 r->ZoneInfoW2K->fAllowUpdate = zoneinfo->fAllowUpdate;
855 r->ZoneInfoW2K->fPaused = zoneinfo->fPaused;
856 r->ZoneInfoW2K->fShutdown = zoneinfo->fShutdown;
857 r->ZoneInfoW2K->fAutoCreated = zoneinfo->fAutoCreated;
858 r->ZoneInfoW2K->fUseDatabase = zoneinfo->fUseDatabase;
859 r->ZoneInfoW2K->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
860 r->ZoneInfoW2K->aipMasters = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
861 r->ZoneInfoW2K->fSecureSecondaries = zoneinfo->fSecureSecondaries;
862 r->ZoneInfoW2K->fNotifyLevel = zoneinfo->fNotifyLevel;
863 r->ZoneInfoW2K->aipSecondaries = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
864 r->ZoneInfoW2K->aipNotify = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
865 r->ZoneInfoW2K->fUseWins = zoneinfo->fUseWins;
866 r->ZoneInfoW2K->fUseNbstat = zoneinfo->fUseNbstat;
867 r->ZoneInfoW2K->fAging = zoneinfo->fAging;
868 r->ZoneInfoW2K->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
869 r->ZoneInfoW2K->dwRefreshInterval = zoneinfo->dwRefreshInterval;
870 r->ZoneInfoW2K->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
871 r->ZoneInfoW2K->aipScavengeServers = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
873 } else if (client_version == DNS_CLIENT_VERSION_DOTNET) {
874 *typeid = DNSSRV_TYPEID_ZONE_INFO_DOTNET;
875 r->ZoneInfoDotNet = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_DOTNET);
877 r->ZoneInfoDotNet->dwRpcStructureVersion = 0x01;
878 r->ZoneInfoDotNet->pszZoneName = talloc_strdup(mem_ctx, z->name);
879 r->ZoneInfoDotNet->dwZoneType = zoneinfo->dwZoneType;
880 r->ZoneInfoDotNet->fReverse = zoneinfo->fReverse;
881 r->ZoneInfoDotNet->fAllowUpdate = zoneinfo->fAllowUpdate;
882 r->ZoneInfoDotNet->fPaused = zoneinfo->fPaused;
883 r->ZoneInfoDotNet->fShutdown = zoneinfo->fShutdown;
884 r->ZoneInfoDotNet->fAutoCreated = zoneinfo->fAutoCreated;
885 r->ZoneInfoDotNet->fUseDatabase = zoneinfo->fUseDatabase;
886 r->ZoneInfoDotNet->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
887 r->ZoneInfoDotNet->aipMasters = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
888 r->ZoneInfoDotNet->fSecureSecondaries = zoneinfo->fSecureSecondaries;
889 r->ZoneInfoDotNet->fNotifyLevel = zoneinfo->fNotifyLevel;
890 r->ZoneInfoDotNet->aipSecondaries = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
891 r->ZoneInfoDotNet->aipNotify = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
892 r->ZoneInfoDotNet->fUseWins = zoneinfo->fUseWins;
893 r->ZoneInfoDotNet->fUseNbstat = zoneinfo->fUseNbstat;
894 r->ZoneInfoDotNet->fAging = zoneinfo->fAging;
895 r->ZoneInfoDotNet->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
896 r->ZoneInfoDotNet->dwRefreshInterval = zoneinfo->dwRefreshInterval;
897 r->ZoneInfoDotNet->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
898 r->ZoneInfoDotNet->aipScavengeServers = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
899 r->ZoneInfoDotNet->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
900 r->ZoneInfoDotNet->fForwarderSlave = zoneinfo->fForwarderSlave;
901 r->ZoneInfoDotNet->aipLocalMasters = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
902 r->ZoneInfoDotNet->dwDpFlags = z->partition->dwDpFlags;
903 r->ZoneInfoDotNet->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
904 r->ZoneInfoDotNet->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
905 r->ZoneInfoDotNet->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
906 r->ZoneInfoDotNet->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
908 } else {
909 *typeid = DNSSRV_TYPEID_ZONE_INFO;
910 r->ZoneInfo = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_LONGHORN);
912 r->ZoneInfo->dwRpcStructureVersion = 0x02;
913 r->ZoneInfo->pszZoneName = talloc_strdup(mem_ctx, z->name);
914 r->ZoneInfo->dwZoneType = zoneinfo->dwZoneType;
915 r->ZoneInfo->fReverse = zoneinfo->fReverse;
916 r->ZoneInfo->fAllowUpdate = zoneinfo->fAllowUpdate;
917 r->ZoneInfo->fPaused = zoneinfo->fPaused;
918 r->ZoneInfo->fShutdown = zoneinfo->fShutdown;
919 r->ZoneInfo->fAutoCreated = zoneinfo->fAutoCreated;
920 r->ZoneInfo->fUseDatabase = zoneinfo->fUseDatabase;
921 r->ZoneInfo->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
922 r->ZoneInfo->aipMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipMasters);
923 r->ZoneInfo->fSecureSecondaries = zoneinfo->fSecureSecondaries;
924 r->ZoneInfo->fNotifyLevel = zoneinfo->fNotifyLevel;
925 r->ZoneInfo->aipSecondaries = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipSecondaries);
926 r->ZoneInfo->aipNotify = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipNotify);
927 r->ZoneInfo->fUseWins = zoneinfo->fUseWins;
928 r->ZoneInfo->fUseNbstat = zoneinfo->fUseNbstat;
929 r->ZoneInfo->fAging = zoneinfo->fAging;
930 r->ZoneInfo->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
931 r->ZoneInfo->dwRefreshInterval = zoneinfo->dwRefreshInterval;
932 r->ZoneInfo->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
933 r->ZoneInfo->aipScavengeServers = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipScavengeServers);
934 r->ZoneInfo->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
935 r->ZoneInfo->fForwarderSlave = zoneinfo->fForwarderSlave;
936 r->ZoneInfo->aipLocalMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
937 r->ZoneInfo->dwDpFlags = z->partition->dwDpFlags;
938 r->ZoneInfo->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
939 r->ZoneInfo->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
940 r->ZoneInfo->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
941 r->ZoneInfo->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
943 r->ZoneInfo->fQueuedForBackgroundLoad = zoneinfo->fQueuedForBackgroundLoad;
944 r->ZoneInfo->fBackgroundLoadInProgress = zoneinfo->fBackgroundLoadInProgress;
945 r->ZoneInfo->fReadOnlyZone = zoneinfo->fReadOnlyZone;
946 r->ZoneInfo->dwLastXfrAttempt = zoneinfo->dwLastXfrAttempt;
947 r->ZoneInfo->dwLastXfrResult = zoneinfo->dwLastXfrResult;
950 return WERR_OK;
953 is_integer = 0;
955 if (strcasecmp(operation, "AllowUpdate") == 0) {
956 answer_integer = zoneinfo->fAllowUpdate;
957 is_integer = 1;
958 } else if (strcasecmp(operation, "Secured") == 0) {
959 answer_integer = 0;
960 is_integer = 1;
961 } else if (strcasecmp(operation, "DsIntegrated") == 0) {
962 answer_integer = zoneinfo->fUseDatabase;
963 is_integer = 1;
964 } else if (strcasecmp(operation, "LogUpdates") == 0) {
965 answer_integer = 0;
966 is_integer = 1;
967 } else if (strcasecmp(operation, "NoRefreshInterval") == 0) {
968 answer_integer = zoneinfo->dwNoRefreshInterval;
969 is_integer = 1;
970 } else if (strcasecmp(operation, "NotifyLevel") == 0) {
971 answer_integer = zoneinfo->fNotifyLevel;
972 is_integer = 1;
973 } else if (strcasecmp(operation, "RefreshInterval") == 0) {
974 answer_integer = zoneinfo->dwRefreshInterval;
975 is_integer = 1;
976 } else if (strcasecmp(operation, "SecureSecondaries") == 0) {
977 answer_integer = zoneinfo->fSecureSecondaries;
978 is_integer = 1;
979 } else if (strcasecmp(operation, "Type") == 0) {
980 answer_integer = zoneinfo->dwZoneType;
981 is_integer = 1;
982 } else if (strcasecmp(operation, "Aging") == 0) {
983 answer_integer = zoneinfo->fAging;
984 is_integer = 1;
985 } else if (strcasecmp(operation, "ForwarderSlave") == 0) {
986 answer_integer = zoneinfo->fForwarderSlave;
987 is_integer = 1;
988 } else if (strcasecmp(operation, "ForwarderTimeout") == 0) {
989 answer_integer = zoneinfo->dwForwarderTimeout;
990 is_integer = 1;
991 } else if (strcasecmp(operation, "Unicode") == 0) {
992 answer_integer = 0;
993 is_integer = 1;
996 if (is_integer == 1) {
997 *typeid = DNSSRV_TYPEID_DWORD;
998 r->Dword = answer_integer;
999 return WERR_OK;
1002 is_addresses = 0;
1004 if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
1005 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1006 answer_addrarray = NULL;
1007 } else {
1008 answer_iparray = NULL;
1010 is_addresses = 1;
1011 } else if (strcasecmp(operation, "ScavengeServers") == 0) {
1012 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1013 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipScavengeServers);
1014 } else {
1015 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
1017 is_addresses = 1;
1018 } else if (strcasecmp(operation, "MasterServers") == 0) {
1019 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1020 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipMasters);
1021 } else {
1022 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
1024 is_addresses = 1;
1025 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
1026 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1027 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
1028 } else {
1029 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
1031 is_addresses = 1;
1032 } else if (strcasecmp(operation, "NotifyServers") == 0) {
1033 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1034 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipNotify);
1035 } else {
1036 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
1038 is_addresses = 1;
1039 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
1040 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1041 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipSecondaries);
1042 } else {
1043 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
1045 is_addresses = 1;
1048 if (is_addresses == 1) {
1049 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1050 *typeid = DNSSRV_TYPEID_ADDRARRAY;
1051 r->AddrArray = answer_addrarray;
1052 } else {
1053 *typeid = DNSSRV_TYPEID_IPARRAY;
1054 r->IpArray = answer_iparray;
1056 return WERR_OK;
1059 is_string = 0;
1061 if (strcasecmp(operation, "DatabaseFile") == 0) {
1062 answer_string = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
1063 is_string = 1;
1064 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1065 answer_string = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
1066 is_string = 1;
1067 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1068 answer_string = NULL;
1069 is_string = 1;
1072 if (is_string == 1) {
1073 *typeid = DNSSRV_TYPEID_LPSTR;
1074 r->String = answer_string;
1075 return WERR_OK;
1078 DEBUG(0,("dnsserver: Invalid zone operation %s", operation));
1079 return WERR_DNS_ERROR_INVALID_PROPERTY;
1083 /* dnsserver operation functions */
1085 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
1086 static WERROR dnsserver_operate_server(struct dnsserver_state *dsstate,
1087 TALLOC_CTX *mem_ctx,
1088 const char *operation,
1089 const unsigned int client_version,
1090 enum DNS_RPC_TYPEID typeid,
1091 union DNSSRV_RPC_UNION *r)
1093 bool valid_operation = false;
1095 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1096 valid_operation = true;
1097 } else if (strcasecmp(operation, "Restart") == 0) {
1098 valid_operation = true;
1099 } else if (strcasecmp(operation, "ClearDebugLog") == 0) {
1100 valid_operation = true;
1101 } else if (strcasecmp(operation, "ClearCache") == 0) {
1102 valid_operation = true;
1103 } else if (strcasecmp(operation, "WriteDirtyZones") == 0) {
1104 valid_operation = true;
1105 } else if (strcasecmp(operation, "ZoneCreate") == 0) {
1106 struct dnsserver_zone *z, *z2;
1107 WERROR status;
1109 z = talloc_zero(mem_ctx, struct dnsserver_zone);
1110 W_ERROR_HAVE_NO_MEMORY(z);
1111 z->partition = talloc_zero(z, struct dnsserver_partition);
1112 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z->partition, z);
1113 z->zoneinfo = talloc_zero(z, struct dnsserver_zoneinfo);
1114 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z->zoneinfo, z);
1116 if (typeid == DNSSRV_TYPEID_ZONE_CREATE_W2K) {
1117 z->name = talloc_strdup(z, r->ZoneCreateW2K->pszZoneName);
1118 z->zoneinfo->dwZoneType = r->ZoneCreateW2K->dwZoneType;
1119 z->zoneinfo->fAllowUpdate = r->ZoneCreateW2K->fAllowUpdate;
1120 z->zoneinfo->fAging = r->ZoneCreateW2K->fAging;
1121 z->zoneinfo->Flags = r->ZoneCreateW2K->dwFlags;
1122 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE_DOTNET) {
1123 z->name = talloc_strdup(z, r->ZoneCreateDotNet->pszZoneName);
1124 z->zoneinfo->dwZoneType = r->ZoneCreateDotNet->dwZoneType;
1125 z->zoneinfo->fAllowUpdate = r->ZoneCreateDotNet->fAllowUpdate;
1126 z->zoneinfo->fAging = r->ZoneCreateDotNet->fAging;
1127 z->zoneinfo->Flags = r->ZoneCreateDotNet->dwFlags;
1128 z->partition->dwDpFlags = r->ZoneCreateDotNet->dwDpFlags;
1129 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE) {
1130 z->name = talloc_strdup(z, r->ZoneCreate->pszZoneName);
1131 z->zoneinfo->dwZoneType = r->ZoneCreate->dwZoneType;
1132 z->zoneinfo->fAllowUpdate = r->ZoneCreate->fAllowUpdate;
1133 z->zoneinfo->fAging = r->ZoneCreate->fAging;
1134 z->zoneinfo->Flags = r->ZoneCreate->dwFlags;
1135 z->partition->dwDpFlags = r->ZoneCreate->dwDpFlags;
1136 } else {
1137 talloc_free(z);
1138 return WERR_DNS_ERROR_INVALID_PROPERTY;
1141 z2 = dnsserver_find_zone(dsstate->zones, z->name);
1142 if (z2 != NULL) {
1143 talloc_free(z);
1144 return WERR_DNS_ERROR_ZONE_ALREADY_EXISTS;
1147 status = dnsserver_db_create_zone(dsstate->samdb, dsstate->partitions, z,
1148 dsstate->lp_ctx);
1149 talloc_free(z);
1151 if (W_ERROR_IS_OK(status)) {
1152 dnsserver_reload_zones(dsstate);
1154 return status;
1155 } else if (strcasecmp(operation, "ClearStatistics") == 0) {
1156 valid_operation = true;
1157 } else if (strcasecmp(operation, "EnlistDirectoryPartition") == 0) {
1158 valid_operation = true;
1159 } else if (strcasecmp(operation, "StartScavenging") == 0) {
1160 valid_operation = true;
1161 } else if (strcasecmp(operation, "AbortScavenging") == 0) {
1162 valid_operation = true;
1163 } else if (strcasecmp(operation, "AutoConfigure") == 0) {
1164 valid_operation = true;
1165 } else if (strcasecmp(operation, "ExportSettings") == 0) {
1166 valid_operation = true;
1167 } else if (strcasecmp(operation, "PrepareForDemotion") == 0) {
1168 valid_operation = true;
1169 } else if (strcasecmp(operation, "PrepareForUninstall") == 0) {
1170 valid_operation = true;
1171 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1172 valid_operation = true;
1173 } else if (strcasecmp(operation, "DeleteRecord") == 0) {
1174 valid_operation = true;
1175 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1176 valid_operation = true;
1177 } else if (strcasecmp(operation, "ListenAddresses") == 0) {
1178 valid_operation = true;
1179 } else if (strcasecmp(operation, "Forwarders") == 0) {
1180 valid_operation = true;
1181 } else if (strcasecmp(operation, "LogFilePath") == 0) {
1182 valid_operation = true;
1183 } else if (strcasecmp(operation, "LogIpFilterList") == 0) {
1184 valid_operation = true;
1185 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
1186 valid_operation = true;
1187 } else if (strcasecmp(operation, "DomainDirectoryPartitionBaseName") == 0) {
1188 valid_operation = true;
1189 } else if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
1190 valid_operation = true;
1191 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
1192 valid_operation = true;
1193 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
1194 valid_operation = true;
1195 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
1196 valid_operation = true;
1199 if (valid_operation) {
1200 DEBUG(0, ("dnsserver: server operation '%s' not implemented", operation));
1201 return WERR_CALL_NOT_IMPLEMENTED;
1204 DEBUG(0, ("dnsserver: invalid server operation '%s'", operation));
1205 return WERR_DNS_ERROR_INVALID_PROPERTY;
1208 static WERROR dnsserver_complex_operate_server(struct dnsserver_state *dsstate,
1209 TALLOC_CTX *mem_ctx,
1210 const char *operation,
1211 const unsigned int client_version,
1212 enum DNS_RPC_TYPEID typeid_in,
1213 union DNSSRV_RPC_UNION *rin,
1214 enum DNS_RPC_TYPEID *typeid_out,
1215 union DNSSRV_RPC_UNION *rout)
1217 int valid_operation = 0;
1218 struct dnsserver_zone *z, **zlist;
1219 int zcount;
1220 bool found1, found2, found3, found4;
1221 int i;
1223 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1224 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1225 return dnsserver_query_server(dsstate, mem_ctx,
1226 rin->String,
1227 client_version,
1228 typeid_out,
1229 rout);
1231 } else if (strcasecmp(operation, "EnumZones") == 0) {
1232 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1233 return WERR_DNS_ERROR_INVALID_PROPERTY;
1236 zcount = 0;
1237 zlist = talloc_zero_array(mem_ctx, struct dnsserver_zone *, 0);
1238 for (z = dsstate->zones; z; z = z->next) {
1240 /* Match the flags in groups
1242 * Group1 : PRIMARY, SECONDARY, CACHE, AUTO
1243 * Group2 : FORWARD, REVERSE, FORWARDER, STUB
1244 * Group3 : DS, NON_DS, DOMAIN_DP, FOREST_DP
1245 * Group4 : CUSTOM_DP, LEGACY_DP
1248 /* Group 1 */
1249 found1 = false;
1250 if (rin->Dword & 0x0000000f) {
1251 if (rin->Dword & DNS_ZONE_REQUEST_PRIMARY) {
1252 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_PRIMARY) {
1253 found1 = true;
1256 if (rin->Dword & DNS_ZONE_REQUEST_SECONDARY) {
1257 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_SECONDARY) {
1258 found1 = true;
1261 if (rin->Dword & DNS_ZONE_REQUEST_CACHE) {
1262 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_CACHE) {
1263 found1 = true;
1266 if (rin->Dword & DNS_ZONE_REQUEST_AUTO) {
1267 if (z->zoneinfo->fAutoCreated
1268 || z->partition->dwDpFlags & DNS_DP_AUTOCREATED) {
1269 found1 = true;
1272 } else {
1273 found1 = true;
1276 /* Group 2 */
1277 found2 = false;
1278 if (rin->Dword & 0x000000f0) {
1279 if (rin->Dword & DNS_ZONE_REQUEST_FORWARD) {
1280 if (!(z->zoneinfo->fReverse)) {
1281 found2 = true;
1284 if (rin->Dword & DNS_ZONE_REQUEST_REVERSE) {
1285 if (z->zoneinfo->fReverse) {
1286 found2 = true;
1289 if (rin->Dword & DNS_ZONE_REQUEST_FORWARDER) {
1290 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_FORWARDER) {
1291 found2 = true;
1294 if (rin->Dword & DNS_ZONE_REQUEST_STUB) {
1295 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_STUB) {
1296 found2 = true;
1299 } else {
1300 found2 = true;
1303 /* Group 3 */
1304 found3 = false;
1305 if (rin->Dword & 0x00000f00) {
1306 if (rin->Dword & DNS_ZONE_REQUEST_DS) {
1307 if (z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED) {
1308 found3 = true;
1311 if (rin->Dword & DNS_ZONE_REQUEST_NON_DS) {
1312 if (!(z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED)) {
1313 found3 = true;
1316 if (rin->Dword & DNS_ZONE_REQUEST_DOMAIN_DP) {
1317 if (!(z->partition->dwDpFlags & DNS_DP_DOMAIN_DEFAULT)) {
1318 found3 = true;
1321 if (rin->Dword & DNS_ZONE_REQUEST_FOREST_DP) {
1322 if (!(z->partition->dwDpFlags & DNS_DP_FOREST_DEFAULT)) {
1323 found3 = true;
1326 } else {
1327 found3 = true;
1330 /* Group 4 */
1331 if (rin->Dword & 0x0000f000) {
1332 found4 = false;
1333 } else {
1334 found4 = true;
1337 if (found1 && found2 && found3 && found4) {
1338 zlist = talloc_realloc(mem_ctx, zlist, struct dnsserver_zone *, zcount+1);
1339 zlist[zcount] = z;
1340 zcount++;
1344 if (client_version == DNS_CLIENT_VERSION_W2K) {
1345 *typeid_out = DNSSRV_TYPEID_ZONE_LIST_W2K;
1346 rout->ZoneListW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_W2K);
1348 if (zcount == 0) {
1349 rout->ZoneListW2K->dwZoneCount = 0;
1350 rout->ZoneListW2K->ZoneArray = NULL;
1352 return WERR_OK;
1355 rout->ZoneListW2K->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_W2K *, zcount);
1356 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout->ZoneListW2K->ZoneArray, zlist);
1358 for (i=0; i<zcount; i++) {
1359 rout->ZoneListW2K->ZoneArray[i] = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
1361 rout->ZoneListW2K->ZoneArray[i]->pszZoneName = talloc_strdup(mem_ctx, zlist[i]->name);
1362 rout->ZoneListW2K->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
1363 rout->ZoneListW2K->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
1364 rout->ZoneListW2K->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
1366 rout->ZoneListW2K->dwZoneCount = zcount;
1368 } else {
1369 *typeid_out = DNSSRV_TYPEID_ZONE_LIST;
1370 rout->ZoneList = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_DOTNET);
1372 if (zcount == 0) {
1373 rout->ZoneList->dwRpcStructureVersion = 1;
1374 rout->ZoneList->dwZoneCount = 0;
1375 rout->ZoneList->ZoneArray = NULL;
1377 return WERR_OK;
1380 rout->ZoneList->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_DOTNET *, zcount);
1381 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout->ZoneList->ZoneArray, zlist);
1383 for (i=0; i<zcount; i++) {
1384 rout->ZoneList->ZoneArray[i] = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
1386 rout->ZoneList->ZoneArray[i]->dwRpcStructureVersion = 1;
1387 rout->ZoneList->ZoneArray[i]->pszZoneName = talloc_strdup(mem_ctx, zlist[i]->name);
1388 rout->ZoneList->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
1389 rout->ZoneList->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
1390 rout->ZoneList->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
1391 rout->ZoneList->ZoneArray[i]->dwDpFlags = zlist[i]->partition->dwDpFlags;
1392 rout->ZoneList->ZoneArray[i]->pszDpFqdn = talloc_strdup(mem_ctx, zlist[i]->partition->pszDpFqdn);
1394 rout->ZoneList->dwRpcStructureVersion = 1;
1395 rout->ZoneList->dwZoneCount = zcount;
1397 talloc_free(zlist);
1398 return WERR_OK;
1399 } else if (strcasecmp(operation, "EnumZones2") == 0) {
1400 valid_operation = true;
1401 } else if (strcasecmp(operation, "EnumDirectoryPartitions") == 0) {
1402 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1403 return WERR_DNS_ERROR_INVALID_PROPERTY;
1406 *typeid_out = DNSSRV_TYPEID_DP_LIST;
1407 rout->DirectoryPartitionList = talloc_zero(mem_ctx, struct DNS_RPC_DP_LIST);
1409 if (rin->Dword != 0) {
1410 rout->DirectoryPartitionList->dwDpCount = 0;
1411 rout->DirectoryPartitionList->DpArray = NULL;
1412 } else {
1413 struct DNS_RPC_DP_ENUM **dplist;
1414 struct dnsserver_partition *p;
1415 int pcount = 2;
1417 dplist = talloc_zero_array(mem_ctx, struct DNS_RPC_DP_ENUM *, pcount);
1418 W_ERROR_HAVE_NO_MEMORY(dplist);
1420 p = dsstate->partitions;
1421 for (i=0; i<pcount; i++) {
1422 dplist[i] = talloc_zero(dplist, struct DNS_RPC_DP_ENUM);
1424 dplist[i]->pszDpFqdn = talloc_strdup(mem_ctx, p->pszDpFqdn);
1425 dplist[i]->dwFlags = p->dwDpFlags;
1426 dplist[i]->dwZoneCount = p->zones_count;
1427 p = p->next;
1430 rout->DirectoryPartitionList->dwDpCount = pcount;
1431 rout->DirectoryPartitionList->DpArray = dplist;
1433 return WERR_OK;
1434 } else if (strcasecmp(operation, "DirectoryPartitionInfo") == 0) {
1435 struct dnsserver_partition *p;
1436 struct dnsserver_partition_info *partinfo;
1437 struct DNS_RPC_DP_INFO *dpinfo = NULL;
1439 if (typeid_in != DNSSRV_TYPEID_LPSTR) {
1440 return WERR_DNS_ERROR_INVALID_PROPERTY;
1443 *typeid_out = DNSSRV_TYPEID_DP_INFO;
1445 for (p = dsstate->partitions; p; p = p->next) {
1446 if (strcasecmp(p->pszDpFqdn, rin->String) == 0) {
1447 dpinfo = talloc_zero(mem_ctx, struct DNS_RPC_DP_INFO);
1448 W_ERROR_HAVE_NO_MEMORY(dpinfo);
1450 partinfo = dnsserver_db_partition_info(mem_ctx, dsstate->samdb, p);
1451 W_ERROR_HAVE_NO_MEMORY(partinfo);
1453 dpinfo->pszDpFqdn = talloc_strdup(dpinfo, p->pszDpFqdn);
1454 dpinfo->pszDpDn = talloc_strdup(dpinfo, ldb_dn_get_linearized(p->partition_dn));
1455 dpinfo->pszCrDn = talloc_steal(dpinfo, partinfo->pszCrDn);
1456 dpinfo->dwFlags = p->dwDpFlags;
1457 dpinfo->dwZoneCount = p->zones_count;
1458 dpinfo->dwState = partinfo->dwState;
1459 dpinfo->dwReplicaCount = partinfo->dwReplicaCount;
1460 if (partinfo->dwReplicaCount > 0) {
1461 dpinfo->ReplicaArray = talloc_steal(dpinfo,
1462 partinfo->ReplicaArray);
1463 } else {
1464 dpinfo->ReplicaArray = NULL;
1466 break;
1470 if (dpinfo == NULL) {
1471 return WERR_DNS_ERROR_DP_DOES_NOT_EXIST;
1474 rout->DirectoryPartition = dpinfo;
1475 return WERR_OK;
1476 } else if (strcasecmp(operation, "Statistics") == 0) {
1477 valid_operation = true;
1478 } else if (strcasecmp(operation, "IpValidate") == 0) {
1479 valid_operation = true;
1482 if (valid_operation) {
1483 DEBUG(0, ("dnsserver: server complex operation '%s' not implemented", operation));
1484 return WERR_CALL_NOT_IMPLEMENTED;
1487 DEBUG(0, ("dnsserver: invalid server complex operation '%s'", operation));
1488 return WERR_DNS_ERROR_INVALID_PROPERTY;
1491 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
1492 static WERROR dnsserver_operate_zone(struct dnsserver_state *dsstate,
1493 TALLOC_CTX *mem_ctx,
1494 struct dnsserver_zone *z,
1495 unsigned int request_filter,
1496 const char *operation,
1497 const unsigned int client_version,
1498 enum DNS_RPC_TYPEID typeid,
1499 union DNSSRV_RPC_UNION *r)
1501 bool valid_operation = false;
1503 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1504 if (typeid != DNSSRV_TYPEID_NAME_AND_PARAM) {
1505 return WERR_DNS_ERROR_INVALID_PROPERTY;
1508 /* Ignore property resets */
1509 if (strcasecmp(r->NameAndParam->pszNodeName, "AllowUpdate") == 0) {
1510 return WERR_OK;
1512 valid_operation = true;
1513 } else if (strcasecmp(operation, "ZoneTypeReset") == 0) {
1514 valid_operation = true;
1515 } else if (strcasecmp(operation, "PauseZone") == 0) {
1516 valid_operation = true;
1517 } else if (strcasecmp(operation, "ResumeZone") == 0) {
1518 valid_operation = true;
1519 } else if (strcasecmp(operation, "DeleteZone") == 0) {
1520 valid_operation = true;
1521 } else if (strcasecmp(operation, "ReloadZone") == 0) {
1522 valid_operation = true;
1523 } else if (strcasecmp(operation, "RefreshZone") == 0) {
1524 valid_operation = true;
1525 } else if (strcasecmp(operation, "ExpireZone") == 0) {
1526 valid_operation = true;
1527 } else if (strcasecmp(operation, "IncrementVersion") == 0) {
1528 valid_operation = true;
1529 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1530 valid_operation = true;
1531 } else if (strcasecmp(operation, "DeleteZoneFromDs") == 0) {
1532 WERROR status;
1533 if (z == NULL) {
1534 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1536 status = dnsserver_db_delete_zone(dsstate->samdb, z);
1537 if (W_ERROR_IS_OK(status)) {
1538 dnsserver_reload_zones(dsstate);
1540 return status;
1541 } else if (strcasecmp(operation, "UpdateZoneFromDs") == 0) {
1542 valid_operation = true;
1543 } else if (strcasecmp(operation, "ZoneExport") == 0) {
1544 valid_operation = true;
1545 } else if (strcasecmp(operation, "ZoneChangeDirectoryPartition") == 0) {
1546 valid_operation = true;
1547 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1548 valid_operation = true;
1549 } else if (strcasecmp(operation, "DeleteRecordSet") == 0) {
1550 valid_operation = true;
1551 } else if (strcasecmp(operation, "ForceAgingOnNode") == 0) {
1552 valid_operation = true;
1553 } else if (strcasecmp(operation, "DatabaseFile") == 0) {
1554 valid_operation = true;
1555 } else if (strcasecmp(operation, "MasterServers") == 0) {
1556 valid_operation = true;
1557 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
1558 valid_operation = true;
1559 } else if (strcasecmp(operation, "NotifyServers") == 0) {
1560 valid_operation = true;
1561 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
1562 valid_operation = true;
1563 } else if (strcasecmp(operation, "ScavengingServers") == 0) {
1564 valid_operation = true;
1565 } else if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
1566 valid_operation = true;
1567 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1568 valid_operation = true;
1569 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1570 valid_operation = true;
1573 if (valid_operation) {
1574 DEBUG(0, ("dnsserver: zone operation '%s' not implemented", operation));
1575 return WERR_CALL_NOT_IMPLEMENTED;
1578 DEBUG(0, ("dnsserver: invalid zone operation '%s'", operation));
1579 return WERR_DNS_ERROR_INVALID_PROPERTY;
1582 static WERROR dnsserver_complex_operate_zone(struct dnsserver_state *dsstate,
1583 TALLOC_CTX *mem_ctx,
1584 struct dnsserver_zone *z,
1585 const char *operation,
1586 const unsigned int client_version,
1587 enum DNS_RPC_TYPEID typeid_in,
1588 union DNSSRV_RPC_UNION *rin,
1589 enum DNS_RPC_TYPEID *typeid_out,
1590 union DNSSRV_RPC_UNION *rout)
1592 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1593 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1594 return dnsserver_query_zone(dsstate, mem_ctx, z,
1595 rin->String,
1596 client_version,
1597 typeid_out,
1598 rout);
1603 DEBUG(0,("dnsserver: Invalid zone operation %s", operation));
1604 return WERR_DNS_ERROR_INVALID_PROPERTY;
1607 /* dnsserver enumerate function */
1609 static WERROR dnsserver_enumerate_root_records(struct dnsserver_state *dsstate,
1610 TALLOC_CTX *mem_ctx,
1611 unsigned int client_version,
1612 const char *node_name,
1613 enum dns_record_type record_type,
1614 unsigned int select_flag,
1615 unsigned int *buffer_length,
1616 struct DNS_RPC_RECORDS_ARRAY **buffer)
1618 TALLOC_CTX *tmp_ctx;
1619 struct dnsserver_zone *z;
1620 const char * const attrs[] = { "name", "dnsRecord", NULL };
1621 struct ldb_result *res;
1622 struct DNS_RPC_RECORDS_ARRAY *recs;
1623 char **add_names;
1624 char *rname;
1625 int add_count;
1626 int i, ret, len;
1627 WERROR status;
1629 tmp_ctx = talloc_new(mem_ctx);
1630 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1632 z = dnsserver_find_zone(dsstate->zones, ".");
1633 if (z == NULL) {
1634 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1637 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1638 LDB_SCOPE_ONELEVEL, attrs,
1639 "(&(objectClass=dnsNode)(name=@)(!(dNSTombstoned=TRUE)))");
1640 if (ret != LDB_SUCCESS) {
1641 talloc_free(tmp_ctx);
1642 return WERR_INTERNAL_DB_ERROR;
1644 if (res->count == 0) {
1645 talloc_free(tmp_ctx);
1646 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1649 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1650 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1652 add_names = NULL;
1653 add_count = 0;
1655 for (i=0; i<res->count; i++) {
1656 status = dns_fill_records_array(tmp_ctx, NULL, record_type,
1657 select_flag, NULL,
1658 res->msgs[i], 0, recs,
1659 &add_names, &add_count);
1660 if (!W_ERROR_IS_OK(status)) {
1661 talloc_free(tmp_ctx);
1662 return status;
1665 talloc_free(res);
1667 /* Add any additional records */
1668 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1669 for (i=0; i<add_count; i++) {
1670 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1671 LDB_SCOPE_ONELEVEL, attrs,
1672 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1673 add_names[i]);
1674 if (ret != LDB_SUCCESS || res->count == 0) {
1675 talloc_free(res);
1676 continue;
1679 len = strlen(add_names[i]);
1680 if (add_names[i][len-1] == '.') {
1681 rname = talloc_strdup(tmp_ctx, add_names[i]);
1682 } else {
1683 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1685 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1686 select_flag, rname,
1687 res->msgs[0], 0, recs,
1688 NULL, NULL);
1689 talloc_free(rname);
1690 talloc_free(res);
1694 talloc_free(tmp_ctx);
1696 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1697 *buffer = recs;
1699 return WERR_OK;
1703 static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
1704 TALLOC_CTX *mem_ctx,
1705 struct dnsserver_zone *z,
1706 unsigned int client_version,
1707 const char *node_name,
1708 const char *start_child,
1709 enum dns_record_type record_type,
1710 unsigned int select_flag,
1711 const char *filter_start,
1712 const char *filter_stop,
1713 unsigned int *buffer_length,
1714 struct DNS_RPC_RECORDS_ARRAY **buffer)
1716 TALLOC_CTX *tmp_ctx;
1717 char *name;
1718 const char * const attrs[] = { "name", "dnsRecord", NULL };
1719 struct ldb_result *res;
1720 struct DNS_RPC_RECORDS_ARRAY *recs;
1721 char **add_names = NULL;
1722 char *rname;
1723 int add_count = 0;
1724 int i, ret, len;
1725 WERROR status;
1726 struct dns_tree *tree, *base, *node;
1728 tmp_ctx = talloc_new(mem_ctx);
1729 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1731 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1732 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1734 /* search all records under parent tree */
1735 if (strcasecmp(name, z->name) == 0) {
1736 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1737 LDB_SCOPE_ONELEVEL, attrs,
1738 "(&(objectClass=dnsNode)(!(dNSTombstoned=TRUE)))");
1739 } else {
1740 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1741 LDB_SCOPE_ONELEVEL, attrs,
1742 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s))(!(dNSTombstoned=TRUE)))",
1743 name, name);
1745 if (ret != LDB_SUCCESS) {
1746 talloc_free(tmp_ctx);
1747 return WERR_INTERNAL_DB_ERROR;
1749 if (res->count == 0) {
1750 talloc_free(tmp_ctx);
1751 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1754 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1755 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1757 /* Sort the names, so that the first record is the parent record */
1758 ldb_qsort(res->msgs, res->count, sizeof(struct ldb_message *), name,
1759 (ldb_qsort_cmp_fn_t)dns_name_compare);
1761 /* Build a tree of name components from dns name */
1762 if (strcasecmp(name, z->name) == 0) {
1763 tree = dns_build_tree(tmp_ctx, "@", res);
1764 } else {
1765 tree = dns_build_tree(tmp_ctx, name, res);
1767 W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree, tmp_ctx);
1769 /* Find the parent record in the tree */
1770 base = tree;
1771 while (base->level != -1) {
1772 base = base->children[0];
1775 /* Add the parent record with blank name */
1776 if (!(select_flag & DNS_RPC_VIEW_ONLY_CHILDREN)) {
1777 status = dns_fill_records_array(tmp_ctx, z, record_type,
1778 select_flag, NULL,
1779 base->data, 0,
1780 recs, &add_names, &add_count);
1781 if (!W_ERROR_IS_OK(status)) {
1782 talloc_free(tmp_ctx);
1783 return status;
1787 /* Add all the children records */
1788 if (!(select_flag & DNS_RPC_VIEW_NO_CHILDREN)) {
1789 for (i=0; i<base->num_children; i++) {
1790 node = base->children[i];
1792 status = dns_fill_records_array(tmp_ctx, z, record_type,
1793 select_flag, node->name,
1794 node->data, node->num_children,
1795 recs, &add_names, &add_count);
1796 if (!W_ERROR_IS_OK(status)) {
1797 talloc_free(tmp_ctx);
1798 return status;
1803 talloc_free(res);
1804 talloc_free(tree);
1805 talloc_free(name);
1807 /* Add any additional records */
1808 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1809 for (i=0; i<add_count; i++) {
1810 struct dnsserver_zone *z2;
1812 /* Search all the available zones for additional name */
1813 for (z2 = dsstate->zones; z2; z2 = z2->next) {
1814 name = dns_split_node_name(tmp_ctx, add_names[i], z2->name);
1815 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z2->zone_dn,
1816 LDB_SCOPE_ONELEVEL, attrs,
1817 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1818 name);
1819 talloc_free(name);
1820 if (ret != LDB_SUCCESS) {
1821 continue;
1823 if (res->count == 1) {
1824 break;
1825 } else {
1826 talloc_free(res);
1827 continue;
1831 len = strlen(add_names[i]);
1832 if (add_names[i][len-1] == '.') {
1833 rname = talloc_strdup(tmp_ctx, add_names[i]);
1834 } else {
1835 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1837 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1838 select_flag, rname,
1839 res->msgs[0], 0, recs,
1840 NULL, NULL);
1841 talloc_free(rname);
1842 talloc_free(res);
1846 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1847 *buffer = recs;
1849 return WERR_OK;
1852 /* dnsserver update function */
1854 static WERROR dnsserver_update_record(struct dnsserver_state *dsstate,
1855 TALLOC_CTX *mem_ctx,
1856 struct dnsserver_zone *z,
1857 unsigned int client_version,
1858 const char *node_name,
1859 struct DNS_RPC_RECORD_BUF *add_buf,
1860 struct DNS_RPC_RECORD_BUF *del_buf)
1862 TALLOC_CTX *tmp_ctx;
1863 char *name;
1864 WERROR status;
1866 tmp_ctx = talloc_new(mem_ctx);
1867 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1869 /* If node_name is @ or zone name, dns record is @ */
1870 if (strcmp(node_name, "@") == 0 ||
1871 strcmp(node_name, ".") == 0 ||
1872 strcasecmp(node_name, z->name) == 0) {
1873 name = talloc_strdup(tmp_ctx, "@");
1874 } else {
1875 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1877 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1879 if (add_buf != NULL) {
1880 if (del_buf == NULL) {
1881 /* Add record */
1882 status = dnsserver_db_add_record(tmp_ctx, dsstate->samdb,
1883 z, name,
1884 &add_buf->rec);
1885 } else {
1886 /* Update record */
1887 status = dnsserver_db_update_record(tmp_ctx, dsstate->samdb,
1888 z, name,
1889 &add_buf->rec,
1890 &del_buf->rec);
1892 } else {
1893 if (del_buf == NULL) {
1894 /* Add empty node */
1895 status = dnsserver_db_add_empty_node(tmp_ctx, dsstate->samdb,
1896 z, name);
1897 } else {
1898 /* Delete record */
1899 status = dnsserver_db_delete_record(tmp_ctx, dsstate->samdb,
1900 z, name,
1901 &del_buf->rec);
1905 talloc_free(tmp_ctx);
1906 return status;
1910 /* dnsserver interface functions */
1912 static WERROR dcesrv_DnssrvOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation *r)
1914 struct dnsserver_state *dsstate;
1915 struct dnsserver_zone *z = NULL;
1916 uint32_t request_filter = 0;
1917 WERROR ret;
1919 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1920 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1923 if (r->in.dwContext == 0) {
1924 if (r->in.pszZone != NULL) {
1925 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
1927 } else {
1928 request_filter = r->in.dwContext;
1931 if (r->in.pszZone == NULL) {
1932 ret = dnsserver_operate_server(dsstate, mem_ctx,
1933 r->in.pszOperation,
1934 DNS_CLIENT_VERSION_W2K,
1935 r->in.dwTypeId,
1936 &r->in.pData);
1937 } else {
1938 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1939 if (z == NULL && request_filter == 0) {
1940 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1943 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
1944 request_filter,
1945 r->in.pszOperation,
1946 DNS_CLIENT_VERSION_W2K,
1947 r->in.dwTypeId,
1948 &r->in.pData);
1951 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1952 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation, NDR_IN, r);
1954 return ret;
1957 static WERROR dcesrv_DnssrvQuery(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery *r)
1959 struct dnsserver_state *dsstate;
1960 struct dnsserver_zone *z;
1961 WERROR ret;
1963 ZERO_STRUCTP(r->out.pdwTypeId);
1964 ZERO_STRUCTP(r->out.ppData);
1966 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1967 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1970 if (r->in.pszZone == NULL) {
1971 /* FIXME: DNS Server Configuration Access Control List */
1972 ret = dnsserver_query_server(dsstate, mem_ctx,
1973 r->in.pszOperation,
1974 DNS_CLIENT_VERSION_W2K,
1975 r->out.pdwTypeId,
1976 r->out.ppData);
1977 } else {
1978 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1979 if (z == NULL) {
1980 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1983 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
1984 r->in.pszOperation,
1985 DNS_CLIENT_VERSION_W2K,
1986 r->out.pdwTypeId,
1987 r->out.ppData);
1990 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1991 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery, NDR_IN, r);
1993 return ret;
1996 static WERROR dcesrv_DnssrvComplexOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation *r)
1998 struct dnsserver_state *dsstate;
1999 struct dnsserver_zone *z;
2000 WERROR ret;
2002 ZERO_STRUCTP(r->out.pdwTypeOut);
2003 ZERO_STRUCTP(r->out.ppDataOut);
2005 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2006 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2009 if (r->in.pszZone == NULL) {
2010 /* Server operation */
2011 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
2012 r->in.pszOperation,
2013 DNS_CLIENT_VERSION_W2K,
2014 r->in.dwTypeIn,
2015 &r->in.pDataIn,
2016 r->out.pdwTypeOut,
2017 r->out.ppDataOut);
2018 } else {
2019 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2020 if (z == NULL) {
2021 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2024 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2025 r->in.pszOperation,
2026 DNS_CLIENT_VERSION_W2K,
2027 r->in.dwTypeIn,
2028 &r->in.pDataIn,
2029 r->out.pdwTypeOut,
2030 r->out.ppDataOut);
2033 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2034 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation, NDR_IN, r);
2036 return ret;
2039 static WERROR dcesrv_DnssrvEnumRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords *r)
2041 struct dnsserver_state *dsstate;
2042 struct dnsserver_zone *z;
2043 WERROR ret;
2045 ZERO_STRUCTP(r->out.pdwBufferLength);
2046 ZERO_STRUCTP(r->out.pBuffer);
2048 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2049 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2052 if (r->in.pszZone == NULL) {
2053 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2056 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
2057 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
2058 DNS_CLIENT_VERSION_W2K,
2059 r->in.pszNodeName,
2060 r->in.wRecordType,
2061 r->in.fSelectFlag,
2062 r->out.pdwBufferLength,
2063 r->out.pBuffer);
2064 } else {
2065 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2066 if (z == NULL) {
2067 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2070 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2071 DNS_CLIENT_VERSION_W2K,
2072 r->in.pszNodeName,
2073 r->in.pszStartChild,
2074 r->in.wRecordType,
2075 r->in.fSelectFlag,
2076 r->in.pszFilterStart,
2077 r->in.pszFilterStop,
2078 r->out.pdwBufferLength,
2079 r->out.pBuffer);
2082 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2083 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords, NDR_IN, r);
2085 return ret;
2088 static WERROR dcesrv_DnssrvUpdateRecord(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord *r)
2090 struct dnsserver_state *dsstate;
2091 struct dnsserver_zone *z;
2092 WERROR ret;
2094 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2095 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2098 if (r->in.pszZone == NULL) {
2099 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2102 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2103 if (z == NULL) {
2104 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2107 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2108 DNS_CLIENT_VERSION_W2K,
2109 r->in.pszNodeName,
2110 r->in.pAddRecord,
2111 r->in.pDeleteRecord);
2113 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2114 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord, NDR_IN, r);
2116 return ret;
2119 static WERROR dcesrv_DnssrvOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation2 *r)
2121 struct dnsserver_state *dsstate;
2122 struct dnsserver_zone *z = NULL;
2123 uint32_t request_filter = 0;
2124 WERROR ret;
2126 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2127 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2130 if (r->in.dwContext == 0) {
2131 if (r->in.pszZone != NULL) {
2132 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
2134 } else {
2135 request_filter = r->in.dwContext;
2138 if (r->in.pszZone == NULL) {
2139 ret = dnsserver_operate_server(dsstate, mem_ctx,
2140 r->in.pszOperation,
2141 r->in.dwClientVersion,
2142 r->in.dwTypeId,
2143 &r->in.pData);
2144 } else {
2145 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2146 if (z == NULL && request_filter == 0) {
2147 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2150 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
2151 request_filter,
2152 r->in.pszOperation,
2153 r->in.dwClientVersion,
2154 r->in.dwTypeId,
2155 &r->in.pData);
2158 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2159 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation2, NDR_IN, r);
2161 return ret;
2164 static WERROR dcesrv_DnssrvQuery2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery2 *r)
2166 struct dnsserver_state *dsstate;
2167 struct dnsserver_zone *z;
2168 WERROR ret;
2170 ZERO_STRUCTP(r->out.pdwTypeId);
2171 ZERO_STRUCTP(r->out.ppData);
2173 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2174 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2177 if (r->in.pszZone == NULL) {
2178 /* FIXME: DNS Server Configuration Access Control List */
2179 ret = dnsserver_query_server(dsstate, mem_ctx,
2180 r->in.pszOperation,
2181 r->in.dwClientVersion,
2182 r->out.pdwTypeId,
2183 r->out.ppData);
2184 } else {
2185 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2186 if (z == NULL) {
2187 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2190 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
2191 r->in.pszOperation,
2192 r->in.dwClientVersion,
2193 r->out.pdwTypeId,
2194 r->out.ppData);
2197 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2198 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery2, NDR_IN, r);
2200 return ret;
2203 static WERROR dcesrv_DnssrvComplexOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation2 *r)
2205 struct dnsserver_state *dsstate;
2206 struct dnsserver_zone *z;
2207 WERROR ret;
2209 ZERO_STRUCTP(r->out.pdwTypeOut);
2210 ZERO_STRUCTP(r->out.ppDataOut);
2212 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2213 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2216 if (r->in.pszZone == NULL) {
2217 /* Server operation */
2218 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
2219 r->in.pszOperation,
2220 r->in.dwClientVersion,
2221 r->in.dwTypeIn,
2222 &r->in.pDataIn,
2223 r->out.pdwTypeOut,
2224 r->out.ppDataOut);
2225 } else {
2227 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2228 if (z == NULL) {
2229 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2232 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2233 r->in.pszOperation,
2234 r->in.dwClientVersion,
2235 r->in.dwTypeIn,
2236 &r->in.pDataIn,
2237 r->out.pdwTypeOut,
2238 r->out.ppDataOut);
2241 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2242 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation2, NDR_IN, r);
2244 return ret;
2247 static WERROR dcesrv_DnssrvEnumRecords2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords2 *r)
2249 struct dnsserver_state *dsstate;
2250 struct dnsserver_zone *z;
2251 WERROR ret;
2253 ZERO_STRUCTP(r->out.pdwBufferLength);
2254 ZERO_STRUCTP(r->out.pBuffer);
2256 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2257 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2260 if (r->in.pszZone == NULL) {
2261 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2264 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
2265 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
2266 r->in.dwClientVersion,
2267 r->in.pszNodeName,
2268 r->in.wRecordType,
2269 r->in.fSelectFlag,
2270 r->out.pdwBufferLength,
2271 r->out.pBuffer);
2272 } else {
2273 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2274 if (z == NULL) {
2275 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2278 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2279 r->in.dwClientVersion,
2280 r->in.pszNodeName,
2281 r->in.pszStartChild,
2282 r->in.wRecordType,
2283 r->in.fSelectFlag,
2284 r->in.pszFilterStart,
2285 r->in.pszFilterStop,
2286 r->out.pdwBufferLength,
2287 r->out.pBuffer);
2291 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2292 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords2, NDR_IN, r);
2294 return ret;
2297 static WERROR dcesrv_DnssrvUpdateRecord2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord2 *r)
2299 struct dnsserver_state *dsstate;
2300 struct dnsserver_zone *z;
2301 WERROR ret;
2303 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2304 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2307 if (r->in.pszZone == NULL) {
2308 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2311 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2312 if (z == NULL) {
2313 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2316 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2317 r->in.dwClientVersion,
2318 r->in.pszNodeName,
2319 r->in.pAddRecord,
2320 r->in.pDeleteRecord);
2322 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2323 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord2, NDR_IN, r);
2325 return ret;
2328 /* include the generated boilerplate */
2329 #include "librpc/gen_ndr/ndr_dnsserver_s.c"