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 "rpc_server/common/common.h"
26 #include "dsdb/samdb/samdb.h"
27 #include "lib/util/dlinklist.h"
28 #include "librpc/gen_ndr/ndr_dnsserver.h"
29 #include "dns_server/dnsserver_common.h"
30 #include "dnsserver.h"
34 #define DCESRV_INTERFACE_DNSSERVER_BIND(context, iface) \
35 dcesrv_interface_dnsserver_bind(context, iface)
36 static NTSTATUS
dcesrv_interface_dnsserver_bind(struct dcesrv_connection_context
*context
,
37 const struct dcesrv_interface
*iface
)
39 return dcesrv_interface_bind_require_integrity(context
, iface
);
42 #define DNSSERVER_STATE_MAGIC 0xc9657ab4
43 struct dnsserver_state
{
44 struct loadparm_context
*lp_ctx
;
45 struct ldb_context
*samdb
;
46 struct dnsserver_partition
*partitions
;
47 struct dnsserver_zone
*zones
;
49 struct dnsserver_serverinfo
*serverinfo
;
53 /* Utility functions */
55 static void dnsserver_reload_zones(struct dnsserver_state
*dsstate
)
57 struct dnsserver_partition
*p
;
58 struct dnsserver_zone
*zones
, *z
, *znext
, *zmatch
;
59 struct dnsserver_zone
*old_list
, *new_list
;
61 old_list
= dsstate
->zones
;
64 for (p
= dsstate
->partitions
; p
; p
= p
->next
) {
65 zones
= dnsserver_db_enumerate_zones(dsstate
, dsstate
->samdb
, p
);
69 for (z
= zones
; z
; ) {
71 zmatch
= dnsserver_find_zone(old_list
, z
->name
);
74 z
->zoneinfo
= dnsserver_init_zoneinfo(z
, dsstate
->serverinfo
);
75 if (z
->zoneinfo
== NULL
) {
78 DLIST_ADD_END(new_list
, z
);
80 dsstate
->zones_count
++;
84 DLIST_REMOVE(old_list
, zmatch
);
85 DLIST_ADD_END(new_list
, zmatch
);
91 if (new_list
== NULL
) {
96 for (z
= old_list
; z
; ) {
98 z
->partition
->zones_count
--;
99 dsstate
->zones_count
--;
104 dsstate
->zones
= new_list
;
108 static struct dnsserver_state
*dnsserver_connect(struct dcesrv_call_state
*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 dsstate
->samdb
= dcesrv_samdb_connect_as_user(dsstate
, dce_call
);
130 if (dsstate
->samdb
== NULL
) {
131 DEBUG(0,("dnsserver: Failed to open samdb\n"));
135 /* Initialize server info */
136 dsstate
->serverinfo
= dnsserver_init_serverinfo(dsstate
,
139 if (dsstate
->serverinfo
== NULL
) {
143 /* Search for DNS partitions */
144 partitions
= dnsserver_db_enumerate_partitions(dsstate
, dsstate
->serverinfo
, dsstate
->samdb
);
145 if (partitions
== NULL
) {
148 dsstate
->partitions
= partitions
;
150 /* Search for DNS zones */
151 for (p
= partitions
; p
; p
= p
->next
) {
152 zones
= dnsserver_db_enumerate_zones(dsstate
, dsstate
->samdb
, p
);
156 for (z
= zones
; z
; ) {
158 if (dnsserver_find_zone(dsstate
->zones
, z
->name
) == NULL
) {
159 z
->zoneinfo
= dnsserver_init_zoneinfo(z
, dsstate
->serverinfo
);
160 if (z
->zoneinfo
== NULL
) {
163 DLIST_ADD_END(dsstate
->zones
, z
);
165 dsstate
->zones_count
++;
167 /* Ignore duplicate zone */
168 DEBUG(3,("dnsserver: Ignoring duplicate zone '%s' from '%s'\n",
169 z
->name
, ldb_dn_get_linearized(z
->zone_dn
)));
175 status
= dcesrv_iface_state_store_conn(dce_call
,
176 DNSSERVER_STATE_MAGIC
,
178 if (!NT_STATUS_IS_OK(status
)) {
185 talloc_free(dsstate
);
191 /* dnsserver query functions */
193 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
194 static WERROR
dnsserver_query_server(struct dnsserver_state
*dsstate
,
196 const char *operation
,
197 const unsigned int client_version
,
198 enum DNS_RPC_TYPEID
*typeid,
199 union DNSSRV_RPC_UNION
*r
)
201 uint8_t is_integer
, is_addresses
, is_string
, is_wstring
, is_stringlist
;
202 uint32_t answer_integer
;
203 struct IP4_ARRAY
*answer_iparray
= NULL
;
204 struct DNS_ADDR_ARRAY
*answer_addrarray
= NULL
;
205 char *answer_string
= NULL
;
206 struct DNS_RPC_UTF8_STRING_LIST
*answer_stringlist
= NULL
;
207 struct dnsserver_serverinfo
*serverinfo
;
209 serverinfo
= dsstate
->serverinfo
;
211 if (strcasecmp(operation
, "ServerInfo") == 0) {
212 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
213 *typeid = DNSSRV_TYPEID_SERVER_INFO_W2K
;
214 r
->ServerInfoW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_SERVER_INFO_W2K
);
216 r
->ServerInfoW2K
->dwVersion
= serverinfo
->dwVersion
;
217 r
->ServerInfoW2K
->fBootMethod
= serverinfo
->fBootMethod
;
218 r
->ServerInfoW2K
->fAdminConfigured
= serverinfo
->fAdminConfigured
;
219 r
->ServerInfoW2K
->fAllowUpdate
= serverinfo
->fAllowUpdate
;
220 r
->ServerInfoW2K
->fDsAvailable
= serverinfo
->fDsAvailable
;
221 r
->ServerInfoW2K
->pszServerName
= talloc_strdup(mem_ctx
, serverinfo
->pszServerName
);
222 r
->ServerInfoW2K
->pszDsContainer
= talloc_strdup(mem_ctx
, serverinfo
->pszDsContainer
);
223 r
->ServerInfoW2K
->aipServerAddrs
= dns_addr_array_to_ip4_array(mem_ctx
,
224 serverinfo
->aipServerAddrs
);
225 r
->ServerInfoW2K
->aipListenAddrs
= dns_addr_array_to_ip4_array(mem_ctx
,
226 serverinfo
->aipListenAddrs
);
227 r
->ServerInfoW2K
->aipForwarders
= ip4_array_copy(mem_ctx
, serverinfo
->aipForwarders
);
228 r
->ServerInfoW2K
->dwLogLevel
= serverinfo
->dwLogLevel
;
229 r
->ServerInfoW2K
->dwDebugLevel
= serverinfo
->dwDebugLevel
;
230 r
->ServerInfoW2K
->dwForwardTimeout
= serverinfo
->dwForwardTimeout
;
231 r
->ServerInfoW2K
->dwRpcProtocol
= serverinfo
->dwRpcProtocol
;
232 r
->ServerInfoW2K
->dwNameCheckFlag
= serverinfo
->dwNameCheckFlag
;
233 r
->ServerInfoW2K
->cAddressAnswerLimit
= serverinfo
->cAddressAnswerLimit
;
234 r
->ServerInfoW2K
->dwRecursionRetry
= serverinfo
->dwRecursionRetry
;
235 r
->ServerInfoW2K
->dwRecursionTimeout
= serverinfo
->dwRecursionTimeout
;
236 r
->ServerInfoW2K
->dwMaxCacheTtl
= serverinfo
->dwMaxCacheTtl
;
237 r
->ServerInfoW2K
->dwDsPollingInterval
= serverinfo
->dwDsPollingInterval
;
238 r
->ServerInfoW2K
->dwScavengingInterval
= serverinfo
->dwScavengingInterval
;
239 r
->ServerInfoW2K
->dwDefaultRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
240 r
->ServerInfoW2K
->dwDefaultNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
241 r
->ServerInfoW2K
->fAutoReverseZones
= serverinfo
->fAutoReverseZones
;
242 r
->ServerInfoW2K
->fAutoCacheUpdate
= serverinfo
->fAutoCacheUpdate
;
243 r
->ServerInfoW2K
->fRecurseAfterForwarding
= serverinfo
->fRecurseAfterForwarding
;
244 r
->ServerInfoW2K
->fForwardDelegations
= serverinfo
->fForwardDelegations
;
245 r
->ServerInfoW2K
->fNoRecursion
= serverinfo
->fNoRecursion
;
246 r
->ServerInfoW2K
->fSecureResponses
= serverinfo
->fSecureResponses
;
247 r
->ServerInfoW2K
->fRoundRobin
= serverinfo
->fRoundRobin
;
248 r
->ServerInfoW2K
->fLocalNetPriority
= serverinfo
->fLocalNetPriority
;
249 r
->ServerInfoW2K
->fBindSecondaries
= serverinfo
->fBindSecondaries
;
250 r
->ServerInfoW2K
->fWriteAuthorityNs
= serverinfo
->fWriteAuthorityNs
;
251 r
->ServerInfoW2K
->fStrictFileParsing
= serverinfo
->fStrictFileParsing
;
252 r
->ServerInfoW2K
->fLooseWildcarding
= serverinfo
->fLooseWildcarding
;
253 r
->ServerInfoW2K
->fDefaultAgingState
= serverinfo
->fDefaultAgingState
;
255 } else if (client_version
== DNS_CLIENT_VERSION_DOTNET
) {
256 *typeid = DNSSRV_TYPEID_SERVER_INFO_DOTNET
;
257 r
->ServerInfoDotNet
= talloc_zero(mem_ctx
, struct DNS_RPC_SERVER_INFO_DOTNET
);
259 r
->ServerInfoDotNet
->dwRpcStructureVersion
= 0x01;
260 r
->ServerInfoDotNet
->dwVersion
= serverinfo
->dwVersion
;
261 r
->ServerInfoDotNet
->fBootMethod
= serverinfo
->fBootMethod
;
262 r
->ServerInfoDotNet
->fAdminConfigured
= serverinfo
->fAdminConfigured
;
263 r
->ServerInfoDotNet
->fAllowUpdate
= serverinfo
->fAllowUpdate
;
264 r
->ServerInfoDotNet
->fDsAvailable
= serverinfo
->fDsAvailable
;
265 r
->ServerInfoDotNet
->pszServerName
= talloc_strdup(mem_ctx
, serverinfo
->pszServerName
);
266 r
->ServerInfoDotNet
->pszDsContainer
= talloc_strdup(mem_ctx
, serverinfo
->pszDsContainer
);
267 r
->ServerInfoDotNet
->aipServerAddrs
= dns_addr_array_to_ip4_array(mem_ctx
,
268 serverinfo
->aipServerAddrs
);
269 r
->ServerInfoDotNet
->aipListenAddrs
= dns_addr_array_to_ip4_array(mem_ctx
,
270 serverinfo
->aipListenAddrs
);
271 r
->ServerInfoDotNet
->aipForwarders
= ip4_array_copy(mem_ctx
, serverinfo
->aipForwarders
);
272 r
->ServerInfoDotNet
->aipLogFilter
= ip4_array_copy(mem_ctx
, serverinfo
->aipLogFilter
);
273 r
->ServerInfoDotNet
->pwszLogFilePath
= talloc_strdup(mem_ctx
, serverinfo
->pwszLogFilePath
);
274 r
->ServerInfoDotNet
->pszDomainName
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainName
);
275 r
->ServerInfoDotNet
->pszForestName
= talloc_strdup(mem_ctx
, serverinfo
->pszForestName
);
276 r
->ServerInfoDotNet
->pszDomainDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainDirectoryPartition
);
277 r
->ServerInfoDotNet
->pszForestDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszForestDirectoryPartition
);
278 r
->ServerInfoDotNet
->dwLogLevel
= serverinfo
->dwLogLevel
;
279 r
->ServerInfoDotNet
->dwDebugLevel
= serverinfo
->dwDebugLevel
;
280 r
->ServerInfoDotNet
->dwForwardTimeout
= serverinfo
->dwForwardTimeout
;
281 r
->ServerInfoDotNet
->dwRpcProtocol
= serverinfo
->dwRpcProtocol
;
282 r
->ServerInfoDotNet
->dwNameCheckFlag
= serverinfo
->dwNameCheckFlag
;
283 r
->ServerInfoDotNet
->cAddressAnswerLimit
= serverinfo
->cAddressAnswerLimit
;
284 r
->ServerInfoDotNet
->dwRecursionRetry
= serverinfo
->dwRecursionRetry
;
285 r
->ServerInfoDotNet
->dwRecursionTimeout
= serverinfo
->dwRecursionTimeout
;
286 r
->ServerInfoDotNet
->dwMaxCacheTtl
= serverinfo
->dwMaxCacheTtl
;
287 r
->ServerInfoDotNet
->dwDsPollingInterval
= serverinfo
->dwDsPollingInterval
;
288 r
->ServerInfoDotNet
->dwLocalNetPriorityNetMask
= serverinfo
->dwLocalNetPriorityNetMask
;
289 r
->ServerInfoDotNet
->dwScavengingInterval
= serverinfo
->dwScavengingInterval
;
290 r
->ServerInfoDotNet
->dwDefaultRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
291 r
->ServerInfoDotNet
->dwDefaultNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
292 r
->ServerInfoDotNet
->dwLastScavengeTime
= serverinfo
->dwLastScavengeTime
;
293 r
->ServerInfoDotNet
->dwEventLogLevel
= serverinfo
->dwEventLogLevel
;
294 r
->ServerInfoDotNet
->dwLogFileMaxSize
= serverinfo
->dwLogFileMaxSize
;
295 r
->ServerInfoDotNet
->dwDsForestVersion
= serverinfo
->dwDsForestVersion
;
296 r
->ServerInfoDotNet
->dwDsDomainVersion
= serverinfo
->dwDsDomainVersion
;
297 r
->ServerInfoDotNet
->dwDsDsaVersion
= serverinfo
->dwDsDsaVersion
;
298 r
->ServerInfoDotNet
->fAutoReverseZones
= serverinfo
->fAutoReverseZones
;
299 r
->ServerInfoDotNet
->fAutoCacheUpdate
= serverinfo
->fAutoCacheUpdate
;
300 r
->ServerInfoDotNet
->fRecurseAfterForwarding
= serverinfo
->fRecurseAfterForwarding
;
301 r
->ServerInfoDotNet
->fForwardDelegations
= serverinfo
->fForwardDelegations
;
302 r
->ServerInfoDotNet
->fNoRecursion
= serverinfo
->fNoRecursion
;
303 r
->ServerInfoDotNet
->fSecureResponses
= serverinfo
->fSecureResponses
;
304 r
->ServerInfoDotNet
->fRoundRobin
= serverinfo
->fRoundRobin
;
305 r
->ServerInfoDotNet
->fLocalNetPriority
= serverinfo
->fLocalNetPriority
;
306 r
->ServerInfoDotNet
->fBindSecondaries
= serverinfo
->fBindSecondaries
;
307 r
->ServerInfoDotNet
->fWriteAuthorityNs
= serverinfo
->fWriteAuthorityNs
;
308 r
->ServerInfoDotNet
->fStrictFileParsing
= serverinfo
->fStrictFileParsing
;
309 r
->ServerInfoDotNet
->fLooseWildcarding
= serverinfo
->fLooseWildcarding
;
310 r
->ServerInfoDotNet
->fDefaultAgingState
= serverinfo
->fDefaultAgingState
;
312 } else if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
313 *typeid = DNSSRV_TYPEID_SERVER_INFO
;
314 r
->ServerInfo
= talloc_zero(mem_ctx
, struct DNS_RPC_SERVER_INFO_LONGHORN
);
316 r
->ServerInfo
->dwRpcStructureVersion
= 0x02;
317 r
->ServerInfo
->dwVersion
= serverinfo
->dwVersion
;
318 r
->ServerInfo
->fBootMethod
= serverinfo
->fBootMethod
;
319 r
->ServerInfo
->fAdminConfigured
= serverinfo
->fAdminConfigured
;
320 r
->ServerInfo
->fAllowUpdate
= serverinfo
->fAllowUpdate
;
321 r
->ServerInfo
->fDsAvailable
= serverinfo
->fDsAvailable
;
322 r
->ServerInfo
->pszServerName
= talloc_strdup(mem_ctx
, serverinfo
->pszServerName
);
323 r
->ServerInfo
->pszDsContainer
= talloc_strdup(mem_ctx
, serverinfo
->pszDsContainer
);
324 r
->ServerInfo
->aipServerAddrs
= serverinfo
->aipServerAddrs
;
325 r
->ServerInfo
->aipListenAddrs
= serverinfo
->aipListenAddrs
;
326 r
->ServerInfo
->aipForwarders
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipForwarders
);
327 r
->ServerInfo
->aipLogFilter
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipLogFilter
);
328 r
->ServerInfo
->pwszLogFilePath
= talloc_strdup(mem_ctx
, serverinfo
->pwszLogFilePath
);
329 r
->ServerInfo
->pszDomainName
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainName
);
330 r
->ServerInfo
->pszForestName
= talloc_strdup(mem_ctx
, serverinfo
->pszForestName
);
331 r
->ServerInfo
->pszDomainDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainDirectoryPartition
);
332 r
->ServerInfo
->pszForestDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszForestDirectoryPartition
);
333 r
->ServerInfo
->dwLogLevel
= serverinfo
->dwLogLevel
;
334 r
->ServerInfo
->dwDebugLevel
= serverinfo
->dwDebugLevel
;
335 r
->ServerInfo
->dwForwardTimeout
= serverinfo
->dwForwardTimeout
;
336 r
->ServerInfo
->dwRpcProtocol
= serverinfo
->dwRpcProtocol
;
337 r
->ServerInfo
->dwNameCheckFlag
= serverinfo
->dwNameCheckFlag
;
338 r
->ServerInfo
->cAddressAnswerLimit
= serverinfo
->cAddressAnswerLimit
;
339 r
->ServerInfo
->dwRecursionRetry
= serverinfo
->dwRecursionRetry
;
340 r
->ServerInfo
->dwRecursionTimeout
= serverinfo
->dwRecursionTimeout
;
341 r
->ServerInfo
->dwMaxCacheTtl
= serverinfo
->dwMaxCacheTtl
;
342 r
->ServerInfo
->dwDsPollingInterval
= serverinfo
->dwDsPollingInterval
;
343 r
->ServerInfo
->dwLocalNetPriorityNetMask
= serverinfo
->dwLocalNetPriorityNetMask
;
344 r
->ServerInfo
->dwScavengingInterval
= serverinfo
->dwScavengingInterval
;
345 r
->ServerInfo
->dwDefaultRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
346 r
->ServerInfo
->dwDefaultNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
347 r
->ServerInfo
->dwLastScavengeTime
= serverinfo
->dwLastScavengeTime
;
348 r
->ServerInfo
->dwEventLogLevel
= serverinfo
->dwEventLogLevel
;
349 r
->ServerInfo
->dwLogFileMaxSize
= serverinfo
->dwLogFileMaxSize
;
350 r
->ServerInfo
->dwDsForestVersion
= serverinfo
->dwDsForestVersion
;
351 r
->ServerInfo
->dwDsDomainVersion
= serverinfo
->dwDsDomainVersion
;
352 r
->ServerInfo
->dwDsDsaVersion
= serverinfo
->dwDsDsaVersion
;
353 r
->ServerInfo
->fReadOnlyDC
= serverinfo
->fReadOnlyDC
;
354 r
->ServerInfo
->fAutoReverseZones
= serverinfo
->fAutoReverseZones
;
355 r
->ServerInfo
->fAutoCacheUpdate
= serverinfo
->fAutoCacheUpdate
;
356 r
->ServerInfo
->fRecurseAfterForwarding
= serverinfo
->fRecurseAfterForwarding
;
357 r
->ServerInfo
->fForwardDelegations
= serverinfo
->fForwardDelegations
;
358 r
->ServerInfo
->fNoRecursion
= serverinfo
->fNoRecursion
;
359 r
->ServerInfo
->fSecureResponses
= serverinfo
->fSecureResponses
;
360 r
->ServerInfo
->fRoundRobin
= serverinfo
->fRoundRobin
;
361 r
->ServerInfo
->fLocalNetPriority
= serverinfo
->fLocalNetPriority
;
362 r
->ServerInfo
->fBindSecondaries
= serverinfo
->fBindSecondaries
;
363 r
->ServerInfo
->fWriteAuthorityNs
= serverinfo
->fWriteAuthorityNs
;
364 r
->ServerInfo
->fStrictFileParsing
= serverinfo
->fStrictFileParsing
;
365 r
->ServerInfo
->fLooseWildcarding
= serverinfo
->fLooseWildcarding
;
366 r
->ServerInfo
->fDefaultAgingState
= serverinfo
->fDefaultAgingState
;
374 if (strcasecmp(operation
, "AddressAnswerLimit") == 0) {
375 answer_integer
= serverinfo
->cAddressAnswerLimit
;
377 } else if (strcasecmp(operation
, "AdminConfigured") == 0) {
378 answer_integer
= serverinfo
->fAdminConfigured
;
380 } else if (strcasecmp(operation
, "AllowCNAMEAtNS") == 0) {
383 } else if (strcasecmp(operation
, "AllowUpdate") == 0) {
384 answer_integer
= serverinfo
->fAllowUpdate
;
386 } else if (strcasecmp(operation
, "AutoCacheUpdate") == 0) {
387 answer_integer
= serverinfo
->fAutoCacheUpdate
;
389 } else if (strcasecmp(operation
, "AutoConfigFileZones") == 0) {
392 } else if (strcasecmp(operation
, "BindSecondaries") == 0) {
393 answer_integer
= serverinfo
->fBindSecondaries
;
395 } else if (strcasecmp(operation
, "BootMethod") == 0) {
396 answer_integer
= serverinfo
->fBootMethod
;
398 } else if (strcasecmp(operation
, "DebugLevel") == 0) {
399 answer_integer
= serverinfo
->dwDebugLevel
;
401 } else if (strcasecmp(operation
, "DefaultAgingState") == 0) {
402 answer_integer
= serverinfo
->fDefaultAgingState
;
404 } else if (strcasecmp(operation
, "DefaultNoRefreshInterval") == 0) {
405 answer_integer
= serverinfo
->dwDefaultNoRefreshInterval
;
407 } else if (strcasecmp(operation
, "DefaultRefreshInterval") == 0) {
408 answer_integer
= serverinfo
->dwDefaultRefreshInterval
;
410 } else if (strcasecmp(operation
, "DeleteOutsideGlue") == 0) {
413 } else if (strcasecmp(operation
, "DisjointNets") == 0) {
416 } else if (strcasecmp(operation
, "DsLazyUpdateInterval") == 0) {
417 answer_integer
= 3; /* seconds */
419 } else if (strcasecmp(operation
, "DsPollingInterval") == 0) {
420 answer_integer
= serverinfo
->dwDsPollingInterval
;
422 } else if (strcasecmp(operation
, "DsTombstoneInterval") == 0) {
423 answer_integer
= 0x00127500; /* 14 days */
425 } else if (strcasecmp(operation
, "EnableRegistryBoot") == 0) {
428 } else if (strcasecmp(operation
, "EventLogLevel") == 0) {
429 answer_integer
= serverinfo
->dwEventLogLevel
;
431 } else if (strcasecmp(operation
, "ForceSoaSerial") == 0) {
434 } else if (strcasecmp(operation
, "ForceSaoRetry") == 0) {
437 } else if (strcasecmp(operation
, "ForceSoaRefresh") == 0) {
440 } else if (strcasecmp(operation
, "ForceSoaMinimumTtl") == 0) {
443 } else if (strcasecmp(operation
, "ForwardDelegations") == 0) {
446 } else if (strcasecmp(operation
, "ForwardingTimeout") == 0) {
447 answer_integer
= serverinfo
->dwForwardTimeout
;
449 } else if (strcasecmp(operation
, "IsSlave") == 0) {
452 } else if (strcasecmp(operation
, "LocalNetPriority") == 0) {
453 answer_integer
= serverinfo
->fLocalNetPriority
;
455 } else if (strcasecmp(operation
, "LogFileMaxSize") == 0) {
456 answer_integer
= serverinfo
->dwLogFileMaxSize
;
458 } else if (strcasecmp(operation
, "LogLevel") == 0) {
459 answer_integer
= serverinfo
->dwLogLevel
;
461 } else if (strcasecmp(operation
, "LooseWildcarding") == 0) {
462 answer_integer
= serverinfo
->fLooseWildcarding
;
464 } else if (strcasecmp(operation
, "MaxCacheTtl") == 0) {
465 answer_integer
= serverinfo
->dwMaxCacheTtl
;
467 } else if (strcasecmp(operation
, "MaxNegativeCacheTtl") == 0) {
468 answer_integer
= 0x00000384; /* 15 minutes */
470 } else if (strcasecmp(operation
, "NameCheckFlag") == 0) {
471 answer_integer
= serverinfo
->dwNameCheckFlag
;
473 } else if (strcasecmp(operation
, "NoRecursion") == 0) {
474 answer_integer
= serverinfo
->fNoRecursion
;
476 } else if (strcasecmp(operation
, "NoUpdateDelegations") == 0) {
479 } else if (strcasecmp(operation
, "PublishAutonet") == 0) {
482 } else if (strcasecmp(operation
, "QuietRecvFaultInterval") == 0) {
485 } else if (strcasecmp(operation
, "QuietRecvLogInterval") == 0) {
488 } else if (strcasecmp(operation
, "RecursionRetry") == 0) {
489 answer_integer
= serverinfo
->dwRecursionRetry
;
491 } else if (strcasecmp(operation
, "RecursionTimeout") == 0) {
492 answer_integer
= serverinfo
->dwRecursionTimeout
;
494 } else if (strcasecmp(operation
, "ReloadException") == 0) {
497 } else if (strcasecmp(operation
, "RoundRobin") == 0) {
498 answer_integer
= serverinfo
->fRoundRobin
;
500 } else if (strcasecmp(operation
, "RpcProtocol") == 0) {
501 answer_integer
= serverinfo
->dwRpcProtocol
;
503 } else if (strcasecmp(operation
, "SecureResponses") == 0) {
504 answer_integer
= serverinfo
->fSecureResponses
;
506 } else if (strcasecmp(operation
, "SendPort") == 0) {
509 } else if (strcasecmp(operation
, "ScavengingInterval") == 0) {
510 answer_integer
= serverinfo
->dwScavengingInterval
;
512 } else if (strcasecmp(operation
, "SocketPoolSize") == 0) {
513 answer_integer
= 0x000009C4;
515 } else if (strcasecmp(operation
, "StrictFileParsing") == 0) {
516 answer_integer
= serverinfo
->fStrictFileParsing
;
518 } else if (strcasecmp(operation
, "SyncDnsZoneSerial") == 0) {
519 answer_integer
= 2; /* ZONE_SERIAL_SYNC_XFER */
521 } else if (strcasecmp(operation
, "UpdateOptions") == 0) {
522 answer_integer
= 0x0000030F; /* DNS_DEFAULT_UPDATE_OPTIONS */
524 } else if (strcasecmp(operation
, "UseSystemEvengLog") == 0) {
527 } else if (strcasecmp(operation
, "Version") == 0) {
528 answer_integer
= serverinfo
->dwVersion
;
530 } else if (strcasecmp(operation
, "XfrConnectTimeout") == 0) {
531 answer_integer
= 0x0000001E;
533 } else if (strcasecmp(operation
, "WriteAuthorityNs") == 0) {
534 answer_integer
= serverinfo
->fWriteAuthorityNs
;
536 } else if (strcasecmp(operation
, "AdditionalRecursionTimeout") == 0) {
537 answer_integer
= 0x00000004;
539 } else if (strcasecmp(operation
, "AppendMsZoneTransferFlag") == 0) {
542 } else if (strcasecmp(operation
, "AutoCreateDelegations") == 0) {
543 answer_integer
= 0; /* DNS_ACD_DONT_CREATE */
545 } else if (strcasecmp(operation
, "BreakOnAscFailure") == 0) {
548 } else if (strcasecmp(operation
, "CacheEmptyAuthResponses") == 0) {
551 } else if (strcasecmp(operation
, "DirectoryPartitionAutoEnlistInterval") == 0) {
552 answer_integer
= 0x00015180; /* 1 day */
554 } else if (strcasecmp(operation
, "DisableAutoReverseZones") == 0) {
555 answer_integer
= ~serverinfo
->fAutoReverseZones
;
557 } else if (strcasecmp(operation
, "EDnsCacheTimeout") == 0) {
558 answer_integer
= 0x00000384; /* 15 minutes */
560 } else if (strcasecmp(operation
, "EnableDirectoryPartitions") == 0) {
561 answer_integer
= serverinfo
->fDsAvailable
;
563 } else if (strcasecmp(operation
, "EnableDnsSec") == 0) {
566 } else if (strcasecmp(operation
, "EnableEDnsProbes") == 0) {
569 } else if (strcasecmp(operation
, "EnableEDnsReception") == 0) {
572 } else if (strcasecmp(operation
, "EnableIPv6") == 0) {
575 } else if (strcasecmp(operation
, "EnableIQueryResponseGeneration") == 0) {
578 } else if (strcasecmp(operation
, "EnableSendErrorSuppression") == 0) {
581 } else if (strcasecmp(operation
, "EnableUpdateForwarding") == 0) {
584 } else if (strcasecmp(operation
, "EnableWinsR") == 0) {
587 } else if (strcasecmp(operation
, "ForceDsaBehaviorVersion") == 0) {
588 answer_integer
= serverinfo
->dwDsDsaVersion
;
590 } else if (strcasecmp(operation
, "ForceDomainBehaviorVersion") == 0) {
591 answer_integer
= serverinfo
->dwDsDsaVersion
;
593 } else if (strcasecmp(operation
, "ForceForestBehaviorVersion") == 0) {
594 answer_integer
= serverinfo
->dwDsDsaVersion
;
596 } else if (strcasecmp(operation
, "HeapDebug") == 0) {
599 } else if (strcasecmp(operation
, "LameDelegationTtl") == 0) {
600 answer_integer
= 0; /* seconds */
602 } else if (strcasecmp(operation
, "LocalNetPriorityNetMask") == 0) {
603 answer_integer
= serverinfo
->dwLocalNetPriorityNetMask
;
605 } else if (strcasecmp(operation
, "MaxCacheSize") == 0) {
608 } else if (strcasecmp(operation
, "MaxResourceRecordsInNonSecureUpdate") == 0) {
609 answer_integer
= 0x0000001E;
611 } else if (strcasecmp(operation
, "OperationsLogLevel") == 0) {
614 } else if (strcasecmp(operation
, "OperationsLogLevel2") == 0) {
617 } else if (strcasecmp(operation
, "MaximumUdpPacketSize") == 0) {
618 answer_integer
= 0x00004000; /* maximum possible */
620 } else if (strcasecmp(operation
, "RecurseToInternetRootMask") == 0) {
623 } else if (strcasecmp(operation
, "SelfTest") == 0) {
626 } else if (strcasecmp(operation
, "SilentlyIgnoreCNameUpdateConflicts") == 0) {
629 } else if (strcasecmp(operation
, "TcpReceivePacketSize") == 0) {
630 answer_integer
= 0x00010000;
632 } else if (strcasecmp(operation
, "XfrThrottleMultiplier") == 0) {
633 answer_integer
= 0x0000000A;
635 } else if (strcasecmp(operation
, "AllowMsdcsLookupRetry") == 0) {
638 } else if (strcasecmp(operation
, "AllowReadOnlyZoneTransfer") == 0) {
641 } else if (strcasecmp(operation
, "DsBackGroundLoadPaused") == 0) {
644 } else if (strcasecmp(operation
, "DsMinimumBackgroundLoadThreads") == 0) {
647 } else if (strcasecmp(operation
, "DsRemoteReplicationDelay") == 0) {
648 answer_integer
= 0x0000001E; /* 30 seconds */
650 } else if (strcasecmp(operation
, "EnableDuplicateQuerySuppresion") == 0) {
653 } else if (strcasecmp(operation
, "EnableGlobalNamesSupport") == 0) {
656 } else if (strcasecmp(operation
, "EnableVersionQuery") == 0) {
657 answer_integer
= 1; /* DNS_VERSION_QUERY_FULL */
659 } else if (strcasecmp(operation
, "EnableRsoForRodc") == 0) {
662 } else if (strcasecmp(operation
, "ForceRODCMode") == 0) {
665 } else if (strcasecmp(operation
, "GlobalNamesAlwaysQuerySrv") == 0) {
668 } else if (strcasecmp(operation
, "GlobalNamesBlockUpdates") == 0) {
671 } else if (strcasecmp(operation
, "GlobalNamesEnableEDnsProbes") == 0) {
674 } else if (strcasecmp(operation
, "GlobalNamesPreferAAAA") == 0) {
677 } else if (strcasecmp(operation
, "GlobalNamesQueryOrder") == 0) {
680 } else if (strcasecmp(operation
, "GlobalNamesSendTimeout") == 0) {
681 answer_integer
= 3; /* seconds */
683 } else if (strcasecmp(operation
, "GlobalNamesServerQueryInterval") == 0) {
684 answer_integer
= 0x00005460; /* 6 hours */
686 } else if (strcasecmp(operation
, "RemoteIPv4RankBoost") == 0) {
689 } else if (strcasecmp(operation
, "RemoteIPv6RankBoost") == 0) {
692 } else if (strcasecmp(operation
, "MaximumRodcRsoAttemptsPerCycle") == 0) {
693 answer_integer
= 0x00000064;
695 } else if (strcasecmp(operation
, "MaximumRodcRsoQueueLength") == 0) {
696 answer_integer
= 0x0000012C;
698 } else if (strcasecmp(operation
, "EnableGlobalQueryBlockList") == 0) {
701 } else if (strcasecmp(operation
, "OpenACLOnProxyUpdates") == 0) {
704 } else if (strcasecmp(operation
, "CacheLockingPercent") == 0) {
705 answer_integer
= 0x00000064;
709 if (is_integer
== 1) {
710 *typeid = DNSSRV_TYPEID_DWORD
;
711 r
->Dword
= answer_integer
;
717 if (strcasecmp(operation
, "Forwarders") == 0) {
718 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
719 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipForwarders
);
721 answer_iparray
= ip4_array_copy(mem_ctx
, serverinfo
->aipForwarders
);
724 } else if (strcasecmp(operation
, "ListenAddresses") == 0) {
725 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
726 answer_addrarray
= serverinfo
->aipListenAddrs
;
728 answer_iparray
= dns_addr_array_to_ip4_array(mem_ctx
, serverinfo
->aipListenAddrs
);
731 } else if (strcasecmp(operation
, "BreakOnReceiveFrom") == 0) {
733 } else if (strcasecmp(operation
, "BreakOnUpdateFrom") == 0) {
735 } else if (strcasecmp(operation
, "LogIPFilterList") == 0) {
736 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
737 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipLogFilter
);
739 answer_iparray
= ip4_array_copy(mem_ctx
, serverinfo
->aipLogFilter
);
744 if (is_addresses
== 1) {
745 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
746 *typeid = DNSSRV_TYPEID_ADDRARRAY
;
747 r
->AddrArray
= answer_addrarray
;
749 *typeid = DNSSRV_TYPEID_IPARRAY
;
750 r
->IpArray
= answer_iparray
;
755 is_string
= is_wstring
= 0;
757 if (strcasecmp(operation
, "DomainDirectoryPartitionBaseName") == 0) {
758 answer_string
= talloc_strdup(mem_ctx
, "DomainDnsZones");
759 if (! answer_string
) {
760 return WERR_OUTOFMEMORY
;
763 } else if (strcasecmp(operation
, "ForestDirectoryPartitionBaseName") == 0) {
764 answer_string
= talloc_strdup(mem_ctx
, "ForestDnsZones");
765 if (! answer_string
) {
766 return WERR_OUTOFMEMORY
;
769 } else if (strcasecmp(operation
, "LogFilePath") == 0) {
770 answer_string
= talloc_strdup(mem_ctx
, serverinfo
->pwszLogFilePath
);
772 } else if (strcasecmp(operation
, "ServerLevelPluginDll") == 0) {
774 } else if (strcasecmp(operation
, "DsBackgroundPauseName") == 0) {
776 } else if (strcasecmp(operation
, "DsNotRoundRobinTypes") == 0) {
780 if (is_string
== 1) {
781 *typeid = DNSSRV_TYPEID_LPSTR
;
782 r
->String
= answer_string
;
784 } else if (is_wstring
== 1) {
785 *typeid = DNSSRV_TYPEID_LPWSTR
;
786 r
->WideString
= answer_string
;
792 if (strcasecmp(operation
, "GlobalQueryBlockList") == 0) {
794 } else if (strcasecmp(operation
, "SocketPoolExcludedPortRanges") == 0) {
798 if (is_stringlist
== 1) {
799 *typeid = DNSSRV_TYPEID_UTF8_STRING_LIST
;
800 r
->Utf8StringList
= answer_stringlist
;
804 DEBUG(0,("dnsserver: Invalid server operation %s\n", operation
));
805 return WERR_DNS_ERROR_INVALID_PROPERTY
;
808 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
809 static WERROR
dnsserver_query_zone(struct dnsserver_state
*dsstate
,
811 struct dnsserver_zone
*z
,
812 const char *operation
,
813 const unsigned int client_version
,
814 enum DNS_RPC_TYPEID
*typeid,
815 union DNSSRV_RPC_UNION
*r
)
817 uint8_t is_integer
, is_addresses
, is_string
;
818 uint32_t answer_integer
= 0;
819 struct IP4_ARRAY
*answer_iparray
= NULL
;
820 struct DNS_ADDR_ARRAY
*answer_addrarray
= NULL
;
821 char *answer_string
= NULL
;
822 struct dnsserver_zoneinfo
*zoneinfo
;
824 zoneinfo
= z
->zoneinfo
;
826 if (strcasecmp(operation
, "Zone") == 0) {
827 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
828 *typeid = DNSSRV_TYPEID_ZONE_W2K
;
829 r
->ZoneW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_W2K
);
831 r
->ZoneW2K
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
832 r
->ZoneW2K
->Flags
= zoneinfo
->Flags
;
833 r
->ZoneW2K
->ZoneType
= zoneinfo
->dwZoneType
;
834 r
->ZoneW2K
->Version
= zoneinfo
->Version
;
836 *typeid = DNSSRV_TYPEID_ZONE
;
837 r
->Zone
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_DOTNET
);
839 r
->Zone
->dwRpcStructureVersion
= 0x01;
840 r
->Zone
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
841 r
->Zone
->Flags
= zoneinfo
->Flags
;
842 r
->Zone
->ZoneType
= zoneinfo
->dwZoneType
;
843 r
->Zone
->Version
= zoneinfo
->Version
;
844 r
->Zone
->dwDpFlags
= z
->partition
->dwDpFlags
;
845 r
->Zone
->pszDpFqdn
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
850 if (strcasecmp(operation
, "ZoneInfo") == 0) {
851 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
852 *typeid = DNSSRV_TYPEID_ZONE_INFO_W2K
;
853 r
->ZoneInfoW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_INFO_W2K
);
855 r
->ZoneInfoW2K
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
856 r
->ZoneInfoW2K
->dwZoneType
= zoneinfo
->dwZoneType
;
857 r
->ZoneInfoW2K
->fReverse
= zoneinfo
->fReverse
;
858 r
->ZoneInfoW2K
->fAllowUpdate
= zoneinfo
->fAllowUpdate
;
859 r
->ZoneInfoW2K
->fPaused
= zoneinfo
->fPaused
;
860 r
->ZoneInfoW2K
->fShutdown
= zoneinfo
->fShutdown
;
861 r
->ZoneInfoW2K
->fAutoCreated
= zoneinfo
->fAutoCreated
;
862 r
->ZoneInfoW2K
->fUseDatabase
= zoneinfo
->fUseDatabase
;
863 r
->ZoneInfoW2K
->pszDataFile
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
864 r
->ZoneInfoW2K
->aipMasters
= ip4_array_copy(mem_ctx
, zoneinfo
->aipMasters
);
865 r
->ZoneInfoW2K
->fSecureSecondaries
= zoneinfo
->fSecureSecondaries
;
866 r
->ZoneInfoW2K
->fNotifyLevel
= zoneinfo
->fNotifyLevel
;
867 r
->ZoneInfoW2K
->aipSecondaries
= ip4_array_copy(mem_ctx
, zoneinfo
->aipSecondaries
);
868 r
->ZoneInfoW2K
->aipNotify
= ip4_array_copy(mem_ctx
, zoneinfo
->aipNotify
);
869 r
->ZoneInfoW2K
->fUseWins
= zoneinfo
->fUseWins
;
870 r
->ZoneInfoW2K
->fUseNbstat
= zoneinfo
->fUseNbstat
;
871 r
->ZoneInfoW2K
->fAging
= zoneinfo
->fAging
;
872 r
->ZoneInfoW2K
->dwNoRefreshInterval
= zoneinfo
->dwNoRefreshInterval
;
873 r
->ZoneInfoW2K
->dwRefreshInterval
= zoneinfo
->dwRefreshInterval
;
874 r
->ZoneInfoW2K
->dwAvailForScavengeTime
= zoneinfo
->dwAvailForScavengeTime
;
875 r
->ZoneInfoW2K
->aipScavengeServers
= ip4_array_copy(mem_ctx
, zoneinfo
->aipScavengeServers
);
877 } else if (client_version
== DNS_CLIENT_VERSION_DOTNET
) {
878 *typeid = DNSSRV_TYPEID_ZONE_INFO_DOTNET
;
879 r
->ZoneInfoDotNet
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_INFO_DOTNET
);
881 r
->ZoneInfoDotNet
->dwRpcStructureVersion
= 0x01;
882 r
->ZoneInfoDotNet
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
883 r
->ZoneInfoDotNet
->dwZoneType
= zoneinfo
->dwZoneType
;
884 r
->ZoneInfoDotNet
->fReverse
= zoneinfo
->fReverse
;
885 r
->ZoneInfoDotNet
->fAllowUpdate
= zoneinfo
->fAllowUpdate
;
886 r
->ZoneInfoDotNet
->fPaused
= zoneinfo
->fPaused
;
887 r
->ZoneInfoDotNet
->fShutdown
= zoneinfo
->fShutdown
;
888 r
->ZoneInfoDotNet
->fAutoCreated
= zoneinfo
->fAutoCreated
;
889 r
->ZoneInfoDotNet
->fUseDatabase
= zoneinfo
->fUseDatabase
;
890 r
->ZoneInfoDotNet
->pszDataFile
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
891 r
->ZoneInfoDotNet
->aipMasters
= ip4_array_copy(mem_ctx
, zoneinfo
->aipMasters
);
892 r
->ZoneInfoDotNet
->fSecureSecondaries
= zoneinfo
->fSecureSecondaries
;
893 r
->ZoneInfoDotNet
->fNotifyLevel
= zoneinfo
->fNotifyLevel
;
894 r
->ZoneInfoDotNet
->aipSecondaries
= ip4_array_copy(mem_ctx
, zoneinfo
->aipSecondaries
);
895 r
->ZoneInfoDotNet
->aipNotify
= ip4_array_copy(mem_ctx
, zoneinfo
->aipNotify
);
896 r
->ZoneInfoDotNet
->fUseWins
= zoneinfo
->fUseWins
;
897 r
->ZoneInfoDotNet
->fUseNbstat
= zoneinfo
->fUseNbstat
;
898 r
->ZoneInfoDotNet
->fAging
= zoneinfo
->fAging
;
899 r
->ZoneInfoDotNet
->dwNoRefreshInterval
= zoneinfo
->dwNoRefreshInterval
;
900 r
->ZoneInfoDotNet
->dwRefreshInterval
= zoneinfo
->dwRefreshInterval
;
901 r
->ZoneInfoDotNet
->dwAvailForScavengeTime
= zoneinfo
->dwAvailForScavengeTime
;
902 r
->ZoneInfoDotNet
->aipScavengeServers
= ip4_array_copy(mem_ctx
, zoneinfo
->aipScavengeServers
);
903 r
->ZoneInfoDotNet
->dwForwarderTimeout
= zoneinfo
->dwForwarderTimeout
;
904 r
->ZoneInfoDotNet
->fForwarderSlave
= zoneinfo
->fForwarderSlave
;
905 r
->ZoneInfoDotNet
->aipLocalMasters
= ip4_array_copy(mem_ctx
, zoneinfo
->aipLocalMasters
);
906 r
->ZoneInfoDotNet
->dwDpFlags
= z
->partition
->dwDpFlags
;
907 r
->ZoneInfoDotNet
->pszDpFqdn
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
908 r
->ZoneInfoDotNet
->pwszZoneDn
= talloc_strdup(mem_ctx
, zoneinfo
->pwszZoneDn
);
909 r
->ZoneInfoDotNet
->dwLastSuccessfulSoaCheck
= zoneinfo
->dwLastSuccessfulSoaCheck
;
910 r
->ZoneInfoDotNet
->dwLastSuccessfulXfr
= zoneinfo
->dwLastSuccessfulXfr
;
913 *typeid = DNSSRV_TYPEID_ZONE_INFO
;
914 r
->ZoneInfo
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_INFO_LONGHORN
);
916 r
->ZoneInfo
->dwRpcStructureVersion
= 0x02;
917 r
->ZoneInfo
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
918 r
->ZoneInfo
->dwZoneType
= zoneinfo
->dwZoneType
;
919 r
->ZoneInfo
->fReverse
= zoneinfo
->fReverse
;
920 r
->ZoneInfo
->fAllowUpdate
= zoneinfo
->fAllowUpdate
;
921 r
->ZoneInfo
->fPaused
= zoneinfo
->fPaused
;
922 r
->ZoneInfo
->fShutdown
= zoneinfo
->fShutdown
;
923 r
->ZoneInfo
->fAutoCreated
= zoneinfo
->fAutoCreated
;
924 r
->ZoneInfo
->fUseDatabase
= zoneinfo
->fUseDatabase
;
925 r
->ZoneInfo
->pszDataFile
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
926 r
->ZoneInfo
->aipMasters
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipMasters
);
927 r
->ZoneInfo
->fSecureSecondaries
= zoneinfo
->fSecureSecondaries
;
928 r
->ZoneInfo
->fNotifyLevel
= zoneinfo
->fNotifyLevel
;
929 r
->ZoneInfo
->aipSecondaries
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipSecondaries
);
930 r
->ZoneInfo
->aipNotify
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipNotify
);
931 r
->ZoneInfo
->fUseWins
= zoneinfo
->fUseWins
;
932 r
->ZoneInfo
->fUseNbstat
= zoneinfo
->fUseNbstat
;
933 r
->ZoneInfo
->fAging
= zoneinfo
->fAging
;
934 r
->ZoneInfo
->dwNoRefreshInterval
= zoneinfo
->dwNoRefreshInterval
;
935 r
->ZoneInfo
->dwRefreshInterval
= zoneinfo
->dwRefreshInterval
;
936 r
->ZoneInfo
->dwAvailForScavengeTime
= zoneinfo
->dwAvailForScavengeTime
;
937 r
->ZoneInfo
->aipScavengeServers
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipScavengeServers
);
938 r
->ZoneInfo
->dwForwarderTimeout
= zoneinfo
->dwForwarderTimeout
;
939 r
->ZoneInfo
->fForwarderSlave
= zoneinfo
->fForwarderSlave
;
940 r
->ZoneInfo
->aipLocalMasters
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipLocalMasters
);
941 r
->ZoneInfo
->dwDpFlags
= z
->partition
->dwDpFlags
;
942 r
->ZoneInfo
->pszDpFqdn
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
943 r
->ZoneInfo
->pwszZoneDn
= talloc_strdup(mem_ctx
, zoneinfo
->pwszZoneDn
);
944 r
->ZoneInfo
->dwLastSuccessfulSoaCheck
= zoneinfo
->dwLastSuccessfulSoaCheck
;
945 r
->ZoneInfo
->dwLastSuccessfulXfr
= zoneinfo
->dwLastSuccessfulXfr
;
947 r
->ZoneInfo
->fQueuedForBackgroundLoad
= zoneinfo
->fQueuedForBackgroundLoad
;
948 r
->ZoneInfo
->fBackgroundLoadInProgress
= zoneinfo
->fBackgroundLoadInProgress
;
949 r
->ZoneInfo
->fReadOnlyZone
= zoneinfo
->fReadOnlyZone
;
950 r
->ZoneInfo
->dwLastXfrAttempt
= zoneinfo
->dwLastXfrAttempt
;
951 r
->ZoneInfo
->dwLastXfrResult
= zoneinfo
->dwLastXfrResult
;
959 if (strcasecmp(operation
, "AllowUpdate") == 0) {
960 answer_integer
= zoneinfo
->fAllowUpdate
;
962 } else if (strcasecmp(operation
, "Secured") == 0) {
965 } else if (strcasecmp(operation
, "DsIntegrated") == 0) {
966 answer_integer
= zoneinfo
->fUseDatabase
;
968 } else if (strcasecmp(operation
, "LogUpdates") == 0) {
971 } else if (strcasecmp(operation
, "NoRefreshInterval") == 0) {
972 answer_integer
= zoneinfo
->dwNoRefreshInterval
;
974 } else if (strcasecmp(operation
, "NotifyLevel") == 0) {
975 answer_integer
= zoneinfo
->fNotifyLevel
;
977 } else if (strcasecmp(operation
, "RefreshInterval") == 0) {
978 answer_integer
= zoneinfo
->dwRefreshInterval
;
980 } else if (strcasecmp(operation
, "SecureSecondaries") == 0) {
981 answer_integer
= zoneinfo
->fSecureSecondaries
;
983 } else if (strcasecmp(operation
, "Type") == 0) {
984 answer_integer
= zoneinfo
->dwZoneType
;
986 } else if (strcasecmp(operation
, "Aging") == 0) {
987 answer_integer
= zoneinfo
->fAging
;
989 } else if (strcasecmp(operation
, "ForwarderSlave") == 0) {
990 answer_integer
= zoneinfo
->fForwarderSlave
;
992 } else if (strcasecmp(operation
, "ForwarderTimeout") == 0) {
993 answer_integer
= zoneinfo
->dwForwarderTimeout
;
995 } else if (strcasecmp(operation
, "Unicode") == 0) {
1000 if (is_integer
== 1) {
1001 *typeid = DNSSRV_TYPEID_DWORD
;
1002 r
->Dword
= answer_integer
;
1008 if (strcasecmp(operation
, "AllowNSRecordsAutoCreation") == 0) {
1010 } else if (strcasecmp(operation
, "ScavengeServers") == 0) {
1011 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1012 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipScavengeServers
);
1014 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipScavengeServers
);
1017 } else if (strcasecmp(operation
, "MasterServers") == 0) {
1018 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1019 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipMasters
);
1021 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipMasters
);
1024 } else if (strcasecmp(operation
, "LocalMasterServers") == 0) {
1025 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1026 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipLocalMasters
);
1028 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipLocalMasters
);
1031 } else if (strcasecmp(operation
, "NotifyServers") == 0) {
1032 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1033 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipNotify
);
1035 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipNotify
);
1038 } else if (strcasecmp(operation
, "SecondaryServers") == 0) {
1039 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1040 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipSecondaries
);
1042 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipSecondaries
);
1047 if (is_addresses
== 1) {
1048 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1049 *typeid = DNSSRV_TYPEID_ADDRARRAY
;
1050 r
->AddrArray
= answer_addrarray
;
1052 *typeid = DNSSRV_TYPEID_IPARRAY
;
1053 r
->IpArray
= answer_iparray
;
1060 if (strcasecmp(operation
, "DatabaseFile") == 0) {
1061 answer_string
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
1063 } else if (strcasecmp(operation
, "ApplicationDirectoryPartition") == 0) {
1064 answer_string
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
1066 } else if (strcasecmp(operation
, "BreakOnNameUpdate") == 0) {
1070 if (is_string
== 1) {
1071 *typeid = DNSSRV_TYPEID_LPSTR
;
1072 r
->String
= answer_string
;
1076 DEBUG(0,("dnsserver: Invalid zone operation %s\n", operation
));
1077 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1081 /* dnsserver operation functions */
1083 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
1084 static WERROR
dnsserver_operate_server(struct dnsserver_state
*dsstate
,
1085 TALLOC_CTX
*mem_ctx
,
1086 const char *operation
,
1087 const unsigned int client_version
,
1088 enum DNS_RPC_TYPEID
typeid,
1089 union DNSSRV_RPC_UNION
*r
)
1091 bool valid_operation
= false;
1093 if (strcasecmp(operation
, "ResetDwordProperty") == 0) {
1094 valid_operation
= true;
1095 } else if (strcasecmp(operation
, "Restart") == 0) {
1096 valid_operation
= true;
1097 } else if (strcasecmp(operation
, "ClearDebugLog") == 0) {
1098 valid_operation
= true;
1099 } else if (strcasecmp(operation
, "ClearCache") == 0) {
1100 valid_operation
= true;
1101 } else if (strcasecmp(operation
, "WriteDirtyZones") == 0) {
1102 valid_operation
= true;
1103 } else if (strcasecmp(operation
, "ZoneCreate") == 0) {
1104 struct dnsserver_zone
*z
, *z2
;
1108 z
= talloc_zero(mem_ctx
, struct dnsserver_zone
);
1109 W_ERROR_HAVE_NO_MEMORY(z
);
1110 z
->partition
= talloc_zero(z
, struct dnsserver_partition
);
1111 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z
->partition
, z
);
1112 z
->zoneinfo
= talloc_zero(z
, struct dnsserver_zoneinfo
);
1113 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z
->zoneinfo
, z
);
1115 if (typeid == DNSSRV_TYPEID_ZONE_CREATE_W2K
) {
1116 name
= r
->ZoneCreateW2K
->pszZoneName
;
1117 z
->zoneinfo
->dwZoneType
= r
->ZoneCreateW2K
->dwZoneType
;
1118 z
->zoneinfo
->fAllowUpdate
= r
->ZoneCreateW2K
->fAllowUpdate
;
1119 z
->zoneinfo
->fAging
= r
->ZoneCreateW2K
->fAging
;
1120 z
->zoneinfo
->Flags
= r
->ZoneCreateW2K
->dwFlags
;
1121 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE_DOTNET
) {
1122 name
= r
->ZoneCreateDotNet
->pszZoneName
;
1123 z
->zoneinfo
->dwZoneType
= r
->ZoneCreateDotNet
->dwZoneType
;
1124 z
->zoneinfo
->fAllowUpdate
= r
->ZoneCreateDotNet
->fAllowUpdate
;
1125 z
->zoneinfo
->fAging
= r
->ZoneCreateDotNet
->fAging
;
1126 z
->zoneinfo
->Flags
= r
->ZoneCreateDotNet
->dwFlags
;
1127 z
->partition
->dwDpFlags
= r
->ZoneCreateDotNet
->dwDpFlags
;
1128 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE
) {
1129 name
= r
->ZoneCreate
->pszZoneName
;
1130 z
->zoneinfo
->dwZoneType
= r
->ZoneCreate
->dwZoneType
;
1131 z
->zoneinfo
->fAllowUpdate
= r
->ZoneCreate
->fAllowUpdate
;
1132 z
->zoneinfo
->fAging
= r
->ZoneCreate
->fAging
;
1133 z
->zoneinfo
->Flags
= r
->ZoneCreate
->dwFlags
;
1134 z
->partition
->dwDpFlags
= r
->ZoneCreate
->dwDpFlags
;
1137 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1141 if (name
[len
-1] == '.') {
1144 z
->name
= talloc_strndup(z
, name
, len
);
1145 if (z
->name
== NULL
) {
1147 return WERR_NOT_ENOUGH_MEMORY
;
1150 z2
= dnsserver_find_zone(dsstate
->zones
, z
->name
);
1153 return WERR_DNS_ERROR_ZONE_ALREADY_EXISTS
;
1156 status
= dnsserver_db_create_zone(dsstate
->samdb
, dsstate
->partitions
, z
,
1160 if (W_ERROR_IS_OK(status
)) {
1161 dnsserver_reload_zones(dsstate
);
1164 } else if (strcasecmp(operation
, "ClearStatistics") == 0) {
1165 valid_operation
= true;
1166 } else if (strcasecmp(operation
, "EnlistDirectoryPartition") == 0) {
1167 valid_operation
= true;
1168 } else if (strcasecmp(operation
, "StartScavenging") == 0) {
1169 valid_operation
= true;
1170 } else if (strcasecmp(operation
, "AbortScavenging") == 0) {
1171 valid_operation
= true;
1172 } else if (strcasecmp(operation
, "AutoConfigure") == 0) {
1173 valid_operation
= true;
1174 } else if (strcasecmp(operation
, "ExportSettings") == 0) {
1175 valid_operation
= true;
1176 } else if (strcasecmp(operation
, "PrepareForDemotion") == 0) {
1177 valid_operation
= true;
1178 } else if (strcasecmp(operation
, "PrepareForUninstall") == 0) {
1179 valid_operation
= true;
1180 } else if (strcasecmp(operation
, "DeleteNode") == 0) {
1181 valid_operation
= true;
1182 } else if (strcasecmp(operation
, "DeleteRecord") == 0) {
1183 valid_operation
= true;
1184 } else if (strcasecmp(operation
, "WriteBackFile") == 0) {
1185 valid_operation
= true;
1186 } else if (strcasecmp(operation
, "ListenAddresses") == 0) {
1187 valid_operation
= true;
1188 } else if (strcasecmp(operation
, "Forwarders") == 0) {
1189 valid_operation
= true;
1190 } else if (strcasecmp(operation
, "LogFilePath") == 0) {
1191 valid_operation
= true;
1192 } else if (strcasecmp(operation
, "LogIpFilterList") == 0) {
1193 valid_operation
= true;
1194 } else if (strcasecmp(operation
, "ForestDirectoryPartitionBaseName") == 0) {
1195 valid_operation
= true;
1196 } else if (strcasecmp(operation
, "DomainDirectoryPartitionBaseName") == 0) {
1197 valid_operation
= true;
1198 } else if (strcasecmp(operation
, "GlobalQueryBlockList") == 0) {
1199 valid_operation
= true;
1200 } else if (strcasecmp(operation
, "BreakOnReceiveFrom") == 0) {
1201 valid_operation
= true;
1202 } else if (strcasecmp(operation
, "BreakOnUpdateFrom") == 0) {
1203 valid_operation
= true;
1204 } else if (strcasecmp(operation
, "ServerLevelPluginDll") == 0) {
1205 valid_operation
= true;
1208 if (valid_operation
) {
1209 DEBUG(0, ("dnsserver: server operation '%s' not implemented\n", operation
));
1210 return WERR_CALL_NOT_IMPLEMENTED
;
1213 DEBUG(0, ("dnsserver: invalid server operation '%s'\n", operation
));
1214 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1217 static WERROR
dnsserver_complex_operate_server(struct dnsserver_state
*dsstate
,
1218 TALLOC_CTX
*mem_ctx
,
1219 const char *operation
,
1220 const unsigned int client_version
,
1221 enum DNS_RPC_TYPEID typeid_in
,
1222 union DNSSRV_RPC_UNION
*rin
,
1223 enum DNS_RPC_TYPEID
*typeid_out
,
1224 union DNSSRV_RPC_UNION
*rout
)
1226 int valid_operation
= 0;
1227 struct dnsserver_zone
*z
, **zlist
;
1229 bool found1
, found2
, found3
, found4
;
1232 if (strcasecmp(operation
, "QueryDwordProperty") == 0) {
1233 if (typeid_in
== DNSSRV_TYPEID_LPSTR
) {
1234 return dnsserver_query_server(dsstate
, mem_ctx
,
1240 } else if (strcasecmp(operation
, "EnumZones") == 0) {
1241 if (typeid_in
!= DNSSRV_TYPEID_DWORD
) {
1242 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1246 zlist
= talloc_zero_array(mem_ctx
, struct dnsserver_zone
*, 0);
1247 for (z
= dsstate
->zones
; z
; z
= z
->next
) {
1249 /* Match the flags in groups
1251 * Group1 : PRIMARY, SECONDARY, CACHE, AUTO
1252 * Group2 : FORWARD, REVERSE, FORWARDER, STUB
1253 * Group3 : DS, NON_DS, DOMAIN_DP, FOREST_DP
1254 * Group4 : CUSTOM_DP, LEGACY_DP
1259 if (rin
->Dword
& 0x0000000f) {
1260 if (rin
->Dword
& DNS_ZONE_REQUEST_PRIMARY
) {
1261 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_PRIMARY
) {
1265 if (rin
->Dword
& DNS_ZONE_REQUEST_SECONDARY
) {
1266 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_SECONDARY
) {
1270 if (rin
->Dword
& DNS_ZONE_REQUEST_CACHE
) {
1271 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_CACHE
) {
1275 if (rin
->Dword
& DNS_ZONE_REQUEST_AUTO
) {
1276 if (z
->zoneinfo
->fAutoCreated
1277 || z
->partition
->dwDpFlags
& DNS_DP_AUTOCREATED
) {
1287 if (rin
->Dword
& 0x000000f0) {
1288 if (rin
->Dword
& DNS_ZONE_REQUEST_FORWARD
) {
1289 if (!(z
->zoneinfo
->fReverse
)) {
1293 if (rin
->Dword
& DNS_ZONE_REQUEST_REVERSE
) {
1294 if (z
->zoneinfo
->fReverse
) {
1298 if (rin
->Dword
& DNS_ZONE_REQUEST_FORWARDER
) {
1299 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_FORWARDER
) {
1303 if (rin
->Dword
& DNS_ZONE_REQUEST_STUB
) {
1304 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_STUB
) {
1314 if (rin
->Dword
& 0x00000f00) {
1315 if (rin
->Dword
& DNS_ZONE_REQUEST_DS
) {
1316 if (z
->zoneinfo
->Flags
& DNS_RPC_ZONE_DSINTEGRATED
) {
1320 if (rin
->Dword
& DNS_ZONE_REQUEST_NON_DS
) {
1321 if (!(z
->zoneinfo
->Flags
& DNS_RPC_ZONE_DSINTEGRATED
)) {
1325 if (rin
->Dword
& DNS_ZONE_REQUEST_DOMAIN_DP
) {
1326 if (!(z
->partition
->dwDpFlags
& DNS_DP_DOMAIN_DEFAULT
)) {
1330 if (rin
->Dword
& DNS_ZONE_REQUEST_FOREST_DP
) {
1331 if (!(z
->partition
->dwDpFlags
& DNS_DP_FOREST_DEFAULT
)) {
1340 if (rin
->Dword
& 0x0000f000) {
1346 if (found1
&& found2
&& found3
&& found4
) {
1347 zlist
= talloc_realloc(mem_ctx
, zlist
, struct dnsserver_zone
*, zcount
+1);
1353 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
1354 *typeid_out
= DNSSRV_TYPEID_ZONE_LIST_W2K
;
1355 rout
->ZoneListW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_LIST_W2K
);
1358 rout
->ZoneListW2K
->dwZoneCount
= 0;
1359 rout
->ZoneListW2K
->ZoneArray
= NULL
;
1364 rout
->ZoneListW2K
->ZoneArray
= talloc_zero_array(mem_ctx
, struct DNS_RPC_ZONE_W2K
*, zcount
);
1365 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout
->ZoneListW2K
->ZoneArray
, zlist
);
1367 for (i
=0; i
<zcount
; i
++) {
1368 rout
->ZoneListW2K
->ZoneArray
[i
] = talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_W2K
);
1370 rout
->ZoneListW2K
->ZoneArray
[i
]->pszZoneName
= talloc_strdup(mem_ctx
, zlist
[i
]->name
);
1371 rout
->ZoneListW2K
->ZoneArray
[i
]->Flags
= zlist
[i
]->zoneinfo
->Flags
;
1372 rout
->ZoneListW2K
->ZoneArray
[i
]->ZoneType
= zlist
[i
]->zoneinfo
->dwZoneType
;
1373 rout
->ZoneListW2K
->ZoneArray
[i
]->Version
= zlist
[i
]->zoneinfo
->Version
;
1375 rout
->ZoneListW2K
->dwZoneCount
= zcount
;
1378 *typeid_out
= DNSSRV_TYPEID_ZONE_LIST
;
1379 rout
->ZoneList
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_LIST_DOTNET
);
1382 rout
->ZoneList
->dwRpcStructureVersion
= 1;
1383 rout
->ZoneList
->dwZoneCount
= 0;
1384 rout
->ZoneList
->ZoneArray
= NULL
;
1389 rout
->ZoneList
->ZoneArray
= talloc_zero_array(mem_ctx
, struct DNS_RPC_ZONE_DOTNET
*, zcount
);
1390 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout
->ZoneList
->ZoneArray
, zlist
);
1392 for (i
=0; i
<zcount
; i
++) {
1393 rout
->ZoneList
->ZoneArray
[i
] = talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_DOTNET
);
1395 rout
->ZoneList
->ZoneArray
[i
]->dwRpcStructureVersion
= 1;
1396 rout
->ZoneList
->ZoneArray
[i
]->pszZoneName
= talloc_strdup(mem_ctx
, zlist
[i
]->name
);
1397 rout
->ZoneList
->ZoneArray
[i
]->Flags
= zlist
[i
]->zoneinfo
->Flags
;
1398 rout
->ZoneList
->ZoneArray
[i
]->ZoneType
= zlist
[i
]->zoneinfo
->dwZoneType
;
1399 rout
->ZoneList
->ZoneArray
[i
]->Version
= zlist
[i
]->zoneinfo
->Version
;
1400 rout
->ZoneList
->ZoneArray
[i
]->dwDpFlags
= zlist
[i
]->partition
->dwDpFlags
;
1401 rout
->ZoneList
->ZoneArray
[i
]->pszDpFqdn
= talloc_strdup(mem_ctx
, zlist
[i
]->partition
->pszDpFqdn
);
1403 rout
->ZoneList
->dwRpcStructureVersion
= 1;
1404 rout
->ZoneList
->dwZoneCount
= zcount
;
1408 } else if (strcasecmp(operation
, "EnumZones2") == 0) {
1409 valid_operation
= true;
1410 } else if (strcasecmp(operation
, "EnumDirectoryPartitions") == 0) {
1411 if (typeid_in
!= DNSSRV_TYPEID_DWORD
) {
1412 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1415 *typeid_out
= DNSSRV_TYPEID_DP_LIST
;
1416 rout
->DirectoryPartitionList
= talloc_zero(mem_ctx
, struct DNS_RPC_DP_LIST
);
1418 if (rin
->Dword
!= 0) {
1419 rout
->DirectoryPartitionList
->dwDpCount
= 0;
1420 rout
->DirectoryPartitionList
->DpArray
= NULL
;
1422 struct DNS_RPC_DP_ENUM
**dplist
;
1423 struct dnsserver_partition
*p
;
1426 dplist
= talloc_zero_array(mem_ctx
, struct DNS_RPC_DP_ENUM
*, pcount
);
1427 W_ERROR_HAVE_NO_MEMORY(dplist
);
1429 p
= dsstate
->partitions
;
1430 for (i
=0; i
<pcount
; i
++) {
1431 dplist
[i
] = talloc_zero(dplist
, struct DNS_RPC_DP_ENUM
);
1433 dplist
[i
]->pszDpFqdn
= talloc_strdup(mem_ctx
, p
->pszDpFqdn
);
1434 dplist
[i
]->dwFlags
= p
->dwDpFlags
;
1435 dplist
[i
]->dwZoneCount
= p
->zones_count
;
1439 rout
->DirectoryPartitionList
->dwDpCount
= pcount
;
1440 rout
->DirectoryPartitionList
->DpArray
= dplist
;
1443 } else if (strcasecmp(operation
, "DirectoryPartitionInfo") == 0) {
1444 struct dnsserver_partition
*p
;
1445 struct dnsserver_partition_info
*partinfo
;
1446 struct DNS_RPC_DP_INFO
*dpinfo
= NULL
;
1448 if (typeid_in
!= DNSSRV_TYPEID_LPSTR
) {
1449 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1452 *typeid_out
= DNSSRV_TYPEID_DP_INFO
;
1454 for (p
= dsstate
->partitions
; p
; p
= p
->next
) {
1455 if (strcasecmp(p
->pszDpFqdn
, rin
->String
) == 0) {
1456 dpinfo
= talloc_zero(mem_ctx
, struct DNS_RPC_DP_INFO
);
1457 W_ERROR_HAVE_NO_MEMORY(dpinfo
);
1459 partinfo
= dnsserver_db_partition_info(mem_ctx
, dsstate
->samdb
, p
);
1460 W_ERROR_HAVE_NO_MEMORY(partinfo
);
1462 dpinfo
->pszDpFqdn
= talloc_strdup(dpinfo
, p
->pszDpFqdn
);
1463 dpinfo
->pszDpDn
= talloc_strdup(dpinfo
, ldb_dn_get_linearized(p
->partition_dn
));
1464 dpinfo
->pszCrDn
= talloc_steal(dpinfo
, partinfo
->pszCrDn
);
1465 dpinfo
->dwFlags
= p
->dwDpFlags
;
1466 dpinfo
->dwZoneCount
= p
->zones_count
;
1467 dpinfo
->dwState
= partinfo
->dwState
;
1468 dpinfo
->dwReplicaCount
= partinfo
->dwReplicaCount
;
1469 if (partinfo
->dwReplicaCount
> 0) {
1470 dpinfo
->ReplicaArray
= talloc_steal(dpinfo
,
1471 partinfo
->ReplicaArray
);
1473 dpinfo
->ReplicaArray
= NULL
;
1479 if (dpinfo
== NULL
) {
1480 return WERR_DNS_ERROR_DP_DOES_NOT_EXIST
;
1483 rout
->DirectoryPartition
= dpinfo
;
1485 } else if (strcasecmp(operation
, "Statistics") == 0) {
1486 valid_operation
= true;
1487 } else if (strcasecmp(operation
, "IpValidate") == 0) {
1488 valid_operation
= true;
1491 if (valid_operation
) {
1492 DEBUG(0, ("dnsserver: server complex operation '%s' not implemented\n", operation
));
1493 return WERR_CALL_NOT_IMPLEMENTED
;
1496 DEBUG(0, ("dnsserver: invalid server complex operation '%s'\n", operation
));
1497 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1500 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
1501 static WERROR
dnsserver_operate_zone(struct dnsserver_state
*dsstate
,
1502 TALLOC_CTX
*mem_ctx
,
1503 struct dnsserver_zone
*z
,
1504 unsigned int request_filter
,
1505 const char *operation
,
1506 const unsigned int client_version
,
1507 enum DNS_RPC_TYPEID
typeid,
1508 union DNSSRV_RPC_UNION
*r
)
1510 bool valid_operation
= false;
1512 if (strcasecmp(operation
, "ResetDwordProperty") == 0) {
1514 if (typeid != DNSSRV_TYPEID_NAME_AND_PARAM
) {
1515 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1518 return dnsserver_db_do_reset_dword(dsstate
->samdb
, z
,
1521 } else if (strcasecmp(operation
, "ZoneTypeReset") == 0) {
1522 valid_operation
= true;
1523 } else if (strcasecmp(operation
, "PauseZone") == 0) {
1524 valid_operation
= true;
1525 } else if (strcasecmp(operation
, "ResumeZone") == 0) {
1526 valid_operation
= true;
1527 } else if (strcasecmp(operation
, "DeleteZone") == 0) {
1528 valid_operation
= true;
1529 } else if (strcasecmp(operation
, "ReloadZone") == 0) {
1530 valid_operation
= true;
1531 } else if (strcasecmp(operation
, "RefreshZone") == 0) {
1532 valid_operation
= true;
1533 } else if (strcasecmp(operation
, "ExpireZone") == 0) {
1534 valid_operation
= true;
1535 } else if (strcasecmp(operation
, "IncrementVersion") == 0) {
1536 valid_operation
= true;
1537 } else if (strcasecmp(operation
, "WriteBackFile") == 0) {
1538 valid_operation
= true;
1539 } else if (strcasecmp(operation
, "DeleteZoneFromDs") == 0) {
1542 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
1544 status
= dnsserver_db_delete_zone(dsstate
->samdb
, z
);
1545 if (W_ERROR_IS_OK(status
)) {
1546 dnsserver_reload_zones(dsstate
);
1549 } else if (strcasecmp(operation
, "UpdateZoneFromDs") == 0) {
1550 valid_operation
= true;
1551 } else if (strcasecmp(operation
, "ZoneExport") == 0) {
1552 valid_operation
= true;
1553 } else if (strcasecmp(operation
, "ZoneChangeDirectoryPartition") == 0) {
1554 valid_operation
= true;
1555 } else if (strcasecmp(operation
, "DeleteNode") == 0) {
1556 valid_operation
= true;
1557 } else if (strcasecmp(operation
, "DeleteRecordSet") == 0) {
1558 valid_operation
= true;
1559 } else if (strcasecmp(operation
, "ForceAgingOnNode") == 0) {
1560 valid_operation
= true;
1561 } else if (strcasecmp(operation
, "DatabaseFile") == 0) {
1562 valid_operation
= true;
1563 } else if (strcasecmp(operation
, "MasterServers") == 0) {
1564 valid_operation
= true;
1565 } else if (strcasecmp(operation
, "LocalMasterServers") == 0) {
1566 valid_operation
= true;
1567 } else if (strcasecmp(operation
, "NotifyServers") == 0) {
1568 valid_operation
= true;
1569 } else if (strcasecmp(operation
, "SecondaryServers") == 0) {
1570 valid_operation
= true;
1571 } else if (strcasecmp(operation
, "ScavengingServers") == 0) {
1572 valid_operation
= true;
1573 } else if (strcasecmp(operation
, "AllowNSRecordsAutoCreation") == 0) {
1574 valid_operation
= true;
1575 } else if (strcasecmp(operation
, "BreakOnNameUpdate") == 0) {
1576 valid_operation
= true;
1577 } else if (strcasecmp(operation
, "ApplicationDirectoryPartition") == 0) {
1578 valid_operation
= true;
1581 if (valid_operation
) {
1582 DEBUG(0, ("dnsserver: zone operation '%s' not implemented\n", operation
));
1583 return WERR_CALL_NOT_IMPLEMENTED
;
1586 DEBUG(0, ("dnsserver: invalid zone operation '%s'\n", operation
));
1587 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1590 static WERROR
dnsserver_complex_operate_zone(struct dnsserver_state
*dsstate
,
1591 TALLOC_CTX
*mem_ctx
,
1592 struct dnsserver_zone
*z
,
1593 const char *operation
,
1594 const unsigned int client_version
,
1595 enum DNS_RPC_TYPEID typeid_in
,
1596 union DNSSRV_RPC_UNION
*rin
,
1597 enum DNS_RPC_TYPEID
*typeid_out
,
1598 union DNSSRV_RPC_UNION
*rout
)
1600 if (strcasecmp(operation
, "QueryDwordProperty") == 0) {
1601 if (typeid_in
== DNSSRV_TYPEID_LPSTR
) {
1602 return dnsserver_query_zone(dsstate
, mem_ctx
, z
,
1611 DEBUG(0,("dnsserver: Invalid zone operation %s\n", operation
));
1612 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1615 /* dnsserver enumerate function */
1617 static WERROR
dnsserver_enumerate_root_records(struct dnsserver_state
*dsstate
,
1618 TALLOC_CTX
*mem_ctx
,
1619 unsigned int client_version
,
1620 const char *node_name
,
1621 enum dns_record_type record_type
,
1622 unsigned int select_flag
,
1623 unsigned int *buffer_length
,
1624 struct DNS_RPC_RECORDS_ARRAY
**buffer
)
1626 TALLOC_CTX
*tmp_ctx
;
1627 struct dnsserver_zone
*z
;
1628 const char * const attrs
[] = { "name", "dnsRecord", NULL
};
1629 struct ldb_result
*res
;
1630 struct DNS_RPC_RECORDS_ARRAY
*recs
;
1637 tmp_ctx
= talloc_new(mem_ctx
);
1638 W_ERROR_HAVE_NO_MEMORY(tmp_ctx
);
1640 z
= dnsserver_find_zone(dsstate
->zones
, ".");
1642 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
1645 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1646 LDB_SCOPE_ONELEVEL
, attrs
,
1647 "(&(objectClass=dnsNode)(name=@)(!(dNSTombstoned=TRUE)))");
1648 if (ret
!= LDB_SUCCESS
) {
1649 talloc_free(tmp_ctx
);
1650 return WERR_INTERNAL_DB_ERROR
;
1652 if (res
->count
== 0) {
1653 talloc_free(tmp_ctx
);
1654 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
1657 recs
= talloc_zero(mem_ctx
, struct DNS_RPC_RECORDS_ARRAY
);
1658 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs
, tmp_ctx
);
1663 for (i
=0; i
<res
->count
; i
++) {
1664 status
= dns_fill_records_array(tmp_ctx
, NULL
, record_type
,
1666 res
->msgs
[i
], 0, recs
,
1667 &add_names
, &add_count
);
1668 if (!W_ERROR_IS_OK(status
)) {
1669 talloc_free(tmp_ctx
);
1675 /* Add any additional records */
1676 if (select_flag
& DNS_RPC_VIEW_ADDITIONAL_DATA
) {
1677 for (i
=0; i
<add_count
; i
++) {
1679 = ldb_binary_encode_string(tmp_ctx
,
1681 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1682 LDB_SCOPE_ONELEVEL
, attrs
,
1683 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1685 if (ret
!= LDB_SUCCESS
|| res
->count
== 0) {
1690 len
= strlen(add_names
[i
]);
1691 if (add_names
[i
][len
-1] == '.') {
1692 rname
= talloc_strdup(tmp_ctx
, add_names
[i
]);
1694 rname
= talloc_asprintf(tmp_ctx
, "%s.", add_names
[i
]);
1696 status
= dns_fill_records_array(tmp_ctx
, NULL
, DNS_TYPE_A
,
1698 res
->msgs
[0], 0, recs
,
1702 if (!W_ERROR_IS_OK(status
)) {
1703 talloc_free(tmp_ctx
);
1709 talloc_free(tmp_ctx
);
1711 *buffer_length
= ndr_size_DNS_RPC_RECORDS_ARRAY(recs
, 0);
1718 static WERROR
dnsserver_enumerate_records(struct dnsserver_state
*dsstate
,
1719 TALLOC_CTX
*mem_ctx
,
1720 struct dnsserver_zone
*z
,
1721 unsigned int client_version
,
1722 const char *node_name
,
1723 const char *start_child
,
1724 enum dns_record_type record_type
,
1725 unsigned int select_flag
,
1726 const char *filter_start
,
1727 const char *filter_stop
,
1728 unsigned int *buffer_length
,
1729 struct DNS_RPC_RECORDS_ARRAY
**buffer
)
1731 TALLOC_CTX
*tmp_ctx
;
1733 const char * const attrs
[] = { "name", "dnsRecord", NULL
};
1734 struct ldb_result
*res
= NULL
;
1735 struct DNS_RPC_RECORDS_ARRAY
*recs
= NULL
;
1736 char **add_names
= NULL
;
1738 const char *preference_name
= NULL
;
1742 struct dns_tree
*tree
= NULL
;
1743 struct dns_tree
*base
= NULL
;
1744 struct dns_tree
*node
= NULL
;
1746 tmp_ctx
= talloc_new(mem_ctx
);
1747 W_ERROR_HAVE_NO_MEMORY(tmp_ctx
);
1749 name
= dns_split_node_name(tmp_ctx
, node_name
, z
->name
);
1750 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name
, tmp_ctx
);
1752 /* search all records under parent tree */
1753 if (strcasecmp(name
, z
->name
) == 0) {
1754 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1755 LDB_SCOPE_ONELEVEL
, attrs
,
1756 "(&(objectClass=dnsNode)(!(dNSTombstoned=TRUE)))");
1757 preference_name
= "@";
1760 = ldb_binary_encode_string(tmp_ctx
, name
);
1761 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1762 LDB_SCOPE_ONELEVEL
, attrs
,
1763 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s))(!(dNSTombstoned=TRUE)))",
1764 encoded_name
, encoded_name
);
1765 preference_name
= name
;
1767 if (ret
!= LDB_SUCCESS
) {
1768 talloc_free(tmp_ctx
);
1769 return WERR_INTERNAL_DB_ERROR
;
1771 if (res
->count
== 0) {
1772 talloc_free(tmp_ctx
);
1773 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
1776 recs
= talloc_zero(mem_ctx
, struct DNS_RPC_RECORDS_ARRAY
);
1777 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs
, tmp_ctx
);
1780 * Sort the names, so that the records are in order by the child
1781 * component below "name".
1783 * A full tree sort is not required, so we pass in "name" so
1784 * we know which level to sort, as only direct children are
1785 * eventually returned
1787 LDB_TYPESAFE_QSORT(res
->msgs
, res
->count
, name
, dns_name_compare
);
1789 /* Build a tree of name components from dns name */
1790 tree
= dns_build_tree(tmp_ctx
, preference_name
, res
);
1791 W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree
, tmp_ctx
);
1793 /* Find the parent record in the tree */
1795 while (base
->level
!= -1) {
1796 base
= base
->children
[0];
1799 /* Add the parent record with blank name */
1800 if (!(select_flag
& DNS_RPC_VIEW_ONLY_CHILDREN
)) {
1801 status
= dns_fill_records_array(tmp_ctx
, z
, record_type
,
1804 recs
, &add_names
, &add_count
);
1805 if (!W_ERROR_IS_OK(status
)) {
1806 talloc_free(tmp_ctx
);
1811 /* Add all the children records */
1812 if (!(select_flag
& DNS_RPC_VIEW_NO_CHILDREN
)) {
1813 for (i
=0; i
<base
->num_children
; i
++) {
1814 node
= base
->children
[i
];
1816 status
= dns_fill_records_array(tmp_ctx
, z
, record_type
,
1817 select_flag
, node
->name
,
1818 node
->data
, node
->num_children
,
1819 recs
, &add_names
, &add_count
);
1820 if (!W_ERROR_IS_OK(status
)) {
1821 talloc_free(tmp_ctx
);
1831 /* Add any additional records */
1832 if (select_flag
& DNS_RPC_VIEW_ADDITIONAL_DATA
) {
1833 for (i
=0; i
<add_count
; i
++) {
1834 struct dnsserver_zone
*z2
= NULL
;
1835 struct ldb_message
*msg
= NULL
;
1836 /* Search all the available zones for additional name */
1837 for (z2
= dsstate
->zones
; z2
; z2
= z2
->next
) {
1839 name
= dns_split_node_name(tmp_ctx
, add_names
[i
], z2
->name
);
1841 = ldb_binary_encode_string(tmp_ctx
,
1843 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z2
->zone_dn
,
1844 LDB_SCOPE_ONELEVEL
, attrs
,
1845 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1848 if (ret
!= LDB_SUCCESS
) {
1851 if (res
->count
== 1) {
1860 len
= strlen(add_names
[i
]);
1861 if (add_names
[i
][len
-1] == '.') {
1862 rname
= talloc_strdup(tmp_ctx
, add_names
[i
]);
1864 rname
= talloc_asprintf(tmp_ctx
, "%s.", add_names
[i
]);
1866 status
= dns_fill_records_array(tmp_ctx
, NULL
, DNS_TYPE_A
,
1872 if (!W_ERROR_IS_OK(status
)) {
1873 talloc_free(tmp_ctx
);
1879 *buffer_length
= ndr_size_DNS_RPC_RECORDS_ARRAY(recs
, 0);
1886 * Check str1 + '.' + str2 = name, for example:
1887 * ("dc0", "example.com", "dc0.example.com") = true
1889 static bool cname_self_reference(const char* node_name
,
1890 const char* zone_name
,
1891 struct DNS_RPC_NAME name
) {
1892 size_t node_len
, zone_len
;
1894 if (node_name
== NULL
|| zone_name
== NULL
) {
1898 node_len
= strlen(node_name
);
1899 zone_len
= strlen(zone_name
);
1901 if (node_len
== 0 ||
1903 (name
.len
!= node_len
+ zone_len
+ 1)) {
1907 if (strncmp(node_name
, name
.str
, node_len
) == 0 &&
1908 name
.str
[node_len
] == '.' &&
1909 strncmp(zone_name
, name
.str
+ node_len
+ 1, zone_len
) == 0) {
1916 /* dnsserver update function */
1918 static WERROR
dnsserver_update_record(struct dnsserver_state
*dsstate
,
1919 TALLOC_CTX
*mem_ctx
,
1920 struct dnsserver_zone
*z
,
1921 unsigned int client_version
,
1922 const char *node_name
,
1923 struct DNS_RPC_RECORD_BUF
*add_buf
,
1924 struct DNS_RPC_RECORD_BUF
*del_buf
)
1926 TALLOC_CTX
*tmp_ctx
;
1930 tmp_ctx
= talloc_new(mem_ctx
);
1931 W_ERROR_HAVE_NO_MEMORY(tmp_ctx
);
1933 /* If node_name is @ or zone name, dns record is @ */
1934 if (strcmp(node_name
, "@") == 0 ||
1935 strcmp(node_name
, ".") == 0 ||
1936 strcasecmp(node_name
, z
->name
) == 0) {
1937 name
= talloc_strdup(tmp_ctx
, "@");
1939 name
= dns_split_node_name(tmp_ctx
, node_name
, z
->name
);
1941 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name
, tmp_ctx
);
1943 /* CNAMEs can't point to themselves */
1944 if (add_buf
!= NULL
&& add_buf
->rec
.wType
== DNS_TYPE_CNAME
) {
1945 if (cname_self_reference(node_name
, z
->name
, add_buf
->rec
.data
.name
)) {
1946 return WERR_DNS_ERROR_CNAME_LOOP
;
1950 if (add_buf
!= NULL
) {
1951 if (del_buf
== NULL
) {
1953 status
= dnsserver_db_add_record(tmp_ctx
, dsstate
->samdb
,
1958 status
= dnsserver_db_update_record(tmp_ctx
, dsstate
->samdb
,
1964 if (del_buf
== NULL
) {
1965 /* Add empty node */
1966 status
= dnsserver_db_add_empty_node(tmp_ctx
, dsstate
->samdb
,
1970 status
= dnsserver_db_delete_record(tmp_ctx
, dsstate
->samdb
,
1976 talloc_free(tmp_ctx
);
1981 /* dnsserver interface functions */
1983 static WERROR
dcesrv_DnssrvOperation(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvOperation
*r
)
1985 struct dnsserver_state
*dsstate
;
1986 struct dnsserver_zone
*z
= NULL
;
1987 uint32_t request_filter
= 0;
1990 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
1991 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
1994 if (r
->in
.dwContext
== 0) {
1995 if (r
->in
.pszZone
!= NULL
) {
1996 request_filter
= dnsserver_zone_to_request_filter(r
->in
.pszZone
);
1999 request_filter
= r
->in
.dwContext
;
2002 if (r
->in
.pszZone
== NULL
) {
2003 ret
= dnsserver_operate_server(dsstate
, mem_ctx
,
2005 DNS_CLIENT_VERSION_W2K
,
2009 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2011 * In the case that request_filter is not 0 and z is NULL,
2012 * the request is for a multizone operation, which we do not
2013 * yet support, so just error on NULL zone name.
2016 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2019 ret
= dnsserver_operate_zone(dsstate
, mem_ctx
, z
,
2022 DNS_CLIENT_VERSION_W2K
,
2027 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2028 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation
, NDR_IN
, r
);
2033 static WERROR
dcesrv_DnssrvQuery(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvQuery
*r
)
2035 struct dnsserver_state
*dsstate
;
2036 struct dnsserver_zone
*z
;
2039 ZERO_STRUCTP(r
->out
.pdwTypeId
);
2040 ZERO_STRUCTP(r
->out
.ppData
);
2042 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2043 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2046 if (r
->in
.pszZone
== NULL
) {
2047 /* FIXME: DNS Server Configuration Access Control List */
2048 ret
= dnsserver_query_server(dsstate
, mem_ctx
,
2050 DNS_CLIENT_VERSION_W2K
,
2054 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2056 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2059 ret
= dnsserver_query_zone(dsstate
, mem_ctx
, z
,
2061 DNS_CLIENT_VERSION_W2K
,
2066 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2067 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery
, NDR_IN
, r
);
2072 static WERROR
dcesrv_DnssrvComplexOperation(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvComplexOperation
*r
)
2074 struct dnsserver_state
*dsstate
;
2075 struct dnsserver_zone
*z
;
2078 ZERO_STRUCTP(r
->out
.pdwTypeOut
);
2079 ZERO_STRUCTP(r
->out
.ppDataOut
);
2081 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2082 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2085 if (r
->in
.pszZone
== NULL
) {
2086 /* Server operation */
2087 ret
= dnsserver_complex_operate_server(dsstate
, mem_ctx
,
2089 DNS_CLIENT_VERSION_W2K
,
2095 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2097 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2100 ret
= dnsserver_complex_operate_zone(dsstate
, mem_ctx
, z
,
2102 DNS_CLIENT_VERSION_W2K
,
2109 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2110 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation
, NDR_IN
, r
);
2115 static WERROR
dcesrv_DnssrvEnumRecords(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvEnumRecords
*r
)
2117 struct dnsserver_state
*dsstate
;
2118 struct dnsserver_zone
*z
;
2121 ZERO_STRUCTP(r
->out
.pdwBufferLength
);
2122 ZERO_STRUCTP(r
->out
.pBuffer
);
2124 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2125 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2128 if (r
->in
.pszZone
== NULL
) {
2129 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2132 if (strcasecmp(r
->in
.pszZone
, "..RootHints") == 0) {
2133 ret
= dnsserver_enumerate_root_records(dsstate
, mem_ctx
,
2134 DNS_CLIENT_VERSION_W2K
,
2138 r
->out
.pdwBufferLength
,
2141 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2143 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2146 ret
= dnsserver_enumerate_records(dsstate
, mem_ctx
, z
,
2147 DNS_CLIENT_VERSION_W2K
,
2149 r
->in
.pszStartChild
,
2152 r
->in
.pszFilterStart
,
2153 r
->in
.pszFilterStop
,
2154 r
->out
.pdwBufferLength
,
2158 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2159 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords
, NDR_IN
, r
);
2164 static WERROR
dcesrv_DnssrvUpdateRecord(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvUpdateRecord
*r
)
2166 struct dnsserver_state
*dsstate
;
2167 struct dnsserver_zone
*z
;
2170 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2171 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2174 if (r
->in
.pszZone
== NULL
) {
2175 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2178 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2180 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2183 ret
= dnsserver_update_record(dsstate
, mem_ctx
, z
,
2184 DNS_CLIENT_VERSION_W2K
,
2187 r
->in
.pDeleteRecord
);
2189 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2190 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord
, NDR_IN
, r
);
2195 static WERROR
dcesrv_DnssrvOperation2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvOperation2
*r
)
2197 struct dnsserver_state
*dsstate
;
2198 struct dnsserver_zone
*z
= NULL
;
2199 uint32_t request_filter
= 0;
2202 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2203 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2206 if (r
->in
.dwContext
== 0) {
2207 if (r
->in
.pszZone
!= NULL
) {
2208 request_filter
= dnsserver_zone_to_request_filter(r
->in
.pszZone
);
2211 request_filter
= r
->in
.dwContext
;
2214 if (r
->in
.pszZone
== NULL
) {
2215 ret
= dnsserver_operate_server(dsstate
, mem_ctx
,
2217 r
->in
.dwClientVersion
,
2221 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2223 * In the case that request_filter is not 0 and z is NULL,
2224 * the request is for a multizone operation, which we do not
2225 * yet support, so just error on NULL zone name.
2228 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2231 ret
= dnsserver_operate_zone(dsstate
, mem_ctx
, z
,
2234 r
->in
.dwClientVersion
,
2239 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2240 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation2
, NDR_IN
, r
);
2245 static WERROR
dcesrv_DnssrvQuery2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvQuery2
*r
)
2247 struct dnsserver_state
*dsstate
;
2248 struct dnsserver_zone
*z
;
2251 ZERO_STRUCTP(r
->out
.pdwTypeId
);
2252 ZERO_STRUCTP(r
->out
.ppData
);
2254 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2255 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2258 if (r
->in
.pszZone
== NULL
) {
2259 /* FIXME: DNS Server Configuration Access Control List */
2260 ret
= dnsserver_query_server(dsstate
, mem_ctx
,
2262 r
->in
.dwClientVersion
,
2266 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2268 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2271 ret
= dnsserver_query_zone(dsstate
, mem_ctx
, z
,
2273 r
->in
.dwClientVersion
,
2278 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2279 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery2
, NDR_IN
, r
);
2284 static WERROR
dcesrv_DnssrvComplexOperation2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvComplexOperation2
*r
)
2286 struct dnsserver_state
*dsstate
;
2287 struct dnsserver_zone
*z
;
2290 ZERO_STRUCTP(r
->out
.pdwTypeOut
);
2291 ZERO_STRUCTP(r
->out
.ppDataOut
);
2293 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2294 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2297 if (r
->in
.pszZone
== NULL
) {
2298 /* Server operation */
2299 ret
= dnsserver_complex_operate_server(dsstate
, mem_ctx
,
2301 r
->in
.dwClientVersion
,
2308 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2310 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2313 ret
= dnsserver_complex_operate_zone(dsstate
, mem_ctx
, z
,
2315 r
->in
.dwClientVersion
,
2322 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2323 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation2
, NDR_IN
, r
);
2328 static WERROR
dcesrv_DnssrvEnumRecords2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvEnumRecords2
*r
)
2330 struct dnsserver_state
*dsstate
;
2331 struct dnsserver_zone
*z
;
2334 ZERO_STRUCTP(r
->out
.pdwBufferLength
);
2335 ZERO_STRUCTP(r
->out
.pBuffer
);
2337 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2338 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2341 if (r
->in
.pszZone
== NULL
) {
2342 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2345 if (strcasecmp(r
->in
.pszZone
, "..RootHints") == 0) {
2346 ret
= dnsserver_enumerate_root_records(dsstate
, mem_ctx
,
2347 r
->in
.dwClientVersion
,
2351 r
->out
.pdwBufferLength
,
2354 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2356 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2359 ret
= dnsserver_enumerate_records(dsstate
, mem_ctx
, z
,
2360 r
->in
.dwClientVersion
,
2362 r
->in
.pszStartChild
,
2365 r
->in
.pszFilterStart
,
2366 r
->in
.pszFilterStop
,
2367 r
->out
.pdwBufferLength
,
2372 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2373 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords2
, NDR_IN
, r
);
2378 static WERROR
dcesrv_DnssrvUpdateRecord2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvUpdateRecord2
*r
)
2380 struct dnsserver_state
*dsstate
;
2381 struct dnsserver_zone
*z
;
2384 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2385 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2388 if (r
->in
.pszZone
== NULL
) {
2389 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2392 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2394 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2397 ret
= dnsserver_update_record(dsstate
, mem_ctx
, z
,
2398 r
->in
.dwClientVersion
,
2401 r
->in
.pDeleteRecord
);
2403 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2404 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord2
, NDR_IN
, r
);
2409 /* include the generated boilerplate */
2410 #include "librpc/gen_ndr/ndr_dnsserver_s.c"