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"
30 struct dnsserver_state
{
31 struct loadparm_context
*lp_ctx
;
32 struct ldb_context
*samdb
;
33 struct dnsserver_partition
*partitions
;
34 struct dnsserver_zone
*zones
;
36 struct dnsserver_serverinfo
*serverinfo
;
40 /* Utility functions */
42 static void dnsserver_reload_zones(struct dnsserver_state
*dsstate
)
44 struct dnsserver_partition
*p
;
45 struct dnsserver_zone
*zones
, *z
, *znext
, *zmatch
;
46 struct dnsserver_zone
*old_list
, *new_list
;
48 old_list
= dsstate
->zones
;
51 for (p
= dsstate
->partitions
; p
; p
= p
->next
) {
52 zones
= dnsserver_db_enumerate_zones(dsstate
, dsstate
->samdb
, p
);
56 for (z
= zones
; z
; ) {
58 zmatch
= dnsserver_find_zone(old_list
, z
->name
);
61 z
->zoneinfo
= dnsserver_init_zoneinfo(z
, dsstate
->serverinfo
);
62 if (z
->zoneinfo
== NULL
) {
65 DLIST_ADD_END(new_list
, z
, NULL
);
67 dsstate
->zones_count
++;
71 DLIST_REMOVE(old_list
, zmatch
);
72 DLIST_ADD_END(new_list
, zmatch
, NULL
);
78 if (new_list
== NULL
) {
83 for (z
= old_list
; z
; ) {
85 z
->partition
->zones_count
--;
86 dsstate
->zones_count
--;
91 dsstate
->zones
= new_list
;
95 static struct dnsserver_state
*dnsserver_connect(struct dcesrv_call_state
*dce_call
)
97 struct dnsserver_state
*dsstate
;
98 struct dnsserver_zone
*zones
, *z
, *znext
;
99 struct dnsserver_partition
*partitions
, *p
;
101 dsstate
= talloc_get_type(dce_call
->context
->private_data
, struct dnsserver_state
);
102 if (dsstate
!= NULL
) {
106 dsstate
= talloc_zero(dce_call
->context
, struct dnsserver_state
);
107 if (dsstate
== NULL
) {
111 dsstate
->lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
113 /* FIXME: create correct auth_session_info for connecting user */
114 dsstate
->samdb
= samdb_connect(dsstate
, dce_call
->event_ctx
, dsstate
->lp_ctx
,
115 dce_call
->conn
->auth_state
.session_info
, 0);
116 if (dsstate
->samdb
== NULL
) {
117 DEBUG(0,("dnsserver: Failed to open samdb"));
121 /* Initialize server info */
122 dsstate
->serverinfo
= dnsserver_init_serverinfo(dsstate
,
125 if (dsstate
->serverinfo
== NULL
) {
129 /* Search for DNS partitions */
130 partitions
= dnsserver_db_enumerate_partitions(dsstate
, dsstate
->serverinfo
, dsstate
->samdb
);
131 if (partitions
== NULL
) {
134 dsstate
->partitions
= partitions
;
136 /* Search for DNS zones */
137 for (p
= partitions
; p
; p
= p
->next
) {
138 zones
= dnsserver_db_enumerate_zones(dsstate
, dsstate
->samdb
, p
);
142 for (z
= zones
; z
; ) {
144 if (dnsserver_find_zone(dsstate
->zones
, z
->name
) == NULL
) {
145 z
->zoneinfo
= dnsserver_init_zoneinfo(z
, dsstate
->serverinfo
);
146 if (z
->zoneinfo
== NULL
) {
149 DLIST_ADD_END(dsstate
->zones
, z
, NULL
);
151 dsstate
->zones_count
++;
153 /* Ignore duplicate zone */
154 DEBUG(3,("dnsserver: Ignoring duplicate zone '%s' from '%s'",
155 z
->name
, ldb_dn_get_linearized(z
->zone_dn
)));
161 dce_call
->context
->private_data
= dsstate
;
166 talloc_free(dsstate
);
172 /* dnsserver query functions */
174 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
175 static WERROR
dnsserver_query_server(struct dnsserver_state
*dsstate
,
177 const char *operation
,
178 const unsigned int client_version
,
179 enum DNS_RPC_TYPEID
*typeid,
180 union DNSSRV_RPC_UNION
*r
)
182 uint8_t is_integer
, is_addresses
, is_string
, is_wstring
, is_stringlist
;
183 uint32_t answer_integer
;
184 struct IP4_ARRAY
*answer_iparray
;
185 struct DNS_ADDR_ARRAY
*answer_addrarray
;
187 struct DNS_RPC_UTF8_STRING_LIST
*answer_stringlist
;
188 struct dnsserver_serverinfo
*serverinfo
;
190 serverinfo
= dsstate
->serverinfo
;
192 if (strcasecmp(operation
, "ServerInfo") == 0) {
193 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
194 *typeid = DNSSRV_TYPEID_SERVER_INFO_W2K
;
195 r
->ServerInfoW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_SERVER_INFO_W2K
);
197 r
->ServerInfoW2K
->dwVersion
= serverinfo
->dwVersion
;
198 r
->ServerInfoW2K
->fBootMethod
= serverinfo
->fBootMethod
;
199 r
->ServerInfoW2K
->fAdminConfigured
= serverinfo
->fAdminConfigured
;
200 r
->ServerInfoW2K
->fAllowUpdate
= serverinfo
->fAllowUpdate
;
201 r
->ServerInfoW2K
->fDsAvailable
= serverinfo
->fDsAvailable
;
202 r
->ServerInfoW2K
->pszServerName
= talloc_strdup(mem_ctx
, serverinfo
->pszServerName
);
203 r
->ServerInfoW2K
->pszDsContainer
= talloc_strdup(mem_ctx
, serverinfo
->pszDsContainer
);
204 r
->ServerInfoW2K
->aipServerAddrs
= dns_addr_array_to_ip4_array(mem_ctx
,
205 serverinfo
->aipServerAddrs
);
206 r
->ServerInfoW2K
->aipListenAddrs
= dns_addr_array_to_ip4_array(mem_ctx
,
207 serverinfo
->aipListenAddrs
);
208 r
->ServerInfoW2K
->aipForwarders
= ip4_array_copy(mem_ctx
, serverinfo
->aipForwarders
);
209 r
->ServerInfoW2K
->dwLogLevel
= serverinfo
->dwLogLevel
;
210 r
->ServerInfoW2K
->dwDebugLevel
= serverinfo
->dwDebugLevel
;
211 r
->ServerInfoW2K
->dwForwardTimeout
= serverinfo
->dwForwardTimeout
;
212 r
->ServerInfoW2K
->dwRpcProtocol
= serverinfo
->dwRpcProtocol
;
213 r
->ServerInfoW2K
->dwNameCheckFlag
= serverinfo
->dwNameCheckFlag
;
214 r
->ServerInfoW2K
->cAddressAnswerLimit
= serverinfo
->cAddressAnswerLimit
;
215 r
->ServerInfoW2K
->dwRecursionRetry
= serverinfo
->dwRecursionRetry
;
216 r
->ServerInfoW2K
->dwRecursionTimeout
= serverinfo
->dwRecursionTimeout
;
217 r
->ServerInfoW2K
->dwMaxCacheTtl
= serverinfo
->dwMaxCacheTtl
;
218 r
->ServerInfoW2K
->dwDsPollingInterval
= serverinfo
->dwDsPollingInterval
;
219 r
->ServerInfoW2K
->dwScavengingInterval
= serverinfo
->dwScavengingInterval
;
220 r
->ServerInfoW2K
->dwDefaultRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
221 r
->ServerInfoW2K
->dwDefaultNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
222 r
->ServerInfoW2K
->fAutoReverseZones
= serverinfo
->fAutoReverseZones
;
223 r
->ServerInfoW2K
->fAutoCacheUpdate
= serverinfo
->fAutoCacheUpdate
;
224 r
->ServerInfoW2K
->fRecurseAfterForwarding
= serverinfo
->fRecurseAfterForwarding
;
225 r
->ServerInfoW2K
->fForwardDelegations
= serverinfo
->fForwardDelegations
;
226 r
->ServerInfoW2K
->fNoRecursion
= serverinfo
->fNoRecursion
;
227 r
->ServerInfoW2K
->fSecureResponses
= serverinfo
->fSecureResponses
;
228 r
->ServerInfoW2K
->fRoundRobin
= serverinfo
->fRoundRobin
;
229 r
->ServerInfoW2K
->fLocalNetPriority
= serverinfo
->fLocalNetPriority
;
230 r
->ServerInfoW2K
->fBindSecondaries
= serverinfo
->fBindSecondaries
;
231 r
->ServerInfoW2K
->fWriteAuthorityNs
= serverinfo
->fWriteAuthorityNs
;
232 r
->ServerInfoW2K
->fStrictFileParsing
= serverinfo
->fStrictFileParsing
;
233 r
->ServerInfoW2K
->fLooseWildcarding
= serverinfo
->fLooseWildcarding
;
234 r
->ServerInfoW2K
->fDefaultAgingState
= serverinfo
->fDefaultAgingState
;
236 } else if (client_version
== DNS_CLIENT_VERSION_DOTNET
) {
237 *typeid = DNSSRV_TYPEID_SERVER_INFO_DOTNET
;
238 r
->ServerInfoDotNet
= talloc_zero(mem_ctx
, struct DNS_RPC_SERVER_INFO_DOTNET
);
240 r
->ServerInfoDotNet
->dwRpcStructureVersion
= 0x01;
241 r
->ServerInfoDotNet
->dwVersion
= serverinfo
->dwVersion
;
242 r
->ServerInfoDotNet
->fBootMethod
= serverinfo
->fBootMethod
;
243 r
->ServerInfoDotNet
->fAdminConfigured
= serverinfo
->fAdminConfigured
;
244 r
->ServerInfoDotNet
->fAllowUpdate
= serverinfo
->fAllowUpdate
;
245 r
->ServerInfoDotNet
->fDsAvailable
= serverinfo
->fDsAvailable
;
246 r
->ServerInfoDotNet
->pszServerName
= talloc_strdup(mem_ctx
, serverinfo
->pszServerName
);
247 r
->ServerInfoDotNet
->pszDsContainer
= talloc_strdup(mem_ctx
, serverinfo
->pszDsContainer
);
248 r
->ServerInfoDotNet
->aipServerAddrs
= dns_addr_array_to_ip4_array(mem_ctx
,
249 serverinfo
->aipServerAddrs
);
250 r
->ServerInfoDotNet
->aipListenAddrs
= dns_addr_array_to_ip4_array(mem_ctx
,
251 serverinfo
->aipListenAddrs
);
252 r
->ServerInfoDotNet
->aipForwarders
= ip4_array_copy(mem_ctx
, serverinfo
->aipForwarders
);
253 r
->ServerInfoDotNet
->aipLogFilter
= ip4_array_copy(mem_ctx
, serverinfo
->aipLogFilter
);
254 r
->ServerInfoDotNet
->pwszLogFilePath
= talloc_strdup(mem_ctx
, serverinfo
->pwszLogFilePath
);
255 r
->ServerInfoDotNet
->pszDomainName
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainName
);
256 r
->ServerInfoDotNet
->pszForestName
= talloc_strdup(mem_ctx
, serverinfo
->pszForestName
);
257 r
->ServerInfoDotNet
->pszDomainDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainDirectoryPartition
);
258 r
->ServerInfoDotNet
->pszForestDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszForestDirectoryPartition
);
259 r
->ServerInfoDotNet
->dwLogLevel
= serverinfo
->dwLogLevel
;
260 r
->ServerInfoDotNet
->dwDebugLevel
= serverinfo
->dwDebugLevel
;
261 r
->ServerInfoDotNet
->dwForwardTimeout
= serverinfo
->dwForwardTimeout
;
262 r
->ServerInfoDotNet
->dwRpcProtocol
= serverinfo
->dwRpcProtocol
;
263 r
->ServerInfoDotNet
->dwNameCheckFlag
= serverinfo
->dwNameCheckFlag
;
264 r
->ServerInfoDotNet
->cAddressAnswerLimit
= serverinfo
->cAddressAnswerLimit
;
265 r
->ServerInfoDotNet
->dwRecursionRetry
= serverinfo
->dwRecursionRetry
;
266 r
->ServerInfoDotNet
->dwRecursionTimeout
= serverinfo
->dwRecursionTimeout
;
267 r
->ServerInfoDotNet
->dwMaxCacheTtl
= serverinfo
->dwMaxCacheTtl
;
268 r
->ServerInfoDotNet
->dwDsPollingInterval
= serverinfo
->dwDsPollingInterval
;
269 r
->ServerInfoDotNet
->dwLocalNetPriorityNetMask
= serverinfo
->dwLocalNetPriorityNetMask
;
270 r
->ServerInfoDotNet
->dwScavengingInterval
= serverinfo
->dwScavengingInterval
;
271 r
->ServerInfoDotNet
->dwDefaultRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
272 r
->ServerInfoDotNet
->dwDefaultNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
273 r
->ServerInfoDotNet
->dwLastScavengeTime
= serverinfo
->dwLastScavengeTime
;
274 r
->ServerInfoDotNet
->dwEventLogLevel
= serverinfo
->dwEventLogLevel
;
275 r
->ServerInfoDotNet
->dwLogFileMaxSize
= serverinfo
->dwLogFileMaxSize
;
276 r
->ServerInfoDotNet
->dwDsForestVersion
= serverinfo
->dwDsForestVersion
;
277 r
->ServerInfoDotNet
->dwDsDomainVersion
= serverinfo
->dwDsDomainVersion
;
278 r
->ServerInfoDotNet
->dwDsDsaVersion
= serverinfo
->dwDsDsaVersion
;
279 r
->ServerInfoDotNet
->fAutoReverseZones
= serverinfo
->fAutoReverseZones
;
280 r
->ServerInfoDotNet
->fAutoCacheUpdate
= serverinfo
->fAutoCacheUpdate
;
281 r
->ServerInfoDotNet
->fRecurseAfterForwarding
= serverinfo
->fRecurseAfterForwarding
;
282 r
->ServerInfoDotNet
->fForwardDelegations
= serverinfo
->fForwardDelegations
;
283 r
->ServerInfoDotNet
->fNoRecursion
= serverinfo
->fNoRecursion
;
284 r
->ServerInfoDotNet
->fSecureResponses
= serverinfo
->fSecureResponses
;
285 r
->ServerInfoDotNet
->fRoundRobin
= serverinfo
->fRoundRobin
;
286 r
->ServerInfoDotNet
->fLocalNetPriority
= serverinfo
->fLocalNetPriority
;
287 r
->ServerInfoDotNet
->fBindSecondaries
= serverinfo
->fBindSecondaries
;
288 r
->ServerInfoDotNet
->fWriteAuthorityNs
= serverinfo
->fWriteAuthorityNs
;
289 r
->ServerInfoDotNet
->fStrictFileParsing
= serverinfo
->fStrictFileParsing
;
290 r
->ServerInfoDotNet
->fLooseWildcarding
= serverinfo
->fLooseWildcarding
;
291 r
->ServerInfoDotNet
->fDefaultAgingState
= serverinfo
->fDefaultAgingState
;
293 } else if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
294 *typeid = DNSSRV_TYPEID_SERVER_INFO
;
295 r
->ServerInfo
= talloc_zero(mem_ctx
, struct DNS_RPC_SERVER_INFO_LONGHORN
);
297 r
->ServerInfo
->dwRpcStructureVersion
= 0x02;
298 r
->ServerInfo
->dwVersion
= serverinfo
->dwVersion
;
299 r
->ServerInfo
->fBootMethod
= serverinfo
->fBootMethod
;
300 r
->ServerInfo
->fAdminConfigured
= serverinfo
->fAdminConfigured
;
301 r
->ServerInfo
->fAllowUpdate
= serverinfo
->fAllowUpdate
;
302 r
->ServerInfo
->fDsAvailable
= serverinfo
->fDsAvailable
;
303 r
->ServerInfo
->pszServerName
= talloc_strdup(mem_ctx
, serverinfo
->pszServerName
);
304 r
->ServerInfo
->pszDsContainer
= talloc_strdup(mem_ctx
, serverinfo
->pszDsContainer
);
305 r
->ServerInfo
->aipServerAddrs
= serverinfo
->aipServerAddrs
;
306 r
->ServerInfo
->aipListenAddrs
= serverinfo
->aipListenAddrs
;
307 r
->ServerInfo
->aipForwarders
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipForwarders
);
308 r
->ServerInfo
->aipLogFilter
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipLogFilter
);
309 r
->ServerInfo
->pwszLogFilePath
= talloc_strdup(mem_ctx
, serverinfo
->pwszLogFilePath
);
310 r
->ServerInfo
->pszDomainName
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainName
);
311 r
->ServerInfo
->pszForestName
= talloc_strdup(mem_ctx
, serverinfo
->pszForestName
);
312 r
->ServerInfo
->pszDomainDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainDirectoryPartition
);
313 r
->ServerInfo
->pszForestDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszForestDirectoryPartition
);
314 r
->ServerInfo
->dwLogLevel
= serverinfo
->dwLogLevel
;
315 r
->ServerInfo
->dwDebugLevel
= serverinfo
->dwDebugLevel
;
316 r
->ServerInfo
->dwForwardTimeout
= serverinfo
->dwForwardTimeout
;
317 r
->ServerInfo
->dwRpcProtocol
= serverinfo
->dwRpcProtocol
;
318 r
->ServerInfo
->dwNameCheckFlag
= serverinfo
->dwNameCheckFlag
;
319 r
->ServerInfo
->cAddressAnswerLimit
= serverinfo
->cAddressAnswerLimit
;
320 r
->ServerInfo
->dwRecursionRetry
= serverinfo
->dwRecursionRetry
;
321 r
->ServerInfo
->dwRecursionTimeout
= serverinfo
->dwRecursionTimeout
;
322 r
->ServerInfo
->dwMaxCacheTtl
= serverinfo
->dwMaxCacheTtl
;
323 r
->ServerInfo
->dwDsPollingInterval
= serverinfo
->dwDsPollingInterval
;
324 r
->ServerInfo
->dwLocalNetPriorityNetMask
= serverinfo
->dwLocalNetPriorityNetMask
;
325 r
->ServerInfo
->dwScavengingInterval
= serverinfo
->dwScavengingInterval
;
326 r
->ServerInfo
->dwDefaultRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
327 r
->ServerInfo
->dwDefaultNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
328 r
->ServerInfo
->dwLastScavengeTime
= serverinfo
->dwLastScavengeTime
;
329 r
->ServerInfo
->dwEventLogLevel
= serverinfo
->dwEventLogLevel
;
330 r
->ServerInfo
->dwLogFileMaxSize
= serverinfo
->dwLogFileMaxSize
;
331 r
->ServerInfo
->dwDsForestVersion
= serverinfo
->dwDsForestVersion
;
332 r
->ServerInfo
->dwDsDomainVersion
= serverinfo
->dwDsDomainVersion
;
333 r
->ServerInfo
->dwDsDsaVersion
= serverinfo
->dwDsDsaVersion
;
334 r
->ServerInfo
->fReadOnlyDC
= serverinfo
->fReadOnlyDC
;
335 r
->ServerInfo
->fAutoReverseZones
= serverinfo
->fAutoReverseZones
;
336 r
->ServerInfo
->fAutoCacheUpdate
= serverinfo
->fAutoCacheUpdate
;
337 r
->ServerInfo
->fRecurseAfterForwarding
= serverinfo
->fRecurseAfterForwarding
;
338 r
->ServerInfo
->fForwardDelegations
= serverinfo
->fForwardDelegations
;
339 r
->ServerInfo
->fNoRecursion
= serverinfo
->fNoRecursion
;
340 r
->ServerInfo
->fSecureResponses
= serverinfo
->fSecureResponses
;
341 r
->ServerInfo
->fRoundRobin
= serverinfo
->fRoundRobin
;
342 r
->ServerInfo
->fLocalNetPriority
= serverinfo
->fLocalNetPriority
;
343 r
->ServerInfo
->fBindSecondaries
= serverinfo
->fBindSecondaries
;
344 r
->ServerInfo
->fWriteAuthorityNs
= serverinfo
->fWriteAuthorityNs
;
345 r
->ServerInfo
->fStrictFileParsing
= serverinfo
->fStrictFileParsing
;
346 r
->ServerInfo
->fLooseWildcarding
= serverinfo
->fLooseWildcarding
;
347 r
->ServerInfo
->fDefaultAgingState
= serverinfo
->fDefaultAgingState
;
354 if (strcasecmp(operation
, "AddressAnswerLimit") == 0) {
355 answer_integer
= serverinfo
->cAddressAnswerLimit
;
357 } else if (strcasecmp(operation
, "AdminConfigured") == 0) {
358 answer_integer
= serverinfo
->fAdminConfigured
;
360 } else if (strcasecmp(operation
, "AllowCNAMEAtNS") == 0) {
363 } else if (strcasecmp(operation
, "AllowUpdate") == 0) {
364 answer_integer
= serverinfo
->fAllowUpdate
;
366 } else if (strcasecmp(operation
, "AutoCacheUpdate") == 0) {
367 answer_integer
= serverinfo
->fAutoCacheUpdate
;
369 } else if (strcasecmp(operation
, "AutoConfigFileZones") == 0) {
372 } else if (strcasecmp(operation
, "BindSecondaries") == 0) {
373 answer_integer
= serverinfo
->fBindSecondaries
;
375 } else if (strcasecmp(operation
, "BootMethod") == 0) {
376 answer_integer
= serverinfo
->fBootMethod
;
378 } else if (strcasecmp(operation
, "DebugLevel") == 0) {
379 answer_integer
= serverinfo
->dwDebugLevel
;
381 } else if (strcasecmp(operation
, "DefaultAgingState") == 0) {
382 answer_integer
= serverinfo
->fDefaultAgingState
;
384 } else if (strcasecmp(operation
, "DefaultNoRefreshInterval") == 0) {
385 answer_integer
= serverinfo
->dwDefaultNoRefreshInterval
;
387 } else if (strcasecmp(operation
, "DefaultRefreshInterval") == 0) {
388 answer_integer
= serverinfo
->dwDefaultRefreshInterval
;
390 } else if (strcasecmp(operation
, "DeleteOutsideGlue") == 0) {
393 } else if (strcasecmp(operation
, "DisjointNets") == 0) {
396 } else if (strcasecmp(operation
, "DsLazyUpdateInterval") == 0) {
397 answer_integer
= 3; /* seconds */
399 } else if (strcasecmp(operation
, "DsPollingInterval") == 0) {
400 answer_integer
= serverinfo
->dwDsPollingInterval
;
402 } else if (strcasecmp(operation
, "DsTombstoneInterval") == 0) {
403 answer_integer
= 0x00127500; /* 14 days */
405 } else if (strcasecmp(operation
, "EnableRegistryBoot") == 0) {
408 } else if (strcasecmp(operation
, "EventLogLevel") == 0) {
409 answer_integer
= serverinfo
->dwEventLogLevel
;
411 } else if (strcasecmp(operation
, "ForceSoaSerial") == 0) {
414 } else if (strcasecmp(operation
, "ForceSaoRetry") == 0) {
417 } else if (strcasecmp(operation
, "ForceSoaRefresh") == 0) {
420 } else if (strcasecmp(operation
, "ForceSoaMinimumTtl") == 0) {
423 } else if (strcasecmp(operation
, "ForwardDelegations") == 0) {
426 } else if (strcasecmp(operation
, "ForwardingTimeout") == 0) {
427 answer_integer
= serverinfo
->dwForwardTimeout
;
429 } else if (strcasecmp(operation
, "IsSlave") == 0) {
432 } else if (strcasecmp(operation
, "LocalNetPriority") == 0) {
433 answer_integer
= serverinfo
->fLocalNetPriority
;
435 } else if (strcasecmp(operation
, "LogFileMaxSize") == 0) {
436 answer_integer
= serverinfo
->dwLogFileMaxSize
;
438 } else if (strcasecmp(operation
, "LogLevel") == 0) {
439 answer_integer
= serverinfo
->dwLogLevel
;
441 } else if (strcasecmp(operation
, "LooseWildcarding") == 0) {
442 answer_integer
= serverinfo
->fLooseWildcarding
;
444 } else if (strcasecmp(operation
, "MaxCacheTtl") == 0) {
445 answer_integer
= serverinfo
->dwMaxCacheTtl
;
447 } else if (strcasecmp(operation
, "MaxNegativeCacheTtl") == 0) {
448 answer_integer
= 0x00000384; /* 15 minutes */
450 } else if (strcasecmp(operation
, "NameCheckFlag") == 0) {
451 answer_integer
= serverinfo
->dwNameCheckFlag
;
453 } else if (strcasecmp(operation
, "NoRecursion") == 0) {
454 answer_integer
= serverinfo
->fNoRecursion
;
456 } else if (strcasecmp(operation
, "NoUpdateDelegations") == 0) {
459 } else if (strcasecmp(operation
, "PublishAutonet") == 0) {
462 } else if (strcasecmp(operation
, "QuietRecvFaultInterval") == 0) {
465 } else if (strcasecmp(operation
, "QuietRecvLogInterval") == 0) {
468 } else if (strcasecmp(operation
, "RecursionRetry") == 0) {
469 answer_integer
= serverinfo
->dwRecursionRetry
;
471 } else if (strcasecmp(operation
, "RecursionTimeout") == 0) {
472 answer_integer
= serverinfo
->dwRecursionTimeout
;
474 } else if (strcasecmp(operation
, "ReloadException") == 0) {
477 } else if (strcasecmp(operation
, "RoundRobin") == 0) {
478 answer_integer
= serverinfo
->fRoundRobin
;
480 } else if (strcasecmp(operation
, "RpcProtocol") == 0) {
481 answer_integer
= serverinfo
->dwRpcProtocol
;
483 } else if (strcasecmp(operation
, "SecureResponses") == 0) {
484 answer_integer
= serverinfo
->fSecureResponses
;
486 } else if (strcasecmp(operation
, "SendPort") == 0) {
489 } else if (strcasecmp(operation
, "ScavengingInterval") == 0) {
490 answer_integer
= serverinfo
->dwScavengingInterval
;
492 } else if (strcasecmp(operation
, "SocketPoolSize") == 0) {
493 answer_integer
= 0x000009C4;
495 } else if (strcasecmp(operation
, "StrictFileParsing") == 0) {
496 answer_integer
= serverinfo
->fStrictFileParsing
;
498 } else if (strcasecmp(operation
, "SyncDnsZoneSerial") == 0) {
499 answer_integer
= 2; /* ZONE_SERIAL_SYNC_XFER */
501 } else if (strcasecmp(operation
, "UpdateOptions") == 0) {
502 answer_integer
= 0x0000030F; /* DNS_DEFAULT_UPDATE_OPTIONS */
504 } else if (strcasecmp(operation
, "UseSystemEvengLog") == 0) {
507 } else if (strcasecmp(operation
, "Version") == 0) {
508 answer_integer
= serverinfo
->dwVersion
;
510 } else if (strcasecmp(operation
, "XfrConnectTimeout") == 0) {
511 answer_integer
= 0x0000001E;
513 } else if (strcasecmp(operation
, "WriteAuthorityNs") == 0) {
514 answer_integer
= serverinfo
->fWriteAuthorityNs
;
516 } else if (strcasecmp(operation
, "AdditionalRecursionTimeout") == 0) {
517 answer_integer
= 0x00000004;
519 } else if (strcasecmp(operation
, "AppendMsZoneTransferFlag") == 0) {
522 } else if (strcasecmp(operation
, "AutoCreateDelegations") == 0) {
523 answer_integer
= 0; /* DNS_ACD_DONT_CREATE */
525 } else if (strcasecmp(operation
, "BreakOnAscFailure") == 0) {
528 } else if (strcasecmp(operation
, "CacheEmptyAuthResponses") == 0) {
531 } else if (strcasecmp(operation
, "DirectoryPartitionAutoEnlistInterval") == 0) {
532 answer_integer
= 0x00015180; /* 1 day */
534 } else if (strcasecmp(operation
, "DisableAutoReverseZones") == 0) {
535 answer_integer
= ~serverinfo
->fAutoReverseZones
;
537 } else if (strcasecmp(operation
, "EDnsCacheTimeout") == 0) {
538 answer_integer
= 0x00000384; /* 15 minutes */
540 } else if (strcasecmp(operation
, "EnableDirectoryPartitions") == 0) {
541 answer_integer
= serverinfo
->fDsAvailable
;
543 } else if (strcasecmp(operation
, "EnableDnsSec") == 0) {
546 } else if (strcasecmp(operation
, "EnableEDnsProbes") == 0) {
549 } else if (strcasecmp(operation
, "EnableEDnsReception") == 0) {
552 } else if (strcasecmp(operation
, "EnableIPv6") == 0) {
555 } else if (strcasecmp(operation
, "EnableIQueryResponseGeneration") == 0) {
558 } else if (strcasecmp(operation
, "EnableSendErrorSuppression") == 0) {
561 } else if (strcasecmp(operation
, "EnableUpdateForwarding") == 0) {
564 } else if (strcasecmp(operation
, "EnableWinsR") == 0) {
567 } else if (strcasecmp(operation
, "ForceDsaBehaviorVersion") == 0) {
568 answer_integer
= serverinfo
->dwDsDsaVersion
;
570 } else if (strcasecmp(operation
, "ForceDomainBehaviorVersion") == 0) {
571 answer_integer
= serverinfo
->dwDsDsaVersion
;
573 } else if (strcasecmp(operation
, "ForceForestBehaviorVersion") == 0) {
574 answer_integer
= serverinfo
->dwDsDsaVersion
;
576 } else if (strcasecmp(operation
, "HeapDebug") == 0) {
579 } else if (strcasecmp(operation
, "LameDelegationTtl") == 0) {
580 answer_integer
= 0; /* seconds */
582 } else if (strcasecmp(operation
, "LocalNetPriorityNetMask") == 0) {
583 answer_integer
= serverinfo
->dwLocalNetPriorityNetMask
;
585 } else if (strcasecmp(operation
, "MaxCacheSize") == 0) {
588 } else if (strcasecmp(operation
, "MaxResourceRecordsInNonSecureUpdate") == 0) {
589 answer_integer
= 0x0000001E;
591 } else if (strcasecmp(operation
, "OperationsLogLevel") == 0) {
594 } else if (strcasecmp(operation
, "OperationsLogLevel2") == 0) {
597 } else if (strcasecmp(operation
, "MaximumUdpPacketSize") == 0) {
598 answer_integer
= 0x00004000; /* maximum possible */
600 } else if (strcasecmp(operation
, "RecurseToInternetRootMask") == 0) {
603 } else if (strcasecmp(operation
, "SelfTest") == 0) {
606 } else if (strcasecmp(operation
, "SilentlyIgnoreCNameUpdateConflicts") == 0) {
609 } else if (strcasecmp(operation
, "TcpReceivePacketSize") == 0) {
610 answer_integer
= 0x00010000;
612 } else if (strcasecmp(operation
, "XfrThrottleMultiplier") == 0) {
613 answer_integer
= 0x0000000A;
615 } else if (strcasecmp(operation
, "AllowMsdcsLookupRetry") == 0) {
618 } else if (strcasecmp(operation
, "AllowReadOnlyZoneTransfer") == 0) {
621 } else if (strcasecmp(operation
, "DsBackGroundLoadPaused") == 0) {
624 } else if (strcasecmp(operation
, "DsMinimumBackgroundLoadThreads") == 0) {
627 } else if (strcasecmp(operation
, "DsRemoteReplicationDelay") == 0) {
628 answer_integer
= 0x0000001E; /* 30 seconds */
630 } else if (strcasecmp(operation
, "EnableDuplicateQuerySuppresion") == 0) {
633 } else if (strcasecmp(operation
, "EnableGlobalNamesSupport") == 0) {
636 } else if (strcasecmp(operation
, "EnableVersionQuery") == 0) {
637 answer_integer
= 1; /* DNS_VERSION_QUERY_FULL */
639 } else if (strcasecmp(operation
, "EnableRsoForRodc") == 0) {
642 } else if (strcasecmp(operation
, "ForceRODCMode") == 0) {
645 } else if (strcasecmp(operation
, "GlobalNamesAlwaysQuerySrv") == 0) {
648 } else if (strcasecmp(operation
, "GlobalNamesBlockUpdates") == 0) {
651 } else if (strcasecmp(operation
, "GlobalNamesEnableEDnsProbes") == 0) {
654 } else if (strcasecmp(operation
, "GlobalNamesPreferAAAA") == 0) {
657 } else if (strcasecmp(operation
, "GlobalNamesQueryOrder") == 0) {
660 } else if (strcasecmp(operation
, "GlobalNamesSendTimeout") == 0) {
661 answer_integer
= 3; /* seconds */
663 } else if (strcasecmp(operation
, "GlobalNamesServerQueryInterval") == 0) {
664 answer_integer
= 0x00005460; /* 6 hours */
666 } else if (strcasecmp(operation
, "RemoteIPv4RankBoost") == 0) {
669 } else if (strcasecmp(operation
, "RemoteIPv6RankBoost") == 0) {
672 } else if (strcasecmp(operation
, "MaximumRodcRsoAttemptsPerCycle") == 0) {
673 answer_integer
= 0x00000064;
675 } else if (strcasecmp(operation
, "MaximumRodcRsoQueueLength") == 0) {
676 answer_integer
= 0x0000012C;
678 } else if (strcasecmp(operation
, "EnableGlobalQueryBlockList") == 0) {
681 } else if (strcasecmp(operation
, "OpenACLOnProxyUpdates") == 0) {
684 } else if (strcasecmp(operation
, "CacheLockingPercent") == 0) {
685 answer_integer
= 0x00000064;
689 if (is_integer
== 1) {
690 *typeid = DNSSRV_TYPEID_DWORD
;
691 r
->Dword
= answer_integer
;
697 if (strcasecmp(operation
, "Forwarders") == 0) {
698 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
699 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipForwarders
);
701 answer_iparray
= ip4_array_copy(mem_ctx
, serverinfo
->aipForwarders
);
704 } else if (strcasecmp(operation
, "ListenAddresses") == 0) {
705 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
706 answer_addrarray
= serverinfo
->aipListenAddrs
;
708 answer_iparray
= dns_addr_array_to_ip4_array(mem_ctx
, serverinfo
->aipListenAddrs
);
711 } else if (strcasecmp(operation
, "BreakOnReceiveFrom") == 0) {
712 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
713 answer_addrarray
= NULL
;
715 answer_iparray
= NULL
;
718 } else if (strcasecmp(operation
, "BreakOnUpdateFrom") == 0) {
719 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
720 answer_addrarray
= NULL
;
722 answer_iparray
= NULL
;
725 } else if (strcasecmp(operation
, "LogIPFilterList") == 0) {
726 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
727 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipLogFilter
);
729 answer_iparray
= ip4_array_copy(mem_ctx
, serverinfo
->aipLogFilter
);
734 if (is_addresses
== 1) {
735 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
736 *typeid = DNSSRV_TYPEID_ADDRARRAY
;
737 r
->AddrArray
= answer_addrarray
;
739 *typeid = DNSSRV_TYPEID_IPARRAY
;
740 r
->IpArray
= answer_iparray
;
745 is_string
= is_wstring
= 0;
747 if (strcasecmp(operation
, "DomainDirectoryPartitionBaseName") == 0) {
748 answer_string
= talloc_strdup(mem_ctx
, "DomainDnsZones");
749 if (! answer_string
) {
750 return WERR_OUTOFMEMORY
;
753 } else if (strcasecmp(operation
, "ForestDirectoryPartitionBaseName") == 0) {
754 answer_string
= talloc_strdup(mem_ctx
, "ForestDnsZones");
755 if (! answer_string
) {
756 return WERR_OUTOFMEMORY
;
759 } else if (strcasecmp(operation
, "LogFilePath") == 0) {
760 answer_string
= talloc_strdup(mem_ctx
, serverinfo
->pwszLogFilePath
);
762 } else if (strcasecmp(operation
, "ServerLevelPluginDll") == 0) {
763 answer_string
= NULL
;
765 } else if (strcasecmp(operation
, "DsBackgroundPauseName") == 0) {
766 answer_string
= NULL
;
768 } else if (strcasecmp(operation
, "DsNotRoundRobinTypes") == 0) {
769 answer_string
= NULL
;
773 if (is_string
== 1) {
774 *typeid = DNSSRV_TYPEID_LPSTR
;
775 r
->String
= answer_string
;
777 } else if (is_wstring
== 1) {
778 *typeid = DNSSRV_TYPEID_LPWSTR
;
779 r
->WideString
= answer_string
;
785 if (strcasecmp(operation
, "GlobalQueryBlockList") == 0) {
786 answer_stringlist
= NULL
;
788 } else if (strcasecmp(operation
, "SocketPoolExcludedPortRanges") == 0) {
789 answer_stringlist
= NULL
;
793 if (is_stringlist
== 1) {
794 *typeid = DNSSRV_TYPEID_UTF8_STRING_LIST
;
795 r
->Utf8StringList
= answer_stringlist
;
799 DEBUG(0,("dnsserver: Invalid server operation %s", operation
));
800 return WERR_DNS_ERROR_INVALID_PROPERTY
;
803 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
804 static WERROR
dnsserver_query_zone(struct dnsserver_state
*dsstate
,
806 struct dnsserver_zone
*z
,
807 const char *operation
,
808 const unsigned int client_version
,
809 enum DNS_RPC_TYPEID
*typeid,
810 union DNSSRV_RPC_UNION
*r
)
812 uint8_t is_integer
, is_addresses
, is_string
;
813 uint32_t answer_integer
;
814 struct IP4_ARRAY
*answer_iparray
;
815 struct DNS_ADDR_ARRAY
*answer_addrarray
;
817 struct dnsserver_zoneinfo
*zoneinfo
;
819 zoneinfo
= z
->zoneinfo
;
821 if (strcasecmp(operation
, "Zone") == 0) {
822 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
823 *typeid = DNSSRV_TYPEID_ZONE_W2K
;
824 r
->ZoneW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_W2K
);
826 r
->ZoneW2K
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
827 r
->ZoneW2K
->Flags
= zoneinfo
->Flags
;
828 r
->ZoneW2K
->ZoneType
= zoneinfo
->dwZoneType
;
829 r
->ZoneW2K
->Version
= zoneinfo
->Version
;
831 *typeid = DNSSRV_TYPEID_ZONE
;
832 r
->Zone
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_DOTNET
);
834 r
->Zone
->dwRpcStructureVersion
= 0x01;
835 r
->Zone
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
836 r
->Zone
->Flags
= zoneinfo
->Flags
;
837 r
->Zone
->ZoneType
= zoneinfo
->dwZoneType
;
838 r
->Zone
->Version
= zoneinfo
->Version
;
839 r
->Zone
->dwDpFlags
= z
->partition
->dwDpFlags
;
840 r
->Zone
->pszDpFqdn
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
845 if (strcasecmp(operation
, "ZoneInfo") == 0) {
846 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
847 *typeid = DNSSRV_TYPEID_ZONE_INFO_W2K
;
848 r
->ZoneInfoW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_INFO_W2K
);
850 r
->ZoneInfoW2K
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
851 r
->ZoneInfoW2K
->dwZoneType
= zoneinfo
->dwZoneType
;
852 r
->ZoneInfoW2K
->fReverse
= zoneinfo
->fReverse
;
853 r
->ZoneInfoW2K
->fAllowUpdate
= zoneinfo
->fAllowUpdate
;
854 r
->ZoneInfoW2K
->fPaused
= zoneinfo
->fPaused
;
855 r
->ZoneInfoW2K
->fShutdown
= zoneinfo
->fShutdown
;
856 r
->ZoneInfoW2K
->fAutoCreated
= zoneinfo
->fAutoCreated
;
857 r
->ZoneInfoW2K
->fUseDatabase
= zoneinfo
->fUseDatabase
;
858 r
->ZoneInfoW2K
->pszDataFile
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
859 r
->ZoneInfoW2K
->aipMasters
= ip4_array_copy(mem_ctx
, zoneinfo
->aipMasters
);
860 r
->ZoneInfoW2K
->fSecureSecondaries
= zoneinfo
->fSecureSecondaries
;
861 r
->ZoneInfoW2K
->fNotifyLevel
= zoneinfo
->fNotifyLevel
;
862 r
->ZoneInfoW2K
->aipSecondaries
= ip4_array_copy(mem_ctx
, zoneinfo
->aipSecondaries
);
863 r
->ZoneInfoW2K
->aipNotify
= ip4_array_copy(mem_ctx
, zoneinfo
->aipNotify
);
864 r
->ZoneInfoW2K
->fUseWins
= zoneinfo
->fUseWins
;
865 r
->ZoneInfoW2K
->fUseNbstat
= zoneinfo
->fUseNbstat
;
866 r
->ZoneInfoW2K
->fAging
= zoneinfo
->fAging
;
867 r
->ZoneInfoW2K
->dwNoRefreshInterval
= zoneinfo
->dwNoRefreshInterval
;
868 r
->ZoneInfoW2K
->dwRefreshInterval
= zoneinfo
->dwRefreshInterval
;
869 r
->ZoneInfoW2K
->dwAvailForScavengeTime
= zoneinfo
->dwAvailForScavengeTime
;
870 r
->ZoneInfoW2K
->aipScavengeServers
= ip4_array_copy(mem_ctx
, zoneinfo
->aipScavengeServers
);
872 } else if (client_version
== DNS_CLIENT_VERSION_DOTNET
) {
873 *typeid = DNSSRV_TYPEID_ZONE_INFO_DOTNET
;
874 r
->ZoneInfoDotNet
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_INFO_DOTNET
);
876 r
->ZoneInfoDotNet
->dwRpcStructureVersion
= 0x01;
877 r
->ZoneInfoDotNet
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
878 r
->ZoneInfoDotNet
->dwZoneType
= zoneinfo
->dwZoneType
;
879 r
->ZoneInfoDotNet
->fReverse
= zoneinfo
->fReverse
;
880 r
->ZoneInfoDotNet
->fAllowUpdate
= zoneinfo
->fAllowUpdate
;
881 r
->ZoneInfoDotNet
->fPaused
= zoneinfo
->fPaused
;
882 r
->ZoneInfoDotNet
->fShutdown
= zoneinfo
->fShutdown
;
883 r
->ZoneInfoDotNet
->fAutoCreated
= zoneinfo
->fAutoCreated
;
884 r
->ZoneInfoDotNet
->fUseDatabase
= zoneinfo
->fUseDatabase
;
885 r
->ZoneInfoDotNet
->pszDataFile
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
886 r
->ZoneInfoDotNet
->aipMasters
= ip4_array_copy(mem_ctx
, zoneinfo
->aipMasters
);
887 r
->ZoneInfoDotNet
->fSecureSecondaries
= zoneinfo
->fSecureSecondaries
;
888 r
->ZoneInfoDotNet
->fNotifyLevel
= zoneinfo
->fNotifyLevel
;
889 r
->ZoneInfoDotNet
->aipSecondaries
= ip4_array_copy(mem_ctx
, zoneinfo
->aipSecondaries
);
890 r
->ZoneInfoDotNet
->aipNotify
= ip4_array_copy(mem_ctx
, zoneinfo
->aipNotify
);
891 r
->ZoneInfoDotNet
->fUseWins
= zoneinfo
->fUseWins
;
892 r
->ZoneInfoDotNet
->fUseNbstat
= zoneinfo
->fUseNbstat
;
893 r
->ZoneInfoDotNet
->fAging
= zoneinfo
->fAging
;
894 r
->ZoneInfoDotNet
->dwNoRefreshInterval
= zoneinfo
->dwNoRefreshInterval
;
895 r
->ZoneInfoDotNet
->dwRefreshInterval
= zoneinfo
->dwRefreshInterval
;
896 r
->ZoneInfoDotNet
->dwAvailForScavengeTime
= zoneinfo
->dwAvailForScavengeTime
;
897 r
->ZoneInfoDotNet
->aipScavengeServers
= ip4_array_copy(mem_ctx
, zoneinfo
->aipScavengeServers
);
898 r
->ZoneInfoDotNet
->dwForwarderTimeout
= zoneinfo
->dwForwarderTimeout
;
899 r
->ZoneInfoDotNet
->fForwarderSlave
= zoneinfo
->fForwarderSlave
;
900 r
->ZoneInfoDotNet
->aipLocalMasters
= ip4_array_copy(mem_ctx
, zoneinfo
->aipLocalMasters
);
901 r
->ZoneInfoDotNet
->dwDpFlags
= z
->partition
->dwDpFlags
;
902 r
->ZoneInfoDotNet
->pszDpFqdn
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
903 r
->ZoneInfoDotNet
->pwszZoneDn
= talloc_strdup(mem_ctx
, zoneinfo
->pwszZoneDn
);
904 r
->ZoneInfoDotNet
->dwLastSuccessfulSoaCheck
= zoneinfo
->dwLastSuccessfulSoaCheck
;
905 r
->ZoneInfoDotNet
->dwLastSuccessfulXfr
= zoneinfo
->dwLastSuccessfulXfr
;
908 *typeid = DNSSRV_TYPEID_ZONE_INFO
;
909 r
->ZoneInfo
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_INFO_LONGHORN
);
911 r
->ZoneInfo
->dwRpcStructureVersion
= 0x02;
912 r
->ZoneInfo
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
913 r
->ZoneInfo
->dwZoneType
= zoneinfo
->dwZoneType
;
914 r
->ZoneInfo
->fReverse
= zoneinfo
->fReverse
;
915 r
->ZoneInfo
->fAllowUpdate
= zoneinfo
->fAllowUpdate
;
916 r
->ZoneInfo
->fPaused
= zoneinfo
->fPaused
;
917 r
->ZoneInfo
->fShutdown
= zoneinfo
->fShutdown
;
918 r
->ZoneInfo
->fAutoCreated
= zoneinfo
->fAutoCreated
;
919 r
->ZoneInfo
->fUseDatabase
= zoneinfo
->fUseDatabase
;
920 r
->ZoneInfo
->pszDataFile
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
921 r
->ZoneInfo
->aipMasters
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipMasters
);
922 r
->ZoneInfo
->fSecureSecondaries
= zoneinfo
->fSecureSecondaries
;
923 r
->ZoneInfo
->fNotifyLevel
= zoneinfo
->fNotifyLevel
;
924 r
->ZoneInfo
->aipSecondaries
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipSecondaries
);
925 r
->ZoneInfo
->aipNotify
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipNotify
);
926 r
->ZoneInfo
->fUseWins
= zoneinfo
->fUseWins
;
927 r
->ZoneInfo
->fUseNbstat
= zoneinfo
->fUseNbstat
;
928 r
->ZoneInfo
->fAging
= zoneinfo
->fAging
;
929 r
->ZoneInfo
->dwNoRefreshInterval
= zoneinfo
->dwNoRefreshInterval
;
930 r
->ZoneInfo
->dwRefreshInterval
= zoneinfo
->dwRefreshInterval
;
931 r
->ZoneInfo
->dwAvailForScavengeTime
= zoneinfo
->dwAvailForScavengeTime
;
932 r
->ZoneInfo
->aipScavengeServers
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipScavengeServers
);
933 r
->ZoneInfo
->dwForwarderTimeout
= zoneinfo
->dwForwarderTimeout
;
934 r
->ZoneInfo
->fForwarderSlave
= zoneinfo
->fForwarderSlave
;
935 r
->ZoneInfo
->aipLocalMasters
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipLocalMasters
);
936 r
->ZoneInfo
->dwDpFlags
= z
->partition
->dwDpFlags
;
937 r
->ZoneInfo
->pszDpFqdn
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
938 r
->ZoneInfo
->pwszZoneDn
= talloc_strdup(mem_ctx
, zoneinfo
->pwszZoneDn
);
939 r
->ZoneInfo
->dwLastSuccessfulSoaCheck
= zoneinfo
->dwLastSuccessfulSoaCheck
;
940 r
->ZoneInfo
->dwLastSuccessfulXfr
= zoneinfo
->dwLastSuccessfulXfr
;
942 r
->ZoneInfo
->fQueuedForBackgroundLoad
= zoneinfo
->fQueuedForBackgroundLoad
;
943 r
->ZoneInfo
->fBackgroundLoadInProgress
= zoneinfo
->fBackgroundLoadInProgress
;
944 r
->ZoneInfo
->fReadOnlyZone
= zoneinfo
->fReadOnlyZone
;
945 r
->ZoneInfo
->dwLastXfrAttempt
= zoneinfo
->dwLastXfrAttempt
;
946 r
->ZoneInfo
->dwLastXfrResult
= zoneinfo
->dwLastXfrResult
;
954 if (strcasecmp(operation
, "AllowUpdate") == 0) {
955 answer_integer
= zoneinfo
->fAllowUpdate
;
957 } else if (strcasecmp(operation
, "Secured") == 0) {
960 } else if (strcasecmp(operation
, "DsIntegrated") == 0) {
961 answer_integer
= zoneinfo
->fUseDatabase
;
963 } else if (strcasecmp(operation
, "LogUpdates") == 0) {
966 } else if (strcasecmp(operation
, "NoRefreshInterval") == 0) {
967 answer_integer
= zoneinfo
->dwNoRefreshInterval
;
969 } else if (strcasecmp(operation
, "NotifyLevel") == 0) {
970 answer_integer
= zoneinfo
->fNotifyLevel
;
972 } else if (strcasecmp(operation
, "RefreshInterval") == 0) {
973 answer_integer
= zoneinfo
->dwRefreshInterval
;
975 } else if (strcasecmp(operation
, "SecureSecondaries") == 0) {
976 answer_integer
= zoneinfo
->fSecureSecondaries
;
978 } else if (strcasecmp(operation
, "Type") == 0) {
979 answer_integer
= zoneinfo
->dwZoneType
;
981 } else if (strcasecmp(operation
, "Aging") == 0) {
982 answer_integer
= zoneinfo
->fAging
;
984 } else if (strcasecmp(operation
, "ForwarderSlave") == 0) {
985 answer_integer
= zoneinfo
->fForwarderSlave
;
987 } else if (strcasecmp(operation
, "ForwarderTimeout") == 0) {
988 answer_integer
= zoneinfo
->dwForwarderTimeout
;
990 } else if (strcasecmp(operation
, "Unicode") == 0) {
995 if (is_integer
== 1) {
996 *typeid = DNSSRV_TYPEID_DWORD
;
997 r
->Dword
= answer_integer
;
1003 if (strcasecmp(operation
, "AllowNSRecordsAutoCreation") == 0) {
1004 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1005 answer_addrarray
= NULL
;
1007 answer_iparray
= NULL
;
1010 } else if (strcasecmp(operation
, "ScavengeServers") == 0) {
1011 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1012 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipScavengeServers
);
1014 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipScavengeServers
);
1017 } else if (strcasecmp(operation
, "MasterServers") == 0) {
1018 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1019 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipMasters
);
1021 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipMasters
);
1024 } else if (strcasecmp(operation
, "LocalMasterServers") == 0) {
1025 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1026 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipLocalMasters
);
1028 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipLocalMasters
);
1031 } else if (strcasecmp(operation
, "NotifyServers") == 0) {
1032 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1033 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipNotify
);
1035 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipNotify
);
1038 } else if (strcasecmp(operation
, "SecondaryServers") == 0) {
1039 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1040 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipSecondaries
);
1042 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipSecondaries
);
1047 if (is_addresses
== 1) {
1048 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1049 *typeid = DNSSRV_TYPEID_ADDRARRAY
;
1050 r
->AddrArray
= answer_addrarray
;
1052 *typeid = DNSSRV_TYPEID_IPARRAY
;
1053 r
->IpArray
= answer_iparray
;
1060 if (strcasecmp(operation
, "DatabaseFile") == 0) {
1061 answer_string
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
1063 } else if (strcasecmp(operation
, "ApplicationDirectoryPartition") == 0) {
1064 answer_string
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
1066 } else if (strcasecmp(operation
, "BreakOnNameUpdate") == 0) {
1067 answer_string
= NULL
;
1071 if (is_string
== 1) {
1072 *typeid = DNSSRV_TYPEID_LPSTR
;
1073 r
->String
= answer_string
;
1077 DEBUG(0,("dnsserver: Invalid zone operation %s", operation
));
1078 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1082 /* dnsserver operation functions */
1084 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
1085 static WERROR
dnsserver_operate_server(struct dnsserver_state
*dsstate
,
1086 TALLOC_CTX
*mem_ctx
,
1087 const char *operation
,
1088 const unsigned int client_version
,
1089 enum DNS_RPC_TYPEID
typeid,
1090 union DNSSRV_RPC_UNION
*r
)
1092 bool valid_operation
= false;
1094 if (strcasecmp(operation
, "ResetDwordProperty") == 0) {
1095 valid_operation
= true;
1096 } else if (strcasecmp(operation
, "Restart") == 0) {
1097 valid_operation
= true;
1098 } else if (strcasecmp(operation
, "ClearDebugLog") == 0) {
1099 valid_operation
= true;
1100 } else if (strcasecmp(operation
, "ClearCache") == 0) {
1101 valid_operation
= true;
1102 } else if (strcasecmp(operation
, "WriteDirtyZones") == 0) {
1103 valid_operation
= true;
1104 } else if (strcasecmp(operation
, "ZoneCreate") == 0) {
1105 struct dnsserver_zone
*z
, *z2
;
1108 z
= talloc_zero(mem_ctx
, struct dnsserver_zone
);
1109 W_ERROR_HAVE_NO_MEMORY(z
);
1110 z
->partition
= talloc_zero(z
, struct dnsserver_partition
);
1111 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z
->partition
, z
);
1112 z
->zoneinfo
= talloc_zero(z
, struct dnsserver_zoneinfo
);
1113 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z
->zoneinfo
, z
);
1115 if (typeid == DNSSRV_TYPEID_ZONE_CREATE_W2K
) {
1116 z
->name
= talloc_strdup(z
, r
->ZoneCreateW2K
->pszZoneName
);
1117 z
->zoneinfo
->dwZoneType
= r
->ZoneCreateW2K
->dwZoneType
;
1118 z
->zoneinfo
->fAllowUpdate
= r
->ZoneCreateW2K
->fAllowUpdate
;
1119 z
->zoneinfo
->fAging
= r
->ZoneCreateW2K
->fAging
;
1120 z
->zoneinfo
->Flags
= r
->ZoneCreateW2K
->dwFlags
;
1121 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE_DOTNET
) {
1122 z
->name
= talloc_strdup(z
, r
->ZoneCreateDotNet
->pszZoneName
);
1123 z
->zoneinfo
->dwZoneType
= r
->ZoneCreateDotNet
->dwZoneType
;
1124 z
->zoneinfo
->fAllowUpdate
= r
->ZoneCreateDotNet
->fAllowUpdate
;
1125 z
->zoneinfo
->fAging
= r
->ZoneCreateDotNet
->fAging
;
1126 z
->zoneinfo
->Flags
= r
->ZoneCreateDotNet
->dwFlags
;
1127 z
->partition
->dwDpFlags
= r
->ZoneCreateDotNet
->dwDpFlags
;
1128 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE
) {
1129 z
->name
= talloc_strdup(z
, r
->ZoneCreate
->pszZoneName
);
1130 z
->zoneinfo
->dwZoneType
= r
->ZoneCreate
->dwZoneType
;
1131 z
->zoneinfo
->fAllowUpdate
= r
->ZoneCreate
->fAllowUpdate
;
1132 z
->zoneinfo
->fAging
= r
->ZoneCreate
->fAging
;
1133 z
->zoneinfo
->Flags
= r
->ZoneCreate
->dwFlags
;
1134 z
->partition
->dwDpFlags
= r
->ZoneCreate
->dwDpFlags
;
1137 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1140 z2
= dnsserver_find_zone(dsstate
->zones
, z
->name
);
1143 return WERR_DNS_ERROR_ZONE_ALREADY_EXISTS
;
1146 status
= dnsserver_db_create_zone(dsstate
->samdb
, dsstate
->partitions
, z
,
1150 if (W_ERROR_IS_OK(status
)) {
1151 dnsserver_reload_zones(dsstate
);
1154 } else if (strcasecmp(operation
, "ClearStatistics") == 0) {
1155 valid_operation
= true;
1156 } else if (strcasecmp(operation
, "EnlistDirectoryPartition") == 0) {
1157 valid_operation
= true;
1158 } else if (strcasecmp(operation
, "StartScavenging") == 0) {
1159 valid_operation
= true;
1160 } else if (strcasecmp(operation
, "AbortScavenging") == 0) {
1161 valid_operation
= true;
1162 } else if (strcasecmp(operation
, "AutoConfigure") == 0) {
1163 valid_operation
= true;
1164 } else if (strcasecmp(operation
, "ExportSettings") == 0) {
1165 valid_operation
= true;
1166 } else if (strcasecmp(operation
, "PrepareForDemotion") == 0) {
1167 valid_operation
= true;
1168 } else if (strcasecmp(operation
, "PrepareForUninstall") == 0) {
1169 valid_operation
= true;
1170 } else if (strcasecmp(operation
, "DeleteNode") == 0) {
1171 valid_operation
= true;
1172 } else if (strcasecmp(operation
, "DeleteRecord") == 0) {
1173 valid_operation
= true;
1174 } else if (strcasecmp(operation
, "WriteBackFile") == 0) {
1175 valid_operation
= true;
1176 } else if (strcasecmp(operation
, "ListenAddresses") == 0) {
1177 valid_operation
= true;
1178 } else if (strcasecmp(operation
, "Forwarders") == 0) {
1179 valid_operation
= true;
1180 } else if (strcasecmp(operation
, "LogFilePath") == 0) {
1181 valid_operation
= true;
1182 } else if (strcasecmp(operation
, "LogIpFilterList") == 0) {
1183 valid_operation
= true;
1184 } else if (strcasecmp(operation
, "ForestDirectoryPartitionBaseName") == 0) {
1185 valid_operation
= true;
1186 } else if (strcasecmp(operation
, "DomainDirectoryPartitionBaseName") == 0) {
1187 valid_operation
= true;
1188 } else if (strcasecmp(operation
, "GlobalQueryBlockList") == 0) {
1189 valid_operation
= true;
1190 } else if (strcasecmp(operation
, "BreakOnReceiveFrom") == 0) {
1191 valid_operation
= true;
1192 } else if (strcasecmp(operation
, "BreakOnUpdateFrom") == 0) {
1193 valid_operation
= true;
1194 } else if (strcasecmp(operation
, "ServerLevelPluginDll") == 0) {
1195 valid_operation
= true;
1198 if (valid_operation
) {
1199 DEBUG(0, ("dnsserver: server operation '%s' not implemented", operation
));
1200 return WERR_CALL_NOT_IMPLEMENTED
;
1203 DEBUG(0, ("dnsserver: invalid server operation '%s'", operation
));
1204 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1207 static WERROR
dnsserver_complex_operate_server(struct dnsserver_state
*dsstate
,
1208 TALLOC_CTX
*mem_ctx
,
1209 const char *operation
,
1210 const unsigned int client_version
,
1211 enum DNS_RPC_TYPEID typeid_in
,
1212 union DNSSRV_RPC_UNION
*rin
,
1213 enum DNS_RPC_TYPEID
*typeid_out
,
1214 union DNSSRV_RPC_UNION
*rout
)
1216 int valid_operation
= 0;
1217 struct dnsserver_zone
*z
, **zlist
;
1219 bool found1
, found2
, found3
, found4
;
1222 if (strcasecmp(operation
, "QueryDwordProperty") == 0) {
1223 if (typeid_in
== DNSSRV_TYPEID_LPSTR
) {
1224 return dnsserver_query_server(dsstate
, mem_ctx
,
1230 } else if (strcasecmp(operation
, "EnumZones") == 0) {
1231 if (typeid_in
!= DNSSRV_TYPEID_DWORD
) {
1232 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1236 zlist
= talloc_zero_array(mem_ctx
, struct dnsserver_zone
*, 0);
1237 for (z
= dsstate
->zones
; z
; z
= z
->next
) {
1239 /* Match the flags in groups
1241 * Group1 : PRIMARY, SECONDARY, CACHE, AUTO
1242 * Group2 : FORWARD, REVERSE, FORWARDER, STUB
1243 * Group3 : DS, NON_DS, DOMAIN_DP, FOREST_DP
1244 * Group4 : CUSTOM_DP, LEGACY_DP
1249 if (rin
->Dword
& 0x0000000f) {
1250 if (rin
->Dword
& DNS_ZONE_REQUEST_PRIMARY
) {
1251 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_PRIMARY
) {
1255 if (rin
->Dword
& DNS_ZONE_REQUEST_SECONDARY
) {
1256 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_SECONDARY
) {
1260 if (rin
->Dword
& DNS_ZONE_REQUEST_CACHE
) {
1261 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_CACHE
) {
1265 if (rin
->Dword
& DNS_ZONE_REQUEST_AUTO
) {
1266 if (z
->zoneinfo
->fAutoCreated
1267 || z
->partition
->dwDpFlags
& DNS_DP_AUTOCREATED
) {
1277 if (rin
->Dword
& 0x000000f0) {
1278 if (rin
->Dword
& DNS_ZONE_REQUEST_FORWARD
) {
1279 if (!(z
->zoneinfo
->fReverse
)) {
1283 if (rin
->Dword
& DNS_ZONE_REQUEST_REVERSE
) {
1284 if (z
->zoneinfo
->fReverse
) {
1288 if (rin
->Dword
& DNS_ZONE_REQUEST_FORWARDER
) {
1289 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_FORWARDER
) {
1293 if (rin
->Dword
& DNS_ZONE_REQUEST_STUB
) {
1294 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_STUB
) {
1304 if (rin
->Dword
& 0x00000f00) {
1305 if (rin
->Dword
& DNS_ZONE_REQUEST_DS
) {
1306 if (z
->zoneinfo
->Flags
& DNS_RPC_ZONE_DSINTEGRATED
) {
1310 if (rin
->Dword
& DNS_ZONE_REQUEST_NON_DS
) {
1311 if (!(z
->zoneinfo
->Flags
& DNS_RPC_ZONE_DSINTEGRATED
)) {
1315 if (rin
->Dword
& DNS_ZONE_REQUEST_DOMAIN_DP
) {
1316 if (!(z
->partition
->dwDpFlags
& DNS_DP_DOMAIN_DEFAULT
)) {
1320 if (rin
->Dword
& DNS_ZONE_REQUEST_FOREST_DP
) {
1321 if (!(z
->partition
->dwDpFlags
& DNS_DP_FOREST_DEFAULT
)) {
1330 if (rin
->Dword
& 0x0000f000) {
1336 if (found1
&& found2
&& found3
&& found4
) {
1337 zlist
= talloc_realloc(mem_ctx
, zlist
, struct dnsserver_zone
*, zcount
+1);
1343 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
1344 *typeid_out
= DNSSRV_TYPEID_ZONE_LIST_W2K
;
1345 rout
->ZoneListW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_LIST_W2K
);
1348 rout
->ZoneListW2K
->dwZoneCount
= 0;
1349 rout
->ZoneListW2K
->ZoneArray
= NULL
;
1354 rout
->ZoneListW2K
->ZoneArray
= talloc_zero_array(mem_ctx
, struct DNS_RPC_ZONE_W2K
*, zcount
);
1355 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout
->ZoneListW2K
->ZoneArray
, zlist
);
1357 for (i
=0; i
<zcount
; i
++) {
1358 rout
->ZoneListW2K
->ZoneArray
[i
] = talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_W2K
);
1360 rout
->ZoneListW2K
->ZoneArray
[i
]->pszZoneName
= talloc_strdup(mem_ctx
, zlist
[i
]->name
);
1361 rout
->ZoneListW2K
->ZoneArray
[i
]->Flags
= zlist
[i
]->zoneinfo
->Flags
;
1362 rout
->ZoneListW2K
->ZoneArray
[i
]->ZoneType
= zlist
[i
]->zoneinfo
->dwZoneType
;
1363 rout
->ZoneListW2K
->ZoneArray
[i
]->Version
= zlist
[i
]->zoneinfo
->Version
;
1365 rout
->ZoneListW2K
->dwZoneCount
= zcount
;
1368 *typeid_out
= DNSSRV_TYPEID_ZONE_LIST
;
1369 rout
->ZoneList
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_LIST_DOTNET
);
1372 rout
->ZoneList
->dwRpcStructureVersion
= 1;
1373 rout
->ZoneList
->dwZoneCount
= 0;
1374 rout
->ZoneList
->ZoneArray
= NULL
;
1379 rout
->ZoneList
->ZoneArray
= talloc_zero_array(mem_ctx
, struct DNS_RPC_ZONE_DOTNET
*, zcount
);
1380 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout
->ZoneList
->ZoneArray
, zlist
);
1382 for (i
=0; i
<zcount
; i
++) {
1383 rout
->ZoneList
->ZoneArray
[i
] = talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_DOTNET
);
1385 rout
->ZoneList
->ZoneArray
[i
]->dwRpcStructureVersion
= 1;
1386 rout
->ZoneList
->ZoneArray
[i
]->pszZoneName
= talloc_strdup(mem_ctx
, zlist
[i
]->name
);
1387 rout
->ZoneList
->ZoneArray
[i
]->Flags
= zlist
[i
]->zoneinfo
->Flags
;
1388 rout
->ZoneList
->ZoneArray
[i
]->ZoneType
= zlist
[i
]->zoneinfo
->dwZoneType
;
1389 rout
->ZoneList
->ZoneArray
[i
]->Version
= zlist
[i
]->zoneinfo
->Version
;
1390 rout
->ZoneList
->ZoneArray
[i
]->dwDpFlags
= zlist
[i
]->partition
->dwDpFlags
;
1391 rout
->ZoneList
->ZoneArray
[i
]->pszDpFqdn
= talloc_strdup(mem_ctx
, zlist
[i
]->partition
->pszDpFqdn
);
1393 rout
->ZoneList
->dwRpcStructureVersion
= 1;
1394 rout
->ZoneList
->dwZoneCount
= zcount
;
1398 } else if (strcasecmp(operation
, "EnumZones2") == 0) {
1399 valid_operation
= true;
1400 } else if (strcasecmp(operation
, "EnumDirectoryPartitions") == 0) {
1401 if (typeid_in
!= DNSSRV_TYPEID_DWORD
) {
1402 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1405 *typeid_out
= DNSSRV_TYPEID_DP_LIST
;
1406 rout
->DirectoryPartitionList
= talloc_zero(mem_ctx
, struct DNS_RPC_DP_LIST
);
1408 if (rin
->Dword
!= 0) {
1409 rout
->DirectoryPartitionList
->dwDpCount
= 0;
1410 rout
->DirectoryPartitionList
->DpArray
= NULL
;
1412 struct DNS_RPC_DP_ENUM
**dplist
;
1413 struct dnsserver_partition
*p
;
1416 dplist
= talloc_zero_array(mem_ctx
, struct DNS_RPC_DP_ENUM
*, pcount
);
1417 W_ERROR_HAVE_NO_MEMORY(dplist
);
1419 p
= dsstate
->partitions
;
1420 for (i
=0; i
<pcount
; i
++) {
1421 dplist
[i
] = talloc_zero(dplist
, struct DNS_RPC_DP_ENUM
);
1423 dplist
[i
]->pszDpFqdn
= talloc_strdup(mem_ctx
, p
->pszDpFqdn
);
1424 dplist
[i
]->dwFlags
= p
->dwDpFlags
;
1425 dplist
[i
]->dwZoneCount
= p
->zones_count
;
1429 rout
->DirectoryPartitionList
->dwDpCount
= pcount
;
1430 rout
->DirectoryPartitionList
->DpArray
= dplist
;
1433 } else if (strcasecmp(operation
, "DirectoryPartitionInfo") == 0) {
1434 struct dnsserver_partition
*p
;
1435 struct dnsserver_partition_info
*partinfo
;
1436 struct DNS_RPC_DP_INFO
*dpinfo
= NULL
;
1438 if (typeid_in
!= DNSSRV_TYPEID_LPSTR
) {
1439 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1442 *typeid_out
= DNSSRV_TYPEID_DP_INFO
;
1444 for (p
= dsstate
->partitions
; p
; p
= p
->next
) {
1445 if (strcasecmp(p
->pszDpFqdn
, rin
->String
) == 0) {
1446 dpinfo
= talloc_zero(mem_ctx
, struct DNS_RPC_DP_INFO
);
1447 W_ERROR_HAVE_NO_MEMORY(dpinfo
);
1449 partinfo
= dnsserver_db_partition_info(mem_ctx
, dsstate
->samdb
, p
);
1450 W_ERROR_HAVE_NO_MEMORY(partinfo
);
1452 dpinfo
->pszDpFqdn
= talloc_strdup(dpinfo
, p
->pszDpFqdn
);
1453 dpinfo
->pszDpDn
= talloc_strdup(dpinfo
, ldb_dn_get_linearized(p
->partition_dn
));
1454 dpinfo
->pszCrDn
= talloc_steal(dpinfo
, partinfo
->pszCrDn
);
1455 dpinfo
->dwFlags
= p
->dwDpFlags
;
1456 dpinfo
->dwZoneCount
= p
->zones_count
;
1457 dpinfo
->dwState
= partinfo
->dwState
;
1458 dpinfo
->dwReplicaCount
= partinfo
->dwReplicaCount
;
1459 if (partinfo
->dwReplicaCount
> 0) {
1460 dpinfo
->ReplicaArray
= talloc_steal(dpinfo
,
1461 partinfo
->ReplicaArray
);
1463 dpinfo
->ReplicaArray
= NULL
;
1469 if (dpinfo
== NULL
) {
1470 return WERR_DNS_ERROR_DP_DOES_NOT_EXIST
;
1473 rout
->DirectoryPartition
= dpinfo
;
1475 } else if (strcasecmp(operation
, "Statistics") == 0) {
1476 valid_operation
= true;
1477 } else if (strcasecmp(operation
, "IpValidate") == 0) {
1478 valid_operation
= true;
1481 if (valid_operation
) {
1482 DEBUG(0, ("dnsserver: server complex operation '%s' not implemented", operation
));
1483 return WERR_CALL_NOT_IMPLEMENTED
;
1486 DEBUG(0, ("dnsserver: invalid server complex operation '%s'", operation
));
1487 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1490 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
1491 static WERROR
dnsserver_operate_zone(struct dnsserver_state
*dsstate
,
1492 TALLOC_CTX
*mem_ctx
,
1493 struct dnsserver_zone
*z
,
1494 unsigned int request_filter
,
1495 const char *operation
,
1496 const unsigned int client_version
,
1497 enum DNS_RPC_TYPEID
typeid,
1498 union DNSSRV_RPC_UNION
*r
)
1500 bool valid_operation
= false;
1502 if (strcasecmp(operation
, "ResetDwordProperty") == 0) {
1503 if (typeid != DNSSRV_TYPEID_NAME_AND_PARAM
) {
1504 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1507 /* Ignore property resets */
1508 if (strcasecmp(r
->NameAndParam
->pszNodeName
, "AllowUpdate") == 0) {
1511 valid_operation
= true;
1512 } else if (strcasecmp(operation
, "ZoneTypeReset") == 0) {
1513 valid_operation
= true;
1514 } else if (strcasecmp(operation
, "PauseZone") == 0) {
1515 valid_operation
= true;
1516 } else if (strcasecmp(operation
, "ResumeZone") == 0) {
1517 valid_operation
= true;
1518 } else if (strcasecmp(operation
, "DeleteZone") == 0) {
1519 valid_operation
= true;
1520 } else if (strcasecmp(operation
, "ReloadZone") == 0) {
1521 valid_operation
= true;
1522 } else if (strcasecmp(operation
, "RefreshZone") == 0) {
1523 valid_operation
= true;
1524 } else if (strcasecmp(operation
, "ExpireZone") == 0) {
1525 valid_operation
= true;
1526 } else if (strcasecmp(operation
, "IncrementVersion") == 0) {
1527 valid_operation
= true;
1528 } else if (strcasecmp(operation
, "WriteBackFile") == 0) {
1529 valid_operation
= true;
1530 } else if (strcasecmp(operation
, "DeleteZoneFromDs") == 0) {
1533 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
1535 status
= dnsserver_db_delete_zone(dsstate
->samdb
, z
);
1536 if (W_ERROR_IS_OK(status
)) {
1537 dnsserver_reload_zones(dsstate
);
1540 } else if (strcasecmp(operation
, "UpdateZoneFromDs") == 0) {
1541 valid_operation
= true;
1542 } else if (strcasecmp(operation
, "ZoneExport") == 0) {
1543 valid_operation
= true;
1544 } else if (strcasecmp(operation
, "ZoneChangeDirectoryPartition") == 0) {
1545 valid_operation
= true;
1546 } else if (strcasecmp(operation
, "DeleteNode") == 0) {
1547 valid_operation
= true;
1548 } else if (strcasecmp(operation
, "DeleteRecordSet") == 0) {
1549 valid_operation
= true;
1550 } else if (strcasecmp(operation
, "ForceAgingOnNode") == 0) {
1551 valid_operation
= true;
1552 } else if (strcasecmp(operation
, "DatabaseFile") == 0) {
1553 valid_operation
= true;
1554 } else if (strcasecmp(operation
, "MasterServers") == 0) {
1555 valid_operation
= true;
1556 } else if (strcasecmp(operation
, "LocalMasterServers") == 0) {
1557 valid_operation
= true;
1558 } else if (strcasecmp(operation
, "NotifyServers") == 0) {
1559 valid_operation
= true;
1560 } else if (strcasecmp(operation
, "SecondaryServers") == 0) {
1561 valid_operation
= true;
1562 } else if (strcasecmp(operation
, "ScavengingServers") == 0) {
1563 valid_operation
= true;
1564 } else if (strcasecmp(operation
, "AllowNSRecordsAutoCreation") == 0) {
1565 valid_operation
= true;
1566 } else if (strcasecmp(operation
, "BreakOnNameUpdate") == 0) {
1567 valid_operation
= true;
1568 } else if (strcasecmp(operation
, "ApplicationDirectoryPartition") == 0) {
1569 valid_operation
= true;
1572 if (valid_operation
) {
1573 DEBUG(0, ("dnsserver: zone operation '%s' not implemented", operation
));
1574 return WERR_CALL_NOT_IMPLEMENTED
;
1577 DEBUG(0, ("dnsserver: invalid zone operation '%s'", operation
));
1578 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1581 static WERROR
dnsserver_complex_operate_zone(struct dnsserver_state
*dsstate
,
1582 TALLOC_CTX
*mem_ctx
,
1583 struct dnsserver_zone
*z
,
1584 const char *operation
,
1585 const unsigned int client_version
,
1586 enum DNS_RPC_TYPEID typeid_in
,
1587 union DNSSRV_RPC_UNION
*rin
,
1588 enum DNS_RPC_TYPEID
*typeid_out
,
1589 union DNSSRV_RPC_UNION
*rout
)
1591 if (strcasecmp(operation
, "QueryDwordProperty") == 0) {
1592 if (typeid_in
== DNSSRV_TYPEID_LPSTR
) {
1593 return dnsserver_query_zone(dsstate
, mem_ctx
, z
,
1602 DEBUG(0,("dnsserver: Invalid zone operation %s", operation
));
1603 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1606 /* dnsserver enumerate function */
1608 static WERROR
dnsserver_enumerate_root_records(struct dnsserver_state
*dsstate
,
1609 TALLOC_CTX
*mem_ctx
,
1610 unsigned int client_version
,
1611 const char *node_name
,
1612 enum dns_record_type record_type
,
1613 unsigned int select_flag
,
1614 unsigned int *buffer_length
,
1615 struct DNS_RPC_RECORDS_ARRAY
**buffer
)
1617 TALLOC_CTX
*tmp_ctx
;
1618 struct dnsserver_zone
*z
;
1619 const char * const attrs
[] = { "name", "dnsRecord", NULL
};
1620 struct ldb_result
*res
;
1621 struct DNS_RPC_RECORDS_ARRAY
*recs
;
1628 tmp_ctx
= talloc_new(mem_ctx
);
1629 W_ERROR_HAVE_NO_MEMORY(tmp_ctx
);
1631 z
= dnsserver_find_zone(dsstate
->zones
, ".");
1633 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
1636 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1637 LDB_SCOPE_ONELEVEL
, attrs
,
1638 "(&(objectClass=dnsNode)(name=@)(!(dNSTombstoned=TRUE)))");
1639 if (ret
!= LDB_SUCCESS
) {
1640 talloc_free(tmp_ctx
);
1641 return WERR_INTERNAL_DB_ERROR
;
1643 if (res
->count
== 0) {
1644 talloc_free(tmp_ctx
);
1645 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
1648 recs
= talloc_zero(mem_ctx
, struct DNS_RPC_RECORDS_ARRAY
);
1649 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs
, tmp_ctx
);
1654 for (i
=0; i
<res
->count
; i
++) {
1655 status
= dns_fill_records_array(tmp_ctx
, NULL
, record_type
,
1657 res
->msgs
[i
], 0, recs
,
1658 &add_names
, &add_count
);
1659 if (!W_ERROR_IS_OK(status
)) {
1660 talloc_free(tmp_ctx
);
1666 /* Add any additional records */
1667 if (select_flag
& DNS_RPC_VIEW_ADDITIONAL_DATA
) {
1668 for (i
=0; i
<add_count
; i
++) {
1669 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1670 LDB_SCOPE_ONELEVEL
, attrs
,
1671 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1673 if (ret
!= LDB_SUCCESS
|| res
->count
== 0) {
1678 len
= strlen(add_names
[i
]);
1679 if (add_names
[i
][len
-1] == '.') {
1680 rname
= talloc_strdup(tmp_ctx
, add_names
[i
]);
1682 rname
= talloc_asprintf(tmp_ctx
, "%s.", add_names
[i
]);
1684 status
= dns_fill_records_array(tmp_ctx
, NULL
, DNS_TYPE_A
,
1686 res
->msgs
[0], 0, recs
,
1693 talloc_free(tmp_ctx
);
1695 *buffer_length
= ndr_size_DNS_RPC_RECORDS_ARRAY(recs
, 0);
1702 static WERROR
dnsserver_enumerate_records(struct dnsserver_state
*dsstate
,
1703 TALLOC_CTX
*mem_ctx
,
1704 struct dnsserver_zone
*z
,
1705 unsigned int client_version
,
1706 const char *node_name
,
1707 const char *start_child
,
1708 enum dns_record_type record_type
,
1709 unsigned int select_flag
,
1710 const char *filter_start
,
1711 const char *filter_stop
,
1712 unsigned int *buffer_length
,
1713 struct DNS_RPC_RECORDS_ARRAY
**buffer
)
1715 TALLOC_CTX
*tmp_ctx
;
1717 const char * const attrs
[] = { "name", "dnsRecord", NULL
};
1718 struct ldb_result
*res
;
1719 struct DNS_RPC_RECORDS_ARRAY
*recs
;
1720 char **add_names
= NULL
;
1725 struct dns_tree
*tree
, *base
, *node
;
1727 tmp_ctx
= talloc_new(mem_ctx
);
1728 W_ERROR_HAVE_NO_MEMORY(tmp_ctx
);
1730 name
= dns_split_node_name(tmp_ctx
, node_name
, z
->name
);
1731 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name
, tmp_ctx
);
1733 /* search all records under parent tree */
1734 if (strcasecmp(name
, z
->name
) == 0) {
1735 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1736 LDB_SCOPE_ONELEVEL
, attrs
,
1737 "(&(objectClass=dnsNode)(!(dNSTombstoned=TRUE)))");
1739 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1740 LDB_SCOPE_ONELEVEL
, attrs
,
1741 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s))(!(dNSTombstoned=TRUE)))",
1744 if (ret
!= LDB_SUCCESS
) {
1745 talloc_free(tmp_ctx
);
1746 return WERR_INTERNAL_DB_ERROR
;
1748 if (res
->count
== 0) {
1749 talloc_free(tmp_ctx
);
1750 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
1753 recs
= talloc_zero(mem_ctx
, struct DNS_RPC_RECORDS_ARRAY
);
1754 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs
, tmp_ctx
);
1756 /* Sort the names, so that the first record is the parent record */
1757 ldb_qsort(res
->msgs
, res
->count
, sizeof(struct ldb_message
*), name
,
1758 (ldb_qsort_cmp_fn_t
)dns_name_compare
);
1760 /* Build a tree of name components from dns name */
1761 if (strcasecmp(name
, z
->name
) == 0) {
1762 tree
= dns_build_tree(tmp_ctx
, "@", res
);
1764 tree
= dns_build_tree(tmp_ctx
, name
, res
);
1766 W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree
, tmp_ctx
);
1768 /* Find the parent record in the tree */
1770 while (base
->level
!= -1) {
1771 base
= base
->children
[0];
1774 /* Add the parent record with blank name */
1775 if (!(select_flag
& DNS_RPC_VIEW_ONLY_CHILDREN
)) {
1776 status
= dns_fill_records_array(tmp_ctx
, z
, record_type
,
1779 recs
, &add_names
, &add_count
);
1780 if (!W_ERROR_IS_OK(status
)) {
1781 talloc_free(tmp_ctx
);
1786 /* Add all the children records */
1787 if (!(select_flag
& DNS_RPC_VIEW_NO_CHILDREN
)) {
1788 for (i
=0; i
<base
->num_children
; i
++) {
1789 node
= base
->children
[i
];
1791 status
= dns_fill_records_array(tmp_ctx
, z
, record_type
,
1792 select_flag
, node
->name
,
1793 node
->data
, node
->num_children
,
1794 recs
, &add_names
, &add_count
);
1795 if (!W_ERROR_IS_OK(status
)) {
1796 talloc_free(tmp_ctx
);
1806 /* Add any additional records */
1807 if (select_flag
& DNS_RPC_VIEW_ADDITIONAL_DATA
) {
1808 for (i
=0; i
<add_count
; i
++) {
1809 struct dnsserver_zone
*z2
;
1811 /* Search all the available zones for additional name */
1812 for (z2
= dsstate
->zones
; z2
; z2
= z2
->next
) {
1813 name
= dns_split_node_name(tmp_ctx
, add_names
[i
], z2
->name
);
1814 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z2
->zone_dn
,
1815 LDB_SCOPE_ONELEVEL
, attrs
,
1816 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1819 if (ret
!= LDB_SUCCESS
) {
1822 if (res
->count
== 1) {
1830 len
= strlen(add_names
[i
]);
1831 if (add_names
[i
][len
-1] == '.') {
1832 rname
= talloc_strdup(tmp_ctx
, add_names
[i
]);
1834 rname
= talloc_asprintf(tmp_ctx
, "%s.", add_names
[i
]);
1836 status
= dns_fill_records_array(tmp_ctx
, NULL
, DNS_TYPE_A
,
1838 res
->msgs
[0], 0, recs
,
1845 *buffer_length
= ndr_size_DNS_RPC_RECORDS_ARRAY(recs
, 0);
1851 /* dnsserver update function */
1853 static WERROR
dnsserver_update_record(struct dnsserver_state
*dsstate
,
1854 TALLOC_CTX
*mem_ctx
,
1855 struct dnsserver_zone
*z
,
1856 unsigned int client_version
,
1857 const char *node_name
,
1858 struct DNS_RPC_RECORD_BUF
*add_buf
,
1859 struct DNS_RPC_RECORD_BUF
*del_buf
)
1861 TALLOC_CTX
*tmp_ctx
;
1865 tmp_ctx
= talloc_new(mem_ctx
);
1866 W_ERROR_HAVE_NO_MEMORY(tmp_ctx
);
1868 /* If node_name is @ or zone name, dns record is @ */
1869 if (strcmp(node_name
, "@") == 0 ||
1870 strcmp(node_name
, ".") == 0 ||
1871 strcasecmp(node_name
, z
->name
) == 0) {
1872 name
= talloc_strdup(tmp_ctx
, "@");
1874 name
= dns_split_node_name(tmp_ctx
, node_name
, z
->name
);
1876 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name
, tmp_ctx
);
1878 if (add_buf
!= NULL
) {
1879 if (del_buf
== NULL
) {
1881 status
= dnsserver_db_add_record(tmp_ctx
, dsstate
->samdb
,
1886 status
= dnsserver_db_update_record(tmp_ctx
, dsstate
->samdb
,
1892 if (del_buf
== NULL
) {
1893 /* Add empty node */
1894 status
= dnsserver_db_add_empty_node(tmp_ctx
, dsstate
->samdb
,
1898 status
= dnsserver_db_delete_record(tmp_ctx
, dsstate
->samdb
,
1904 talloc_free(tmp_ctx
);
1909 /* dnsserver interface functions */
1911 static WERROR
dcesrv_DnssrvOperation(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvOperation
*r
)
1913 struct dnsserver_state
*dsstate
;
1914 struct dnsserver_zone
*z
= NULL
;
1915 uint32_t request_filter
= 0;
1918 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
1919 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
1922 if (r
->in
.dwContext
== 0) {
1923 if (r
->in
.pszZone
!= NULL
) {
1924 request_filter
= dnsserver_zone_to_request_filter(r
->in
.pszZone
);
1927 request_filter
= r
->in
.dwContext
;
1930 if (r
->in
.pszZone
== NULL
) {
1931 ret
= dnsserver_operate_server(dsstate
, mem_ctx
,
1933 DNS_CLIENT_VERSION_W2K
,
1937 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
1938 if (z
== NULL
&& request_filter
== 0) {
1939 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
1942 ret
= dnsserver_operate_zone(dsstate
, mem_ctx
, z
,
1945 DNS_CLIENT_VERSION_W2K
,
1950 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
1951 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation
, NDR_IN
, r
);
1956 static WERROR
dcesrv_DnssrvQuery(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvQuery
*r
)
1958 struct dnsserver_state
*dsstate
;
1959 struct dnsserver_zone
*z
;
1962 ZERO_STRUCTP(r
->out
.pdwTypeId
);
1963 ZERO_STRUCTP(r
->out
.ppData
);
1965 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
1966 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
1969 if (r
->in
.pszZone
== NULL
) {
1970 /* FIXME: DNS Server Configuration Access Control List */
1971 ret
= dnsserver_query_server(dsstate
, mem_ctx
,
1973 DNS_CLIENT_VERSION_W2K
,
1977 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
1979 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
1982 ret
= dnsserver_query_zone(dsstate
, mem_ctx
, z
,
1984 DNS_CLIENT_VERSION_W2K
,
1989 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
1990 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery
, NDR_IN
, r
);
1995 static WERROR
dcesrv_DnssrvComplexOperation(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvComplexOperation
*r
)
1997 struct dnsserver_state
*dsstate
;
1998 struct dnsserver_zone
*z
;
2001 ZERO_STRUCTP(r
->out
.pdwTypeOut
);
2002 ZERO_STRUCTP(r
->out
.ppDataOut
);
2004 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2005 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2008 if (r
->in
.pszZone
== NULL
) {
2009 /* Server operation */
2010 ret
= dnsserver_complex_operate_server(dsstate
, mem_ctx
,
2012 DNS_CLIENT_VERSION_W2K
,
2018 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2020 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2023 ret
= dnsserver_complex_operate_zone(dsstate
, mem_ctx
, z
,
2025 DNS_CLIENT_VERSION_W2K
,
2032 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2033 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation
, NDR_IN
, r
);
2038 static WERROR
dcesrv_DnssrvEnumRecords(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvEnumRecords
*r
)
2040 struct dnsserver_state
*dsstate
;
2041 struct dnsserver_zone
*z
;
2044 ZERO_STRUCTP(r
->out
.pdwBufferLength
);
2045 ZERO_STRUCTP(r
->out
.pBuffer
);
2047 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2048 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2051 if (r
->in
.pszZone
== NULL
) {
2052 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2055 if (strcasecmp(r
->in
.pszZone
, "..RootHints") == 0) {
2056 ret
= dnsserver_enumerate_root_records(dsstate
, mem_ctx
,
2057 DNS_CLIENT_VERSION_W2K
,
2061 r
->out
.pdwBufferLength
,
2064 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2066 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2069 ret
= dnsserver_enumerate_records(dsstate
, mem_ctx
, z
,
2070 DNS_CLIENT_VERSION_W2K
,
2072 r
->in
.pszStartChild
,
2075 r
->in
.pszFilterStart
,
2076 r
->in
.pszFilterStop
,
2077 r
->out
.pdwBufferLength
,
2081 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2082 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords
, NDR_IN
, r
);
2087 static WERROR
dcesrv_DnssrvUpdateRecord(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvUpdateRecord
*r
)
2089 struct dnsserver_state
*dsstate
;
2090 struct dnsserver_zone
*z
;
2093 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2094 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2097 if (r
->in
.pszZone
== NULL
) {
2098 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2101 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2103 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2106 ret
= dnsserver_update_record(dsstate
, mem_ctx
, z
,
2107 DNS_CLIENT_VERSION_W2K
,
2110 r
->in
.pDeleteRecord
);
2112 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2113 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord
, NDR_IN
, r
);
2118 static WERROR
dcesrv_DnssrvOperation2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvOperation2
*r
)
2120 struct dnsserver_state
*dsstate
;
2121 struct dnsserver_zone
*z
= NULL
;
2122 uint32_t request_filter
= 0;
2125 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2126 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2129 if (r
->in
.dwContext
== 0) {
2130 if (r
->in
.pszZone
!= NULL
) {
2131 request_filter
= dnsserver_zone_to_request_filter(r
->in
.pszZone
);
2134 request_filter
= r
->in
.dwContext
;
2137 if (r
->in
.pszZone
== NULL
) {
2138 ret
= dnsserver_operate_server(dsstate
, mem_ctx
,
2140 r
->in
.dwClientVersion
,
2144 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2145 if (z
== NULL
&& request_filter
== 0) {
2146 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2149 ret
= dnsserver_operate_zone(dsstate
, mem_ctx
, z
,
2152 r
->in
.dwClientVersion
,
2157 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2158 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation2
, NDR_IN
, r
);
2163 static WERROR
dcesrv_DnssrvQuery2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvQuery2
*r
)
2165 struct dnsserver_state
*dsstate
;
2166 struct dnsserver_zone
*z
;
2169 ZERO_STRUCTP(r
->out
.pdwTypeId
);
2170 ZERO_STRUCTP(r
->out
.ppData
);
2172 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2173 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2176 if (r
->in
.pszZone
== NULL
) {
2177 /* FIXME: DNS Server Configuration Access Control List */
2178 ret
= dnsserver_query_server(dsstate
, mem_ctx
,
2180 r
->in
.dwClientVersion
,
2184 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2186 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2189 ret
= dnsserver_query_zone(dsstate
, mem_ctx
, z
,
2191 r
->in
.dwClientVersion
,
2196 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2197 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery2
, NDR_IN
, r
);
2202 static WERROR
dcesrv_DnssrvComplexOperation2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvComplexOperation2
*r
)
2204 struct dnsserver_state
*dsstate
;
2205 struct dnsserver_zone
*z
;
2208 ZERO_STRUCTP(r
->out
.pdwTypeOut
);
2209 ZERO_STRUCTP(r
->out
.ppDataOut
);
2211 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2212 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2215 if (r
->in
.pszZone
== NULL
) {
2216 /* Server operation */
2217 ret
= dnsserver_complex_operate_server(dsstate
, mem_ctx
,
2219 r
->in
.dwClientVersion
,
2226 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2228 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2231 ret
= dnsserver_complex_operate_zone(dsstate
, mem_ctx
, z
,
2233 r
->in
.dwClientVersion
,
2240 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2241 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation2
, NDR_IN
, r
);
2246 static WERROR
dcesrv_DnssrvEnumRecords2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvEnumRecords2
*r
)
2248 struct dnsserver_state
*dsstate
;
2249 struct dnsserver_zone
*z
;
2252 ZERO_STRUCTP(r
->out
.pdwBufferLength
);
2253 ZERO_STRUCTP(r
->out
.pBuffer
);
2255 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2256 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2259 if (r
->in
.pszZone
== NULL
) {
2260 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2263 if (strcasecmp(r
->in
.pszZone
, "..RootHints") == 0) {
2264 ret
= dnsserver_enumerate_root_records(dsstate
, mem_ctx
,
2265 r
->in
.dwClientVersion
,
2269 r
->out
.pdwBufferLength
,
2272 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2274 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2277 ret
= dnsserver_enumerate_records(dsstate
, mem_ctx
, z
,
2278 r
->in
.dwClientVersion
,
2280 r
->in
.pszStartChild
,
2283 r
->in
.pszFilterStart
,
2284 r
->in
.pszFilterStop
,
2285 r
->out
.pdwBufferLength
,
2290 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2291 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords2
, NDR_IN
, r
);
2296 static WERROR
dcesrv_DnssrvUpdateRecord2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvUpdateRecord2
*r
)
2298 struct dnsserver_state
*dsstate
;
2299 struct dnsserver_zone
*z
;
2302 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2303 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2306 if (r
->in
.pszZone
== NULL
) {
2307 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2310 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2312 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2315 ret
= dnsserver_update_record(dsstate
, mem_ctx
, z
,
2316 r
->in
.dwClientVersion
,
2319 r
->in
.pDeleteRecord
);
2321 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2322 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord2
, NDR_IN
, r
);
2327 /* include the generated boilerplate */
2328 #include "librpc/gen_ndr/ndr_dnsserver_s.c"