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 "dnsserver.h"
29 #include "lib/ldb/include/ldb_private.h"
31 struct dnsserver_state
{
32 struct loadparm_context
*lp_ctx
;
33 struct ldb_context
*samdb
;
34 struct dnsserver_partition
*partitions
;
35 struct dnsserver_zone
*zones
;
37 struct dnsserver_serverinfo
*serverinfo
;
41 /* Utility functions */
43 static void dnsserver_reload_zones(struct dnsserver_state
*dsstate
)
45 struct dnsserver_partition
*p
;
46 struct dnsserver_zone
*zones
, *z
, *znext
, *zmatch
;
47 struct dnsserver_zone
*old_list
, *new_list
;
49 old_list
= dsstate
->zones
;
52 for (p
= dsstate
->partitions
; p
; p
= p
->next
) {
53 zones
= dnsserver_db_enumerate_zones(dsstate
, dsstate
->samdb
, p
);
57 for (z
= zones
; z
; ) {
59 zmatch
= dnsserver_find_zone(old_list
, z
->name
);
62 z
->zoneinfo
= dnsserver_init_zoneinfo(z
, dsstate
->serverinfo
);
63 if (z
->zoneinfo
== NULL
) {
66 DLIST_ADD_END(new_list
, z
, NULL
);
68 dsstate
->zones_count
++;
72 DLIST_REMOVE(old_list
, zmatch
);
73 DLIST_ADD_END(new_list
, zmatch
, NULL
);
79 if (new_list
== NULL
) {
84 for (z
= old_list
; z
; ) {
86 z
->partition
->zones_count
--;
87 dsstate
->zones_count
--;
92 dsstate
->zones
= new_list
;
96 static struct dnsserver_state
*dnsserver_connect(struct dcesrv_call_state
*dce_call
)
98 struct dnsserver_state
*dsstate
;
99 struct dnsserver_zone
*zones
, *z
, *znext
;
100 struct dnsserver_partition
*partitions
, *p
;
102 dsstate
= talloc_get_type(dce_call
->context
->private_data
, struct dnsserver_state
);
103 if (dsstate
!= NULL
) {
107 dsstate
= talloc_zero(dce_call
->context
, struct dnsserver_state
);
108 if (dsstate
== NULL
) {
112 dsstate
->lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
114 /* FIXME: create correct auth_session_info for connecting user */
115 dsstate
->samdb
= samdb_connect(dsstate
, dce_call
->event_ctx
, dsstate
->lp_ctx
,
116 dce_call
->conn
->auth_state
.session_info
, 0);
117 if (dsstate
->samdb
== NULL
) {
118 DEBUG(0,("dnsserver: Failed to open samdb"));
122 /* Initialize server info */
123 dsstate
->serverinfo
= dnsserver_init_serverinfo(dsstate
,
126 if (dsstate
->serverinfo
== NULL
) {
130 /* Search for DNS partitions */
131 partitions
= dnsserver_db_enumerate_partitions(dsstate
, dsstate
->serverinfo
, dsstate
->samdb
);
132 if (partitions
== NULL
) {
135 dsstate
->partitions
= partitions
;
137 /* Search for DNS zones */
138 for (p
= partitions
; p
; p
= p
->next
) {
139 zones
= dnsserver_db_enumerate_zones(dsstate
, dsstate
->samdb
, p
);
143 for (z
= zones
; z
; ) {
145 if (dnsserver_find_zone(dsstate
->zones
, z
->name
) == NULL
) {
146 z
->zoneinfo
= dnsserver_init_zoneinfo(z
, dsstate
->serverinfo
);
147 if (z
->zoneinfo
== NULL
) {
150 DLIST_ADD_END(dsstate
->zones
, z
, NULL
);
152 dsstate
->zones_count
++;
154 /* Ignore duplicate zone */
155 DEBUG(3,("dnsserver: Ignoring duplicate zone '%s' from '%s'",
156 z
->name
, ldb_dn_get_linearized(z
->zone_dn
)));
162 dce_call
->context
->private_data
= dsstate
;
167 talloc_free(dsstate
);
173 /* dnsserver query functions */
175 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
176 static WERROR
dnsserver_query_server(struct dnsserver_state
*dsstate
,
178 const char *operation
,
179 const unsigned int client_version
,
180 enum DNS_RPC_TYPEID
*typeid,
181 union DNSSRV_RPC_UNION
*r
)
183 uint8_t is_integer
, is_addresses
, is_string
, is_wstring
, is_stringlist
;
184 uint32_t answer_integer
;
185 struct IP4_ARRAY
*answer_iparray
;
186 struct DNS_ADDR_ARRAY
*answer_addrarray
;
188 struct DNS_RPC_UTF8_STRING_LIST
*answer_stringlist
;
189 struct dnsserver_serverinfo
*serverinfo
;
191 serverinfo
= dsstate
->serverinfo
;
193 if (strcasecmp(operation
, "ServerInfo") == 0) {
194 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
195 *typeid = DNSSRV_TYPEID_SERVER_INFO_W2K
;
196 r
->ServerInfoW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_SERVER_INFO_W2K
);
198 r
->ServerInfoW2K
->dwVersion
= serverinfo
->dwVersion
;
199 r
->ServerInfoW2K
->fBootMethod
= serverinfo
->fBootMethod
;
200 r
->ServerInfoW2K
->fAdminConfigured
= serverinfo
->fAdminConfigured
;
201 r
->ServerInfoW2K
->fAllowUpdate
= serverinfo
->fAllowUpdate
;
202 r
->ServerInfoW2K
->fDsAvailable
= serverinfo
->fDsAvailable
;
203 r
->ServerInfoW2K
->pszServerName
= talloc_strdup(mem_ctx
, serverinfo
->pszServerName
);
204 r
->ServerInfoW2K
->pszDsContainer
= talloc_strdup(mem_ctx
, serverinfo
->pszDsContainer
);
205 r
->ServerInfoW2K
->aipServerAddrs
= dns_addr_array_to_ip4_array(mem_ctx
,
206 serverinfo
->aipServerAddrs
);
207 r
->ServerInfoW2K
->aipListenAddrs
= dns_addr_array_to_ip4_array(mem_ctx
,
208 serverinfo
->aipListenAddrs
);
209 r
->ServerInfoW2K
->aipForwarders
= ip4_array_copy(mem_ctx
, serverinfo
->aipForwarders
);
210 r
->ServerInfoW2K
->dwLogLevel
= serverinfo
->dwLogLevel
;
211 r
->ServerInfoW2K
->dwDebugLevel
= serverinfo
->dwDebugLevel
;
212 r
->ServerInfoW2K
->dwForwardTimeout
= serverinfo
->dwForwardTimeout
;
213 r
->ServerInfoW2K
->dwRpcProtocol
= serverinfo
->dwRpcProtocol
;
214 r
->ServerInfoW2K
->dwNameCheckFlag
= serverinfo
->dwNameCheckFlag
;
215 r
->ServerInfoW2K
->cAddressAnswerLimit
= serverinfo
->cAddressAnswerLimit
;
216 r
->ServerInfoW2K
->dwRecursionRetry
= serverinfo
->dwRecursionRetry
;
217 r
->ServerInfoW2K
->dwRecursionTimeout
= serverinfo
->dwRecursionTimeout
;
218 r
->ServerInfoW2K
->dwMaxCacheTtl
= serverinfo
->dwMaxCacheTtl
;
219 r
->ServerInfoW2K
->dwDsPollingInterval
= serverinfo
->dwDsPollingInterval
;
220 r
->ServerInfoW2K
->dwScavengingInterval
= serverinfo
->dwScavengingInterval
;
221 r
->ServerInfoW2K
->dwDefaultRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
222 r
->ServerInfoW2K
->dwDefaultNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
223 r
->ServerInfoW2K
->fAutoReverseZones
= serverinfo
->fAutoReverseZones
;
224 r
->ServerInfoW2K
->fAutoCacheUpdate
= serverinfo
->fAutoCacheUpdate
;
225 r
->ServerInfoW2K
->fRecurseAfterForwarding
= serverinfo
->fRecurseAfterForwarding
;
226 r
->ServerInfoW2K
->fForwardDelegations
= serverinfo
->fForwardDelegations
;
227 r
->ServerInfoW2K
->fNoRecursion
= serverinfo
->fNoRecursion
;
228 r
->ServerInfoW2K
->fSecureResponses
= serverinfo
->fSecureResponses
;
229 r
->ServerInfoW2K
->fRoundRobin
= serverinfo
->fRoundRobin
;
230 r
->ServerInfoW2K
->fLocalNetPriority
= serverinfo
->fLocalNetPriority
;
231 r
->ServerInfoW2K
->fBindSecondaries
= serverinfo
->fBindSecondaries
;
232 r
->ServerInfoW2K
->fWriteAuthorityNs
= serverinfo
->fWriteAuthorityNs
;
233 r
->ServerInfoW2K
->fStrictFileParsing
= serverinfo
->fStrictFileParsing
;
234 r
->ServerInfoW2K
->fLooseWildcarding
= serverinfo
->fLooseWildcarding
;
235 r
->ServerInfoW2K
->fDefaultAgingState
= serverinfo
->fDefaultAgingState
;
237 } else if (client_version
== DNS_CLIENT_VERSION_DOTNET
) {
238 *typeid = DNSSRV_TYPEID_SERVER_INFO_DOTNET
;
239 r
->ServerInfoDotNet
= talloc_zero(mem_ctx
, struct DNS_RPC_SERVER_INFO_DOTNET
);
241 r
->ServerInfoDotNet
->dwRpcStructureVersion
= 0x01;
242 r
->ServerInfoDotNet
->dwVersion
= serverinfo
->dwVersion
;
243 r
->ServerInfoDotNet
->fBootMethod
= serverinfo
->fBootMethod
;
244 r
->ServerInfoDotNet
->fAdminConfigured
= serverinfo
->fAdminConfigured
;
245 r
->ServerInfoDotNet
->fAllowUpdate
= serverinfo
->fAllowUpdate
;
246 r
->ServerInfoDotNet
->fDsAvailable
= serverinfo
->fDsAvailable
;
247 r
->ServerInfoDotNet
->pszServerName
= talloc_strdup(mem_ctx
, serverinfo
->pszServerName
);
248 r
->ServerInfoDotNet
->pszDsContainer
= talloc_strdup(mem_ctx
, serverinfo
->pszDsContainer
);
249 r
->ServerInfoDotNet
->aipServerAddrs
= dns_addr_array_to_ip4_array(mem_ctx
,
250 serverinfo
->aipServerAddrs
);
251 r
->ServerInfoDotNet
->aipListenAddrs
= dns_addr_array_to_ip4_array(mem_ctx
,
252 serverinfo
->aipListenAddrs
);
253 r
->ServerInfoDotNet
->aipForwarders
= ip4_array_copy(mem_ctx
, serverinfo
->aipForwarders
);
254 r
->ServerInfoDotNet
->aipLogFilter
= ip4_array_copy(mem_ctx
, serverinfo
->aipLogFilter
);
255 r
->ServerInfoDotNet
->pwszLogFilePath
= talloc_strdup(mem_ctx
, serverinfo
->pwszLogFilePath
);
256 r
->ServerInfoDotNet
->pszDomainName
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainName
);
257 r
->ServerInfoDotNet
->pszForestName
= talloc_strdup(mem_ctx
, serverinfo
->pszForestName
);
258 r
->ServerInfoDotNet
->pszDomainDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainDirectoryPartition
);
259 r
->ServerInfoDotNet
->pszForestDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszForestDirectoryPartition
);
260 r
->ServerInfoDotNet
->dwLogLevel
= serverinfo
->dwLogLevel
;
261 r
->ServerInfoDotNet
->dwDebugLevel
= serverinfo
->dwDebugLevel
;
262 r
->ServerInfoDotNet
->dwForwardTimeout
= serverinfo
->dwForwardTimeout
;
263 r
->ServerInfoDotNet
->dwRpcProtocol
= serverinfo
->dwRpcProtocol
;
264 r
->ServerInfoDotNet
->dwNameCheckFlag
= serverinfo
->dwNameCheckFlag
;
265 r
->ServerInfoDotNet
->cAddressAnswerLimit
= serverinfo
->cAddressAnswerLimit
;
266 r
->ServerInfoDotNet
->dwRecursionRetry
= serverinfo
->dwRecursionRetry
;
267 r
->ServerInfoDotNet
->dwRecursionTimeout
= serverinfo
->dwRecursionTimeout
;
268 r
->ServerInfoDotNet
->dwMaxCacheTtl
= serverinfo
->dwMaxCacheTtl
;
269 r
->ServerInfoDotNet
->dwDsPollingInterval
= serverinfo
->dwDsPollingInterval
;
270 r
->ServerInfoDotNet
->dwLocalNetPriorityNetMask
= serverinfo
->dwLocalNetPriorityNetMask
;
271 r
->ServerInfoDotNet
->dwScavengingInterval
= serverinfo
->dwScavengingInterval
;
272 r
->ServerInfoDotNet
->dwDefaultRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
273 r
->ServerInfoDotNet
->dwDefaultNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
274 r
->ServerInfoDotNet
->dwLastScavengeTime
= serverinfo
->dwLastScavengeTime
;
275 r
->ServerInfoDotNet
->dwEventLogLevel
= serverinfo
->dwEventLogLevel
;
276 r
->ServerInfoDotNet
->dwLogFileMaxSize
= serverinfo
->dwLogFileMaxSize
;
277 r
->ServerInfoDotNet
->dwDsForestVersion
= serverinfo
->dwDsForestVersion
;
278 r
->ServerInfoDotNet
->dwDsDomainVersion
= serverinfo
->dwDsDomainVersion
;
279 r
->ServerInfoDotNet
->dwDsDsaVersion
= serverinfo
->dwDsDsaVersion
;
280 r
->ServerInfoDotNet
->fAutoReverseZones
= serverinfo
->fAutoReverseZones
;
281 r
->ServerInfoDotNet
->fAutoCacheUpdate
= serverinfo
->fAutoCacheUpdate
;
282 r
->ServerInfoDotNet
->fRecurseAfterForwarding
= serverinfo
->fRecurseAfterForwarding
;
283 r
->ServerInfoDotNet
->fForwardDelegations
= serverinfo
->fForwardDelegations
;
284 r
->ServerInfoDotNet
->fNoRecursion
= serverinfo
->fNoRecursion
;
285 r
->ServerInfoDotNet
->fSecureResponses
= serverinfo
->fSecureResponses
;
286 r
->ServerInfoDotNet
->fRoundRobin
= serverinfo
->fRoundRobin
;
287 r
->ServerInfoDotNet
->fLocalNetPriority
= serverinfo
->fLocalNetPriority
;
288 r
->ServerInfoDotNet
->fBindSecondaries
= serverinfo
->fBindSecondaries
;
289 r
->ServerInfoDotNet
->fWriteAuthorityNs
= serverinfo
->fWriteAuthorityNs
;
290 r
->ServerInfoDotNet
->fStrictFileParsing
= serverinfo
->fStrictFileParsing
;
291 r
->ServerInfoDotNet
->fLooseWildcarding
= serverinfo
->fLooseWildcarding
;
292 r
->ServerInfoDotNet
->fDefaultAgingState
= serverinfo
->fDefaultAgingState
;
294 } else if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
295 *typeid = DNSSRV_TYPEID_SERVER_INFO
;
296 r
->ServerInfo
= talloc_zero(mem_ctx
, struct DNS_RPC_SERVER_INFO_LONGHORN
);
298 r
->ServerInfo
->dwRpcStructureVersion
= 0x02;
299 r
->ServerInfo
->dwVersion
= serverinfo
->dwVersion
;
300 r
->ServerInfo
->fBootMethod
= serverinfo
->fBootMethod
;
301 r
->ServerInfo
->fAdminConfigured
= serverinfo
->fAdminConfigured
;
302 r
->ServerInfo
->fAllowUpdate
= serverinfo
->fAllowUpdate
;
303 r
->ServerInfo
->fDsAvailable
= serverinfo
->fDsAvailable
;
304 r
->ServerInfo
->pszServerName
= talloc_strdup(mem_ctx
, serverinfo
->pszServerName
);
305 r
->ServerInfo
->pszDsContainer
= talloc_strdup(mem_ctx
, serverinfo
->pszDsContainer
);
306 r
->ServerInfo
->aipServerAddrs
= serverinfo
->aipServerAddrs
;
307 r
->ServerInfo
->aipListenAddrs
= serverinfo
->aipListenAddrs
;
308 r
->ServerInfo
->aipForwarders
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipForwarders
);
309 r
->ServerInfo
->aipLogFilter
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipLogFilter
);
310 r
->ServerInfo
->pwszLogFilePath
= talloc_strdup(mem_ctx
, serverinfo
->pwszLogFilePath
);
311 r
->ServerInfo
->pszDomainName
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainName
);
312 r
->ServerInfo
->pszForestName
= talloc_strdup(mem_ctx
, serverinfo
->pszForestName
);
313 r
->ServerInfo
->pszDomainDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainDirectoryPartition
);
314 r
->ServerInfo
->pszForestDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszForestDirectoryPartition
);
315 r
->ServerInfo
->dwLogLevel
= serverinfo
->dwLogLevel
;
316 r
->ServerInfo
->dwDebugLevel
= serverinfo
->dwDebugLevel
;
317 r
->ServerInfo
->dwForwardTimeout
= serverinfo
->dwForwardTimeout
;
318 r
->ServerInfo
->dwRpcProtocol
= serverinfo
->dwRpcProtocol
;
319 r
->ServerInfo
->dwNameCheckFlag
= serverinfo
->dwNameCheckFlag
;
320 r
->ServerInfo
->cAddressAnswerLimit
= serverinfo
->cAddressAnswerLimit
;
321 r
->ServerInfo
->dwRecursionRetry
= serverinfo
->dwRecursionRetry
;
322 r
->ServerInfo
->dwRecursionTimeout
= serverinfo
->dwRecursionTimeout
;
323 r
->ServerInfo
->dwMaxCacheTtl
= serverinfo
->dwMaxCacheTtl
;
324 r
->ServerInfo
->dwDsPollingInterval
= serverinfo
->dwDsPollingInterval
;
325 r
->ServerInfo
->dwLocalNetPriorityNetMask
= serverinfo
->dwLocalNetPriorityNetMask
;
326 r
->ServerInfo
->dwScavengingInterval
= serverinfo
->dwScavengingInterval
;
327 r
->ServerInfo
->dwDefaultRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
328 r
->ServerInfo
->dwDefaultNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
329 r
->ServerInfo
->dwLastScavengeTime
= serverinfo
->dwLastScavengeTime
;
330 r
->ServerInfo
->dwEventLogLevel
= serverinfo
->dwEventLogLevel
;
331 r
->ServerInfo
->dwLogFileMaxSize
= serverinfo
->dwLogFileMaxSize
;
332 r
->ServerInfo
->dwDsForestVersion
= serverinfo
->dwDsForestVersion
;
333 r
->ServerInfo
->dwDsDomainVersion
= serverinfo
->dwDsDomainVersion
;
334 r
->ServerInfo
->dwDsDsaVersion
= serverinfo
->dwDsDsaVersion
;
335 r
->ServerInfo
->fReadOnlyDC
= serverinfo
->fReadOnlyDC
;
336 r
->ServerInfo
->fAutoReverseZones
= serverinfo
->fAutoReverseZones
;
337 r
->ServerInfo
->fAutoCacheUpdate
= serverinfo
->fAutoCacheUpdate
;
338 r
->ServerInfo
->fRecurseAfterForwarding
= serverinfo
->fRecurseAfterForwarding
;
339 r
->ServerInfo
->fForwardDelegations
= serverinfo
->fForwardDelegations
;
340 r
->ServerInfo
->fNoRecursion
= serverinfo
->fNoRecursion
;
341 r
->ServerInfo
->fSecureResponses
= serverinfo
->fSecureResponses
;
342 r
->ServerInfo
->fRoundRobin
= serverinfo
->fRoundRobin
;
343 r
->ServerInfo
->fLocalNetPriority
= serverinfo
->fLocalNetPriority
;
344 r
->ServerInfo
->fBindSecondaries
= serverinfo
->fBindSecondaries
;
345 r
->ServerInfo
->fWriteAuthorityNs
= serverinfo
->fWriteAuthorityNs
;
346 r
->ServerInfo
->fStrictFileParsing
= serverinfo
->fStrictFileParsing
;
347 r
->ServerInfo
->fLooseWildcarding
= serverinfo
->fLooseWildcarding
;
348 r
->ServerInfo
->fDefaultAgingState
= serverinfo
->fDefaultAgingState
;
355 if (strcasecmp(operation
, "AddressAnswerLimit") == 0) {
356 answer_integer
= serverinfo
->cAddressAnswerLimit
;
358 } else if (strcasecmp(operation
, "AdminConfigured") == 0) {
359 answer_integer
= serverinfo
->fAdminConfigured
;
361 } else if (strcasecmp(operation
, "AllowCNAMEAtNS") == 0) {
364 } else if (strcasecmp(operation
, "AllowUpdate") == 0) {
365 answer_integer
= serverinfo
->fAllowUpdate
;
367 } else if (strcasecmp(operation
, "AutoCacheUpdate") == 0) {
368 answer_integer
= serverinfo
->fAutoCacheUpdate
;
370 } else if (strcasecmp(operation
, "AutoConfigFileZones") == 0) {
373 } else if (strcasecmp(operation
, "BindSecondaries") == 0) {
374 answer_integer
= serverinfo
->fBindSecondaries
;
376 } else if (strcasecmp(operation
, "BootMethod") == 0) {
377 answer_integer
= serverinfo
->fBootMethod
;
379 } else if (strcasecmp(operation
, "DebugLevel") == 0) {
380 answer_integer
= serverinfo
->dwDebugLevel
;
382 } else if (strcasecmp(operation
, "DefaultAgingState") == 0) {
383 answer_integer
= serverinfo
->fDefaultAgingState
;
385 } else if (strcasecmp(operation
, "DefaultNoRefreshInterval") == 0) {
386 answer_integer
= serverinfo
->dwDefaultNoRefreshInterval
;
388 } else if (strcasecmp(operation
, "DefaultRefreshInterval") == 0) {
389 answer_integer
= serverinfo
->dwDefaultRefreshInterval
;
391 } else if (strcasecmp(operation
, "DeleteOutsideGlue") == 0) {
394 } else if (strcasecmp(operation
, "DisjointNets") == 0) {
397 } else if (strcasecmp(operation
, "DsLazyUpdateInterval") == 0) {
398 answer_integer
= 3; /* seconds */
400 } else if (strcasecmp(operation
, "DsPollingInterval") == 0) {
401 answer_integer
= serverinfo
->dwDsPollingInterval
;
403 } else if (strcasecmp(operation
, "DsTombstoneInterval") == 0) {
404 answer_integer
= 0x00127500; /* 14 days */
406 } else if (strcasecmp(operation
, "EnableRegistryBoot") == 0) {
409 } else if (strcasecmp(operation
, "EventLogLevel") == 0) {
410 answer_integer
= serverinfo
->dwEventLogLevel
;
412 } else if (strcasecmp(operation
, "ForceSoaSerial") == 0) {
415 } else if (strcasecmp(operation
, "ForceSaoRetry") == 0) {
418 } else if (strcasecmp(operation
, "ForceSoaRefresh") == 0) {
421 } else if (strcasecmp(operation
, "ForceSoaMinimumTtl") == 0) {
424 } else if (strcasecmp(operation
, "ForwardDelegations") == 0) {
427 } else if (strcasecmp(operation
, "ForwardingTimeout") == 0) {
428 answer_integer
= serverinfo
->dwForwardTimeout
;
430 } else if (strcasecmp(operation
, "IsSlave") == 0) {
433 } else if (strcasecmp(operation
, "LocalNetPriority") == 0) {
434 answer_integer
= serverinfo
->fLocalNetPriority
;
436 } else if (strcasecmp(operation
, "LogFileMaxSize") == 0) {
437 answer_integer
= serverinfo
->dwLogFileMaxSize
;
439 } else if (strcasecmp(operation
, "LogLevel") == 0) {
440 answer_integer
= serverinfo
->dwLogLevel
;
442 } else if (strcasecmp(operation
, "LooseWildcarding") == 0) {
443 answer_integer
= serverinfo
->fLooseWildcarding
;
445 } else if (strcasecmp(operation
, "MaxCacheTtl") == 0) {
446 answer_integer
= serverinfo
->dwMaxCacheTtl
;
448 } else if (strcasecmp(operation
, "MaxNegativeCacheTtl") == 0) {
449 answer_integer
= 0x00000384; /* 15 minutes */
451 } else if (strcasecmp(operation
, "NameCheckFlag") == 0) {
452 answer_integer
= serverinfo
->dwNameCheckFlag
;
454 } else if (strcasecmp(operation
, "NoRecursion") == 0) {
455 answer_integer
= serverinfo
->fNoRecursion
;
457 } else if (strcasecmp(operation
, "NoUpdateDelegations") == 0) {
460 } else if (strcasecmp(operation
, "PublishAutonet") == 0) {
463 } else if (strcasecmp(operation
, "QuietRecvFaultInterval") == 0) {
466 } else if (strcasecmp(operation
, "QuietRecvLogInterval") == 0) {
469 } else if (strcasecmp(operation
, "RecursionRetry") == 0) {
470 answer_integer
= serverinfo
->dwRecursionRetry
;
472 } else if (strcasecmp(operation
, "RecursionTimeout") == 0) {
473 answer_integer
= serverinfo
->dwRecursionTimeout
;
475 } else if (strcasecmp(operation
, "ReloadException") == 0) {
478 } else if (strcasecmp(operation
, "RoundRobin") == 0) {
479 answer_integer
= serverinfo
->fRoundRobin
;
481 } else if (strcasecmp(operation
, "RpcProtocol") == 0) {
482 answer_integer
= serverinfo
->dwRpcProtocol
;
484 } else if (strcasecmp(operation
, "SecureResponses") == 0) {
485 answer_integer
= serverinfo
->fSecureResponses
;
487 } else if (strcasecmp(operation
, "SendPort") == 0) {
490 } else if (strcasecmp(operation
, "ScavengingInterval") == 0) {
491 answer_integer
= serverinfo
->dwScavengingInterval
;
493 } else if (strcasecmp(operation
, "SocketPoolSize") == 0) {
494 answer_integer
= 0x000009C4;
496 } else if (strcasecmp(operation
, "StrictFileParsing") == 0) {
497 answer_integer
= serverinfo
->fStrictFileParsing
;
499 } else if (strcasecmp(operation
, "SyncDnsZoneSerial") == 0) {
500 answer_integer
= 2; /* ZONE_SERIAL_SYNC_XFER */
502 } else if (strcasecmp(operation
, "UpdateOptions") == 0) {
503 answer_integer
= 0x0000030F; /* DNS_DEFAULT_UPDATE_OPTIONS */
505 } else if (strcasecmp(operation
, "UseSystemEvengLog") == 0) {
508 } else if (strcasecmp(operation
, "Version") == 0) {
509 answer_integer
= serverinfo
->dwVersion
;
511 } else if (strcasecmp(operation
, "XfrConnectTimeout") == 0) {
512 answer_integer
= 0x0000001E;
514 } else if (strcasecmp(operation
, "WriteAuthorityNs") == 0) {
515 answer_integer
= serverinfo
->fWriteAuthorityNs
;
517 } else if (strcasecmp(operation
, "AdditionalRecursionTimeout") == 0) {
518 answer_integer
= 0x00000004;
520 } else if (strcasecmp(operation
, "AppendMsZoneTransferFlag") == 0) {
523 } else if (strcasecmp(operation
, "AutoCreateDelegations") == 0) {
524 answer_integer
= 0; /* DNS_ACD_DONT_CREATE */
526 } else if (strcasecmp(operation
, "BreakOnAscFailure") == 0) {
529 } else if (strcasecmp(operation
, "CacheEmptyAuthResponses") == 0) {
532 } else if (strcasecmp(operation
, "DirectoryPartitionAutoEnlistInterval") == 0) {
533 answer_integer
= 0x00015180; /* 1 day */
535 } else if (strcasecmp(operation
, "DisableAutoReverseZones") == 0) {
536 answer_integer
= ~serverinfo
->fAutoReverseZones
;
538 } else if (strcasecmp(operation
, "EDnsCacheTimeout") == 0) {
539 answer_integer
= 0x00000384; /* 15 minutes */
541 } else if (strcasecmp(operation
, "EnableDirectoryPartitions") == 0) {
542 answer_integer
= serverinfo
->fDsAvailable
;
544 } else if (strcasecmp(operation
, "EnableDnsSec") == 0) {
547 } else if (strcasecmp(operation
, "EnableEDnsProbes") == 0) {
550 } else if (strcasecmp(operation
, "EnableEDnsReception") == 0) {
553 } else if (strcasecmp(operation
, "EnableIPv6") == 0) {
556 } else if (strcasecmp(operation
, "EnableIQueryResponseGeneration") == 0) {
559 } else if (strcasecmp(operation
, "EnableSendErrorSuppression") == 0) {
562 } else if (strcasecmp(operation
, "EnableUpdateForwarding") == 0) {
565 } else if (strcasecmp(operation
, "EnableWinsR") == 0) {
568 } else if (strcasecmp(operation
, "ForceDsaBehaviorVersion") == 0) {
569 answer_integer
= serverinfo
->dwDsDsaVersion
;
571 } else if (strcasecmp(operation
, "ForceDomainBehaviorVersion") == 0) {
572 answer_integer
= serverinfo
->dwDsDsaVersion
;
574 } else if (strcasecmp(operation
, "ForceForestBehaviorVersion") == 0) {
575 answer_integer
= serverinfo
->dwDsDsaVersion
;
577 } else if (strcasecmp(operation
, "HeapDebug") == 0) {
580 } else if (strcasecmp(operation
, "LameDelegationTtl") == 0) {
581 answer_integer
= 0; /* seconds */
583 } else if (strcasecmp(operation
, "LocalNetPriorityNetMask") == 0) {
584 answer_integer
= serverinfo
->dwLocalNetPriorityNetMask
;
586 } else if (strcasecmp(operation
, "MaxCacheSize") == 0) {
589 } else if (strcasecmp(operation
, "MaxResourceRecordsInNonSecureUpdate") == 0) {
590 answer_integer
= 0x0000001E;
592 } else if (strcasecmp(operation
, "OperationsLogLevel") == 0) {
595 } else if (strcasecmp(operation
, "OperationsLogLevel2") == 0) {
598 } else if (strcasecmp(operation
, "MaximumUdpPacketSize") == 0) {
599 answer_integer
= 0x00004000; /* maximum possible */
601 } else if (strcasecmp(operation
, "RecurseToInternetRootMask") == 0) {
604 } else if (strcasecmp(operation
, "SelfTest") == 0) {
607 } else if (strcasecmp(operation
, "SilentlyIgnoreCNameUpdateConflicts") == 0) {
610 } else if (strcasecmp(operation
, "TcpReceivePacketSize") == 0) {
611 answer_integer
= 0x00010000;
613 } else if (strcasecmp(operation
, "XfrThrottleMultiplier") == 0) {
614 answer_integer
= 0x0000000A;
616 } else if (strcasecmp(operation
, "AllowMsdcsLookupRetry") == 0) {
619 } else if (strcasecmp(operation
, "AllowReadOnlyZoneTransfer") == 0) {
622 } else if (strcasecmp(operation
, "DsBackGroundLoadPaused") == 0) {
625 } else if (strcasecmp(operation
, "DsMinimumBackgroundLoadThreads") == 0) {
628 } else if (strcasecmp(operation
, "DsRemoteReplicationDelay") == 0) {
629 answer_integer
= 0x0000001E; /* 30 seconds */
631 } else if (strcasecmp(operation
, "EnableDuplicateQuerySuppresion") == 0) {
634 } else if (strcasecmp(operation
, "EnableGlobalNamesSupport") == 0) {
637 } else if (strcasecmp(operation
, "EnableVersionQuery") == 0) {
638 answer_integer
= 1; /* DNS_VERSION_QUERY_FULL */
640 } else if (strcasecmp(operation
, "EnableRsoForRodc") == 0) {
643 } else if (strcasecmp(operation
, "ForceRODCMode") == 0) {
646 } else if (strcasecmp(operation
, "GlobalNamesAlwaysQuerySrv") == 0) {
649 } else if (strcasecmp(operation
, "GlobalNamesBlockUpdates") == 0) {
652 } else if (strcasecmp(operation
, "GlobalNamesEnableEDnsProbes") == 0) {
655 } else if (strcasecmp(operation
, "GlobalNamesPreferAAAA") == 0) {
658 } else if (strcasecmp(operation
, "GlobalNamesQueryOrder") == 0) {
661 } else if (strcasecmp(operation
, "GlobalNamesSendTimeout") == 0) {
662 answer_integer
= 3; /* seconds */
664 } else if (strcasecmp(operation
, "GlobalNamesServerQueryInterval") == 0) {
665 answer_integer
= 0x00005460; /* 6 hours */
667 } else if (strcasecmp(operation
, "RemoteIPv4RankBoost") == 0) {
670 } else if (strcasecmp(operation
, "RemoteIPv6RankBoost") == 0) {
673 } else if (strcasecmp(operation
, "MaximumRodcRsoAttemptsPerCycle") == 0) {
674 answer_integer
= 0x00000064;
676 } else if (strcasecmp(operation
, "MaximumRodcRsoQueueLength") == 0) {
677 answer_integer
= 0x0000012C;
679 } else if (strcasecmp(operation
, "EnableGlobalQueryBlockList") == 0) {
682 } else if (strcasecmp(operation
, "OpenACLOnProxyUpdates") == 0) {
685 } else if (strcasecmp(operation
, "CacheLockingPercent") == 0) {
686 answer_integer
= 0x00000064;
690 if (is_integer
== 1) {
691 *typeid = DNSSRV_TYPEID_DWORD
;
692 r
->Dword
= answer_integer
;
698 if (strcasecmp(operation
, "Forwarders") == 0) {
699 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
700 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipForwarders
);
702 answer_iparray
= ip4_array_copy(mem_ctx
, serverinfo
->aipForwarders
);
705 } else if (strcasecmp(operation
, "ListenAddresses") == 0) {
706 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
707 answer_addrarray
= serverinfo
->aipListenAddrs
;
709 answer_iparray
= dns_addr_array_to_ip4_array(mem_ctx
, serverinfo
->aipListenAddrs
);
712 } else if (strcasecmp(operation
, "BreakOnReceiveFrom") == 0) {
713 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
714 answer_addrarray
= NULL
;
716 answer_iparray
= NULL
;
719 } else if (strcasecmp(operation
, "BreakOnUpdateFrom") == 0) {
720 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
721 answer_addrarray
= NULL
;
723 answer_iparray
= NULL
;
726 } else if (strcasecmp(operation
, "LogIPFilterList") == 0) {
727 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
728 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipLogFilter
);
730 answer_iparray
= ip4_array_copy(mem_ctx
, serverinfo
->aipLogFilter
);
735 if (is_addresses
== 1) {
736 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
737 *typeid = DNSSRV_TYPEID_ADDRARRAY
;
738 r
->AddrArray
= answer_addrarray
;
740 *typeid = DNSSRV_TYPEID_IPARRAY
;
741 r
->IpArray
= answer_iparray
;
746 is_string
= is_wstring
= 0;
748 if (strcasecmp(operation
, "DomainDirectoryPartitionBaseName") == 0) {
749 answer_string
= talloc_strdup(mem_ctx
, "DomainDnsZones");
750 if (! answer_string
) {
751 return WERR_OUTOFMEMORY
;
754 } else if (strcasecmp(operation
, "ForestDirectoryPartitionBaseName") == 0) {
755 answer_string
= talloc_strdup(mem_ctx
, "ForestDnsZones");
756 if (! answer_string
) {
757 return WERR_OUTOFMEMORY
;
760 } else if (strcasecmp(operation
, "LogFilePath") == 0) {
761 answer_string
= talloc_strdup(mem_ctx
, serverinfo
->pwszLogFilePath
);
763 } else if (strcasecmp(operation
, "ServerLevelPluginDll") == 0) {
764 answer_string
= NULL
;
766 } else if (strcasecmp(operation
, "DsBackgroundPauseName") == 0) {
767 answer_string
= NULL
;
769 } else if (strcasecmp(operation
, "DsNotRoundRobinTypes") == 0) {
770 answer_string
= NULL
;
774 if (is_string
== 1) {
775 *typeid = DNSSRV_TYPEID_LPSTR
;
776 r
->String
= answer_string
;
778 } else if (is_wstring
== 1) {
779 *typeid = DNSSRV_TYPEID_LPWSTR
;
780 r
->WideString
= answer_string
;
786 if (strcasecmp(operation
, "GlobalQueryBlockList") == 0) {
787 answer_stringlist
= NULL
;
789 } else if (strcasecmp(operation
, "SocketPoolExcludedPortRanges") == 0) {
790 answer_stringlist
= NULL
;
794 if (is_stringlist
== 1) {
795 *typeid = DNSSRV_TYPEID_UTF8_STRING_LIST
;
796 r
->Utf8StringList
= answer_stringlist
;
800 DEBUG(0,("dnsserver: Invalid server operation %s", operation
));
801 return WERR_DNS_ERROR_INVALID_PROPERTY
;
804 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
805 static WERROR
dnsserver_query_zone(struct dnsserver_state
*dsstate
,
807 struct dnsserver_zone
*z
,
808 const char *operation
,
809 const unsigned int client_version
,
810 enum DNS_RPC_TYPEID
*typeid,
811 union DNSSRV_RPC_UNION
*r
)
813 uint8_t is_integer
, is_addresses
, is_string
;
814 uint32_t answer_integer
;
815 struct IP4_ARRAY
*answer_iparray
;
816 struct DNS_ADDR_ARRAY
*answer_addrarray
;
818 struct dnsserver_zoneinfo
*zoneinfo
;
820 zoneinfo
= z
->zoneinfo
;
822 if (strcasecmp(operation
, "Zone") == 0) {
823 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
824 *typeid = DNSSRV_TYPEID_ZONE_W2K
;
825 r
->ZoneW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_W2K
);
827 r
->ZoneW2K
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
828 r
->ZoneW2K
->Flags
= zoneinfo
->Flags
;
829 r
->ZoneW2K
->ZoneType
= zoneinfo
->dwZoneType
;
830 r
->ZoneW2K
->Version
= zoneinfo
->Version
;
832 *typeid = DNSSRV_TYPEID_ZONE
;
833 r
->Zone
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_DOTNET
);
835 r
->Zone
->dwRpcStructureVersion
= 0x01;
836 r
->Zone
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
837 r
->Zone
->Flags
= zoneinfo
->Flags
;
838 r
->Zone
->ZoneType
= zoneinfo
->dwZoneType
;
839 r
->Zone
->Version
= zoneinfo
->Version
;
840 r
->Zone
->dwDpFlags
= z
->partition
->dwDpFlags
;
841 r
->Zone
->pszDpFqdn
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
846 if (strcasecmp(operation
, "ZoneInfo") == 0) {
847 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
848 *typeid = DNSSRV_TYPEID_ZONE_INFO_W2K
;
849 r
->ZoneInfoW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_INFO_W2K
);
851 r
->ZoneInfoW2K
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
852 r
->ZoneInfoW2K
->dwZoneType
= zoneinfo
->dwZoneType
;
853 r
->ZoneInfoW2K
->fReverse
= zoneinfo
->fReverse
;
854 r
->ZoneInfoW2K
->fAllowUpdate
= zoneinfo
->fAllowUpdate
;
855 r
->ZoneInfoW2K
->fPaused
= zoneinfo
->fPaused
;
856 r
->ZoneInfoW2K
->fShutdown
= zoneinfo
->fShutdown
;
857 r
->ZoneInfoW2K
->fAutoCreated
= zoneinfo
->fAutoCreated
;
858 r
->ZoneInfoW2K
->fUseDatabase
= zoneinfo
->fUseDatabase
;
859 r
->ZoneInfoW2K
->pszDataFile
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
860 r
->ZoneInfoW2K
->aipMasters
= ip4_array_copy(mem_ctx
, zoneinfo
->aipMasters
);
861 r
->ZoneInfoW2K
->fSecureSecondaries
= zoneinfo
->fSecureSecondaries
;
862 r
->ZoneInfoW2K
->fNotifyLevel
= zoneinfo
->fNotifyLevel
;
863 r
->ZoneInfoW2K
->aipSecondaries
= ip4_array_copy(mem_ctx
, zoneinfo
->aipSecondaries
);
864 r
->ZoneInfoW2K
->aipNotify
= ip4_array_copy(mem_ctx
, zoneinfo
->aipNotify
);
865 r
->ZoneInfoW2K
->fUseWins
= zoneinfo
->fUseWins
;
866 r
->ZoneInfoW2K
->fUseNbstat
= zoneinfo
->fUseNbstat
;
867 r
->ZoneInfoW2K
->fAging
= zoneinfo
->fAging
;
868 r
->ZoneInfoW2K
->dwNoRefreshInterval
= zoneinfo
->dwNoRefreshInterval
;
869 r
->ZoneInfoW2K
->dwRefreshInterval
= zoneinfo
->dwRefreshInterval
;
870 r
->ZoneInfoW2K
->dwAvailForScavengeTime
= zoneinfo
->dwAvailForScavengeTime
;
871 r
->ZoneInfoW2K
->aipScavengeServers
= ip4_array_copy(mem_ctx
, zoneinfo
->aipScavengeServers
);
873 } else if (client_version
== DNS_CLIENT_VERSION_DOTNET
) {
874 *typeid = DNSSRV_TYPEID_ZONE_INFO_DOTNET
;
875 r
->ZoneInfoDotNet
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_INFO_DOTNET
);
877 r
->ZoneInfoDotNet
->dwRpcStructureVersion
= 0x01;
878 r
->ZoneInfoDotNet
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
879 r
->ZoneInfoDotNet
->dwZoneType
= zoneinfo
->dwZoneType
;
880 r
->ZoneInfoDotNet
->fReverse
= zoneinfo
->fReverse
;
881 r
->ZoneInfoDotNet
->fAllowUpdate
= zoneinfo
->fAllowUpdate
;
882 r
->ZoneInfoDotNet
->fPaused
= zoneinfo
->fPaused
;
883 r
->ZoneInfoDotNet
->fShutdown
= zoneinfo
->fShutdown
;
884 r
->ZoneInfoDotNet
->fAutoCreated
= zoneinfo
->fAutoCreated
;
885 r
->ZoneInfoDotNet
->fUseDatabase
= zoneinfo
->fUseDatabase
;
886 r
->ZoneInfoDotNet
->pszDataFile
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
887 r
->ZoneInfoDotNet
->aipMasters
= ip4_array_copy(mem_ctx
, zoneinfo
->aipMasters
);
888 r
->ZoneInfoDotNet
->fSecureSecondaries
= zoneinfo
->fSecureSecondaries
;
889 r
->ZoneInfoDotNet
->fNotifyLevel
= zoneinfo
->fNotifyLevel
;
890 r
->ZoneInfoDotNet
->aipSecondaries
= ip4_array_copy(mem_ctx
, zoneinfo
->aipSecondaries
);
891 r
->ZoneInfoDotNet
->aipNotify
= ip4_array_copy(mem_ctx
, zoneinfo
->aipNotify
);
892 r
->ZoneInfoDotNet
->fUseWins
= zoneinfo
->fUseWins
;
893 r
->ZoneInfoDotNet
->fUseNbstat
= zoneinfo
->fUseNbstat
;
894 r
->ZoneInfoDotNet
->fAging
= zoneinfo
->fAging
;
895 r
->ZoneInfoDotNet
->dwNoRefreshInterval
= zoneinfo
->dwNoRefreshInterval
;
896 r
->ZoneInfoDotNet
->dwRefreshInterval
= zoneinfo
->dwRefreshInterval
;
897 r
->ZoneInfoDotNet
->dwAvailForScavengeTime
= zoneinfo
->dwAvailForScavengeTime
;
898 r
->ZoneInfoDotNet
->aipScavengeServers
= ip4_array_copy(mem_ctx
, zoneinfo
->aipScavengeServers
);
899 r
->ZoneInfoDotNet
->dwForwarderTimeout
= zoneinfo
->dwForwarderTimeout
;
900 r
->ZoneInfoDotNet
->fForwarderSlave
= zoneinfo
->fForwarderSlave
;
901 r
->ZoneInfoDotNet
->aipLocalMasters
= ip4_array_copy(mem_ctx
, zoneinfo
->aipLocalMasters
);
902 r
->ZoneInfoDotNet
->dwDpFlags
= z
->partition
->dwDpFlags
;
903 r
->ZoneInfoDotNet
->pszDpFqdn
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
904 r
->ZoneInfoDotNet
->pwszZoneDn
= talloc_strdup(mem_ctx
, zoneinfo
->pwszZoneDn
);
905 r
->ZoneInfoDotNet
->dwLastSuccessfulSoaCheck
= zoneinfo
->dwLastSuccessfulSoaCheck
;
906 r
->ZoneInfoDotNet
->dwLastSuccessfulXfr
= zoneinfo
->dwLastSuccessfulXfr
;
909 *typeid = DNSSRV_TYPEID_ZONE_INFO
;
910 r
->ZoneInfo
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_INFO_LONGHORN
);
912 r
->ZoneInfo
->dwRpcStructureVersion
= 0x02;
913 r
->ZoneInfo
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
914 r
->ZoneInfo
->dwZoneType
= zoneinfo
->dwZoneType
;
915 r
->ZoneInfo
->fReverse
= zoneinfo
->fReverse
;
916 r
->ZoneInfo
->fAllowUpdate
= zoneinfo
->fAllowUpdate
;
917 r
->ZoneInfo
->fPaused
= zoneinfo
->fPaused
;
918 r
->ZoneInfo
->fShutdown
= zoneinfo
->fShutdown
;
919 r
->ZoneInfo
->fAutoCreated
= zoneinfo
->fAutoCreated
;
920 r
->ZoneInfo
->fUseDatabase
= zoneinfo
->fUseDatabase
;
921 r
->ZoneInfo
->pszDataFile
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
922 r
->ZoneInfo
->aipMasters
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipMasters
);
923 r
->ZoneInfo
->fSecureSecondaries
= zoneinfo
->fSecureSecondaries
;
924 r
->ZoneInfo
->fNotifyLevel
= zoneinfo
->fNotifyLevel
;
925 r
->ZoneInfo
->aipSecondaries
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipSecondaries
);
926 r
->ZoneInfo
->aipNotify
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipNotify
);
927 r
->ZoneInfo
->fUseWins
= zoneinfo
->fUseWins
;
928 r
->ZoneInfo
->fUseNbstat
= zoneinfo
->fUseNbstat
;
929 r
->ZoneInfo
->fAging
= zoneinfo
->fAging
;
930 r
->ZoneInfo
->dwNoRefreshInterval
= zoneinfo
->dwNoRefreshInterval
;
931 r
->ZoneInfo
->dwRefreshInterval
= zoneinfo
->dwRefreshInterval
;
932 r
->ZoneInfo
->dwAvailForScavengeTime
= zoneinfo
->dwAvailForScavengeTime
;
933 r
->ZoneInfo
->aipScavengeServers
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipScavengeServers
);
934 r
->ZoneInfo
->dwForwarderTimeout
= zoneinfo
->dwForwarderTimeout
;
935 r
->ZoneInfo
->fForwarderSlave
= zoneinfo
->fForwarderSlave
;
936 r
->ZoneInfo
->aipLocalMasters
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipLocalMasters
);
937 r
->ZoneInfo
->dwDpFlags
= z
->partition
->dwDpFlags
;
938 r
->ZoneInfo
->pszDpFqdn
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
939 r
->ZoneInfo
->pwszZoneDn
= talloc_strdup(mem_ctx
, zoneinfo
->pwszZoneDn
);
940 r
->ZoneInfo
->dwLastSuccessfulSoaCheck
= zoneinfo
->dwLastSuccessfulSoaCheck
;
941 r
->ZoneInfo
->dwLastSuccessfulXfr
= zoneinfo
->dwLastSuccessfulXfr
;
943 r
->ZoneInfo
->fQueuedForBackgroundLoad
= zoneinfo
->fQueuedForBackgroundLoad
;
944 r
->ZoneInfo
->fBackgroundLoadInProgress
= zoneinfo
->fBackgroundLoadInProgress
;
945 r
->ZoneInfo
->fReadOnlyZone
= zoneinfo
->fReadOnlyZone
;
946 r
->ZoneInfo
->dwLastXfrAttempt
= zoneinfo
->dwLastXfrAttempt
;
947 r
->ZoneInfo
->dwLastXfrResult
= zoneinfo
->dwLastXfrResult
;
955 if (strcasecmp(operation
, "AllowUpdate") == 0) {
956 answer_integer
= zoneinfo
->fAllowUpdate
;
958 } else if (strcasecmp(operation
, "Secured") == 0) {
961 } else if (strcasecmp(operation
, "DsIntegrated") == 0) {
962 answer_integer
= zoneinfo
->fUseDatabase
;
964 } else if (strcasecmp(operation
, "LogUpdates") == 0) {
967 } else if (strcasecmp(operation
, "NoRefreshInterval") == 0) {
968 answer_integer
= zoneinfo
->dwNoRefreshInterval
;
970 } else if (strcasecmp(operation
, "NotifyLevel") == 0) {
971 answer_integer
= zoneinfo
->fNotifyLevel
;
973 } else if (strcasecmp(operation
, "RefreshInterval") == 0) {
974 answer_integer
= zoneinfo
->dwRefreshInterval
;
976 } else if (strcasecmp(operation
, "SecureSecondaries") == 0) {
977 answer_integer
= zoneinfo
->fSecureSecondaries
;
979 } else if (strcasecmp(operation
, "Type") == 0) {
980 answer_integer
= zoneinfo
->dwZoneType
;
982 } else if (strcasecmp(operation
, "Aging") == 0) {
983 answer_integer
= zoneinfo
->fAging
;
985 } else if (strcasecmp(operation
, "ForwarderSlave") == 0) {
986 answer_integer
= zoneinfo
->fForwarderSlave
;
988 } else if (strcasecmp(operation
, "ForwarderTimeout") == 0) {
989 answer_integer
= zoneinfo
->dwForwarderTimeout
;
991 } else if (strcasecmp(operation
, "Unicode") == 0) {
996 if (is_integer
== 1) {
997 *typeid = DNSSRV_TYPEID_DWORD
;
998 r
->Dword
= answer_integer
;
1004 if (strcasecmp(operation
, "AllowNSRecordsAutoCreation") == 0) {
1005 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1006 answer_addrarray
= NULL
;
1008 answer_iparray
= NULL
;
1011 } else if (strcasecmp(operation
, "ScavengeServers") == 0) {
1012 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1013 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipScavengeServers
);
1015 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipScavengeServers
);
1018 } else if (strcasecmp(operation
, "MasterServers") == 0) {
1019 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1020 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipMasters
);
1022 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipMasters
);
1025 } else if (strcasecmp(operation
, "LocalMasterServers") == 0) {
1026 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1027 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipLocalMasters
);
1029 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipLocalMasters
);
1032 } else if (strcasecmp(operation
, "NotifyServers") == 0) {
1033 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1034 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipNotify
);
1036 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipNotify
);
1039 } else if (strcasecmp(operation
, "SecondaryServers") == 0) {
1040 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1041 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipSecondaries
);
1043 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipSecondaries
);
1048 if (is_addresses
== 1) {
1049 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1050 *typeid = DNSSRV_TYPEID_ADDRARRAY
;
1051 r
->AddrArray
= answer_addrarray
;
1053 *typeid = DNSSRV_TYPEID_IPARRAY
;
1054 r
->IpArray
= answer_iparray
;
1061 if (strcasecmp(operation
, "DatabaseFile") == 0) {
1062 answer_string
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
1064 } else if (strcasecmp(operation
, "ApplicationDirectoryPartition") == 0) {
1065 answer_string
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
1067 } else if (strcasecmp(operation
, "BreakOnNameUpdate") == 0) {
1068 answer_string
= NULL
;
1072 if (is_string
== 1) {
1073 *typeid = DNSSRV_TYPEID_LPSTR
;
1074 r
->String
= answer_string
;
1078 DEBUG(0,("dnsserver: Invalid zone operation %s", operation
));
1079 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1083 /* dnsserver operation functions */
1085 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
1086 static WERROR
dnsserver_operate_server(struct dnsserver_state
*dsstate
,
1087 TALLOC_CTX
*mem_ctx
,
1088 const char *operation
,
1089 const unsigned int client_version
,
1090 enum DNS_RPC_TYPEID
typeid,
1091 union DNSSRV_RPC_UNION
*r
)
1093 bool valid_operation
= false;
1095 if (strcasecmp(operation
, "ResetDwordProperty") == 0) {
1096 valid_operation
= true;
1097 } else if (strcasecmp(operation
, "Restart") == 0) {
1098 valid_operation
= true;
1099 } else if (strcasecmp(operation
, "ClearDebugLog") == 0) {
1100 valid_operation
= true;
1101 } else if (strcasecmp(operation
, "ClearCache") == 0) {
1102 valid_operation
= true;
1103 } else if (strcasecmp(operation
, "WriteDirtyZones") == 0) {
1104 valid_operation
= true;
1105 } else if (strcasecmp(operation
, "ZoneCreate") == 0) {
1106 struct dnsserver_zone
*z
, *z2
;
1109 z
= talloc_zero(mem_ctx
, struct dnsserver_zone
);
1110 W_ERROR_HAVE_NO_MEMORY(z
);
1111 z
->partition
= talloc_zero(z
, struct dnsserver_partition
);
1112 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z
->partition
, z
);
1113 z
->zoneinfo
= talloc_zero(z
, struct dnsserver_zoneinfo
);
1114 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z
->zoneinfo
, z
);
1116 if (typeid == DNSSRV_TYPEID_ZONE_CREATE_W2K
) {
1117 z
->name
= talloc_strdup(z
, r
->ZoneCreateW2K
->pszZoneName
);
1118 z
->zoneinfo
->dwZoneType
= r
->ZoneCreateW2K
->dwZoneType
;
1119 z
->zoneinfo
->fAllowUpdate
= r
->ZoneCreateW2K
->fAllowUpdate
;
1120 z
->zoneinfo
->fAging
= r
->ZoneCreateW2K
->fAging
;
1121 z
->zoneinfo
->Flags
= r
->ZoneCreateW2K
->dwFlags
;
1122 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE_DOTNET
) {
1123 z
->name
= talloc_strdup(z
, r
->ZoneCreateDotNet
->pszZoneName
);
1124 z
->zoneinfo
->dwZoneType
= r
->ZoneCreateDotNet
->dwZoneType
;
1125 z
->zoneinfo
->fAllowUpdate
= r
->ZoneCreateDotNet
->fAllowUpdate
;
1126 z
->zoneinfo
->fAging
= r
->ZoneCreateDotNet
->fAging
;
1127 z
->zoneinfo
->Flags
= r
->ZoneCreateDotNet
->dwFlags
;
1128 z
->partition
->dwDpFlags
= r
->ZoneCreateDotNet
->dwDpFlags
;
1129 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE
) {
1130 z
->name
= talloc_strdup(z
, r
->ZoneCreate
->pszZoneName
);
1131 z
->zoneinfo
->dwZoneType
= r
->ZoneCreate
->dwZoneType
;
1132 z
->zoneinfo
->fAllowUpdate
= r
->ZoneCreate
->fAllowUpdate
;
1133 z
->zoneinfo
->fAging
= r
->ZoneCreate
->fAging
;
1134 z
->zoneinfo
->Flags
= r
->ZoneCreate
->dwFlags
;
1135 z
->partition
->dwDpFlags
= r
->ZoneCreate
->dwDpFlags
;
1138 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1141 z2
= dnsserver_find_zone(dsstate
->zones
, z
->name
);
1144 return WERR_DNS_ERROR_ZONE_ALREADY_EXISTS
;
1147 status
= dnsserver_db_create_zone(dsstate
->samdb
, dsstate
->partitions
, z
,
1151 if (W_ERROR_IS_OK(status
)) {
1152 dnsserver_reload_zones(dsstate
);
1155 } else if (strcasecmp(operation
, "ClearStatistics") == 0) {
1156 valid_operation
= true;
1157 } else if (strcasecmp(operation
, "EnlistDirectoryPartition") == 0) {
1158 valid_operation
= true;
1159 } else if (strcasecmp(operation
, "StartScavenging") == 0) {
1160 valid_operation
= true;
1161 } else if (strcasecmp(operation
, "AbortScavenging") == 0) {
1162 valid_operation
= true;
1163 } else if (strcasecmp(operation
, "AutoConfigure") == 0) {
1164 valid_operation
= true;
1165 } else if (strcasecmp(operation
, "ExportSettings") == 0) {
1166 valid_operation
= true;
1167 } else if (strcasecmp(operation
, "PrepareForDemotion") == 0) {
1168 valid_operation
= true;
1169 } else if (strcasecmp(operation
, "PrepareForUninstall") == 0) {
1170 valid_operation
= true;
1171 } else if (strcasecmp(operation
, "DeleteNode") == 0) {
1172 valid_operation
= true;
1173 } else if (strcasecmp(operation
, "DeleteRecord") == 0) {
1174 valid_operation
= true;
1175 } else if (strcasecmp(operation
, "WriteBackFile") == 0) {
1176 valid_operation
= true;
1177 } else if (strcasecmp(operation
, "ListenAddresses") == 0) {
1178 valid_operation
= true;
1179 } else if (strcasecmp(operation
, "Forwarders") == 0) {
1180 valid_operation
= true;
1181 } else if (strcasecmp(operation
, "LogFilePath") == 0) {
1182 valid_operation
= true;
1183 } else if (strcasecmp(operation
, "LogIpFilterList") == 0) {
1184 valid_operation
= true;
1185 } else if (strcasecmp(operation
, "ForestDirectoryPartitionBaseName") == 0) {
1186 valid_operation
= true;
1187 } else if (strcasecmp(operation
, "DomainDirectoryPartitionBaseName") == 0) {
1188 valid_operation
= true;
1189 } else if (strcasecmp(operation
, "GlobalQueryBlockList") == 0) {
1190 valid_operation
= true;
1191 } else if (strcasecmp(operation
, "BreakOnReceiveFrom") == 0) {
1192 valid_operation
= true;
1193 } else if (strcasecmp(operation
, "BreakOnUpdateFrom") == 0) {
1194 valid_operation
= true;
1195 } else if (strcasecmp(operation
, "ServerLevelPluginDll") == 0) {
1196 valid_operation
= true;
1199 if (valid_operation
) {
1200 DEBUG(0, ("dnsserver: server operation '%s' not implemented", operation
));
1201 return WERR_CALL_NOT_IMPLEMENTED
;
1204 DEBUG(0, ("dnsserver: invalid server operation '%s'", operation
));
1205 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1208 static WERROR
dnsserver_complex_operate_server(struct dnsserver_state
*dsstate
,
1209 TALLOC_CTX
*mem_ctx
,
1210 const char *operation
,
1211 const unsigned int client_version
,
1212 enum DNS_RPC_TYPEID typeid_in
,
1213 union DNSSRV_RPC_UNION
*rin
,
1214 enum DNS_RPC_TYPEID
*typeid_out
,
1215 union DNSSRV_RPC_UNION
*rout
)
1217 int valid_operation
= 0;
1218 struct dnsserver_zone
*z
, **zlist
;
1220 bool found1
, found2
, found3
, found4
;
1223 if (strcasecmp(operation
, "QueryDwordProperty") == 0) {
1224 if (typeid_in
== DNSSRV_TYPEID_LPSTR
) {
1225 return dnsserver_query_server(dsstate
, mem_ctx
,
1231 } else if (strcasecmp(operation
, "EnumZones") == 0) {
1232 if (typeid_in
!= DNSSRV_TYPEID_DWORD
) {
1233 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1237 zlist
= talloc_zero_array(mem_ctx
, struct dnsserver_zone
*, 0);
1238 for (z
= dsstate
->zones
; z
; z
= z
->next
) {
1240 /* Match the flags in groups
1242 * Group1 : PRIMARY, SECONDARY, CACHE, AUTO
1243 * Group2 : FORWARD, REVERSE, FORWARDER, STUB
1244 * Group3 : DS, NON_DS, DOMAIN_DP, FOREST_DP
1245 * Group4 : CUSTOM_DP, LEGACY_DP
1250 if (rin
->Dword
& 0x0000000f) {
1251 if (rin
->Dword
& DNS_ZONE_REQUEST_PRIMARY
) {
1252 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_PRIMARY
) {
1256 if (rin
->Dword
& DNS_ZONE_REQUEST_SECONDARY
) {
1257 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_SECONDARY
) {
1261 if (rin
->Dword
& DNS_ZONE_REQUEST_CACHE
) {
1262 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_CACHE
) {
1266 if (rin
->Dword
& DNS_ZONE_REQUEST_AUTO
) {
1267 if (z
->zoneinfo
->fAutoCreated
1268 || z
->partition
->dwDpFlags
& DNS_DP_AUTOCREATED
) {
1278 if (rin
->Dword
& 0x000000f0) {
1279 if (rin
->Dword
& DNS_ZONE_REQUEST_FORWARD
) {
1280 if (!(z
->zoneinfo
->fReverse
)) {
1284 if (rin
->Dword
& DNS_ZONE_REQUEST_REVERSE
) {
1285 if (z
->zoneinfo
->fReverse
) {
1289 if (rin
->Dword
& DNS_ZONE_REQUEST_FORWARDER
) {
1290 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_FORWARDER
) {
1294 if (rin
->Dword
& DNS_ZONE_REQUEST_STUB
) {
1295 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_STUB
) {
1305 if (rin
->Dword
& 0x00000f00) {
1306 if (rin
->Dword
& DNS_ZONE_REQUEST_DS
) {
1307 if (z
->zoneinfo
->Flags
& DNS_RPC_ZONE_DSINTEGRATED
) {
1311 if (rin
->Dword
& DNS_ZONE_REQUEST_NON_DS
) {
1312 if (!(z
->zoneinfo
->Flags
& DNS_RPC_ZONE_DSINTEGRATED
)) {
1316 if (rin
->Dword
& DNS_ZONE_REQUEST_DOMAIN_DP
) {
1317 if (!(z
->partition
->dwDpFlags
& DNS_DP_DOMAIN_DEFAULT
)) {
1321 if (rin
->Dword
& DNS_ZONE_REQUEST_FOREST_DP
) {
1322 if (!(z
->partition
->dwDpFlags
& DNS_DP_FOREST_DEFAULT
)) {
1331 if (rin
->Dword
& 0x0000f000) {
1337 if (found1
&& found2
&& found3
&& found4
) {
1338 zlist
= talloc_realloc(mem_ctx
, zlist
, struct dnsserver_zone
*, zcount
+1);
1344 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
1345 *typeid_out
= DNSSRV_TYPEID_ZONE_LIST_W2K
;
1346 rout
->ZoneListW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_LIST_W2K
);
1349 rout
->ZoneListW2K
->dwZoneCount
= 0;
1350 rout
->ZoneListW2K
->ZoneArray
= NULL
;
1355 rout
->ZoneListW2K
->ZoneArray
= talloc_zero_array(mem_ctx
, struct DNS_RPC_ZONE_W2K
*, zcount
);
1356 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout
->ZoneListW2K
->ZoneArray
, zlist
);
1358 for (i
=0; i
<zcount
; i
++) {
1359 rout
->ZoneListW2K
->ZoneArray
[i
] = talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_W2K
);
1361 rout
->ZoneListW2K
->ZoneArray
[i
]->pszZoneName
= talloc_strdup(mem_ctx
, zlist
[i
]->name
);
1362 rout
->ZoneListW2K
->ZoneArray
[i
]->Flags
= zlist
[i
]->zoneinfo
->Flags
;
1363 rout
->ZoneListW2K
->ZoneArray
[i
]->ZoneType
= zlist
[i
]->zoneinfo
->dwZoneType
;
1364 rout
->ZoneListW2K
->ZoneArray
[i
]->Version
= zlist
[i
]->zoneinfo
->Version
;
1366 rout
->ZoneListW2K
->dwZoneCount
= zcount
;
1369 *typeid_out
= DNSSRV_TYPEID_ZONE_LIST
;
1370 rout
->ZoneList
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_LIST_DOTNET
);
1373 rout
->ZoneList
->dwRpcStructureVersion
= 1;
1374 rout
->ZoneList
->dwZoneCount
= 0;
1375 rout
->ZoneList
->ZoneArray
= NULL
;
1380 rout
->ZoneList
->ZoneArray
= talloc_zero_array(mem_ctx
, struct DNS_RPC_ZONE_DOTNET
*, zcount
);
1381 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout
->ZoneList
->ZoneArray
, zlist
);
1383 for (i
=0; i
<zcount
; i
++) {
1384 rout
->ZoneList
->ZoneArray
[i
] = talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_DOTNET
);
1386 rout
->ZoneList
->ZoneArray
[i
]->dwRpcStructureVersion
= 1;
1387 rout
->ZoneList
->ZoneArray
[i
]->pszZoneName
= talloc_strdup(mem_ctx
, zlist
[i
]->name
);
1388 rout
->ZoneList
->ZoneArray
[i
]->Flags
= zlist
[i
]->zoneinfo
->Flags
;
1389 rout
->ZoneList
->ZoneArray
[i
]->ZoneType
= zlist
[i
]->zoneinfo
->dwZoneType
;
1390 rout
->ZoneList
->ZoneArray
[i
]->Version
= zlist
[i
]->zoneinfo
->Version
;
1391 rout
->ZoneList
->ZoneArray
[i
]->dwDpFlags
= zlist
[i
]->partition
->dwDpFlags
;
1392 rout
->ZoneList
->ZoneArray
[i
]->pszDpFqdn
= talloc_strdup(mem_ctx
, zlist
[i
]->partition
->pszDpFqdn
);
1394 rout
->ZoneList
->dwRpcStructureVersion
= 1;
1395 rout
->ZoneList
->dwZoneCount
= zcount
;
1399 } else if (strcasecmp(operation
, "EnumZones2") == 0) {
1400 valid_operation
= true;
1401 } else if (strcasecmp(operation
, "EnumDirectoryPartitions") == 0) {
1402 if (typeid_in
!= DNSSRV_TYPEID_DWORD
) {
1403 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1406 *typeid_out
= DNSSRV_TYPEID_DP_LIST
;
1407 rout
->DirectoryPartitionList
= talloc_zero(mem_ctx
, struct DNS_RPC_DP_LIST
);
1409 if (rin
->Dword
!= 0) {
1410 rout
->DirectoryPartitionList
->dwDpCount
= 0;
1411 rout
->DirectoryPartitionList
->DpArray
= NULL
;
1413 struct DNS_RPC_DP_ENUM
**dplist
;
1414 struct dnsserver_partition
*p
;
1417 dplist
= talloc_zero_array(mem_ctx
, struct DNS_RPC_DP_ENUM
*, pcount
);
1418 W_ERROR_HAVE_NO_MEMORY(dplist
);
1420 p
= dsstate
->partitions
;
1421 for (i
=0; i
<pcount
; i
++) {
1422 dplist
[i
] = talloc_zero(dplist
, struct DNS_RPC_DP_ENUM
);
1424 dplist
[i
]->pszDpFqdn
= talloc_strdup(mem_ctx
, p
->pszDpFqdn
);
1425 dplist
[i
]->dwFlags
= p
->dwDpFlags
;
1426 dplist
[i
]->dwZoneCount
= p
->zones_count
;
1430 rout
->DirectoryPartitionList
->dwDpCount
= pcount
;
1431 rout
->DirectoryPartitionList
->DpArray
= dplist
;
1434 } else if (strcasecmp(operation
, "DirectoryPartitionInfo") == 0) {
1435 struct dnsserver_partition
*p
;
1436 struct dnsserver_partition_info
*partinfo
;
1437 struct DNS_RPC_DP_INFO
*dpinfo
= NULL
;
1439 if (typeid_in
!= DNSSRV_TYPEID_LPSTR
) {
1440 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1443 *typeid_out
= DNSSRV_TYPEID_DP_INFO
;
1445 for (p
= dsstate
->partitions
; p
; p
= p
->next
) {
1446 if (strcasecmp(p
->pszDpFqdn
, rin
->String
) == 0) {
1447 dpinfo
= talloc_zero(mem_ctx
, struct DNS_RPC_DP_INFO
);
1448 W_ERROR_HAVE_NO_MEMORY(dpinfo
);
1450 partinfo
= dnsserver_db_partition_info(mem_ctx
, dsstate
->samdb
, p
);
1451 W_ERROR_HAVE_NO_MEMORY(partinfo
);
1453 dpinfo
->pszDpFqdn
= talloc_strdup(dpinfo
, p
->pszDpFqdn
);
1454 dpinfo
->pszDpDn
= talloc_strdup(dpinfo
, ldb_dn_get_linearized(p
->partition_dn
));
1455 dpinfo
->pszCrDn
= talloc_steal(dpinfo
, partinfo
->pszCrDn
);
1456 dpinfo
->dwFlags
= p
->dwDpFlags
;
1457 dpinfo
->dwZoneCount
= p
->zones_count
;
1458 dpinfo
->dwState
= partinfo
->dwState
;
1459 dpinfo
->dwReplicaCount
= partinfo
->dwReplicaCount
;
1460 if (partinfo
->dwReplicaCount
> 0) {
1461 dpinfo
->ReplicaArray
= talloc_steal(dpinfo
,
1462 partinfo
->ReplicaArray
);
1464 dpinfo
->ReplicaArray
= NULL
;
1470 if (dpinfo
== NULL
) {
1471 return WERR_DNS_ERROR_DP_DOES_NOT_EXIST
;
1474 rout
->DirectoryPartition
= dpinfo
;
1476 } else if (strcasecmp(operation
, "Statistics") == 0) {
1477 valid_operation
= true;
1478 } else if (strcasecmp(operation
, "IpValidate") == 0) {
1479 valid_operation
= true;
1482 if (valid_operation
) {
1483 DEBUG(0, ("dnsserver: server complex operation '%s' not implemented", operation
));
1484 return WERR_CALL_NOT_IMPLEMENTED
;
1487 DEBUG(0, ("dnsserver: invalid server complex operation '%s'", operation
));
1488 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1491 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
1492 static WERROR
dnsserver_operate_zone(struct dnsserver_state
*dsstate
,
1493 TALLOC_CTX
*mem_ctx
,
1494 struct dnsserver_zone
*z
,
1495 unsigned int request_filter
,
1496 const char *operation
,
1497 const unsigned int client_version
,
1498 enum DNS_RPC_TYPEID
typeid,
1499 union DNSSRV_RPC_UNION
*r
)
1501 bool valid_operation
= false;
1503 if (strcasecmp(operation
, "ResetDwordProperty") == 0) {
1504 if (typeid != DNSSRV_TYPEID_NAME_AND_PARAM
) {
1505 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1508 /* Ignore property resets */
1509 if (strcasecmp(r
->NameAndParam
->pszNodeName
, "AllowUpdate") == 0) {
1512 valid_operation
= true;
1513 } else if (strcasecmp(operation
, "ZoneTypeReset") == 0) {
1514 valid_operation
= true;
1515 } else if (strcasecmp(operation
, "PauseZone") == 0) {
1516 valid_operation
= true;
1517 } else if (strcasecmp(operation
, "ResumeZone") == 0) {
1518 valid_operation
= true;
1519 } else if (strcasecmp(operation
, "DeleteZone") == 0) {
1520 valid_operation
= true;
1521 } else if (strcasecmp(operation
, "ReloadZone") == 0) {
1522 valid_operation
= true;
1523 } else if (strcasecmp(operation
, "RefreshZone") == 0) {
1524 valid_operation
= true;
1525 } else if (strcasecmp(operation
, "ExpireZone") == 0) {
1526 valid_operation
= true;
1527 } else if (strcasecmp(operation
, "IncrementVersion") == 0) {
1528 valid_operation
= true;
1529 } else if (strcasecmp(operation
, "WriteBackFile") == 0) {
1530 valid_operation
= true;
1531 } else if (strcasecmp(operation
, "DeleteZoneFromDs") == 0) {
1534 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
1536 status
= dnsserver_db_delete_zone(dsstate
->samdb
, z
);
1537 if (W_ERROR_IS_OK(status
)) {
1538 dnsserver_reload_zones(dsstate
);
1541 } else if (strcasecmp(operation
, "UpdateZoneFromDs") == 0) {
1542 valid_operation
= true;
1543 } else if (strcasecmp(operation
, "ZoneExport") == 0) {
1544 valid_operation
= true;
1545 } else if (strcasecmp(operation
, "ZoneChangeDirectoryPartition") == 0) {
1546 valid_operation
= true;
1547 } else if (strcasecmp(operation
, "DeleteNode") == 0) {
1548 valid_operation
= true;
1549 } else if (strcasecmp(operation
, "DeleteRecordSet") == 0) {
1550 valid_operation
= true;
1551 } else if (strcasecmp(operation
, "ForceAgingOnNode") == 0) {
1552 valid_operation
= true;
1553 } else if (strcasecmp(operation
, "DatabaseFile") == 0) {
1554 valid_operation
= true;
1555 } else if (strcasecmp(operation
, "MasterServers") == 0) {
1556 valid_operation
= true;
1557 } else if (strcasecmp(operation
, "LocalMasterServers") == 0) {
1558 valid_operation
= true;
1559 } else if (strcasecmp(operation
, "NotifyServers") == 0) {
1560 valid_operation
= true;
1561 } else if (strcasecmp(operation
, "SecondaryServers") == 0) {
1562 valid_operation
= true;
1563 } else if (strcasecmp(operation
, "ScavengingServers") == 0) {
1564 valid_operation
= true;
1565 } else if (strcasecmp(operation
, "AllowNSRecordsAutoCreation") == 0) {
1566 valid_operation
= true;
1567 } else if (strcasecmp(operation
, "BreakOnNameUpdate") == 0) {
1568 valid_operation
= true;
1569 } else if (strcasecmp(operation
, "ApplicationDirectoryPartition") == 0) {
1570 valid_operation
= true;
1573 if (valid_operation
) {
1574 DEBUG(0, ("dnsserver: zone operation '%s' not implemented", operation
));
1575 return WERR_CALL_NOT_IMPLEMENTED
;
1578 DEBUG(0, ("dnsserver: invalid zone operation '%s'", operation
));
1579 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1582 static WERROR
dnsserver_complex_operate_zone(struct dnsserver_state
*dsstate
,
1583 TALLOC_CTX
*mem_ctx
,
1584 struct dnsserver_zone
*z
,
1585 const char *operation
,
1586 const unsigned int client_version
,
1587 enum DNS_RPC_TYPEID typeid_in
,
1588 union DNSSRV_RPC_UNION
*rin
,
1589 enum DNS_RPC_TYPEID
*typeid_out
,
1590 union DNSSRV_RPC_UNION
*rout
)
1592 if (strcasecmp(operation
, "QueryDwordProperty") == 0) {
1593 if (typeid_in
== DNSSRV_TYPEID_LPSTR
) {
1594 return dnsserver_query_zone(dsstate
, mem_ctx
, z
,
1603 DEBUG(0,("dnsserver: Invalid zone operation %s", operation
));
1604 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1607 /* dnsserver enumerate function */
1609 static WERROR
dnsserver_enumerate_root_records(struct dnsserver_state
*dsstate
,
1610 TALLOC_CTX
*mem_ctx
,
1611 unsigned int client_version
,
1612 const char *node_name
,
1613 enum dns_record_type record_type
,
1614 unsigned int select_flag
,
1615 unsigned int *buffer_length
,
1616 struct DNS_RPC_RECORDS_ARRAY
**buffer
)
1618 TALLOC_CTX
*tmp_ctx
;
1619 struct dnsserver_zone
*z
;
1620 const char * const attrs
[] = { "name", "dnsRecord", NULL
};
1621 struct ldb_result
*res
;
1622 struct DNS_RPC_RECORDS_ARRAY
*recs
;
1629 tmp_ctx
= talloc_new(mem_ctx
);
1630 W_ERROR_HAVE_NO_MEMORY(tmp_ctx
);
1632 z
= dnsserver_find_zone(dsstate
->zones
, ".");
1634 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
1637 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1638 LDB_SCOPE_ONELEVEL
, attrs
,
1639 "(&(objectClass=dnsNode)(name=@)(!(dNSTombstoned=TRUE)))");
1640 if (ret
!= LDB_SUCCESS
) {
1641 talloc_free(tmp_ctx
);
1642 return WERR_INTERNAL_DB_ERROR
;
1644 if (res
->count
== 0) {
1645 talloc_free(tmp_ctx
);
1646 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
1649 recs
= talloc_zero(mem_ctx
, struct DNS_RPC_RECORDS_ARRAY
);
1650 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs
, tmp_ctx
);
1655 for (i
=0; i
<res
->count
; i
++) {
1656 status
= dns_fill_records_array(tmp_ctx
, NULL
, record_type
,
1658 res
->msgs
[i
], 0, recs
,
1659 &add_names
, &add_count
);
1660 if (!W_ERROR_IS_OK(status
)) {
1661 talloc_free(tmp_ctx
);
1667 /* Add any additional records */
1668 if (select_flag
& DNS_RPC_VIEW_ADDITIONAL_DATA
) {
1669 for (i
=0; i
<add_count
; i
++) {
1670 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1671 LDB_SCOPE_ONELEVEL
, attrs
,
1672 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1674 if (ret
!= LDB_SUCCESS
|| res
->count
== 0) {
1679 len
= strlen(add_names
[i
]);
1680 if (add_names
[i
][len
-1] == '.') {
1681 rname
= talloc_strdup(tmp_ctx
, add_names
[i
]);
1683 rname
= talloc_asprintf(tmp_ctx
, "%s.", add_names
[i
]);
1685 status
= dns_fill_records_array(tmp_ctx
, NULL
, DNS_TYPE_A
,
1687 res
->msgs
[0], 0, recs
,
1694 talloc_free(tmp_ctx
);
1696 *buffer_length
= ndr_size_DNS_RPC_RECORDS_ARRAY(recs
, 0);
1703 static WERROR
dnsserver_enumerate_records(struct dnsserver_state
*dsstate
,
1704 TALLOC_CTX
*mem_ctx
,
1705 struct dnsserver_zone
*z
,
1706 unsigned int client_version
,
1707 const char *node_name
,
1708 const char *start_child
,
1709 enum dns_record_type record_type
,
1710 unsigned int select_flag
,
1711 const char *filter_start
,
1712 const char *filter_stop
,
1713 unsigned int *buffer_length
,
1714 struct DNS_RPC_RECORDS_ARRAY
**buffer
)
1716 TALLOC_CTX
*tmp_ctx
;
1718 const char * const attrs
[] = { "name", "dnsRecord", NULL
};
1719 struct ldb_result
*res
;
1720 struct DNS_RPC_RECORDS_ARRAY
*recs
;
1721 char **add_names
= NULL
;
1726 struct dns_tree
*tree
, *base
, *node
;
1728 tmp_ctx
= talloc_new(mem_ctx
);
1729 W_ERROR_HAVE_NO_MEMORY(tmp_ctx
);
1731 name
= dns_split_node_name(tmp_ctx
, node_name
, z
->name
);
1732 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name
, tmp_ctx
);
1734 /* search all records under parent tree */
1735 if (strcasecmp(name
, z
->name
) == 0) {
1736 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1737 LDB_SCOPE_ONELEVEL
, attrs
,
1738 "(&(objectClass=dnsNode)(!(dNSTombstoned=TRUE)))");
1740 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1741 LDB_SCOPE_ONELEVEL
, attrs
,
1742 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s))(!(dNSTombstoned=TRUE)))",
1745 if (ret
!= LDB_SUCCESS
) {
1746 talloc_free(tmp_ctx
);
1747 return WERR_INTERNAL_DB_ERROR
;
1749 if (res
->count
== 0) {
1750 talloc_free(tmp_ctx
);
1751 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
1754 recs
= talloc_zero(mem_ctx
, struct DNS_RPC_RECORDS_ARRAY
);
1755 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs
, tmp_ctx
);
1757 /* Sort the names, so that the first record is the parent record */
1758 ldb_qsort(res
->msgs
, res
->count
, sizeof(struct ldb_message
*), name
,
1759 (ldb_qsort_cmp_fn_t
)dns_name_compare
);
1761 /* Build a tree of name components from dns name */
1762 if (strcasecmp(name
, z
->name
) == 0) {
1763 tree
= dns_build_tree(tmp_ctx
, "@", res
);
1765 tree
= dns_build_tree(tmp_ctx
, name
, res
);
1767 W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree
, tmp_ctx
);
1769 /* Find the parent record in the tree */
1771 while (base
->level
!= -1) {
1772 base
= base
->children
[0];
1775 /* Add the parent record with blank name */
1776 if (!(select_flag
& DNS_RPC_VIEW_ONLY_CHILDREN
)) {
1777 status
= dns_fill_records_array(tmp_ctx
, z
, record_type
,
1780 recs
, &add_names
, &add_count
);
1781 if (!W_ERROR_IS_OK(status
)) {
1782 talloc_free(tmp_ctx
);
1787 /* Add all the children records */
1788 if (!(select_flag
& DNS_RPC_VIEW_NO_CHILDREN
)) {
1789 for (i
=0; i
<base
->num_children
; i
++) {
1790 node
= base
->children
[i
];
1792 status
= dns_fill_records_array(tmp_ctx
, z
, record_type
,
1793 select_flag
, node
->name
,
1794 node
->data
, node
->num_children
,
1795 recs
, &add_names
, &add_count
);
1796 if (!W_ERROR_IS_OK(status
)) {
1797 talloc_free(tmp_ctx
);
1807 /* Add any additional records */
1808 if (select_flag
& DNS_RPC_VIEW_ADDITIONAL_DATA
) {
1809 for (i
=0; i
<add_count
; i
++) {
1810 struct dnsserver_zone
*z2
;
1812 /* Search all the available zones for additional name */
1813 for (z2
= dsstate
->zones
; z2
; z2
= z2
->next
) {
1814 name
= dns_split_node_name(tmp_ctx
, add_names
[i
], z2
->name
);
1815 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z2
->zone_dn
,
1816 LDB_SCOPE_ONELEVEL
, attrs
,
1817 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1820 if (ret
!= LDB_SUCCESS
) {
1823 if (res
->count
== 1) {
1831 len
= strlen(add_names
[i
]);
1832 if (add_names
[i
][len
-1] == '.') {
1833 rname
= talloc_strdup(tmp_ctx
, add_names
[i
]);
1835 rname
= talloc_asprintf(tmp_ctx
, "%s.", add_names
[i
]);
1837 status
= dns_fill_records_array(tmp_ctx
, NULL
, DNS_TYPE_A
,
1839 res
->msgs
[0], 0, recs
,
1846 *buffer_length
= ndr_size_DNS_RPC_RECORDS_ARRAY(recs
, 0);
1852 /* dnsserver update function */
1854 static WERROR
dnsserver_update_record(struct dnsserver_state
*dsstate
,
1855 TALLOC_CTX
*mem_ctx
,
1856 struct dnsserver_zone
*z
,
1857 unsigned int client_version
,
1858 const char *node_name
,
1859 struct DNS_RPC_RECORD_BUF
*add_buf
,
1860 struct DNS_RPC_RECORD_BUF
*del_buf
)
1862 TALLOC_CTX
*tmp_ctx
;
1866 tmp_ctx
= talloc_new(mem_ctx
);
1867 W_ERROR_HAVE_NO_MEMORY(tmp_ctx
);
1869 /* If node_name is @ or zone name, dns record is @ */
1870 if (strcmp(node_name
, "@") == 0 ||
1871 strcmp(node_name
, ".") == 0 ||
1872 strcasecmp(node_name
, z
->name
) == 0) {
1873 name
= talloc_strdup(tmp_ctx
, "@");
1875 name
= dns_split_node_name(tmp_ctx
, node_name
, z
->name
);
1877 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name
, tmp_ctx
);
1879 if (add_buf
!= NULL
) {
1880 if (del_buf
== NULL
) {
1882 status
= dnsserver_db_add_record(tmp_ctx
, dsstate
->samdb
,
1887 status
= dnsserver_db_update_record(tmp_ctx
, dsstate
->samdb
,
1893 if (del_buf
== NULL
) {
1894 /* Add empty node */
1895 status
= dnsserver_db_add_empty_node(tmp_ctx
, dsstate
->samdb
,
1899 status
= dnsserver_db_delete_record(tmp_ctx
, dsstate
->samdb
,
1905 talloc_free(tmp_ctx
);
1910 /* dnsserver interface functions */
1912 static WERROR
dcesrv_DnssrvOperation(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvOperation
*r
)
1914 struct dnsserver_state
*dsstate
;
1915 struct dnsserver_zone
*z
= NULL
;
1916 uint32_t request_filter
= 0;
1919 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
1920 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
1923 if (r
->in
.dwContext
== 0) {
1924 if (r
->in
.pszZone
!= NULL
) {
1925 request_filter
= dnsserver_zone_to_request_filter(r
->in
.pszZone
);
1928 request_filter
= r
->in
.dwContext
;
1931 if (r
->in
.pszZone
== NULL
) {
1932 ret
= dnsserver_operate_server(dsstate
, mem_ctx
,
1934 DNS_CLIENT_VERSION_W2K
,
1938 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
1939 if (z
== NULL
&& request_filter
== 0) {
1940 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
1943 ret
= dnsserver_operate_zone(dsstate
, mem_ctx
, z
,
1946 DNS_CLIENT_VERSION_W2K
,
1951 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
1952 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation
, NDR_IN
, r
);
1957 static WERROR
dcesrv_DnssrvQuery(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvQuery
*r
)
1959 struct dnsserver_state
*dsstate
;
1960 struct dnsserver_zone
*z
;
1963 ZERO_STRUCTP(r
->out
.pdwTypeId
);
1964 ZERO_STRUCTP(r
->out
.ppData
);
1966 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
1967 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
1970 if (r
->in
.pszZone
== NULL
) {
1971 /* FIXME: DNS Server Configuration Access Control List */
1972 ret
= dnsserver_query_server(dsstate
, mem_ctx
,
1974 DNS_CLIENT_VERSION_W2K
,
1978 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
1980 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
1983 ret
= dnsserver_query_zone(dsstate
, mem_ctx
, z
,
1985 DNS_CLIENT_VERSION_W2K
,
1990 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
1991 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery
, NDR_IN
, r
);
1996 static WERROR
dcesrv_DnssrvComplexOperation(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvComplexOperation
*r
)
1998 struct dnsserver_state
*dsstate
;
1999 struct dnsserver_zone
*z
;
2002 ZERO_STRUCTP(r
->out
.pdwTypeOut
);
2003 ZERO_STRUCTP(r
->out
.ppDataOut
);
2005 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2006 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2009 if (r
->in
.pszZone
== NULL
) {
2010 /* Server operation */
2011 ret
= dnsserver_complex_operate_server(dsstate
, mem_ctx
,
2013 DNS_CLIENT_VERSION_W2K
,
2019 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2021 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2024 ret
= dnsserver_complex_operate_zone(dsstate
, mem_ctx
, z
,
2026 DNS_CLIENT_VERSION_W2K
,
2033 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2034 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation
, NDR_IN
, r
);
2039 static WERROR
dcesrv_DnssrvEnumRecords(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvEnumRecords
*r
)
2041 struct dnsserver_state
*dsstate
;
2042 struct dnsserver_zone
*z
;
2045 ZERO_STRUCTP(r
->out
.pdwBufferLength
);
2046 ZERO_STRUCTP(r
->out
.pBuffer
);
2048 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2049 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2052 if (r
->in
.pszZone
== NULL
) {
2053 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2056 if (strcasecmp(r
->in
.pszZone
, "..RootHints") == 0) {
2057 ret
= dnsserver_enumerate_root_records(dsstate
, mem_ctx
,
2058 DNS_CLIENT_VERSION_W2K
,
2062 r
->out
.pdwBufferLength
,
2065 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2067 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2070 ret
= dnsserver_enumerate_records(dsstate
, mem_ctx
, z
,
2071 DNS_CLIENT_VERSION_W2K
,
2073 r
->in
.pszStartChild
,
2076 r
->in
.pszFilterStart
,
2077 r
->in
.pszFilterStop
,
2078 r
->out
.pdwBufferLength
,
2082 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2083 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords
, NDR_IN
, r
);
2088 static WERROR
dcesrv_DnssrvUpdateRecord(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvUpdateRecord
*r
)
2090 struct dnsserver_state
*dsstate
;
2091 struct dnsserver_zone
*z
;
2094 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2095 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2098 if (r
->in
.pszZone
== NULL
) {
2099 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2102 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2104 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2107 ret
= dnsserver_update_record(dsstate
, mem_ctx
, z
,
2108 DNS_CLIENT_VERSION_W2K
,
2111 r
->in
.pDeleteRecord
);
2113 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2114 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord
, NDR_IN
, r
);
2119 static WERROR
dcesrv_DnssrvOperation2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvOperation2
*r
)
2121 struct dnsserver_state
*dsstate
;
2122 struct dnsserver_zone
*z
= NULL
;
2123 uint32_t request_filter
= 0;
2126 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2127 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2130 if (r
->in
.dwContext
== 0) {
2131 if (r
->in
.pszZone
!= NULL
) {
2132 request_filter
= dnsserver_zone_to_request_filter(r
->in
.pszZone
);
2135 request_filter
= r
->in
.dwContext
;
2138 if (r
->in
.pszZone
== NULL
) {
2139 ret
= dnsserver_operate_server(dsstate
, mem_ctx
,
2141 r
->in
.dwClientVersion
,
2145 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2146 if (z
== NULL
&& request_filter
== 0) {
2147 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2150 ret
= dnsserver_operate_zone(dsstate
, mem_ctx
, z
,
2153 r
->in
.dwClientVersion
,
2158 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2159 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation2
, NDR_IN
, r
);
2164 static WERROR
dcesrv_DnssrvQuery2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvQuery2
*r
)
2166 struct dnsserver_state
*dsstate
;
2167 struct dnsserver_zone
*z
;
2170 ZERO_STRUCTP(r
->out
.pdwTypeId
);
2171 ZERO_STRUCTP(r
->out
.ppData
);
2173 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2174 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2177 if (r
->in
.pszZone
== NULL
) {
2178 /* FIXME: DNS Server Configuration Access Control List */
2179 ret
= dnsserver_query_server(dsstate
, mem_ctx
,
2181 r
->in
.dwClientVersion
,
2185 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2187 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2190 ret
= dnsserver_query_zone(dsstate
, mem_ctx
, z
,
2192 r
->in
.dwClientVersion
,
2197 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2198 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery2
, NDR_IN
, r
);
2203 static WERROR
dcesrv_DnssrvComplexOperation2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvComplexOperation2
*r
)
2205 struct dnsserver_state
*dsstate
;
2206 struct dnsserver_zone
*z
;
2209 ZERO_STRUCTP(r
->out
.pdwTypeOut
);
2210 ZERO_STRUCTP(r
->out
.ppDataOut
);
2212 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2213 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2216 if (r
->in
.pszZone
== NULL
) {
2217 /* Server operation */
2218 ret
= dnsserver_complex_operate_server(dsstate
, mem_ctx
,
2220 r
->in
.dwClientVersion
,
2227 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2229 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2232 ret
= dnsserver_complex_operate_zone(dsstate
, mem_ctx
, z
,
2234 r
->in
.dwClientVersion
,
2241 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2242 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation2
, NDR_IN
, r
);
2247 static WERROR
dcesrv_DnssrvEnumRecords2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvEnumRecords2
*r
)
2249 struct dnsserver_state
*dsstate
;
2250 struct dnsserver_zone
*z
;
2253 ZERO_STRUCTP(r
->out
.pdwBufferLength
);
2254 ZERO_STRUCTP(r
->out
.pBuffer
);
2256 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2257 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2260 if (r
->in
.pszZone
== NULL
) {
2261 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2264 if (strcasecmp(r
->in
.pszZone
, "..RootHints") == 0) {
2265 ret
= dnsserver_enumerate_root_records(dsstate
, mem_ctx
,
2266 r
->in
.dwClientVersion
,
2270 r
->out
.pdwBufferLength
,
2273 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2275 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2278 ret
= dnsserver_enumerate_records(dsstate
, mem_ctx
, z
,
2279 r
->in
.dwClientVersion
,
2281 r
->in
.pszStartChild
,
2284 r
->in
.pszFilterStart
,
2285 r
->in
.pszFilterStop
,
2286 r
->out
.pdwBufferLength
,
2291 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2292 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords2
, NDR_IN
, r
);
2297 static WERROR
dcesrv_DnssrvUpdateRecord2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvUpdateRecord2
*r
)
2299 struct dnsserver_state
*dsstate
;
2300 struct dnsserver_zone
*z
;
2303 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2304 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2307 if (r
->in
.pszZone
== NULL
) {
2308 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2311 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2313 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2316 ret
= dnsserver_update_record(dsstate
, mem_ctx
, z
,
2317 r
->in
.dwClientVersion
,
2320 r
->in
.pDeleteRecord
);
2322 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2323 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord2
, NDR_IN
, r
);
2328 /* include the generated boilerplate */
2329 #include "librpc/gen_ndr/ndr_dnsserver_s.c"