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 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
++;
156 dce_call
->context
->private_data
= dsstate
;
161 talloc_free(dsstate
);
167 /* dnsserver query functions */
169 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
170 static WERROR
dnsserver_query_server(struct dnsserver_state
*dsstate
,
172 const char *operation
,
173 const unsigned int client_version
,
174 enum DNS_RPC_TYPEID
*typeid,
175 union DNSSRV_RPC_UNION
*r
)
177 uint8_t is_integer
, is_addresses
, is_string
, is_wstring
, is_stringlist
;
178 uint32_t answer_integer
;
179 struct IP4_ARRAY
*answer_iparray
;
180 struct DNS_ADDR_ARRAY
*answer_addrarray
;
182 struct DNS_RPC_UTF8_STRING_LIST
*answer_stringlist
;
183 struct dnsserver_serverinfo
*serverinfo
;
185 serverinfo
= dsstate
->serverinfo
;
187 if (strcasecmp(operation
, "ServerInfo") == 0) {
188 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
189 *typeid = DNSSRV_TYPEID_SERVER_INFO_W2K
;
190 r
->ServerInfoW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_SERVER_INFO_W2K
);
192 r
->ServerInfoW2K
->dwVersion
= serverinfo
->dwVersion
;
193 r
->ServerInfoW2K
->fBootMethod
= serverinfo
->fBootMethod
;
194 r
->ServerInfoW2K
->fAdminConfigured
= serverinfo
->fAdminConfigured
;
195 r
->ServerInfoW2K
->fAllowUpdate
= serverinfo
->fAllowUpdate
;
196 r
->ServerInfoW2K
->fDsAvailable
= serverinfo
->fDsAvailable
;
197 r
->ServerInfoW2K
->pszServerName
= talloc_strdup(mem_ctx
, serverinfo
->pszServerName
);
198 r
->ServerInfoW2K
->pszDsContainer
= talloc_strdup(mem_ctx
, serverinfo
->pszDsContainer
);
199 r
->ServerInfoW2K
->aipServerAddrs
= ip4_array_copy(mem_ctx
, serverinfo
->aipServerAddrs
);
200 r
->ServerInfoW2K
->aipListenAddrs
= ip4_array_copy(mem_ctx
, serverinfo
->aipListenAddrs
);
201 r
->ServerInfoW2K
->aipForwarders
= ip4_array_copy(mem_ctx
, serverinfo
->aipForwarders
);
202 r
->ServerInfoW2K
->dwLogLevel
= serverinfo
->dwLogLevel
;
203 r
->ServerInfoW2K
->dwDebugLevel
= serverinfo
->dwDebugLevel
;
204 r
->ServerInfoW2K
->dwForwardTimeout
= serverinfo
->dwForwardTimeout
;
205 r
->ServerInfoW2K
->dwRpcProtocol
= serverinfo
->dwRpcProtocol
;
206 r
->ServerInfoW2K
->dwNameCheckFlag
= serverinfo
->dwNameCheckFlag
;
207 r
->ServerInfoW2K
->cAddressAnswerLimit
= serverinfo
->cAddressAnswerLimit
;
208 r
->ServerInfoW2K
->dwRecursionRetry
= serverinfo
->dwRecursionRetry
;
209 r
->ServerInfoW2K
->dwRecursionTimeout
= serverinfo
->dwRecursionTimeout
;
210 r
->ServerInfoW2K
->dwMaxCacheTtl
= serverinfo
->dwMaxCacheTtl
;
211 r
->ServerInfoW2K
->dwDsPollingInterval
= serverinfo
->dwDsPollingInterval
;
212 r
->ServerInfoW2K
->dwScavengingInterval
= serverinfo
->dwScavengingInterval
;
213 r
->ServerInfoW2K
->dwDefaultRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
214 r
->ServerInfoW2K
->dwDefaultNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
215 r
->ServerInfoW2K
->fAutoReverseZones
= serverinfo
->fAutoReverseZones
;
216 r
->ServerInfoW2K
->fAutoCacheUpdate
= serverinfo
->fAutoCacheUpdate
;
217 r
->ServerInfoW2K
->fRecurseAfterForwarding
= serverinfo
->fRecurseAfterForwarding
;
218 r
->ServerInfoW2K
->fForwardDelegations
= serverinfo
->fForwardDelegations
;
219 r
->ServerInfoW2K
->fNoRecursion
= serverinfo
->fNoRecursion
;
220 r
->ServerInfoW2K
->fSecureResponses
= serverinfo
->fSecureResponses
;
221 r
->ServerInfoW2K
->fRoundRobin
= serverinfo
->fRoundRobin
;
222 r
->ServerInfoW2K
->fLocalNetPriority
= serverinfo
->fLocalNetPriority
;
223 r
->ServerInfoW2K
->fBindSecondaries
= serverinfo
->fBindSecondaries
;
224 r
->ServerInfoW2K
->fWriteAuthorityNs
= serverinfo
->fWriteAuthorityNs
;
225 r
->ServerInfoW2K
->fStrictFileParsing
= serverinfo
->fStrictFileParsing
;
226 r
->ServerInfoW2K
->fLooseWildcarding
= serverinfo
->fLooseWildcarding
;
227 r
->ServerInfoW2K
->fDefaultAgingState
= serverinfo
->fDefaultAgingState
;
229 } else if (client_version
== DNS_CLIENT_VERSION_DOTNET
) {
230 *typeid = DNSSRV_TYPEID_SERVER_INFO_DOTNET
;
231 r
->ServerInfoDotNet
= talloc_zero(mem_ctx
, struct DNS_RPC_SERVER_INFO_DOTNET
);
233 r
->ServerInfoDotNet
->dwRpcStructureVersion
= 0x01;
234 r
->ServerInfoDotNet
->dwVersion
= serverinfo
->dwVersion
;
235 r
->ServerInfoDotNet
->fBootMethod
= serverinfo
->fBootMethod
;
236 r
->ServerInfoDotNet
->fAdminConfigured
= serverinfo
->fAdminConfigured
;
237 r
->ServerInfoDotNet
->fAllowUpdate
= serverinfo
->fAllowUpdate
;
238 r
->ServerInfoDotNet
->fDsAvailable
= serverinfo
->fDsAvailable
;
239 r
->ServerInfoDotNet
->pszServerName
= talloc_strdup(mem_ctx
, serverinfo
->pszServerName
);
240 r
->ServerInfoDotNet
->pszDsContainer
= talloc_strdup(mem_ctx
, serverinfo
->pszDsContainer
);
241 r
->ServerInfoDotNet
->aipServerAddrs
= ip4_array_copy(mem_ctx
, serverinfo
->aipServerAddrs
);
242 r
->ServerInfoDotNet
->aipListenAddrs
= ip4_array_copy(mem_ctx
, serverinfo
->aipListenAddrs
);
243 r
->ServerInfoDotNet
->aipForwarders
= ip4_array_copy(mem_ctx
, serverinfo
->aipForwarders
);
244 r
->ServerInfoDotNet
->aipLogFilter
= ip4_array_copy(mem_ctx
, serverinfo
->aipLogFilter
);
245 r
->ServerInfoDotNet
->pwszLogFilePath
= talloc_strdup(mem_ctx
, serverinfo
->pwszLogFilePath
);
246 r
->ServerInfoDotNet
->pszDomainName
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainName
);
247 r
->ServerInfoDotNet
->pszForestName
= talloc_strdup(mem_ctx
, serverinfo
->pszForestName
);
248 r
->ServerInfoDotNet
->pszDomainDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainDirectoryPartition
);
249 r
->ServerInfoDotNet
->pszForestDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszForestDirectoryPartition
);
250 r
->ServerInfoDotNet
->dwLogLevel
= serverinfo
->dwLogLevel
;
251 r
->ServerInfoDotNet
->dwDebugLevel
= serverinfo
->dwDebugLevel
;
252 r
->ServerInfoDotNet
->dwForwardTimeout
= serverinfo
->dwForwardTimeout
;
253 r
->ServerInfoDotNet
->dwRpcProtocol
= serverinfo
->dwRpcProtocol
;
254 r
->ServerInfoDotNet
->dwNameCheckFlag
= serverinfo
->dwNameCheckFlag
;
255 r
->ServerInfoDotNet
->cAddressAnswerLimit
= serverinfo
->cAddressAnswerLimit
;
256 r
->ServerInfoDotNet
->dwRecursionRetry
= serverinfo
->dwRecursionRetry
;
257 r
->ServerInfoDotNet
->dwRecursionTimeout
= serverinfo
->dwRecursionTimeout
;
258 r
->ServerInfoDotNet
->dwMaxCacheTtl
= serverinfo
->dwMaxCacheTtl
;
259 r
->ServerInfoDotNet
->dwDsPollingInterval
= serverinfo
->dwDsPollingInterval
;
260 r
->ServerInfoDotNet
->dwLocalNetPriorityNetMask
= serverinfo
->dwLocalNetPriorityNetMask
;
261 r
->ServerInfoDotNet
->dwScavengingInterval
= serverinfo
->dwScavengingInterval
;
262 r
->ServerInfoDotNet
->dwDefaultRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
263 r
->ServerInfoDotNet
->dwDefaultNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
264 r
->ServerInfoDotNet
->dwLastScavengeTime
= serverinfo
->dwLastScavengeTime
;
265 r
->ServerInfoDotNet
->dwEventLogLevel
= serverinfo
->dwEventLogLevel
;
266 r
->ServerInfoDotNet
->dwLogFileMaxSize
= serverinfo
->dwLogFileMaxSize
;
267 r
->ServerInfoDotNet
->dwDsForestVersion
= serverinfo
->dwDsForestVersion
;
268 r
->ServerInfoDotNet
->dwDsDomainVersion
= serverinfo
->dwDsDomainVersion
;
269 r
->ServerInfoDotNet
->dwDsDsaVersion
= serverinfo
->dwDsDsaVersion
;
270 r
->ServerInfoDotNet
->fAutoReverseZones
= serverinfo
->fAutoReverseZones
;
271 r
->ServerInfoDotNet
->fAutoCacheUpdate
= serverinfo
->fAutoCacheUpdate
;
272 r
->ServerInfoDotNet
->fRecurseAfterForwarding
= serverinfo
->fRecurseAfterForwarding
;
273 r
->ServerInfoDotNet
->fForwardDelegations
= serverinfo
->fForwardDelegations
;
274 r
->ServerInfoDotNet
->fNoRecursion
= serverinfo
->fNoRecursion
;
275 r
->ServerInfoDotNet
->fSecureResponses
= serverinfo
->fSecureResponses
;
276 r
->ServerInfoDotNet
->fRoundRobin
= serverinfo
->fRoundRobin
;
277 r
->ServerInfoDotNet
->fLocalNetPriority
= serverinfo
->fLocalNetPriority
;
278 r
->ServerInfoDotNet
->fBindSecondaries
= serverinfo
->fBindSecondaries
;
279 r
->ServerInfoDotNet
->fWriteAuthorityNs
= serverinfo
->fWriteAuthorityNs
;
280 r
->ServerInfoDotNet
->fStrictFileParsing
= serverinfo
->fStrictFileParsing
;
281 r
->ServerInfoDotNet
->fLooseWildcarding
= serverinfo
->fLooseWildcarding
;
282 r
->ServerInfoDotNet
->fDefaultAgingState
= serverinfo
->fDefaultAgingState
;
284 } else if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
285 *typeid = DNSSRV_TYPEID_SERVER_INFO
;
286 r
->ServerInfo
= talloc_zero(mem_ctx
, struct DNS_RPC_SERVER_INFO_LONGHORN
);
288 r
->ServerInfo
->dwRpcStructureVersion
= 0x02;
289 r
->ServerInfo
->dwVersion
= serverinfo
->dwVersion
;
290 r
->ServerInfo
->fBootMethod
= serverinfo
->fBootMethod
;
291 r
->ServerInfo
->fAdminConfigured
= serverinfo
->fAdminConfigured
;
292 r
->ServerInfo
->fAllowUpdate
= serverinfo
->fAllowUpdate
;
293 r
->ServerInfo
->fDsAvailable
= serverinfo
->fDsAvailable
;
294 r
->ServerInfo
->pszServerName
= talloc_strdup(mem_ctx
, serverinfo
->pszServerName
);
295 r
->ServerInfo
->pszDsContainer
= talloc_strdup(mem_ctx
, serverinfo
->pszDsContainer
);
296 r
->ServerInfo
->aipServerAddrs
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipServerAddrs
);
297 r
->ServerInfo
->aipListenAddrs
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipListenAddrs
);
298 r
->ServerInfo
->aipForwarders
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipForwarders
);
299 r
->ServerInfo
->aipLogFilter
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipLogFilter
);
300 r
->ServerInfo
->pwszLogFilePath
= talloc_strdup(mem_ctx
, serverinfo
->pwszLogFilePath
);
301 r
->ServerInfo
->pszDomainName
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainName
);
302 r
->ServerInfo
->pszForestName
= talloc_strdup(mem_ctx
, serverinfo
->pszForestName
);
303 r
->ServerInfo
->pszDomainDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszDomainDirectoryPartition
);
304 r
->ServerInfo
->pszForestDirectoryPartition
= talloc_strdup(mem_ctx
, serverinfo
->pszForestDirectoryPartition
);
305 r
->ServerInfo
->dwLogLevel
= serverinfo
->dwLogLevel
;
306 r
->ServerInfo
->dwDebugLevel
= serverinfo
->dwDebugLevel
;
307 r
->ServerInfo
->dwForwardTimeout
= serverinfo
->dwForwardTimeout
;
308 r
->ServerInfo
->dwRpcProtocol
= serverinfo
->dwRpcProtocol
;
309 r
->ServerInfo
->dwNameCheckFlag
= serverinfo
->dwNameCheckFlag
;
310 r
->ServerInfo
->cAddressAnswerLimit
= serverinfo
->cAddressAnswerLimit
;
311 r
->ServerInfo
->dwRecursionRetry
= serverinfo
->dwRecursionRetry
;
312 r
->ServerInfo
->dwRecursionTimeout
= serverinfo
->dwRecursionTimeout
;
313 r
->ServerInfo
->dwMaxCacheTtl
= serverinfo
->dwMaxCacheTtl
;
314 r
->ServerInfo
->dwDsPollingInterval
= serverinfo
->dwDsPollingInterval
;
315 r
->ServerInfo
->dwLocalNetPriorityNetMask
= serverinfo
->dwLocalNetPriorityNetMask
;
316 r
->ServerInfo
->dwScavengingInterval
= serverinfo
->dwScavengingInterval
;
317 r
->ServerInfo
->dwDefaultRefreshInterval
= serverinfo
->dwDefaultRefreshInterval
;
318 r
->ServerInfo
->dwDefaultNoRefreshInterval
= serverinfo
->dwDefaultNoRefreshInterval
;
319 r
->ServerInfo
->dwLastScavengeTime
= serverinfo
->dwLastScavengeTime
;
320 r
->ServerInfo
->dwEventLogLevel
= serverinfo
->dwEventLogLevel
;
321 r
->ServerInfo
->dwLogFileMaxSize
= serverinfo
->dwLogFileMaxSize
;
322 r
->ServerInfo
->dwDsForestVersion
= serverinfo
->dwDsForestVersion
;
323 r
->ServerInfo
->dwDsDomainVersion
= serverinfo
->dwDsDomainVersion
;
324 r
->ServerInfo
->dwDsDsaVersion
= serverinfo
->dwDsDsaVersion
;
325 r
->ServerInfo
->fReadOnlyDC
= serverinfo
->fReadOnlyDC
;
326 r
->ServerInfo
->fAutoReverseZones
= serverinfo
->fAutoReverseZones
;
327 r
->ServerInfo
->fAutoCacheUpdate
= serverinfo
->fAutoCacheUpdate
;
328 r
->ServerInfo
->fRecurseAfterForwarding
= serverinfo
->fRecurseAfterForwarding
;
329 r
->ServerInfo
->fForwardDelegations
= serverinfo
->fForwardDelegations
;
330 r
->ServerInfo
->fNoRecursion
= serverinfo
->fNoRecursion
;
331 r
->ServerInfo
->fSecureResponses
= serverinfo
->fSecureResponses
;
332 r
->ServerInfo
->fRoundRobin
= serverinfo
->fRoundRobin
;
333 r
->ServerInfo
->fLocalNetPriority
= serverinfo
->fLocalNetPriority
;
334 r
->ServerInfo
->fBindSecondaries
= serverinfo
->fBindSecondaries
;
335 r
->ServerInfo
->fWriteAuthorityNs
= serverinfo
->fWriteAuthorityNs
;
336 r
->ServerInfo
->fStrictFileParsing
= serverinfo
->fStrictFileParsing
;
337 r
->ServerInfo
->fLooseWildcarding
= serverinfo
->fLooseWildcarding
;
338 r
->ServerInfo
->fDefaultAgingState
= serverinfo
->fDefaultAgingState
;
345 if (strcasecmp(operation
, "AddressAnswerLimit") == 0) {
346 answer_integer
= serverinfo
->cAddressAnswerLimit
;
348 } else if (strcasecmp(operation
, "AdminConfigured") == 0) {
349 answer_integer
= serverinfo
->fAdminConfigured
;
351 } else if (strcasecmp(operation
, "AllowCNAMEAtNS") == 0) {
354 } else if (strcasecmp(operation
, "AllowUpdate") == 0) {
355 answer_integer
= serverinfo
->fAllowUpdate
;
357 } else if (strcasecmp(operation
, "AutoCacheUpdate") == 0) {
358 answer_integer
= serverinfo
->fAutoCacheUpdate
;
360 } else if (strcasecmp(operation
, "AutoConfigFileZones") == 0) {
363 } else if (strcasecmp(operation
, "BindSecondaries") == 0) {
364 answer_integer
= serverinfo
->fBindSecondaries
;
366 } else if (strcasecmp(operation
, "BootMethod") == 0) {
367 answer_integer
= serverinfo
->fBootMethod
;
369 } else if (strcasecmp(operation
, "DebugLevel") == 0) {
370 answer_integer
= serverinfo
->dwDebugLevel
;
372 } else if (strcasecmp(operation
, "DefaultAgingState") == 0) {
373 answer_integer
= serverinfo
->fDefaultAgingState
;
375 } else if (strcasecmp(operation
, "DefaultNoRefreshInterval") == 0) {
376 answer_integer
= serverinfo
->dwDefaultNoRefreshInterval
;
378 } else if (strcasecmp(operation
, "DefaultRefreshInterval") == 0) {
379 answer_integer
= serverinfo
->dwDefaultRefreshInterval
;
381 } else if (strcasecmp(operation
, "DeleteOutsideGlue") == 0) {
384 } else if (strcasecmp(operation
, "DisjointNets") == 0) {
387 } else if (strcasecmp(operation
, "DsLazyUpdateInterval") == 0) {
388 answer_integer
= 3; /* seconds */
390 } else if (strcasecmp(operation
, "DsPollingInterval") == 0) {
391 answer_integer
= serverinfo
->dwDsPollingInterval
;
393 } else if (strcasecmp(operation
, "DsTombstoneInterval") == 0) {
394 answer_integer
= 0x00127500; /* 14 days */
396 } else if (strcasecmp(operation
, "EnableRegistryBoot") == 0) {
399 } else if (strcasecmp(operation
, "EventLogLevel") == 0) {
400 answer_integer
= serverinfo
->dwEventLogLevel
;
402 } else if (strcasecmp(operation
, "ForceSoaSerial") == 0) {
405 } else if (strcasecmp(operation
, "ForceSaoRetry") == 0) {
408 } else if (strcasecmp(operation
, "ForceSoaRefresh") == 0) {
411 } else if (strcasecmp(operation
, "ForceSoaMinimumTtl") == 0) {
414 } else if (strcasecmp(operation
, "ForwardDelegations") == 0) {
417 } else if (strcasecmp(operation
, "ForwardingTimeout") == 0) {
418 answer_integer
= serverinfo
->dwForwardTimeout
;
420 } else if (strcasecmp(operation
, "IsSlave") == 0) {
423 } else if (strcasecmp(operation
, "LocalNetPriority") == 0) {
424 answer_integer
= serverinfo
->fLocalNetPriority
;
426 } else if (strcasecmp(operation
, "LogFileMaxSize") == 0) {
427 answer_integer
= serverinfo
->dwLogFileMaxSize
;
429 } else if (strcasecmp(operation
, "LogLevel") == 0) {
430 answer_integer
= serverinfo
->dwLogLevel
;
432 } else if (strcasecmp(operation
, "LooseWildcarding") == 0) {
433 answer_integer
= serverinfo
->fLooseWildcarding
;
435 } else if (strcasecmp(operation
, "MaxCacheTtl") == 0) {
436 answer_integer
= serverinfo
->dwMaxCacheTtl
;
438 } else if (strcasecmp(operation
, "MaxNegativeCacheTtl") == 0) {
439 answer_integer
= 0x00000384; /* 15 minutes */
441 } else if (strcasecmp(operation
, "NameCheckFlag") == 0) {
442 answer_integer
= serverinfo
->dwNameCheckFlag
;
444 } else if (strcasecmp(operation
, "NoRecursion") == 0) {
445 answer_integer
= serverinfo
->fNoRecursion
;
447 } else if (strcasecmp(operation
, "NoUpdateDelegations") == 0) {
450 } else if (strcasecmp(operation
, "PublishAutonet") == 0) {
453 } else if (strcasecmp(operation
, "QuietRecvFaultInterval") == 0) {
456 } else if (strcasecmp(operation
, "QuietRecvLogInterval") == 0) {
459 } else if (strcasecmp(operation
, "RecursionRetry") == 0) {
460 answer_integer
= serverinfo
->dwRecursionRetry
;
462 } else if (strcasecmp(operation
, "RecursionTimeout") == 0) {
463 answer_integer
= serverinfo
->dwRecursionTimeout
;
465 } else if (strcasecmp(operation
, "ReloadException") == 0) {
468 } else if (strcasecmp(operation
, "RoundRobin") == 0) {
469 answer_integer
= serverinfo
->fRoundRobin
;
471 } else if (strcasecmp(operation
, "RpcProtocol") == 0) {
472 answer_integer
= serverinfo
->dwRpcProtocol
;
474 } else if (strcasecmp(operation
, "SecureResponses") == 0) {
475 answer_integer
= serverinfo
->fSecureResponses
;
477 } else if (strcasecmp(operation
, "SendPort") == 0) {
480 } else if (strcasecmp(operation
, "ScavengingInterval") == 0) {
481 answer_integer
= serverinfo
->dwScavengingInterval
;
483 } else if (strcasecmp(operation
, "SocketPoolSize") == 0) {
484 answer_integer
= 0x000009C4;
486 } else if (strcasecmp(operation
, "StrictFileParsing") == 0) {
487 answer_integer
= serverinfo
->fStrictFileParsing
;
489 } else if (strcasecmp(operation
, "SyncDnsZoneSerial") == 0) {
490 answer_integer
= 2; /* ZONE_SERIAL_SYNC_XFER */
492 } else if (strcasecmp(operation
, "UpdateOptions") == 0) {
493 answer_integer
= 0x0000030F; /* DNS_DEFAULT_UPDATE_OPTIONS */
495 } else if (strcasecmp(operation
, "UseSystemEvengLog") == 0) {
498 } else if (strcasecmp(operation
, "Version") == 0) {
499 answer_integer
= serverinfo
->dwVersion
;
501 } else if (strcasecmp(operation
, "XfrConnectTimeout") == 0) {
502 answer_integer
= 0x0000001E;
504 } else if (strcasecmp(operation
, "WriteAuthorityNs") == 0) {
505 answer_integer
= serverinfo
->fWriteAuthorityNs
;
507 } else if (strcasecmp(operation
, "AdditionalRecursionTimeout") == 0) {
508 answer_integer
= 0x00000004;
510 } else if (strcasecmp(operation
, "AppendMsZoneTransferFlag") == 0) {
513 } else if (strcasecmp(operation
, "AutoCreateDelegations") == 0) {
514 answer_integer
= 0; /* DNS_ACD_DONT_CREATE */
516 } else if (strcasecmp(operation
, "BreakOnAscFailure") == 0) {
519 } else if (strcasecmp(operation
, "CacheEmptyAuthResponses") == 0) {
522 } else if (strcasecmp(operation
, "DirectoryPartitionAutoEnlistInterval") == 0) {
523 answer_integer
= 0x00015180; /* 1 day */
525 } else if (strcasecmp(operation
, "DisableAutoReverseZones") == 0) {
526 answer_integer
= ~serverinfo
->fAutoReverseZones
;
528 } else if (strcasecmp(operation
, "EDnsCacheTimeout") == 0) {
529 answer_integer
= 0x00000384; /* 15 minutes */
531 } else if (strcasecmp(operation
, "EnableDirectoryPartitions") == 0) {
532 answer_integer
= serverinfo
->fDsAvailable
;
534 } else if (strcasecmp(operation
, "EnableDnsSec") == 0) {
537 } else if (strcasecmp(operation
, "EnableEDnsProbes") == 0) {
540 } else if (strcasecmp(operation
, "EnableEDnsReception") == 0) {
543 } else if (strcasecmp(operation
, "EnableIPv6") == 0) {
546 } else if (strcasecmp(operation
, "EnableIQueryResponseGeneration") == 0) {
549 } else if (strcasecmp(operation
, "EnableSendErrorSuppression") == 0) {
552 } else if (strcasecmp(operation
, "EnableUpdateForwarding") == 0) {
555 } else if (strcasecmp(operation
, "EnableWinsR") == 0) {
558 } else if (strcasecmp(operation
, "ForceDsaBehaviorVersion") == 0) {
559 answer_integer
= serverinfo
->dwDsDsaVersion
;
561 } else if (strcasecmp(operation
, "ForceDomainBehaviorVersion") == 0) {
562 answer_integer
= serverinfo
->dwDsDsaVersion
;
564 } else if (strcasecmp(operation
, "ForceForestBehaviorVersion") == 0) {
565 answer_integer
= serverinfo
->dwDsDsaVersion
;
567 } else if (strcasecmp(operation
, "HeapDebug") == 0) {
570 } else if (strcasecmp(operation
, "LameDelegationTtl") == 0) {
571 answer_integer
= 0; /* seconds */
573 } else if (strcasecmp(operation
, "LocalNetPriorityNetMask") == 0) {
574 answer_integer
= serverinfo
->dwLocalNetPriorityNetMask
;
576 } else if (strcasecmp(operation
, "MaxCacheSize") == 0) {
579 } else if (strcasecmp(operation
, "MaxResourceRecordsInNonSecureUpdate") == 0) {
580 answer_integer
= 0x0000001E;
582 } else if (strcasecmp(operation
, "OperationsLogLevel") == 0) {
585 } else if (strcasecmp(operation
, "OperationsLogLevel2") == 0) {
588 } else if (strcasecmp(operation
, "MaximumUdpPacketSize") == 0) {
589 answer_integer
= 0x00004000; /* maximum possible */
591 } else if (strcasecmp(operation
, "RecurseToInternetRootMask") == 0) {
594 } else if (strcasecmp(operation
, "SelfTest") == 0) {
597 } else if (strcasecmp(operation
, "SilentlyIgnoreCNameUpdateConflicts") == 0) {
600 } else if (strcasecmp(operation
, "TcpReceivePacketSize") == 0) {
601 answer_integer
= 0x00010000;
603 } else if (strcasecmp(operation
, "XfrThrottleMultiplier") == 0) {
604 answer_integer
= 0x0000000A;
606 } else if (strcasecmp(operation
, "AllowMsdcsLookupRetry") == 0) {
609 } else if (strcasecmp(operation
, "AllowReadOnlyZoneTransfer") == 0) {
612 } else if (strcasecmp(operation
, "DsBackGroundLoadPaused") == 0) {
615 } else if (strcasecmp(operation
, "DsMinimumBackgroundLoadThreads") == 0) {
618 } else if (strcasecmp(operation
, "DsRemoteReplicationDelay") == 0) {
619 answer_integer
= 0x0000001E; /* 30 seconds */
621 } else if (strcasecmp(operation
, "EnableDuplicateQuerySuppresion") == 0) {
624 } else if (strcasecmp(operation
, "EnableGlobalNamesSupport") == 0) {
627 } else if (strcasecmp(operation
, "EnableVersionQuery") == 0) {
628 answer_integer
= 1; /* DNS_VERSION_QUERY_FULL */
630 } else if (strcasecmp(operation
, "EnableRsoForRodc") == 0) {
633 } else if (strcasecmp(operation
, "ForceRODCMode") == 0) {
636 } else if (strcasecmp(operation
, "GlobalNamesAlwaysQuerySrv") == 0) {
639 } else if (strcasecmp(operation
, "GlobalNamesBlockUpdates") == 0) {
642 } else if (strcasecmp(operation
, "GlobalNamesEnableEDnsProbes") == 0) {
645 } else if (strcasecmp(operation
, "GlobalNamesPreferAAAA") == 0) {
648 } else if (strcasecmp(operation
, "GlobalNamesQueryOrder") == 0) {
651 } else if (strcasecmp(operation
, "GlobalNamesSendTimeout") == 0) {
652 answer_integer
= 3; /* seconds */
654 } else if (strcasecmp(operation
, "GlobalNamesServerQueryInterval") == 0) {
655 answer_integer
= 0x00005460; /* 6 hours */
657 } else if (strcasecmp(operation
, "RemoteIPv4RankBoost") == 0) {
660 } else if (strcasecmp(operation
, "RemoteIPv6RankBoost") == 0) {
663 } else if (strcasecmp(operation
, "MaximumRodcRsoAttemptsPerCycle") == 0) {
664 answer_integer
= 0x00000064;
666 } else if (strcasecmp(operation
, "MaximumRodcRsoQueueLength") == 0) {
667 answer_integer
= 0x0000012C;
669 } else if (strcasecmp(operation
, "EnableGlobalQueryBlockList") == 0) {
672 } else if (strcasecmp(operation
, "OpenACLOnProxyUpdates") == 0) {
675 } else if (strcasecmp(operation
, "CacheLockingPercent") == 0) {
676 answer_integer
= 0x00000064;
680 if (is_integer
== 1) {
681 *typeid = DNSSRV_TYPEID_DWORD
;
682 r
->Dword
= answer_integer
;
688 if (strcasecmp(operation
, "Forwarders") == 0) {
689 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
690 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipForwarders
);
692 answer_iparray
= ip4_array_copy(mem_ctx
, serverinfo
->aipForwarders
);
695 } else if (strcasecmp(operation
, "ListenAddresses") == 0) {
696 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
697 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipListenAddrs
);
699 answer_iparray
= ip4_array_copy(mem_ctx
, serverinfo
->aipListenAddrs
);
702 } else if (strcasecmp(operation
, "BreakOnReceiveFrom") == 0) {
703 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
704 answer_addrarray
= NULL
;
706 answer_iparray
= NULL
;
709 } else if (strcasecmp(operation
, "BreakOnUpdateFrom") == 0) {
710 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
711 answer_addrarray
= NULL
;
713 answer_iparray
= NULL
;
716 } else if (strcasecmp(operation
, "LogIPFilterList") == 0) {
717 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
718 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, serverinfo
->aipLogFilter
);
720 answer_iparray
= ip4_array_copy(mem_ctx
, serverinfo
->aipLogFilter
);
725 if (is_addresses
== 1) {
726 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
727 *typeid = DNSSRV_TYPEID_ADDRARRAY
;
728 r
->AddrArray
= answer_addrarray
;
730 *typeid = DNSSRV_TYPEID_IPARRAY
;
731 r
->IpArray
= answer_iparray
;
736 is_string
= is_wstring
= 0;
738 if (strcasecmp(operation
, "DomainDirectoryPartitionBaseName") == 0) {
739 answer_string
= talloc_strdup(mem_ctx
, "DomainDnsZones");
740 if (! answer_string
) {
741 return WERR_OUTOFMEMORY
;
744 } else if (strcasecmp(operation
, "ForestDirectoryPartitionBaseName") == 0) {
745 answer_string
= talloc_strdup(mem_ctx
, "ForestDnsZones");
746 if (! answer_string
) {
747 return WERR_OUTOFMEMORY
;
750 } else if (strcasecmp(operation
, "LogFilePath") == 0) {
751 answer_string
= talloc_strdup(mem_ctx
, serverinfo
->pwszLogFilePath
);
753 } else if (strcasecmp(operation
, "ServerLevelPluginDll") == 0) {
754 answer_string
= NULL
;
756 } else if (strcasecmp(operation
, "DsBackgroundPauseName") == 0) {
757 answer_string
= NULL
;
759 } else if (strcasecmp(operation
, "DsNotRoundRobinTypes") == 0) {
760 answer_string
= NULL
;
764 if (is_string
== 1) {
765 *typeid = DNSSRV_TYPEID_LPSTR
;
766 r
->String
= answer_string
;
768 } else if (is_wstring
== 1) {
769 *typeid = DNSSRV_TYPEID_LPWSTR
;
770 r
->WideString
= answer_string
;
776 if (strcasecmp(operation
, "GlobalQueryBlockList") == 0) {
777 answer_stringlist
= NULL
;
779 } else if (strcasecmp(operation
, "SocketPoolExcludedPortRanges") == 0) {
780 answer_stringlist
= NULL
;
784 if (is_stringlist
== 1) {
785 *typeid = DNSSRV_TYPEID_UTF8_STRING_LIST
;
786 r
->Utf8StringList
= answer_stringlist
;
790 DEBUG(0,("dnsserver: Invalid server operation %s", operation
));
791 return WERR_DNS_ERROR_INVALID_PROPERTY
;
794 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
795 static WERROR
dnsserver_query_zone(struct dnsserver_state
*dsstate
,
797 struct dnsserver_zone
*z
,
798 const char *operation
,
799 const unsigned int client_version
,
800 enum DNS_RPC_TYPEID
*typeid,
801 union DNSSRV_RPC_UNION
*r
)
803 uint8_t is_integer
, is_addresses
, is_string
;
804 uint32_t answer_integer
;
805 struct IP4_ARRAY
*answer_iparray
;
806 struct DNS_ADDR_ARRAY
*answer_addrarray
;
808 struct dnsserver_zoneinfo
*zoneinfo
;
810 zoneinfo
= z
->zoneinfo
;
812 if (strcasecmp(operation
, "Zone") == 0) {
813 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
814 *typeid = DNSSRV_TYPEID_ZONE_W2K
;
815 r
->ZoneW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_W2K
);
817 r
->ZoneW2K
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
818 r
->ZoneW2K
->Flags
= zoneinfo
->Flags
;
819 r
->ZoneW2K
->ZoneType
= zoneinfo
->dwZoneType
;
820 r
->ZoneW2K
->Version
= zoneinfo
->Version
;
822 *typeid = DNSSRV_TYPEID_ZONE
;
823 r
->Zone
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_DOTNET
);
825 r
->Zone
->dwRpcStructureVersion
= 0x01;
826 r
->Zone
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
827 r
->Zone
->Flags
= zoneinfo
->Flags
;
828 r
->Zone
->ZoneType
= zoneinfo
->dwZoneType
;
829 r
->Zone
->Version
= zoneinfo
->Version
;
830 r
->Zone
->dwDpFlags
= z
->partition
->dwDpFlags
;
831 r
->Zone
->pszDpFqdn
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
836 if (strcasecmp(operation
, "ZoneInfo") == 0) {
837 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
838 *typeid = DNSSRV_TYPEID_ZONE_INFO_W2K
;
839 r
->ZoneInfoW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_INFO_W2K
);
841 r
->ZoneInfoW2K
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
842 r
->ZoneInfoW2K
->dwZoneType
= zoneinfo
->dwZoneType
;
843 r
->ZoneInfoW2K
->fReverse
= zoneinfo
->fReverse
;
844 r
->ZoneInfoW2K
->fAllowUpdate
= zoneinfo
->fAllowUpdate
;
845 r
->ZoneInfoW2K
->fPaused
= zoneinfo
->fPaused
;
846 r
->ZoneInfoW2K
->fShutdown
= zoneinfo
->fShutdown
;
847 r
->ZoneInfoW2K
->fAutoCreated
= zoneinfo
->fAutoCreated
;
848 r
->ZoneInfoW2K
->fUseDatabase
= zoneinfo
->fUseDatabase
;
849 r
->ZoneInfoW2K
->pszDataFile
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
850 r
->ZoneInfoW2K
->aipMasters
= ip4_array_copy(mem_ctx
, zoneinfo
->aipMasters
);
851 r
->ZoneInfoW2K
->fSecureSecondaries
= zoneinfo
->fSecureSecondaries
;
852 r
->ZoneInfoW2K
->fNotifyLevel
= zoneinfo
->fNotifyLevel
;
853 r
->ZoneInfoW2K
->aipSecondaries
= ip4_array_copy(mem_ctx
, zoneinfo
->aipSecondaries
);
854 r
->ZoneInfoW2K
->aipNotify
= ip4_array_copy(mem_ctx
, zoneinfo
->aipNotify
);
855 r
->ZoneInfoW2K
->fUseWins
= zoneinfo
->fUseWins
;
856 r
->ZoneInfoW2K
->fUseNbstat
= zoneinfo
->fUseNbstat
;
857 r
->ZoneInfoW2K
->fAging
= zoneinfo
->fAging
;
858 r
->ZoneInfoW2K
->dwNoRefreshInterval
= zoneinfo
->dwNoRefreshInterval
;
859 r
->ZoneInfoW2K
->dwRefreshInterval
= zoneinfo
->dwRefreshInterval
;
860 r
->ZoneInfoW2K
->dwAvailForScavengeTime
= zoneinfo
->dwAvailForScavengeTime
;
861 r
->ZoneInfoW2K
->aipScavengeServers
= ip4_array_copy(mem_ctx
, zoneinfo
->aipScavengeServers
);
863 } else if (client_version
== DNS_CLIENT_VERSION_DOTNET
) {
864 *typeid = DNSSRV_TYPEID_ZONE_INFO_DOTNET
;
865 r
->ZoneInfoDotNet
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_INFO_DOTNET
);
867 r
->ZoneInfoDotNet
->dwRpcStructureVersion
= 0x01;
868 r
->ZoneInfoDotNet
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
869 r
->ZoneInfoDotNet
->dwZoneType
= zoneinfo
->dwZoneType
;
870 r
->ZoneInfoDotNet
->fReverse
= zoneinfo
->fReverse
;
871 r
->ZoneInfoDotNet
->fAllowUpdate
= zoneinfo
->fAllowUpdate
;
872 r
->ZoneInfoDotNet
->fPaused
= zoneinfo
->fPaused
;
873 r
->ZoneInfoDotNet
->fShutdown
= zoneinfo
->fShutdown
;
874 r
->ZoneInfoDotNet
->fAutoCreated
= zoneinfo
->fAutoCreated
;
875 r
->ZoneInfoDotNet
->fUseDatabase
= zoneinfo
->fUseDatabase
;
876 r
->ZoneInfoDotNet
->pszDataFile
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
877 r
->ZoneInfoDotNet
->aipMasters
= ip4_array_copy(mem_ctx
, zoneinfo
->aipMasters
);
878 r
->ZoneInfoDotNet
->fSecureSecondaries
= zoneinfo
->fSecureSecondaries
;
879 r
->ZoneInfoDotNet
->fNotifyLevel
= zoneinfo
->fNotifyLevel
;
880 r
->ZoneInfoDotNet
->aipSecondaries
= ip4_array_copy(mem_ctx
, zoneinfo
->aipSecondaries
);
881 r
->ZoneInfoDotNet
->aipNotify
= ip4_array_copy(mem_ctx
, zoneinfo
->aipNotify
);
882 r
->ZoneInfoDotNet
->fUseWins
= zoneinfo
->fUseWins
;
883 r
->ZoneInfoDotNet
->fUseNbstat
= zoneinfo
->fUseNbstat
;
884 r
->ZoneInfoDotNet
->fAging
= zoneinfo
->fAging
;
885 r
->ZoneInfoDotNet
->dwNoRefreshInterval
= zoneinfo
->dwNoRefreshInterval
;
886 r
->ZoneInfoDotNet
->dwRefreshInterval
= zoneinfo
->dwRefreshInterval
;
887 r
->ZoneInfoDotNet
->dwAvailForScavengeTime
= zoneinfo
->dwAvailForScavengeTime
;
888 r
->ZoneInfoDotNet
->aipScavengeServers
= ip4_array_copy(mem_ctx
, zoneinfo
->aipScavengeServers
);
889 r
->ZoneInfoDotNet
->dwForwarderTimeout
= zoneinfo
->dwForwarderTimeout
;
890 r
->ZoneInfoDotNet
->fForwarderSlave
= zoneinfo
->fForwarderSlave
;
891 r
->ZoneInfoDotNet
->aipLocalMasters
= ip4_array_copy(mem_ctx
, zoneinfo
->aipLocalMasters
);
892 r
->ZoneInfoDotNet
->dwDpFlags
= z
->partition
->dwDpFlags
;
893 r
->ZoneInfoDotNet
->pszDpFqdn
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
894 r
->ZoneInfoDotNet
->pwszZoneDn
= talloc_strdup(mem_ctx
, zoneinfo
->pwszZoneDn
);
895 r
->ZoneInfoDotNet
->dwLastSuccessfulSoaCheck
= zoneinfo
->dwLastSuccessfulSoaCheck
;
896 r
->ZoneInfoDotNet
->dwLastSuccessfulXfr
= zoneinfo
->dwLastSuccessfulXfr
;
899 *typeid = DNSSRV_TYPEID_ZONE_INFO
;
900 r
->ZoneInfo
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_INFO_LONGHORN
);
902 r
->ZoneInfo
->dwRpcStructureVersion
= 0x02;
903 r
->ZoneInfo
->pszZoneName
= talloc_strdup(mem_ctx
, z
->name
);
904 r
->ZoneInfo
->dwZoneType
= zoneinfo
->dwZoneType
;
905 r
->ZoneInfo
->fReverse
= zoneinfo
->fReverse
;
906 r
->ZoneInfo
->fAllowUpdate
= zoneinfo
->fAllowUpdate
;
907 r
->ZoneInfo
->fPaused
= zoneinfo
->fPaused
;
908 r
->ZoneInfo
->fShutdown
= zoneinfo
->fShutdown
;
909 r
->ZoneInfo
->fAutoCreated
= zoneinfo
->fAutoCreated
;
910 r
->ZoneInfo
->fUseDatabase
= zoneinfo
->fUseDatabase
;
911 r
->ZoneInfo
->pszDataFile
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
912 r
->ZoneInfo
->aipMasters
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipMasters
);
913 r
->ZoneInfo
->fSecureSecondaries
= zoneinfo
->fSecureSecondaries
;
914 r
->ZoneInfo
->fNotifyLevel
= zoneinfo
->fNotifyLevel
;
915 r
->ZoneInfo
->aipSecondaries
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipSecondaries
);
916 r
->ZoneInfo
->aipNotify
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipNotify
);
917 r
->ZoneInfo
->fUseWins
= zoneinfo
->fUseWins
;
918 r
->ZoneInfo
->fUseNbstat
= zoneinfo
->fUseNbstat
;
919 r
->ZoneInfo
->fAging
= zoneinfo
->fAging
;
920 r
->ZoneInfo
->dwNoRefreshInterval
= zoneinfo
->dwNoRefreshInterval
;
921 r
->ZoneInfo
->dwRefreshInterval
= zoneinfo
->dwRefreshInterval
;
922 r
->ZoneInfo
->dwAvailForScavengeTime
= zoneinfo
->dwAvailForScavengeTime
;
923 r
->ZoneInfo
->aipScavengeServers
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipScavengeServers
);
924 r
->ZoneInfo
->dwForwarderTimeout
= zoneinfo
->dwForwarderTimeout
;
925 r
->ZoneInfo
->fForwarderSlave
= zoneinfo
->fForwarderSlave
;
926 r
->ZoneInfo
->aipLocalMasters
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipLocalMasters
);
927 r
->ZoneInfo
->dwDpFlags
= z
->partition
->dwDpFlags
;
928 r
->ZoneInfo
->pszDpFqdn
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
929 r
->ZoneInfo
->pwszZoneDn
= talloc_strdup(mem_ctx
, zoneinfo
->pwszZoneDn
);
930 r
->ZoneInfo
->dwLastSuccessfulSoaCheck
= zoneinfo
->dwLastSuccessfulSoaCheck
;
931 r
->ZoneInfo
->dwLastSuccessfulXfr
= zoneinfo
->dwLastSuccessfulXfr
;
933 r
->ZoneInfo
->fQueuedForBackgroundLoad
= zoneinfo
->fQueuedForBackgroundLoad
;
934 r
->ZoneInfo
->fBackgroundLoadInProgress
= zoneinfo
->fBackgroundLoadInProgress
;
935 r
->ZoneInfo
->fReadOnlyZone
= zoneinfo
->fReadOnlyZone
;
936 r
->ZoneInfo
->dwLastXfrAttempt
= zoneinfo
->dwLastXfrAttempt
;
937 r
->ZoneInfo
->dwLastXfrResult
= zoneinfo
->dwLastXfrResult
;
945 if (strcasecmp(operation
, "AllowUpdate") == 0) {
946 answer_integer
= zoneinfo
->fAllowUpdate
;
948 } else if (strcasecmp(operation
, "Secured") == 0) {
951 } else if (strcasecmp(operation
, "DsIntegrated") == 0) {
952 answer_integer
= zoneinfo
->fUseDatabase
;
954 } else if (strcasecmp(operation
, "LogUpdates") == 0) {
957 } else if (strcasecmp(operation
, "NoRefreshInterval") == 0) {
958 answer_integer
= zoneinfo
->dwNoRefreshInterval
;
960 } else if (strcasecmp(operation
, "NotifyLevel") == 0) {
961 answer_integer
= zoneinfo
->fNotifyLevel
;
963 } else if (strcasecmp(operation
, "RefreshInterval") == 0) {
964 answer_integer
= zoneinfo
->dwRefreshInterval
;
966 } else if (strcasecmp(operation
, "SecureSecondaries") == 0) {
967 answer_integer
= zoneinfo
->fSecureSecondaries
;
969 } else if (strcasecmp(operation
, "Type") == 0) {
970 answer_integer
= zoneinfo
->dwZoneType
;
972 } else if (strcasecmp(operation
, "Aging") == 0) {
973 answer_integer
= zoneinfo
->fAging
;
975 } else if (strcasecmp(operation
, "ForwarderSlave") == 0) {
976 answer_integer
= zoneinfo
->fForwarderSlave
;
978 } else if (strcasecmp(operation
, "ForwarderTimeout") == 0) {
979 answer_integer
= zoneinfo
->dwForwarderTimeout
;
981 } else if (strcasecmp(operation
, "Unicode") == 0) {
986 if (is_integer
== 1) {
987 *typeid = DNSSRV_TYPEID_DWORD
;
988 r
->Dword
= answer_integer
;
994 if (strcasecmp(operation
, "AllowNSRecordsAutoCreation") == 0) {
995 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
996 answer_addrarray
= NULL
;
998 answer_iparray
= NULL
;
1001 } else if (strcasecmp(operation
, "ScavengeServers") == 0) {
1002 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1003 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipScavengeServers
);
1005 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipScavengeServers
);
1008 } else if (strcasecmp(operation
, "MasterServers") == 0) {
1009 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1010 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipMasters
);
1012 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipMasters
);
1015 } else if (strcasecmp(operation
, "LocalMasterServers") == 0) {
1016 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1017 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipLocalMasters
);
1019 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipLocalMasters
);
1022 } else if (strcasecmp(operation
, "NotifyServers") == 0) {
1023 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1024 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipNotify
);
1026 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipNotify
);
1029 } else if (strcasecmp(operation
, "SecondaryServers") == 0) {
1030 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1031 answer_addrarray
= ip4_array_to_dns_addr_array(mem_ctx
, zoneinfo
->aipSecondaries
);
1033 answer_iparray
= ip4_array_copy(mem_ctx
, zoneinfo
->aipSecondaries
);
1038 if (is_addresses
== 1) {
1039 if (client_version
== DNS_CLIENT_VERSION_LONGHORN
) {
1040 *typeid = DNSSRV_TYPEID_ADDRARRAY
;
1041 r
->AddrArray
= answer_addrarray
;
1043 *typeid = DNSSRV_TYPEID_IPARRAY
;
1044 r
->IpArray
= answer_iparray
;
1051 if (strcasecmp(operation
, "DatabaseFile") == 0) {
1052 answer_string
= talloc_strdup(mem_ctx
, zoneinfo
->pszDataFile
);
1054 } else if (strcasecmp(operation
, "ApplicationDirectoryPartition") == 0) {
1055 answer_string
= talloc_strdup(mem_ctx
, z
->partition
->pszDpFqdn
);
1057 } else if (strcasecmp(operation
, "BreakOnNameUpdate") == 0) {
1058 answer_string
= NULL
;
1062 if (is_string
== 1) {
1063 *typeid = DNSSRV_TYPEID_LPSTR
;
1064 r
->String
= answer_string
;
1068 DEBUG(0,("dnsserver: Invalid zone operation %s", operation
));
1069 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1073 /* dnsserver operation functions */
1075 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
1076 static WERROR
dnsserver_operate_server(struct dnsserver_state
*dsstate
,
1077 TALLOC_CTX
*mem_ctx
,
1078 const char *operation
,
1079 const unsigned int client_version
,
1080 enum DNS_RPC_TYPEID
typeid,
1081 union DNSSRV_RPC_UNION
*r
)
1083 bool valid_operation
= false;
1085 if (strcasecmp(operation
, "ResetDwordProperty") == 0) {
1086 valid_operation
= true;
1087 } else if (strcasecmp(operation
, "Restart") == 0) {
1088 valid_operation
= true;
1089 } else if (strcasecmp(operation
, "ClearDebugLog") == 0) {
1090 valid_operation
= true;
1091 } else if (strcasecmp(operation
, "ClearCache") == 0) {
1092 valid_operation
= true;
1093 } else if (strcasecmp(operation
, "WriteDirtyZones") == 0) {
1094 valid_operation
= true;
1095 } else if (strcasecmp(operation
, "ZoneCreate") == 0) {
1096 struct dnsserver_zone
*z
, *z2
;
1099 z
= talloc_zero(mem_ctx
, struct dnsserver_zone
);
1100 W_ERROR_HAVE_NO_MEMORY(z
);
1101 z
->partition
= talloc_zero(z
, struct dnsserver_partition
);
1102 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z
->partition
, z
);
1103 z
->zoneinfo
= talloc_zero(z
, struct dnsserver_zoneinfo
);
1104 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z
->zoneinfo
, z
);
1106 if (typeid == DNSSRV_TYPEID_ZONE_CREATE_W2K
) {
1107 z
->name
= talloc_strdup(z
, r
->ZoneCreateW2K
->pszZoneName
);
1108 z
->zoneinfo
->dwZoneType
= r
->ZoneCreateW2K
->dwZoneType
;
1109 z
->zoneinfo
->fAllowUpdate
= r
->ZoneCreateW2K
->fAllowUpdate
;
1110 z
->zoneinfo
->fAging
= r
->ZoneCreateW2K
->fAging
;
1111 z
->zoneinfo
->Flags
= r
->ZoneCreateW2K
->dwFlags
;
1112 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE_DOTNET
) {
1113 z
->name
= talloc_strdup(z
, r
->ZoneCreateDotNet
->pszZoneName
);
1114 z
->zoneinfo
->dwZoneType
= r
->ZoneCreateDotNet
->dwZoneType
;
1115 z
->zoneinfo
->fAllowUpdate
= r
->ZoneCreateDotNet
->fAllowUpdate
;
1116 z
->zoneinfo
->fAging
= r
->ZoneCreateDotNet
->fAging
;
1117 z
->zoneinfo
->Flags
= r
->ZoneCreateDotNet
->dwFlags
;
1118 z
->partition
->dwDpFlags
= r
->ZoneCreateDotNet
->dwDpFlags
;
1119 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE
) {
1120 z
->name
= talloc_strdup(z
, r
->ZoneCreate
->pszZoneName
);
1121 z
->zoneinfo
->dwZoneType
= r
->ZoneCreate
->dwZoneType
;
1122 z
->zoneinfo
->fAllowUpdate
= r
->ZoneCreate
->fAllowUpdate
;
1123 z
->zoneinfo
->fAging
= r
->ZoneCreate
->fAging
;
1124 z
->zoneinfo
->Flags
= r
->ZoneCreate
->dwFlags
;
1125 z
->partition
->dwDpFlags
= r
->ZoneCreate
->dwDpFlags
;
1128 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1131 z2
= dnsserver_find_zone(dsstate
->zones
, z
->name
);
1134 return WERR_DNS_ERROR_ZONE_ALREADY_EXISTS
;
1137 status
= dnsserver_db_create_zone(dsstate
->samdb
, dsstate
->partitions
, z
,
1141 if (W_ERROR_IS_OK(status
)) {
1142 dnsserver_reload_zones(dsstate
);
1145 } else if (strcasecmp(operation
, "ClearStatistics") == 0) {
1146 valid_operation
= true;
1147 } else if (strcasecmp(operation
, "EnlistDirectoryPartition") == 0) {
1148 valid_operation
= true;
1149 } else if (strcasecmp(operation
, "StartScavenging") == 0) {
1150 valid_operation
= true;
1151 } else if (strcasecmp(operation
, "AbortScavenging") == 0) {
1152 valid_operation
= true;
1153 } else if (strcasecmp(operation
, "AutoConfigure") == 0) {
1154 valid_operation
= true;
1155 } else if (strcasecmp(operation
, "ExportSettings") == 0) {
1156 valid_operation
= true;
1157 } else if (strcasecmp(operation
, "PrepareForDemotion") == 0) {
1158 valid_operation
= true;
1159 } else if (strcasecmp(operation
, "PrepareForUninstall") == 0) {
1160 valid_operation
= true;
1161 } else if (strcasecmp(operation
, "DeleteNode") == 0) {
1162 valid_operation
= true;
1163 } else if (strcasecmp(operation
, "DeleteRecord") == 0) {
1164 valid_operation
= true;
1165 } else if (strcasecmp(operation
, "WriteBackFile") == 0) {
1166 valid_operation
= true;
1167 } else if (strcasecmp(operation
, "ListenAddresses") == 0) {
1168 valid_operation
= true;
1169 } else if (strcasecmp(operation
, "Forwarders") == 0) {
1170 valid_operation
= true;
1171 } else if (strcasecmp(operation
, "LogFilePath") == 0) {
1172 valid_operation
= true;
1173 } else if (strcasecmp(operation
, "LogIpFilterList") == 0) {
1174 valid_operation
= true;
1175 } else if (strcasecmp(operation
, "ForestDirectoryPartitionBaseName") == 0) {
1176 valid_operation
= true;
1177 } else if (strcasecmp(operation
, "DomainDirectoryPartitionBaseName") == 0) {
1178 valid_operation
= true;
1179 } else if (strcasecmp(operation
, "GlobalQueryBlockList") == 0) {
1180 valid_operation
= true;
1181 } else if (strcasecmp(operation
, "BreakOnReceiveFrom") == 0) {
1182 valid_operation
= true;
1183 } else if (strcasecmp(operation
, "BreakOnUpdateFrom") == 0) {
1184 valid_operation
= true;
1185 } else if (strcasecmp(operation
, "ServerLevelPluginDll") == 0) {
1186 valid_operation
= true;
1189 if (valid_operation
) {
1190 DEBUG(0, ("dnsserver: server operation '%s' not implemented", operation
));
1191 return WERR_CALL_NOT_IMPLEMENTED
;
1194 DEBUG(0, ("dnsserver: invalid server operation '%s'", operation
));
1195 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1198 static WERROR
dnsserver_complex_operate_server(struct dnsserver_state
*dsstate
,
1199 TALLOC_CTX
*mem_ctx
,
1200 const char *operation
,
1201 const unsigned int client_version
,
1202 enum DNS_RPC_TYPEID typeid_in
,
1203 union DNSSRV_RPC_UNION
*rin
,
1204 enum DNS_RPC_TYPEID
*typeid_out
,
1205 union DNSSRV_RPC_UNION
*rout
)
1207 int valid_operation
= 0;
1208 struct dnsserver_zone
*z
, **zlist
;
1210 bool found1
, found2
, found3
, found4
;
1213 if (strcasecmp(operation
, "QueryDwordProperty") == 0) {
1214 if (typeid_in
== DNSSRV_TYPEID_LPSTR
) {
1215 return dnsserver_query_server(dsstate
, mem_ctx
,
1221 } else if (strcasecmp(operation
, "EnumZones") == 0) {
1222 if (typeid_in
!= DNSSRV_TYPEID_DWORD
) {
1223 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1227 zlist
= talloc_zero_array(mem_ctx
, struct dnsserver_zone
*, 0);
1228 for (z
= dsstate
->zones
; z
; z
= z
->next
) {
1230 /* Match the flags in groups
1232 * Group1 : PRIMARY, SECONDARY, CACHE, AUTO
1233 * Group2 : FORWARD, REVERSE, FORWARDER, STUB
1234 * Group3 : DS, NON_DS, DOMAIN_DP, FOREST_DP
1235 * Group4 : CUSTOM_DP, LEGACY_DP
1240 if (rin
->Dword
& 0x0000000f) {
1241 if (rin
->Dword
& DNS_ZONE_REQUEST_PRIMARY
) {
1242 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_PRIMARY
) {
1246 if (rin
->Dword
& DNS_ZONE_REQUEST_SECONDARY
) {
1247 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_SECONDARY
) {
1251 if (rin
->Dword
& DNS_ZONE_REQUEST_CACHE
) {
1252 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_CACHE
) {
1256 if (rin
->Dword
& DNS_ZONE_REQUEST_AUTO
) {
1257 if (z
->zoneinfo
->fAutoCreated
1258 || z
->partition
->dwDpFlags
& DNS_DP_AUTOCREATED
) {
1268 if (rin
->Dword
& 0x000000f0) {
1269 if (rin
->Dword
& DNS_ZONE_REQUEST_FORWARD
) {
1270 if (!(z
->zoneinfo
->fReverse
)) {
1274 if (rin
->Dword
& DNS_ZONE_REQUEST_REVERSE
) {
1275 if (z
->zoneinfo
->fReverse
) {
1279 if (rin
->Dword
& DNS_ZONE_REQUEST_FORWARDER
) {
1280 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_FORWARDER
) {
1284 if (rin
->Dword
& DNS_ZONE_REQUEST_STUB
) {
1285 if (z
->zoneinfo
->dwZoneType
== DNS_ZONE_TYPE_STUB
) {
1295 if (rin
->Dword
& 0x00000f00) {
1296 if (rin
->Dword
& DNS_ZONE_REQUEST_DS
) {
1297 if (z
->zoneinfo
->Flags
& DNS_RPC_ZONE_DSINTEGRATED
) {
1301 if (rin
->Dword
& DNS_ZONE_REQUEST_NON_DS
) {
1302 if (!(z
->zoneinfo
->Flags
& DNS_RPC_ZONE_DSINTEGRATED
)) {
1306 if (rin
->Dword
& DNS_ZONE_REQUEST_DOMAIN_DP
) {
1307 if (!(z
->partition
->dwDpFlags
& DNS_DP_DOMAIN_DEFAULT
)) {
1311 if (rin
->Dword
& DNS_ZONE_REQUEST_FOREST_DP
) {
1312 if (!(z
->partition
->dwDpFlags
& DNS_DP_FOREST_DEFAULT
)) {
1321 if (rin
->Dword
& 0x0000f000) {
1327 if (found1
&& found2
&& found3
&& found4
) {
1328 zlist
= talloc_realloc(mem_ctx
, zlist
, struct dnsserver_zone
*, zcount
+1);
1334 if (client_version
== DNS_CLIENT_VERSION_W2K
) {
1335 *typeid_out
= DNSSRV_TYPEID_ZONE_LIST_W2K
;
1336 rout
->ZoneListW2K
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_LIST_W2K
);
1339 rout
->ZoneListW2K
->dwZoneCount
= 0;
1340 rout
->ZoneListW2K
->ZoneArray
= NULL
;
1345 rout
->ZoneListW2K
->ZoneArray
= talloc_zero_array(mem_ctx
, struct DNS_RPC_ZONE_W2K
*, zcount
);
1346 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout
->ZoneListW2K
->ZoneArray
, zlist
);
1348 for (i
=0; i
<zcount
; i
++) {
1349 rout
->ZoneListW2K
->ZoneArray
[i
] = talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_W2K
);
1351 rout
->ZoneListW2K
->ZoneArray
[i
]->pszZoneName
= talloc_strdup(mem_ctx
, zlist
[i
]->name
);
1352 rout
->ZoneListW2K
->ZoneArray
[i
]->Flags
= zlist
[i
]->zoneinfo
->Flags
;
1353 rout
->ZoneListW2K
->ZoneArray
[i
]->ZoneType
= zlist
[i
]->zoneinfo
->dwZoneType
;
1354 rout
->ZoneListW2K
->ZoneArray
[i
]->Version
= zlist
[i
]->zoneinfo
->Version
;
1356 rout
->ZoneListW2K
->dwZoneCount
= zcount
;
1359 *typeid_out
= DNSSRV_TYPEID_ZONE_LIST
;
1360 rout
->ZoneList
= talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_LIST_DOTNET
);
1363 rout
->ZoneList
->dwRpcStructureVersion
= 1;
1364 rout
->ZoneList
->dwZoneCount
= 0;
1365 rout
->ZoneList
->ZoneArray
= NULL
;
1370 rout
->ZoneList
->ZoneArray
= talloc_zero_array(mem_ctx
, struct DNS_RPC_ZONE_DOTNET
*, zcount
);
1371 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout
->ZoneList
->ZoneArray
, zlist
);
1373 for (i
=0; i
<zcount
; i
++) {
1374 rout
->ZoneList
->ZoneArray
[i
] = talloc_zero(mem_ctx
, struct DNS_RPC_ZONE_DOTNET
);
1376 rout
->ZoneList
->ZoneArray
[i
]->dwRpcStructureVersion
= 1;
1377 rout
->ZoneList
->ZoneArray
[i
]->pszZoneName
= talloc_strdup(mem_ctx
, zlist
[i
]->name
);
1378 rout
->ZoneList
->ZoneArray
[i
]->Flags
= zlist
[i
]->zoneinfo
->Flags
;
1379 rout
->ZoneList
->ZoneArray
[i
]->ZoneType
= zlist
[i
]->zoneinfo
->dwZoneType
;
1380 rout
->ZoneList
->ZoneArray
[i
]->Version
= zlist
[i
]->zoneinfo
->Version
;
1381 rout
->ZoneList
->ZoneArray
[i
]->dwDpFlags
= zlist
[i
]->partition
->dwDpFlags
;
1382 rout
->ZoneList
->ZoneArray
[i
]->pszDpFqdn
= talloc_strdup(mem_ctx
, zlist
[i
]->partition
->pszDpFqdn
);
1384 rout
->ZoneList
->dwRpcStructureVersion
= 1;
1385 rout
->ZoneList
->dwZoneCount
= zcount
;
1389 } else if (strcasecmp(operation
, "EnumZones2") == 0) {
1390 valid_operation
= true;
1391 } else if (strcasecmp(operation
, "EnumDirectoryPartitions") == 0) {
1392 if (typeid_in
!= DNSSRV_TYPEID_DWORD
) {
1393 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1396 *typeid_out
= DNSSRV_TYPEID_DP_LIST
;
1397 rout
->DirectoryPartitionList
= talloc_zero(mem_ctx
, struct DNS_RPC_DP_LIST
);
1399 if (rin
->Dword
!= 0) {
1400 rout
->DirectoryPartitionList
->dwDpCount
= 0;
1401 rout
->DirectoryPartitionList
->DpArray
= NULL
;
1403 struct DNS_RPC_DP_ENUM
**dplist
;
1404 struct dnsserver_partition
*p
;
1407 dplist
= talloc_zero_array(mem_ctx
, struct DNS_RPC_DP_ENUM
*, pcount
);
1408 W_ERROR_HAVE_NO_MEMORY(dplist
);
1410 p
= dsstate
->partitions
;
1411 for (i
=0; i
<pcount
; i
++) {
1412 dplist
[i
] = talloc_zero(dplist
, struct DNS_RPC_DP_ENUM
);
1414 dplist
[i
]->pszDpFqdn
= talloc_strdup(mem_ctx
, p
->pszDpFqdn
);
1415 dplist
[i
]->dwFlags
= p
->dwDpFlags
;
1416 dplist
[i
]->dwZoneCount
= p
->zones_count
;
1420 rout
->DirectoryPartitionList
->dwDpCount
= pcount
;
1421 rout
->DirectoryPartitionList
->DpArray
= dplist
;
1424 } else if (strcasecmp(operation
, "DirectoryPartitionInfo") == 0) {
1425 struct dnsserver_partition
*p
;
1426 struct dnsserver_partition_info
*partinfo
;
1427 struct DNS_RPC_DP_INFO
*dpinfo
= NULL
;
1429 if (typeid_in
!= DNSSRV_TYPEID_LPSTR
) {
1430 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1433 *typeid_out
= DNSSRV_TYPEID_DP_INFO
;
1435 for (p
= dsstate
->partitions
; p
; p
= p
->next
) {
1436 if (strcasecmp(p
->pszDpFqdn
, rin
->String
) == 0) {
1437 dpinfo
= talloc_zero(mem_ctx
, struct DNS_RPC_DP_INFO
);
1438 W_ERROR_HAVE_NO_MEMORY(dpinfo
);
1440 partinfo
= dnsserver_db_partition_info(mem_ctx
, dsstate
->samdb
, p
);
1441 W_ERROR_HAVE_NO_MEMORY(partinfo
);
1443 dpinfo
->pszDpFqdn
= talloc_strdup(dpinfo
, p
->pszDpFqdn
);
1444 dpinfo
->pszDpDn
= talloc_strdup(dpinfo
, ldb_dn_get_linearized(p
->partition_dn
));
1445 dpinfo
->pszCrDn
= talloc_steal(dpinfo
, partinfo
->pszCrDn
);
1446 dpinfo
->dwFlags
= p
->dwDpFlags
;
1447 dpinfo
->dwZoneCount
= p
->zones_count
;
1448 dpinfo
->dwState
= partinfo
->dwState
;
1449 dpinfo
->dwReplicaCount
= partinfo
->dwReplicaCount
;
1450 if (partinfo
->dwReplicaCount
> 0) {
1451 dpinfo
->ReplicaArray
= talloc_steal(dpinfo
,
1452 partinfo
->ReplicaArray
);
1454 dpinfo
->ReplicaArray
= NULL
;
1460 if (dpinfo
== NULL
) {
1461 return WERR_DNS_ERROR_DP_DOES_NOT_EXIST
;
1464 rout
->DirectoryPartition
= dpinfo
;
1466 } else if (strcasecmp(operation
, "Statistics") == 0) {
1467 valid_operation
= true;
1468 } else if (strcasecmp(operation
, "IpValidate") == 0) {
1469 valid_operation
= true;
1472 if (valid_operation
) {
1473 DEBUG(0, ("dnsserver: server complex operation '%s' not implemented", operation
));
1474 return WERR_CALL_NOT_IMPLEMENTED
;
1477 DEBUG(0, ("dnsserver: invalid server complex operation '%s'", operation
));
1478 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1481 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
1482 static WERROR
dnsserver_operate_zone(struct dnsserver_state
*dsstate
,
1483 TALLOC_CTX
*mem_ctx
,
1484 struct dnsserver_zone
*z
,
1485 unsigned int request_filter
,
1486 const char *operation
,
1487 const unsigned int client_version
,
1488 enum DNS_RPC_TYPEID
typeid,
1489 union DNSSRV_RPC_UNION
*r
)
1491 bool valid_operation
= false;
1493 if (strcasecmp(operation
, "ResetDwordProperty") == 0) {
1494 if (typeid != DNSSRV_TYPEID_NAME_AND_PARAM
) {
1495 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1498 /* Ignore property resets */
1499 if (strcasecmp(r
->NameAndParam
->pszNodeName
, "AllowUpdate") == 0) {
1502 valid_operation
= true;
1503 } else if (strcasecmp(operation
, "ZoneTypeReset") == 0) {
1504 valid_operation
= true;
1505 } else if (strcasecmp(operation
, "PauseZone") == 0) {
1506 valid_operation
= true;
1507 } else if (strcasecmp(operation
, "ResumeZone") == 0) {
1508 valid_operation
= true;
1509 } else if (strcasecmp(operation
, "DeleteZone") == 0) {
1510 valid_operation
= true;
1511 } else if (strcasecmp(operation
, "ReloadZone") == 0) {
1512 valid_operation
= true;
1513 } else if (strcasecmp(operation
, "RefreshZone") == 0) {
1514 valid_operation
= true;
1515 } else if (strcasecmp(operation
, "ExpireZone") == 0) {
1516 valid_operation
= true;
1517 } else if (strcasecmp(operation
, "IncrementVersion") == 0) {
1518 valid_operation
= true;
1519 } else if (strcasecmp(operation
, "WriteBackFile") == 0) {
1520 valid_operation
= true;
1521 } else if (strcasecmp(operation
, "DeleteZoneFromDs") == 0) {
1524 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
1526 status
= dnsserver_db_delete_zone(dsstate
->samdb
, z
);
1527 if (W_ERROR_IS_OK(status
)) {
1528 dnsserver_reload_zones(dsstate
);
1531 } else if (strcasecmp(operation
, "UpdateZoneFromDs") == 0) {
1532 valid_operation
= true;
1533 } else if (strcasecmp(operation
, "ZoneExport") == 0) {
1534 valid_operation
= true;
1535 } else if (strcasecmp(operation
, "ZoneChangeDirectoryPartition") == 0) {
1536 valid_operation
= true;
1537 } else if (strcasecmp(operation
, "DeleteNode") == 0) {
1538 valid_operation
= true;
1539 } else if (strcasecmp(operation
, "DeleteRecordSet") == 0) {
1540 valid_operation
= true;
1541 } else if (strcasecmp(operation
, "ForceAgingOnNode") == 0) {
1542 valid_operation
= true;
1543 } else if (strcasecmp(operation
, "DatabaseFile") == 0) {
1544 valid_operation
= true;
1545 } else if (strcasecmp(operation
, "MasterServers") == 0) {
1546 valid_operation
= true;
1547 } else if (strcasecmp(operation
, "LocalMasterServers") == 0) {
1548 valid_operation
= true;
1549 } else if (strcasecmp(operation
, "NotifyServers") == 0) {
1550 valid_operation
= true;
1551 } else if (strcasecmp(operation
, "SecondaryServers") == 0) {
1552 valid_operation
= true;
1553 } else if (strcasecmp(operation
, "ScavengingServers") == 0) {
1554 valid_operation
= true;
1555 } else if (strcasecmp(operation
, "AllowNSRecordsAutoCreation") == 0) {
1556 valid_operation
= true;
1557 } else if (strcasecmp(operation
, "BreakOnNameUpdate") == 0) {
1558 valid_operation
= true;
1559 } else if (strcasecmp(operation
, "ApplicationDirectoryPartition") == 0) {
1560 valid_operation
= true;
1563 if (valid_operation
) {
1564 DEBUG(0, ("dnsserver: zone operation '%s' not implemented", operation
));
1565 return WERR_CALL_NOT_IMPLEMENTED
;
1568 DEBUG(0, ("dnsserver: invalid zone operation '%s'", operation
));
1569 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1572 static WERROR
dnsserver_complex_operate_zone(struct dnsserver_state
*dsstate
,
1573 TALLOC_CTX
*mem_ctx
,
1574 struct dnsserver_zone
*z
,
1575 const char *operation
,
1576 const unsigned int client_version
,
1577 enum DNS_RPC_TYPEID typeid_in
,
1578 union DNSSRV_RPC_UNION
*rin
,
1579 enum DNS_RPC_TYPEID
*typeid_out
,
1580 union DNSSRV_RPC_UNION
*rout
)
1582 if (strcasecmp(operation
, "QueryDwordProperty") == 0) {
1583 if (typeid_in
== DNSSRV_TYPEID_LPSTR
) {
1584 return dnsserver_query_zone(dsstate
, mem_ctx
, z
,
1593 DEBUG(0,("dnsserver: Invalid zone operation %s", operation
));
1594 return WERR_DNS_ERROR_INVALID_PROPERTY
;
1597 /* dnsserver enumerate function */
1599 static WERROR
dnsserver_enumerate_root_records(struct dnsserver_state
*dsstate
,
1600 TALLOC_CTX
*mem_ctx
,
1601 unsigned int client_version
,
1602 const char *node_name
,
1603 enum dns_record_type record_type
,
1604 unsigned int select_flag
,
1605 unsigned int *buffer_length
,
1606 struct DNS_RPC_RECORDS_ARRAY
**buffer
)
1608 TALLOC_CTX
*tmp_ctx
;
1609 struct dnsserver_zone
*z
;
1610 const char * const attrs
[] = { "name", "dnsRecord", NULL
};
1611 struct ldb_result
*res
;
1612 struct DNS_RPC_RECORDS_ARRAY
*recs
;
1619 tmp_ctx
= talloc_new(mem_ctx
);
1620 W_ERROR_HAVE_NO_MEMORY(tmp_ctx
);
1622 z
= dnsserver_find_zone(dsstate
->zones
, ".");
1624 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
1627 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1628 LDB_SCOPE_ONELEVEL
, attrs
, "(&(objectClass=dnsNode)(name=@))");
1629 if (ret
!= LDB_SUCCESS
) {
1630 talloc_free(tmp_ctx
);
1631 return WERR_INTERNAL_DB_ERROR
;
1633 if (res
->count
== 0) {
1634 talloc_free(tmp_ctx
);
1635 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
1638 recs
= talloc_zero(mem_ctx
, struct DNS_RPC_RECORDS_ARRAY
);
1639 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs
, tmp_ctx
);
1644 for (i
=0; i
<res
->count
; i
++) {
1645 status
= dns_fill_records_array(tmp_ctx
, NULL
, record_type
,
1647 res
->msgs
[i
], 0, recs
,
1648 &add_names
, &add_count
);
1649 if (!W_ERROR_IS_OK(status
)) {
1650 talloc_free(tmp_ctx
);
1656 /* Add any additional records */
1657 if (select_flag
& DNS_RPC_VIEW_ADDITIONAL_DATA
) {
1658 for (i
=0; i
<add_count
; i
++) {
1659 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1660 LDB_SCOPE_ONELEVEL
, attrs
,
1661 "(&(objectClass=dnsNode)(name=%s))", add_names
[i
]);
1662 if (ret
!= LDB_SUCCESS
|| res
->count
== 0) {
1667 len
= strlen(add_names
[i
]);
1668 if (add_names
[i
][len
-1] == '.') {
1669 rname
= talloc_strdup(tmp_ctx
, add_names
[i
]);
1671 rname
= talloc_asprintf(tmp_ctx
, "%s.", add_names
[i
]);
1673 status
= dns_fill_records_array(tmp_ctx
, NULL
, DNS_TYPE_A
,
1675 res
->msgs
[0], 0, recs
,
1682 talloc_free(tmp_ctx
);
1684 *buffer_length
= ndr_size_DNS_RPC_RECORDS_ARRAY(recs
, 0);
1691 static WERROR
dnsserver_enumerate_records(struct dnsserver_state
*dsstate
,
1692 TALLOC_CTX
*mem_ctx
,
1693 struct dnsserver_zone
*z
,
1694 unsigned int client_version
,
1695 const char *node_name
,
1696 const char *start_child
,
1697 enum dns_record_type record_type
,
1698 unsigned int select_flag
,
1699 const char *filter_start
,
1700 const char *filter_stop
,
1701 unsigned int *buffer_length
,
1702 struct DNS_RPC_RECORDS_ARRAY
**buffer
)
1704 TALLOC_CTX
*tmp_ctx
;
1706 const char * const attrs
[] = { "name", "dnsRecord", NULL
};
1707 struct ldb_result
*res
;
1708 struct DNS_RPC_RECORDS_ARRAY
*recs
;
1709 char **add_names
= NULL
;
1714 struct dns_tree
*tree
, *base
, *node
;
1716 tmp_ctx
= talloc_new(mem_ctx
);
1717 W_ERROR_HAVE_NO_MEMORY(tmp_ctx
);
1719 name
= dns_split_node_name(tmp_ctx
, node_name
, z
->name
);
1720 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name
, tmp_ctx
);
1722 /* search all records under parent tree */
1723 if (strcasecmp(name
, z
->name
) == 0) {
1724 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1725 LDB_SCOPE_ONELEVEL
, attrs
, "(objectClass=dnsNode)");
1727 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z
->zone_dn
,
1728 LDB_SCOPE_ONELEVEL
, attrs
,
1729 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s)))",
1732 if (ret
!= LDB_SUCCESS
) {
1733 talloc_free(tmp_ctx
);
1734 return WERR_INTERNAL_DB_ERROR
;
1736 if (res
->count
== 0) {
1737 talloc_free(tmp_ctx
);
1738 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
1741 recs
= talloc_zero(mem_ctx
, struct DNS_RPC_RECORDS_ARRAY
);
1742 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs
, tmp_ctx
);
1744 /* Sort the names, so that the first record is the parent record */
1745 ldb_qsort(res
->msgs
, res
->count
, sizeof(struct ldb_message
*), name
,
1746 (ldb_qsort_cmp_fn_t
)dns_name_compare
);
1748 /* Build a tree of name components from dns name */
1749 if (strcasecmp(name
, z
->name
) == 0) {
1750 tree
= dns_build_tree(tmp_ctx
, "@", res
);
1752 tree
= dns_build_tree(tmp_ctx
, name
, res
);
1754 W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree
, tmp_ctx
);
1756 /* Find the parent record in the tree */
1758 while (base
->level
!= -1) {
1759 base
= base
->children
[0];
1762 /* Add the parent record with blank name */
1763 if (!(select_flag
& DNS_RPC_VIEW_ONLY_CHILDREN
)) {
1764 status
= dns_fill_records_array(tmp_ctx
, z
, record_type
,
1767 recs
, &add_names
, &add_count
);
1768 if (!W_ERROR_IS_OK(status
)) {
1769 talloc_free(tmp_ctx
);
1774 /* Add all the children records */
1775 if (!(select_flag
& DNS_RPC_VIEW_NO_CHILDREN
)) {
1776 for (i
=0; i
<base
->num_children
; i
++) {
1777 node
= base
->children
[i
];
1779 status
= dns_fill_records_array(tmp_ctx
, z
, record_type
,
1780 select_flag
, node
->name
,
1781 node
->data
, node
->num_children
,
1782 recs
, &add_names
, &add_count
);
1783 if (!W_ERROR_IS_OK(status
)) {
1784 talloc_free(tmp_ctx
);
1794 /* Add any additional records */
1795 if (select_flag
& DNS_RPC_VIEW_ADDITIONAL_DATA
) {
1796 for (i
=0; i
<add_count
; i
++) {
1797 struct dnsserver_zone
*z2
;
1799 /* Search all the available zones for additional name */
1800 for (z2
= dsstate
->zones
; z2
; z2
= z2
->next
) {
1801 name
= dns_split_node_name(tmp_ctx
, add_names
[i
], z2
->name
);
1802 ret
= ldb_search(dsstate
->samdb
, tmp_ctx
, &res
, z2
->zone_dn
,
1803 LDB_SCOPE_ONELEVEL
, attrs
,
1804 "(&(objectClass=dnsNode)(name=%s))", name
);
1806 if (ret
!= LDB_SUCCESS
) {
1809 if (res
->count
== 1) {
1817 len
= strlen(add_names
[i
]);
1818 if (add_names
[i
][len
-1] == '.') {
1819 rname
= talloc_strdup(tmp_ctx
, add_names
[i
]);
1821 rname
= talloc_asprintf(tmp_ctx
, "%s.", add_names
[i
]);
1823 status
= dns_fill_records_array(tmp_ctx
, NULL
, DNS_TYPE_A
,
1825 res
->msgs
[0], 0, recs
,
1832 *buffer_length
= ndr_size_DNS_RPC_RECORDS_ARRAY(recs
, 0);
1838 /* dnsserver update function */
1840 static WERROR
dnsserver_update_record(struct dnsserver_state
*dsstate
,
1841 TALLOC_CTX
*mem_ctx
,
1842 struct dnsserver_zone
*z
,
1843 unsigned int client_version
,
1844 const char *node_name
,
1845 struct DNS_RPC_RECORD_BUF
*add_buf
,
1846 struct DNS_RPC_RECORD_BUF
*del_buf
)
1848 TALLOC_CTX
*tmp_ctx
;
1852 tmp_ctx
= talloc_new(mem_ctx
);
1853 W_ERROR_HAVE_NO_MEMORY(tmp_ctx
);
1855 /* If node_name is @ or zone name, dns record is @ */
1856 if (strcmp(node_name
, "@") == 0 || strcasecmp(node_name
, z
->name
) == 0) {
1857 name
= talloc_strdup(tmp_ctx
, "@");
1859 name
= dns_split_node_name(tmp_ctx
, node_name
, z
->name
);
1861 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name
, tmp_ctx
);
1863 if (add_buf
!= NULL
) {
1864 if (del_buf
== NULL
) {
1866 status
= dnsserver_db_add_record(tmp_ctx
, dsstate
->samdb
,
1871 status
= dnsserver_db_update_record(tmp_ctx
, dsstate
->samdb
,
1877 if (del_buf
== NULL
) {
1878 /* Add empty node */
1879 status
= dnsserver_db_add_empty_node(tmp_ctx
, dsstate
->samdb
,
1883 status
= dnsserver_db_delete_record(tmp_ctx
, dsstate
->samdb
,
1889 talloc_free(tmp_ctx
);
1894 /* dnsserver interface functions */
1896 static WERROR
dcesrv_DnssrvOperation(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvOperation
*r
)
1898 struct dnsserver_state
*dsstate
;
1899 struct dnsserver_zone
*z
= NULL
;
1900 uint32_t request_filter
= 0;
1903 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
1904 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
1907 if (r
->in
.dwContext
== 0) {
1908 if (r
->in
.pszZone
!= NULL
) {
1909 request_filter
= dnsserver_zone_to_request_filter(r
->in
.pszZone
);
1912 request_filter
= r
->in
.dwContext
;
1915 if (r
->in
.pszZone
== NULL
) {
1916 ret
= dnsserver_operate_server(dsstate
, mem_ctx
,
1918 DNS_CLIENT_VERSION_W2K
,
1922 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
1923 if (z
== NULL
&& request_filter
== 0) {
1924 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
1927 ret
= dnsserver_operate_zone(dsstate
, mem_ctx
, z
,
1930 DNS_CLIENT_VERSION_W2K
,
1935 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
1936 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation
, NDR_IN
, r
);
1941 static WERROR
dcesrv_DnssrvQuery(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvQuery
*r
)
1943 struct dnsserver_state
*dsstate
;
1944 struct dnsserver_zone
*z
;
1947 ZERO_STRUCTP(r
->out
.pdwTypeId
);
1948 ZERO_STRUCTP(r
->out
.ppData
);
1950 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
1951 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
1954 if (r
->in
.pszZone
== NULL
) {
1955 /* FIXME: DNS Server Configuration Access Control List */
1956 ret
= dnsserver_query_server(dsstate
, mem_ctx
,
1958 DNS_CLIENT_VERSION_W2K
,
1962 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
1964 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
1967 ret
= dnsserver_query_zone(dsstate
, mem_ctx
, z
,
1969 DNS_CLIENT_VERSION_W2K
,
1974 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
1975 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery
, NDR_IN
, r
);
1980 static WERROR
dcesrv_DnssrvComplexOperation(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvComplexOperation
*r
)
1982 struct dnsserver_state
*dsstate
;
1983 struct dnsserver_zone
*z
;
1986 ZERO_STRUCTP(r
->out
.pdwTypeOut
);
1987 ZERO_STRUCTP(r
->out
.ppDataOut
);
1989 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
1990 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
1993 if (r
->in
.pszZone
== NULL
) {
1994 /* Server operation */
1995 ret
= dnsserver_complex_operate_server(dsstate
, mem_ctx
,
1997 DNS_CLIENT_VERSION_W2K
,
2003 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2005 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2008 ret
= dnsserver_complex_operate_zone(dsstate
, mem_ctx
, z
,
2010 DNS_CLIENT_VERSION_W2K
,
2017 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2018 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation
, NDR_IN
, r
);
2023 static WERROR
dcesrv_DnssrvEnumRecords(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvEnumRecords
*r
)
2025 struct dnsserver_state
*dsstate
;
2026 struct dnsserver_zone
*z
;
2029 ZERO_STRUCTP(r
->out
.pdwBufferLength
);
2030 ZERO_STRUCTP(r
->out
.pBuffer
);
2032 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2033 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2036 if (r
->in
.pszZone
== NULL
) {
2037 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2040 if (strcasecmp(r
->in
.pszZone
, "..RootHints") == 0) {
2041 ret
= dnsserver_enumerate_root_records(dsstate
, mem_ctx
,
2042 DNS_CLIENT_VERSION_W2K
,
2046 r
->out
.pdwBufferLength
,
2049 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2051 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2054 ret
= dnsserver_enumerate_records(dsstate
, mem_ctx
, z
,
2055 DNS_CLIENT_VERSION_W2K
,
2057 r
->in
.pszStartChild
,
2060 r
->in
.pszFilterStart
,
2061 r
->in
.pszFilterStop
,
2062 r
->out
.pdwBufferLength
,
2066 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2067 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords
, NDR_IN
, r
);
2072 static WERROR
dcesrv_DnssrvUpdateRecord(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvUpdateRecord
*r
)
2074 struct dnsserver_state
*dsstate
;
2075 struct dnsserver_zone
*z
;
2078 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2079 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2082 if (r
->in
.pszZone
== NULL
) {
2083 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2086 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2088 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2091 ret
= dnsserver_update_record(dsstate
, mem_ctx
, z
,
2092 DNS_CLIENT_VERSION_W2K
,
2095 r
->in
.pDeleteRecord
);
2097 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2098 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord
, NDR_IN
, r
);
2103 static WERROR
dcesrv_DnssrvOperation2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvOperation2
*r
)
2105 struct dnsserver_state
*dsstate
;
2106 struct dnsserver_zone
*z
= NULL
;
2107 uint32_t request_filter
= 0;
2110 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2111 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2114 if (r
->in
.dwContext
== 0) {
2115 if (r
->in
.pszZone
!= NULL
) {
2116 request_filter
= dnsserver_zone_to_request_filter(r
->in
.pszZone
);
2119 request_filter
= r
->in
.dwContext
;
2122 if (r
->in
.pszZone
== NULL
) {
2123 ret
= dnsserver_operate_server(dsstate
, mem_ctx
,
2125 r
->in
.dwClientVersion
,
2129 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2130 if (z
== NULL
&& request_filter
== 0) {
2131 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2134 ret
= dnsserver_operate_zone(dsstate
, mem_ctx
, z
,
2137 r
->in
.dwClientVersion
,
2142 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2143 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation2
, NDR_IN
, r
);
2148 static WERROR
dcesrv_DnssrvQuery2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvQuery2
*r
)
2150 struct dnsserver_state
*dsstate
;
2151 struct dnsserver_zone
*z
;
2154 ZERO_STRUCTP(r
->out
.pdwTypeId
);
2155 ZERO_STRUCTP(r
->out
.ppData
);
2157 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2158 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2161 if (r
->in
.pszZone
== NULL
) {
2162 /* FIXME: DNS Server Configuration Access Control List */
2163 ret
= dnsserver_query_server(dsstate
, mem_ctx
,
2165 r
->in
.dwClientVersion
,
2169 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2171 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2174 ret
= dnsserver_query_zone(dsstate
, mem_ctx
, z
,
2176 r
->in
.dwClientVersion
,
2181 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2182 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery2
, NDR_IN
, r
);
2187 static WERROR
dcesrv_DnssrvComplexOperation2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvComplexOperation2
*r
)
2189 struct dnsserver_state
*dsstate
;
2190 struct dnsserver_zone
*z
;
2193 ZERO_STRUCTP(r
->out
.pdwTypeOut
);
2194 ZERO_STRUCTP(r
->out
.ppDataOut
);
2196 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2197 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2200 if (r
->in
.pszZone
== NULL
) {
2201 /* Server operation */
2202 ret
= dnsserver_complex_operate_server(dsstate
, mem_ctx
,
2204 r
->in
.dwClientVersion
,
2211 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2213 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST
;
2216 ret
= dnsserver_complex_operate_zone(dsstate
, mem_ctx
, z
,
2218 r
->in
.dwClientVersion
,
2225 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2226 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation2
, NDR_IN
, r
);
2231 static WERROR
dcesrv_DnssrvEnumRecords2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvEnumRecords2
*r
)
2233 struct dnsserver_state
*dsstate
;
2234 struct dnsserver_zone
*z
;
2237 ZERO_STRUCTP(r
->out
.pdwBufferLength
);
2238 ZERO_STRUCTP(r
->out
.pBuffer
);
2240 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2241 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2244 if (r
->in
.pszZone
== NULL
) {
2245 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2248 if (strcasecmp(r
->in
.pszZone
, "..RootHints") == 0) {
2249 ret
= dnsserver_enumerate_root_records(dsstate
, mem_ctx
,
2250 r
->in
.dwClientVersion
,
2254 r
->out
.pdwBufferLength
,
2257 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2259 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2262 ret
= dnsserver_enumerate_records(dsstate
, mem_ctx
, z
,
2263 r
->in
.dwClientVersion
,
2265 r
->in
.pszStartChild
,
2268 r
->in
.pszFilterStart
,
2269 r
->in
.pszFilterStop
,
2270 r
->out
.pdwBufferLength
,
2275 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2276 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords2
, NDR_IN
, r
);
2281 static WERROR
dcesrv_DnssrvUpdateRecord2(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
, struct DnssrvUpdateRecord2
*r
)
2283 struct dnsserver_state
*dsstate
;
2284 struct dnsserver_zone
*z
;
2287 if ((dsstate
= dnsserver_connect(dce_call
)) == NULL
) {
2288 return WERR_DNS_ERROR_DS_UNAVAILABLE
;
2291 if (r
->in
.pszZone
== NULL
) {
2292 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2295 z
= dnsserver_find_zone(dsstate
->zones
, r
->in
.pszZone
);
2297 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST
;
2300 ret
= dnsserver_update_record(dsstate
, mem_ctx
, z
,
2301 r
->in
.dwClientVersion
,
2304 r
->in
.pDeleteRecord
);
2306 if (W_ERROR_EQUAL(ret
, WERR_CALL_NOT_IMPLEMENTED
)) {
2307 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord2
, NDR_IN
, r
);
2312 /* include the generated boilerplate */
2313 #include "librpc/gen_ndr/ndr_dnsserver_s.c"