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 return dcesrv_interface_bind_require_integrity(dce_call, iface);
39 struct dnsserver_state {
40 struct loadparm_context *lp_ctx;
41 struct ldb_context *samdb;
42 struct dnsserver_partition *partitions;
43 struct dnsserver_zone *zones;
45 struct dnsserver_serverinfo *serverinfo;
49 /* Utility functions */
51 static void dnsserver_reload_zones(struct dnsserver_state *dsstate)
53 struct dnsserver_partition *p;
54 struct dnsserver_zone *zones, *z, *znext, *zmatch;
55 struct dnsserver_zone *old_list, *new_list;
57 old_list = dsstate->zones;
60 for (p = dsstate->partitions; p; p = p->next) {
61 zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, p);
65 for (z = zones; z; ) {
67 zmatch = dnsserver_find_zone(old_list, z->name);
70 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
71 if (z->zoneinfo == NULL) {
74 DLIST_ADD_END(new_list, z);
76 dsstate->zones_count++;
80 DLIST_REMOVE(old_list, zmatch);
81 DLIST_ADD_END(new_list, zmatch);
87 if (new_list == NULL) {
92 for (z = old_list; z; ) {
94 z->partition->zones_count--;
95 dsstate->zones_count--;
100 dsstate->zones = new_list;
104 static struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_call)
106 struct auth_session_info *session_info =
107 dcesrv_call_session_info(dce_call);
108 struct dnsserver_state *dsstate;
109 struct dnsserver_zone *zones, *z, *znext;
110 struct dnsserver_partition *partitions, *p;
112 dsstate = talloc_get_type(dce_call->context->private_data, struct dnsserver_state);
113 if (dsstate != NULL) {
117 dsstate = talloc_zero(dce_call->context, struct dnsserver_state);
118 if (dsstate == NULL) {
122 dsstate->lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
124 /* FIXME: create correct auth_session_info for connecting user */
125 dsstate->samdb = samdb_connect(dsstate,
129 dce_call->conn->remote_address,
131 if (dsstate->samdb == NULL) {
132 DEBUG(0,("dnsserver: Failed to open samdb"));
136 /* Initialize server info */
137 dsstate->serverinfo = dnsserver_init_serverinfo(dsstate,
140 if (dsstate->serverinfo == NULL) {
144 /* Search for DNS partitions */
145 partitions = dnsserver_db_enumerate_partitions(dsstate, dsstate->serverinfo, dsstate->samdb);
146 if (partitions == NULL) {
149 dsstate->partitions = partitions;
151 /* Search for DNS zones */
152 for (p = partitions; p; p = p->next) {
153 zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, p);
157 for (z = zones; z; ) {
159 if (dnsserver_find_zone(dsstate->zones, z->name) == NULL) {
160 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
161 if (z->zoneinfo == NULL) {
164 DLIST_ADD_END(dsstate->zones, z);
166 dsstate->zones_count++;
168 /* Ignore duplicate zone */
169 DEBUG(3,("dnsserver: Ignoring duplicate zone '%s' from '%s'",
170 z->name, ldb_dn_get_linearized(z->zone_dn)));
176 dce_call->context->private_data = dsstate;
181 talloc_free(dsstate);
187 /* dnsserver query functions */
189 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
190 static WERROR dnsserver_query_server(struct dnsserver_state *dsstate,
192 const char *operation,
193 const unsigned int client_version,
194 enum DNS_RPC_TYPEID *typeid,
195 union DNSSRV_RPC_UNION *r)
197 uint8_t is_integer, is_addresses, is_string, is_wstring, is_stringlist;
198 uint32_t answer_integer;
199 struct IP4_ARRAY *answer_iparray;
200 struct DNS_ADDR_ARRAY *answer_addrarray;
202 struct DNS_RPC_UTF8_STRING_LIST *answer_stringlist;
203 struct dnsserver_serverinfo *serverinfo;
205 serverinfo = dsstate->serverinfo;
207 if (strcasecmp(operation, "ServerInfo") == 0) {
208 if (client_version == DNS_CLIENT_VERSION_W2K) {
209 *typeid = DNSSRV_TYPEID_SERVER_INFO_W2K;
210 r->ServerInfoW2K = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_W2K);
212 r->ServerInfoW2K->dwVersion = serverinfo->dwVersion;
213 r->ServerInfoW2K->fBootMethod = serverinfo->fBootMethod;
214 r->ServerInfoW2K->fAdminConfigured = serverinfo->fAdminConfigured;
215 r->ServerInfoW2K->fAllowUpdate = serverinfo->fAllowUpdate;
216 r->ServerInfoW2K->fDsAvailable = serverinfo->fDsAvailable;
217 r->ServerInfoW2K->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
218 r->ServerInfoW2K->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
219 r->ServerInfoW2K->aipServerAddrs = dns_addr_array_to_ip4_array(mem_ctx,
220 serverinfo->aipServerAddrs);
221 r->ServerInfoW2K->aipListenAddrs = dns_addr_array_to_ip4_array(mem_ctx,
222 serverinfo->aipListenAddrs);
223 r->ServerInfoW2K->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
224 r->ServerInfoW2K->dwLogLevel = serverinfo->dwLogLevel;
225 r->ServerInfoW2K->dwDebugLevel = serverinfo->dwDebugLevel;
226 r->ServerInfoW2K->dwForwardTimeout = serverinfo->dwForwardTimeout;
227 r->ServerInfoW2K->dwRpcProtocol = serverinfo->dwRpcProtocol;
228 r->ServerInfoW2K->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
229 r->ServerInfoW2K->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
230 r->ServerInfoW2K->dwRecursionRetry = serverinfo->dwRecursionRetry;
231 r->ServerInfoW2K->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
232 r->ServerInfoW2K->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
233 r->ServerInfoW2K->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
234 r->ServerInfoW2K->dwScavengingInterval = serverinfo->dwScavengingInterval;
235 r->ServerInfoW2K->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
236 r->ServerInfoW2K->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
237 r->ServerInfoW2K->fAutoReverseZones = serverinfo->fAutoReverseZones;
238 r->ServerInfoW2K->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
239 r->ServerInfoW2K->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
240 r->ServerInfoW2K->fForwardDelegations = serverinfo->fForwardDelegations;
241 r->ServerInfoW2K->fNoRecursion = serverinfo->fNoRecursion;
242 r->ServerInfoW2K->fSecureResponses = serverinfo->fSecureResponses;
243 r->ServerInfoW2K->fRoundRobin = serverinfo->fRoundRobin;
244 r->ServerInfoW2K->fLocalNetPriority = serverinfo->fLocalNetPriority;
245 r->ServerInfoW2K->fBindSecondaries = serverinfo->fBindSecondaries;
246 r->ServerInfoW2K->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
247 r->ServerInfoW2K->fStrictFileParsing = serverinfo->fStrictFileParsing;
248 r->ServerInfoW2K->fLooseWildcarding = serverinfo->fLooseWildcarding;
249 r->ServerInfoW2K->fDefaultAgingState = serverinfo->fDefaultAgingState;
251 } else if (client_version == DNS_CLIENT_VERSION_DOTNET) {
252 *typeid = DNSSRV_TYPEID_SERVER_INFO_DOTNET;
253 r->ServerInfoDotNet = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_DOTNET);
255 r->ServerInfoDotNet->dwRpcStructureVersion = 0x01;
256 r->ServerInfoDotNet->dwVersion = serverinfo->dwVersion;
257 r->ServerInfoDotNet->fBootMethod = serverinfo->fBootMethod;
258 r->ServerInfoDotNet->fAdminConfigured = serverinfo->fAdminConfigured;
259 r->ServerInfoDotNet->fAllowUpdate = serverinfo->fAllowUpdate;
260 r->ServerInfoDotNet->fDsAvailable = serverinfo->fDsAvailable;
261 r->ServerInfoDotNet->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
262 r->ServerInfoDotNet->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
263 r->ServerInfoDotNet->aipServerAddrs = dns_addr_array_to_ip4_array(mem_ctx,
264 serverinfo->aipServerAddrs);
265 r->ServerInfoDotNet->aipListenAddrs = dns_addr_array_to_ip4_array(mem_ctx,
266 serverinfo->aipListenAddrs);
267 r->ServerInfoDotNet->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
268 r->ServerInfoDotNet->aipLogFilter = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
269 r->ServerInfoDotNet->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
270 r->ServerInfoDotNet->pszDomainName = talloc_strdup(mem_ctx, serverinfo->pszDomainName);
271 r->ServerInfoDotNet->pszForestName = talloc_strdup(mem_ctx, serverinfo->pszForestName);
272 r->ServerInfoDotNet->pszDomainDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszDomainDirectoryPartition);
273 r->ServerInfoDotNet->pszForestDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszForestDirectoryPartition);
274 r->ServerInfoDotNet->dwLogLevel = serverinfo->dwLogLevel;
275 r->ServerInfoDotNet->dwDebugLevel = serverinfo->dwDebugLevel;
276 r->ServerInfoDotNet->dwForwardTimeout = serverinfo->dwForwardTimeout;
277 r->ServerInfoDotNet->dwRpcProtocol = serverinfo->dwRpcProtocol;
278 r->ServerInfoDotNet->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
279 r->ServerInfoDotNet->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
280 r->ServerInfoDotNet->dwRecursionRetry = serverinfo->dwRecursionRetry;
281 r->ServerInfoDotNet->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
282 r->ServerInfoDotNet->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
283 r->ServerInfoDotNet->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
284 r->ServerInfoDotNet->dwLocalNetPriorityNetMask = serverinfo->dwLocalNetPriorityNetMask;
285 r->ServerInfoDotNet->dwScavengingInterval = serverinfo->dwScavengingInterval;
286 r->ServerInfoDotNet->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
287 r->ServerInfoDotNet->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
288 r->ServerInfoDotNet->dwLastScavengeTime = serverinfo->dwLastScavengeTime;
289 r->ServerInfoDotNet->dwEventLogLevel = serverinfo->dwEventLogLevel;
290 r->ServerInfoDotNet->dwLogFileMaxSize = serverinfo->dwLogFileMaxSize;
291 r->ServerInfoDotNet->dwDsForestVersion = serverinfo->dwDsForestVersion;
292 r->ServerInfoDotNet->dwDsDomainVersion = serverinfo->dwDsDomainVersion;
293 r->ServerInfoDotNet->dwDsDsaVersion = serverinfo->dwDsDsaVersion;
294 r->ServerInfoDotNet->fAutoReverseZones = serverinfo->fAutoReverseZones;
295 r->ServerInfoDotNet->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
296 r->ServerInfoDotNet->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
297 r->ServerInfoDotNet->fForwardDelegations = serverinfo->fForwardDelegations;
298 r->ServerInfoDotNet->fNoRecursion = serverinfo->fNoRecursion;
299 r->ServerInfoDotNet->fSecureResponses = serverinfo->fSecureResponses;
300 r->ServerInfoDotNet->fRoundRobin = serverinfo->fRoundRobin;
301 r->ServerInfoDotNet->fLocalNetPriority = serverinfo->fLocalNetPriority;
302 r->ServerInfoDotNet->fBindSecondaries = serverinfo->fBindSecondaries;
303 r->ServerInfoDotNet->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
304 r->ServerInfoDotNet->fStrictFileParsing = serverinfo->fStrictFileParsing;
305 r->ServerInfoDotNet->fLooseWildcarding = serverinfo->fLooseWildcarding;
306 r->ServerInfoDotNet->fDefaultAgingState = serverinfo->fDefaultAgingState;
308 } else if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
309 *typeid = DNSSRV_TYPEID_SERVER_INFO;
310 r->ServerInfo = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_LONGHORN);
312 r->ServerInfo->dwRpcStructureVersion = 0x02;
313 r->ServerInfo->dwVersion = serverinfo->dwVersion;
314 r->ServerInfo->fBootMethod = serverinfo->fBootMethod;
315 r->ServerInfo->fAdminConfigured = serverinfo->fAdminConfigured;
316 r->ServerInfo->fAllowUpdate = serverinfo->fAllowUpdate;
317 r->ServerInfo->fDsAvailable = serverinfo->fDsAvailable;
318 r->ServerInfo->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
319 r->ServerInfo->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
320 r->ServerInfo->aipServerAddrs = serverinfo->aipServerAddrs;
321 r->ServerInfo->aipListenAddrs = serverinfo->aipListenAddrs;
322 r->ServerInfo->aipForwarders = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders);
323 r->ServerInfo->aipLogFilter = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter);
324 r->ServerInfo->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
325 r->ServerInfo->pszDomainName = talloc_strdup(mem_ctx, serverinfo->pszDomainName);
326 r->ServerInfo->pszForestName = talloc_strdup(mem_ctx, serverinfo->pszForestName);
327 r->ServerInfo->pszDomainDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszDomainDirectoryPartition);
328 r->ServerInfo->pszForestDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszForestDirectoryPartition);
329 r->ServerInfo->dwLogLevel = serverinfo->dwLogLevel;
330 r->ServerInfo->dwDebugLevel = serverinfo->dwDebugLevel;
331 r->ServerInfo->dwForwardTimeout = serverinfo->dwForwardTimeout;
332 r->ServerInfo->dwRpcProtocol = serverinfo->dwRpcProtocol;
333 r->ServerInfo->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
334 r->ServerInfo->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
335 r->ServerInfo->dwRecursionRetry = serverinfo->dwRecursionRetry;
336 r->ServerInfo->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
337 r->ServerInfo->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
338 r->ServerInfo->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
339 r->ServerInfo->dwLocalNetPriorityNetMask = serverinfo->dwLocalNetPriorityNetMask;
340 r->ServerInfo->dwScavengingInterval = serverinfo->dwScavengingInterval;
341 r->ServerInfo->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
342 r->ServerInfo->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
343 r->ServerInfo->dwLastScavengeTime = serverinfo->dwLastScavengeTime;
344 r->ServerInfo->dwEventLogLevel = serverinfo->dwEventLogLevel;
345 r->ServerInfo->dwLogFileMaxSize = serverinfo->dwLogFileMaxSize;
346 r->ServerInfo->dwDsForestVersion = serverinfo->dwDsForestVersion;
347 r->ServerInfo->dwDsDomainVersion = serverinfo->dwDsDomainVersion;
348 r->ServerInfo->dwDsDsaVersion = serverinfo->dwDsDsaVersion;
349 r->ServerInfo->fReadOnlyDC = serverinfo->fReadOnlyDC;
350 r->ServerInfo->fAutoReverseZones = serverinfo->fAutoReverseZones;
351 r->ServerInfo->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
352 r->ServerInfo->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
353 r->ServerInfo->fForwardDelegations = serverinfo->fForwardDelegations;
354 r->ServerInfo->fNoRecursion = serverinfo->fNoRecursion;
355 r->ServerInfo->fSecureResponses = serverinfo->fSecureResponses;
356 r->ServerInfo->fRoundRobin = serverinfo->fRoundRobin;
357 r->ServerInfo->fLocalNetPriority = serverinfo->fLocalNetPriority;
358 r->ServerInfo->fBindSecondaries = serverinfo->fBindSecondaries;
359 r->ServerInfo->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
360 r->ServerInfo->fStrictFileParsing = serverinfo->fStrictFileParsing;
361 r->ServerInfo->fLooseWildcarding = serverinfo->fLooseWildcarding;
362 r->ServerInfo->fDefaultAgingState = serverinfo->fDefaultAgingState;
369 if (strcasecmp(operation, "AddressAnswerLimit") == 0) {
370 answer_integer = serverinfo->cAddressAnswerLimit;
372 } else if (strcasecmp(operation, "AdminConfigured") == 0) {
373 answer_integer = serverinfo->fAdminConfigured;
375 } else if (strcasecmp(operation, "AllowCNAMEAtNS") == 0) {
378 } else if (strcasecmp(operation, "AllowUpdate") == 0) {
379 answer_integer = serverinfo->fAllowUpdate;
381 } else if (strcasecmp(operation, "AutoCacheUpdate") == 0) {
382 answer_integer = serverinfo->fAutoCacheUpdate;
384 } else if (strcasecmp(operation, "AutoConfigFileZones") == 0) {
387 } else if (strcasecmp(operation, "BindSecondaries") == 0) {
388 answer_integer = serverinfo->fBindSecondaries;
390 } else if (strcasecmp(operation, "BootMethod") == 0) {
391 answer_integer = serverinfo->fBootMethod;
393 } else if (strcasecmp(operation, "DebugLevel") == 0) {
394 answer_integer = serverinfo->dwDebugLevel;
396 } else if (strcasecmp(operation, "DefaultAgingState") == 0) {
397 answer_integer = serverinfo->fDefaultAgingState;
399 } else if (strcasecmp(operation, "DefaultNoRefreshInterval") == 0) {
400 answer_integer = serverinfo->dwDefaultNoRefreshInterval;
402 } else if (strcasecmp(operation, "DefaultRefreshInterval") == 0) {
403 answer_integer = serverinfo->dwDefaultRefreshInterval;
405 } else if (strcasecmp(operation, "DeleteOutsideGlue") == 0) {
408 } else if (strcasecmp(operation, "DisjointNets") == 0) {
411 } else if (strcasecmp(operation, "DsLazyUpdateInterval") == 0) {
412 answer_integer = 3; /* seconds */
414 } else if (strcasecmp(operation, "DsPollingInterval") == 0) {
415 answer_integer = serverinfo->dwDsPollingInterval;
417 } else if (strcasecmp(operation, "DsTombstoneInterval") == 0) {
418 answer_integer = 0x00127500; /* 14 days */
420 } else if (strcasecmp(operation, "EnableRegistryBoot") == 0) {
423 } else if (strcasecmp(operation, "EventLogLevel") == 0) {
424 answer_integer = serverinfo->dwEventLogLevel;
426 } else if (strcasecmp(operation, "ForceSoaSerial") == 0) {
429 } else if (strcasecmp(operation, "ForceSaoRetry") == 0) {
432 } else if (strcasecmp(operation, "ForceSoaRefresh") == 0) {
435 } else if (strcasecmp(operation, "ForceSoaMinimumTtl") == 0) {
438 } else if (strcasecmp(operation, "ForwardDelegations") == 0) {
441 } else if (strcasecmp(operation, "ForwardingTimeout") == 0) {
442 answer_integer = serverinfo->dwForwardTimeout;
444 } else if (strcasecmp(operation, "IsSlave") == 0) {
447 } else if (strcasecmp(operation, "LocalNetPriority") == 0) {
448 answer_integer = serverinfo->fLocalNetPriority;
450 } else if (strcasecmp(operation, "LogFileMaxSize") == 0) {
451 answer_integer = serverinfo->dwLogFileMaxSize;
453 } else if (strcasecmp(operation, "LogLevel") == 0) {
454 answer_integer = serverinfo->dwLogLevel;
456 } else if (strcasecmp(operation, "LooseWildcarding") == 0) {
457 answer_integer = serverinfo->fLooseWildcarding;
459 } else if (strcasecmp(operation, "MaxCacheTtl") == 0) {
460 answer_integer = serverinfo->dwMaxCacheTtl;
462 } else if (strcasecmp(operation, "MaxNegativeCacheTtl") == 0) {
463 answer_integer = 0x00000384; /* 15 minutes */
465 } else if (strcasecmp(operation, "NameCheckFlag") == 0) {
466 answer_integer = serverinfo->dwNameCheckFlag;
468 } else if (strcasecmp(operation, "NoRecursion") == 0) {
469 answer_integer = serverinfo->fNoRecursion;
471 } else if (strcasecmp(operation, "NoUpdateDelegations") == 0) {
474 } else if (strcasecmp(operation, "PublishAutonet") == 0) {
477 } else if (strcasecmp(operation, "QuietRecvFaultInterval") == 0) {
480 } else if (strcasecmp(operation, "QuietRecvLogInterval") == 0) {
483 } else if (strcasecmp(operation, "RecursionRetry") == 0) {
484 answer_integer = serverinfo->dwRecursionRetry;
486 } else if (strcasecmp(operation, "RecursionTimeout") == 0) {
487 answer_integer = serverinfo->dwRecursionTimeout;
489 } else if (strcasecmp(operation, "ReloadException") == 0) {
492 } else if (strcasecmp(operation, "RoundRobin") == 0) {
493 answer_integer = serverinfo->fRoundRobin;
495 } else if (strcasecmp(operation, "RpcProtocol") == 0) {
496 answer_integer = serverinfo->dwRpcProtocol;
498 } else if (strcasecmp(operation, "SecureResponses") == 0) {
499 answer_integer = serverinfo->fSecureResponses;
501 } else if (strcasecmp(operation, "SendPort") == 0) {
504 } else if (strcasecmp(operation, "ScavengingInterval") == 0) {
505 answer_integer = serverinfo->dwScavengingInterval;
507 } else if (strcasecmp(operation, "SocketPoolSize") == 0) {
508 answer_integer = 0x000009C4;
510 } else if (strcasecmp(operation, "StrictFileParsing") == 0) {
511 answer_integer = serverinfo->fStrictFileParsing;
513 } else if (strcasecmp(operation, "SyncDnsZoneSerial") == 0) {
514 answer_integer = 2; /* ZONE_SERIAL_SYNC_XFER */
516 } else if (strcasecmp(operation, "UpdateOptions") == 0) {
517 answer_integer = 0x0000030F; /* DNS_DEFAULT_UPDATE_OPTIONS */
519 } else if (strcasecmp(operation, "UseSystemEvengLog") == 0) {
522 } else if (strcasecmp(operation, "Version") == 0) {
523 answer_integer = serverinfo->dwVersion;
525 } else if (strcasecmp(operation, "XfrConnectTimeout") == 0) {
526 answer_integer = 0x0000001E;
528 } else if (strcasecmp(operation, "WriteAuthorityNs") == 0) {
529 answer_integer = serverinfo->fWriteAuthorityNs;
531 } else if (strcasecmp(operation, "AdditionalRecursionTimeout") == 0) {
532 answer_integer = 0x00000004;
534 } else if (strcasecmp(operation, "AppendMsZoneTransferFlag") == 0) {
537 } else if (strcasecmp(operation, "AutoCreateDelegations") == 0) {
538 answer_integer = 0; /* DNS_ACD_DONT_CREATE */
540 } else if (strcasecmp(operation, "BreakOnAscFailure") == 0) {
543 } else if (strcasecmp(operation, "CacheEmptyAuthResponses") == 0) {
546 } else if (strcasecmp(operation, "DirectoryPartitionAutoEnlistInterval") == 0) {
547 answer_integer = 0x00015180; /* 1 day */
549 } else if (strcasecmp(operation, "DisableAutoReverseZones") == 0) {
550 answer_integer = ~serverinfo->fAutoReverseZones;
552 } else if (strcasecmp(operation, "EDnsCacheTimeout") == 0) {
553 answer_integer = 0x00000384; /* 15 minutes */
555 } else if (strcasecmp(operation, "EnableDirectoryPartitions") == 0) {
556 answer_integer = serverinfo->fDsAvailable;
558 } else if (strcasecmp(operation, "EnableDnsSec") == 0) {
561 } else if (strcasecmp(operation, "EnableEDnsProbes") == 0) {
564 } else if (strcasecmp(operation, "EnableEDnsReception") == 0) {
567 } else if (strcasecmp(operation, "EnableIPv6") == 0) {
570 } else if (strcasecmp(operation, "EnableIQueryResponseGeneration") == 0) {
573 } else if (strcasecmp(operation, "EnableSendErrorSuppression") == 0) {
576 } else if (strcasecmp(operation, "EnableUpdateForwarding") == 0) {
579 } else if (strcasecmp(operation, "EnableWinsR") == 0) {
582 } else if (strcasecmp(operation, "ForceDsaBehaviorVersion") == 0) {
583 answer_integer = serverinfo->dwDsDsaVersion;
585 } else if (strcasecmp(operation, "ForceDomainBehaviorVersion") == 0) {
586 answer_integer = serverinfo->dwDsDsaVersion;
588 } else if (strcasecmp(operation, "ForceForestBehaviorVersion") == 0) {
589 answer_integer = serverinfo->dwDsDsaVersion;
591 } else if (strcasecmp(operation, "HeapDebug") == 0) {
594 } else if (strcasecmp(operation, "LameDelegationTtl") == 0) {
595 answer_integer = 0; /* seconds */
597 } else if (strcasecmp(operation, "LocalNetPriorityNetMask") == 0) {
598 answer_integer = serverinfo->dwLocalNetPriorityNetMask;
600 } else if (strcasecmp(operation, "MaxCacheSize") == 0) {
603 } else if (strcasecmp(operation, "MaxResourceRecordsInNonSecureUpdate") == 0) {
604 answer_integer = 0x0000001E;
606 } else if (strcasecmp(operation, "OperationsLogLevel") == 0) {
609 } else if (strcasecmp(operation, "OperationsLogLevel2") == 0) {
612 } else if (strcasecmp(operation, "MaximumUdpPacketSize") == 0) {
613 answer_integer = 0x00004000; /* maximum possible */
615 } else if (strcasecmp(operation, "RecurseToInternetRootMask") == 0) {
618 } else if (strcasecmp(operation, "SelfTest") == 0) {
621 } else if (strcasecmp(operation, "SilentlyIgnoreCNameUpdateConflicts") == 0) {
624 } else if (strcasecmp(operation, "TcpReceivePacketSize") == 0) {
625 answer_integer = 0x00010000;
627 } else if (strcasecmp(operation, "XfrThrottleMultiplier") == 0) {
628 answer_integer = 0x0000000A;
630 } else if (strcasecmp(operation, "AllowMsdcsLookupRetry") == 0) {
633 } else if (strcasecmp(operation, "AllowReadOnlyZoneTransfer") == 0) {
636 } else if (strcasecmp(operation, "DsBackGroundLoadPaused") == 0) {
639 } else if (strcasecmp(operation, "DsMinimumBackgroundLoadThreads") == 0) {
642 } else if (strcasecmp(operation, "DsRemoteReplicationDelay") == 0) {
643 answer_integer = 0x0000001E; /* 30 seconds */
645 } else if (strcasecmp(operation, "EnableDuplicateQuerySuppresion") == 0) {
648 } else if (strcasecmp(operation, "EnableGlobalNamesSupport") == 0) {
651 } else if (strcasecmp(operation, "EnableVersionQuery") == 0) {
652 answer_integer = 1; /* DNS_VERSION_QUERY_FULL */
654 } else if (strcasecmp(operation, "EnableRsoForRodc") == 0) {
657 } else if (strcasecmp(operation, "ForceRODCMode") == 0) {
660 } else if (strcasecmp(operation, "GlobalNamesAlwaysQuerySrv") == 0) {
663 } else if (strcasecmp(operation, "GlobalNamesBlockUpdates") == 0) {
666 } else if (strcasecmp(operation, "GlobalNamesEnableEDnsProbes") == 0) {
669 } else if (strcasecmp(operation, "GlobalNamesPreferAAAA") == 0) {
672 } else if (strcasecmp(operation, "GlobalNamesQueryOrder") == 0) {
675 } else if (strcasecmp(operation, "GlobalNamesSendTimeout") == 0) {
676 answer_integer = 3; /* seconds */
678 } else if (strcasecmp(operation, "GlobalNamesServerQueryInterval") == 0) {
679 answer_integer = 0x00005460; /* 6 hours */
681 } else if (strcasecmp(operation, "RemoteIPv4RankBoost") == 0) {
684 } else if (strcasecmp(operation, "RemoteIPv6RankBoost") == 0) {
687 } else if (strcasecmp(operation, "MaximumRodcRsoAttemptsPerCycle") == 0) {
688 answer_integer = 0x00000064;
690 } else if (strcasecmp(operation, "MaximumRodcRsoQueueLength") == 0) {
691 answer_integer = 0x0000012C;
693 } else if (strcasecmp(operation, "EnableGlobalQueryBlockList") == 0) {
696 } else if (strcasecmp(operation, "OpenACLOnProxyUpdates") == 0) {
699 } else if (strcasecmp(operation, "CacheLockingPercent") == 0) {
700 answer_integer = 0x00000064;
704 if (is_integer == 1) {
705 *typeid = DNSSRV_TYPEID_DWORD;
706 r->Dword = answer_integer;
712 if (strcasecmp(operation, "Forwarders") == 0) {
713 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
714 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders);
716 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
719 } else if (strcasecmp(operation, "ListenAddresses") == 0) {
720 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
721 answer_addrarray = serverinfo->aipListenAddrs;
723 answer_iparray = dns_addr_array_to_ip4_array(mem_ctx, serverinfo->aipListenAddrs);
726 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
727 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
728 answer_addrarray = NULL;
730 answer_iparray = NULL;
733 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
734 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
735 answer_addrarray = NULL;
737 answer_iparray = NULL;
740 } else if (strcasecmp(operation, "LogIPFilterList") == 0) {
741 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
742 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter);
744 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
749 if (is_addresses == 1) {
750 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
751 *typeid = DNSSRV_TYPEID_ADDRARRAY;
752 r->AddrArray = answer_addrarray;
754 *typeid = DNSSRV_TYPEID_IPARRAY;
755 r->IpArray = answer_iparray;
760 is_string = is_wstring = 0;
762 if (strcasecmp(operation, "DomainDirectoryPartitionBaseName") == 0) {
763 answer_string = talloc_strdup(mem_ctx, "DomainDnsZones");
764 if (! answer_string) {
765 return WERR_OUTOFMEMORY;
768 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
769 answer_string = talloc_strdup(mem_ctx, "ForestDnsZones");
770 if (! answer_string) {
771 return WERR_OUTOFMEMORY;
774 } else if (strcasecmp(operation, "LogFilePath") == 0) {
775 answer_string = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
777 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
778 answer_string = NULL;
780 } else if (strcasecmp(operation, "DsBackgroundPauseName") == 0) {
781 answer_string = NULL;
783 } else if (strcasecmp(operation, "DsNotRoundRobinTypes") == 0) {
784 answer_string = NULL;
788 if (is_string == 1) {
789 *typeid = DNSSRV_TYPEID_LPSTR;
790 r->String = answer_string;
792 } else if (is_wstring == 1) {
793 *typeid = DNSSRV_TYPEID_LPWSTR;
794 r->WideString = answer_string;
800 if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
801 answer_stringlist = NULL;
803 } else if (strcasecmp(operation, "SocketPoolExcludedPortRanges") == 0) {
804 answer_stringlist = NULL;
808 if (is_stringlist == 1) {
809 *typeid = DNSSRV_TYPEID_UTF8_STRING_LIST;
810 r->Utf8StringList = answer_stringlist;
814 DEBUG(0,("dnsserver: Invalid server operation %s", operation));
815 return WERR_DNS_ERROR_INVALID_PROPERTY;
818 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
819 static WERROR dnsserver_query_zone(struct dnsserver_state *dsstate,
821 struct dnsserver_zone *z,
822 const char *operation,
823 const unsigned int client_version,
824 enum DNS_RPC_TYPEID *typeid,
825 union DNSSRV_RPC_UNION *r)
827 uint8_t is_integer, is_addresses, is_string;
828 uint32_t answer_integer;
829 struct IP4_ARRAY *answer_iparray;
830 struct DNS_ADDR_ARRAY *answer_addrarray;
832 struct dnsserver_zoneinfo *zoneinfo;
834 zoneinfo = z->zoneinfo;
836 if (strcasecmp(operation, "Zone") == 0) {
837 if (client_version == DNS_CLIENT_VERSION_W2K) {
838 *typeid = DNSSRV_TYPEID_ZONE_W2K;
839 r->ZoneW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
841 r->ZoneW2K->pszZoneName = talloc_strdup(mem_ctx, z->name);
842 r->ZoneW2K->Flags = zoneinfo->Flags;
843 r->ZoneW2K->ZoneType = zoneinfo->dwZoneType;
844 r->ZoneW2K->Version = zoneinfo->Version;
846 *typeid = DNSSRV_TYPEID_ZONE;
847 r->Zone = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
849 r->Zone->dwRpcStructureVersion = 0x01;
850 r->Zone->pszZoneName = talloc_strdup(mem_ctx, z->name);
851 r->Zone->Flags = zoneinfo->Flags;
852 r->Zone->ZoneType = zoneinfo->dwZoneType;
853 r->Zone->Version = zoneinfo->Version;
854 r->Zone->dwDpFlags = z->partition->dwDpFlags;
855 r->Zone->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
860 if (strcasecmp(operation, "ZoneInfo") == 0) {
861 if (client_version == DNS_CLIENT_VERSION_W2K) {
862 *typeid = DNSSRV_TYPEID_ZONE_INFO_W2K;
863 r->ZoneInfoW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_W2K);
865 r->ZoneInfoW2K->pszZoneName = talloc_strdup(mem_ctx, z->name);
866 r->ZoneInfoW2K->dwZoneType = zoneinfo->dwZoneType;
867 r->ZoneInfoW2K->fReverse = zoneinfo->fReverse;
868 r->ZoneInfoW2K->fAllowUpdate = zoneinfo->fAllowUpdate;
869 r->ZoneInfoW2K->fPaused = zoneinfo->fPaused;
870 r->ZoneInfoW2K->fShutdown = zoneinfo->fShutdown;
871 r->ZoneInfoW2K->fAutoCreated = zoneinfo->fAutoCreated;
872 r->ZoneInfoW2K->fUseDatabase = zoneinfo->fUseDatabase;
873 r->ZoneInfoW2K->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
874 r->ZoneInfoW2K->aipMasters = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
875 r->ZoneInfoW2K->fSecureSecondaries = zoneinfo->fSecureSecondaries;
876 r->ZoneInfoW2K->fNotifyLevel = zoneinfo->fNotifyLevel;
877 r->ZoneInfoW2K->aipSecondaries = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
878 r->ZoneInfoW2K->aipNotify = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
879 r->ZoneInfoW2K->fUseWins = zoneinfo->fUseWins;
880 r->ZoneInfoW2K->fUseNbstat = zoneinfo->fUseNbstat;
881 r->ZoneInfoW2K->fAging = zoneinfo->fAging;
882 r->ZoneInfoW2K->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
883 r->ZoneInfoW2K->dwRefreshInterval = zoneinfo->dwRefreshInterval;
884 r->ZoneInfoW2K->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
885 r->ZoneInfoW2K->aipScavengeServers = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
887 } else if (client_version == DNS_CLIENT_VERSION_DOTNET) {
888 *typeid = DNSSRV_TYPEID_ZONE_INFO_DOTNET;
889 r->ZoneInfoDotNet = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_DOTNET);
891 r->ZoneInfoDotNet->dwRpcStructureVersion = 0x01;
892 r->ZoneInfoDotNet->pszZoneName = talloc_strdup(mem_ctx, z->name);
893 r->ZoneInfoDotNet->dwZoneType = zoneinfo->dwZoneType;
894 r->ZoneInfoDotNet->fReverse = zoneinfo->fReverse;
895 r->ZoneInfoDotNet->fAllowUpdate = zoneinfo->fAllowUpdate;
896 r->ZoneInfoDotNet->fPaused = zoneinfo->fPaused;
897 r->ZoneInfoDotNet->fShutdown = zoneinfo->fShutdown;
898 r->ZoneInfoDotNet->fAutoCreated = zoneinfo->fAutoCreated;
899 r->ZoneInfoDotNet->fUseDatabase = zoneinfo->fUseDatabase;
900 r->ZoneInfoDotNet->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
901 r->ZoneInfoDotNet->aipMasters = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
902 r->ZoneInfoDotNet->fSecureSecondaries = zoneinfo->fSecureSecondaries;
903 r->ZoneInfoDotNet->fNotifyLevel = zoneinfo->fNotifyLevel;
904 r->ZoneInfoDotNet->aipSecondaries = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
905 r->ZoneInfoDotNet->aipNotify = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
906 r->ZoneInfoDotNet->fUseWins = zoneinfo->fUseWins;
907 r->ZoneInfoDotNet->fUseNbstat = zoneinfo->fUseNbstat;
908 r->ZoneInfoDotNet->fAging = zoneinfo->fAging;
909 r->ZoneInfoDotNet->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
910 r->ZoneInfoDotNet->dwRefreshInterval = zoneinfo->dwRefreshInterval;
911 r->ZoneInfoDotNet->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
912 r->ZoneInfoDotNet->aipScavengeServers = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
913 r->ZoneInfoDotNet->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
914 r->ZoneInfoDotNet->fForwarderSlave = zoneinfo->fForwarderSlave;
915 r->ZoneInfoDotNet->aipLocalMasters = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
916 r->ZoneInfoDotNet->dwDpFlags = z->partition->dwDpFlags;
917 r->ZoneInfoDotNet->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
918 r->ZoneInfoDotNet->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
919 r->ZoneInfoDotNet->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
920 r->ZoneInfoDotNet->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
923 *typeid = DNSSRV_TYPEID_ZONE_INFO;
924 r->ZoneInfo = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_LONGHORN);
926 r->ZoneInfo->dwRpcStructureVersion = 0x02;
927 r->ZoneInfo->pszZoneName = talloc_strdup(mem_ctx, z->name);
928 r->ZoneInfo->dwZoneType = zoneinfo->dwZoneType;
929 r->ZoneInfo->fReverse = zoneinfo->fReverse;
930 r->ZoneInfo->fAllowUpdate = zoneinfo->fAllowUpdate;
931 r->ZoneInfo->fPaused = zoneinfo->fPaused;
932 r->ZoneInfo->fShutdown = zoneinfo->fShutdown;
933 r->ZoneInfo->fAutoCreated = zoneinfo->fAutoCreated;
934 r->ZoneInfo->fUseDatabase = zoneinfo->fUseDatabase;
935 r->ZoneInfo->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
936 r->ZoneInfo->aipMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipMasters);
937 r->ZoneInfo->fSecureSecondaries = zoneinfo->fSecureSecondaries;
938 r->ZoneInfo->fNotifyLevel = zoneinfo->fNotifyLevel;
939 r->ZoneInfo->aipSecondaries = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipSecondaries);
940 r->ZoneInfo->aipNotify = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipNotify);
941 r->ZoneInfo->fUseWins = zoneinfo->fUseWins;
942 r->ZoneInfo->fUseNbstat = zoneinfo->fUseNbstat;
943 r->ZoneInfo->fAging = zoneinfo->fAging;
944 r->ZoneInfo->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
945 r->ZoneInfo->dwRefreshInterval = zoneinfo->dwRefreshInterval;
946 r->ZoneInfo->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
947 r->ZoneInfo->aipScavengeServers = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipScavengeServers);
948 r->ZoneInfo->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
949 r->ZoneInfo->fForwarderSlave = zoneinfo->fForwarderSlave;
950 r->ZoneInfo->aipLocalMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
951 r->ZoneInfo->dwDpFlags = z->partition->dwDpFlags;
952 r->ZoneInfo->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
953 r->ZoneInfo->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
954 r->ZoneInfo->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
955 r->ZoneInfo->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
957 r->ZoneInfo->fQueuedForBackgroundLoad = zoneinfo->fQueuedForBackgroundLoad;
958 r->ZoneInfo->fBackgroundLoadInProgress = zoneinfo->fBackgroundLoadInProgress;
959 r->ZoneInfo->fReadOnlyZone = zoneinfo->fReadOnlyZone;
960 r->ZoneInfo->dwLastXfrAttempt = zoneinfo->dwLastXfrAttempt;
961 r->ZoneInfo->dwLastXfrResult = zoneinfo->dwLastXfrResult;
969 if (strcasecmp(operation, "AllowUpdate") == 0) {
970 answer_integer = zoneinfo->fAllowUpdate;
972 } else if (strcasecmp(operation, "Secured") == 0) {
975 } else if (strcasecmp(operation, "DsIntegrated") == 0) {
976 answer_integer = zoneinfo->fUseDatabase;
978 } else if (strcasecmp(operation, "LogUpdates") == 0) {
981 } else if (strcasecmp(operation, "NoRefreshInterval") == 0) {
982 answer_integer = zoneinfo->dwNoRefreshInterval;
984 } else if (strcasecmp(operation, "NotifyLevel") == 0) {
985 answer_integer = zoneinfo->fNotifyLevel;
987 } else if (strcasecmp(operation, "RefreshInterval") == 0) {
988 answer_integer = zoneinfo->dwRefreshInterval;
990 } else if (strcasecmp(operation, "SecureSecondaries") == 0) {
991 answer_integer = zoneinfo->fSecureSecondaries;
993 } else if (strcasecmp(operation, "Type") == 0) {
994 answer_integer = zoneinfo->dwZoneType;
996 } else if (strcasecmp(operation, "Aging") == 0) {
997 answer_integer = zoneinfo->fAging;
999 } else if (strcasecmp(operation, "ForwarderSlave") == 0) {
1000 answer_integer = zoneinfo->fForwarderSlave;
1002 } else if (strcasecmp(operation, "ForwarderTimeout") == 0) {
1003 answer_integer = zoneinfo->dwForwarderTimeout;
1005 } else if (strcasecmp(operation, "Unicode") == 0) {
1010 if (is_integer == 1) {
1011 *typeid = DNSSRV_TYPEID_DWORD;
1012 r->Dword = answer_integer;
1018 if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
1019 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1020 answer_addrarray = NULL;
1022 answer_iparray = NULL;
1025 } else if (strcasecmp(operation, "ScavengeServers") == 0) {
1026 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1027 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipScavengeServers);
1029 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
1032 } else if (strcasecmp(operation, "MasterServers") == 0) {
1033 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1034 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipMasters);
1036 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
1039 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
1040 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1041 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
1043 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
1046 } else if (strcasecmp(operation, "NotifyServers") == 0) {
1047 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1048 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipNotify);
1050 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
1053 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
1054 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1055 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipSecondaries);
1057 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
1062 if (is_addresses == 1) {
1063 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1064 *typeid = DNSSRV_TYPEID_ADDRARRAY;
1065 r->AddrArray = answer_addrarray;
1067 *typeid = DNSSRV_TYPEID_IPARRAY;
1068 r->IpArray = answer_iparray;
1075 if (strcasecmp(operation, "DatabaseFile") == 0) {
1076 answer_string = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
1078 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1079 answer_string = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
1081 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1082 answer_string = NULL;
1086 if (is_string == 1) {
1087 *typeid = DNSSRV_TYPEID_LPSTR;
1088 r->String = answer_string;
1092 DEBUG(0,("dnsserver: Invalid zone operation %s", operation));
1093 return WERR_DNS_ERROR_INVALID_PROPERTY;
1097 /* dnsserver operation functions */
1099 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
1100 static WERROR dnsserver_operate_server(struct dnsserver_state *dsstate,
1101 TALLOC_CTX *mem_ctx,
1102 const char *operation,
1103 const unsigned int client_version,
1104 enum DNS_RPC_TYPEID typeid,
1105 union DNSSRV_RPC_UNION *r)
1107 bool valid_operation = false;
1109 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1110 valid_operation = true;
1111 } else if (strcasecmp(operation, "Restart") == 0) {
1112 valid_operation = true;
1113 } else if (strcasecmp(operation, "ClearDebugLog") == 0) {
1114 valid_operation = true;
1115 } else if (strcasecmp(operation, "ClearCache") == 0) {
1116 valid_operation = true;
1117 } else if (strcasecmp(operation, "WriteDirtyZones") == 0) {
1118 valid_operation = true;
1119 } else if (strcasecmp(operation, "ZoneCreate") == 0) {
1120 struct dnsserver_zone *z, *z2;
1124 z = talloc_zero(mem_ctx, struct dnsserver_zone);
1125 W_ERROR_HAVE_NO_MEMORY(z);
1126 z->partition = talloc_zero(z, struct dnsserver_partition);
1127 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z->partition, z);
1128 z->zoneinfo = talloc_zero(z, struct dnsserver_zoneinfo);
1129 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z->zoneinfo, z);
1131 if (typeid == DNSSRV_TYPEID_ZONE_CREATE_W2K) {
1132 len = strlen(r->ZoneCreateW2K->pszZoneName);
1133 if (r->ZoneCreateW2K->pszZoneName[len-1] == '.') {
1136 z->name = talloc_strndup(z, r->ZoneCreateW2K->pszZoneName, len);
1137 z->zoneinfo->dwZoneType = r->ZoneCreateW2K->dwZoneType;
1138 z->zoneinfo->fAllowUpdate = r->ZoneCreateW2K->fAllowUpdate;
1139 z->zoneinfo->fAging = r->ZoneCreateW2K->fAging;
1140 z->zoneinfo->Flags = r->ZoneCreateW2K->dwFlags;
1141 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE_DOTNET) {
1142 len = strlen(r->ZoneCreateDotNet->pszZoneName);
1143 if (r->ZoneCreateDotNet->pszZoneName[len-1] == '.') {
1146 z->name = talloc_strndup(z, r->ZoneCreateDotNet->pszZoneName, len);
1147 z->zoneinfo->dwZoneType = r->ZoneCreateDotNet->dwZoneType;
1148 z->zoneinfo->fAllowUpdate = r->ZoneCreateDotNet->fAllowUpdate;
1149 z->zoneinfo->fAging = r->ZoneCreateDotNet->fAging;
1150 z->zoneinfo->Flags = r->ZoneCreateDotNet->dwFlags;
1151 z->partition->dwDpFlags = r->ZoneCreateDotNet->dwDpFlags;
1152 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE) {
1153 len = strlen(r->ZoneCreate->pszZoneName);
1154 if (r->ZoneCreate->pszZoneName[len-1] == '.') {
1157 z->name = talloc_strndup(z, r->ZoneCreate->pszZoneName, len);
1158 z->zoneinfo->dwZoneType = r->ZoneCreate->dwZoneType;
1159 z->zoneinfo->fAllowUpdate = r->ZoneCreate->fAllowUpdate;
1160 z->zoneinfo->fAging = r->ZoneCreate->fAging;
1161 z->zoneinfo->Flags = r->ZoneCreate->dwFlags;
1162 z->partition->dwDpFlags = r->ZoneCreate->dwDpFlags;
1165 return WERR_DNS_ERROR_INVALID_PROPERTY;
1168 z2 = dnsserver_find_zone(dsstate->zones, z->name);
1171 return WERR_DNS_ERROR_ZONE_ALREADY_EXISTS;
1174 status = dnsserver_db_create_zone(dsstate->samdb, dsstate->partitions, z,
1178 if (W_ERROR_IS_OK(status)) {
1179 dnsserver_reload_zones(dsstate);
1182 } else if (strcasecmp(operation, "ClearStatistics") == 0) {
1183 valid_operation = true;
1184 } else if (strcasecmp(operation, "EnlistDirectoryPartition") == 0) {
1185 valid_operation = true;
1186 } else if (strcasecmp(operation, "StartScavenging") == 0) {
1187 valid_operation = true;
1188 } else if (strcasecmp(operation, "AbortScavenging") == 0) {
1189 valid_operation = true;
1190 } else if (strcasecmp(operation, "AutoConfigure") == 0) {
1191 valid_operation = true;
1192 } else if (strcasecmp(operation, "ExportSettings") == 0) {
1193 valid_operation = true;
1194 } else if (strcasecmp(operation, "PrepareForDemotion") == 0) {
1195 valid_operation = true;
1196 } else if (strcasecmp(operation, "PrepareForUninstall") == 0) {
1197 valid_operation = true;
1198 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1199 valid_operation = true;
1200 } else if (strcasecmp(operation, "DeleteRecord") == 0) {
1201 valid_operation = true;
1202 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1203 valid_operation = true;
1204 } else if (strcasecmp(operation, "ListenAddresses") == 0) {
1205 valid_operation = true;
1206 } else if (strcasecmp(operation, "Forwarders") == 0) {
1207 valid_operation = true;
1208 } else if (strcasecmp(operation, "LogFilePath") == 0) {
1209 valid_operation = true;
1210 } else if (strcasecmp(operation, "LogIpFilterList") == 0) {
1211 valid_operation = true;
1212 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
1213 valid_operation = true;
1214 } else if (strcasecmp(operation, "DomainDirectoryPartitionBaseName") == 0) {
1215 valid_operation = true;
1216 } else if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
1217 valid_operation = true;
1218 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
1219 valid_operation = true;
1220 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
1221 valid_operation = true;
1222 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
1223 valid_operation = true;
1226 if (valid_operation) {
1227 DEBUG(0, ("dnsserver: server operation '%s' not implemented", operation));
1228 return WERR_CALL_NOT_IMPLEMENTED;
1231 DEBUG(0, ("dnsserver: invalid server operation '%s'", operation));
1232 return WERR_DNS_ERROR_INVALID_PROPERTY;
1235 static WERROR dnsserver_complex_operate_server(struct dnsserver_state *dsstate,
1236 TALLOC_CTX *mem_ctx,
1237 const char *operation,
1238 const unsigned int client_version,
1239 enum DNS_RPC_TYPEID typeid_in,
1240 union DNSSRV_RPC_UNION *rin,
1241 enum DNS_RPC_TYPEID *typeid_out,
1242 union DNSSRV_RPC_UNION *rout)
1244 int valid_operation = 0;
1245 struct dnsserver_zone *z, **zlist;
1247 bool found1, found2, found3, found4;
1250 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1251 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1252 return dnsserver_query_server(dsstate, mem_ctx,
1258 } else if (strcasecmp(operation, "EnumZones") == 0) {
1259 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1260 return WERR_DNS_ERROR_INVALID_PROPERTY;
1264 zlist = talloc_zero_array(mem_ctx, struct dnsserver_zone *, 0);
1265 for (z = dsstate->zones; z; z = z->next) {
1267 /* Match the flags in groups
1269 * Group1 : PRIMARY, SECONDARY, CACHE, AUTO
1270 * Group2 : FORWARD, REVERSE, FORWARDER, STUB
1271 * Group3 : DS, NON_DS, DOMAIN_DP, FOREST_DP
1272 * Group4 : CUSTOM_DP, LEGACY_DP
1277 if (rin->Dword & 0x0000000f) {
1278 if (rin->Dword & DNS_ZONE_REQUEST_PRIMARY) {
1279 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_PRIMARY) {
1283 if (rin->Dword & DNS_ZONE_REQUEST_SECONDARY) {
1284 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_SECONDARY) {
1288 if (rin->Dword & DNS_ZONE_REQUEST_CACHE) {
1289 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_CACHE) {
1293 if (rin->Dword & DNS_ZONE_REQUEST_AUTO) {
1294 if (z->zoneinfo->fAutoCreated
1295 || z->partition->dwDpFlags & DNS_DP_AUTOCREATED) {
1305 if (rin->Dword & 0x000000f0) {
1306 if (rin->Dword & DNS_ZONE_REQUEST_FORWARD) {
1307 if (!(z->zoneinfo->fReverse)) {
1311 if (rin->Dword & DNS_ZONE_REQUEST_REVERSE) {
1312 if (z->zoneinfo->fReverse) {
1316 if (rin->Dword & DNS_ZONE_REQUEST_FORWARDER) {
1317 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_FORWARDER) {
1321 if (rin->Dword & DNS_ZONE_REQUEST_STUB) {
1322 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_STUB) {
1332 if (rin->Dword & 0x00000f00) {
1333 if (rin->Dword & DNS_ZONE_REQUEST_DS) {
1334 if (z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED) {
1338 if (rin->Dword & DNS_ZONE_REQUEST_NON_DS) {
1339 if (!(z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED)) {
1343 if (rin->Dword & DNS_ZONE_REQUEST_DOMAIN_DP) {
1344 if (!(z->partition->dwDpFlags & DNS_DP_DOMAIN_DEFAULT)) {
1348 if (rin->Dword & DNS_ZONE_REQUEST_FOREST_DP) {
1349 if (!(z->partition->dwDpFlags & DNS_DP_FOREST_DEFAULT)) {
1358 if (rin->Dword & 0x0000f000) {
1364 if (found1 && found2 && found3 && found4) {
1365 zlist = talloc_realloc(mem_ctx, zlist, struct dnsserver_zone *, zcount+1);
1371 if (client_version == DNS_CLIENT_VERSION_W2K) {
1372 *typeid_out = DNSSRV_TYPEID_ZONE_LIST_W2K;
1373 rout->ZoneListW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_W2K);
1376 rout->ZoneListW2K->dwZoneCount = 0;
1377 rout->ZoneListW2K->ZoneArray = NULL;
1382 rout->ZoneListW2K->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_W2K *, zcount);
1383 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout->ZoneListW2K->ZoneArray, zlist);
1385 for (i=0; i<zcount; i++) {
1386 rout->ZoneListW2K->ZoneArray[i] = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
1388 rout->ZoneListW2K->ZoneArray[i]->pszZoneName = talloc_strdup(mem_ctx, zlist[i]->name);
1389 rout->ZoneListW2K->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
1390 rout->ZoneListW2K->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
1391 rout->ZoneListW2K->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
1393 rout->ZoneListW2K->dwZoneCount = zcount;
1396 *typeid_out = DNSSRV_TYPEID_ZONE_LIST;
1397 rout->ZoneList = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_DOTNET);
1400 rout->ZoneList->dwRpcStructureVersion = 1;
1401 rout->ZoneList->dwZoneCount = 0;
1402 rout->ZoneList->ZoneArray = NULL;
1407 rout->ZoneList->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_DOTNET *, zcount);
1408 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout->ZoneList->ZoneArray, zlist);
1410 for (i=0; i<zcount; i++) {
1411 rout->ZoneList->ZoneArray[i] = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
1413 rout->ZoneList->ZoneArray[i]->dwRpcStructureVersion = 1;
1414 rout->ZoneList->ZoneArray[i]->pszZoneName = talloc_strdup(mem_ctx, zlist[i]->name);
1415 rout->ZoneList->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
1416 rout->ZoneList->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
1417 rout->ZoneList->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
1418 rout->ZoneList->ZoneArray[i]->dwDpFlags = zlist[i]->partition->dwDpFlags;
1419 rout->ZoneList->ZoneArray[i]->pszDpFqdn = talloc_strdup(mem_ctx, zlist[i]->partition->pszDpFqdn);
1421 rout->ZoneList->dwRpcStructureVersion = 1;
1422 rout->ZoneList->dwZoneCount = zcount;
1426 } else if (strcasecmp(operation, "EnumZones2") == 0) {
1427 valid_operation = true;
1428 } else if (strcasecmp(operation, "EnumDirectoryPartitions") == 0) {
1429 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1430 return WERR_DNS_ERROR_INVALID_PROPERTY;
1433 *typeid_out = DNSSRV_TYPEID_DP_LIST;
1434 rout->DirectoryPartitionList = talloc_zero(mem_ctx, struct DNS_RPC_DP_LIST);
1436 if (rin->Dword != 0) {
1437 rout->DirectoryPartitionList->dwDpCount = 0;
1438 rout->DirectoryPartitionList->DpArray = NULL;
1440 struct DNS_RPC_DP_ENUM **dplist;
1441 struct dnsserver_partition *p;
1444 dplist = talloc_zero_array(mem_ctx, struct DNS_RPC_DP_ENUM *, pcount);
1445 W_ERROR_HAVE_NO_MEMORY(dplist);
1447 p = dsstate->partitions;
1448 for (i=0; i<pcount; i++) {
1449 dplist[i] = talloc_zero(dplist, struct DNS_RPC_DP_ENUM);
1451 dplist[i]->pszDpFqdn = talloc_strdup(mem_ctx, p->pszDpFqdn);
1452 dplist[i]->dwFlags = p->dwDpFlags;
1453 dplist[i]->dwZoneCount = p->zones_count;
1457 rout->DirectoryPartitionList->dwDpCount = pcount;
1458 rout->DirectoryPartitionList->DpArray = dplist;
1461 } else if (strcasecmp(operation, "DirectoryPartitionInfo") == 0) {
1462 struct dnsserver_partition *p;
1463 struct dnsserver_partition_info *partinfo;
1464 struct DNS_RPC_DP_INFO *dpinfo = NULL;
1466 if (typeid_in != DNSSRV_TYPEID_LPSTR) {
1467 return WERR_DNS_ERROR_INVALID_PROPERTY;
1470 *typeid_out = DNSSRV_TYPEID_DP_INFO;
1472 for (p = dsstate->partitions; p; p = p->next) {
1473 if (strcasecmp(p->pszDpFqdn, rin->String) == 0) {
1474 dpinfo = talloc_zero(mem_ctx, struct DNS_RPC_DP_INFO);
1475 W_ERROR_HAVE_NO_MEMORY(dpinfo);
1477 partinfo = dnsserver_db_partition_info(mem_ctx, dsstate->samdb, p);
1478 W_ERROR_HAVE_NO_MEMORY(partinfo);
1480 dpinfo->pszDpFqdn = talloc_strdup(dpinfo, p->pszDpFqdn);
1481 dpinfo->pszDpDn = talloc_strdup(dpinfo, ldb_dn_get_linearized(p->partition_dn));
1482 dpinfo->pszCrDn = talloc_steal(dpinfo, partinfo->pszCrDn);
1483 dpinfo->dwFlags = p->dwDpFlags;
1484 dpinfo->dwZoneCount = p->zones_count;
1485 dpinfo->dwState = partinfo->dwState;
1486 dpinfo->dwReplicaCount = partinfo->dwReplicaCount;
1487 if (partinfo->dwReplicaCount > 0) {
1488 dpinfo->ReplicaArray = talloc_steal(dpinfo,
1489 partinfo->ReplicaArray);
1491 dpinfo->ReplicaArray = NULL;
1497 if (dpinfo == NULL) {
1498 return WERR_DNS_ERROR_DP_DOES_NOT_EXIST;
1501 rout->DirectoryPartition = dpinfo;
1503 } else if (strcasecmp(operation, "Statistics") == 0) {
1504 valid_operation = true;
1505 } else if (strcasecmp(operation, "IpValidate") == 0) {
1506 valid_operation = true;
1509 if (valid_operation) {
1510 DEBUG(0, ("dnsserver: server complex operation '%s' not implemented", operation));
1511 return WERR_CALL_NOT_IMPLEMENTED;
1514 DEBUG(0, ("dnsserver: invalid server complex operation '%s'", operation));
1515 return WERR_DNS_ERROR_INVALID_PROPERTY;
1518 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
1519 static WERROR dnsserver_operate_zone(struct dnsserver_state *dsstate,
1520 TALLOC_CTX *mem_ctx,
1521 struct dnsserver_zone *z,
1522 unsigned int request_filter,
1523 const char *operation,
1524 const unsigned int client_version,
1525 enum DNS_RPC_TYPEID typeid,
1526 union DNSSRV_RPC_UNION *r)
1528 bool valid_operation = false;
1530 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1532 if (typeid != DNSSRV_TYPEID_NAME_AND_PARAM) {
1533 return WERR_DNS_ERROR_INVALID_PROPERTY;
1536 return dnsserver_db_do_reset_dword(dsstate->samdb, z,
1539 } else if (strcasecmp(operation, "ZoneTypeReset") == 0) {
1540 valid_operation = true;
1541 } else if (strcasecmp(operation, "PauseZone") == 0) {
1542 valid_operation = true;
1543 } else if (strcasecmp(operation, "ResumeZone") == 0) {
1544 valid_operation = true;
1545 } else if (strcasecmp(operation, "DeleteZone") == 0) {
1546 valid_operation = true;
1547 } else if (strcasecmp(operation, "ReloadZone") == 0) {
1548 valid_operation = true;
1549 } else if (strcasecmp(operation, "RefreshZone") == 0) {
1550 valid_operation = true;
1551 } else if (strcasecmp(operation, "ExpireZone") == 0) {
1552 valid_operation = true;
1553 } else if (strcasecmp(operation, "IncrementVersion") == 0) {
1554 valid_operation = true;
1555 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1556 valid_operation = true;
1557 } else if (strcasecmp(operation, "DeleteZoneFromDs") == 0) {
1560 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1562 status = dnsserver_db_delete_zone(dsstate->samdb, z);
1563 if (W_ERROR_IS_OK(status)) {
1564 dnsserver_reload_zones(dsstate);
1567 } else if (strcasecmp(operation, "UpdateZoneFromDs") == 0) {
1568 valid_operation = true;
1569 } else if (strcasecmp(operation, "ZoneExport") == 0) {
1570 valid_operation = true;
1571 } else if (strcasecmp(operation, "ZoneChangeDirectoryPartition") == 0) {
1572 valid_operation = true;
1573 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1574 valid_operation = true;
1575 } else if (strcasecmp(operation, "DeleteRecordSet") == 0) {
1576 valid_operation = true;
1577 } else if (strcasecmp(operation, "ForceAgingOnNode") == 0) {
1578 valid_operation = true;
1579 } else if (strcasecmp(operation, "DatabaseFile") == 0) {
1580 valid_operation = true;
1581 } else if (strcasecmp(operation, "MasterServers") == 0) {
1582 valid_operation = true;
1583 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
1584 valid_operation = true;
1585 } else if (strcasecmp(operation, "NotifyServers") == 0) {
1586 valid_operation = true;
1587 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
1588 valid_operation = true;
1589 } else if (strcasecmp(operation, "ScavengingServers") == 0) {
1590 valid_operation = true;
1591 } else if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
1592 valid_operation = true;
1593 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1594 valid_operation = true;
1595 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1596 valid_operation = true;
1599 if (valid_operation) {
1600 DEBUG(0, ("dnsserver: zone operation '%s' not implemented", operation));
1601 return WERR_CALL_NOT_IMPLEMENTED;
1604 DEBUG(0, ("dnsserver: invalid zone operation '%s'", operation));
1605 return WERR_DNS_ERROR_INVALID_PROPERTY;
1608 static WERROR dnsserver_complex_operate_zone(struct dnsserver_state *dsstate,
1609 TALLOC_CTX *mem_ctx,
1610 struct dnsserver_zone *z,
1611 const char *operation,
1612 const unsigned int client_version,
1613 enum DNS_RPC_TYPEID typeid_in,
1614 union DNSSRV_RPC_UNION *rin,
1615 enum DNS_RPC_TYPEID *typeid_out,
1616 union DNSSRV_RPC_UNION *rout)
1618 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1619 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1620 return dnsserver_query_zone(dsstate, mem_ctx, z,
1629 DEBUG(0,("dnsserver: Invalid zone operation %s", operation));
1630 return WERR_DNS_ERROR_INVALID_PROPERTY;
1633 /* dnsserver enumerate function */
1635 static WERROR dnsserver_enumerate_root_records(struct dnsserver_state *dsstate,
1636 TALLOC_CTX *mem_ctx,
1637 unsigned int client_version,
1638 const char *node_name,
1639 enum dns_record_type record_type,
1640 unsigned int select_flag,
1641 unsigned int *buffer_length,
1642 struct DNS_RPC_RECORDS_ARRAY **buffer)
1644 TALLOC_CTX *tmp_ctx;
1645 struct dnsserver_zone *z;
1646 const char * const attrs[] = { "name", "dnsRecord", NULL };
1647 struct ldb_result *res;
1648 struct DNS_RPC_RECORDS_ARRAY *recs;
1655 tmp_ctx = talloc_new(mem_ctx);
1656 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1658 z = dnsserver_find_zone(dsstate->zones, ".");
1660 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1663 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1664 LDB_SCOPE_ONELEVEL, attrs,
1665 "(&(objectClass=dnsNode)(name=@)(!(dNSTombstoned=TRUE)))");
1666 if (ret != LDB_SUCCESS) {
1667 talloc_free(tmp_ctx);
1668 return WERR_INTERNAL_DB_ERROR;
1670 if (res->count == 0) {
1671 talloc_free(tmp_ctx);
1672 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1675 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1676 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1681 for (i=0; i<res->count; i++) {
1682 status = dns_fill_records_array(tmp_ctx, NULL, record_type,
1684 res->msgs[i], 0, recs,
1685 &add_names, &add_count);
1686 if (!W_ERROR_IS_OK(status)) {
1687 talloc_free(tmp_ctx);
1693 /* Add any additional records */
1694 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1695 for (i=0; i<add_count; i++) {
1697 = ldb_binary_encode_string(tmp_ctx,
1699 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1700 LDB_SCOPE_ONELEVEL, attrs,
1701 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1703 if (ret != LDB_SUCCESS || res->count == 0) {
1708 len = strlen(add_names[i]);
1709 if (add_names[i][len-1] == '.') {
1710 rname = talloc_strdup(tmp_ctx, add_names[i]);
1712 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1714 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1716 res->msgs[0], 0, recs,
1723 talloc_free(tmp_ctx);
1725 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1732 static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
1733 TALLOC_CTX *mem_ctx,
1734 struct dnsserver_zone *z,
1735 unsigned int client_version,
1736 const char *node_name,
1737 const char *start_child,
1738 enum dns_record_type record_type,
1739 unsigned int select_flag,
1740 const char *filter_start,
1741 const char *filter_stop,
1742 unsigned int *buffer_length,
1743 struct DNS_RPC_RECORDS_ARRAY **buffer)
1745 TALLOC_CTX *tmp_ctx;
1747 const char * const attrs[] = { "name", "dnsRecord", NULL };
1748 struct ldb_result *res;
1749 struct DNS_RPC_RECORDS_ARRAY *recs;
1750 char **add_names = NULL;
1755 struct dns_tree *tree, *base, *node;
1757 tmp_ctx = talloc_new(mem_ctx);
1758 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1760 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1761 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1763 /* search all records under parent tree */
1764 if (strcasecmp(name, z->name) == 0) {
1765 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1766 LDB_SCOPE_ONELEVEL, attrs,
1767 "(&(objectClass=dnsNode)(!(dNSTombstoned=TRUE)))");
1770 = ldb_binary_encode_string(tmp_ctx, name);
1771 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1772 LDB_SCOPE_ONELEVEL, attrs,
1773 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s))(!(dNSTombstoned=TRUE)))",
1774 encoded_name, encoded_name);
1776 if (ret != LDB_SUCCESS) {
1777 talloc_free(tmp_ctx);
1778 return WERR_INTERNAL_DB_ERROR;
1780 if (res->count == 0) {
1781 talloc_free(tmp_ctx);
1782 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1785 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1786 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1788 /* Sort the names, so that the first record is the parent record */
1789 ldb_qsort(res->msgs, res->count, sizeof(struct ldb_message *), name,
1790 (ldb_qsort_cmp_fn_t)dns_name_compare);
1792 /* Build a tree of name components from dns name */
1793 if (strcasecmp(name, z->name) == 0) {
1794 tree = dns_build_tree(tmp_ctx, "@", res);
1796 tree = dns_build_tree(tmp_ctx, name, res);
1798 W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree, tmp_ctx);
1800 /* Find the parent record in the tree */
1802 while (base->level != -1) {
1803 base = base->children[0];
1806 /* Add the parent record with blank name */
1807 if (!(select_flag & DNS_RPC_VIEW_ONLY_CHILDREN)) {
1808 status = dns_fill_records_array(tmp_ctx, z, record_type,
1811 recs, &add_names, &add_count);
1812 if (!W_ERROR_IS_OK(status)) {
1813 talloc_free(tmp_ctx);
1818 /* Add all the children records */
1819 if (!(select_flag & DNS_RPC_VIEW_NO_CHILDREN)) {
1820 for (i=0; i<base->num_children; i++) {
1821 node = base->children[i];
1823 status = dns_fill_records_array(tmp_ctx, z, record_type,
1824 select_flag, node->name,
1825 node->data, node->num_children,
1826 recs, &add_names, &add_count);
1827 if (!W_ERROR_IS_OK(status)) {
1828 talloc_free(tmp_ctx);
1838 /* Add any additional records */
1839 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1840 for (i=0; i<add_count; i++) {
1841 struct dnsserver_zone *z2;
1843 /* Search all the available zones for additional name */
1844 for (z2 = dsstate->zones; z2; z2 = z2->next) {
1846 name = dns_split_node_name(tmp_ctx, add_names[i], z2->name);
1848 = ldb_binary_encode_string(tmp_ctx,
1850 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z2->zone_dn,
1851 LDB_SCOPE_ONELEVEL, attrs,
1852 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1855 if (ret != LDB_SUCCESS) {
1858 if (res->count == 1) {
1866 len = strlen(add_names[i]);
1867 if (add_names[i][len-1] == '.') {
1868 rname = talloc_strdup(tmp_ctx, add_names[i]);
1870 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1872 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1874 res->msgs[0], 0, recs,
1881 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1888 * Check str1 + '.' + str2 = name, for example:
1889 * ("dc0", "example.com", "dc0.example.com") = true
1891 static bool cname_self_reference(const char* node_name,
1892 const char* zone_name,
1893 struct DNS_RPC_NAME name) {
1894 size_t node_len, zone_len;
1896 if (node_name == NULL || zone_name == NULL) {
1900 node_len = strlen(node_name);
1901 zone_len = strlen(zone_name);
1903 if (node_len == 0 ||
1905 (name.len != node_len + zone_len + 1)) {
1909 if (strncmp(node_name, name.str, node_len) == 0 &&
1910 name.str[node_len] == '.' &&
1911 strncmp(zone_name, name.str + node_len + 1, zone_len) == 0) {
1918 /* dnsserver update function */
1920 static WERROR dnsserver_update_record(struct dnsserver_state *dsstate,
1921 TALLOC_CTX *mem_ctx,
1922 struct dnsserver_zone *z,
1923 unsigned int client_version,
1924 const char *node_name,
1925 struct DNS_RPC_RECORD_BUF *add_buf,
1926 struct DNS_RPC_RECORD_BUF *del_buf)
1928 TALLOC_CTX *tmp_ctx;
1932 tmp_ctx = talloc_new(mem_ctx);
1933 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1935 /* If node_name is @ or zone name, dns record is @ */
1936 if (strcmp(node_name, "@") == 0 ||
1937 strcmp(node_name, ".") == 0 ||
1938 strcasecmp(node_name, z->name) == 0) {
1939 name = talloc_strdup(tmp_ctx, "@");
1941 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1943 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1945 /* CNAMEs can't point to themselves */
1946 if (add_buf != NULL && add_buf->rec.wType == DNS_TYPE_CNAME) {
1947 if (cname_self_reference(node_name, z->name, add_buf->rec.data.name)) {
1948 return WERR_DNS_ERROR_CNAME_LOOP;
1952 if (add_buf != NULL) {
1953 if (del_buf == NULL) {
1955 status = dnsserver_db_add_record(tmp_ctx, dsstate->samdb,
1960 status = dnsserver_db_update_record(tmp_ctx, dsstate->samdb,
1966 if (del_buf == NULL) {
1967 /* Add empty node */
1968 status = dnsserver_db_add_empty_node(tmp_ctx, dsstate->samdb,
1972 status = dnsserver_db_delete_record(tmp_ctx, dsstate->samdb,
1978 talloc_free(tmp_ctx);
1983 /* dnsserver interface functions */
1985 static WERROR dcesrv_DnssrvOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation *r)
1987 struct dnsserver_state *dsstate;
1988 struct dnsserver_zone *z = NULL;
1989 uint32_t request_filter = 0;
1992 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1993 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1996 if (r->in.dwContext == 0) {
1997 if (r->in.pszZone != NULL) {
1998 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
2001 request_filter = r->in.dwContext;
2004 if (r->in.pszZone == NULL) {
2005 ret = dnsserver_operate_server(dsstate, mem_ctx,
2007 DNS_CLIENT_VERSION_W2K,
2011 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2012 if (z == NULL && request_filter == 0) {
2013 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2016 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
2019 DNS_CLIENT_VERSION_W2K,
2024 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2025 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation, NDR_IN, r);
2030 static WERROR dcesrv_DnssrvQuery(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery *r)
2032 struct dnsserver_state *dsstate;
2033 struct dnsserver_zone *z;
2036 ZERO_STRUCTP(r->out.pdwTypeId);
2037 ZERO_STRUCTP(r->out.ppData);
2039 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2040 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2043 if (r->in.pszZone == NULL) {
2044 /* FIXME: DNS Server Configuration Access Control List */
2045 ret = dnsserver_query_server(dsstate, mem_ctx,
2047 DNS_CLIENT_VERSION_W2K,
2051 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2053 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2056 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
2058 DNS_CLIENT_VERSION_W2K,
2063 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2064 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery, NDR_IN, r);
2069 static WERROR dcesrv_DnssrvComplexOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation *r)
2071 struct dnsserver_state *dsstate;
2072 struct dnsserver_zone *z;
2075 ZERO_STRUCTP(r->out.pdwTypeOut);
2076 ZERO_STRUCTP(r->out.ppDataOut);
2078 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2079 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2082 if (r->in.pszZone == NULL) {
2083 /* Server operation */
2084 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
2086 DNS_CLIENT_VERSION_W2K,
2092 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2094 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2097 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2099 DNS_CLIENT_VERSION_W2K,
2106 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2107 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation, NDR_IN, r);
2112 static WERROR dcesrv_DnssrvEnumRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords *r)
2114 struct dnsserver_state *dsstate;
2115 struct dnsserver_zone *z;
2118 ZERO_STRUCTP(r->out.pdwBufferLength);
2119 ZERO_STRUCTP(r->out.pBuffer);
2121 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2122 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2125 if (r->in.pszZone == NULL) {
2126 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2129 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
2130 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
2131 DNS_CLIENT_VERSION_W2K,
2135 r->out.pdwBufferLength,
2138 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2140 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2143 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2144 DNS_CLIENT_VERSION_W2K,
2146 r->in.pszStartChild,
2149 r->in.pszFilterStart,
2150 r->in.pszFilterStop,
2151 r->out.pdwBufferLength,
2155 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2156 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords, NDR_IN, r);
2161 static WERROR dcesrv_DnssrvUpdateRecord(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord *r)
2163 struct dnsserver_state *dsstate;
2164 struct dnsserver_zone *z;
2167 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2168 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2171 if (r->in.pszZone == NULL) {
2172 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2175 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2177 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2180 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2181 DNS_CLIENT_VERSION_W2K,
2184 r->in.pDeleteRecord);
2186 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2187 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord, NDR_IN, r);
2192 static WERROR dcesrv_DnssrvOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation2 *r)
2194 struct dnsserver_state *dsstate;
2195 struct dnsserver_zone *z = NULL;
2196 uint32_t request_filter = 0;
2199 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2200 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2203 if (r->in.dwContext == 0) {
2204 if (r->in.pszZone != NULL) {
2205 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
2208 request_filter = r->in.dwContext;
2211 if (r->in.pszZone == NULL) {
2212 ret = dnsserver_operate_server(dsstate, mem_ctx,
2214 r->in.dwClientVersion,
2218 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2219 if (z == NULL && request_filter == 0) {
2220 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2223 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
2226 r->in.dwClientVersion,
2231 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2232 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation2, NDR_IN, r);
2237 static WERROR dcesrv_DnssrvQuery2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery2 *r)
2239 struct dnsserver_state *dsstate;
2240 struct dnsserver_zone *z;
2243 ZERO_STRUCTP(r->out.pdwTypeId);
2244 ZERO_STRUCTP(r->out.ppData);
2246 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2247 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2250 if (r->in.pszZone == NULL) {
2251 /* FIXME: DNS Server Configuration Access Control List */
2252 ret = dnsserver_query_server(dsstate, mem_ctx,
2254 r->in.dwClientVersion,
2258 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2260 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2263 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
2265 r->in.dwClientVersion,
2270 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2271 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery2, NDR_IN, r);
2276 static WERROR dcesrv_DnssrvComplexOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation2 *r)
2278 struct dnsserver_state *dsstate;
2279 struct dnsserver_zone *z;
2282 ZERO_STRUCTP(r->out.pdwTypeOut);
2283 ZERO_STRUCTP(r->out.ppDataOut);
2285 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2286 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2289 if (r->in.pszZone == NULL) {
2290 /* Server operation */
2291 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
2293 r->in.dwClientVersion,
2300 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2302 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2305 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2307 r->in.dwClientVersion,
2314 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2315 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation2, NDR_IN, r);
2320 static WERROR dcesrv_DnssrvEnumRecords2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords2 *r)
2322 struct dnsserver_state *dsstate;
2323 struct dnsserver_zone *z;
2326 ZERO_STRUCTP(r->out.pdwBufferLength);
2327 ZERO_STRUCTP(r->out.pBuffer);
2329 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2330 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2333 if (r->in.pszZone == NULL) {
2334 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2337 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
2338 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
2339 r->in.dwClientVersion,
2343 r->out.pdwBufferLength,
2346 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2348 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2351 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2352 r->in.dwClientVersion,
2354 r->in.pszStartChild,
2357 r->in.pszFilterStart,
2358 r->in.pszFilterStop,
2359 r->out.pdwBufferLength,
2364 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2365 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords2, NDR_IN, r);
2370 static WERROR dcesrv_DnssrvUpdateRecord2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord2 *r)
2372 struct dnsserver_state *dsstate;
2373 struct dnsserver_zone *z;
2376 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2377 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2380 if (r->in.pszZone == NULL) {
2381 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2384 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2386 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2389 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2390 r->in.dwClientVersion,
2393 r->in.pDeleteRecord);
2395 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2396 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord2, NDR_IN, r);
2401 /* include the generated boilerplate */
2402 #include "librpc/gen_ndr/ndr_dnsserver_s.c"