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 dnsserver_state
*dsstate
;
107 struct dnsserver_zone
*zones
, *z
, *znext
;
108 struct dnsserver_partition
*partitions
, *p
;
110 dsstate
= talloc_get_type(dce_call
->context
->private_data
, struct dnsserver_state
);
111 if (dsstate
!= NULL
) {
115 dsstate
= talloc_zero(dce_call
->context
, struct dnsserver_state
);
116 if (dsstate
== NULL
) {
120 dsstate
->lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
122 /* FIXME: create correct auth_session_info for connecting user */
123 dsstate
->samdb
= samdb_connect(dsstate
,
126 dce_call
->conn
->auth_state
.session_info
,
127 dce_call
->conn
->remote_address
,
129 if (dsstate
->samdb
== NULL
) {
130 DEBUG(0,("dnsserver: Failed to open samdb"));
134 /* Initialize server info */
135 dsstate
->serverinfo
= dnsserver_init_serverinfo(dsstate
,
138 if (dsstate
->serverinfo
== NULL
) {
142 /* Search for DNS partitions */
143 partitions
= dnsserver_db_enumerate_partitions(dsstate
, dsstate
->serverinfo
, dsstate
->samdb
);
144 if (partitions
== NULL
) {
147 dsstate
->partitions
= partitions
;
149 /* Search for DNS zones */
150 for (p
= partitions
; p
; p
= p
->next
) {
151 zones
= dnsserver_db_enumerate_zones(dsstate
, dsstate
->samdb
, p
);
155 for (z
= zones
; z
; ) {
157 if (dnsserver_find_zone(dsstate
->zones
, z
->name
) == NULL
) {
158 z
->zoneinfo
= dnsserver_init_zoneinfo(z
, dsstate
->serverinfo
);
159 if (z
->zoneinfo
== NULL
) {
162 DLIST_ADD_END(dsstate
->zones
, z
);
164 dsstate
->zones_count
++;
166 /* Ignore duplicate zone */
167 DEBUG(3,("dnsserver: Ignoring duplicate zone '%s' from '%s'",
168 z
->name
, ldb_dn_get_linearized(z
->zone_dn
)));
174 dce_call
->context
->private_data
= dsstate
;
179 talloc_free(dsstate
);
185 /* dnsserver query functions */
187 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
188 static WERROR
dnsserver_query_server(struct dnsserver_state
*dsstate
,
190 const char *operation
,
191 const unsigned int client_version
,
192 enum DNS_RPC_TYPEID
*typeid,
193 union DNSSRV_RPC_UNION
*r
)
195 uint8_t is_integer
, is_addresses
, is_string
, is_wstring
, is_stringlist
;
196 uint32_t answer_integer
;
197 struct IP4_ARRAY
*answer_iparray
;
198 struct DNS_ADDR_ARRAY
*answer_addrarray
;
200 struct DNS_RPC_UTF8_STRING_LIST
*answer_stringlist
;
201 struct dnsserver_serverinfo
*serverinfo
;
203 serverinfo
= dsstate
->serverinfo
;
205 if (strcasecmp(operation
, "ServerInfo") == 0) {
206 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
207 *typeid = DNSSRV_TYPEID_SERVER_INFO_W2K
;
208 r
->ServerInfoW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_SERVER_INFO_W2K
);
210 r
->ServerInfoW2K
->dwVersion
= serverinfo
->dwVersion
;
211 r
->ServerInfoW2K
->fBootMethod
= serverinfo
->fBootMethod
;
212 r
->ServerInfoW2K
->fAdminConfigured
= serverinfo
->fAdminConfigured
;
213 r
->ServerInfoW2K
->fAllowUpdate
= serverinfo
->fAllowUpdate
;
214 r
->ServerInfoW2K
->fDsAvailable
= serverinfo
->fDsAvailable
;
215 r
->ServerInfoW2K
->pszServerName
= talloc_strdup(mem_ctx
, serverinfo
->pszServerName
);
216 r
->ServerInfoW2K
->pszDsContainer
= talloc_strdup(mem_ctx
, serverinfo
->pszDsContainer
);
217 r
->ServerInfoW2K
->aipServerAddrs
= dns_addr_array_to_ip4_array(mem_ctx
,
218 serverinfo
->aipServerAddrs
);
219 r
->ServerInfoW2K
->aipListenAddrs
= dns_addr_array_to_ip4_array(mem_ctx
,
220 serverinfo
->aipListenAddrs
);
221 r
->ServerInfoW2K
->aipForwarders
= ip4_array_copy(mem_ctx
, serverinfo
->aipForwarders
);
222 r
->ServerInfoW2K
->dwLogLevel
= serverinfo
->dwLogLevel
;
223 r
->ServerInfoW2K
->dwDebugLevel
= serverinfo
->dwDebugLevel
;
224 r
->ServerInfoW2K
->dwForwardTimeout
= serverinfo
->dwForwardTimeout
;
225 r
->ServerInfoW2K
->dwRpcProtocol
= serverinfo
->dwRpcProtocol
;
226 r
->ServerInfoW2K
->dwNameCheckFlag
= serverinfo
->dwNameCheckFlag
;
227 r
->ServerInfoW2K
->cAddressAnswerLimit
= serverinfo
->cAddressAnswerLimit
;
228 r
->ServerInfoW2K
->dwRecursionRetry
= serverinfo
->dwRecursionRetry
;
229 r
->ServerInfoW2K
->dwRecursionTimeout
= serverinfo
->dwRecursionTimeout
;
230 r
->ServerInfoW2K
->dwMaxCacheTtl
= serverinfo
->dwMaxCacheTtl
;
231 r
->ServerInfoW2K
->dwDsPollingInterval
= serverinfo
->dwDsPollingInterval
;
232 r
->ServerInfoW2K
->dwScavengingInterval
= serverinfo
->dwScavengingInterval
;
233 r
->ServerInfoW2K
->dwDefaultRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
234 r
->ServerInfoW2K
->dwDefaultNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
235 r
->ServerInfoW2K
->fAutoReverseZones
= serverinfo
->fAutoReverseZones
;
236 r
->ServerInfoW2K
->fAutoCacheUpdate
= serverinfo
->fAutoCacheUpdate
;
237 r
->ServerInfoW2K
->fRecurseAfterForwarding
= serverinfo
->fRecurseAfterForwarding
;
238 r
->ServerInfoW2K
->fForwardDelegations
= serverinfo
->fForwardDelegations
;
239 r
->ServerInfoW2K
->fNoRecursion
= serverinfo
->fNoRecursion
;
240 r
->ServerInfoW2K
->fSecureResponses
= serverinfo
->fSecureResponses
;
241 r
->ServerInfoW2K
->fRoundRobin
= serverinfo
->fRoundRobin
;
242 r
->ServerInfoW2K
->fLocalNetPriority
= serverinfo
->fLocalNetPriority
;
243 r
->ServerInfoW2K
->fBindSecondaries
= serverinfo
->fBindSecondaries
;
244 r
->ServerInfoW2K
->fWriteAuthorityNs
= serverinfo
->fWriteAuthorityNs
;
245 r
->ServerInfoW2K
->fStrictFileParsing
= serverinfo
->fStrictFileParsing
;
246 r
->ServerInfoW2K
->fLooseWildcarding
= serverinfo
->fLooseWildcarding
;
247 r
->ServerInfoW2K
->fDefaultAgingState
= serverinfo
->fDefaultAgingState
;
249 } else if (client_version
== DNS_CLIENT_VERSION_DOTNET
) {
250 *typeid = DNSSRV_TYPEID_SERVER_INFO_DOTNET
;
251 r
->ServerInfoDotNet
= talloc_zero(mem_ctx
, struct DNS_RPC_SERVER_INFO_DOTNET
);
253 r
->ServerInfoDotNet
->dwRpcStructureVersion
= 0x01;
254 r
->ServerInfoDotNet
->dwVersion
= serverinfo
->dwVersion
;
255 r
->ServerInfoDotNet
->fBootMethod
= serverinfo
->fBootMethod
;
256 r
->ServerInfoDotNet
->fAdminConfigured
= serverinfo
->fAdminConfigured
;
257 r
->ServerInfoDotNet
->fAllowUpdate
= serverinfo
->fAllowUpdate
;
258 r
->ServerInfoDotNet
->fDsAvailable
= serverinfo
->fDsAvailable
;
259 r
->ServerInfoDotNet
->pszServerName
= talloc_strdup(mem_ctx
, serverinfo
->pszServerName
);
260 r
->ServerInfoDotNet
->pszDsContainer
= talloc_strdup(mem_ctx
, serverinfo
->pszDsContainer
);
261 r
->ServerInfoDotNet
->aipServerAddrs
= dns_addr_array_to_ip4_array(mem_ctx
,
262 serverinfo
->aipServerAddrs
);
263 r
->ServerInfoDotNet
->aipListenAddrs
= dns_addr_array_to_ip4_array(mem_ctx
,
264 serverinfo
->aipListenAddrs
);
265 r
->ServerInfoDotNet
->aipForwarders
= ip4_array_copy(mem_ctx
, serverinfo
->aipForwarders
);
266 r
->ServerInfoDotNet
->aipLogFilter
= ip4_array_copy(mem_ctx
, serverinfo
->aipLogFilter
);
267 r
->ServerInfoDotNet
->pwszLogFilePath
= talloc_strdup(mem_ctx
, serverinfo
->pwszLogFilePath
);
268 r
->ServerInfoDotNet
->pszDomainName
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainName
);
269 r
->ServerInfoDotNet
->pszForestName
= talloc_strdup(mem_ctx
, serverinfo
->pszForestName
);
270 r
->ServerInfoDotNet
->pszDomainDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainDirectoryPartition
);
271 r
->ServerInfoDotNet
->pszForestDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszForestDirectoryPartition
);
272 r
->ServerInfoDotNet
->dwLogLevel
= serverinfo
->dwLogLevel
;
273 r
->ServerInfoDotNet
->dwDebugLevel
= serverinfo
->dwDebugLevel
;
274 r
->ServerInfoDotNet
->dwForwardTimeout
= serverinfo
->dwForwardTimeout
;
275 r
->ServerInfoDotNet
->dwRpcProtocol
= serverinfo
->dwRpcProtocol
;
276 r
->ServerInfoDotNet
->dwNameCheckFlag
= serverinfo
->dwNameCheckFlag
;
277 r
->ServerInfoDotNet
->cAddressAnswerLimit
= serverinfo
->cAddressAnswerLimit
;
278 r
->ServerInfoDotNet
->dwRecursionRetry
= serverinfo
->dwRecursionRetry
;
279 r
->ServerInfoDotNet
->dwRecursionTimeout
= serverinfo
->dwRecursionTimeout
;
280 r
->ServerInfoDotNet
->dwMaxCacheTtl
= serverinfo
->dwMaxCacheTtl
;
281 r
->ServerInfoDotNet
->dwDsPollingInterval
= serverinfo
->dwDsPollingInterval
;
282 r
->ServerInfoDotNet
->dwLocalNetPriorityNetMask
= serverinfo
->dwLocalNetPriorityNetMask
;
283 r
->ServerInfoDotNet
->dwScavengingInterval
= serverinfo
->dwScavengingInterval
;
284 r
->ServerInfoDotNet
->dwDefaultRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
285 r
->ServerInfoDotNet
->dwDefaultNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
286 r
->ServerInfoDotNet
->dwLastScavengeTime
= serverinfo
->dwLastScavengeTime
;
287 r
->ServerInfoDotNet
->dwEventLogLevel
= serverinfo
->dwEventLogLevel
;
288 r
->ServerInfoDotNet
->dwLogFileMaxSize
= serverinfo
->dwLogFileMaxSize
;
289 r
->ServerInfoDotNet
->dwDsForestVersion
= serverinfo
->dwDsForestVersion
;
290 r
->ServerInfoDotNet
->dwDsDomainVersion
= serverinfo
->dwDsDomainVersion
;
291 r
->ServerInfoDotNet
->dwDsDsaVersion
= serverinfo
->dwDsDsaVersion
;
292 r
->ServerInfoDotNet
->fAutoReverseZones
= serverinfo
->fAutoReverseZones
;
293 r
->ServerInfoDotNet
->fAutoCacheUpdate
= serverinfo
->fAutoCacheUpdate
;
294 r
->ServerInfoDotNet
->fRecurseAfterForwarding
= serverinfo
->fRecurseAfterForwarding
;
295 r
->ServerInfoDotNet
->fForwardDelegations
= serverinfo
->fForwardDelegations
;
296 r
->ServerInfoDotNet
->fNoRecursion
= serverinfo
->fNoRecursion
;
297 r
->ServerInfoDotNet
->fSecureResponses
= serverinfo
->fSecureResponses
;
298 r
->ServerInfoDotNet
->fRoundRobin
= serverinfo
->fRoundRobin
;
299 r
->ServerInfoDotNet
->fLocalNetPriority
= serverinfo
->fLocalNetPriority
;
300 r
->ServerInfoDotNet
->fBindSecondaries
= serverinfo
->fBindSecondaries
;
301 r
->ServerInfoDotNet
->fWriteAuthorityNs
= serverinfo
->fWriteAuthorityNs
;
302 r
->ServerInfoDotNet
->fStrictFileParsing
= serverinfo
->fStrictFileParsing
;
303 r
->ServerInfoDotNet
->fLooseWildcarding
= serverinfo
->fLooseWildcarding
;
304 r
->ServerInfoDotNet
->fDefaultAgingState
= serverinfo
->fDefaultAgingState
;
306 } else if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
307 *typeid = DNSSRV_TYPEID_SERVER_INFO
;
308 r
->ServerInfo
= talloc_zero(mem_ctx
, struct DNS_RPC_SERVER_INFO_LONGHORN
);
310 r
->ServerInfo
->dwRpcStructureVersion
= 0x02;
311 r
->ServerInfo
->dwVersion
= serverinfo
->dwVersion
;
312 r
->ServerInfo
->fBootMethod
= serverinfo
->fBootMethod
;
313 r
->ServerInfo
->fAdminConfigured
= serverinfo
->fAdminConfigured
;
314 r
->ServerInfo
->fAllowUpdate
= serverinfo
->fAllowUpdate
;
315 r
->ServerInfo
->fDsAvailable
= serverinfo
->fDsAvailable
;
316 r
->ServerInfo
->pszServerName
= talloc_strdup(mem_ctx
, serverinfo
->pszServerName
);
317 r
->ServerInfo
->pszDsContainer
= talloc_strdup(mem_ctx
, serverinfo
->pszDsContainer
);
318 r
->ServerInfo
->aipServerAddrs
= serverinfo
->aipServerAddrs
;
319 r
->ServerInfo
->aipListenAddrs
= serverinfo
->aipListenAddrs
;
320 r
->ServerInfo
->aipForwarders
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipForwarders
);
321 r
->ServerInfo
->aipLogFilter
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipLogFilter
);
322 r
->ServerInfo
->pwszLogFilePath
= talloc_strdup(mem_ctx
, serverinfo
->pwszLogFilePath
);
323 r
->ServerInfo
->pszDomainName
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainName
);
324 r
->ServerInfo
->pszForestName
= talloc_strdup(mem_ctx
, serverinfo
->pszForestName
);
325 r
->ServerInfo
->pszDomainDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainDirectoryPartition
);
326 r
->ServerInfo
->pszForestDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszForestDirectoryPartition
);
327 r
->ServerInfo
->dwLogLevel
= serverinfo
->dwLogLevel
;
328 r
->ServerInfo
->dwDebugLevel
= serverinfo
->dwDebugLevel
;
329 r
->ServerInfo
->dwForwardTimeout
= serverinfo
->dwForwardTimeout
;
330 r
->ServerInfo
->dwRpcProtocol
= serverinfo
->dwRpcProtocol
;
331 r
->ServerInfo
->dwNameCheckFlag
= serverinfo
->dwNameCheckFlag
;
332 r
->ServerInfo
->cAddressAnswerLimit
= serverinfo
->cAddressAnswerLimit
;
333 r
->ServerInfo
->dwRecursionRetry
= serverinfo
->dwRecursionRetry
;
334 r
->ServerInfo
->dwRecursionTimeout
= serverinfo
->dwRecursionTimeout
;
335 r
->ServerInfo
->dwMaxCacheTtl
= serverinfo
->dwMaxCacheTtl
;
336 r
->ServerInfo
->dwDsPollingInterval
= serverinfo
->dwDsPollingInterval
;
337 r
->ServerInfo
->dwLocalNetPriorityNetMask
= serverinfo
->dwLocalNetPriorityNetMask
;
338 r
->ServerInfo
->dwScavengingInterval
= serverinfo
->dwScavengingInterval
;
339 r
->ServerInfo
->dwDefaultRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
340 r
->ServerInfo
->dwDefaultNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
341 r
->ServerInfo
->dwLastScavengeTime
= serverinfo
->dwLastScavengeTime
;
342 r
->ServerInfo
->dwEventLogLevel
= serverinfo
->dwEventLogLevel
;
343 r
->ServerInfo
->dwLogFileMaxSize
= serverinfo
->dwLogFileMaxSize
;
344 r
->ServerInfo
->dwDsForestVersion
= serverinfo
->dwDsForestVersion
;
345 r
->ServerInfo
->dwDsDomainVersion
= serverinfo
->dwDsDomainVersion
;
346 r
->ServerInfo
->dwDsDsaVersion
= serverinfo
->dwDsDsaVersion
;
347 r
->ServerInfo
->fReadOnlyDC
= serverinfo
->fReadOnlyDC
;
348 r
->ServerInfo
->fAutoReverseZones
= serverinfo
->fAutoReverseZones
;
349 r
->ServerInfo
->fAutoCacheUpdate
= serverinfo
->fAutoCacheUpdate
;
350 r
->ServerInfo
->fRecurseAfterForwarding
= serverinfo
->fRecurseAfterForwarding
;
351 r
->ServerInfo
->fForwardDelegations
= serverinfo
->fForwardDelegations
;
352 r
->ServerInfo
->fNoRecursion
= serverinfo
->fNoRecursion
;
353 r
->ServerInfo
->fSecureResponses
= serverinfo
->fSecureResponses
;
354 r
->ServerInfo
->fRoundRobin
= serverinfo
->fRoundRobin
;
355 r
->ServerInfo
->fLocalNetPriority
= serverinfo
->fLocalNetPriority
;
356 r
->ServerInfo
->fBindSecondaries
= serverinfo
->fBindSecondaries
;
357 r
->ServerInfo
->fWriteAuthorityNs
= serverinfo
->fWriteAuthorityNs
;
358 r
->ServerInfo
->fStrictFileParsing
= serverinfo
->fStrictFileParsing
;
359 r
->ServerInfo
->fLooseWildcarding
= serverinfo
->fLooseWildcarding
;
360 r
->ServerInfo
->fDefaultAgingState
= serverinfo
->fDefaultAgingState
;
367 if (strcasecmp(operation
, "AddressAnswerLimit") == 0) {
368 answer_integer
= serverinfo
->cAddressAnswerLimit
;
370 } else if (strcasecmp(operation
, "AdminConfigured") == 0) {
371 answer_integer
= serverinfo
->fAdminConfigured
;
373 } else if (strcasecmp(operation
, "AllowCNAMEAtNS") == 0) {
376 } else if (strcasecmp(operation
, "AllowUpdate") == 0) {
377 answer_integer
= serverinfo
->fAllowUpdate
;
379 } else if (strcasecmp(operation
, "AutoCacheUpdate") == 0) {
380 answer_integer
= serverinfo
->fAutoCacheUpdate
;
382 } else if (strcasecmp(operation
, "AutoConfigFileZones") == 0) {
385 } else if (strcasecmp(operation
, "BindSecondaries") == 0) {
386 answer_integer
= serverinfo
->fBindSecondaries
;
388 } else if (strcasecmp(operation
, "BootMethod") == 0) {
389 answer_integer
= serverinfo
->fBootMethod
;
391 } else if (strcasecmp(operation
, "DebugLevel") == 0) {
392 answer_integer
= serverinfo
->dwDebugLevel
;
394 } else if (strcasecmp(operation
, "DefaultAgingState") == 0) {
395 answer_integer
= serverinfo
->fDefaultAgingState
;
397 } else if (strcasecmp(operation
, "DefaultNoRefreshInterval") == 0) {
398 answer_integer
= serverinfo
->dwDefaultNoRefreshInterval
;
400 } else if (strcasecmp(operation
, "DefaultRefreshInterval") == 0) {
401 answer_integer
= serverinfo
->dwDefaultRefreshInterval
;
403 } else if (strcasecmp(operation
, "DeleteOutsideGlue") == 0) {
406 } else if (strcasecmp(operation
, "DisjointNets") == 0) {
409 } else if (strcasecmp(operation
, "DsLazyUpdateInterval") == 0) {
410 answer_integer
= 3; /* seconds */
412 } else if (strcasecmp(operation
, "DsPollingInterval") == 0) {
413 answer_integer
= serverinfo
->dwDsPollingInterval
;
415 } else if (strcasecmp(operation
, "DsTombstoneInterval") == 0) {
416 answer_integer
= 0x00127500; /* 14 days */
418 } else if (strcasecmp(operation
, "EnableRegistryBoot") == 0) {
421 } else if (strcasecmp(operation
, "EventLogLevel") == 0) {
422 answer_integer
= serverinfo
->dwEventLogLevel
;
424 } else if (strcasecmp(operation
, "ForceSoaSerial") == 0) {
427 } else if (strcasecmp(operation
, "ForceSaoRetry") == 0) {
430 } else if (strcasecmp(operation
, "ForceSoaRefresh") == 0) {
433 } else if (strcasecmp(operation
, "ForceSoaMinimumTtl") == 0) {
436 } else if (strcasecmp(operation
, "ForwardDelegations") == 0) {
439 } else if (strcasecmp(operation
, "ForwardingTimeout") == 0) {
440 answer_integer
= serverinfo
->dwForwardTimeout
;
442 } else if (strcasecmp(operation
, "IsSlave") == 0) {
445 } else if (strcasecmp(operation
, "LocalNetPriority") == 0) {
446 answer_integer
= serverinfo
->fLocalNetPriority
;
448 } else if (strcasecmp(operation
, "LogFileMaxSize") == 0) {
449 answer_integer
= serverinfo
->dwLogFileMaxSize
;
451 } else if (strcasecmp(operation
, "LogLevel") == 0) {
452 answer_integer
= serverinfo
->dwLogLevel
;
454 } else if (strcasecmp(operation
, "LooseWildcarding") == 0) {
455 answer_integer
= serverinfo
->fLooseWildcarding
;
457 } else if (strcasecmp(operation
, "MaxCacheTtl") == 0) {
458 answer_integer
= serverinfo
->dwMaxCacheTtl
;
460 } else if (strcasecmp(operation
, "MaxNegativeCacheTtl") == 0) {
461 answer_integer
= 0x00000384; /* 15 minutes */
463 } else if (strcasecmp(operation
, "NameCheckFlag") == 0) {
464 answer_integer
= serverinfo
->dwNameCheckFlag
;
466 } else if (strcasecmp(operation
, "NoRecursion") == 0) {
467 answer_integer
= serverinfo
->fNoRecursion
;
469 } else if (strcasecmp(operation
, "NoUpdateDelegations") == 0) {
472 } else if (strcasecmp(operation
, "PublishAutonet") == 0) {
475 } else if (strcasecmp(operation
, "QuietRecvFaultInterval") == 0) {
478 } else if (strcasecmp(operation
, "QuietRecvLogInterval") == 0) {
481 } else if (strcasecmp(operation
, "RecursionRetry") == 0) {
482 answer_integer
= serverinfo
->dwRecursionRetry
;
484 } else if (strcasecmp(operation
, "RecursionTimeout") == 0) {
485 answer_integer
= serverinfo
->dwRecursionTimeout
;
487 } else if (strcasecmp(operation
, "ReloadException") == 0) {
490 } else if (strcasecmp(operation
, "RoundRobin") == 0) {
491 answer_integer
= serverinfo
->fRoundRobin
;
493 } else if (strcasecmp(operation
, "RpcProtocol") == 0) {
494 answer_integer
= serverinfo
->dwRpcProtocol
;
496 } else if (strcasecmp(operation
, "SecureResponses") == 0) {
497 answer_integer
= serverinfo
->fSecureResponses
;
499 } else if (strcasecmp(operation
, "SendPort") == 0) {
502 } else if (strcasecmp(operation
, "ScavengingInterval") == 0) {
503 answer_integer
= serverinfo
->dwScavengingInterval
;
505 } else if (strcasecmp(operation
, "SocketPoolSize") == 0) {
506 answer_integer
= 0x000009C4;
508 } else if (strcasecmp(operation
, "StrictFileParsing") == 0) {
509 answer_integer
= serverinfo
->fStrictFileParsing
;
511 } else if (strcasecmp(operation
, "SyncDnsZoneSerial") == 0) {
512 answer_integer
= 2; /* ZONE_SERIAL_SYNC_XFER */
514 } else if (strcasecmp(operation
, "UpdateOptions") == 0) {
515 answer_integer
= 0x0000030F; /* DNS_DEFAULT_UPDATE_OPTIONS */
517 } else if (strcasecmp(operation
, "UseSystemEvengLog") == 0) {
520 } else if (strcasecmp(operation
, "Version") == 0) {
521 answer_integer
= serverinfo
->dwVersion
;
523 } else if (strcasecmp(operation
, "XfrConnectTimeout") == 0) {
524 answer_integer
= 0x0000001E;
526 } else if (strcasecmp(operation
, "WriteAuthorityNs") == 0) {
527 answer_integer
= serverinfo
->fWriteAuthorityNs
;
529 } else if (strcasecmp(operation
, "AdditionalRecursionTimeout") == 0) {
530 answer_integer
= 0x00000004;
532 } else if (strcasecmp(operation
, "AppendMsZoneTransferFlag") == 0) {
535 } else if (strcasecmp(operation
, "AutoCreateDelegations") == 0) {
536 answer_integer
= 0; /* DNS_ACD_DONT_CREATE */
538 } else if (strcasecmp(operation
, "BreakOnAscFailure") == 0) {
541 } else if (strcasecmp(operation
, "CacheEmptyAuthResponses") == 0) {
544 } else if (strcasecmp(operation
, "DirectoryPartitionAutoEnlistInterval") == 0) {
545 answer_integer
= 0x00015180; /* 1 day */
547 } else if (strcasecmp(operation
, "DisableAutoReverseZones") == 0) {
548 answer_integer
= ~serverinfo
->fAutoReverseZones
;
550 } else if (strcasecmp(operation
, "EDnsCacheTimeout") == 0) {
551 answer_integer
= 0x00000384; /* 15 minutes */
553 } else if (strcasecmp(operation
, "EnableDirectoryPartitions") == 0) {
554 answer_integer
= serverinfo
->fDsAvailable
;
556 } else if (strcasecmp(operation
, "EnableDnsSec") == 0) {
559 } else if (strcasecmp(operation
, "EnableEDnsProbes") == 0) {
562 } else if (strcasecmp(operation
, "EnableEDnsReception") == 0) {
565 } else if (strcasecmp(operation
, "EnableIPv6") == 0) {
568 } else if (strcasecmp(operation
, "EnableIQueryResponseGeneration") == 0) {
571 } else if (strcasecmp(operation
, "EnableSendErrorSuppression") == 0) {
574 } else if (strcasecmp(operation
, "EnableUpdateForwarding") == 0) {
577 } else if (strcasecmp(operation
, "EnableWinsR") == 0) {
580 } else if (strcasecmp(operation
, "ForceDsaBehaviorVersion") == 0) {
581 answer_integer
= serverinfo
->dwDsDsaVersion
;
583 } else if (strcasecmp(operation
, "ForceDomainBehaviorVersion") == 0) {
584 answer_integer
= serverinfo
->dwDsDsaVersion
;
586 } else if (strcasecmp(operation
, "ForceForestBehaviorVersion") == 0) {
587 answer_integer
= serverinfo
->dwDsDsaVersion
;
589 } else if (strcasecmp(operation
, "HeapDebug") == 0) {
592 } else if (strcasecmp(operation
, "LameDelegationTtl") == 0) {
593 answer_integer
= 0; /* seconds */
595 } else if (strcasecmp(operation
, "LocalNetPriorityNetMask") == 0) {
596 answer_integer
= serverinfo
->dwLocalNetPriorityNetMask
;
598 } else if (strcasecmp(operation
, "MaxCacheSize") == 0) {
601 } else if (strcasecmp(operation
, "MaxResourceRecordsInNonSecureUpdate") == 0) {
602 answer_integer
= 0x0000001E;
604 } else if (strcasecmp(operation
, "OperationsLogLevel") == 0) {
607 } else if (strcasecmp(operation
, "OperationsLogLevel2") == 0) {
610 } else if (strcasecmp(operation
, "MaximumUdpPacketSize") == 0) {
611 answer_integer
= 0x00004000; /* maximum possible */
613 } else if (strcasecmp(operation
, "RecurseToInternetRootMask") == 0) {
616 } else if (strcasecmp(operation
, "SelfTest") == 0) {
619 } else if (strcasecmp(operation
, "SilentlyIgnoreCNameUpdateConflicts") == 0) {
622 } else if (strcasecmp(operation
, "TcpReceivePacketSize") == 0) {
623 answer_integer
= 0x00010000;
625 } else if (strcasecmp(operation
, "XfrThrottleMultiplier") == 0) {
626 answer_integer
= 0x0000000A;
628 } else if (strcasecmp(operation
, "AllowMsdcsLookupRetry") == 0) {
631 } else if (strcasecmp(operation
, "AllowReadOnlyZoneTransfer") == 0) {
634 } else if (strcasecmp(operation
, "DsBackGroundLoadPaused") == 0) {
637 } else if (strcasecmp(operation
, "DsMinimumBackgroundLoadThreads") == 0) {
640 } else if (strcasecmp(operation
, "DsRemoteReplicationDelay") == 0) {
641 answer_integer
= 0x0000001E; /* 30 seconds */
643 } else if (strcasecmp(operation
, "EnableDuplicateQuerySuppresion") == 0) {
646 } else if (strcasecmp(operation
, "EnableGlobalNamesSupport") == 0) {
649 } else if (strcasecmp(operation
, "EnableVersionQuery") == 0) {
650 answer_integer
= 1; /* DNS_VERSION_QUERY_FULL */
652 } else if (strcasecmp(operation
, "EnableRsoForRodc") == 0) {
655 } else if (strcasecmp(operation
, "ForceRODCMode") == 0) {
658 } else if (strcasecmp(operation
, "GlobalNamesAlwaysQuerySrv") == 0) {
661 } else if (strcasecmp(operation
, "GlobalNamesBlockUpdates") == 0) {
664 } else if (strcasecmp(operation
, "GlobalNamesEnableEDnsProbes") == 0) {
667 } else if (strcasecmp(operation
, "GlobalNamesPreferAAAA") == 0) {
670 } else if (strcasecmp(operation
, "GlobalNamesQueryOrder") == 0) {
673 } else if (strcasecmp(operation
, "GlobalNamesSendTimeout") == 0) {
674 answer_integer
= 3; /* seconds */
676 } else if (strcasecmp(operation
, "GlobalNamesServerQueryInterval") == 0) {
677 answer_integer
= 0x00005460; /* 6 hours */
679 } else if (strcasecmp(operation
, "RemoteIPv4RankBoost") == 0) {
682 } else if (strcasecmp(operation
, "RemoteIPv6RankBoost") == 0) {
685 } else if (strcasecmp(operation
, "MaximumRodcRsoAttemptsPerCycle") == 0) {
686 answer_integer
= 0x00000064;
688 } else if (strcasecmp(operation
, "MaximumRodcRsoQueueLength") == 0) {
689 answer_integer
= 0x0000012C;
691 } else if (strcasecmp(operation
, "EnableGlobalQueryBlockList") == 0) {
694 } else if (strcasecmp(operation
, "OpenACLOnProxyUpdates") == 0) {
697 } else if (strcasecmp(operation
, "CacheLockingPercent") == 0) {
698 answer_integer
= 0x00000064;
702 if (is_integer
== 1) {
703 *typeid = DNSSRV_TYPEID_DWORD
;
704 r
->Dword
= answer_integer
;
710 if (strcasecmp(operation
, "Forwarders") == 0) {
711 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
712 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipForwarders
);
714 answer_iparray
= ip4_array_copy(mem_ctx
, serverinfo
->aipForwarders
);
717 } else if (strcasecmp(operation
, "ListenAddresses") == 0) {
718 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
719 answer_addrarray
= serverinfo
->aipListenAddrs
;
721 answer_iparray
= dns_addr_array_to_ip4_array(mem_ctx
, serverinfo
->aipListenAddrs
);
724 } else if (strcasecmp(operation
, "BreakOnReceiveFrom") == 0) {
725 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
726 answer_addrarray
= NULL
;
728 answer_iparray
= NULL
;
731 } else if (strcasecmp(operation
, "BreakOnUpdateFrom") == 0) {
732 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
733 answer_addrarray
= NULL
;
735 answer_iparray
= NULL
;
738 } else if (strcasecmp(operation
, "LogIPFilterList") == 0) {
739 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
740 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipLogFilter
);
742 answer_iparray
= ip4_array_copy(mem_ctx
, serverinfo
->aipLogFilter
);
747 if (is_addresses
== 1) {
748 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
749 *typeid = DNSSRV_TYPEID_ADDRARRAY
;
750 r
->AddrArray
= answer_addrarray
;
752 *typeid = DNSSRV_TYPEID_IPARRAY
;
753 r
->IpArray
= answer_iparray
;
758 is_string
= is_wstring
= 0;
760 if (strcasecmp(operation
, "DomainDirectoryPartitionBaseName") == 0) {
761 answer_string
= talloc_strdup(mem_ctx
, "DomainDnsZones");
762 if (! answer_string
) {
763 return WERR_OUTOFMEMORY
;
766 } else if (strcasecmp(operation
, "ForestDirectoryPartitionBaseName") == 0) {
767 answer_string
= talloc_strdup(mem_ctx
, "ForestDnsZones");
768 if (! answer_string
) {
769 return WERR_OUTOFMEMORY
;
772 } else if (strcasecmp(operation
, "LogFilePath") == 0) {
773 answer_string
= talloc_strdup(mem_ctx
, serverinfo
->pwszLogFilePath
);
775 } else if (strcasecmp(operation
, "ServerLevelPluginDll") == 0) {
776 answer_string
= NULL
;
778 } else if (strcasecmp(operation
, "DsBackgroundPauseName") == 0) {
779 answer_string
= NULL
;
781 } else if (strcasecmp(operation
, "DsNotRoundRobinTypes") == 0) {
782 answer_string
= NULL
;
786 if (is_string
== 1) {
787 *typeid = DNSSRV_TYPEID_LPSTR
;
788 r
->String
= answer_string
;
790 } else if (is_wstring
== 1) {
791 *typeid = DNSSRV_TYPEID_LPWSTR
;
792 r
->WideString
= answer_string
;
798 if (strcasecmp(operation
, "GlobalQueryBlockList") == 0) {
799 answer_stringlist
= NULL
;
801 } else if (strcasecmp(operation
, "SocketPoolExcludedPortRanges") == 0) {
802 answer_stringlist
= NULL
;
806 if (is_stringlist
== 1) {
807 *typeid = DNSSRV_TYPEID_UTF8_STRING_LIST
;
808 r
->Utf8StringList
= answer_stringlist
;
812 DEBUG(0,("dnsserver: Invalid server operation %s", operation
));
813 return WERR_DNS_ERROR_INVALID_PROPERTY
;
816 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
817 static WERROR
dnsserver_query_zone(struct dnsserver_state
*dsstate
,
819 struct dnsserver_zone
*z
,
820 const char *operation
,
821 const unsigned int client_version
,
822 enum DNS_RPC_TYPEID
*typeid,
823 union DNSSRV_RPC_UNION
*r
)
825 uint8_t is_integer
, is_addresses
, is_string
;
826 uint32_t answer_integer
;
827 struct IP4_ARRAY
*answer_iparray
;
828 struct DNS_ADDR_ARRAY
*answer_addrarray
;
830 struct dnsserver_zoneinfo
*zoneinfo
;
832 zoneinfo
= z
->zoneinfo
;
834 if (strcasecmp(operation
, "Zone") == 0) {
835 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
836 *typeid = DNSSRV_TYPEID_ZONE_W2K
;
837 r
->ZoneW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_W2K
);
839 r
->ZoneW2K
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
840 r
->ZoneW2K
->Flags
= zoneinfo
->Flags
;
841 r
->ZoneW2K
->ZoneType
= zoneinfo
->dwZoneType
;
842 r
->ZoneW2K
->Version
= zoneinfo
->Version
;
844 *typeid = DNSSRV_TYPEID_ZONE
;
845 r
->Zone
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_DOTNET
);
847 r
->Zone
->dwRpcStructureVersion
= 0x01;
848 r
->Zone
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
849 r
->Zone
->Flags
= zoneinfo
->Flags
;
850 r
->Zone
->ZoneType
= zoneinfo
->dwZoneType
;
851 r
->Zone
->Version
= zoneinfo
->Version
;
852 r
->Zone
->dwDpFlags
= z
->partition
->dwDpFlags
;
853 r
->Zone
->pszDpFqdn
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
858 if (strcasecmp(operation
, "ZoneInfo") == 0) {
859 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
860 *typeid = DNSSRV_TYPEID_ZONE_INFO_W2K
;
861 r
->ZoneInfoW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_INFO_W2K
);
863 r
->ZoneInfoW2K
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
864 r
->ZoneInfoW2K
->dwZoneType
= zoneinfo
->dwZoneType
;
865 r
->ZoneInfoW2K
->fReverse
= zoneinfo
->fReverse
;
866 r
->ZoneInfoW2K
->fAllowUpdate
= zoneinfo
->fAllowUpdate
;
867 r
->ZoneInfoW2K
->fPaused
= zoneinfo
->fPaused
;
868 r
->ZoneInfoW2K
->fShutdown
= zoneinfo
->fShutdown
;
869 r
->ZoneInfoW2K
->fAutoCreated
= zoneinfo
->fAutoCreated
;
870 r
->ZoneInfoW2K
->fUseDatabase
= zoneinfo
->fUseDatabase
;
871 r
->ZoneInfoW2K
->pszDataFile
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
872 r
->ZoneInfoW2K
->aipMasters
= ip4_array_copy(mem_ctx
, zoneinfo
->aipMasters
);
873 r
->ZoneInfoW2K
->fSecureSecondaries
= zoneinfo
->fSecureSecondaries
;
874 r
->ZoneInfoW2K
->fNotifyLevel
= zoneinfo
->fNotifyLevel
;
875 r
->ZoneInfoW2K
->aipSecondaries
= ip4_array_copy(mem_ctx
, zoneinfo
->aipSecondaries
);
876 r
->ZoneInfoW2K
->aipNotify
= ip4_array_copy(mem_ctx
, zoneinfo
->aipNotify
);
877 r
->ZoneInfoW2K
->fUseWins
= zoneinfo
->fUseWins
;
878 r
->ZoneInfoW2K
->fUseNbstat
= zoneinfo
->fUseNbstat
;
879 r
->ZoneInfoW2K
->fAging
= zoneinfo
->fAging
;
880 r
->ZoneInfoW2K
->dwNoRefreshInterval
= zoneinfo
->dwNoRefreshInterval
;
881 r
->ZoneInfoW2K
->dwRefreshInterval
= zoneinfo
->dwRefreshInterval
;
882 r
->ZoneInfoW2K
->dwAvailForScavengeTime
= zoneinfo
->dwAvailForScavengeTime
;
883 r
->ZoneInfoW2K
->aipScavengeServers
= ip4_array_copy(mem_ctx
, zoneinfo
->aipScavengeServers
);
885 } else if (client_version
== DNS_CLIENT_VERSION_DOTNET
) {
886 *typeid = DNSSRV_TYPEID_ZONE_INFO_DOTNET
;
887 r
->ZoneInfoDotNet
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_INFO_DOTNET
);
889 r
->ZoneInfoDotNet
->dwRpcStructureVersion
= 0x01;
890 r
->ZoneInfoDotNet
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
891 r
->ZoneInfoDotNet
->dwZoneType
= zoneinfo
->dwZoneType
;
892 r
->ZoneInfoDotNet
->fReverse
= zoneinfo
->fReverse
;
893 r
->ZoneInfoDotNet
->fAllowUpdate
= zoneinfo
->fAllowUpdate
;
894 r
->ZoneInfoDotNet
->fPaused
= zoneinfo
->fPaused
;
895 r
->ZoneInfoDotNet
->fShutdown
= zoneinfo
->fShutdown
;
896 r
->ZoneInfoDotNet
->fAutoCreated
= zoneinfo
->fAutoCreated
;
897 r
->ZoneInfoDotNet
->fUseDatabase
= zoneinfo
->fUseDatabase
;
898 r
->ZoneInfoDotNet
->pszDataFile
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
899 r
->ZoneInfoDotNet
->aipMasters
= ip4_array_copy(mem_ctx
, zoneinfo
->aipMasters
);
900 r
->ZoneInfoDotNet
->fSecureSecondaries
= zoneinfo
->fSecureSecondaries
;
901 r
->ZoneInfoDotNet
->fNotifyLevel
= zoneinfo
->fNotifyLevel
;
902 r
->ZoneInfoDotNet
->aipSecondaries
= ip4_array_copy(mem_ctx
, zoneinfo
->aipSecondaries
);
903 r
->ZoneInfoDotNet
->aipNotify
= ip4_array_copy(mem_ctx
, zoneinfo
->aipNotify
);
904 r
->ZoneInfoDotNet
->fUseWins
= zoneinfo
->fUseWins
;
905 r
->ZoneInfoDotNet
->fUseNbstat
= zoneinfo
->fUseNbstat
;
906 r
->ZoneInfoDotNet
->fAging
= zoneinfo
->fAging
;
907 r
->ZoneInfoDotNet
->dwNoRefreshInterval
= zoneinfo
->dwNoRefreshInterval
;
908 r
->ZoneInfoDotNet
->dwRefreshInterval
= zoneinfo
->dwRefreshInterval
;
909 r
->ZoneInfoDotNet
->dwAvailForScavengeTime
= zoneinfo
->dwAvailForScavengeTime
;
910 r
->ZoneInfoDotNet
->aipScavengeServers
= ip4_array_copy(mem_ctx
, zoneinfo
->aipScavengeServers
);
911 r
->ZoneInfoDotNet
->dwForwarderTimeout
= zoneinfo
->dwForwarderTimeout
;
912 r
->ZoneInfoDotNet
->fForwarderSlave
= zoneinfo
->fForwarderSlave
;
913 r
->ZoneInfoDotNet
->aipLocalMasters
= ip4_array_copy(mem_ctx
, zoneinfo
->aipLocalMasters
);
914 r
->ZoneInfoDotNet
->dwDpFlags
= z
->partition
->dwDpFlags
;
915 r
->ZoneInfoDotNet
->pszDpFqdn
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
916 r
->ZoneInfoDotNet
->pwszZoneDn
= talloc_strdup(mem_ctx
, zoneinfo
->pwszZoneDn
);
917 r
->ZoneInfoDotNet
->dwLastSuccessfulSoaCheck
= zoneinfo
->dwLastSuccessfulSoaCheck
;
918 r
->ZoneInfoDotNet
->dwLastSuccessfulXfr
= zoneinfo
->dwLastSuccessfulXfr
;
921 *typeid = DNSSRV_TYPEID_ZONE_INFO
;
922 r
->ZoneInfo
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_INFO_LONGHORN
);
924 r
->ZoneInfo
->dwRpcStructureVersion
= 0x02;
925 r
->ZoneInfo
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
926 r
->ZoneInfo
->dwZoneType
= zoneinfo
->dwZoneType
;
927 r
->ZoneInfo
->fReverse
= zoneinfo
->fReverse
;
928 r
->ZoneInfo
->fAllowUpdate
= zoneinfo
->fAllowUpdate
;
929 r
->ZoneInfo
->fPaused
= zoneinfo
->fPaused
;
930 r
->ZoneInfo
->fShutdown
= zoneinfo
->fShutdown
;
931 r
->ZoneInfo
->fAutoCreated
= zoneinfo
->fAutoCreated
;
932 r
->ZoneInfo
->fUseDatabase
= zoneinfo
->fUseDatabase
;
933 r
->ZoneInfo
->pszDataFile
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
934 r
->ZoneInfo
->aipMasters
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipMasters
);
935 r
->ZoneInfo
->fSecureSecondaries
= zoneinfo
->fSecureSecondaries
;
936 r
->ZoneInfo
->fNotifyLevel
= zoneinfo
->fNotifyLevel
;
937 r
->ZoneInfo
->aipSecondaries
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipSecondaries
);
938 r
->ZoneInfo
->aipNotify
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipNotify
);
939 r
->ZoneInfo
->fUseWins
= zoneinfo
->fUseWins
;
940 r
->ZoneInfo
->fUseNbstat
= zoneinfo
->fUseNbstat
;
941 r
->ZoneInfo
->fAging
= zoneinfo
->fAging
;
942 r
->ZoneInfo
->dwNoRefreshInterval
= zoneinfo
->dwNoRefreshInterval
;
943 r
->ZoneInfo
->dwRefreshInterval
= zoneinfo
->dwRefreshInterval
;
944 r
->ZoneInfo
->dwAvailForScavengeTime
= zoneinfo
->dwAvailForScavengeTime
;
945 r
->ZoneInfo
->aipScavengeServers
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipScavengeServers
);
946 r
->ZoneInfo
->dwForwarderTimeout
= zoneinfo
->dwForwarderTimeout
;
947 r
->ZoneInfo
->fForwarderSlave
= zoneinfo
->fForwarderSlave
;
948 r
->ZoneInfo
->aipLocalMasters
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipLocalMasters
);
949 r
->ZoneInfo
->dwDpFlags
= z
->partition
->dwDpFlags
;
950 r
->ZoneInfo
->pszDpFqdn
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
951 r
->ZoneInfo
->pwszZoneDn
= talloc_strdup(mem_ctx
, zoneinfo
->pwszZoneDn
);
952 r
->ZoneInfo
->dwLastSuccessfulSoaCheck
= zoneinfo
->dwLastSuccessfulSoaCheck
;
953 r
->ZoneInfo
->dwLastSuccessfulXfr
= zoneinfo
->dwLastSuccessfulXfr
;
955 r
->ZoneInfo
->fQueuedForBackgroundLoad
= zoneinfo
->fQueuedForBackgroundLoad
;
956 r
->ZoneInfo
->fBackgroundLoadInProgress
= zoneinfo
->fBackgroundLoadInProgress
;
957 r
->ZoneInfo
->fReadOnlyZone
= zoneinfo
->fReadOnlyZone
;
958 r
->ZoneInfo
->dwLastXfrAttempt
= zoneinfo
->dwLastXfrAttempt
;
959 r
->ZoneInfo
->dwLastXfrResult
= zoneinfo
->dwLastXfrResult
;
967 if (strcasecmp(operation
, "AllowUpdate") == 0) {
968 answer_integer
= zoneinfo
->fAllowUpdate
;
970 } else if (strcasecmp(operation
, "Secured") == 0) {
973 } else if (strcasecmp(operation
, "DsIntegrated") == 0) {
974 answer_integer
= zoneinfo
->fUseDatabase
;
976 } else if (strcasecmp(operation
, "LogUpdates") == 0) {
979 } else if (strcasecmp(operation
, "NoRefreshInterval") == 0) {
980 answer_integer
= zoneinfo
->dwNoRefreshInterval
;
982 } else if (strcasecmp(operation
, "NotifyLevel") == 0) {
983 answer_integer
= zoneinfo
->fNotifyLevel
;
985 } else if (strcasecmp(operation
, "RefreshInterval") == 0) {
986 answer_integer
= zoneinfo
->dwRefreshInterval
;
988 } else if (strcasecmp(operation
, "SecureSecondaries") == 0) {
989 answer_integer
= zoneinfo
->fSecureSecondaries
;
991 } else if (strcasecmp(operation
, "Type") == 0) {
992 answer_integer
= zoneinfo
->dwZoneType
;
994 } else if (strcasecmp(operation
, "Aging") == 0) {
995 answer_integer
= zoneinfo
->fAging
;
997 } else if (strcasecmp(operation
, "ForwarderSlave") == 0) {
998 answer_integer
= zoneinfo
->fForwarderSlave
;
1000 } else if (strcasecmp(operation
, "ForwarderTimeout") == 0) {
1001 answer_integer
= zoneinfo
->dwForwarderTimeout
;
1003 } else if (strcasecmp(operation
, "Unicode") == 0) {
1008 if (is_integer
== 1) {
1009 *typeid = DNSSRV_TYPEID_DWORD
;
1010 r
->Dword
= answer_integer
;
1016 if (strcasecmp(operation
, "AllowNSRecordsAutoCreation") == 0) {
1017 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1018 answer_addrarray
= NULL
;
1020 answer_iparray
= NULL
;
1023 } else if (strcasecmp(operation
, "ScavengeServers") == 0) {
1024 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1025 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipScavengeServers
);
1027 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipScavengeServers
);
1030 } else if (strcasecmp(operation
, "MasterServers") == 0) {
1031 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1032 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipMasters
);
1034 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipMasters
);
1037 } else if (strcasecmp(operation
, "LocalMasterServers") == 0) {
1038 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1039 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipLocalMasters
);
1041 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipLocalMasters
);
1044 } else if (strcasecmp(operation
, "NotifyServers") == 0) {
1045 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1046 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipNotify
);
1048 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipNotify
);
1051 } else if (strcasecmp(operation
, "SecondaryServers") == 0) {
1052 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1053 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipSecondaries
);
1055 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipSecondaries
);
1060 if (is_addresses
== 1) {
1061 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1062 *typeid = DNSSRV_TYPEID_ADDRARRAY
;
1063 r
->AddrArray
= answer_addrarray
;
1065 *typeid = DNSSRV_TYPEID_IPARRAY
;
1066 r
->IpArray
= answer_iparray
;
1073 if (strcasecmp(operation
, "DatabaseFile") == 0) {
1074 answer_string
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
1076 } else if (strcasecmp(operation
, "ApplicationDirectoryPartition") == 0) {
1077 answer_string
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
1079 } else if (strcasecmp(operation
, "BreakOnNameUpdate") == 0) {
1080 answer_string
= NULL
;
1084 if (is_string
== 1) {
1085 *typeid = DNSSRV_TYPEID_LPSTR
;
1086 r
->String
= answer_string
;
1090 DEBUG(0,("dnsserver: Invalid zone operation %s", operation
));
1091 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1095 /* dnsserver operation functions */
1097 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
1098 static WERROR
dnsserver_operate_server(struct dnsserver_state
*dsstate
,
1099 TALLOC_CTX
*mem_ctx
,
1100 const char *operation
,
1101 const unsigned int client_version
,
1102 enum DNS_RPC_TYPEID
typeid,
1103 union DNSSRV_RPC_UNION
*r
)
1105 bool valid_operation
= false;
1107 if (strcasecmp(operation
, "ResetDwordProperty") == 0) {
1108 valid_operation
= true;
1109 } else if (strcasecmp(operation
, "Restart") == 0) {
1110 valid_operation
= true;
1111 } else if (strcasecmp(operation
, "ClearDebugLog") == 0) {
1112 valid_operation
= true;
1113 } else if (strcasecmp(operation
, "ClearCache") == 0) {
1114 valid_operation
= true;
1115 } else if (strcasecmp(operation
, "WriteDirtyZones") == 0) {
1116 valid_operation
= true;
1117 } else if (strcasecmp(operation
, "ZoneCreate") == 0) {
1118 struct dnsserver_zone
*z
, *z2
;
1121 z
= talloc_zero(mem_ctx
, struct dnsserver_zone
);
1122 W_ERROR_HAVE_NO_MEMORY(z
);
1123 z
->partition
= talloc_zero(z
, struct dnsserver_partition
);
1124 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z
->partition
, z
);
1125 z
->zoneinfo
= talloc_zero(z
, struct dnsserver_zoneinfo
);
1126 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z
->zoneinfo
, z
);
1128 if (typeid == DNSSRV_TYPEID_ZONE_CREATE_W2K
) {
1129 z
->name
= talloc_strdup(z
, r
->ZoneCreateW2K
->pszZoneName
);
1130 z
->zoneinfo
->dwZoneType
= r
->ZoneCreateW2K
->dwZoneType
;
1131 z
->zoneinfo
->fAllowUpdate
= r
->ZoneCreateW2K
->fAllowUpdate
;
1132 z
->zoneinfo
->fAging
= r
->ZoneCreateW2K
->fAging
;
1133 z
->zoneinfo
->Flags
= r
->ZoneCreateW2K
->dwFlags
;
1134 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE_DOTNET
) {
1135 z
->name
= talloc_strdup(z
, r
->ZoneCreateDotNet
->pszZoneName
);
1136 z
->zoneinfo
->dwZoneType
= r
->ZoneCreateDotNet
->dwZoneType
;
1137 z
->zoneinfo
->fAllowUpdate
= r
->ZoneCreateDotNet
->fAllowUpdate
;
1138 z
->zoneinfo
->fAging
= r
->ZoneCreateDotNet
->fAging
;
1139 z
->zoneinfo
->Flags
= r
->ZoneCreateDotNet
->dwFlags
;
1140 z
->partition
->dwDpFlags
= r
->ZoneCreateDotNet
->dwDpFlags
;
1141 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE
) {
1142 z
->name
= talloc_strdup(z
, r
->ZoneCreate
->pszZoneName
);
1143 z
->zoneinfo
->dwZoneType
= r
->ZoneCreate
->dwZoneType
;
1144 z
->zoneinfo
->fAllowUpdate
= r
->ZoneCreate
->fAllowUpdate
;
1145 z
->zoneinfo
->fAging
= r
->ZoneCreate
->fAging
;
1146 z
->zoneinfo
->Flags
= r
->ZoneCreate
->dwFlags
;
1147 z
->partition
->dwDpFlags
= r
->ZoneCreate
->dwDpFlags
;
1150 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1153 z2
= dnsserver_find_zone(dsstate
->zones
, z
->name
);
1156 return WERR_DNS_ERROR_ZONE_ALREADY_EXISTS
;
1159 status
= dnsserver_db_create_zone(dsstate
->samdb
, dsstate
->partitions
, z
,
1163 if (W_ERROR_IS_OK(status
)) {
1164 dnsserver_reload_zones(dsstate
);
1167 } else if (strcasecmp(operation
, "ClearStatistics") == 0) {
1168 valid_operation
= true;
1169 } else if (strcasecmp(operation
, "EnlistDirectoryPartition") == 0) {
1170 valid_operation
= true;
1171 } else if (strcasecmp(operation
, "StartScavenging") == 0) {
1172 valid_operation
= true;
1173 } else if (strcasecmp(operation
, "AbortScavenging") == 0) {
1174 valid_operation
= true;
1175 } else if (strcasecmp(operation
, "AutoConfigure") == 0) {
1176 valid_operation
= true;
1177 } else if (strcasecmp(operation
, "ExportSettings") == 0) {
1178 valid_operation
= true;
1179 } else if (strcasecmp(operation
, "PrepareForDemotion") == 0) {
1180 valid_operation
= true;
1181 } else if (strcasecmp(operation
, "PrepareForUninstall") == 0) {
1182 valid_operation
= true;
1183 } else if (strcasecmp(operation
, "DeleteNode") == 0) {
1184 valid_operation
= true;
1185 } else if (strcasecmp(operation
, "DeleteRecord") == 0) {
1186 valid_operation
= true;
1187 } else if (strcasecmp(operation
, "WriteBackFile") == 0) {
1188 valid_operation
= true;
1189 } else if (strcasecmp(operation
, "ListenAddresses") == 0) {
1190 valid_operation
= true;
1191 } else if (strcasecmp(operation
, "Forwarders") == 0) {
1192 valid_operation
= true;
1193 } else if (strcasecmp(operation
, "LogFilePath") == 0) {
1194 valid_operation
= true;
1195 } else if (strcasecmp(operation
, "LogIpFilterList") == 0) {
1196 valid_operation
= true;
1197 } else if (strcasecmp(operation
, "ForestDirectoryPartitionBaseName") == 0) {
1198 valid_operation
= true;
1199 } else if (strcasecmp(operation
, "DomainDirectoryPartitionBaseName") == 0) {
1200 valid_operation
= true;
1201 } else if (strcasecmp(operation
, "GlobalQueryBlockList") == 0) {
1202 valid_operation
= true;
1203 } else if (strcasecmp(operation
, "BreakOnReceiveFrom") == 0) {
1204 valid_operation
= true;
1205 } else if (strcasecmp(operation
, "BreakOnUpdateFrom") == 0) {
1206 valid_operation
= true;
1207 } else if (strcasecmp(operation
, "ServerLevelPluginDll") == 0) {
1208 valid_operation
= true;
1211 if (valid_operation
) {
1212 DEBUG(0, ("dnsserver: server operation '%s' not implemented", operation
));
1213 return WERR_CALL_NOT_IMPLEMENTED
;
1216 DEBUG(0, ("dnsserver: invalid server operation '%s'", operation
));
1217 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1220 static WERROR
dnsserver_complex_operate_server(struct dnsserver_state
*dsstate
,
1221 TALLOC_CTX
*mem_ctx
,
1222 const char *operation
,
1223 const unsigned int client_version
,
1224 enum DNS_RPC_TYPEID typeid_in
,
1225 union DNSSRV_RPC_UNION
*rin
,
1226 enum DNS_RPC_TYPEID
*typeid_out
,
1227 union DNSSRV_RPC_UNION
*rout
)
1229 int valid_operation
= 0;
1230 struct dnsserver_zone
*z
, **zlist
;
1232 bool found1
, found2
, found3
, found4
;
1235 if (strcasecmp(operation
, "QueryDwordProperty") == 0) {
1236 if (typeid_in
== DNSSRV_TYPEID_LPSTR
) {
1237 return dnsserver_query_server(dsstate
, mem_ctx
,
1243 } else if (strcasecmp(operation
, "EnumZones") == 0) {
1244 if (typeid_in
!= DNSSRV_TYPEID_DWORD
) {
1245 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1249 zlist
= talloc_zero_array(mem_ctx
, struct dnsserver_zone
*, 0);
1250 for (z
= dsstate
->zones
; z
; z
= z
->next
) {
1252 /* Match the flags in groups
1254 * Group1 : PRIMARY, SECONDARY, CACHE, AUTO
1255 * Group2 : FORWARD, REVERSE, FORWARDER, STUB
1256 * Group3 : DS, NON_DS, DOMAIN_DP, FOREST_DP
1257 * Group4 : CUSTOM_DP, LEGACY_DP
1262 if (rin
->Dword
& 0x0000000f) {
1263 if (rin
->Dword
& DNS_ZONE_REQUEST_PRIMARY
) {
1264 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_PRIMARY
) {
1268 if (rin
->Dword
& DNS_ZONE_REQUEST_SECONDARY
) {
1269 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_SECONDARY
) {
1273 if (rin
->Dword
& DNS_ZONE_REQUEST_CACHE
) {
1274 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_CACHE
) {
1278 if (rin
->Dword
& DNS_ZONE_REQUEST_AUTO
) {
1279 if (z
->zoneinfo
->fAutoCreated
1280 || z
->partition
->dwDpFlags
& DNS_DP_AUTOCREATED
) {
1290 if (rin
->Dword
& 0x000000f0) {
1291 if (rin
->Dword
& DNS_ZONE_REQUEST_FORWARD
) {
1292 if (!(z
->zoneinfo
->fReverse
)) {
1296 if (rin
->Dword
& DNS_ZONE_REQUEST_REVERSE
) {
1297 if (z
->zoneinfo
->fReverse
) {
1301 if (rin
->Dword
& DNS_ZONE_REQUEST_FORWARDER
) {
1302 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_FORWARDER
) {
1306 if (rin
->Dword
& DNS_ZONE_REQUEST_STUB
) {
1307 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_STUB
) {
1317 if (rin
->Dword
& 0x00000f00) {
1318 if (rin
->Dword
& DNS_ZONE_REQUEST_DS
) {
1319 if (z
->zoneinfo
->Flags
& DNS_RPC_ZONE_DSINTEGRATED
) {
1323 if (rin
->Dword
& DNS_ZONE_REQUEST_NON_DS
) {
1324 if (!(z
->zoneinfo
->Flags
& DNS_RPC_ZONE_DSINTEGRATED
)) {
1328 if (rin
->Dword
& DNS_ZONE_REQUEST_DOMAIN_DP
) {
1329 if (!(z
->partition
->dwDpFlags
& DNS_DP_DOMAIN_DEFAULT
)) {
1333 if (rin
->Dword
& DNS_ZONE_REQUEST_FOREST_DP
) {
1334 if (!(z
->partition
->dwDpFlags
& DNS_DP_FOREST_DEFAULT
)) {
1343 if (rin
->Dword
& 0x0000f000) {
1349 if (found1
&& found2
&& found3
&& found4
) {
1350 zlist
= talloc_realloc(mem_ctx
, zlist
, struct dnsserver_zone
*, zcount
+1);
1356 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
1357 *typeid_out
= DNSSRV_TYPEID_ZONE_LIST_W2K
;
1358 rout
->ZoneListW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_LIST_W2K
);
1361 rout
->ZoneListW2K
->dwZoneCount
= 0;
1362 rout
->ZoneListW2K
->ZoneArray
= NULL
;
1367 rout
->ZoneListW2K
->ZoneArray
= talloc_zero_array(mem_ctx
, struct DNS_RPC_ZONE_W2K
*, zcount
);
1368 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout
->ZoneListW2K
->ZoneArray
, zlist
);
1370 for (i
=0; i
<zcount
; i
++) {
1371 rout
->ZoneListW2K
->ZoneArray
[i
] = talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_W2K
);
1373 rout
->ZoneListW2K
->ZoneArray
[i
]->pszZoneName
= talloc_strdup(mem_ctx
, zlist
[i
]->name
);
1374 rout
->ZoneListW2K
->ZoneArray
[i
]->Flags
= zlist
[i
]->zoneinfo
->Flags
;
1375 rout
->ZoneListW2K
->ZoneArray
[i
]->ZoneType
= zlist
[i
]->zoneinfo
->dwZoneType
;
1376 rout
->ZoneListW2K
->ZoneArray
[i
]->Version
= zlist
[i
]->zoneinfo
->Version
;
1378 rout
->ZoneListW2K
->dwZoneCount
= zcount
;
1381 *typeid_out
= DNSSRV_TYPEID_ZONE_LIST
;
1382 rout
->ZoneList
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_LIST_DOTNET
);
1385 rout
->ZoneList
->dwRpcStructureVersion
= 1;
1386 rout
->ZoneList
->dwZoneCount
= 0;
1387 rout
->ZoneList
->ZoneArray
= NULL
;
1392 rout
->ZoneList
->ZoneArray
= talloc_zero_array(mem_ctx
, struct DNS_RPC_ZONE_DOTNET
*, zcount
);
1393 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout
->ZoneList
->ZoneArray
, zlist
);
1395 for (i
=0; i
<zcount
; i
++) {
1396 rout
->ZoneList
->ZoneArray
[i
] = talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_DOTNET
);
1398 rout
->ZoneList
->ZoneArray
[i
]->dwRpcStructureVersion
= 1;
1399 rout
->ZoneList
->ZoneArray
[i
]->pszZoneName
= talloc_strdup(mem_ctx
, zlist
[i
]->name
);
1400 rout
->ZoneList
->ZoneArray
[i
]->Flags
= zlist
[i
]->zoneinfo
->Flags
;
1401 rout
->ZoneList
->ZoneArray
[i
]->ZoneType
= zlist
[i
]->zoneinfo
->dwZoneType
;
1402 rout
->ZoneList
->ZoneArray
[i
]->Version
= zlist
[i
]->zoneinfo
->Version
;
1403 rout
->ZoneList
->ZoneArray
[i
]->dwDpFlags
= zlist
[i
]->partition
->dwDpFlags
;
1404 rout
->ZoneList
->ZoneArray
[i
]->pszDpFqdn
= talloc_strdup(mem_ctx
, zlist
[i
]->partition
->pszDpFqdn
);
1406 rout
->ZoneList
->dwRpcStructureVersion
= 1;
1407 rout
->ZoneList
->dwZoneCount
= zcount
;
1411 } else if (strcasecmp(operation
, "EnumZones2") == 0) {
1412 valid_operation
= true;
1413 } else if (strcasecmp(operation
, "EnumDirectoryPartitions") == 0) {
1414 if (typeid_in
!= DNSSRV_TYPEID_DWORD
) {
1415 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1418 *typeid_out
= DNSSRV_TYPEID_DP_LIST
;
1419 rout
->DirectoryPartitionList
= talloc_zero(mem_ctx
, struct DNS_RPC_DP_LIST
);
1421 if (rin
->Dword
!= 0) {
1422 rout
->DirectoryPartitionList
->dwDpCount
= 0;
1423 rout
->DirectoryPartitionList
->DpArray
= NULL
;
1425 struct DNS_RPC_DP_ENUM
**dplist
;
1426 struct dnsserver_partition
*p
;
1429 dplist
= talloc_zero_array(mem_ctx
, struct DNS_RPC_DP_ENUM
*, pcount
);
1430 W_ERROR_HAVE_NO_MEMORY(dplist
);
1432 p
= dsstate
->partitions
;
1433 for (i
=0; i
<pcount
; i
++) {
1434 dplist
[i
] = talloc_zero(dplist
, struct DNS_RPC_DP_ENUM
);
1436 dplist
[i
]->pszDpFqdn
= talloc_strdup(mem_ctx
, p
->pszDpFqdn
);
1437 dplist
[i
]->dwFlags
= p
->dwDpFlags
;
1438 dplist
[i
]->dwZoneCount
= p
->zones_count
;
1442 rout
->DirectoryPartitionList
->dwDpCount
= pcount
;
1443 rout
->DirectoryPartitionList
->DpArray
= dplist
;
1446 } else if (strcasecmp(operation
, "DirectoryPartitionInfo") == 0) {
1447 struct dnsserver_partition
*p
;
1448 struct dnsserver_partition_info
*partinfo
;
1449 struct DNS_RPC_DP_INFO
*dpinfo
= NULL
;
1451 if (typeid_in
!= DNSSRV_TYPEID_LPSTR
) {
1452 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1455 *typeid_out
= DNSSRV_TYPEID_DP_INFO
;
1457 for (p
= dsstate
->partitions
; p
; p
= p
->next
) {
1458 if (strcasecmp(p
->pszDpFqdn
, rin
->String
) == 0) {
1459 dpinfo
= talloc_zero(mem_ctx
, struct DNS_RPC_DP_INFO
);
1460 W_ERROR_HAVE_NO_MEMORY(dpinfo
);
1462 partinfo
= dnsserver_db_partition_info(mem_ctx
, dsstate
->samdb
, p
);
1463 W_ERROR_HAVE_NO_MEMORY(partinfo
);
1465 dpinfo
->pszDpFqdn
= talloc_strdup(dpinfo
, p
->pszDpFqdn
);
1466 dpinfo
->pszDpDn
= talloc_strdup(dpinfo
, ldb_dn_get_linearized(p
->partition_dn
));
1467 dpinfo
->pszCrDn
= talloc_steal(dpinfo
, partinfo
->pszCrDn
);
1468 dpinfo
->dwFlags
= p
->dwDpFlags
;
1469 dpinfo
->dwZoneCount
= p
->zones_count
;
1470 dpinfo
->dwState
= partinfo
->dwState
;
1471 dpinfo
->dwReplicaCount
= partinfo
->dwReplicaCount
;
1472 if (partinfo
->dwReplicaCount
> 0) {
1473 dpinfo
->ReplicaArray
= talloc_steal(dpinfo
,
1474 partinfo
->ReplicaArray
);
1476 dpinfo
->ReplicaArray
= NULL
;
1482 if (dpinfo
== NULL
) {
1483 return WERR_DNS_ERROR_DP_DOES_NOT_EXIST
;
1486 rout
->DirectoryPartition
= dpinfo
;
1488 } else if (strcasecmp(operation
, "Statistics") == 0) {
1489 valid_operation
= true;
1490 } else if (strcasecmp(operation
, "IpValidate") == 0) {
1491 valid_operation
= true;
1494 if (valid_operation
) {
1495 DEBUG(0, ("dnsserver: server complex operation '%s' not implemented", operation
));
1496 return WERR_CALL_NOT_IMPLEMENTED
;
1499 DEBUG(0, ("dnsserver: invalid server complex operation '%s'", operation
));
1500 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1503 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
1504 static WERROR
dnsserver_operate_zone(struct dnsserver_state
*dsstate
,
1505 TALLOC_CTX
*mem_ctx
,
1506 struct dnsserver_zone
*z
,
1507 unsigned int request_filter
,
1508 const char *operation
,
1509 const unsigned int client_version
,
1510 enum DNS_RPC_TYPEID
typeid,
1511 union DNSSRV_RPC_UNION
*r
)
1513 bool valid_operation
= false;
1515 if (strcasecmp(operation
, "ResetDwordProperty") == 0) {
1517 if (typeid != DNSSRV_TYPEID_NAME_AND_PARAM
) {
1518 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1521 return dnsserver_db_do_reset_dword(dsstate
->samdb
, z
,
1524 } else if (strcasecmp(operation
, "ZoneTypeReset") == 0) {
1525 valid_operation
= true;
1526 } else if (strcasecmp(operation
, "PauseZone") == 0) {
1527 valid_operation
= true;
1528 } else if (strcasecmp(operation
, "ResumeZone") == 0) {
1529 valid_operation
= true;
1530 } else if (strcasecmp(operation
, "DeleteZone") == 0) {
1531 valid_operation
= true;
1532 } else if (strcasecmp(operation
, "ReloadZone") == 0) {
1533 valid_operation
= true;
1534 } else if (strcasecmp(operation
, "RefreshZone") == 0) {
1535 valid_operation
= true;
1536 } else if (strcasecmp(operation
, "ExpireZone") == 0) {
1537 valid_operation
= true;
1538 } else if (strcasecmp(operation
, "IncrementVersion") == 0) {
1539 valid_operation
= true;
1540 } else if (strcasecmp(operation
, "WriteBackFile") == 0) {
1541 valid_operation
= true;
1542 } else if (strcasecmp(operation
, "DeleteZoneFromDs") == 0) {
1545 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
1547 status
= dnsserver_db_delete_zone(dsstate
->samdb
, z
);
1548 if (W_ERROR_IS_OK(status
)) {
1549 dnsserver_reload_zones(dsstate
);
1552 } else if (strcasecmp(operation
, "UpdateZoneFromDs") == 0) {
1553 valid_operation
= true;
1554 } else if (strcasecmp(operation
, "ZoneExport") == 0) {
1555 valid_operation
= true;
1556 } else if (strcasecmp(operation
, "ZoneChangeDirectoryPartition") == 0) {
1557 valid_operation
= true;
1558 } else if (strcasecmp(operation
, "DeleteNode") == 0) {
1559 valid_operation
= true;
1560 } else if (strcasecmp(operation
, "DeleteRecordSet") == 0) {
1561 valid_operation
= true;
1562 } else if (strcasecmp(operation
, "ForceAgingOnNode") == 0) {
1563 valid_operation
= true;
1564 } else if (strcasecmp(operation
, "DatabaseFile") == 0) {
1565 valid_operation
= true;
1566 } else if (strcasecmp(operation
, "MasterServers") == 0) {
1567 valid_operation
= true;
1568 } else if (strcasecmp(operation
, "LocalMasterServers") == 0) {
1569 valid_operation
= true;
1570 } else if (strcasecmp(operation
, "NotifyServers") == 0) {
1571 valid_operation
= true;
1572 } else if (strcasecmp(operation
, "SecondaryServers") == 0) {
1573 valid_operation
= true;
1574 } else if (strcasecmp(operation
, "ScavengingServers") == 0) {
1575 valid_operation
= true;
1576 } else if (strcasecmp(operation
, "AllowNSRecordsAutoCreation") == 0) {
1577 valid_operation
= true;
1578 } else if (strcasecmp(operation
, "BreakOnNameUpdate") == 0) {
1579 valid_operation
= true;
1580 } else if (strcasecmp(operation
, "ApplicationDirectoryPartition") == 0) {
1581 valid_operation
= true;
1584 if (valid_operation
) {
1585 DEBUG(0, ("dnsserver: zone operation '%s' not implemented", operation
));
1586 return WERR_CALL_NOT_IMPLEMENTED
;
1589 DEBUG(0, ("dnsserver: invalid zone operation '%s'", operation
));
1590 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1593 static WERROR
dnsserver_complex_operate_zone(struct dnsserver_state
*dsstate
,
1594 TALLOC_CTX
*mem_ctx
,
1595 struct dnsserver_zone
*z
,
1596 const char *operation
,
1597 const unsigned int client_version
,
1598 enum DNS_RPC_TYPEID typeid_in
,
1599 union DNSSRV_RPC_UNION
*rin
,
1600 enum DNS_RPC_TYPEID
*typeid_out
,
1601 union DNSSRV_RPC_UNION
*rout
)
1603 if (strcasecmp(operation
, "QueryDwordProperty") == 0) {
1604 if (typeid_in
== DNSSRV_TYPEID_LPSTR
) {
1605 return dnsserver_query_zone(dsstate
, mem_ctx
, z
,
1614 DEBUG(0,("dnsserver: Invalid zone operation %s", operation
));
1615 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1618 /* dnsserver enumerate function */
1620 static WERROR
dnsserver_enumerate_root_records(struct dnsserver_state
*dsstate
,
1621 TALLOC_CTX
*mem_ctx
,
1622 unsigned int client_version
,
1623 const char *node_name
,
1624 enum dns_record_type record_type
,
1625 unsigned int select_flag
,
1626 unsigned int *buffer_length
,
1627 struct DNS_RPC_RECORDS_ARRAY
**buffer
)
1629 TALLOC_CTX
*tmp_ctx
;
1630 struct dnsserver_zone
*z
;
1631 const char * const attrs
[] = { "name", "dnsRecord", NULL
};
1632 struct ldb_result
*res
;
1633 struct DNS_RPC_RECORDS_ARRAY
*recs
;
1640 tmp_ctx
= talloc_new(mem_ctx
);
1641 W_ERROR_HAVE_NO_MEMORY(tmp_ctx
);
1643 z
= dnsserver_find_zone(dsstate
->zones
, ".");
1645 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
1648 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1649 LDB_SCOPE_ONELEVEL
, attrs
,
1650 "(&(objectClass=dnsNode)(name=@)(!(dNSTombstoned=TRUE)))");
1651 if (ret
!= LDB_SUCCESS
) {
1652 talloc_free(tmp_ctx
);
1653 return WERR_INTERNAL_DB_ERROR
;
1655 if (res
->count
== 0) {
1656 talloc_free(tmp_ctx
);
1657 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
1660 recs
= talloc_zero(mem_ctx
, struct DNS_RPC_RECORDS_ARRAY
);
1661 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs
, tmp_ctx
);
1666 for (i
=0; i
<res
->count
; i
++) {
1667 status
= dns_fill_records_array(tmp_ctx
, NULL
, record_type
,
1669 res
->msgs
[i
], 0, recs
,
1670 &add_names
, &add_count
);
1671 if (!W_ERROR_IS_OK(status
)) {
1672 talloc_free(tmp_ctx
);
1678 /* Add any additional records */
1679 if (select_flag
& DNS_RPC_VIEW_ADDITIONAL_DATA
) {
1680 for (i
=0; i
<add_count
; i
++) {
1682 = ldb_binary_encode_string(tmp_ctx
,
1684 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1685 LDB_SCOPE_ONELEVEL
, attrs
,
1686 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1688 if (ret
!= LDB_SUCCESS
|| res
->count
== 0) {
1693 len
= strlen(add_names
[i
]);
1694 if (add_names
[i
][len
-1] == '.') {
1695 rname
= talloc_strdup(tmp_ctx
, add_names
[i
]);
1697 rname
= talloc_asprintf(tmp_ctx
, "%s.", add_names
[i
]);
1699 status
= dns_fill_records_array(tmp_ctx
, NULL
, DNS_TYPE_A
,
1701 res
->msgs
[0], 0, recs
,
1708 talloc_free(tmp_ctx
);
1710 *buffer_length
= ndr_size_DNS_RPC_RECORDS_ARRAY(recs
, 0);
1717 static WERROR
dnsserver_enumerate_records(struct dnsserver_state
*dsstate
,
1718 TALLOC_CTX
*mem_ctx
,
1719 struct dnsserver_zone
*z
,
1720 unsigned int client_version
,
1721 const char *node_name
,
1722 const char *start_child
,
1723 enum dns_record_type record_type
,
1724 unsigned int select_flag
,
1725 const char *filter_start
,
1726 const char *filter_stop
,
1727 unsigned int *buffer_length
,
1728 struct DNS_RPC_RECORDS_ARRAY
**buffer
)
1730 TALLOC_CTX
*tmp_ctx
;
1732 const char * const attrs
[] = { "name", "dnsRecord", NULL
};
1733 struct ldb_result
*res
;
1734 struct DNS_RPC_RECORDS_ARRAY
*recs
;
1735 char **add_names
= NULL
;
1740 struct dns_tree
*tree
, *base
, *node
;
1742 tmp_ctx
= talloc_new(mem_ctx
);
1743 W_ERROR_HAVE_NO_MEMORY(tmp_ctx
);
1745 name
= dns_split_node_name(tmp_ctx
, node_name
, z
->name
);
1746 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name
, tmp_ctx
);
1748 /* search all records under parent tree */
1749 if (strcasecmp(name
, z
->name
) == 0) {
1750 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1751 LDB_SCOPE_ONELEVEL
, attrs
,
1752 "(&(objectClass=dnsNode)(!(dNSTombstoned=TRUE)))");
1755 = ldb_binary_encode_string(tmp_ctx
, name
);
1756 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1757 LDB_SCOPE_ONELEVEL
, attrs
,
1758 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s))(!(dNSTombstoned=TRUE)))",
1759 encoded_name
, encoded_name
);
1761 if (ret
!= LDB_SUCCESS
) {
1762 talloc_free(tmp_ctx
);
1763 return WERR_INTERNAL_DB_ERROR
;
1765 if (res
->count
== 0) {
1766 talloc_free(tmp_ctx
);
1767 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
1770 recs
= talloc_zero(mem_ctx
, struct DNS_RPC_RECORDS_ARRAY
);
1771 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs
, tmp_ctx
);
1773 /* Sort the names, so that the first record is the parent record */
1774 ldb_qsort(res
->msgs
, res
->count
, sizeof(struct ldb_message
*), name
,
1775 (ldb_qsort_cmp_fn_t
)dns_name_compare
);
1777 /* Build a tree of name components from dns name */
1778 if (strcasecmp(name
, z
->name
) == 0) {
1779 tree
= dns_build_tree(tmp_ctx
, "@", res
);
1781 tree
= dns_build_tree(tmp_ctx
, name
, res
);
1783 W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree
, tmp_ctx
);
1785 /* Find the parent record in the tree */
1787 while (base
->level
!= -1) {
1788 base
= base
->children
[0];
1791 /* Add the parent record with blank name */
1792 if (!(select_flag
& DNS_RPC_VIEW_ONLY_CHILDREN
)) {
1793 status
= dns_fill_records_array(tmp_ctx
, z
, record_type
,
1796 recs
, &add_names
, &add_count
);
1797 if (!W_ERROR_IS_OK(status
)) {
1798 talloc_free(tmp_ctx
);
1803 /* Add all the children records */
1804 if (!(select_flag
& DNS_RPC_VIEW_NO_CHILDREN
)) {
1805 for (i
=0; i
<base
->num_children
; i
++) {
1806 node
= base
->children
[i
];
1808 status
= dns_fill_records_array(tmp_ctx
, z
, record_type
,
1809 select_flag
, node
->name
,
1810 node
->data
, node
->num_children
,
1811 recs
, &add_names
, &add_count
);
1812 if (!W_ERROR_IS_OK(status
)) {
1813 talloc_free(tmp_ctx
);
1823 /* Add any additional records */
1824 if (select_flag
& DNS_RPC_VIEW_ADDITIONAL_DATA
) {
1825 for (i
=0; i
<add_count
; i
++) {
1826 struct dnsserver_zone
*z2
;
1828 /* Search all the available zones for additional name */
1829 for (z2
= dsstate
->zones
; z2
; z2
= z2
->next
) {
1831 name
= dns_split_node_name(tmp_ctx
, add_names
[i
], z2
->name
);
1833 = ldb_binary_encode_string(tmp_ctx
,
1835 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z2
->zone_dn
,
1836 LDB_SCOPE_ONELEVEL
, attrs
,
1837 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1840 if (ret
!= LDB_SUCCESS
) {
1843 if (res
->count
== 1) {
1851 len
= strlen(add_names
[i
]);
1852 if (add_names
[i
][len
-1] == '.') {
1853 rname
= talloc_strdup(tmp_ctx
, add_names
[i
]);
1855 rname
= talloc_asprintf(tmp_ctx
, "%s.", add_names
[i
]);
1857 status
= dns_fill_records_array(tmp_ctx
, NULL
, DNS_TYPE_A
,
1859 res
->msgs
[0], 0, recs
,
1866 *buffer_length
= ndr_size_DNS_RPC_RECORDS_ARRAY(recs
, 0);
1873 * Check str1 + '.' + str2 = name, for example:
1874 * ("dc0", "example.com", "dc0.example.com") = true
1876 static bool cname_self_reference(const char* node_name
,
1877 const char* zone_name
,
1878 struct DNS_RPC_NAME name
) {
1879 size_t node_len
, zone_len
;
1881 if (node_name
== NULL
|| zone_name
== NULL
) {
1885 node_len
= strlen(node_name
);
1886 zone_len
= strlen(zone_name
);
1888 if (node_len
== 0 ||
1890 (name
.len
!= node_len
+ zone_len
+ 1)) {
1894 if (strncmp(node_name
, name
.str
, node_len
) == 0 &&
1895 name
.str
[node_len
] == '.' &&
1896 strncmp(zone_name
, name
.str
+ node_len
+ 1, zone_len
) == 0) {
1903 /* dnsserver update function */
1905 static WERROR
dnsserver_update_record(struct dnsserver_state
*dsstate
,
1906 TALLOC_CTX
*mem_ctx
,
1907 struct dnsserver_zone
*z
,
1908 unsigned int client_version
,
1909 const char *node_name
,
1910 struct DNS_RPC_RECORD_BUF
*add_buf
,
1911 struct DNS_RPC_RECORD_BUF
*del_buf
)
1913 TALLOC_CTX
*tmp_ctx
;
1917 tmp_ctx
= talloc_new(mem_ctx
);
1918 W_ERROR_HAVE_NO_MEMORY(tmp_ctx
);
1920 /* If node_name is @ or zone name, dns record is @ */
1921 if (strcmp(node_name
, "@") == 0 ||
1922 strcmp(node_name
, ".") == 0 ||
1923 strcasecmp(node_name
, z
->name
) == 0) {
1924 name
= talloc_strdup(tmp_ctx
, "@");
1926 name
= dns_split_node_name(tmp_ctx
, node_name
, z
->name
);
1928 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name
, tmp_ctx
);
1930 /* CNAMEs can't point to themselves */
1931 if (add_buf
!= NULL
&& add_buf
->rec
.wType
== DNS_TYPE_CNAME
) {
1932 if (cname_self_reference(node_name
, z
->name
, add_buf
->rec
.data
.name
)) {
1933 return WERR_DNS_ERROR_CNAME_LOOP
;
1937 if (add_buf
!= NULL
) {
1938 if (del_buf
== NULL
) {
1940 status
= dnsserver_db_add_record(tmp_ctx
, dsstate
->samdb
,
1945 status
= dnsserver_db_update_record(tmp_ctx
, dsstate
->samdb
,
1951 if (del_buf
== NULL
) {
1952 /* Add empty node */
1953 status
= dnsserver_db_add_empty_node(tmp_ctx
, dsstate
->samdb
,
1957 status
= dnsserver_db_delete_record(tmp_ctx
, dsstate
->samdb
,
1963 talloc_free(tmp_ctx
);
1968 /* dnsserver interface functions */
1970 static WERROR
dcesrv_DnssrvOperation(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvOperation
*r
)
1972 struct dnsserver_state
*dsstate
;
1973 struct dnsserver_zone
*z
= NULL
;
1974 uint32_t request_filter
= 0;
1977 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
1978 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
1981 if (r
->in
.dwContext
== 0) {
1982 if (r
->in
.pszZone
!= NULL
) {
1983 request_filter
= dnsserver_zone_to_request_filter(r
->in
.pszZone
);
1986 request_filter
= r
->in
.dwContext
;
1989 if (r
->in
.pszZone
== NULL
) {
1990 ret
= dnsserver_operate_server(dsstate
, mem_ctx
,
1992 DNS_CLIENT_VERSION_W2K
,
1996 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
1997 if (z
== NULL
&& request_filter
== 0) {
1998 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2001 ret
= dnsserver_operate_zone(dsstate
, mem_ctx
, z
,
2004 DNS_CLIENT_VERSION_W2K
,
2009 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2010 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation
, NDR_IN
, r
);
2015 static WERROR
dcesrv_DnssrvQuery(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvQuery
*r
)
2017 struct dnsserver_state
*dsstate
;
2018 struct dnsserver_zone
*z
;
2021 ZERO_STRUCTP(r
->out
.pdwTypeId
);
2022 ZERO_STRUCTP(r
->out
.ppData
);
2024 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2025 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2028 if (r
->in
.pszZone
== NULL
) {
2029 /* FIXME: DNS Server Configuration Access Control List */
2030 ret
= dnsserver_query_server(dsstate
, mem_ctx
,
2032 DNS_CLIENT_VERSION_W2K
,
2036 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2038 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2041 ret
= dnsserver_query_zone(dsstate
, mem_ctx
, z
,
2043 DNS_CLIENT_VERSION_W2K
,
2048 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2049 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery
, NDR_IN
, r
);
2054 static WERROR
dcesrv_DnssrvComplexOperation(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvComplexOperation
*r
)
2056 struct dnsserver_state
*dsstate
;
2057 struct dnsserver_zone
*z
;
2060 ZERO_STRUCTP(r
->out
.pdwTypeOut
);
2061 ZERO_STRUCTP(r
->out
.ppDataOut
);
2063 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2064 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2067 if (r
->in
.pszZone
== NULL
) {
2068 /* Server operation */
2069 ret
= dnsserver_complex_operate_server(dsstate
, mem_ctx
,
2071 DNS_CLIENT_VERSION_W2K
,
2077 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2079 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2082 ret
= dnsserver_complex_operate_zone(dsstate
, mem_ctx
, z
,
2084 DNS_CLIENT_VERSION_W2K
,
2091 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2092 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation
, NDR_IN
, r
);
2097 static WERROR
dcesrv_DnssrvEnumRecords(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvEnumRecords
*r
)
2099 struct dnsserver_state
*dsstate
;
2100 struct dnsserver_zone
*z
;
2103 ZERO_STRUCTP(r
->out
.pdwBufferLength
);
2104 ZERO_STRUCTP(r
->out
.pBuffer
);
2106 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2107 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2110 if (r
->in
.pszZone
== NULL
) {
2111 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2114 if (strcasecmp(r
->in
.pszZone
, "..RootHints") == 0) {
2115 ret
= dnsserver_enumerate_root_records(dsstate
, mem_ctx
,
2116 DNS_CLIENT_VERSION_W2K
,
2120 r
->out
.pdwBufferLength
,
2123 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2125 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2128 ret
= dnsserver_enumerate_records(dsstate
, mem_ctx
, z
,
2129 DNS_CLIENT_VERSION_W2K
,
2131 r
->in
.pszStartChild
,
2134 r
->in
.pszFilterStart
,
2135 r
->in
.pszFilterStop
,
2136 r
->out
.pdwBufferLength
,
2140 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2141 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords
, NDR_IN
, r
);
2146 static WERROR
dcesrv_DnssrvUpdateRecord(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvUpdateRecord
*r
)
2148 struct dnsserver_state
*dsstate
;
2149 struct dnsserver_zone
*z
;
2152 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2153 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2156 if (r
->in
.pszZone
== NULL
) {
2157 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2160 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2162 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2165 ret
= dnsserver_update_record(dsstate
, mem_ctx
, z
,
2166 DNS_CLIENT_VERSION_W2K
,
2169 r
->in
.pDeleteRecord
);
2171 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2172 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord
, NDR_IN
, r
);
2177 static WERROR
dcesrv_DnssrvOperation2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvOperation2
*r
)
2179 struct dnsserver_state
*dsstate
;
2180 struct dnsserver_zone
*z
= NULL
;
2181 uint32_t request_filter
= 0;
2184 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2185 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2188 if (r
->in
.dwContext
== 0) {
2189 if (r
->in
.pszZone
!= NULL
) {
2190 request_filter
= dnsserver_zone_to_request_filter(r
->in
.pszZone
);
2193 request_filter
= r
->in
.dwContext
;
2196 if (r
->in
.pszZone
== NULL
) {
2197 ret
= dnsserver_operate_server(dsstate
, mem_ctx
,
2199 r
->in
.dwClientVersion
,
2203 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2204 if (z
== NULL
&& request_filter
== 0) {
2205 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2208 ret
= dnsserver_operate_zone(dsstate
, mem_ctx
, z
,
2211 r
->in
.dwClientVersion
,
2216 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2217 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation2
, NDR_IN
, r
);
2222 static WERROR
dcesrv_DnssrvQuery2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvQuery2
*r
)
2224 struct dnsserver_state
*dsstate
;
2225 struct dnsserver_zone
*z
;
2228 ZERO_STRUCTP(r
->out
.pdwTypeId
);
2229 ZERO_STRUCTP(r
->out
.ppData
);
2231 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2232 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2235 if (r
->in
.pszZone
== NULL
) {
2236 /* FIXME: DNS Server Configuration Access Control List */
2237 ret
= dnsserver_query_server(dsstate
, mem_ctx
,
2239 r
->in
.dwClientVersion
,
2243 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2245 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2248 ret
= dnsserver_query_zone(dsstate
, mem_ctx
, z
,
2250 r
->in
.dwClientVersion
,
2255 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2256 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery2
, NDR_IN
, r
);
2261 static WERROR
dcesrv_DnssrvComplexOperation2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvComplexOperation2
*r
)
2263 struct dnsserver_state
*dsstate
;
2264 struct dnsserver_zone
*z
;
2267 ZERO_STRUCTP(r
->out
.pdwTypeOut
);
2268 ZERO_STRUCTP(r
->out
.ppDataOut
);
2270 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2271 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2274 if (r
->in
.pszZone
== NULL
) {
2275 /* Server operation */
2276 ret
= dnsserver_complex_operate_server(dsstate
, mem_ctx
,
2278 r
->in
.dwClientVersion
,
2285 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2287 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2290 ret
= dnsserver_complex_operate_zone(dsstate
, mem_ctx
, z
,
2292 r
->in
.dwClientVersion
,
2299 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2300 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation2
, NDR_IN
, r
);
2305 static WERROR
dcesrv_DnssrvEnumRecords2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvEnumRecords2
*r
)
2307 struct dnsserver_state
*dsstate
;
2308 struct dnsserver_zone
*z
;
2311 ZERO_STRUCTP(r
->out
.pdwBufferLength
);
2312 ZERO_STRUCTP(r
->out
.pBuffer
);
2314 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2315 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2318 if (r
->in
.pszZone
== NULL
) {
2319 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2322 if (strcasecmp(r
->in
.pszZone
, "..RootHints") == 0) {
2323 ret
= dnsserver_enumerate_root_records(dsstate
, mem_ctx
,
2324 r
->in
.dwClientVersion
,
2328 r
->out
.pdwBufferLength
,
2331 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2333 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2336 ret
= dnsserver_enumerate_records(dsstate
, mem_ctx
, z
,
2337 r
->in
.dwClientVersion
,
2339 r
->in
.pszStartChild
,
2342 r
->in
.pszFilterStart
,
2343 r
->in
.pszFilterStop
,
2344 r
->out
.pdwBufferLength
,
2349 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2350 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords2
, NDR_IN
, r
);
2355 static WERROR
dcesrv_DnssrvUpdateRecord2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvUpdateRecord2
*r
)
2357 struct dnsserver_state
*dsstate
;
2358 struct dnsserver_zone
*z
;
2361 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2362 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2365 if (r
->in
.pszZone
== NULL
) {
2366 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2369 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2371 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2374 ret
= dnsserver_update_record(dsstate
, mem_ctx
, z
,
2375 r
->in
.dwClientVersion
,
2378 r
->in
.pDeleteRecord
);
2380 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2381 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord2
, NDR_IN
, r
);
2386 /* include the generated boilerplate */
2387 #include "librpc/gen_ndr/ndr_dnsserver_s.c"