2 Unix SMB/CIFS implementation.
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/>.
24 #include "rpc_server/dcerpc_server.h"
25 #include "dsdb/samdb/samdb.h"
26 #include "lib/util/dlinklist.h"
27 #include "librpc/gen_ndr/ndr_dnsserver.h"
28 #include "dns_server/dnsserver_common.h"
29 #include "dnsserver.h"
31 #define DCESRV_INTERFACE_DNSSERVER_BIND(call, iface) \
32 dcesrv_interface_dnsserver_bind(call, iface)
33 static NTSTATUS dcesrv_interface_dnsserver_bind(struct dcesrv_call_state *dce_call,
34 const struct dcesrv_interface *iface)
36 struct dcesrv_connection_context *context = dce_call->context;
37 return dcesrv_interface_bind_require_integrity(context, iface);
40 #define DNSSERVER_STATE_MAGIC 0xc9657ab4
41 struct dnsserver_state {
42 struct loadparm_context *lp_ctx;
43 struct ldb_context *samdb;
44 struct dnsserver_partition *partitions;
45 struct dnsserver_zone *zones;
47 struct dnsserver_serverinfo *serverinfo;
51 /* Utility functions */
53 static void dnsserver_reload_zones(struct dnsserver_state *dsstate)
55 struct dnsserver_partition *p;
56 struct dnsserver_zone *zones, *z, *znext, *zmatch;
57 struct dnsserver_zone *old_list, *new_list;
59 old_list = dsstate->zones;
62 for (p = dsstate->partitions; p; p = p->next) {
63 zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, p);
67 for (z = zones; z; ) {
69 zmatch = dnsserver_find_zone(old_list, z->name);
72 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
73 if (z->zoneinfo == NULL) {
76 DLIST_ADD_END(new_list, z);
78 dsstate->zones_count++;
82 DLIST_REMOVE(old_list, zmatch);
83 DLIST_ADD_END(new_list, zmatch);
89 if (new_list == NULL) {
94 for (z = old_list; z; ) {
96 z->partition->zones_count--;
97 dsstate->zones_count--;
102 dsstate->zones = new_list;
106 static struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_call)
108 struct auth_session_info *session_info =
109 dcesrv_call_session_info(dce_call);
110 struct dnsserver_state *dsstate;
111 struct dnsserver_zone *zones, *z, *znext;
112 struct dnsserver_partition *partitions, *p;
115 dsstate = dcesrv_iface_state_find_conn(dce_call,
116 DNSSERVER_STATE_MAGIC,
117 struct dnsserver_state);
118 if (dsstate != NULL) {
122 dsstate = talloc_zero(dce_call, struct dnsserver_state);
123 if (dsstate == NULL) {
127 dsstate->lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
129 /* FIXME: create correct auth_session_info for connecting user */
130 dsstate->samdb = samdb_connect(dsstate,
134 dce_call->conn->remote_address,
136 if (dsstate->samdb == NULL) {
137 DEBUG(0,("dnsserver: Failed to open samdb"));
141 /* Initialize server info */
142 dsstate->serverinfo = dnsserver_init_serverinfo(dsstate,
145 if (dsstate->serverinfo == NULL) {
149 /* Search for DNS partitions */
150 partitions = dnsserver_db_enumerate_partitions(dsstate, dsstate->serverinfo, dsstate->samdb);
151 if (partitions == NULL) {
154 dsstate->partitions = partitions;
156 /* Search for DNS zones */
157 for (p = partitions; p; p = p->next) {
158 zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, p);
162 for (z = zones; z; ) {
164 if (dnsserver_find_zone(dsstate->zones, z->name) == NULL) {
165 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
166 if (z->zoneinfo == NULL) {
169 DLIST_ADD_END(dsstate->zones, z);
171 dsstate->zones_count++;
173 /* Ignore duplicate zone */
174 DEBUG(3,("dnsserver: Ignoring duplicate zone '%s' from '%s'",
175 z->name, ldb_dn_get_linearized(z->zone_dn)));
181 status = dcesrv_iface_state_store_conn(dce_call,
182 DNSSERVER_STATE_MAGIC,
184 if (!NT_STATUS_IS_OK(status)) {
191 talloc_free(dsstate);
197 /* dnsserver query functions */
199 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
200 static WERROR dnsserver_query_server(struct dnsserver_state *dsstate,
202 const char *operation,
203 const unsigned int client_version,
204 enum DNS_RPC_TYPEID *typeid,
205 union DNSSRV_RPC_UNION *r)
207 uint8_t is_integer, is_addresses, is_string, is_wstring, is_stringlist;
208 uint32_t answer_integer;
209 struct IP4_ARRAY *answer_iparray;
210 struct DNS_ADDR_ARRAY *answer_addrarray;
212 struct DNS_RPC_UTF8_STRING_LIST *answer_stringlist;
213 struct dnsserver_serverinfo *serverinfo;
215 serverinfo = dsstate->serverinfo;
217 if (strcasecmp(operation, "ServerInfo") == 0) {
218 if (client_version == DNS_CLIENT_VERSION_W2K) {
219 *typeid = DNSSRV_TYPEID_SERVER_INFO_W2K;
220 r->ServerInfoW2K = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_W2K);
222 r->ServerInfoW2K->dwVersion = serverinfo->dwVersion;
223 r->ServerInfoW2K->fBootMethod = serverinfo->fBootMethod;
224 r->ServerInfoW2K->fAdminConfigured = serverinfo->fAdminConfigured;
225 r->ServerInfoW2K->fAllowUpdate = serverinfo->fAllowUpdate;
226 r->ServerInfoW2K->fDsAvailable = serverinfo->fDsAvailable;
227 r->ServerInfoW2K->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
228 r->ServerInfoW2K->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
229 r->ServerInfoW2K->aipServerAddrs = dns_addr_array_to_ip4_array(mem_ctx,
230 serverinfo->aipServerAddrs);
231 r->ServerInfoW2K->aipListenAddrs = dns_addr_array_to_ip4_array(mem_ctx,
232 serverinfo->aipListenAddrs);
233 r->ServerInfoW2K->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
234 r->ServerInfoW2K->dwLogLevel = serverinfo->dwLogLevel;
235 r->ServerInfoW2K->dwDebugLevel = serverinfo->dwDebugLevel;
236 r->ServerInfoW2K->dwForwardTimeout = serverinfo->dwForwardTimeout;
237 r->ServerInfoW2K->dwRpcProtocol = serverinfo->dwRpcProtocol;
238 r->ServerInfoW2K->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
239 r->ServerInfoW2K->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
240 r->ServerInfoW2K->dwRecursionRetry = serverinfo->dwRecursionRetry;
241 r->ServerInfoW2K->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
242 r->ServerInfoW2K->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
243 r->ServerInfoW2K->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
244 r->ServerInfoW2K->dwScavengingInterval = serverinfo->dwScavengingInterval;
245 r->ServerInfoW2K->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
246 r->ServerInfoW2K->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
247 r->ServerInfoW2K->fAutoReverseZones = serverinfo->fAutoReverseZones;
248 r->ServerInfoW2K->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
249 r->ServerInfoW2K->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
250 r->ServerInfoW2K->fForwardDelegations = serverinfo->fForwardDelegations;
251 r->ServerInfoW2K->fNoRecursion = serverinfo->fNoRecursion;
252 r->ServerInfoW2K->fSecureResponses = serverinfo->fSecureResponses;
253 r->ServerInfoW2K->fRoundRobin = serverinfo->fRoundRobin;
254 r->ServerInfoW2K->fLocalNetPriority = serverinfo->fLocalNetPriority;
255 r->ServerInfoW2K->fBindSecondaries = serverinfo->fBindSecondaries;
256 r->ServerInfoW2K->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
257 r->ServerInfoW2K->fStrictFileParsing = serverinfo->fStrictFileParsing;
258 r->ServerInfoW2K->fLooseWildcarding = serverinfo->fLooseWildcarding;
259 r->ServerInfoW2K->fDefaultAgingState = serverinfo->fDefaultAgingState;
261 } else if (client_version == DNS_CLIENT_VERSION_DOTNET) {
262 *typeid = DNSSRV_TYPEID_SERVER_INFO_DOTNET;
263 r->ServerInfoDotNet = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_DOTNET);
265 r->ServerInfoDotNet->dwRpcStructureVersion = 0x01;
266 r->ServerInfoDotNet->dwVersion = serverinfo->dwVersion;
267 r->ServerInfoDotNet->fBootMethod = serverinfo->fBootMethod;
268 r->ServerInfoDotNet->fAdminConfigured = serverinfo->fAdminConfigured;
269 r->ServerInfoDotNet->fAllowUpdate = serverinfo->fAllowUpdate;
270 r->ServerInfoDotNet->fDsAvailable = serverinfo->fDsAvailable;
271 r->ServerInfoDotNet->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
272 r->ServerInfoDotNet->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
273 r->ServerInfoDotNet->aipServerAddrs = dns_addr_array_to_ip4_array(mem_ctx,
274 serverinfo->aipServerAddrs);
275 r->ServerInfoDotNet->aipListenAddrs = dns_addr_array_to_ip4_array(mem_ctx,
276 serverinfo->aipListenAddrs);
277 r->ServerInfoDotNet->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
278 r->ServerInfoDotNet->aipLogFilter = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
279 r->ServerInfoDotNet->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
280 r->ServerInfoDotNet->pszDomainName = talloc_strdup(mem_ctx, serverinfo->pszDomainName);
281 r->ServerInfoDotNet->pszForestName = talloc_strdup(mem_ctx, serverinfo->pszForestName);
282 r->ServerInfoDotNet->pszDomainDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszDomainDirectoryPartition);
283 r->ServerInfoDotNet->pszForestDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszForestDirectoryPartition);
284 r->ServerInfoDotNet->dwLogLevel = serverinfo->dwLogLevel;
285 r->ServerInfoDotNet->dwDebugLevel = serverinfo->dwDebugLevel;
286 r->ServerInfoDotNet->dwForwardTimeout = serverinfo->dwForwardTimeout;
287 r->ServerInfoDotNet->dwRpcProtocol = serverinfo->dwRpcProtocol;
288 r->ServerInfoDotNet->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
289 r->ServerInfoDotNet->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
290 r->ServerInfoDotNet->dwRecursionRetry = serverinfo->dwRecursionRetry;
291 r->ServerInfoDotNet->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
292 r->ServerInfoDotNet->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
293 r->ServerInfoDotNet->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
294 r->ServerInfoDotNet->dwLocalNetPriorityNetMask = serverinfo->dwLocalNetPriorityNetMask;
295 r->ServerInfoDotNet->dwScavengingInterval = serverinfo->dwScavengingInterval;
296 r->ServerInfoDotNet->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
297 r->ServerInfoDotNet->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
298 r->ServerInfoDotNet->dwLastScavengeTime = serverinfo->dwLastScavengeTime;
299 r->ServerInfoDotNet->dwEventLogLevel = serverinfo->dwEventLogLevel;
300 r->ServerInfoDotNet->dwLogFileMaxSize = serverinfo->dwLogFileMaxSize;
301 r->ServerInfoDotNet->dwDsForestVersion = serverinfo->dwDsForestVersion;
302 r->ServerInfoDotNet->dwDsDomainVersion = serverinfo->dwDsDomainVersion;
303 r->ServerInfoDotNet->dwDsDsaVersion = serverinfo->dwDsDsaVersion;
304 r->ServerInfoDotNet->fAutoReverseZones = serverinfo->fAutoReverseZones;
305 r->ServerInfoDotNet->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
306 r->ServerInfoDotNet->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
307 r->ServerInfoDotNet->fForwardDelegations = serverinfo->fForwardDelegations;
308 r->ServerInfoDotNet->fNoRecursion = serverinfo->fNoRecursion;
309 r->ServerInfoDotNet->fSecureResponses = serverinfo->fSecureResponses;
310 r->ServerInfoDotNet->fRoundRobin = serverinfo->fRoundRobin;
311 r->ServerInfoDotNet->fLocalNetPriority = serverinfo->fLocalNetPriority;
312 r->ServerInfoDotNet->fBindSecondaries = serverinfo->fBindSecondaries;
313 r->ServerInfoDotNet->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
314 r->ServerInfoDotNet->fStrictFileParsing = serverinfo->fStrictFileParsing;
315 r->ServerInfoDotNet->fLooseWildcarding = serverinfo->fLooseWildcarding;
316 r->ServerInfoDotNet->fDefaultAgingState = serverinfo->fDefaultAgingState;
318 } else if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
319 *typeid = DNSSRV_TYPEID_SERVER_INFO;
320 r->ServerInfo = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_LONGHORN);
322 r->ServerInfo->dwRpcStructureVersion = 0x02;
323 r->ServerInfo->dwVersion = serverinfo->dwVersion;
324 r->ServerInfo->fBootMethod = serverinfo->fBootMethod;
325 r->ServerInfo->fAdminConfigured = serverinfo->fAdminConfigured;
326 r->ServerInfo->fAllowUpdate = serverinfo->fAllowUpdate;
327 r->ServerInfo->fDsAvailable = serverinfo->fDsAvailable;
328 r->ServerInfo->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
329 r->ServerInfo->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
330 r->ServerInfo->aipServerAddrs = serverinfo->aipServerAddrs;
331 r->ServerInfo->aipListenAddrs = serverinfo->aipListenAddrs;
332 r->ServerInfo->aipForwarders = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders);
333 r->ServerInfo->aipLogFilter = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter);
334 r->ServerInfo->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
335 r->ServerInfo->pszDomainName = talloc_strdup(mem_ctx, serverinfo->pszDomainName);
336 r->ServerInfo->pszForestName = talloc_strdup(mem_ctx, serverinfo->pszForestName);
337 r->ServerInfo->pszDomainDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszDomainDirectoryPartition);
338 r->ServerInfo->pszForestDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszForestDirectoryPartition);
339 r->ServerInfo->dwLogLevel = serverinfo->dwLogLevel;
340 r->ServerInfo->dwDebugLevel = serverinfo->dwDebugLevel;
341 r->ServerInfo->dwForwardTimeout = serverinfo->dwForwardTimeout;
342 r->ServerInfo->dwRpcProtocol = serverinfo->dwRpcProtocol;
343 r->ServerInfo->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
344 r->ServerInfo->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
345 r->ServerInfo->dwRecursionRetry = serverinfo->dwRecursionRetry;
346 r->ServerInfo->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
347 r->ServerInfo->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
348 r->ServerInfo->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
349 r->ServerInfo->dwLocalNetPriorityNetMask = serverinfo->dwLocalNetPriorityNetMask;
350 r->ServerInfo->dwScavengingInterval = serverinfo->dwScavengingInterval;
351 r->ServerInfo->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
352 r->ServerInfo->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
353 r->ServerInfo->dwLastScavengeTime = serverinfo->dwLastScavengeTime;
354 r->ServerInfo->dwEventLogLevel = serverinfo->dwEventLogLevel;
355 r->ServerInfo->dwLogFileMaxSize = serverinfo->dwLogFileMaxSize;
356 r->ServerInfo->dwDsForestVersion = serverinfo->dwDsForestVersion;
357 r->ServerInfo->dwDsDomainVersion = serverinfo->dwDsDomainVersion;
358 r->ServerInfo->dwDsDsaVersion = serverinfo->dwDsDsaVersion;
359 r->ServerInfo->fReadOnlyDC = serverinfo->fReadOnlyDC;
360 r->ServerInfo->fAutoReverseZones = serverinfo->fAutoReverseZones;
361 r->ServerInfo->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
362 r->ServerInfo->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
363 r->ServerInfo->fForwardDelegations = serverinfo->fForwardDelegations;
364 r->ServerInfo->fNoRecursion = serverinfo->fNoRecursion;
365 r->ServerInfo->fSecureResponses = serverinfo->fSecureResponses;
366 r->ServerInfo->fRoundRobin = serverinfo->fRoundRobin;
367 r->ServerInfo->fLocalNetPriority = serverinfo->fLocalNetPriority;
368 r->ServerInfo->fBindSecondaries = serverinfo->fBindSecondaries;
369 r->ServerInfo->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
370 r->ServerInfo->fStrictFileParsing = serverinfo->fStrictFileParsing;
371 r->ServerInfo->fLooseWildcarding = serverinfo->fLooseWildcarding;
372 r->ServerInfo->fDefaultAgingState = serverinfo->fDefaultAgingState;
379 if (strcasecmp(operation, "AddressAnswerLimit") == 0) {
380 answer_integer = serverinfo->cAddressAnswerLimit;
382 } else if (strcasecmp(operation, "AdminConfigured") == 0) {
383 answer_integer = serverinfo->fAdminConfigured;
385 } else if (strcasecmp(operation, "AllowCNAMEAtNS") == 0) {
388 } else if (strcasecmp(operation, "AllowUpdate") == 0) {
389 answer_integer = serverinfo->fAllowUpdate;
391 } else if (strcasecmp(operation, "AutoCacheUpdate") == 0) {
392 answer_integer = serverinfo->fAutoCacheUpdate;
394 } else if (strcasecmp(operation, "AutoConfigFileZones") == 0) {
397 } else if (strcasecmp(operation, "BindSecondaries") == 0) {
398 answer_integer = serverinfo->fBindSecondaries;
400 } else if (strcasecmp(operation, "BootMethod") == 0) {
401 answer_integer = serverinfo->fBootMethod;
403 } else if (strcasecmp(operation, "DebugLevel") == 0) {
404 answer_integer = serverinfo->dwDebugLevel;
406 } else if (strcasecmp(operation, "DefaultAgingState") == 0) {
407 answer_integer = serverinfo->fDefaultAgingState;
409 } else if (strcasecmp(operation, "DefaultNoRefreshInterval") == 0) {
410 answer_integer = serverinfo->dwDefaultNoRefreshInterval;
412 } else if (strcasecmp(operation, "DefaultRefreshInterval") == 0) {
413 answer_integer = serverinfo->dwDefaultRefreshInterval;
415 } else if (strcasecmp(operation, "DeleteOutsideGlue") == 0) {
418 } else if (strcasecmp(operation, "DisjointNets") == 0) {
421 } else if (strcasecmp(operation, "DsLazyUpdateInterval") == 0) {
422 answer_integer = 3; /* seconds */
424 } else if (strcasecmp(operation, "DsPollingInterval") == 0) {
425 answer_integer = serverinfo->dwDsPollingInterval;
427 } else if (strcasecmp(operation, "DsTombstoneInterval") == 0) {
428 answer_integer = 0x00127500; /* 14 days */
430 } else if (strcasecmp(operation, "EnableRegistryBoot") == 0) {
433 } else if (strcasecmp(operation, "EventLogLevel") == 0) {
434 answer_integer = serverinfo->dwEventLogLevel;
436 } else if (strcasecmp(operation, "ForceSoaSerial") == 0) {
439 } else if (strcasecmp(operation, "ForceSaoRetry") == 0) {
442 } else if (strcasecmp(operation, "ForceSoaRefresh") == 0) {
445 } else if (strcasecmp(operation, "ForceSoaMinimumTtl") == 0) {
448 } else if (strcasecmp(operation, "ForwardDelegations") == 0) {
451 } else if (strcasecmp(operation, "ForwardingTimeout") == 0) {
452 answer_integer = serverinfo->dwForwardTimeout;
454 } else if (strcasecmp(operation, "IsSlave") == 0) {
457 } else if (strcasecmp(operation, "LocalNetPriority") == 0) {
458 answer_integer = serverinfo->fLocalNetPriority;
460 } else if (strcasecmp(operation, "LogFileMaxSize") == 0) {
461 answer_integer = serverinfo->dwLogFileMaxSize;
463 } else if (strcasecmp(operation, "LogLevel") == 0) {
464 answer_integer = serverinfo->dwLogLevel;
466 } else if (strcasecmp(operation, "LooseWildcarding") == 0) {
467 answer_integer = serverinfo->fLooseWildcarding;
469 } else if (strcasecmp(operation, "MaxCacheTtl") == 0) {
470 answer_integer = serverinfo->dwMaxCacheTtl;
472 } else if (strcasecmp(operation, "MaxNegativeCacheTtl") == 0) {
473 answer_integer = 0x00000384; /* 15 minutes */
475 } else if (strcasecmp(operation, "NameCheckFlag") == 0) {
476 answer_integer = serverinfo->dwNameCheckFlag;
478 } else if (strcasecmp(operation, "NoRecursion") == 0) {
479 answer_integer = serverinfo->fNoRecursion;
481 } else if (strcasecmp(operation, "NoUpdateDelegations") == 0) {
484 } else if (strcasecmp(operation, "PublishAutonet") == 0) {
487 } else if (strcasecmp(operation, "QuietRecvFaultInterval") == 0) {
490 } else if (strcasecmp(operation, "QuietRecvLogInterval") == 0) {
493 } else if (strcasecmp(operation, "RecursionRetry") == 0) {
494 answer_integer = serverinfo->dwRecursionRetry;
496 } else if (strcasecmp(operation, "RecursionTimeout") == 0) {
497 answer_integer = serverinfo->dwRecursionTimeout;
499 } else if (strcasecmp(operation, "ReloadException") == 0) {
502 } else if (strcasecmp(operation, "RoundRobin") == 0) {
503 answer_integer = serverinfo->fRoundRobin;
505 } else if (strcasecmp(operation, "RpcProtocol") == 0) {
506 answer_integer = serverinfo->dwRpcProtocol;
508 } else if (strcasecmp(operation, "SecureResponses") == 0) {
509 answer_integer = serverinfo->fSecureResponses;
511 } else if (strcasecmp(operation, "SendPort") == 0) {
514 } else if (strcasecmp(operation, "ScavengingInterval") == 0) {
515 answer_integer = serverinfo->dwScavengingInterval;
517 } else if (strcasecmp(operation, "SocketPoolSize") == 0) {
518 answer_integer = 0x000009C4;
520 } else if (strcasecmp(operation, "StrictFileParsing") == 0) {
521 answer_integer = serverinfo->fStrictFileParsing;
523 } else if (strcasecmp(operation, "SyncDnsZoneSerial") == 0) {
524 answer_integer = 2; /* ZONE_SERIAL_SYNC_XFER */
526 } else if (strcasecmp(operation, "UpdateOptions") == 0) {
527 answer_integer = 0x0000030F; /* DNS_DEFAULT_UPDATE_OPTIONS */
529 } else if (strcasecmp(operation, "UseSystemEvengLog") == 0) {
532 } else if (strcasecmp(operation, "Version") == 0) {
533 answer_integer = serverinfo->dwVersion;
535 } else if (strcasecmp(operation, "XfrConnectTimeout") == 0) {
536 answer_integer = 0x0000001E;
538 } else if (strcasecmp(operation, "WriteAuthorityNs") == 0) {
539 answer_integer = serverinfo->fWriteAuthorityNs;
541 } else if (strcasecmp(operation, "AdditionalRecursionTimeout") == 0) {
542 answer_integer = 0x00000004;
544 } else if (strcasecmp(operation, "AppendMsZoneTransferFlag") == 0) {
547 } else if (strcasecmp(operation, "AutoCreateDelegations") == 0) {
548 answer_integer = 0; /* DNS_ACD_DONT_CREATE */
550 } else if (strcasecmp(operation, "BreakOnAscFailure") == 0) {
553 } else if (strcasecmp(operation, "CacheEmptyAuthResponses") == 0) {
556 } else if (strcasecmp(operation, "DirectoryPartitionAutoEnlistInterval") == 0) {
557 answer_integer = 0x00015180; /* 1 day */
559 } else if (strcasecmp(operation, "DisableAutoReverseZones") == 0) {
560 answer_integer = ~serverinfo->fAutoReverseZones;
562 } else if (strcasecmp(operation, "EDnsCacheTimeout") == 0) {
563 answer_integer = 0x00000384; /* 15 minutes */
565 } else if (strcasecmp(operation, "EnableDirectoryPartitions") == 0) {
566 answer_integer = serverinfo->fDsAvailable;
568 } else if (strcasecmp(operation, "EnableDnsSec") == 0) {
571 } else if (strcasecmp(operation, "EnableEDnsProbes") == 0) {
574 } else if (strcasecmp(operation, "EnableEDnsReception") == 0) {
577 } else if (strcasecmp(operation, "EnableIPv6") == 0) {
580 } else if (strcasecmp(operation, "EnableIQueryResponseGeneration") == 0) {
583 } else if (strcasecmp(operation, "EnableSendErrorSuppression") == 0) {
586 } else if (strcasecmp(operation, "EnableUpdateForwarding") == 0) {
589 } else if (strcasecmp(operation, "EnableWinsR") == 0) {
592 } else if (strcasecmp(operation, "ForceDsaBehaviorVersion") == 0) {
593 answer_integer = serverinfo->dwDsDsaVersion;
595 } else if (strcasecmp(operation, "ForceDomainBehaviorVersion") == 0) {
596 answer_integer = serverinfo->dwDsDsaVersion;
598 } else if (strcasecmp(operation, "ForceForestBehaviorVersion") == 0) {
599 answer_integer = serverinfo->dwDsDsaVersion;
601 } else if (strcasecmp(operation, "HeapDebug") == 0) {
604 } else if (strcasecmp(operation, "LameDelegationTtl") == 0) {
605 answer_integer = 0; /* seconds */
607 } else if (strcasecmp(operation, "LocalNetPriorityNetMask") == 0) {
608 answer_integer = serverinfo->dwLocalNetPriorityNetMask;
610 } else if (strcasecmp(operation, "MaxCacheSize") == 0) {
613 } else if (strcasecmp(operation, "MaxResourceRecordsInNonSecureUpdate") == 0) {
614 answer_integer = 0x0000001E;
616 } else if (strcasecmp(operation, "OperationsLogLevel") == 0) {
619 } else if (strcasecmp(operation, "OperationsLogLevel2") == 0) {
622 } else if (strcasecmp(operation, "MaximumUdpPacketSize") == 0) {
623 answer_integer = 0x00004000; /* maximum possible */
625 } else if (strcasecmp(operation, "RecurseToInternetRootMask") == 0) {
628 } else if (strcasecmp(operation, "SelfTest") == 0) {
631 } else if (strcasecmp(operation, "SilentlyIgnoreCNameUpdateConflicts") == 0) {
634 } else if (strcasecmp(operation, "TcpReceivePacketSize") == 0) {
635 answer_integer = 0x00010000;
637 } else if (strcasecmp(operation, "XfrThrottleMultiplier") == 0) {
638 answer_integer = 0x0000000A;
640 } else if (strcasecmp(operation, "AllowMsdcsLookupRetry") == 0) {
643 } else if (strcasecmp(operation, "AllowReadOnlyZoneTransfer") == 0) {
646 } else if (strcasecmp(operation, "DsBackGroundLoadPaused") == 0) {
649 } else if (strcasecmp(operation, "DsMinimumBackgroundLoadThreads") == 0) {
652 } else if (strcasecmp(operation, "DsRemoteReplicationDelay") == 0) {
653 answer_integer = 0x0000001E; /* 30 seconds */
655 } else if (strcasecmp(operation, "EnableDuplicateQuerySuppresion") == 0) {
658 } else if (strcasecmp(operation, "EnableGlobalNamesSupport") == 0) {
661 } else if (strcasecmp(operation, "EnableVersionQuery") == 0) {
662 answer_integer = 1; /* DNS_VERSION_QUERY_FULL */
664 } else if (strcasecmp(operation, "EnableRsoForRodc") == 0) {
667 } else if (strcasecmp(operation, "ForceRODCMode") == 0) {
670 } else if (strcasecmp(operation, "GlobalNamesAlwaysQuerySrv") == 0) {
673 } else if (strcasecmp(operation, "GlobalNamesBlockUpdates") == 0) {
676 } else if (strcasecmp(operation, "GlobalNamesEnableEDnsProbes") == 0) {
679 } else if (strcasecmp(operation, "GlobalNamesPreferAAAA") == 0) {
682 } else if (strcasecmp(operation, "GlobalNamesQueryOrder") == 0) {
685 } else if (strcasecmp(operation, "GlobalNamesSendTimeout") == 0) {
686 answer_integer = 3; /* seconds */
688 } else if (strcasecmp(operation, "GlobalNamesServerQueryInterval") == 0) {
689 answer_integer = 0x00005460; /* 6 hours */
691 } else if (strcasecmp(operation, "RemoteIPv4RankBoost") == 0) {
694 } else if (strcasecmp(operation, "RemoteIPv6RankBoost") == 0) {
697 } else if (strcasecmp(operation, "MaximumRodcRsoAttemptsPerCycle") == 0) {
698 answer_integer = 0x00000064;
700 } else if (strcasecmp(operation, "MaximumRodcRsoQueueLength") == 0) {
701 answer_integer = 0x0000012C;
703 } else if (strcasecmp(operation, "EnableGlobalQueryBlockList") == 0) {
706 } else if (strcasecmp(operation, "OpenACLOnProxyUpdates") == 0) {
709 } else if (strcasecmp(operation, "CacheLockingPercent") == 0) {
710 answer_integer = 0x00000064;
714 if (is_integer == 1) {
715 *typeid = DNSSRV_TYPEID_DWORD;
716 r->Dword = answer_integer;
722 if (strcasecmp(operation, "Forwarders") == 0) {
723 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
724 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders);
726 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
729 } else if (strcasecmp(operation, "ListenAddresses") == 0) {
730 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
731 answer_addrarray = serverinfo->aipListenAddrs;
733 answer_iparray = dns_addr_array_to_ip4_array(mem_ctx, serverinfo->aipListenAddrs);
736 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
737 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
738 answer_addrarray = NULL;
740 answer_iparray = NULL;
743 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
744 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
745 answer_addrarray = NULL;
747 answer_iparray = NULL;
750 } else if (strcasecmp(operation, "LogIPFilterList") == 0) {
751 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
752 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter);
754 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
759 if (is_addresses == 1) {
760 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
761 *typeid = DNSSRV_TYPEID_ADDRARRAY;
762 r->AddrArray = answer_addrarray;
764 *typeid = DNSSRV_TYPEID_IPARRAY;
765 r->IpArray = answer_iparray;
770 is_string = is_wstring = 0;
772 if (strcasecmp(operation, "DomainDirectoryPartitionBaseName") == 0) {
773 answer_string = talloc_strdup(mem_ctx, "DomainDnsZones");
774 if (! answer_string) {
775 return WERR_OUTOFMEMORY;
778 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
779 answer_string = talloc_strdup(mem_ctx, "ForestDnsZones");
780 if (! answer_string) {
781 return WERR_OUTOFMEMORY;
784 } else if (strcasecmp(operation, "LogFilePath") == 0) {
785 answer_string = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
787 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
788 answer_string = NULL;
790 } else if (strcasecmp(operation, "DsBackgroundPauseName") == 0) {
791 answer_string = NULL;
793 } else if (strcasecmp(operation, "DsNotRoundRobinTypes") == 0) {
794 answer_string = NULL;
798 if (is_string == 1) {
799 *typeid = DNSSRV_TYPEID_LPSTR;
800 r->String = answer_string;
802 } else if (is_wstring == 1) {
803 *typeid = DNSSRV_TYPEID_LPWSTR;
804 r->WideString = answer_string;
810 if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
811 answer_stringlist = NULL;
813 } else if (strcasecmp(operation, "SocketPoolExcludedPortRanges") == 0) {
814 answer_stringlist = NULL;
818 if (is_stringlist == 1) {
819 *typeid = DNSSRV_TYPEID_UTF8_STRING_LIST;
820 r->Utf8StringList = answer_stringlist;
824 DEBUG(0,("dnsserver: Invalid server operation %s", operation));
825 return WERR_DNS_ERROR_INVALID_PROPERTY;
828 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
829 static WERROR dnsserver_query_zone(struct dnsserver_state *dsstate,
831 struct dnsserver_zone *z,
832 const char *operation,
833 const unsigned int client_version,
834 enum DNS_RPC_TYPEID *typeid,
835 union DNSSRV_RPC_UNION *r)
837 uint8_t is_integer, is_addresses, is_string;
838 uint32_t answer_integer;
839 struct IP4_ARRAY *answer_iparray;
840 struct DNS_ADDR_ARRAY *answer_addrarray;
842 struct dnsserver_zoneinfo *zoneinfo;
844 zoneinfo = z->zoneinfo;
846 if (strcasecmp(operation, "Zone") == 0) {
847 if (client_version == DNS_CLIENT_VERSION_W2K) {
848 *typeid = DNSSRV_TYPEID_ZONE_W2K;
849 r->ZoneW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
851 r->ZoneW2K->pszZoneName = talloc_strdup(mem_ctx, z->name);
852 r->ZoneW2K->Flags = zoneinfo->Flags;
853 r->ZoneW2K->ZoneType = zoneinfo->dwZoneType;
854 r->ZoneW2K->Version = zoneinfo->Version;
856 *typeid = DNSSRV_TYPEID_ZONE;
857 r->Zone = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
859 r->Zone->dwRpcStructureVersion = 0x01;
860 r->Zone->pszZoneName = talloc_strdup(mem_ctx, z->name);
861 r->Zone->Flags = zoneinfo->Flags;
862 r->Zone->ZoneType = zoneinfo->dwZoneType;
863 r->Zone->Version = zoneinfo->Version;
864 r->Zone->dwDpFlags = z->partition->dwDpFlags;
865 r->Zone->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
870 if (strcasecmp(operation, "ZoneInfo") == 0) {
871 if (client_version == DNS_CLIENT_VERSION_W2K) {
872 *typeid = DNSSRV_TYPEID_ZONE_INFO_W2K;
873 r->ZoneInfoW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_W2K);
875 r->ZoneInfoW2K->pszZoneName = talloc_strdup(mem_ctx, z->name);
876 r->ZoneInfoW2K->dwZoneType = zoneinfo->dwZoneType;
877 r->ZoneInfoW2K->fReverse = zoneinfo->fReverse;
878 r->ZoneInfoW2K->fAllowUpdate = zoneinfo->fAllowUpdate;
879 r->ZoneInfoW2K->fPaused = zoneinfo->fPaused;
880 r->ZoneInfoW2K->fShutdown = zoneinfo->fShutdown;
881 r->ZoneInfoW2K->fAutoCreated = zoneinfo->fAutoCreated;
882 r->ZoneInfoW2K->fUseDatabase = zoneinfo->fUseDatabase;
883 r->ZoneInfoW2K->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
884 r->ZoneInfoW2K->aipMasters = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
885 r->ZoneInfoW2K->fSecureSecondaries = zoneinfo->fSecureSecondaries;
886 r->ZoneInfoW2K->fNotifyLevel = zoneinfo->fNotifyLevel;
887 r->ZoneInfoW2K->aipSecondaries = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
888 r->ZoneInfoW2K->aipNotify = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
889 r->ZoneInfoW2K->fUseWins = zoneinfo->fUseWins;
890 r->ZoneInfoW2K->fUseNbstat = zoneinfo->fUseNbstat;
891 r->ZoneInfoW2K->fAging = zoneinfo->fAging;
892 r->ZoneInfoW2K->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
893 r->ZoneInfoW2K->dwRefreshInterval = zoneinfo->dwRefreshInterval;
894 r->ZoneInfoW2K->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
895 r->ZoneInfoW2K->aipScavengeServers = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
897 } else if (client_version == DNS_CLIENT_VERSION_DOTNET) {
898 *typeid = DNSSRV_TYPEID_ZONE_INFO_DOTNET;
899 r->ZoneInfoDotNet = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_DOTNET);
901 r->ZoneInfoDotNet->dwRpcStructureVersion = 0x01;
902 r->ZoneInfoDotNet->pszZoneName = talloc_strdup(mem_ctx, z->name);
903 r->ZoneInfoDotNet->dwZoneType = zoneinfo->dwZoneType;
904 r->ZoneInfoDotNet->fReverse = zoneinfo->fReverse;
905 r->ZoneInfoDotNet->fAllowUpdate = zoneinfo->fAllowUpdate;
906 r->ZoneInfoDotNet->fPaused = zoneinfo->fPaused;
907 r->ZoneInfoDotNet->fShutdown = zoneinfo->fShutdown;
908 r->ZoneInfoDotNet->fAutoCreated = zoneinfo->fAutoCreated;
909 r->ZoneInfoDotNet->fUseDatabase = zoneinfo->fUseDatabase;
910 r->ZoneInfoDotNet->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
911 r->ZoneInfoDotNet->aipMasters = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
912 r->ZoneInfoDotNet->fSecureSecondaries = zoneinfo->fSecureSecondaries;
913 r->ZoneInfoDotNet->fNotifyLevel = zoneinfo->fNotifyLevel;
914 r->ZoneInfoDotNet->aipSecondaries = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
915 r->ZoneInfoDotNet->aipNotify = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
916 r->ZoneInfoDotNet->fUseWins = zoneinfo->fUseWins;
917 r->ZoneInfoDotNet->fUseNbstat = zoneinfo->fUseNbstat;
918 r->ZoneInfoDotNet->fAging = zoneinfo->fAging;
919 r->ZoneInfoDotNet->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
920 r->ZoneInfoDotNet->dwRefreshInterval = zoneinfo->dwRefreshInterval;
921 r->ZoneInfoDotNet->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
922 r->ZoneInfoDotNet->aipScavengeServers = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
923 r->ZoneInfoDotNet->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
924 r->ZoneInfoDotNet->fForwarderSlave = zoneinfo->fForwarderSlave;
925 r->ZoneInfoDotNet->aipLocalMasters = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
926 r->ZoneInfoDotNet->dwDpFlags = z->partition->dwDpFlags;
927 r->ZoneInfoDotNet->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
928 r->ZoneInfoDotNet->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
929 r->ZoneInfoDotNet->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
930 r->ZoneInfoDotNet->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
933 *typeid = DNSSRV_TYPEID_ZONE_INFO;
934 r->ZoneInfo = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_LONGHORN);
936 r->ZoneInfo->dwRpcStructureVersion = 0x02;
937 r->ZoneInfo->pszZoneName = talloc_strdup(mem_ctx, z->name);
938 r->ZoneInfo->dwZoneType = zoneinfo->dwZoneType;
939 r->ZoneInfo->fReverse = zoneinfo->fReverse;
940 r->ZoneInfo->fAllowUpdate = zoneinfo->fAllowUpdate;
941 r->ZoneInfo->fPaused = zoneinfo->fPaused;
942 r->ZoneInfo->fShutdown = zoneinfo->fShutdown;
943 r->ZoneInfo->fAutoCreated = zoneinfo->fAutoCreated;
944 r->ZoneInfo->fUseDatabase = zoneinfo->fUseDatabase;
945 r->ZoneInfo->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
946 r->ZoneInfo->aipMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipMasters);
947 r->ZoneInfo->fSecureSecondaries = zoneinfo->fSecureSecondaries;
948 r->ZoneInfo->fNotifyLevel = zoneinfo->fNotifyLevel;
949 r->ZoneInfo->aipSecondaries = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipSecondaries);
950 r->ZoneInfo->aipNotify = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipNotify);
951 r->ZoneInfo->fUseWins = zoneinfo->fUseWins;
952 r->ZoneInfo->fUseNbstat = zoneinfo->fUseNbstat;
953 r->ZoneInfo->fAging = zoneinfo->fAging;
954 r->ZoneInfo->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
955 r->ZoneInfo->dwRefreshInterval = zoneinfo->dwRefreshInterval;
956 r->ZoneInfo->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
957 r->ZoneInfo->aipScavengeServers = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipScavengeServers);
958 r->ZoneInfo->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
959 r->ZoneInfo->fForwarderSlave = zoneinfo->fForwarderSlave;
960 r->ZoneInfo->aipLocalMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
961 r->ZoneInfo->dwDpFlags = z->partition->dwDpFlags;
962 r->ZoneInfo->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
963 r->ZoneInfo->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
964 r->ZoneInfo->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
965 r->ZoneInfo->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
967 r->ZoneInfo->fQueuedForBackgroundLoad = zoneinfo->fQueuedForBackgroundLoad;
968 r->ZoneInfo->fBackgroundLoadInProgress = zoneinfo->fBackgroundLoadInProgress;
969 r->ZoneInfo->fReadOnlyZone = zoneinfo->fReadOnlyZone;
970 r->ZoneInfo->dwLastXfrAttempt = zoneinfo->dwLastXfrAttempt;
971 r->ZoneInfo->dwLastXfrResult = zoneinfo->dwLastXfrResult;
979 if (strcasecmp(operation, "AllowUpdate") == 0) {
980 answer_integer = zoneinfo->fAllowUpdate;
982 } else if (strcasecmp(operation, "Secured") == 0) {
985 } else if (strcasecmp(operation, "DsIntegrated") == 0) {
986 answer_integer = zoneinfo->fUseDatabase;
988 } else if (strcasecmp(operation, "LogUpdates") == 0) {
991 } else if (strcasecmp(operation, "NoRefreshInterval") == 0) {
992 answer_integer = zoneinfo->dwNoRefreshInterval;
994 } else if (strcasecmp(operation, "NotifyLevel") == 0) {
995 answer_integer = zoneinfo->fNotifyLevel;
997 } else if (strcasecmp(operation, "RefreshInterval") == 0) {
998 answer_integer = zoneinfo->dwRefreshInterval;
1000 } else if (strcasecmp(operation, "SecureSecondaries") == 0) {
1001 answer_integer = zoneinfo->fSecureSecondaries;
1003 } else if (strcasecmp(operation, "Type") == 0) {
1004 answer_integer = zoneinfo->dwZoneType;
1006 } else if (strcasecmp(operation, "Aging") == 0) {
1007 answer_integer = zoneinfo->fAging;
1009 } else if (strcasecmp(operation, "ForwarderSlave") == 0) {
1010 answer_integer = zoneinfo->fForwarderSlave;
1012 } else if (strcasecmp(operation, "ForwarderTimeout") == 0) {
1013 answer_integer = zoneinfo->dwForwarderTimeout;
1015 } else if (strcasecmp(operation, "Unicode") == 0) {
1020 if (is_integer == 1) {
1021 *typeid = DNSSRV_TYPEID_DWORD;
1022 r->Dword = answer_integer;
1028 if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
1029 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1030 answer_addrarray = NULL;
1032 answer_iparray = NULL;
1035 } else if (strcasecmp(operation, "ScavengeServers") == 0) {
1036 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1037 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipScavengeServers);
1039 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
1042 } else if (strcasecmp(operation, "MasterServers") == 0) {
1043 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1044 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipMasters);
1046 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
1049 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
1050 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1051 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
1053 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
1056 } else if (strcasecmp(operation, "NotifyServers") == 0) {
1057 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1058 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipNotify);
1060 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
1063 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
1064 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1065 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipSecondaries);
1067 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
1072 if (is_addresses == 1) {
1073 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1074 *typeid = DNSSRV_TYPEID_ADDRARRAY;
1075 r->AddrArray = answer_addrarray;
1077 *typeid = DNSSRV_TYPEID_IPARRAY;
1078 r->IpArray = answer_iparray;
1085 if (strcasecmp(operation, "DatabaseFile") == 0) {
1086 answer_string = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
1088 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1089 answer_string = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
1091 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1092 answer_string = NULL;
1096 if (is_string == 1) {
1097 *typeid = DNSSRV_TYPEID_LPSTR;
1098 r->String = answer_string;
1102 DEBUG(0,("dnsserver: Invalid zone operation %s", operation));
1103 return WERR_DNS_ERROR_INVALID_PROPERTY;
1107 /* dnsserver operation functions */
1109 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
1110 static WERROR dnsserver_operate_server(struct dnsserver_state *dsstate,
1111 TALLOC_CTX *mem_ctx,
1112 const char *operation,
1113 const unsigned int client_version,
1114 enum DNS_RPC_TYPEID typeid,
1115 union DNSSRV_RPC_UNION *r)
1117 bool valid_operation = false;
1119 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1120 valid_operation = true;
1121 } else if (strcasecmp(operation, "Restart") == 0) {
1122 valid_operation = true;
1123 } else if (strcasecmp(operation, "ClearDebugLog") == 0) {
1124 valid_operation = true;
1125 } else if (strcasecmp(operation, "ClearCache") == 0) {
1126 valid_operation = true;
1127 } else if (strcasecmp(operation, "WriteDirtyZones") == 0) {
1128 valid_operation = true;
1129 } else if (strcasecmp(operation, "ZoneCreate") == 0) {
1130 struct dnsserver_zone *z, *z2;
1134 z = talloc_zero(mem_ctx, struct dnsserver_zone);
1135 W_ERROR_HAVE_NO_MEMORY(z);
1136 z->partition = talloc_zero(z, struct dnsserver_partition);
1137 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z->partition, z);
1138 z->zoneinfo = talloc_zero(z, struct dnsserver_zoneinfo);
1139 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z->zoneinfo, z);
1141 if (typeid == DNSSRV_TYPEID_ZONE_CREATE_W2K) {
1142 len = strlen(r->ZoneCreateW2K->pszZoneName);
1143 if (r->ZoneCreateW2K->pszZoneName[len-1] == '.') {
1146 z->name = talloc_strndup(z, r->ZoneCreateW2K->pszZoneName, len);
1147 z->zoneinfo->dwZoneType = r->ZoneCreateW2K->dwZoneType;
1148 z->zoneinfo->fAllowUpdate = r->ZoneCreateW2K->fAllowUpdate;
1149 z->zoneinfo->fAging = r->ZoneCreateW2K->fAging;
1150 z->zoneinfo->Flags = r->ZoneCreateW2K->dwFlags;
1151 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE_DOTNET) {
1152 len = strlen(r->ZoneCreateDotNet->pszZoneName);
1153 if (r->ZoneCreateDotNet->pszZoneName[len-1] == '.') {
1156 z->name = talloc_strndup(z, r->ZoneCreateDotNet->pszZoneName, len);
1157 z->zoneinfo->dwZoneType = r->ZoneCreateDotNet->dwZoneType;
1158 z->zoneinfo->fAllowUpdate = r->ZoneCreateDotNet->fAllowUpdate;
1159 z->zoneinfo->fAging = r->ZoneCreateDotNet->fAging;
1160 z->zoneinfo->Flags = r->ZoneCreateDotNet->dwFlags;
1161 z->partition->dwDpFlags = r->ZoneCreateDotNet->dwDpFlags;
1162 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE) {
1163 len = strlen(r->ZoneCreate->pszZoneName);
1164 if (r->ZoneCreate->pszZoneName[len-1] == '.') {
1167 z->name = talloc_strndup(z, r->ZoneCreate->pszZoneName, len);
1168 z->zoneinfo->dwZoneType = r->ZoneCreate->dwZoneType;
1169 z->zoneinfo->fAllowUpdate = r->ZoneCreate->fAllowUpdate;
1170 z->zoneinfo->fAging = r->ZoneCreate->fAging;
1171 z->zoneinfo->Flags = r->ZoneCreate->dwFlags;
1172 z->partition->dwDpFlags = r->ZoneCreate->dwDpFlags;
1175 return WERR_DNS_ERROR_INVALID_PROPERTY;
1178 z2 = dnsserver_find_zone(dsstate->zones, z->name);
1181 return WERR_DNS_ERROR_ZONE_ALREADY_EXISTS;
1184 status = dnsserver_db_create_zone(dsstate->samdb, dsstate->partitions, z,
1188 if (W_ERROR_IS_OK(status)) {
1189 dnsserver_reload_zones(dsstate);
1192 } else if (strcasecmp(operation, "ClearStatistics") == 0) {
1193 valid_operation = true;
1194 } else if (strcasecmp(operation, "EnlistDirectoryPartition") == 0) {
1195 valid_operation = true;
1196 } else if (strcasecmp(operation, "StartScavenging") == 0) {
1197 valid_operation = true;
1198 } else if (strcasecmp(operation, "AbortScavenging") == 0) {
1199 valid_operation = true;
1200 } else if (strcasecmp(operation, "AutoConfigure") == 0) {
1201 valid_operation = true;
1202 } else if (strcasecmp(operation, "ExportSettings") == 0) {
1203 valid_operation = true;
1204 } else if (strcasecmp(operation, "PrepareForDemotion") == 0) {
1205 valid_operation = true;
1206 } else if (strcasecmp(operation, "PrepareForUninstall") == 0) {
1207 valid_operation = true;
1208 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1209 valid_operation = true;
1210 } else if (strcasecmp(operation, "DeleteRecord") == 0) {
1211 valid_operation = true;
1212 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1213 valid_operation = true;
1214 } else if (strcasecmp(operation, "ListenAddresses") == 0) {
1215 valid_operation = true;
1216 } else if (strcasecmp(operation, "Forwarders") == 0) {
1217 valid_operation = true;
1218 } else if (strcasecmp(operation, "LogFilePath") == 0) {
1219 valid_operation = true;
1220 } else if (strcasecmp(operation, "LogIpFilterList") == 0) {
1221 valid_operation = true;
1222 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
1223 valid_operation = true;
1224 } else if (strcasecmp(operation, "DomainDirectoryPartitionBaseName") == 0) {
1225 valid_operation = true;
1226 } else if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
1227 valid_operation = true;
1228 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
1229 valid_operation = true;
1230 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
1231 valid_operation = true;
1232 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
1233 valid_operation = true;
1236 if (valid_operation) {
1237 DEBUG(0, ("dnsserver: server operation '%s' not implemented", operation));
1238 return WERR_CALL_NOT_IMPLEMENTED;
1241 DEBUG(0, ("dnsserver: invalid server operation '%s'", operation));
1242 return WERR_DNS_ERROR_INVALID_PROPERTY;
1245 static WERROR dnsserver_complex_operate_server(struct dnsserver_state *dsstate,
1246 TALLOC_CTX *mem_ctx,
1247 const char *operation,
1248 const unsigned int client_version,
1249 enum DNS_RPC_TYPEID typeid_in,
1250 union DNSSRV_RPC_UNION *rin,
1251 enum DNS_RPC_TYPEID *typeid_out,
1252 union DNSSRV_RPC_UNION *rout)
1254 int valid_operation = 0;
1255 struct dnsserver_zone *z, **zlist;
1257 bool found1, found2, found3, found4;
1260 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1261 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1262 return dnsserver_query_server(dsstate, mem_ctx,
1268 } else if (strcasecmp(operation, "EnumZones") == 0) {
1269 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1270 return WERR_DNS_ERROR_INVALID_PROPERTY;
1274 zlist = talloc_zero_array(mem_ctx, struct dnsserver_zone *, 0);
1275 for (z = dsstate->zones; z; z = z->next) {
1277 /* Match the flags in groups
1279 * Group1 : PRIMARY, SECONDARY, CACHE, AUTO
1280 * Group2 : FORWARD, REVERSE, FORWARDER, STUB
1281 * Group3 : DS, NON_DS, DOMAIN_DP, FOREST_DP
1282 * Group4 : CUSTOM_DP, LEGACY_DP
1287 if (rin->Dword & 0x0000000f) {
1288 if (rin->Dword & DNS_ZONE_REQUEST_PRIMARY) {
1289 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_PRIMARY) {
1293 if (rin->Dword & DNS_ZONE_REQUEST_SECONDARY) {
1294 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_SECONDARY) {
1298 if (rin->Dword & DNS_ZONE_REQUEST_CACHE) {
1299 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_CACHE) {
1303 if (rin->Dword & DNS_ZONE_REQUEST_AUTO) {
1304 if (z->zoneinfo->fAutoCreated
1305 || z->partition->dwDpFlags & DNS_DP_AUTOCREATED) {
1315 if (rin->Dword & 0x000000f0) {
1316 if (rin->Dword & DNS_ZONE_REQUEST_FORWARD) {
1317 if (!(z->zoneinfo->fReverse)) {
1321 if (rin->Dword & DNS_ZONE_REQUEST_REVERSE) {
1322 if (z->zoneinfo->fReverse) {
1326 if (rin->Dword & DNS_ZONE_REQUEST_FORWARDER) {
1327 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_FORWARDER) {
1331 if (rin->Dword & DNS_ZONE_REQUEST_STUB) {
1332 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_STUB) {
1342 if (rin->Dword & 0x00000f00) {
1343 if (rin->Dword & DNS_ZONE_REQUEST_DS) {
1344 if (z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED) {
1348 if (rin->Dword & DNS_ZONE_REQUEST_NON_DS) {
1349 if (!(z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED)) {
1353 if (rin->Dword & DNS_ZONE_REQUEST_DOMAIN_DP) {
1354 if (!(z->partition->dwDpFlags & DNS_DP_DOMAIN_DEFAULT)) {
1358 if (rin->Dword & DNS_ZONE_REQUEST_FOREST_DP) {
1359 if (!(z->partition->dwDpFlags & DNS_DP_FOREST_DEFAULT)) {
1368 if (rin->Dword & 0x0000f000) {
1374 if (found1 && found2 && found3 && found4) {
1375 zlist = talloc_realloc(mem_ctx, zlist, struct dnsserver_zone *, zcount+1);
1381 if (client_version == DNS_CLIENT_VERSION_W2K) {
1382 *typeid_out = DNSSRV_TYPEID_ZONE_LIST_W2K;
1383 rout->ZoneListW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_W2K);
1386 rout->ZoneListW2K->dwZoneCount = 0;
1387 rout->ZoneListW2K->ZoneArray = NULL;
1392 rout->ZoneListW2K->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_W2K *, zcount);
1393 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout->ZoneListW2K->ZoneArray, zlist);
1395 for (i=0; i<zcount; i++) {
1396 rout->ZoneListW2K->ZoneArray[i] = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
1398 rout->ZoneListW2K->ZoneArray[i]->pszZoneName = talloc_strdup(mem_ctx, zlist[i]->name);
1399 rout->ZoneListW2K->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
1400 rout->ZoneListW2K->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
1401 rout->ZoneListW2K->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
1403 rout->ZoneListW2K->dwZoneCount = zcount;
1406 *typeid_out = DNSSRV_TYPEID_ZONE_LIST;
1407 rout->ZoneList = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_DOTNET);
1410 rout->ZoneList->dwRpcStructureVersion = 1;
1411 rout->ZoneList->dwZoneCount = 0;
1412 rout->ZoneList->ZoneArray = NULL;
1417 rout->ZoneList->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_DOTNET *, zcount);
1418 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout->ZoneList->ZoneArray, zlist);
1420 for (i=0; i<zcount; i++) {
1421 rout->ZoneList->ZoneArray[i] = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
1423 rout->ZoneList->ZoneArray[i]->dwRpcStructureVersion = 1;
1424 rout->ZoneList->ZoneArray[i]->pszZoneName = talloc_strdup(mem_ctx, zlist[i]->name);
1425 rout->ZoneList->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
1426 rout->ZoneList->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
1427 rout->ZoneList->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
1428 rout->ZoneList->ZoneArray[i]->dwDpFlags = zlist[i]->partition->dwDpFlags;
1429 rout->ZoneList->ZoneArray[i]->pszDpFqdn = talloc_strdup(mem_ctx, zlist[i]->partition->pszDpFqdn);
1431 rout->ZoneList->dwRpcStructureVersion = 1;
1432 rout->ZoneList->dwZoneCount = zcount;
1436 } else if (strcasecmp(operation, "EnumZones2") == 0) {
1437 valid_operation = true;
1438 } else if (strcasecmp(operation, "EnumDirectoryPartitions") == 0) {
1439 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1440 return WERR_DNS_ERROR_INVALID_PROPERTY;
1443 *typeid_out = DNSSRV_TYPEID_DP_LIST;
1444 rout->DirectoryPartitionList = talloc_zero(mem_ctx, struct DNS_RPC_DP_LIST);
1446 if (rin->Dword != 0) {
1447 rout->DirectoryPartitionList->dwDpCount = 0;
1448 rout->DirectoryPartitionList->DpArray = NULL;
1450 struct DNS_RPC_DP_ENUM **dplist;
1451 struct dnsserver_partition *p;
1454 dplist = talloc_zero_array(mem_ctx, struct DNS_RPC_DP_ENUM *, pcount);
1455 W_ERROR_HAVE_NO_MEMORY(dplist);
1457 p = dsstate->partitions;
1458 for (i=0; i<pcount; i++) {
1459 dplist[i] = talloc_zero(dplist, struct DNS_RPC_DP_ENUM);
1461 dplist[i]->pszDpFqdn = talloc_strdup(mem_ctx, p->pszDpFqdn);
1462 dplist[i]->dwFlags = p->dwDpFlags;
1463 dplist[i]->dwZoneCount = p->zones_count;
1467 rout->DirectoryPartitionList->dwDpCount = pcount;
1468 rout->DirectoryPartitionList->DpArray = dplist;
1471 } else if (strcasecmp(operation, "DirectoryPartitionInfo") == 0) {
1472 struct dnsserver_partition *p;
1473 struct dnsserver_partition_info *partinfo;
1474 struct DNS_RPC_DP_INFO *dpinfo = NULL;
1476 if (typeid_in != DNSSRV_TYPEID_LPSTR) {
1477 return WERR_DNS_ERROR_INVALID_PROPERTY;
1480 *typeid_out = DNSSRV_TYPEID_DP_INFO;
1482 for (p = dsstate->partitions; p; p = p->next) {
1483 if (strcasecmp(p->pszDpFqdn, rin->String) == 0) {
1484 dpinfo = talloc_zero(mem_ctx, struct DNS_RPC_DP_INFO);
1485 W_ERROR_HAVE_NO_MEMORY(dpinfo);
1487 partinfo = dnsserver_db_partition_info(mem_ctx, dsstate->samdb, p);
1488 W_ERROR_HAVE_NO_MEMORY(partinfo);
1490 dpinfo->pszDpFqdn = talloc_strdup(dpinfo, p->pszDpFqdn);
1491 dpinfo->pszDpDn = talloc_strdup(dpinfo, ldb_dn_get_linearized(p->partition_dn));
1492 dpinfo->pszCrDn = talloc_steal(dpinfo, partinfo->pszCrDn);
1493 dpinfo->dwFlags = p->dwDpFlags;
1494 dpinfo->dwZoneCount = p->zones_count;
1495 dpinfo->dwState = partinfo->dwState;
1496 dpinfo->dwReplicaCount = partinfo->dwReplicaCount;
1497 if (partinfo->dwReplicaCount > 0) {
1498 dpinfo->ReplicaArray = talloc_steal(dpinfo,
1499 partinfo->ReplicaArray);
1501 dpinfo->ReplicaArray = NULL;
1507 if (dpinfo == NULL) {
1508 return WERR_DNS_ERROR_DP_DOES_NOT_EXIST;
1511 rout->DirectoryPartition = dpinfo;
1513 } else if (strcasecmp(operation, "Statistics") == 0) {
1514 valid_operation = true;
1515 } else if (strcasecmp(operation, "IpValidate") == 0) {
1516 valid_operation = true;
1519 if (valid_operation) {
1520 DEBUG(0, ("dnsserver: server complex operation '%s' not implemented", operation));
1521 return WERR_CALL_NOT_IMPLEMENTED;
1524 DEBUG(0, ("dnsserver: invalid server complex operation '%s'", operation));
1525 return WERR_DNS_ERROR_INVALID_PROPERTY;
1528 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
1529 static WERROR dnsserver_operate_zone(struct dnsserver_state *dsstate,
1530 TALLOC_CTX *mem_ctx,
1531 struct dnsserver_zone *z,
1532 unsigned int request_filter,
1533 const char *operation,
1534 const unsigned int client_version,
1535 enum DNS_RPC_TYPEID typeid,
1536 union DNSSRV_RPC_UNION *r)
1538 bool valid_operation = false;
1540 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1542 if (typeid != DNSSRV_TYPEID_NAME_AND_PARAM) {
1543 return WERR_DNS_ERROR_INVALID_PROPERTY;
1546 return dnsserver_db_do_reset_dword(dsstate->samdb, z,
1549 } else if (strcasecmp(operation, "ZoneTypeReset") == 0) {
1550 valid_operation = true;
1551 } else if (strcasecmp(operation, "PauseZone") == 0) {
1552 valid_operation = true;
1553 } else if (strcasecmp(operation, "ResumeZone") == 0) {
1554 valid_operation = true;
1555 } else if (strcasecmp(operation, "DeleteZone") == 0) {
1556 valid_operation = true;
1557 } else if (strcasecmp(operation, "ReloadZone") == 0) {
1558 valid_operation = true;
1559 } else if (strcasecmp(operation, "RefreshZone") == 0) {
1560 valid_operation = true;
1561 } else if (strcasecmp(operation, "ExpireZone") == 0) {
1562 valid_operation = true;
1563 } else if (strcasecmp(operation, "IncrementVersion") == 0) {
1564 valid_operation = true;
1565 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1566 valid_operation = true;
1567 } else if (strcasecmp(operation, "DeleteZoneFromDs") == 0) {
1570 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1572 status = dnsserver_db_delete_zone(dsstate->samdb, z);
1573 if (W_ERROR_IS_OK(status)) {
1574 dnsserver_reload_zones(dsstate);
1577 } else if (strcasecmp(operation, "UpdateZoneFromDs") == 0) {
1578 valid_operation = true;
1579 } else if (strcasecmp(operation, "ZoneExport") == 0) {
1580 valid_operation = true;
1581 } else if (strcasecmp(operation, "ZoneChangeDirectoryPartition") == 0) {
1582 valid_operation = true;
1583 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1584 valid_operation = true;
1585 } else if (strcasecmp(operation, "DeleteRecordSet") == 0) {
1586 valid_operation = true;
1587 } else if (strcasecmp(operation, "ForceAgingOnNode") == 0) {
1588 valid_operation = true;
1589 } else if (strcasecmp(operation, "DatabaseFile") == 0) {
1590 valid_operation = true;
1591 } else if (strcasecmp(operation, "MasterServers") == 0) {
1592 valid_operation = true;
1593 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
1594 valid_operation = true;
1595 } else if (strcasecmp(operation, "NotifyServers") == 0) {
1596 valid_operation = true;
1597 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
1598 valid_operation = true;
1599 } else if (strcasecmp(operation, "ScavengingServers") == 0) {
1600 valid_operation = true;
1601 } else if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
1602 valid_operation = true;
1603 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1604 valid_operation = true;
1605 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1606 valid_operation = true;
1609 if (valid_operation) {
1610 DEBUG(0, ("dnsserver: zone operation '%s' not implemented", operation));
1611 return WERR_CALL_NOT_IMPLEMENTED;
1614 DEBUG(0, ("dnsserver: invalid zone operation '%s'", operation));
1615 return WERR_DNS_ERROR_INVALID_PROPERTY;
1618 static WERROR dnsserver_complex_operate_zone(struct dnsserver_state *dsstate,
1619 TALLOC_CTX *mem_ctx,
1620 struct dnsserver_zone *z,
1621 const char *operation,
1622 const unsigned int client_version,
1623 enum DNS_RPC_TYPEID typeid_in,
1624 union DNSSRV_RPC_UNION *rin,
1625 enum DNS_RPC_TYPEID *typeid_out,
1626 union DNSSRV_RPC_UNION *rout)
1628 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1629 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1630 return dnsserver_query_zone(dsstate, mem_ctx, z,
1639 DEBUG(0,("dnsserver: Invalid zone operation %s", operation));
1640 return WERR_DNS_ERROR_INVALID_PROPERTY;
1643 /* dnsserver enumerate function */
1645 static WERROR dnsserver_enumerate_root_records(struct dnsserver_state *dsstate,
1646 TALLOC_CTX *mem_ctx,
1647 unsigned int client_version,
1648 const char *node_name,
1649 enum dns_record_type record_type,
1650 unsigned int select_flag,
1651 unsigned int *buffer_length,
1652 struct DNS_RPC_RECORDS_ARRAY **buffer)
1654 TALLOC_CTX *tmp_ctx;
1655 struct dnsserver_zone *z;
1656 const char * const attrs[] = { "name", "dnsRecord", NULL };
1657 struct ldb_result *res;
1658 struct DNS_RPC_RECORDS_ARRAY *recs;
1665 tmp_ctx = talloc_new(mem_ctx);
1666 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1668 z = dnsserver_find_zone(dsstate->zones, ".");
1670 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1673 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1674 LDB_SCOPE_ONELEVEL, attrs,
1675 "(&(objectClass=dnsNode)(name=@)(!(dNSTombstoned=TRUE)))");
1676 if (ret != LDB_SUCCESS) {
1677 talloc_free(tmp_ctx);
1678 return WERR_INTERNAL_DB_ERROR;
1680 if (res->count == 0) {
1681 talloc_free(tmp_ctx);
1682 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1685 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1686 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1691 for (i=0; i<res->count; i++) {
1692 status = dns_fill_records_array(tmp_ctx, NULL, record_type,
1694 res->msgs[i], 0, recs,
1695 &add_names, &add_count);
1696 if (!W_ERROR_IS_OK(status)) {
1697 talloc_free(tmp_ctx);
1703 /* Add any additional records */
1704 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1705 for (i=0; i<add_count; i++) {
1707 = ldb_binary_encode_string(tmp_ctx,
1709 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1710 LDB_SCOPE_ONELEVEL, attrs,
1711 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1713 if (ret != LDB_SUCCESS || res->count == 0) {
1718 len = strlen(add_names[i]);
1719 if (add_names[i][len-1] == '.') {
1720 rname = talloc_strdup(tmp_ctx, add_names[i]);
1722 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1724 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1726 res->msgs[0], 0, recs,
1733 talloc_free(tmp_ctx);
1735 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1742 static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
1743 TALLOC_CTX *mem_ctx,
1744 struct dnsserver_zone *z,
1745 unsigned int client_version,
1746 const char *node_name,
1747 const char *start_child,
1748 enum dns_record_type record_type,
1749 unsigned int select_flag,
1750 const char *filter_start,
1751 const char *filter_stop,
1752 unsigned int *buffer_length,
1753 struct DNS_RPC_RECORDS_ARRAY **buffer)
1755 TALLOC_CTX *tmp_ctx;
1757 const char * const attrs[] = { "name", "dnsRecord", NULL };
1758 struct ldb_result *res;
1759 struct DNS_RPC_RECORDS_ARRAY *recs;
1760 char **add_names = NULL;
1765 struct dns_tree *tree, *base, *node;
1767 tmp_ctx = talloc_new(mem_ctx);
1768 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1770 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1771 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1773 /* search all records under parent tree */
1774 if (strcasecmp(name, z->name) == 0) {
1775 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1776 LDB_SCOPE_ONELEVEL, attrs,
1777 "(&(objectClass=dnsNode)(!(dNSTombstoned=TRUE)))");
1780 = ldb_binary_encode_string(tmp_ctx, name);
1781 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1782 LDB_SCOPE_ONELEVEL, attrs,
1783 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s))(!(dNSTombstoned=TRUE)))",
1784 encoded_name, encoded_name);
1786 if (ret != LDB_SUCCESS) {
1787 talloc_free(tmp_ctx);
1788 return WERR_INTERNAL_DB_ERROR;
1790 if (res->count == 0) {
1791 talloc_free(tmp_ctx);
1792 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1795 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1796 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1798 /* Sort the names, so that the first record is the parent record */
1799 ldb_qsort(res->msgs, res->count, sizeof(struct ldb_message *), name,
1800 (ldb_qsort_cmp_fn_t)dns_name_compare);
1802 /* Build a tree of name components from dns name */
1803 if (strcasecmp(name, z->name) == 0) {
1804 tree = dns_build_tree(tmp_ctx, "@", res);
1806 tree = dns_build_tree(tmp_ctx, name, res);
1808 W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree, tmp_ctx);
1810 /* Find the parent record in the tree */
1812 while (base->level != -1) {
1813 base = base->children[0];
1816 /* Add the parent record with blank name */
1817 if (!(select_flag & DNS_RPC_VIEW_ONLY_CHILDREN)) {
1818 status = dns_fill_records_array(tmp_ctx, z, record_type,
1821 recs, &add_names, &add_count);
1822 if (!W_ERROR_IS_OK(status)) {
1823 talloc_free(tmp_ctx);
1828 /* Add all the children records */
1829 if (!(select_flag & DNS_RPC_VIEW_NO_CHILDREN)) {
1830 for (i=0; i<base->num_children; i++) {
1831 node = base->children[i];
1833 status = dns_fill_records_array(tmp_ctx, z, record_type,
1834 select_flag, node->name,
1835 node->data, node->num_children,
1836 recs, &add_names, &add_count);
1837 if (!W_ERROR_IS_OK(status)) {
1838 talloc_free(tmp_ctx);
1848 /* Add any additional records */
1849 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1850 for (i=0; i<add_count; i++) {
1851 struct dnsserver_zone *z2;
1853 /* Search all the available zones for additional name */
1854 for (z2 = dsstate->zones; z2; z2 = z2->next) {
1856 name = dns_split_node_name(tmp_ctx, add_names[i], z2->name);
1858 = ldb_binary_encode_string(tmp_ctx,
1860 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z2->zone_dn,
1861 LDB_SCOPE_ONELEVEL, attrs,
1862 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1865 if (ret != LDB_SUCCESS) {
1868 if (res->count == 1) {
1876 len = strlen(add_names[i]);
1877 if (add_names[i][len-1] == '.') {
1878 rname = talloc_strdup(tmp_ctx, add_names[i]);
1880 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1882 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1884 res->msgs[0], 0, recs,
1891 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1898 * Check str1 + '.' + str2 = name, for example:
1899 * ("dc0", "example.com", "dc0.example.com") = true
1901 static bool cname_self_reference(const char* node_name,
1902 const char* zone_name,
1903 struct DNS_RPC_NAME name) {
1904 size_t node_len, zone_len;
1906 if (node_name == NULL || zone_name == NULL) {
1910 node_len = strlen(node_name);
1911 zone_len = strlen(zone_name);
1913 if (node_len == 0 ||
1915 (name.len != node_len + zone_len + 1)) {
1919 if (strncmp(node_name, name.str, node_len) == 0 &&
1920 name.str[node_len] == '.' &&
1921 strncmp(zone_name, name.str + node_len + 1, zone_len) == 0) {
1928 /* dnsserver update function */
1930 static WERROR dnsserver_update_record(struct dnsserver_state *dsstate,
1931 TALLOC_CTX *mem_ctx,
1932 struct dnsserver_zone *z,
1933 unsigned int client_version,
1934 const char *node_name,
1935 struct DNS_RPC_RECORD_BUF *add_buf,
1936 struct DNS_RPC_RECORD_BUF *del_buf)
1938 TALLOC_CTX *tmp_ctx;
1942 tmp_ctx = talloc_new(mem_ctx);
1943 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1945 /* If node_name is @ or zone name, dns record is @ */
1946 if (strcmp(node_name, "@") == 0 ||
1947 strcmp(node_name, ".") == 0 ||
1948 strcasecmp(node_name, z->name) == 0) {
1949 name = talloc_strdup(tmp_ctx, "@");
1951 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1953 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1955 /* CNAMEs can't point to themselves */
1956 if (add_buf != NULL && add_buf->rec.wType == DNS_TYPE_CNAME) {
1957 if (cname_self_reference(node_name, z->name, add_buf->rec.data.name)) {
1958 return WERR_DNS_ERROR_CNAME_LOOP;
1962 if (add_buf != NULL) {
1963 if (del_buf == NULL) {
1965 status = dnsserver_db_add_record(tmp_ctx, dsstate->samdb,
1970 status = dnsserver_db_update_record(tmp_ctx, dsstate->samdb,
1976 if (del_buf == NULL) {
1977 /* Add empty node */
1978 status = dnsserver_db_add_empty_node(tmp_ctx, dsstate->samdb,
1982 status = dnsserver_db_delete_record(tmp_ctx, dsstate->samdb,
1988 talloc_free(tmp_ctx);
1993 /* dnsserver interface functions */
1995 static WERROR dcesrv_DnssrvOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation *r)
1997 struct dnsserver_state *dsstate;
1998 struct dnsserver_zone *z = NULL;
1999 uint32_t request_filter = 0;
2002 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2003 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2006 if (r->in.dwContext == 0) {
2007 if (r->in.pszZone != NULL) {
2008 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
2011 request_filter = r->in.dwContext;
2014 if (r->in.pszZone == NULL) {
2015 ret = dnsserver_operate_server(dsstate, mem_ctx,
2017 DNS_CLIENT_VERSION_W2K,
2021 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2022 if (z == NULL && request_filter == 0) {
2023 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2026 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
2029 DNS_CLIENT_VERSION_W2K,
2034 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2035 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation, NDR_IN, r);
2040 static WERROR dcesrv_DnssrvQuery(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery *r)
2042 struct dnsserver_state *dsstate;
2043 struct dnsserver_zone *z;
2046 ZERO_STRUCTP(r->out.pdwTypeId);
2047 ZERO_STRUCTP(r->out.ppData);
2049 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2050 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2053 if (r->in.pszZone == NULL) {
2054 /* FIXME: DNS Server Configuration Access Control List */
2055 ret = dnsserver_query_server(dsstate, mem_ctx,
2057 DNS_CLIENT_VERSION_W2K,
2061 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2063 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2066 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
2068 DNS_CLIENT_VERSION_W2K,
2073 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2074 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery, NDR_IN, r);
2079 static WERROR dcesrv_DnssrvComplexOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation *r)
2081 struct dnsserver_state *dsstate;
2082 struct dnsserver_zone *z;
2085 ZERO_STRUCTP(r->out.pdwTypeOut);
2086 ZERO_STRUCTP(r->out.ppDataOut);
2088 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2089 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2092 if (r->in.pszZone == NULL) {
2093 /* Server operation */
2094 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
2096 DNS_CLIENT_VERSION_W2K,
2102 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2104 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2107 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2109 DNS_CLIENT_VERSION_W2K,
2116 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2117 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation, NDR_IN, r);
2122 static WERROR dcesrv_DnssrvEnumRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords *r)
2124 struct dnsserver_state *dsstate;
2125 struct dnsserver_zone *z;
2128 ZERO_STRUCTP(r->out.pdwBufferLength);
2129 ZERO_STRUCTP(r->out.pBuffer);
2131 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2132 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2135 if (r->in.pszZone == NULL) {
2136 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2139 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
2140 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
2141 DNS_CLIENT_VERSION_W2K,
2145 r->out.pdwBufferLength,
2148 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2150 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2153 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2154 DNS_CLIENT_VERSION_W2K,
2156 r->in.pszStartChild,
2159 r->in.pszFilterStart,
2160 r->in.pszFilterStop,
2161 r->out.pdwBufferLength,
2165 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2166 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords, NDR_IN, r);
2171 static WERROR dcesrv_DnssrvUpdateRecord(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord *r)
2173 struct dnsserver_state *dsstate;
2174 struct dnsserver_zone *z;
2177 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2178 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2181 if (r->in.pszZone == NULL) {
2182 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2185 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2187 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2190 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2191 DNS_CLIENT_VERSION_W2K,
2194 r->in.pDeleteRecord);
2196 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2197 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord, NDR_IN, r);
2202 static WERROR dcesrv_DnssrvOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation2 *r)
2204 struct dnsserver_state *dsstate;
2205 struct dnsserver_zone *z = NULL;
2206 uint32_t request_filter = 0;
2209 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2210 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2213 if (r->in.dwContext == 0) {
2214 if (r->in.pszZone != NULL) {
2215 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
2218 request_filter = r->in.dwContext;
2221 if (r->in.pszZone == NULL) {
2222 ret = dnsserver_operate_server(dsstate, mem_ctx,
2224 r->in.dwClientVersion,
2228 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2229 if (z == NULL && request_filter == 0) {
2230 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2233 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
2236 r->in.dwClientVersion,
2241 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2242 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation2, NDR_IN, r);
2247 static WERROR dcesrv_DnssrvQuery2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery2 *r)
2249 struct dnsserver_state *dsstate;
2250 struct dnsserver_zone *z;
2253 ZERO_STRUCTP(r->out.pdwTypeId);
2254 ZERO_STRUCTP(r->out.ppData);
2256 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2257 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2260 if (r->in.pszZone == NULL) {
2261 /* FIXME: DNS Server Configuration Access Control List */
2262 ret = dnsserver_query_server(dsstate, mem_ctx,
2264 r->in.dwClientVersion,
2268 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2270 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2273 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
2275 r->in.dwClientVersion,
2280 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2281 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery2, NDR_IN, r);
2286 static WERROR dcesrv_DnssrvComplexOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation2 *r)
2288 struct dnsserver_state *dsstate;
2289 struct dnsserver_zone *z;
2292 ZERO_STRUCTP(r->out.pdwTypeOut);
2293 ZERO_STRUCTP(r->out.ppDataOut);
2295 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2296 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2299 if (r->in.pszZone == NULL) {
2300 /* Server operation */
2301 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
2303 r->in.dwClientVersion,
2310 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2312 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2315 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2317 r->in.dwClientVersion,
2324 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2325 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation2, NDR_IN, r);
2330 static WERROR dcesrv_DnssrvEnumRecords2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords2 *r)
2332 struct dnsserver_state *dsstate;
2333 struct dnsserver_zone *z;
2336 ZERO_STRUCTP(r->out.pdwBufferLength);
2337 ZERO_STRUCTP(r->out.pBuffer);
2339 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2340 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2343 if (r->in.pszZone == NULL) {
2344 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2347 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
2348 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
2349 r->in.dwClientVersion,
2353 r->out.pdwBufferLength,
2356 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2358 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2361 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2362 r->in.dwClientVersion,
2364 r->in.pszStartChild,
2367 r->in.pszFilterStart,
2368 r->in.pszFilterStop,
2369 r->out.pdwBufferLength,
2374 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2375 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords2, NDR_IN, r);
2380 static WERROR dcesrv_DnssrvUpdateRecord2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord2 *r)
2382 struct dnsserver_state *dsstate;
2383 struct dnsserver_zone *z;
2386 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2387 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2390 if (r->in.pszZone == NULL) {
2391 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2394 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2396 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2399 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2400 r->in.dwClientVersion,
2403 r->in.pDeleteRecord);
2405 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2406 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord2, NDR_IN, r);
2411 /* include the generated boilerplate */
2412 #include "librpc/gen_ndr/ndr_dnsserver_s.c"