dnsserver: Remove incorrect and not required include of ldb_private.h
[Samba.git] / source4 / rpc_server / dnsserver / dcerpc_dnsserver.c
blob3df7294737163e0bc273f290230aaa4f1e598c5a
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"
30 struct dnsserver_state {
31 struct loadparm_context *lp_ctx;
32 struct ldb_context *samdb;
33 struct dnsserver_partition *partitions;
34 struct dnsserver_zone *zones;
35 int zones_count;
36 struct dnsserver_serverinfo *serverinfo;
40 /* Utility functions */
42 static void dnsserver_reload_zones(struct dnsserver_state *dsstate)
44 struct dnsserver_partition *p;
45 struct dnsserver_zone *zones, *z, *znext, *zmatch;
46 struct dnsserver_zone *old_list, *new_list;
48 old_list = dsstate->zones;
49 new_list = NULL;
51 for (p = dsstate->partitions; p; p = p->next) {
52 zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, p);
53 if (zones == NULL) {
54 continue;
56 for (z = zones; z; ) {
57 znext = z->next;
58 zmatch = dnsserver_find_zone(old_list, z->name);
59 if (zmatch == NULL) {
60 /* Missing zone */
61 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
62 if (z->zoneinfo == NULL) {
63 continue;
65 DLIST_ADD_END(new_list, z, NULL);
66 p->zones_count++;
67 dsstate->zones_count++;
68 } else {
69 /* Existing zone */
70 talloc_free(z);
71 DLIST_REMOVE(old_list, zmatch);
72 DLIST_ADD_END(new_list, zmatch, NULL);
74 z = znext;
78 if (new_list == NULL) {
79 return;
82 /* Deleted zones */
83 for (z = old_list; z; ) {
84 znext = z->next;
85 z->partition->zones_count--;
86 dsstate->zones_count--;
87 talloc_free(z);
88 z = znext;
91 dsstate->zones = new_list;
95 static struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_call)
97 struct dnsserver_state *dsstate;
98 struct dnsserver_zone *zones, *z, *znext;
99 struct dnsserver_partition *partitions, *p;
101 dsstate = talloc_get_type(dce_call->context->private_data, struct dnsserver_state);
102 if (dsstate != NULL) {
103 return dsstate;
106 dsstate = talloc_zero(dce_call->context, struct dnsserver_state);
107 if (dsstate == NULL) {
108 return NULL;
111 dsstate->lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
113 /* FIXME: create correct auth_session_info for connecting user */
114 dsstate->samdb = samdb_connect(dsstate, dce_call->event_ctx, dsstate->lp_ctx,
115 dce_call->conn->auth_state.session_info, 0);
116 if (dsstate->samdb == NULL) {
117 DEBUG(0,("dnsserver: Failed to open samdb"));
118 goto failed;
121 /* Initialize server info */
122 dsstate->serverinfo = dnsserver_init_serverinfo(dsstate,
123 dsstate->lp_ctx,
124 dsstate->samdb);
125 if (dsstate->serverinfo == NULL) {
126 goto failed;
129 /* Search for DNS partitions */
130 partitions = dnsserver_db_enumerate_partitions(dsstate, dsstate->serverinfo, dsstate->samdb);
131 if (partitions == NULL) {
132 goto failed;
134 dsstate->partitions = partitions;
136 /* Search for DNS zones */
137 for (p = partitions; p; p = p->next) {
138 zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, p);
139 if (zones == NULL) {
140 goto failed;
142 for (z = zones; z; ) {
143 znext = z->next;
144 if (dnsserver_find_zone(dsstate->zones, z->name) == NULL) {
145 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
146 if (z->zoneinfo == NULL) {
147 goto failed;
149 DLIST_ADD_END(dsstate->zones, z, NULL);
150 p->zones_count++;
151 dsstate->zones_count++;
152 } else {
153 /* Ignore duplicate zone */
154 DEBUG(3,("dnsserver: Ignoring duplicate zone '%s' from '%s'",
155 z->name, ldb_dn_get_linearized(z->zone_dn)));
157 z = znext;
161 dce_call->context->private_data = dsstate;
163 return dsstate;
165 failed:
166 talloc_free(dsstate);
167 dsstate = NULL;
168 return NULL;
172 /* dnsserver query functions */
174 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
175 static WERROR dnsserver_query_server(struct dnsserver_state *dsstate,
176 TALLOC_CTX *mem_ctx,
177 const char *operation,
178 const unsigned int client_version,
179 enum DNS_RPC_TYPEID *typeid,
180 union DNSSRV_RPC_UNION *r)
182 uint8_t is_integer, is_addresses, is_string, is_wstring, is_stringlist;
183 uint32_t answer_integer;
184 struct IP4_ARRAY *answer_iparray;
185 struct DNS_ADDR_ARRAY *answer_addrarray;
186 char *answer_string;
187 struct DNS_RPC_UTF8_STRING_LIST *answer_stringlist;
188 struct dnsserver_serverinfo *serverinfo;
190 serverinfo = dsstate->serverinfo;
192 if (strcasecmp(operation, "ServerInfo") == 0) {
193 if (client_version == DNS_CLIENT_VERSION_W2K) {
194 *typeid = DNSSRV_TYPEID_SERVER_INFO_W2K;
195 r->ServerInfoW2K = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_W2K);
197 r->ServerInfoW2K->dwVersion = serverinfo->dwVersion;
198 r->ServerInfoW2K->fBootMethod = serverinfo->fBootMethod;
199 r->ServerInfoW2K->fAdminConfigured = serverinfo->fAdminConfigured;
200 r->ServerInfoW2K->fAllowUpdate = serverinfo->fAllowUpdate;
201 r->ServerInfoW2K->fDsAvailable = serverinfo->fDsAvailable;
202 r->ServerInfoW2K->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
203 r->ServerInfoW2K->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
204 r->ServerInfoW2K->aipServerAddrs = dns_addr_array_to_ip4_array(mem_ctx,
205 serverinfo->aipServerAddrs);
206 r->ServerInfoW2K->aipListenAddrs = dns_addr_array_to_ip4_array(mem_ctx,
207 serverinfo->aipListenAddrs);
208 r->ServerInfoW2K->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
209 r->ServerInfoW2K->dwLogLevel = serverinfo->dwLogLevel;
210 r->ServerInfoW2K->dwDebugLevel = serverinfo->dwDebugLevel;
211 r->ServerInfoW2K->dwForwardTimeout = serverinfo->dwForwardTimeout;
212 r->ServerInfoW2K->dwRpcProtocol = serverinfo->dwRpcProtocol;
213 r->ServerInfoW2K->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
214 r->ServerInfoW2K->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
215 r->ServerInfoW2K->dwRecursionRetry = serverinfo->dwRecursionRetry;
216 r->ServerInfoW2K->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
217 r->ServerInfoW2K->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
218 r->ServerInfoW2K->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
219 r->ServerInfoW2K->dwScavengingInterval = serverinfo->dwScavengingInterval;
220 r->ServerInfoW2K->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
221 r->ServerInfoW2K->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
222 r->ServerInfoW2K->fAutoReverseZones = serverinfo->fAutoReverseZones;
223 r->ServerInfoW2K->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
224 r->ServerInfoW2K->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
225 r->ServerInfoW2K->fForwardDelegations = serverinfo->fForwardDelegations;
226 r->ServerInfoW2K->fNoRecursion = serverinfo->fNoRecursion;
227 r->ServerInfoW2K->fSecureResponses = serverinfo->fSecureResponses;
228 r->ServerInfoW2K->fRoundRobin = serverinfo->fRoundRobin;
229 r->ServerInfoW2K->fLocalNetPriority = serverinfo->fLocalNetPriority;
230 r->ServerInfoW2K->fBindSecondaries = serverinfo->fBindSecondaries;
231 r->ServerInfoW2K->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
232 r->ServerInfoW2K->fStrictFileParsing = serverinfo->fStrictFileParsing;
233 r->ServerInfoW2K->fLooseWildcarding = serverinfo->fLooseWildcarding;
234 r->ServerInfoW2K->fDefaultAgingState = serverinfo->fDefaultAgingState;
236 } else if (client_version == DNS_CLIENT_VERSION_DOTNET) {
237 *typeid = DNSSRV_TYPEID_SERVER_INFO_DOTNET;
238 r->ServerInfoDotNet = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_DOTNET);
240 r->ServerInfoDotNet->dwRpcStructureVersion = 0x01;
241 r->ServerInfoDotNet->dwVersion = serverinfo->dwVersion;
242 r->ServerInfoDotNet->fBootMethod = serverinfo->fBootMethod;
243 r->ServerInfoDotNet->fAdminConfigured = serverinfo->fAdminConfigured;
244 r->ServerInfoDotNet->fAllowUpdate = serverinfo->fAllowUpdate;
245 r->ServerInfoDotNet->fDsAvailable = serverinfo->fDsAvailable;
246 r->ServerInfoDotNet->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
247 r->ServerInfoDotNet->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
248 r->ServerInfoDotNet->aipServerAddrs = dns_addr_array_to_ip4_array(mem_ctx,
249 serverinfo->aipServerAddrs);
250 r->ServerInfoDotNet->aipListenAddrs = dns_addr_array_to_ip4_array(mem_ctx,
251 serverinfo->aipListenAddrs);
252 r->ServerInfoDotNet->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
253 r->ServerInfoDotNet->aipLogFilter = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
254 r->ServerInfoDotNet->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
255 r->ServerInfoDotNet->pszDomainName = talloc_strdup(mem_ctx, serverinfo->pszDomainName);
256 r->ServerInfoDotNet->pszForestName = talloc_strdup(mem_ctx, serverinfo->pszForestName);
257 r->ServerInfoDotNet->pszDomainDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszDomainDirectoryPartition);
258 r->ServerInfoDotNet->pszForestDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszForestDirectoryPartition);
259 r->ServerInfoDotNet->dwLogLevel = serverinfo->dwLogLevel;
260 r->ServerInfoDotNet->dwDebugLevel = serverinfo->dwDebugLevel;
261 r->ServerInfoDotNet->dwForwardTimeout = serverinfo->dwForwardTimeout;
262 r->ServerInfoDotNet->dwRpcProtocol = serverinfo->dwRpcProtocol;
263 r->ServerInfoDotNet->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
264 r->ServerInfoDotNet->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
265 r->ServerInfoDotNet->dwRecursionRetry = serverinfo->dwRecursionRetry;
266 r->ServerInfoDotNet->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
267 r->ServerInfoDotNet->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
268 r->ServerInfoDotNet->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
269 r->ServerInfoDotNet->dwLocalNetPriorityNetMask = serverinfo->dwLocalNetPriorityNetMask;
270 r->ServerInfoDotNet->dwScavengingInterval = serverinfo->dwScavengingInterval;
271 r->ServerInfoDotNet->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
272 r->ServerInfoDotNet->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
273 r->ServerInfoDotNet->dwLastScavengeTime = serverinfo->dwLastScavengeTime;
274 r->ServerInfoDotNet->dwEventLogLevel = serverinfo->dwEventLogLevel;
275 r->ServerInfoDotNet->dwLogFileMaxSize = serverinfo->dwLogFileMaxSize;
276 r->ServerInfoDotNet->dwDsForestVersion = serverinfo->dwDsForestVersion;
277 r->ServerInfoDotNet->dwDsDomainVersion = serverinfo->dwDsDomainVersion;
278 r->ServerInfoDotNet->dwDsDsaVersion = serverinfo->dwDsDsaVersion;
279 r->ServerInfoDotNet->fAutoReverseZones = serverinfo->fAutoReverseZones;
280 r->ServerInfoDotNet->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
281 r->ServerInfoDotNet->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
282 r->ServerInfoDotNet->fForwardDelegations = serverinfo->fForwardDelegations;
283 r->ServerInfoDotNet->fNoRecursion = serverinfo->fNoRecursion;
284 r->ServerInfoDotNet->fSecureResponses = serverinfo->fSecureResponses;
285 r->ServerInfoDotNet->fRoundRobin = serverinfo->fRoundRobin;
286 r->ServerInfoDotNet->fLocalNetPriority = serverinfo->fLocalNetPriority;
287 r->ServerInfoDotNet->fBindSecondaries = serverinfo->fBindSecondaries;
288 r->ServerInfoDotNet->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
289 r->ServerInfoDotNet->fStrictFileParsing = serverinfo->fStrictFileParsing;
290 r->ServerInfoDotNet->fLooseWildcarding = serverinfo->fLooseWildcarding;
291 r->ServerInfoDotNet->fDefaultAgingState = serverinfo->fDefaultAgingState;
293 } else if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
294 *typeid = DNSSRV_TYPEID_SERVER_INFO;
295 r->ServerInfo = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_LONGHORN);
297 r->ServerInfo->dwRpcStructureVersion = 0x02;
298 r->ServerInfo->dwVersion = serverinfo->dwVersion;
299 r->ServerInfo->fBootMethod = serverinfo->fBootMethod;
300 r->ServerInfo->fAdminConfigured = serverinfo->fAdminConfigured;
301 r->ServerInfo->fAllowUpdate = serverinfo->fAllowUpdate;
302 r->ServerInfo->fDsAvailable = serverinfo->fDsAvailable;
303 r->ServerInfo->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
304 r->ServerInfo->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
305 r->ServerInfo->aipServerAddrs = serverinfo->aipServerAddrs;
306 r->ServerInfo->aipListenAddrs = serverinfo->aipListenAddrs;
307 r->ServerInfo->aipForwarders = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders);
308 r->ServerInfo->aipLogFilter = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter);
309 r->ServerInfo->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
310 r->ServerInfo->pszDomainName = talloc_strdup(mem_ctx, serverinfo->pszDomainName);
311 r->ServerInfo->pszForestName = talloc_strdup(mem_ctx, serverinfo->pszForestName);
312 r->ServerInfo->pszDomainDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszDomainDirectoryPartition);
313 r->ServerInfo->pszForestDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszForestDirectoryPartition);
314 r->ServerInfo->dwLogLevel = serverinfo->dwLogLevel;
315 r->ServerInfo->dwDebugLevel = serverinfo->dwDebugLevel;
316 r->ServerInfo->dwForwardTimeout = serverinfo->dwForwardTimeout;
317 r->ServerInfo->dwRpcProtocol = serverinfo->dwRpcProtocol;
318 r->ServerInfo->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
319 r->ServerInfo->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
320 r->ServerInfo->dwRecursionRetry = serverinfo->dwRecursionRetry;
321 r->ServerInfo->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
322 r->ServerInfo->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
323 r->ServerInfo->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
324 r->ServerInfo->dwLocalNetPriorityNetMask = serverinfo->dwLocalNetPriorityNetMask;
325 r->ServerInfo->dwScavengingInterval = serverinfo->dwScavengingInterval;
326 r->ServerInfo->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
327 r->ServerInfo->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
328 r->ServerInfo->dwLastScavengeTime = serverinfo->dwLastScavengeTime;
329 r->ServerInfo->dwEventLogLevel = serverinfo->dwEventLogLevel;
330 r->ServerInfo->dwLogFileMaxSize = serverinfo->dwLogFileMaxSize;
331 r->ServerInfo->dwDsForestVersion = serverinfo->dwDsForestVersion;
332 r->ServerInfo->dwDsDomainVersion = serverinfo->dwDsDomainVersion;
333 r->ServerInfo->dwDsDsaVersion = serverinfo->dwDsDsaVersion;
334 r->ServerInfo->fReadOnlyDC = serverinfo->fReadOnlyDC;
335 r->ServerInfo->fAutoReverseZones = serverinfo->fAutoReverseZones;
336 r->ServerInfo->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
337 r->ServerInfo->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
338 r->ServerInfo->fForwardDelegations = serverinfo->fForwardDelegations;
339 r->ServerInfo->fNoRecursion = serverinfo->fNoRecursion;
340 r->ServerInfo->fSecureResponses = serverinfo->fSecureResponses;
341 r->ServerInfo->fRoundRobin = serverinfo->fRoundRobin;
342 r->ServerInfo->fLocalNetPriority = serverinfo->fLocalNetPriority;
343 r->ServerInfo->fBindSecondaries = serverinfo->fBindSecondaries;
344 r->ServerInfo->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
345 r->ServerInfo->fStrictFileParsing = serverinfo->fStrictFileParsing;
346 r->ServerInfo->fLooseWildcarding = serverinfo->fLooseWildcarding;
347 r->ServerInfo->fDefaultAgingState = serverinfo->fDefaultAgingState;
349 return WERR_OK;
352 is_integer = 0;
354 if (strcasecmp(operation, "AddressAnswerLimit") == 0) {
355 answer_integer = serverinfo->cAddressAnswerLimit;
356 is_integer = 1;
357 } else if (strcasecmp(operation, "AdminConfigured") == 0) {
358 answer_integer = serverinfo->fAdminConfigured;
359 is_integer = 1;
360 } else if (strcasecmp(operation, "AllowCNAMEAtNS") == 0) {
361 answer_integer = 0;
362 is_integer = 1;
363 } else if (strcasecmp(operation, "AllowUpdate") == 0) {
364 answer_integer = serverinfo->fAllowUpdate;
365 is_integer = 1;
366 } else if (strcasecmp(operation, "AutoCacheUpdate") == 0) {
367 answer_integer = serverinfo->fAutoCacheUpdate;
368 is_integer = 1;
369 } else if (strcasecmp(operation, "AutoConfigFileZones") == 0) {
370 answer_integer = 1;
371 is_integer = 1;
372 } else if (strcasecmp(operation, "BindSecondaries") == 0) {
373 answer_integer = serverinfo->fBindSecondaries;
374 is_integer = 1;
375 } else if (strcasecmp(operation, "BootMethod") == 0) {
376 answer_integer = serverinfo->fBootMethod;
377 is_integer = 1;
378 } else if (strcasecmp(operation, "DebugLevel") == 0) {
379 answer_integer = serverinfo->dwDebugLevel;
380 is_integer = 1;
381 } else if (strcasecmp(operation, "DefaultAgingState") == 0) {
382 answer_integer = serverinfo->fDefaultAgingState;
383 is_integer = 1;
384 } else if (strcasecmp(operation, "DefaultNoRefreshInterval") == 0) {
385 answer_integer = serverinfo->dwDefaultNoRefreshInterval;
386 is_integer = 1;
387 } else if (strcasecmp(operation, "DefaultRefreshInterval") == 0) {
388 answer_integer = serverinfo->dwDefaultRefreshInterval;
389 is_integer = 1;
390 } else if (strcasecmp(operation, "DeleteOutsideGlue") == 0) {
391 answer_integer = 0;
392 is_integer = 1;
393 } else if (strcasecmp(operation, "DisjointNets") == 0) {
394 answer_integer = 0;
395 is_integer = 1;
396 } else if (strcasecmp(operation, "DsLazyUpdateInterval") == 0) {
397 answer_integer = 3; /* seconds */
398 is_integer = 1;
399 } else if (strcasecmp(operation, "DsPollingInterval") == 0) {
400 answer_integer = serverinfo->dwDsPollingInterval;
401 is_integer = 1;
402 } else if (strcasecmp(operation, "DsTombstoneInterval") == 0) {
403 answer_integer = 0x00127500; /* 14 days */
404 is_integer = 1;
405 } else if (strcasecmp(operation, "EnableRegistryBoot") == 0) {
406 answer_integer = 0;
407 is_integer = 1;
408 } else if (strcasecmp(operation, "EventLogLevel") == 0) {
409 answer_integer = serverinfo->dwEventLogLevel;
410 is_integer = 1;
411 } else if (strcasecmp(operation, "ForceSoaSerial") == 0) {
412 answer_integer = 0;
413 is_integer = 1;
414 } else if (strcasecmp(operation, "ForceSaoRetry") == 0) {
415 answer_integer = 0;
416 is_integer = 1;
417 } else if (strcasecmp(operation, "ForceSoaRefresh") == 0) {
418 answer_integer = 0;
419 is_integer = 1;
420 } else if (strcasecmp(operation, "ForceSoaMinimumTtl") == 0) {
421 answer_integer = 0;
422 is_integer = 1;
423 } else if (strcasecmp(operation, "ForwardDelegations") == 0) {
424 answer_integer = 1;
425 is_integer = 1;
426 } else if (strcasecmp(operation, "ForwardingTimeout") == 0) {
427 answer_integer = serverinfo->dwForwardTimeout;
428 is_integer = 1;
429 } else if (strcasecmp(operation, "IsSlave") == 0) {
430 answer_integer = 0;
431 is_integer = 1;
432 } else if (strcasecmp(operation, "LocalNetPriority") == 0) {
433 answer_integer = serverinfo->fLocalNetPriority;
434 is_integer = 1;
435 } else if (strcasecmp(operation, "LogFileMaxSize") == 0) {
436 answer_integer = serverinfo->dwLogFileMaxSize;
437 is_integer = 1;
438 } else if (strcasecmp(operation, "LogLevel") == 0) {
439 answer_integer = serverinfo->dwLogLevel;
440 is_integer = 1;
441 } else if (strcasecmp(operation, "LooseWildcarding") == 0) {
442 answer_integer = serverinfo->fLooseWildcarding;
443 is_integer = 1;
444 } else if (strcasecmp(operation, "MaxCacheTtl") == 0) {
445 answer_integer = serverinfo->dwMaxCacheTtl;
446 is_integer = 1;
447 } else if (strcasecmp(operation, "MaxNegativeCacheTtl") == 0) {
448 answer_integer = 0x00000384; /* 15 minutes */
449 is_integer = 1;
450 } else if (strcasecmp(operation, "NameCheckFlag") == 0) {
451 answer_integer = serverinfo->dwNameCheckFlag;
452 is_integer = 1;
453 } else if (strcasecmp(operation, "NoRecursion") == 0) {
454 answer_integer = serverinfo->fNoRecursion;
455 is_integer = 1;
456 } else if (strcasecmp(operation, "NoUpdateDelegations") == 0) {
457 answer_integer = 1;
458 is_integer = 1;
459 } else if (strcasecmp(operation, "PublishAutonet") == 0) {
460 answer_integer = 0;
461 is_integer = 1;
462 } else if (strcasecmp(operation, "QuietRecvFaultInterval") == 0) {
463 answer_integer = 0;
464 is_integer = 1;
465 } else if (strcasecmp(operation, "QuietRecvLogInterval") == 0) {
466 answer_integer = 0;
467 is_integer = 1;
468 } else if (strcasecmp(operation, "RecursionRetry") == 0) {
469 answer_integer = serverinfo->dwRecursionRetry;
470 is_integer = 1;
471 } else if (strcasecmp(operation, "RecursionTimeout") == 0) {
472 answer_integer = serverinfo->dwRecursionTimeout;
473 is_integer = 1;
474 } else if (strcasecmp(operation, "ReloadException") == 0) {
475 answer_integer = 0;
476 is_integer = 1;
477 } else if (strcasecmp(operation, "RoundRobin") == 0) {
478 answer_integer = serverinfo->fRoundRobin;
479 is_integer = 1;
480 } else if (strcasecmp(operation, "RpcProtocol") == 0) {
481 answer_integer = serverinfo->dwRpcProtocol;
482 is_integer = 1;
483 } else if (strcasecmp(operation, "SecureResponses") == 0) {
484 answer_integer = serverinfo->fSecureResponses;
485 is_integer = 1;
486 } else if (strcasecmp(operation, "SendPort") == 0) {
487 answer_integer = 0;
488 is_integer = 1;
489 } else if (strcasecmp(operation, "ScavengingInterval") == 0) {
490 answer_integer = serverinfo->dwScavengingInterval;
491 is_integer = 1;
492 } else if (strcasecmp(operation, "SocketPoolSize") == 0) {
493 answer_integer = 0x000009C4;
494 is_integer = 1;
495 } else if (strcasecmp(operation, "StrictFileParsing") == 0) {
496 answer_integer = serverinfo->fStrictFileParsing;
497 is_integer = 1;
498 } else if (strcasecmp(operation, "SyncDnsZoneSerial") == 0) {
499 answer_integer = 2; /* ZONE_SERIAL_SYNC_XFER */
500 is_integer = 1;
501 } else if (strcasecmp(operation, "UpdateOptions") == 0) {
502 answer_integer = 0x0000030F; /* DNS_DEFAULT_UPDATE_OPTIONS */
503 is_integer = 1;
504 } else if (strcasecmp(operation, "UseSystemEvengLog") == 0) {
505 answer_integer = 0;
506 is_integer = 1;
507 } else if (strcasecmp(operation, "Version") == 0) {
508 answer_integer = serverinfo->dwVersion;
509 is_integer = 1;
510 } else if (strcasecmp(operation, "XfrConnectTimeout") == 0) {
511 answer_integer = 0x0000001E;
512 is_integer = 1;
513 } else if (strcasecmp(operation, "WriteAuthorityNs") == 0) {
514 answer_integer = serverinfo->fWriteAuthorityNs;
515 is_integer = 1;
516 } else if (strcasecmp(operation, "AdditionalRecursionTimeout") == 0) {
517 answer_integer = 0x00000004;
518 is_integer = 1;
519 } else if (strcasecmp(operation, "AppendMsZoneTransferFlag") == 0) {
520 answer_integer = 0;
521 is_integer = 1;
522 } else if (strcasecmp(operation, "AutoCreateDelegations") == 0) {
523 answer_integer = 0; /* DNS_ACD_DONT_CREATE */
524 is_integer = 1;
525 } else if (strcasecmp(operation, "BreakOnAscFailure") == 0) {
526 answer_integer = 0;
527 is_integer = 1;
528 } else if (strcasecmp(operation, "CacheEmptyAuthResponses") == 0) {
529 answer_integer = 0;
530 is_integer = 1;
531 } else if (strcasecmp(operation, "DirectoryPartitionAutoEnlistInterval") == 0) {
532 answer_integer = 0x00015180; /* 1 day */
533 is_integer = 1;
534 } else if (strcasecmp(operation, "DisableAutoReverseZones") == 0) {
535 answer_integer = ~serverinfo->fAutoReverseZones;
536 is_integer = 1;
537 } else if (strcasecmp(operation, "EDnsCacheTimeout") == 0) {
538 answer_integer = 0x00000384; /* 15 minutes */
539 is_integer = 1;
540 } else if (strcasecmp(operation, "EnableDirectoryPartitions") == 0) {
541 answer_integer = serverinfo->fDsAvailable;
542 is_integer = 1;
543 } else if (strcasecmp(operation, "EnableDnsSec") == 0) {
544 answer_integer = 0;
545 is_integer = 1;
546 } else if (strcasecmp(operation, "EnableEDnsProbes") == 0) {
547 answer_integer = 0;
548 is_integer = 1;
549 } else if (strcasecmp(operation, "EnableEDnsReception") == 0) {
550 answer_integer = 0;
551 is_integer = 1;
552 } else if (strcasecmp(operation, "EnableIPv6") == 0) {
553 answer_integer = 0;
554 is_integer = 1;
555 } else if (strcasecmp(operation, "EnableIQueryResponseGeneration") == 0) {
556 answer_integer = 0;
557 is_integer = 1;
558 } else if (strcasecmp(operation, "EnableSendErrorSuppression") == 0) {
559 answer_integer = 0;
560 is_integer = 1;
561 } else if (strcasecmp(operation, "EnableUpdateForwarding") == 0) {
562 answer_integer = 0;
563 is_integer = 1;
564 } else if (strcasecmp(operation, "EnableWinsR") == 0) {
565 answer_integer = 0;
566 is_integer = 1;
567 } else if (strcasecmp(operation, "ForceDsaBehaviorVersion") == 0) {
568 answer_integer = serverinfo->dwDsDsaVersion;
569 is_integer = 1;
570 } else if (strcasecmp(operation, "ForceDomainBehaviorVersion") == 0) {
571 answer_integer = serverinfo->dwDsDsaVersion;
572 is_integer = 1;
573 } else if (strcasecmp(operation, "ForceForestBehaviorVersion") == 0) {
574 answer_integer = serverinfo->dwDsDsaVersion;
575 is_integer = 1;
576 } else if (strcasecmp(operation, "HeapDebug") == 0) {
577 answer_integer = 0;
578 is_integer = 1;
579 } else if (strcasecmp(operation, "LameDelegationTtl") == 0) {
580 answer_integer = 0; /* seconds */
581 is_integer = 1;
582 } else if (strcasecmp(operation, "LocalNetPriorityNetMask") == 0) {
583 answer_integer = serverinfo->dwLocalNetPriorityNetMask;
584 is_integer = 1;
585 } else if (strcasecmp(operation, "MaxCacheSize") == 0) {
586 answer_integer = 0;
587 is_integer = 1;
588 } else if (strcasecmp(operation, "MaxResourceRecordsInNonSecureUpdate") == 0) {
589 answer_integer = 0x0000001E;
590 is_integer = 1;
591 } else if (strcasecmp(operation, "OperationsLogLevel") == 0) {
592 answer_integer = 0;
593 is_integer = 1;
594 } else if (strcasecmp(operation, "OperationsLogLevel2") == 0) {
595 answer_integer = 0;
596 is_integer = 1;
597 } else if (strcasecmp(operation, "MaximumUdpPacketSize") == 0) {
598 answer_integer = 0x00004000; /* maximum possible */
599 is_integer = 1;
600 } else if (strcasecmp(operation, "RecurseToInternetRootMask") == 0) {
601 answer_integer = 0;
602 is_integer = 1;
603 } else if (strcasecmp(operation, "SelfTest") == 0) {
604 answer_integer = 0;
605 is_integer = 1;
606 } else if (strcasecmp(operation, "SilentlyIgnoreCNameUpdateConflicts") == 0) {
607 answer_integer = 1;
608 is_integer = 1;
609 } else if (strcasecmp(operation, "TcpReceivePacketSize") == 0) {
610 answer_integer = 0x00010000;
611 is_integer = 1;
612 } else if (strcasecmp(operation, "XfrThrottleMultiplier") == 0) {
613 answer_integer = 0x0000000A;
614 is_integer = 1;
615 } else if (strcasecmp(operation, "AllowMsdcsLookupRetry") == 0) {
616 answer_integer = 1;
617 is_integer = 1;
618 } else if (strcasecmp(operation, "AllowReadOnlyZoneTransfer") == 0) {
619 answer_integer = 0;
620 is_integer = 1;
621 } else if (strcasecmp(operation, "DsBackGroundLoadPaused") == 0) {
622 answer_integer = 0;
623 is_integer = 1;
624 } else if (strcasecmp(operation, "DsMinimumBackgroundLoadThreads") == 0) {
625 answer_integer = 0;
626 is_integer = 1;
627 } else if (strcasecmp(operation, "DsRemoteReplicationDelay") == 0) {
628 answer_integer = 0x0000001E; /* 30 seconds */
629 is_integer = 1;
630 } else if (strcasecmp(operation, "EnableDuplicateQuerySuppresion") == 0) {
631 answer_integer = 0;
632 is_integer = 1;
633 } else if (strcasecmp(operation, "EnableGlobalNamesSupport") == 0) {
634 answer_integer = 0;
635 is_integer = 1;
636 } else if (strcasecmp(operation, "EnableVersionQuery") == 0) {
637 answer_integer = 1; /* DNS_VERSION_QUERY_FULL */
638 is_integer = 1;
639 } else if (strcasecmp(operation, "EnableRsoForRodc") == 0) {
640 answer_integer = 0;
641 is_integer = 1;
642 } else if (strcasecmp(operation, "ForceRODCMode") == 0) {
643 answer_integer = 0;
644 is_integer = 1;
645 } else if (strcasecmp(operation, "GlobalNamesAlwaysQuerySrv") == 0) {
646 answer_integer = 1;
647 is_integer = 1;
648 } else if (strcasecmp(operation, "GlobalNamesBlockUpdates") == 0) {
649 answer_integer = 0;
650 is_integer = 1;
651 } else if (strcasecmp(operation, "GlobalNamesEnableEDnsProbes") == 0) {
652 answer_integer = 0;
653 is_integer = 1;
654 } else if (strcasecmp(operation, "GlobalNamesPreferAAAA") == 0) {
655 answer_integer = 0;
656 is_integer = 1;
657 } else if (strcasecmp(operation, "GlobalNamesQueryOrder") == 0) {
658 answer_integer = 1;
659 is_integer = 1;
660 } else if (strcasecmp(operation, "GlobalNamesSendTimeout") == 0) {
661 answer_integer = 3; /* seconds */
662 is_integer = 1;
663 } else if (strcasecmp(operation, "GlobalNamesServerQueryInterval") == 0) {
664 answer_integer = 0x00005460; /* 6 hours */
665 is_integer = 1;
666 } else if (strcasecmp(operation, "RemoteIPv4RankBoost") == 0) {
667 answer_integer = 0;
668 is_integer = 1;
669 } else if (strcasecmp(operation, "RemoteIPv6RankBoost") == 0) {
670 answer_integer = 0;
671 is_integer = 1;
672 } else if (strcasecmp(operation, "MaximumRodcRsoAttemptsPerCycle") == 0) {
673 answer_integer = 0x00000064;
674 is_integer = 1;
675 } else if (strcasecmp(operation, "MaximumRodcRsoQueueLength") == 0) {
676 answer_integer = 0x0000012C;
677 is_integer = 1;
678 } else if (strcasecmp(operation, "EnableGlobalQueryBlockList") == 0) {
679 answer_integer = 0;
680 is_integer = 1;
681 } else if (strcasecmp(operation, "OpenACLOnProxyUpdates") == 0) {
682 answer_integer = 0;
683 is_integer = 1;
684 } else if (strcasecmp(operation, "CacheLockingPercent") == 0) {
685 answer_integer = 0x00000064;
686 is_integer = 1;
689 if (is_integer == 1) {
690 *typeid = DNSSRV_TYPEID_DWORD;
691 r->Dword = answer_integer;
692 return WERR_OK;
695 is_addresses = 0;
697 if (strcasecmp(operation, "Forwarders") == 0) {
698 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
699 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders);
700 } else {
701 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
703 is_addresses = 1;
704 } else if (strcasecmp(operation, "ListenAddresses") == 0) {
705 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
706 answer_addrarray = serverinfo->aipListenAddrs;
707 } else {
708 answer_iparray = dns_addr_array_to_ip4_array(mem_ctx, serverinfo->aipListenAddrs);
710 is_addresses = 1;
711 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
712 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
713 answer_addrarray = NULL;
714 } else {
715 answer_iparray = NULL;
717 is_addresses = 1;
718 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
719 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
720 answer_addrarray = NULL;
721 } else {
722 answer_iparray = NULL;
724 is_addresses = 1;
725 } else if (strcasecmp(operation, "LogIPFilterList") == 0) {
726 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
727 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter);
728 } else {
729 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
731 is_addresses = 1;
734 if (is_addresses == 1) {
735 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
736 *typeid = DNSSRV_TYPEID_ADDRARRAY;
737 r->AddrArray = answer_addrarray;
738 } else {
739 *typeid = DNSSRV_TYPEID_IPARRAY;
740 r->IpArray = answer_iparray;
742 return WERR_OK;
745 is_string = is_wstring = 0;
747 if (strcasecmp(operation, "DomainDirectoryPartitionBaseName") == 0) {
748 answer_string = talloc_strdup(mem_ctx, "DomainDnsZones");
749 if (! answer_string) {
750 return WERR_OUTOFMEMORY;
752 is_string = 1;
753 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
754 answer_string = talloc_strdup(mem_ctx, "ForestDnsZones");
755 if (! answer_string) {
756 return WERR_OUTOFMEMORY;
758 is_string = 1;
759 } else if (strcasecmp(operation, "LogFilePath") == 0) {
760 answer_string = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
761 is_wstring = 1;
762 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
763 answer_string = NULL;
764 is_wstring = 1;
765 } else if (strcasecmp(operation, "DsBackgroundPauseName") == 0) {
766 answer_string = NULL;
767 is_string = 1;
768 } else if (strcasecmp(operation, "DsNotRoundRobinTypes") == 0) {
769 answer_string = NULL;
770 is_string = 1;
773 if (is_string == 1) {
774 *typeid = DNSSRV_TYPEID_LPSTR;
775 r->String = answer_string;
776 return WERR_OK;
777 } else if (is_wstring == 1) {
778 *typeid = DNSSRV_TYPEID_LPWSTR;
779 r->WideString = answer_string;
780 return WERR_OK;
783 is_stringlist = 0;
785 if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
786 answer_stringlist = NULL;
787 is_stringlist = 1;
788 } else if (strcasecmp(operation, "SocketPoolExcludedPortRanges") == 0) {
789 answer_stringlist = NULL;
790 is_stringlist = 1;
793 if (is_stringlist == 1) {
794 *typeid = DNSSRV_TYPEID_UTF8_STRING_LIST;
795 r->Utf8StringList = answer_stringlist;
796 return WERR_OK;
799 DEBUG(0,("dnsserver: Invalid server operation %s", operation));
800 return WERR_DNS_ERROR_INVALID_PROPERTY;
803 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
804 static WERROR dnsserver_query_zone(struct dnsserver_state *dsstate,
805 TALLOC_CTX *mem_ctx,
806 struct dnsserver_zone *z,
807 const char *operation,
808 const unsigned int client_version,
809 enum DNS_RPC_TYPEID *typeid,
810 union DNSSRV_RPC_UNION *r)
812 uint8_t is_integer, is_addresses, is_string;
813 uint32_t answer_integer;
814 struct IP4_ARRAY *answer_iparray;
815 struct DNS_ADDR_ARRAY *answer_addrarray;
816 char *answer_string;
817 struct dnsserver_zoneinfo *zoneinfo;
819 zoneinfo = z->zoneinfo;
821 if (strcasecmp(operation, "Zone") == 0) {
822 if (client_version == DNS_CLIENT_VERSION_W2K) {
823 *typeid = DNSSRV_TYPEID_ZONE_W2K;
824 r->ZoneW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
826 r->ZoneW2K->pszZoneName = talloc_strdup(mem_ctx, z->name);
827 r->ZoneW2K->Flags = zoneinfo->Flags;
828 r->ZoneW2K->ZoneType = zoneinfo->dwZoneType;
829 r->ZoneW2K->Version = zoneinfo->Version;
830 } else {
831 *typeid = DNSSRV_TYPEID_ZONE;
832 r->Zone = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
834 r->Zone->dwRpcStructureVersion = 0x01;
835 r->Zone->pszZoneName = talloc_strdup(mem_ctx, z->name);
836 r->Zone->Flags = zoneinfo->Flags;
837 r->Zone->ZoneType = zoneinfo->dwZoneType;
838 r->Zone->Version = zoneinfo->Version;
839 r->Zone->dwDpFlags = z->partition->dwDpFlags;
840 r->Zone->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
842 return WERR_OK;
845 if (strcasecmp(operation, "ZoneInfo") == 0) {
846 if (client_version == DNS_CLIENT_VERSION_W2K) {
847 *typeid = DNSSRV_TYPEID_ZONE_INFO_W2K;
848 r->ZoneInfoW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_W2K);
850 r->ZoneInfoW2K->pszZoneName = talloc_strdup(mem_ctx, z->name);
851 r->ZoneInfoW2K->dwZoneType = zoneinfo->dwZoneType;
852 r->ZoneInfoW2K->fReverse = zoneinfo->fReverse;
853 r->ZoneInfoW2K->fAllowUpdate = zoneinfo->fAllowUpdate;
854 r->ZoneInfoW2K->fPaused = zoneinfo->fPaused;
855 r->ZoneInfoW2K->fShutdown = zoneinfo->fShutdown;
856 r->ZoneInfoW2K->fAutoCreated = zoneinfo->fAutoCreated;
857 r->ZoneInfoW2K->fUseDatabase = zoneinfo->fUseDatabase;
858 r->ZoneInfoW2K->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
859 r->ZoneInfoW2K->aipMasters = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
860 r->ZoneInfoW2K->fSecureSecondaries = zoneinfo->fSecureSecondaries;
861 r->ZoneInfoW2K->fNotifyLevel = zoneinfo->fNotifyLevel;
862 r->ZoneInfoW2K->aipSecondaries = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
863 r->ZoneInfoW2K->aipNotify = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
864 r->ZoneInfoW2K->fUseWins = zoneinfo->fUseWins;
865 r->ZoneInfoW2K->fUseNbstat = zoneinfo->fUseNbstat;
866 r->ZoneInfoW2K->fAging = zoneinfo->fAging;
867 r->ZoneInfoW2K->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
868 r->ZoneInfoW2K->dwRefreshInterval = zoneinfo->dwRefreshInterval;
869 r->ZoneInfoW2K->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
870 r->ZoneInfoW2K->aipScavengeServers = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
872 } else if (client_version == DNS_CLIENT_VERSION_DOTNET) {
873 *typeid = DNSSRV_TYPEID_ZONE_INFO_DOTNET;
874 r->ZoneInfoDotNet = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_DOTNET);
876 r->ZoneInfoDotNet->dwRpcStructureVersion = 0x01;
877 r->ZoneInfoDotNet->pszZoneName = talloc_strdup(mem_ctx, z->name);
878 r->ZoneInfoDotNet->dwZoneType = zoneinfo->dwZoneType;
879 r->ZoneInfoDotNet->fReverse = zoneinfo->fReverse;
880 r->ZoneInfoDotNet->fAllowUpdate = zoneinfo->fAllowUpdate;
881 r->ZoneInfoDotNet->fPaused = zoneinfo->fPaused;
882 r->ZoneInfoDotNet->fShutdown = zoneinfo->fShutdown;
883 r->ZoneInfoDotNet->fAutoCreated = zoneinfo->fAutoCreated;
884 r->ZoneInfoDotNet->fUseDatabase = zoneinfo->fUseDatabase;
885 r->ZoneInfoDotNet->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
886 r->ZoneInfoDotNet->aipMasters = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
887 r->ZoneInfoDotNet->fSecureSecondaries = zoneinfo->fSecureSecondaries;
888 r->ZoneInfoDotNet->fNotifyLevel = zoneinfo->fNotifyLevel;
889 r->ZoneInfoDotNet->aipSecondaries = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
890 r->ZoneInfoDotNet->aipNotify = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
891 r->ZoneInfoDotNet->fUseWins = zoneinfo->fUseWins;
892 r->ZoneInfoDotNet->fUseNbstat = zoneinfo->fUseNbstat;
893 r->ZoneInfoDotNet->fAging = zoneinfo->fAging;
894 r->ZoneInfoDotNet->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
895 r->ZoneInfoDotNet->dwRefreshInterval = zoneinfo->dwRefreshInterval;
896 r->ZoneInfoDotNet->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
897 r->ZoneInfoDotNet->aipScavengeServers = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
898 r->ZoneInfoDotNet->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
899 r->ZoneInfoDotNet->fForwarderSlave = zoneinfo->fForwarderSlave;
900 r->ZoneInfoDotNet->aipLocalMasters = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
901 r->ZoneInfoDotNet->dwDpFlags = z->partition->dwDpFlags;
902 r->ZoneInfoDotNet->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
903 r->ZoneInfoDotNet->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
904 r->ZoneInfoDotNet->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
905 r->ZoneInfoDotNet->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
907 } else {
908 *typeid = DNSSRV_TYPEID_ZONE_INFO;
909 r->ZoneInfo = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_LONGHORN);
911 r->ZoneInfo->dwRpcStructureVersion = 0x02;
912 r->ZoneInfo->pszZoneName = talloc_strdup(mem_ctx, z->name);
913 r->ZoneInfo->dwZoneType = zoneinfo->dwZoneType;
914 r->ZoneInfo->fReverse = zoneinfo->fReverse;
915 r->ZoneInfo->fAllowUpdate = zoneinfo->fAllowUpdate;
916 r->ZoneInfo->fPaused = zoneinfo->fPaused;
917 r->ZoneInfo->fShutdown = zoneinfo->fShutdown;
918 r->ZoneInfo->fAutoCreated = zoneinfo->fAutoCreated;
919 r->ZoneInfo->fUseDatabase = zoneinfo->fUseDatabase;
920 r->ZoneInfo->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
921 r->ZoneInfo->aipMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipMasters);
922 r->ZoneInfo->fSecureSecondaries = zoneinfo->fSecureSecondaries;
923 r->ZoneInfo->fNotifyLevel = zoneinfo->fNotifyLevel;
924 r->ZoneInfo->aipSecondaries = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipSecondaries);
925 r->ZoneInfo->aipNotify = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipNotify);
926 r->ZoneInfo->fUseWins = zoneinfo->fUseWins;
927 r->ZoneInfo->fUseNbstat = zoneinfo->fUseNbstat;
928 r->ZoneInfo->fAging = zoneinfo->fAging;
929 r->ZoneInfo->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
930 r->ZoneInfo->dwRefreshInterval = zoneinfo->dwRefreshInterval;
931 r->ZoneInfo->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
932 r->ZoneInfo->aipScavengeServers = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipScavengeServers);
933 r->ZoneInfo->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
934 r->ZoneInfo->fForwarderSlave = zoneinfo->fForwarderSlave;
935 r->ZoneInfo->aipLocalMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
936 r->ZoneInfo->dwDpFlags = z->partition->dwDpFlags;
937 r->ZoneInfo->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
938 r->ZoneInfo->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
939 r->ZoneInfo->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
940 r->ZoneInfo->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
942 r->ZoneInfo->fQueuedForBackgroundLoad = zoneinfo->fQueuedForBackgroundLoad;
943 r->ZoneInfo->fBackgroundLoadInProgress = zoneinfo->fBackgroundLoadInProgress;
944 r->ZoneInfo->fReadOnlyZone = zoneinfo->fReadOnlyZone;
945 r->ZoneInfo->dwLastXfrAttempt = zoneinfo->dwLastXfrAttempt;
946 r->ZoneInfo->dwLastXfrResult = zoneinfo->dwLastXfrResult;
949 return WERR_OK;
952 is_integer = 0;
954 if (strcasecmp(operation, "AllowUpdate") == 0) {
955 answer_integer = zoneinfo->fAllowUpdate;
956 is_integer = 1;
957 } else if (strcasecmp(operation, "Secured") == 0) {
958 answer_integer = 0;
959 is_integer = 1;
960 } else if (strcasecmp(operation, "DsIntegrated") == 0) {
961 answer_integer = zoneinfo->fUseDatabase;
962 is_integer = 1;
963 } else if (strcasecmp(operation, "LogUpdates") == 0) {
964 answer_integer = 0;
965 is_integer = 1;
966 } else if (strcasecmp(operation, "NoRefreshInterval") == 0) {
967 answer_integer = zoneinfo->dwNoRefreshInterval;
968 is_integer = 1;
969 } else if (strcasecmp(operation, "NotifyLevel") == 0) {
970 answer_integer = zoneinfo->fNotifyLevel;
971 is_integer = 1;
972 } else if (strcasecmp(operation, "RefreshInterval") == 0) {
973 answer_integer = zoneinfo->dwRefreshInterval;
974 is_integer = 1;
975 } else if (strcasecmp(operation, "SecureSecondaries") == 0) {
976 answer_integer = zoneinfo->fSecureSecondaries;
977 is_integer = 1;
978 } else if (strcasecmp(operation, "Type") == 0) {
979 answer_integer = zoneinfo->dwZoneType;
980 is_integer = 1;
981 } else if (strcasecmp(operation, "Aging") == 0) {
982 answer_integer = zoneinfo->fAging;
983 is_integer = 1;
984 } else if (strcasecmp(operation, "ForwarderSlave") == 0) {
985 answer_integer = zoneinfo->fForwarderSlave;
986 is_integer = 1;
987 } else if (strcasecmp(operation, "ForwarderTimeout") == 0) {
988 answer_integer = zoneinfo->dwForwarderTimeout;
989 is_integer = 1;
990 } else if (strcasecmp(operation, "Unicode") == 0) {
991 answer_integer = 0;
992 is_integer = 1;
995 if (is_integer == 1) {
996 *typeid = DNSSRV_TYPEID_DWORD;
997 r->Dword = answer_integer;
998 return WERR_OK;
1001 is_addresses = 0;
1003 if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
1004 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1005 answer_addrarray = NULL;
1006 } else {
1007 answer_iparray = NULL;
1009 is_addresses = 1;
1010 } else if (strcasecmp(operation, "ScavengeServers") == 0) {
1011 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1012 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipScavengeServers);
1013 } else {
1014 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
1016 is_addresses = 1;
1017 } else if (strcasecmp(operation, "MasterServers") == 0) {
1018 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1019 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipMasters);
1020 } else {
1021 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
1023 is_addresses = 1;
1024 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
1025 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1026 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
1027 } else {
1028 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
1030 is_addresses = 1;
1031 } else if (strcasecmp(operation, "NotifyServers") == 0) {
1032 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1033 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipNotify);
1034 } else {
1035 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
1037 is_addresses = 1;
1038 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
1039 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1040 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipSecondaries);
1041 } else {
1042 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
1044 is_addresses = 1;
1047 if (is_addresses == 1) {
1048 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1049 *typeid = DNSSRV_TYPEID_ADDRARRAY;
1050 r->AddrArray = answer_addrarray;
1051 } else {
1052 *typeid = DNSSRV_TYPEID_IPARRAY;
1053 r->IpArray = answer_iparray;
1055 return WERR_OK;
1058 is_string = 0;
1060 if (strcasecmp(operation, "DatabaseFile") == 0) {
1061 answer_string = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
1062 is_string = 1;
1063 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1064 answer_string = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
1065 is_string = 1;
1066 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1067 answer_string = NULL;
1068 is_string = 1;
1071 if (is_string == 1) {
1072 *typeid = DNSSRV_TYPEID_LPSTR;
1073 r->String = answer_string;
1074 return WERR_OK;
1077 DEBUG(0,("dnsserver: Invalid zone operation %s", operation));
1078 return WERR_DNS_ERROR_INVALID_PROPERTY;
1082 /* dnsserver operation functions */
1084 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
1085 static WERROR dnsserver_operate_server(struct dnsserver_state *dsstate,
1086 TALLOC_CTX *mem_ctx,
1087 const char *operation,
1088 const unsigned int client_version,
1089 enum DNS_RPC_TYPEID typeid,
1090 union DNSSRV_RPC_UNION *r)
1092 bool valid_operation = false;
1094 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1095 valid_operation = true;
1096 } else if (strcasecmp(operation, "Restart") == 0) {
1097 valid_operation = true;
1098 } else if (strcasecmp(operation, "ClearDebugLog") == 0) {
1099 valid_operation = true;
1100 } else if (strcasecmp(operation, "ClearCache") == 0) {
1101 valid_operation = true;
1102 } else if (strcasecmp(operation, "WriteDirtyZones") == 0) {
1103 valid_operation = true;
1104 } else if (strcasecmp(operation, "ZoneCreate") == 0) {
1105 struct dnsserver_zone *z, *z2;
1106 WERROR status;
1108 z = talloc_zero(mem_ctx, struct dnsserver_zone);
1109 W_ERROR_HAVE_NO_MEMORY(z);
1110 z->partition = talloc_zero(z, struct dnsserver_partition);
1111 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z->partition, z);
1112 z->zoneinfo = talloc_zero(z, struct dnsserver_zoneinfo);
1113 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z->zoneinfo, z);
1115 if (typeid == DNSSRV_TYPEID_ZONE_CREATE_W2K) {
1116 z->name = talloc_strdup(z, r->ZoneCreateW2K->pszZoneName);
1117 z->zoneinfo->dwZoneType = r->ZoneCreateW2K->dwZoneType;
1118 z->zoneinfo->fAllowUpdate = r->ZoneCreateW2K->fAllowUpdate;
1119 z->zoneinfo->fAging = r->ZoneCreateW2K->fAging;
1120 z->zoneinfo->Flags = r->ZoneCreateW2K->dwFlags;
1121 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE_DOTNET) {
1122 z->name = talloc_strdup(z, r->ZoneCreateDotNet->pszZoneName);
1123 z->zoneinfo->dwZoneType = r->ZoneCreateDotNet->dwZoneType;
1124 z->zoneinfo->fAllowUpdate = r->ZoneCreateDotNet->fAllowUpdate;
1125 z->zoneinfo->fAging = r->ZoneCreateDotNet->fAging;
1126 z->zoneinfo->Flags = r->ZoneCreateDotNet->dwFlags;
1127 z->partition->dwDpFlags = r->ZoneCreateDotNet->dwDpFlags;
1128 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE) {
1129 z->name = talloc_strdup(z, r->ZoneCreate->pszZoneName);
1130 z->zoneinfo->dwZoneType = r->ZoneCreate->dwZoneType;
1131 z->zoneinfo->fAllowUpdate = r->ZoneCreate->fAllowUpdate;
1132 z->zoneinfo->fAging = r->ZoneCreate->fAging;
1133 z->zoneinfo->Flags = r->ZoneCreate->dwFlags;
1134 z->partition->dwDpFlags = r->ZoneCreate->dwDpFlags;
1135 } else {
1136 talloc_free(z);
1137 return WERR_DNS_ERROR_INVALID_PROPERTY;
1140 z2 = dnsserver_find_zone(dsstate->zones, z->name);
1141 if (z2 != NULL) {
1142 talloc_free(z);
1143 return WERR_DNS_ERROR_ZONE_ALREADY_EXISTS;
1146 status = dnsserver_db_create_zone(dsstate->samdb, dsstate->partitions, z,
1147 dsstate->lp_ctx);
1148 talloc_free(z);
1150 if (W_ERROR_IS_OK(status)) {
1151 dnsserver_reload_zones(dsstate);
1153 return status;
1154 } else if (strcasecmp(operation, "ClearStatistics") == 0) {
1155 valid_operation = true;
1156 } else if (strcasecmp(operation, "EnlistDirectoryPartition") == 0) {
1157 valid_operation = true;
1158 } else if (strcasecmp(operation, "StartScavenging") == 0) {
1159 valid_operation = true;
1160 } else if (strcasecmp(operation, "AbortScavenging") == 0) {
1161 valid_operation = true;
1162 } else if (strcasecmp(operation, "AutoConfigure") == 0) {
1163 valid_operation = true;
1164 } else if (strcasecmp(operation, "ExportSettings") == 0) {
1165 valid_operation = true;
1166 } else if (strcasecmp(operation, "PrepareForDemotion") == 0) {
1167 valid_operation = true;
1168 } else if (strcasecmp(operation, "PrepareForUninstall") == 0) {
1169 valid_operation = true;
1170 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1171 valid_operation = true;
1172 } else if (strcasecmp(operation, "DeleteRecord") == 0) {
1173 valid_operation = true;
1174 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1175 valid_operation = true;
1176 } else if (strcasecmp(operation, "ListenAddresses") == 0) {
1177 valid_operation = true;
1178 } else if (strcasecmp(operation, "Forwarders") == 0) {
1179 valid_operation = true;
1180 } else if (strcasecmp(operation, "LogFilePath") == 0) {
1181 valid_operation = true;
1182 } else if (strcasecmp(operation, "LogIpFilterList") == 0) {
1183 valid_operation = true;
1184 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
1185 valid_operation = true;
1186 } else if (strcasecmp(operation, "DomainDirectoryPartitionBaseName") == 0) {
1187 valid_operation = true;
1188 } else if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
1189 valid_operation = true;
1190 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
1191 valid_operation = true;
1192 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
1193 valid_operation = true;
1194 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
1195 valid_operation = true;
1198 if (valid_operation) {
1199 DEBUG(0, ("dnsserver: server operation '%s' not implemented", operation));
1200 return WERR_CALL_NOT_IMPLEMENTED;
1203 DEBUG(0, ("dnsserver: invalid server operation '%s'", operation));
1204 return WERR_DNS_ERROR_INVALID_PROPERTY;
1207 static WERROR dnsserver_complex_operate_server(struct dnsserver_state *dsstate,
1208 TALLOC_CTX *mem_ctx,
1209 const char *operation,
1210 const unsigned int client_version,
1211 enum DNS_RPC_TYPEID typeid_in,
1212 union DNSSRV_RPC_UNION *rin,
1213 enum DNS_RPC_TYPEID *typeid_out,
1214 union DNSSRV_RPC_UNION *rout)
1216 int valid_operation = 0;
1217 struct dnsserver_zone *z, **zlist;
1218 int zcount;
1219 bool found1, found2, found3, found4;
1220 int i;
1222 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1223 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1224 return dnsserver_query_server(dsstate, mem_ctx,
1225 rin->String,
1226 client_version,
1227 typeid_out,
1228 rout);
1230 } else if (strcasecmp(operation, "EnumZones") == 0) {
1231 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1232 return WERR_DNS_ERROR_INVALID_PROPERTY;
1235 zcount = 0;
1236 zlist = talloc_zero_array(mem_ctx, struct dnsserver_zone *, 0);
1237 for (z = dsstate->zones; z; z = z->next) {
1239 /* Match the flags in groups
1241 * Group1 : PRIMARY, SECONDARY, CACHE, AUTO
1242 * Group2 : FORWARD, REVERSE, FORWARDER, STUB
1243 * Group3 : DS, NON_DS, DOMAIN_DP, FOREST_DP
1244 * Group4 : CUSTOM_DP, LEGACY_DP
1247 /* Group 1 */
1248 found1 = false;
1249 if (rin->Dword & 0x0000000f) {
1250 if (rin->Dword & DNS_ZONE_REQUEST_PRIMARY) {
1251 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_PRIMARY) {
1252 found1 = true;
1255 if (rin->Dword & DNS_ZONE_REQUEST_SECONDARY) {
1256 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_SECONDARY) {
1257 found1 = true;
1260 if (rin->Dword & DNS_ZONE_REQUEST_CACHE) {
1261 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_CACHE) {
1262 found1 = true;
1265 if (rin->Dword & DNS_ZONE_REQUEST_AUTO) {
1266 if (z->zoneinfo->fAutoCreated
1267 || z->partition->dwDpFlags & DNS_DP_AUTOCREATED) {
1268 found1 = true;
1271 } else {
1272 found1 = true;
1275 /* Group 2 */
1276 found2 = false;
1277 if (rin->Dword & 0x000000f0) {
1278 if (rin->Dword & DNS_ZONE_REQUEST_FORWARD) {
1279 if (!(z->zoneinfo->fReverse)) {
1280 found2 = true;
1283 if (rin->Dword & DNS_ZONE_REQUEST_REVERSE) {
1284 if (z->zoneinfo->fReverse) {
1285 found2 = true;
1288 if (rin->Dword & DNS_ZONE_REQUEST_FORWARDER) {
1289 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_FORWARDER) {
1290 found2 = true;
1293 if (rin->Dword & DNS_ZONE_REQUEST_STUB) {
1294 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_STUB) {
1295 found2 = true;
1298 } else {
1299 found2 = true;
1302 /* Group 3 */
1303 found3 = false;
1304 if (rin->Dword & 0x00000f00) {
1305 if (rin->Dword & DNS_ZONE_REQUEST_DS) {
1306 if (z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED) {
1307 found3 = true;
1310 if (rin->Dword & DNS_ZONE_REQUEST_NON_DS) {
1311 if (!(z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED)) {
1312 found3 = true;
1315 if (rin->Dword & DNS_ZONE_REQUEST_DOMAIN_DP) {
1316 if (!(z->partition->dwDpFlags & DNS_DP_DOMAIN_DEFAULT)) {
1317 found3 = true;
1320 if (rin->Dword & DNS_ZONE_REQUEST_FOREST_DP) {
1321 if (!(z->partition->dwDpFlags & DNS_DP_FOREST_DEFAULT)) {
1322 found3 = true;
1325 } else {
1326 found3 = true;
1329 /* Group 4 */
1330 if (rin->Dword & 0x0000f000) {
1331 found4 = false;
1332 } else {
1333 found4 = true;
1336 if (found1 && found2 && found3 && found4) {
1337 zlist = talloc_realloc(mem_ctx, zlist, struct dnsserver_zone *, zcount+1);
1338 zlist[zcount] = z;
1339 zcount++;
1343 if (client_version == DNS_CLIENT_VERSION_W2K) {
1344 *typeid_out = DNSSRV_TYPEID_ZONE_LIST_W2K;
1345 rout->ZoneListW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_W2K);
1347 if (zcount == 0) {
1348 rout->ZoneListW2K->dwZoneCount = 0;
1349 rout->ZoneListW2K->ZoneArray = NULL;
1351 return WERR_OK;
1354 rout->ZoneListW2K->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_W2K *, zcount);
1355 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout->ZoneListW2K->ZoneArray, zlist);
1357 for (i=0; i<zcount; i++) {
1358 rout->ZoneListW2K->ZoneArray[i] = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
1360 rout->ZoneListW2K->ZoneArray[i]->pszZoneName = talloc_strdup(mem_ctx, zlist[i]->name);
1361 rout->ZoneListW2K->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
1362 rout->ZoneListW2K->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
1363 rout->ZoneListW2K->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
1365 rout->ZoneListW2K->dwZoneCount = zcount;
1367 } else {
1368 *typeid_out = DNSSRV_TYPEID_ZONE_LIST;
1369 rout->ZoneList = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_DOTNET);
1371 if (zcount == 0) {
1372 rout->ZoneList->dwRpcStructureVersion = 1;
1373 rout->ZoneList->dwZoneCount = 0;
1374 rout->ZoneList->ZoneArray = NULL;
1376 return WERR_OK;
1379 rout->ZoneList->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_DOTNET *, zcount);
1380 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout->ZoneList->ZoneArray, zlist);
1382 for (i=0; i<zcount; i++) {
1383 rout->ZoneList->ZoneArray[i] = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
1385 rout->ZoneList->ZoneArray[i]->dwRpcStructureVersion = 1;
1386 rout->ZoneList->ZoneArray[i]->pszZoneName = talloc_strdup(mem_ctx, zlist[i]->name);
1387 rout->ZoneList->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
1388 rout->ZoneList->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
1389 rout->ZoneList->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
1390 rout->ZoneList->ZoneArray[i]->dwDpFlags = zlist[i]->partition->dwDpFlags;
1391 rout->ZoneList->ZoneArray[i]->pszDpFqdn = talloc_strdup(mem_ctx, zlist[i]->partition->pszDpFqdn);
1393 rout->ZoneList->dwRpcStructureVersion = 1;
1394 rout->ZoneList->dwZoneCount = zcount;
1396 talloc_free(zlist);
1397 return WERR_OK;
1398 } else if (strcasecmp(operation, "EnumZones2") == 0) {
1399 valid_operation = true;
1400 } else if (strcasecmp(operation, "EnumDirectoryPartitions") == 0) {
1401 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1402 return WERR_DNS_ERROR_INVALID_PROPERTY;
1405 *typeid_out = DNSSRV_TYPEID_DP_LIST;
1406 rout->DirectoryPartitionList = talloc_zero(mem_ctx, struct DNS_RPC_DP_LIST);
1408 if (rin->Dword != 0) {
1409 rout->DirectoryPartitionList->dwDpCount = 0;
1410 rout->DirectoryPartitionList->DpArray = NULL;
1411 } else {
1412 struct DNS_RPC_DP_ENUM **dplist;
1413 struct dnsserver_partition *p;
1414 int pcount = 2;
1416 dplist = talloc_zero_array(mem_ctx, struct DNS_RPC_DP_ENUM *, pcount);
1417 W_ERROR_HAVE_NO_MEMORY(dplist);
1419 p = dsstate->partitions;
1420 for (i=0; i<pcount; i++) {
1421 dplist[i] = talloc_zero(dplist, struct DNS_RPC_DP_ENUM);
1423 dplist[i]->pszDpFqdn = talloc_strdup(mem_ctx, p->pszDpFqdn);
1424 dplist[i]->dwFlags = p->dwDpFlags;
1425 dplist[i]->dwZoneCount = p->zones_count;
1426 p = p->next;
1429 rout->DirectoryPartitionList->dwDpCount = pcount;
1430 rout->DirectoryPartitionList->DpArray = dplist;
1432 return WERR_OK;
1433 } else if (strcasecmp(operation, "DirectoryPartitionInfo") == 0) {
1434 struct dnsserver_partition *p;
1435 struct dnsserver_partition_info *partinfo;
1436 struct DNS_RPC_DP_INFO *dpinfo = NULL;
1438 if (typeid_in != DNSSRV_TYPEID_LPSTR) {
1439 return WERR_DNS_ERROR_INVALID_PROPERTY;
1442 *typeid_out = DNSSRV_TYPEID_DP_INFO;
1444 for (p = dsstate->partitions; p; p = p->next) {
1445 if (strcasecmp(p->pszDpFqdn, rin->String) == 0) {
1446 dpinfo = talloc_zero(mem_ctx, struct DNS_RPC_DP_INFO);
1447 W_ERROR_HAVE_NO_MEMORY(dpinfo);
1449 partinfo = dnsserver_db_partition_info(mem_ctx, dsstate->samdb, p);
1450 W_ERROR_HAVE_NO_MEMORY(partinfo);
1452 dpinfo->pszDpFqdn = talloc_strdup(dpinfo, p->pszDpFqdn);
1453 dpinfo->pszDpDn = talloc_strdup(dpinfo, ldb_dn_get_linearized(p->partition_dn));
1454 dpinfo->pszCrDn = talloc_steal(dpinfo, partinfo->pszCrDn);
1455 dpinfo->dwFlags = p->dwDpFlags;
1456 dpinfo->dwZoneCount = p->zones_count;
1457 dpinfo->dwState = partinfo->dwState;
1458 dpinfo->dwReplicaCount = partinfo->dwReplicaCount;
1459 if (partinfo->dwReplicaCount > 0) {
1460 dpinfo->ReplicaArray = talloc_steal(dpinfo,
1461 partinfo->ReplicaArray);
1462 } else {
1463 dpinfo->ReplicaArray = NULL;
1465 break;
1469 if (dpinfo == NULL) {
1470 return WERR_DNS_ERROR_DP_DOES_NOT_EXIST;
1473 rout->DirectoryPartition = dpinfo;
1474 return WERR_OK;
1475 } else if (strcasecmp(operation, "Statistics") == 0) {
1476 valid_operation = true;
1477 } else if (strcasecmp(operation, "IpValidate") == 0) {
1478 valid_operation = true;
1481 if (valid_operation) {
1482 DEBUG(0, ("dnsserver: server complex operation '%s' not implemented", operation));
1483 return WERR_CALL_NOT_IMPLEMENTED;
1486 DEBUG(0, ("dnsserver: invalid server complex operation '%s'", operation));
1487 return WERR_DNS_ERROR_INVALID_PROPERTY;
1490 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
1491 static WERROR dnsserver_operate_zone(struct dnsserver_state *dsstate,
1492 TALLOC_CTX *mem_ctx,
1493 struct dnsserver_zone *z,
1494 unsigned int request_filter,
1495 const char *operation,
1496 const unsigned int client_version,
1497 enum DNS_RPC_TYPEID typeid,
1498 union DNSSRV_RPC_UNION *r)
1500 bool valid_operation = false;
1502 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1503 if (typeid != DNSSRV_TYPEID_NAME_AND_PARAM) {
1504 return WERR_DNS_ERROR_INVALID_PROPERTY;
1507 /* Ignore property resets */
1508 if (strcasecmp(r->NameAndParam->pszNodeName, "AllowUpdate") == 0) {
1509 return WERR_OK;
1511 valid_operation = true;
1512 } else if (strcasecmp(operation, "ZoneTypeReset") == 0) {
1513 valid_operation = true;
1514 } else if (strcasecmp(operation, "PauseZone") == 0) {
1515 valid_operation = true;
1516 } else if (strcasecmp(operation, "ResumeZone") == 0) {
1517 valid_operation = true;
1518 } else if (strcasecmp(operation, "DeleteZone") == 0) {
1519 valid_operation = true;
1520 } else if (strcasecmp(operation, "ReloadZone") == 0) {
1521 valid_operation = true;
1522 } else if (strcasecmp(operation, "RefreshZone") == 0) {
1523 valid_operation = true;
1524 } else if (strcasecmp(operation, "ExpireZone") == 0) {
1525 valid_operation = true;
1526 } else if (strcasecmp(operation, "IncrementVersion") == 0) {
1527 valid_operation = true;
1528 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1529 valid_operation = true;
1530 } else if (strcasecmp(operation, "DeleteZoneFromDs") == 0) {
1531 WERROR status;
1532 if (z == NULL) {
1533 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1535 status = dnsserver_db_delete_zone(dsstate->samdb, z);
1536 if (W_ERROR_IS_OK(status)) {
1537 dnsserver_reload_zones(dsstate);
1539 return status;
1540 } else if (strcasecmp(operation, "UpdateZoneFromDs") == 0) {
1541 valid_operation = true;
1542 } else if (strcasecmp(operation, "ZoneExport") == 0) {
1543 valid_operation = true;
1544 } else if (strcasecmp(operation, "ZoneChangeDirectoryPartition") == 0) {
1545 valid_operation = true;
1546 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1547 valid_operation = true;
1548 } else if (strcasecmp(operation, "DeleteRecordSet") == 0) {
1549 valid_operation = true;
1550 } else if (strcasecmp(operation, "ForceAgingOnNode") == 0) {
1551 valid_operation = true;
1552 } else if (strcasecmp(operation, "DatabaseFile") == 0) {
1553 valid_operation = true;
1554 } else if (strcasecmp(operation, "MasterServers") == 0) {
1555 valid_operation = true;
1556 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
1557 valid_operation = true;
1558 } else if (strcasecmp(operation, "NotifyServers") == 0) {
1559 valid_operation = true;
1560 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
1561 valid_operation = true;
1562 } else if (strcasecmp(operation, "ScavengingServers") == 0) {
1563 valid_operation = true;
1564 } else if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
1565 valid_operation = true;
1566 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1567 valid_operation = true;
1568 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1569 valid_operation = true;
1572 if (valid_operation) {
1573 DEBUG(0, ("dnsserver: zone operation '%s' not implemented", operation));
1574 return WERR_CALL_NOT_IMPLEMENTED;
1577 DEBUG(0, ("dnsserver: invalid zone operation '%s'", operation));
1578 return WERR_DNS_ERROR_INVALID_PROPERTY;
1581 static WERROR dnsserver_complex_operate_zone(struct dnsserver_state *dsstate,
1582 TALLOC_CTX *mem_ctx,
1583 struct dnsserver_zone *z,
1584 const char *operation,
1585 const unsigned int client_version,
1586 enum DNS_RPC_TYPEID typeid_in,
1587 union DNSSRV_RPC_UNION *rin,
1588 enum DNS_RPC_TYPEID *typeid_out,
1589 union DNSSRV_RPC_UNION *rout)
1591 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1592 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1593 return dnsserver_query_zone(dsstate, mem_ctx, z,
1594 rin->String,
1595 client_version,
1596 typeid_out,
1597 rout);
1602 DEBUG(0,("dnsserver: Invalid zone operation %s", operation));
1603 return WERR_DNS_ERROR_INVALID_PROPERTY;
1606 /* dnsserver enumerate function */
1608 static WERROR dnsserver_enumerate_root_records(struct dnsserver_state *dsstate,
1609 TALLOC_CTX *mem_ctx,
1610 unsigned int client_version,
1611 const char *node_name,
1612 enum dns_record_type record_type,
1613 unsigned int select_flag,
1614 unsigned int *buffer_length,
1615 struct DNS_RPC_RECORDS_ARRAY **buffer)
1617 TALLOC_CTX *tmp_ctx;
1618 struct dnsserver_zone *z;
1619 const char * const attrs[] = { "name", "dnsRecord", NULL };
1620 struct ldb_result *res;
1621 struct DNS_RPC_RECORDS_ARRAY *recs;
1622 char **add_names;
1623 char *rname;
1624 int add_count;
1625 int i, ret, len;
1626 WERROR status;
1628 tmp_ctx = talloc_new(mem_ctx);
1629 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1631 z = dnsserver_find_zone(dsstate->zones, ".");
1632 if (z == NULL) {
1633 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1636 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1637 LDB_SCOPE_ONELEVEL, attrs,
1638 "(&(objectClass=dnsNode)(name=@)(!(dNSTombstoned=TRUE)))");
1639 if (ret != LDB_SUCCESS) {
1640 talloc_free(tmp_ctx);
1641 return WERR_INTERNAL_DB_ERROR;
1643 if (res->count == 0) {
1644 talloc_free(tmp_ctx);
1645 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1648 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1649 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1651 add_names = NULL;
1652 add_count = 0;
1654 for (i=0; i<res->count; i++) {
1655 status = dns_fill_records_array(tmp_ctx, NULL, record_type,
1656 select_flag, NULL,
1657 res->msgs[i], 0, recs,
1658 &add_names, &add_count);
1659 if (!W_ERROR_IS_OK(status)) {
1660 talloc_free(tmp_ctx);
1661 return status;
1664 talloc_free(res);
1666 /* Add any additional records */
1667 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1668 for (i=0; i<add_count; i++) {
1669 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1670 LDB_SCOPE_ONELEVEL, attrs,
1671 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1672 add_names[i]);
1673 if (ret != LDB_SUCCESS || res->count == 0) {
1674 talloc_free(res);
1675 continue;
1678 len = strlen(add_names[i]);
1679 if (add_names[i][len-1] == '.') {
1680 rname = talloc_strdup(tmp_ctx, add_names[i]);
1681 } else {
1682 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1684 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1685 select_flag, rname,
1686 res->msgs[0], 0, recs,
1687 NULL, NULL);
1688 talloc_free(rname);
1689 talloc_free(res);
1693 talloc_free(tmp_ctx);
1695 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1696 *buffer = recs;
1698 return WERR_OK;
1702 static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
1703 TALLOC_CTX *mem_ctx,
1704 struct dnsserver_zone *z,
1705 unsigned int client_version,
1706 const char *node_name,
1707 const char *start_child,
1708 enum dns_record_type record_type,
1709 unsigned int select_flag,
1710 const char *filter_start,
1711 const char *filter_stop,
1712 unsigned int *buffer_length,
1713 struct DNS_RPC_RECORDS_ARRAY **buffer)
1715 TALLOC_CTX *tmp_ctx;
1716 char *name;
1717 const char * const attrs[] = { "name", "dnsRecord", NULL };
1718 struct ldb_result *res;
1719 struct DNS_RPC_RECORDS_ARRAY *recs;
1720 char **add_names = NULL;
1721 char *rname;
1722 int add_count = 0;
1723 int i, ret, len;
1724 WERROR status;
1725 struct dns_tree *tree, *base, *node;
1727 tmp_ctx = talloc_new(mem_ctx);
1728 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1730 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1731 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1733 /* search all records under parent tree */
1734 if (strcasecmp(name, z->name) == 0) {
1735 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1736 LDB_SCOPE_ONELEVEL, attrs,
1737 "(&(objectClass=dnsNode)(!(dNSTombstoned=TRUE)))");
1738 } else {
1739 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1740 LDB_SCOPE_ONELEVEL, attrs,
1741 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s))(!(dNSTombstoned=TRUE)))",
1742 name, name);
1744 if (ret != LDB_SUCCESS) {
1745 talloc_free(tmp_ctx);
1746 return WERR_INTERNAL_DB_ERROR;
1748 if (res->count == 0) {
1749 talloc_free(tmp_ctx);
1750 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1753 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1754 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1756 /* Sort the names, so that the first record is the parent record */
1757 ldb_qsort(res->msgs, res->count, sizeof(struct ldb_message *), name,
1758 (ldb_qsort_cmp_fn_t)dns_name_compare);
1760 /* Build a tree of name components from dns name */
1761 if (strcasecmp(name, z->name) == 0) {
1762 tree = dns_build_tree(tmp_ctx, "@", res);
1763 } else {
1764 tree = dns_build_tree(tmp_ctx, name, res);
1766 W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree, tmp_ctx);
1768 /* Find the parent record in the tree */
1769 base = tree;
1770 while (base->level != -1) {
1771 base = base->children[0];
1774 /* Add the parent record with blank name */
1775 if (!(select_flag & DNS_RPC_VIEW_ONLY_CHILDREN)) {
1776 status = dns_fill_records_array(tmp_ctx, z, record_type,
1777 select_flag, NULL,
1778 base->data, 0,
1779 recs, &add_names, &add_count);
1780 if (!W_ERROR_IS_OK(status)) {
1781 talloc_free(tmp_ctx);
1782 return status;
1786 /* Add all the children records */
1787 if (!(select_flag & DNS_RPC_VIEW_NO_CHILDREN)) {
1788 for (i=0; i<base->num_children; i++) {
1789 node = base->children[i];
1791 status = dns_fill_records_array(tmp_ctx, z, record_type,
1792 select_flag, node->name,
1793 node->data, node->num_children,
1794 recs, &add_names, &add_count);
1795 if (!W_ERROR_IS_OK(status)) {
1796 talloc_free(tmp_ctx);
1797 return status;
1802 talloc_free(res);
1803 talloc_free(tree);
1804 talloc_free(name);
1806 /* Add any additional records */
1807 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1808 for (i=0; i<add_count; i++) {
1809 struct dnsserver_zone *z2;
1811 /* Search all the available zones for additional name */
1812 for (z2 = dsstate->zones; z2; z2 = z2->next) {
1813 name = dns_split_node_name(tmp_ctx, add_names[i], z2->name);
1814 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z2->zone_dn,
1815 LDB_SCOPE_ONELEVEL, attrs,
1816 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1817 name);
1818 talloc_free(name);
1819 if (ret != LDB_SUCCESS) {
1820 continue;
1822 if (res->count == 1) {
1823 break;
1824 } else {
1825 talloc_free(res);
1826 continue;
1830 len = strlen(add_names[i]);
1831 if (add_names[i][len-1] == '.') {
1832 rname = talloc_strdup(tmp_ctx, add_names[i]);
1833 } else {
1834 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1836 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1837 select_flag, rname,
1838 res->msgs[0], 0, recs,
1839 NULL, NULL);
1840 talloc_free(rname);
1841 talloc_free(res);
1845 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1846 *buffer = recs;
1848 return WERR_OK;
1851 /* dnsserver update function */
1853 static WERROR dnsserver_update_record(struct dnsserver_state *dsstate,
1854 TALLOC_CTX *mem_ctx,
1855 struct dnsserver_zone *z,
1856 unsigned int client_version,
1857 const char *node_name,
1858 struct DNS_RPC_RECORD_BUF *add_buf,
1859 struct DNS_RPC_RECORD_BUF *del_buf)
1861 TALLOC_CTX *tmp_ctx;
1862 char *name;
1863 WERROR status;
1865 tmp_ctx = talloc_new(mem_ctx);
1866 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1868 /* If node_name is @ or zone name, dns record is @ */
1869 if (strcmp(node_name, "@") == 0 ||
1870 strcmp(node_name, ".") == 0 ||
1871 strcasecmp(node_name, z->name) == 0) {
1872 name = talloc_strdup(tmp_ctx, "@");
1873 } else {
1874 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1876 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1878 if (add_buf != NULL) {
1879 if (del_buf == NULL) {
1880 /* Add record */
1881 status = dnsserver_db_add_record(tmp_ctx, dsstate->samdb,
1882 z, name,
1883 &add_buf->rec);
1884 } else {
1885 /* Update record */
1886 status = dnsserver_db_update_record(tmp_ctx, dsstate->samdb,
1887 z, name,
1888 &add_buf->rec,
1889 &del_buf->rec);
1891 } else {
1892 if (del_buf == NULL) {
1893 /* Add empty node */
1894 status = dnsserver_db_add_empty_node(tmp_ctx, dsstate->samdb,
1895 z, name);
1896 } else {
1897 /* Delete record */
1898 status = dnsserver_db_delete_record(tmp_ctx, dsstate->samdb,
1899 z, name,
1900 &del_buf->rec);
1904 talloc_free(tmp_ctx);
1905 return status;
1909 /* dnsserver interface functions */
1911 static WERROR dcesrv_DnssrvOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation *r)
1913 struct dnsserver_state *dsstate;
1914 struct dnsserver_zone *z = NULL;
1915 uint32_t request_filter = 0;
1916 WERROR ret;
1918 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1919 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1922 if (r->in.dwContext == 0) {
1923 if (r->in.pszZone != NULL) {
1924 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
1926 } else {
1927 request_filter = r->in.dwContext;
1930 if (r->in.pszZone == NULL) {
1931 ret = dnsserver_operate_server(dsstate, mem_ctx,
1932 r->in.pszOperation,
1933 DNS_CLIENT_VERSION_W2K,
1934 r->in.dwTypeId,
1935 &r->in.pData);
1936 } else {
1937 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1938 if (z == NULL && request_filter == 0) {
1939 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1942 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
1943 request_filter,
1944 r->in.pszOperation,
1945 DNS_CLIENT_VERSION_W2K,
1946 r->in.dwTypeId,
1947 &r->in.pData);
1950 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1951 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation, NDR_IN, r);
1953 return ret;
1956 static WERROR dcesrv_DnssrvQuery(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery *r)
1958 struct dnsserver_state *dsstate;
1959 struct dnsserver_zone *z;
1960 WERROR ret;
1962 ZERO_STRUCTP(r->out.pdwTypeId);
1963 ZERO_STRUCTP(r->out.ppData);
1965 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1966 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1969 if (r->in.pszZone == NULL) {
1970 /* FIXME: DNS Server Configuration Access Control List */
1971 ret = dnsserver_query_server(dsstate, mem_ctx,
1972 r->in.pszOperation,
1973 DNS_CLIENT_VERSION_W2K,
1974 r->out.pdwTypeId,
1975 r->out.ppData);
1976 } else {
1977 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1978 if (z == NULL) {
1979 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1982 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
1983 r->in.pszOperation,
1984 DNS_CLIENT_VERSION_W2K,
1985 r->out.pdwTypeId,
1986 r->out.ppData);
1989 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1990 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery, NDR_IN, r);
1992 return ret;
1995 static WERROR dcesrv_DnssrvComplexOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation *r)
1997 struct dnsserver_state *dsstate;
1998 struct dnsserver_zone *z;
1999 WERROR ret;
2001 ZERO_STRUCTP(r->out.pdwTypeOut);
2002 ZERO_STRUCTP(r->out.ppDataOut);
2004 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2005 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2008 if (r->in.pszZone == NULL) {
2009 /* Server operation */
2010 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
2011 r->in.pszOperation,
2012 DNS_CLIENT_VERSION_W2K,
2013 r->in.dwTypeIn,
2014 &r->in.pDataIn,
2015 r->out.pdwTypeOut,
2016 r->out.ppDataOut);
2017 } else {
2018 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2019 if (z == NULL) {
2020 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2023 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2024 r->in.pszOperation,
2025 DNS_CLIENT_VERSION_W2K,
2026 r->in.dwTypeIn,
2027 &r->in.pDataIn,
2028 r->out.pdwTypeOut,
2029 r->out.ppDataOut);
2032 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2033 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation, NDR_IN, r);
2035 return ret;
2038 static WERROR dcesrv_DnssrvEnumRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords *r)
2040 struct dnsserver_state *dsstate;
2041 struct dnsserver_zone *z;
2042 WERROR ret;
2044 ZERO_STRUCTP(r->out.pdwBufferLength);
2045 ZERO_STRUCTP(r->out.pBuffer);
2047 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2048 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2051 if (r->in.pszZone == NULL) {
2052 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2055 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
2056 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
2057 DNS_CLIENT_VERSION_W2K,
2058 r->in.pszNodeName,
2059 r->in.wRecordType,
2060 r->in.fSelectFlag,
2061 r->out.pdwBufferLength,
2062 r->out.pBuffer);
2063 } else {
2064 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2065 if (z == NULL) {
2066 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2069 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2070 DNS_CLIENT_VERSION_W2K,
2071 r->in.pszNodeName,
2072 r->in.pszStartChild,
2073 r->in.wRecordType,
2074 r->in.fSelectFlag,
2075 r->in.pszFilterStart,
2076 r->in.pszFilterStop,
2077 r->out.pdwBufferLength,
2078 r->out.pBuffer);
2081 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2082 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords, NDR_IN, r);
2084 return ret;
2087 static WERROR dcesrv_DnssrvUpdateRecord(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord *r)
2089 struct dnsserver_state *dsstate;
2090 struct dnsserver_zone *z;
2091 WERROR ret;
2093 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2094 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2097 if (r->in.pszZone == NULL) {
2098 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2101 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2102 if (z == NULL) {
2103 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2106 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2107 DNS_CLIENT_VERSION_W2K,
2108 r->in.pszNodeName,
2109 r->in.pAddRecord,
2110 r->in.pDeleteRecord);
2112 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2113 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord, NDR_IN, r);
2115 return ret;
2118 static WERROR dcesrv_DnssrvOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation2 *r)
2120 struct dnsserver_state *dsstate;
2121 struct dnsserver_zone *z = NULL;
2122 uint32_t request_filter = 0;
2123 WERROR ret;
2125 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2126 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2129 if (r->in.dwContext == 0) {
2130 if (r->in.pszZone != NULL) {
2131 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
2133 } else {
2134 request_filter = r->in.dwContext;
2137 if (r->in.pszZone == NULL) {
2138 ret = dnsserver_operate_server(dsstate, mem_ctx,
2139 r->in.pszOperation,
2140 r->in.dwClientVersion,
2141 r->in.dwTypeId,
2142 &r->in.pData);
2143 } else {
2144 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2145 if (z == NULL && request_filter == 0) {
2146 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2149 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
2150 request_filter,
2151 r->in.pszOperation,
2152 r->in.dwClientVersion,
2153 r->in.dwTypeId,
2154 &r->in.pData);
2157 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2158 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation2, NDR_IN, r);
2160 return ret;
2163 static WERROR dcesrv_DnssrvQuery2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery2 *r)
2165 struct dnsserver_state *dsstate;
2166 struct dnsserver_zone *z;
2167 WERROR ret;
2169 ZERO_STRUCTP(r->out.pdwTypeId);
2170 ZERO_STRUCTP(r->out.ppData);
2172 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2173 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2176 if (r->in.pszZone == NULL) {
2177 /* FIXME: DNS Server Configuration Access Control List */
2178 ret = dnsserver_query_server(dsstate, mem_ctx,
2179 r->in.pszOperation,
2180 r->in.dwClientVersion,
2181 r->out.pdwTypeId,
2182 r->out.ppData);
2183 } else {
2184 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2185 if (z == NULL) {
2186 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2189 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
2190 r->in.pszOperation,
2191 r->in.dwClientVersion,
2192 r->out.pdwTypeId,
2193 r->out.ppData);
2196 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2197 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery2, NDR_IN, r);
2199 return ret;
2202 static WERROR dcesrv_DnssrvComplexOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation2 *r)
2204 struct dnsserver_state *dsstate;
2205 struct dnsserver_zone *z;
2206 WERROR ret;
2208 ZERO_STRUCTP(r->out.pdwTypeOut);
2209 ZERO_STRUCTP(r->out.ppDataOut);
2211 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2212 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2215 if (r->in.pszZone == NULL) {
2216 /* Server operation */
2217 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
2218 r->in.pszOperation,
2219 r->in.dwClientVersion,
2220 r->in.dwTypeIn,
2221 &r->in.pDataIn,
2222 r->out.pdwTypeOut,
2223 r->out.ppDataOut);
2224 } else {
2226 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2227 if (z == NULL) {
2228 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2231 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2232 r->in.pszOperation,
2233 r->in.dwClientVersion,
2234 r->in.dwTypeIn,
2235 &r->in.pDataIn,
2236 r->out.pdwTypeOut,
2237 r->out.ppDataOut);
2240 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2241 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation2, NDR_IN, r);
2243 return ret;
2246 static WERROR dcesrv_DnssrvEnumRecords2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords2 *r)
2248 struct dnsserver_state *dsstate;
2249 struct dnsserver_zone *z;
2250 WERROR ret;
2252 ZERO_STRUCTP(r->out.pdwBufferLength);
2253 ZERO_STRUCTP(r->out.pBuffer);
2255 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2256 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2259 if (r->in.pszZone == NULL) {
2260 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2263 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
2264 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
2265 r->in.dwClientVersion,
2266 r->in.pszNodeName,
2267 r->in.wRecordType,
2268 r->in.fSelectFlag,
2269 r->out.pdwBufferLength,
2270 r->out.pBuffer);
2271 } else {
2272 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2273 if (z == NULL) {
2274 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2277 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2278 r->in.dwClientVersion,
2279 r->in.pszNodeName,
2280 r->in.pszStartChild,
2281 r->in.wRecordType,
2282 r->in.fSelectFlag,
2283 r->in.pszFilterStart,
2284 r->in.pszFilterStop,
2285 r->out.pdwBufferLength,
2286 r->out.pBuffer);
2290 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2291 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords2, NDR_IN, r);
2293 return ret;
2296 static WERROR dcesrv_DnssrvUpdateRecord2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord2 *r)
2298 struct dnsserver_state *dsstate;
2299 struct dnsserver_zone *z;
2300 WERROR ret;
2302 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2303 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2306 if (r->in.pszZone == NULL) {
2307 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2310 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2311 if (z == NULL) {
2312 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2315 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2316 r->in.dwClientVersion,
2317 r->in.pszNodeName,
2318 r->in.pAddRecord,
2319 r->in.pDeleteRecord);
2321 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2322 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord2, NDR_IN, r);
2324 return ret;
2327 /* include the generated boilerplate */
2328 #include "librpc/gen_ndr/ndr_dnsserver_s.c"