s3: Simplify check_reduced_name a bit
[Samba/gebeck_regimport.git] / source4 / rpc_server / dnsserver / dcerpc_dnsserver.c
blob5733a51177ae3a824272198880ce6abaa1285ba2
1 /*
2 Unix SMB/CIFS implementation.
4 DNS Server
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/>.
22 #include "includes.h"
23 #include "talloc.h"
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;
36 int zones_count;
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;
50 new_list = NULL;
52 for (p = dsstate->partitions; p; p = p->next) {
53 zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, p);
54 if (zones == NULL) {
55 continue;
57 for (z = zones; z; ) {
58 znext = z->next;
59 zmatch = dnsserver_find_zone(old_list, z->name);
60 if (zmatch == NULL) {
61 /* Missing zone */
62 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
63 if (z->zoneinfo == NULL) {
64 continue;
66 DLIST_ADD_END(new_list, z, NULL);
67 p->zones_count++;
68 dsstate->zones_count++;
69 } else {
70 /* Existing zone */
71 talloc_free(z);
72 DLIST_REMOVE(old_list, zmatch);
73 DLIST_ADD_END(new_list, zmatch, NULL);
75 z = znext;
79 if (new_list == NULL) {
80 return;
83 /* Deleted zones */
84 for (z = old_list; z; ) {
85 znext = z->next;
86 z->partition->zones_count--;
87 dsstate->zones_count--;
88 talloc_free(z);
89 z = znext;
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) {
104 return dsstate;
107 dsstate = talloc_zero(dce_call->context, struct dnsserver_state);
108 if (dsstate == NULL) {
109 return 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"));
119 goto failed;
122 /* Initialize server info */
123 dsstate->serverinfo = dnsserver_init_serverinfo(dsstate,
124 dsstate->lp_ctx,
125 dsstate->samdb);
126 if (dsstate->serverinfo == NULL) {
127 goto failed;
130 /* Search for DNS partitions */
131 partitions = dnsserver_db_enumerate_partitions(dsstate, dsstate->serverinfo, dsstate->samdb);
132 if (partitions == NULL) {
133 goto failed;
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);
140 if (zones == NULL) {
141 goto failed;
143 for (z = zones; z; ) {
144 znext = z->next;
145 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
146 if (z->zoneinfo == NULL) {
147 goto failed;
149 DLIST_ADD_END(dsstate->zones, z, NULL);
150 p->zones_count++;
151 dsstate->zones_count++;
152 z = znext;
156 dce_call->context->private_data = dsstate;
158 return dsstate;
160 failed:
161 talloc_free(dsstate);
162 dsstate = NULL;
163 return NULL;
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,
171 TALLOC_CTX *mem_ctx,
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;
181 char *answer_string;
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;
340 return WERR_OK;
343 is_integer = 0;
345 if (strcasecmp(operation, "AddressAnswerLimit") == 0) {
346 answer_integer = serverinfo->cAddressAnswerLimit;
347 is_integer = 1;
348 } else if (strcasecmp(operation, "AdminConfigured") == 0) {
349 answer_integer = serverinfo->fAdminConfigured;
350 is_integer = 1;
351 } else if (strcasecmp(operation, "AllowCNAMEAtNS") == 0) {
352 answer_integer = 0;
353 is_integer = 1;
354 } else if (strcasecmp(operation, "AllowUpdate") == 0) {
355 answer_integer = serverinfo->fAllowUpdate;
356 is_integer = 1;
357 } else if (strcasecmp(operation, "AutoCacheUpdate") == 0) {
358 answer_integer = serverinfo->fAutoCacheUpdate;
359 is_integer = 1;
360 } else if (strcasecmp(operation, "AutoConfigFileZones") == 0) {
361 answer_integer = 1;
362 is_integer = 1;
363 } else if (strcasecmp(operation, "BindSecondaries") == 0) {
364 answer_integer = serverinfo->fBindSecondaries;
365 is_integer = 1;
366 } else if (strcasecmp(operation, "BootMethod") == 0) {
367 answer_integer = serverinfo->fBootMethod;
368 is_integer = 1;
369 } else if (strcasecmp(operation, "DebugLevel") == 0) {
370 answer_integer = serverinfo->dwDebugLevel;
371 is_integer = 1;
372 } else if (strcasecmp(operation, "DefaultAgingState") == 0) {
373 answer_integer = serverinfo->fDefaultAgingState;
374 is_integer = 1;
375 } else if (strcasecmp(operation, "DefaultNoRefreshInterval") == 0) {
376 answer_integer = serverinfo->dwDefaultNoRefreshInterval;
377 is_integer = 1;
378 } else if (strcasecmp(operation, "DefaultRefreshInterval") == 0) {
379 answer_integer = serverinfo->dwDefaultRefreshInterval;
380 is_integer = 1;
381 } else if (strcasecmp(operation, "DeleteOutsideGlue") == 0) {
382 answer_integer = 0;
383 is_integer = 1;
384 } else if (strcasecmp(operation, "DisjointNets") == 0) {
385 answer_integer = 0;
386 is_integer = 1;
387 } else if (strcasecmp(operation, "DsLazyUpdateInterval") == 0) {
388 answer_integer = 3; /* seconds */
389 is_integer = 1;
390 } else if (strcasecmp(operation, "DsPollingInterval") == 0) {
391 answer_integer = serverinfo->dwDsPollingInterval;
392 is_integer = 1;
393 } else if (strcasecmp(operation, "DsTombstoneInterval") == 0) {
394 answer_integer = 0x00127500; /* 14 days */
395 is_integer = 1;
396 } else if (strcasecmp(operation, "EnableRegistryBoot") == 0) {
397 answer_integer = 0;
398 is_integer = 1;
399 } else if (strcasecmp(operation, "EventLogLevel") == 0) {
400 answer_integer = serverinfo->dwEventLogLevel;
401 is_integer = 1;
402 } else if (strcasecmp(operation, "ForceSoaSerial") == 0) {
403 answer_integer = 0;
404 is_integer = 1;
405 } else if (strcasecmp(operation, "ForceSaoRetry") == 0) {
406 answer_integer = 0;
407 is_integer = 1;
408 } else if (strcasecmp(operation, "ForceSoaRefresh") == 0) {
409 answer_integer = 0;
410 is_integer = 1;
411 } else if (strcasecmp(operation, "ForceSoaMinimumTtl") == 0) {
412 answer_integer = 0;
413 is_integer = 1;
414 } else if (strcasecmp(operation, "ForwardDelegations") == 0) {
415 answer_integer = 1;
416 is_integer = 1;
417 } else if (strcasecmp(operation, "ForwardingTimeout") == 0) {
418 answer_integer = serverinfo->dwForwardTimeout;
419 is_integer = 1;
420 } else if (strcasecmp(operation, "IsSlave") == 0) {
421 answer_integer = 0;
422 is_integer = 1;
423 } else if (strcasecmp(operation, "LocalNetPriority") == 0) {
424 answer_integer = serverinfo->fLocalNetPriority;
425 is_integer = 1;
426 } else if (strcasecmp(operation, "LogFileMaxSize") == 0) {
427 answer_integer = serverinfo->dwLogFileMaxSize;
428 is_integer = 1;
429 } else if (strcasecmp(operation, "LogLevel") == 0) {
430 answer_integer = serverinfo->dwLogLevel;
431 is_integer = 1;
432 } else if (strcasecmp(operation, "LooseWildcarding") == 0) {
433 answer_integer = serverinfo->fLooseWildcarding;
434 is_integer = 1;
435 } else if (strcasecmp(operation, "MaxCacheTtl") == 0) {
436 answer_integer = serverinfo->dwMaxCacheTtl;
437 is_integer = 1;
438 } else if (strcasecmp(operation, "MaxNegativeCacheTtl") == 0) {
439 answer_integer = 0x00000384; /* 15 minutes */
440 is_integer = 1;
441 } else if (strcasecmp(operation, "NameCheckFlag") == 0) {
442 answer_integer = serverinfo->dwNameCheckFlag;
443 is_integer = 1;
444 } else if (strcasecmp(operation, "NoRecursion") == 0) {
445 answer_integer = serverinfo->fNoRecursion;
446 is_integer = 1;
447 } else if (strcasecmp(operation, "NoUpdateDelegations") == 0) {
448 answer_integer = 1;
449 is_integer = 1;
450 } else if (strcasecmp(operation, "PublishAutonet") == 0) {
451 answer_integer = 0;
452 is_integer = 1;
453 } else if (strcasecmp(operation, "QuietRecvFaultInterval") == 0) {
454 answer_integer = 0;
455 is_integer = 1;
456 } else if (strcasecmp(operation, "QuietRecvLogInterval") == 0) {
457 answer_integer = 0;
458 is_integer = 1;
459 } else if (strcasecmp(operation, "RecursionRetry") == 0) {
460 answer_integer = serverinfo->dwRecursionRetry;
461 is_integer = 1;
462 } else if (strcasecmp(operation, "RecursionTimeout") == 0) {
463 answer_integer = serverinfo->dwRecursionTimeout;
464 is_integer = 1;
465 } else if (strcasecmp(operation, "ReloadException") == 0) {
466 answer_integer = 0;
467 is_integer = 1;
468 } else if (strcasecmp(operation, "RoundRobin") == 0) {
469 answer_integer = serverinfo->fRoundRobin;
470 is_integer = 1;
471 } else if (strcasecmp(operation, "RpcProtocol") == 0) {
472 answer_integer = serverinfo->dwRpcProtocol;
473 is_integer = 1;
474 } else if (strcasecmp(operation, "SecureResponses") == 0) {
475 answer_integer = serverinfo->fSecureResponses;
476 is_integer = 1;
477 } else if (strcasecmp(operation, "SendPort") == 0) {
478 answer_integer = 0;
479 is_integer = 1;
480 } else if (strcasecmp(operation, "ScavengingInterval") == 0) {
481 answer_integer = serverinfo->dwScavengingInterval;
482 is_integer = 1;
483 } else if (strcasecmp(operation, "SocketPoolSize") == 0) {
484 answer_integer = 0x000009C4;
485 is_integer = 1;
486 } else if (strcasecmp(operation, "StrictFileParsing") == 0) {
487 answer_integer = serverinfo->fStrictFileParsing;
488 is_integer = 1;
489 } else if (strcasecmp(operation, "SyncDnsZoneSerial") == 0) {
490 answer_integer = 2; /* ZONE_SERIAL_SYNC_XFER */
491 is_integer = 1;
492 } else if (strcasecmp(operation, "UpdateOptions") == 0) {
493 answer_integer = 0x0000030F; /* DNS_DEFAULT_UPDATE_OPTIONS */
494 is_integer = 1;
495 } else if (strcasecmp(operation, "UseSystemEvengLog") == 0) {
496 answer_integer = 0;
497 is_integer = 1;
498 } else if (strcasecmp(operation, "Version") == 0) {
499 answer_integer = serverinfo->dwVersion;
500 is_integer = 1;
501 } else if (strcasecmp(operation, "XfrConnectTimeout") == 0) {
502 answer_integer = 0x0000001E;
503 is_integer = 1;
504 } else if (strcasecmp(operation, "WriteAuthorityNs") == 0) {
505 answer_integer = serverinfo->fWriteAuthorityNs;
506 is_integer = 1;
507 } else if (strcasecmp(operation, "AdditionalRecursionTimeout") == 0) {
508 answer_integer = 0x00000004;
509 is_integer = 1;
510 } else if (strcasecmp(operation, "AppendMsZoneTransferFlag") == 0) {
511 answer_integer = 0;
512 is_integer = 1;
513 } else if (strcasecmp(operation, "AutoCreateDelegations") == 0) {
514 answer_integer = 0; /* DNS_ACD_DONT_CREATE */
515 is_integer = 1;
516 } else if (strcasecmp(operation, "BreakOnAscFailure") == 0) {
517 answer_integer = 0;
518 is_integer = 1;
519 } else if (strcasecmp(operation, "CacheEmptyAuthResponses") == 0) {
520 answer_integer = 0;
521 is_integer = 1;
522 } else if (strcasecmp(operation, "DirectoryPartitionAutoEnlistInterval") == 0) {
523 answer_integer = 0x00015180; /* 1 day */
524 is_integer = 1;
525 } else if (strcasecmp(operation, "DisableAutoReverseZones") == 0) {
526 answer_integer = ~serverinfo->fAutoReverseZones;
527 is_integer = 1;
528 } else if (strcasecmp(operation, "EDnsCacheTimeout") == 0) {
529 answer_integer = 0x00000384; /* 15 minutes */
530 is_integer = 1;
531 } else if (strcasecmp(operation, "EnableDirectoryPartitions") == 0) {
532 answer_integer = serverinfo->fDsAvailable;
533 is_integer = 1;
534 } else if (strcasecmp(operation, "EnableDnsSec") == 0) {
535 answer_integer = 0;
536 is_integer = 1;
537 } else if (strcasecmp(operation, "EnableEDnsProbes") == 0) {
538 answer_integer = 0;
539 is_integer = 1;
540 } else if (strcasecmp(operation, "EnableEDnsReception") == 0) {
541 answer_integer = 0;
542 is_integer = 1;
543 } else if (strcasecmp(operation, "EnableIPv6") == 0) {
544 answer_integer = 0;
545 is_integer = 1;
546 } else if (strcasecmp(operation, "EnableIQueryResponseGeneration") == 0) {
547 answer_integer = 0;
548 is_integer = 1;
549 } else if (strcasecmp(operation, "EnableSendErrorSuppression") == 0) {
550 answer_integer = 0;
551 is_integer = 1;
552 } else if (strcasecmp(operation, "EnableUpdateForwarding") == 0) {
553 answer_integer = 0;
554 is_integer = 1;
555 } else if (strcasecmp(operation, "EnableWinsR") == 0) {
556 answer_integer = 0;
557 is_integer = 1;
558 } else if (strcasecmp(operation, "ForceDsaBehaviorVersion") == 0) {
559 answer_integer = serverinfo->dwDsDsaVersion;
560 is_integer = 1;
561 } else if (strcasecmp(operation, "ForceDomainBehaviorVersion") == 0) {
562 answer_integer = serverinfo->dwDsDsaVersion;
563 is_integer = 1;
564 } else if (strcasecmp(operation, "ForceForestBehaviorVersion") == 0) {
565 answer_integer = serverinfo->dwDsDsaVersion;
566 is_integer = 1;
567 } else if (strcasecmp(operation, "HeapDebug") == 0) {
568 answer_integer = 0;
569 is_integer = 1;
570 } else if (strcasecmp(operation, "LameDelegationTtl") == 0) {
571 answer_integer = 0; /* seconds */
572 is_integer = 1;
573 } else if (strcasecmp(operation, "LocalNetPriorityNetMask") == 0) {
574 answer_integer = serverinfo->dwLocalNetPriorityNetMask;
575 is_integer = 1;
576 } else if (strcasecmp(operation, "MaxCacheSize") == 0) {
577 answer_integer = 0;
578 is_integer = 1;
579 } else if (strcasecmp(operation, "MaxResourceRecordsInNonSecureUpdate") == 0) {
580 answer_integer = 0x0000001E;
581 is_integer = 1;
582 } else if (strcasecmp(operation, "OperationsLogLevel") == 0) {
583 answer_integer = 0;
584 is_integer = 1;
585 } else if (strcasecmp(operation, "OperationsLogLevel2") == 0) {
586 answer_integer = 0;
587 is_integer = 1;
588 } else if (strcasecmp(operation, "MaximumUdpPacketSize") == 0) {
589 answer_integer = 0x00004000; /* maximum possible */
590 is_integer = 1;
591 } else if (strcasecmp(operation, "RecurseToInternetRootMask") == 0) {
592 answer_integer = 0;
593 is_integer = 1;
594 } else if (strcasecmp(operation, "SelfTest") == 0) {
595 answer_integer = 0;
596 is_integer = 1;
597 } else if (strcasecmp(operation, "SilentlyIgnoreCNameUpdateConflicts") == 0) {
598 answer_integer = 1;
599 is_integer = 1;
600 } else if (strcasecmp(operation, "TcpReceivePacketSize") == 0) {
601 answer_integer = 0x00010000;
602 is_integer = 1;
603 } else if (strcasecmp(operation, "XfrThrottleMultiplier") == 0) {
604 answer_integer = 0x0000000A;
605 is_integer = 1;
606 } else if (strcasecmp(operation, "AllowMsdcsLookupRetry") == 0) {
607 answer_integer = 1;
608 is_integer = 1;
609 } else if (strcasecmp(operation, "AllowReadOnlyZoneTransfer") == 0) {
610 answer_integer = 0;
611 is_integer = 1;
612 } else if (strcasecmp(operation, "DsBackGroundLoadPaused") == 0) {
613 answer_integer = 0;
614 is_integer = 1;
615 } else if (strcasecmp(operation, "DsMinimumBackgroundLoadThreads") == 0) {
616 answer_integer = 0;
617 is_integer = 1;
618 } else if (strcasecmp(operation, "DsRemoteReplicationDelay") == 0) {
619 answer_integer = 0x0000001E; /* 30 seconds */
620 is_integer = 1;
621 } else if (strcasecmp(operation, "EnableDuplicateQuerySuppresion") == 0) {
622 answer_integer = 0;
623 is_integer = 1;
624 } else if (strcasecmp(operation, "EnableGlobalNamesSupport") == 0) {
625 answer_integer = 0;
626 is_integer = 1;
627 } else if (strcasecmp(operation, "EnableVersionQuery") == 0) {
628 answer_integer = 1; /* DNS_VERSION_QUERY_FULL */
629 is_integer = 1;
630 } else if (strcasecmp(operation, "EnableRsoForRodc") == 0) {
631 answer_integer = 0;
632 is_integer = 1;
633 } else if (strcasecmp(operation, "ForceRODCMode") == 0) {
634 answer_integer = 0;
635 is_integer = 1;
636 } else if (strcasecmp(operation, "GlobalNamesAlwaysQuerySrv") == 0) {
637 answer_integer = 1;
638 is_integer = 1;
639 } else if (strcasecmp(operation, "GlobalNamesBlockUpdates") == 0) {
640 answer_integer = 0;
641 is_integer = 1;
642 } else if (strcasecmp(operation, "GlobalNamesEnableEDnsProbes") == 0) {
643 answer_integer = 0;
644 is_integer = 1;
645 } else if (strcasecmp(operation, "GlobalNamesPreferAAAA") == 0) {
646 answer_integer = 0;
647 is_integer = 1;
648 } else if (strcasecmp(operation, "GlobalNamesQueryOrder") == 0) {
649 answer_integer = 1;
650 is_integer = 1;
651 } else if (strcasecmp(operation, "GlobalNamesSendTimeout") == 0) {
652 answer_integer = 3; /* seconds */
653 is_integer = 1;
654 } else if (strcasecmp(operation, "GlobalNamesServerQueryInterval") == 0) {
655 answer_integer = 0x00005460; /* 6 hours */
656 is_integer = 1;
657 } else if (strcasecmp(operation, "RemoteIPv4RankBoost") == 0) {
658 answer_integer = 0;
659 is_integer = 1;
660 } else if (strcasecmp(operation, "RemoteIPv6RankBoost") == 0) {
661 answer_integer = 0;
662 is_integer = 1;
663 } else if (strcasecmp(operation, "MaximumRodcRsoAttemptsPerCycle") == 0) {
664 answer_integer = 0x00000064;
665 is_integer = 1;
666 } else if (strcasecmp(operation, "MaximumRodcRsoQueueLength") == 0) {
667 answer_integer = 0x0000012C;
668 is_integer = 1;
669 } else if (strcasecmp(operation, "EnableGlobalQueryBlockList") == 0) {
670 answer_integer = 0;
671 is_integer = 1;
672 } else if (strcasecmp(operation, "OpenACLOnProxyUpdates") == 0) {
673 answer_integer = 0;
674 is_integer = 1;
675 } else if (strcasecmp(operation, "CacheLockingPercent") == 0) {
676 answer_integer = 0x00000064;
677 is_integer = 1;
680 if (is_integer == 1) {
681 *typeid = DNSSRV_TYPEID_DWORD;
682 r->Dword = answer_integer;
683 return WERR_OK;
686 is_addresses = 0;
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);
691 } else {
692 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
694 is_addresses = 1;
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);
698 } else {
699 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipListenAddrs);
701 is_addresses = 1;
702 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
703 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
704 answer_addrarray = NULL;
705 } else {
706 answer_iparray = NULL;
708 is_addresses = 1;
709 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
710 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
711 answer_addrarray = NULL;
712 } else {
713 answer_iparray = NULL;
715 is_addresses = 1;
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);
719 } else {
720 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
722 is_addresses = 1;
725 if (is_addresses == 1) {
726 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
727 *typeid = DNSSRV_TYPEID_ADDRARRAY;
728 r->AddrArray = answer_addrarray;
729 } else {
730 *typeid = DNSSRV_TYPEID_IPARRAY;
731 r->IpArray = answer_iparray;
733 return WERR_OK;
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;
743 is_string = 1;
744 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
745 answer_string = talloc_strdup(mem_ctx, "ForestDnsZones");
746 if (! answer_string) {
747 return WERR_OUTOFMEMORY;
749 is_string = 1;
750 } else if (strcasecmp(operation, "LogFilePath") == 0) {
751 answer_string = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
752 is_wstring = 1;
753 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
754 answer_string = NULL;
755 is_wstring = 1;
756 } else if (strcasecmp(operation, "DsBackgroundPauseName") == 0) {
757 answer_string = NULL;
758 is_string = 1;
759 } else if (strcasecmp(operation, "DsNotRoundRobinTypes") == 0) {
760 answer_string = NULL;
761 is_string = 1;
764 if (is_string == 1) {
765 *typeid = DNSSRV_TYPEID_LPSTR;
766 r->String = answer_string;
767 return WERR_OK;
768 } else if (is_wstring == 1) {
769 *typeid = DNSSRV_TYPEID_LPWSTR;
770 r->WideString = answer_string;
771 return WERR_OK;
774 is_stringlist = 0;
776 if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
777 answer_stringlist = NULL;
778 is_stringlist = 1;
779 } else if (strcasecmp(operation, "SocketPoolExcludedPortRanges") == 0) {
780 answer_stringlist = NULL;
781 is_stringlist = 1;
784 if (is_stringlist == 1) {
785 *typeid = DNSSRV_TYPEID_UTF8_STRING_LIST;
786 r->Utf8StringList = answer_stringlist;
787 return WERR_OK;
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,
796 TALLOC_CTX *mem_ctx,
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;
807 char *answer_string;
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;
821 } else {
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);
833 return WERR_OK;
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;
898 } else {
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;
940 return WERR_OK;
943 is_integer = 0;
945 if (strcasecmp(operation, "AllowUpdate") == 0) {
946 answer_integer = zoneinfo->fAllowUpdate;
947 is_integer = 1;
948 } else if (strcasecmp(operation, "Secured") == 0) {
949 answer_integer = 0;
950 is_integer = 1;
951 } else if (strcasecmp(operation, "DsIntegrated") == 0) {
952 answer_integer = zoneinfo->fUseDatabase;
953 is_integer = 1;
954 } else if (strcasecmp(operation, "LogUpdates") == 0) {
955 answer_integer = 0;
956 is_integer = 1;
957 } else if (strcasecmp(operation, "NoRefreshInterval") == 0) {
958 answer_integer = zoneinfo->dwNoRefreshInterval;
959 is_integer = 1;
960 } else if (strcasecmp(operation, "NotifyLevel") == 0) {
961 answer_integer = zoneinfo->fNotifyLevel;
962 is_integer = 1;
963 } else if (strcasecmp(operation, "RefreshInterval") == 0) {
964 answer_integer = zoneinfo->dwRefreshInterval;
965 is_integer = 1;
966 } else if (strcasecmp(operation, "SecureSecondaries") == 0) {
967 answer_integer = zoneinfo->fSecureSecondaries;
968 is_integer = 1;
969 } else if (strcasecmp(operation, "Type") == 0) {
970 answer_integer = zoneinfo->dwZoneType;
971 is_integer = 1;
972 } else if (strcasecmp(operation, "Aging") == 0) {
973 answer_integer = zoneinfo->fAging;
974 is_integer = 1;
975 } else if (strcasecmp(operation, "ForwarderSlave") == 0) {
976 answer_integer = zoneinfo->fForwarderSlave;
977 is_integer = 1;
978 } else if (strcasecmp(operation, "ForwarderTimeout") == 0) {
979 answer_integer = zoneinfo->dwForwarderTimeout;
980 is_integer = 1;
981 } else if (strcasecmp(operation, "Unicode") == 0) {
982 answer_integer = 0;
983 is_integer = 1;
986 if (is_integer == 1) {
987 *typeid = DNSSRV_TYPEID_DWORD;
988 r->Dword = answer_integer;
989 return WERR_OK;
992 is_addresses = 0;
994 if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
995 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
996 answer_addrarray = NULL;
997 } else {
998 answer_iparray = NULL;
1000 is_addresses = 1;
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);
1004 } else {
1005 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
1007 is_addresses = 1;
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);
1011 } else {
1012 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
1014 is_addresses = 1;
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);
1018 } else {
1019 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
1021 is_addresses = 1;
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);
1025 } else {
1026 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
1028 is_addresses = 1;
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);
1032 } else {
1033 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
1035 is_addresses = 1;
1038 if (is_addresses == 1) {
1039 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1040 *typeid = DNSSRV_TYPEID_ADDRARRAY;
1041 r->AddrArray = answer_addrarray;
1042 } else {
1043 *typeid = DNSSRV_TYPEID_IPARRAY;
1044 r->IpArray = answer_iparray;
1046 return WERR_OK;
1049 is_string = 0;
1051 if (strcasecmp(operation, "DatabaseFile") == 0) {
1052 answer_string = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
1053 is_string = 1;
1054 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1055 answer_string = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
1056 is_string = 1;
1057 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1058 answer_string = NULL;
1059 is_string = 1;
1062 if (is_string == 1) {
1063 *typeid = DNSSRV_TYPEID_LPSTR;
1064 r->String = answer_string;
1065 return WERR_OK;
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;
1097 WERROR status;
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;
1126 } else {
1127 talloc_free(z);
1128 return WERR_DNS_ERROR_INVALID_PROPERTY;
1131 z2 = dnsserver_find_zone(dsstate->zones, z->name);
1132 if (z2 != NULL) {
1133 talloc_free(z);
1134 return WERR_DNS_ERROR_ZONE_ALREADY_EXISTS;
1137 status = dnsserver_db_create_zone(dsstate->samdb, dsstate->partitions, z,
1138 dsstate->lp_ctx);
1139 talloc_free(z);
1141 if (W_ERROR_IS_OK(status)) {
1142 dnsserver_reload_zones(dsstate);
1144 return status;
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;
1209 int zcount;
1210 bool found1, found2, found3, found4;
1211 int i;
1213 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1214 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1215 return dnsserver_query_server(dsstate, mem_ctx,
1216 rin->String,
1217 client_version,
1218 typeid_out,
1219 rout);
1221 } else if (strcasecmp(operation, "EnumZones") == 0) {
1222 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1223 return WERR_DNS_ERROR_INVALID_PROPERTY;
1226 zcount = 0;
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
1238 /* Group 1 */
1239 found1 = false;
1240 if (rin->Dword & 0x0000000f) {
1241 if (rin->Dword & DNS_ZONE_REQUEST_PRIMARY) {
1242 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_PRIMARY) {
1243 found1 = true;
1246 if (rin->Dword & DNS_ZONE_REQUEST_SECONDARY) {
1247 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_SECONDARY) {
1248 found1 = true;
1251 if (rin->Dword & DNS_ZONE_REQUEST_CACHE) {
1252 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_CACHE) {
1253 found1 = true;
1256 if (rin->Dword & DNS_ZONE_REQUEST_AUTO) {
1257 if (z->zoneinfo->fAutoCreated
1258 || z->partition->dwDpFlags & DNS_DP_AUTOCREATED) {
1259 found1 = true;
1262 } else {
1263 found1 = true;
1266 /* Group 2 */
1267 found2 = false;
1268 if (rin->Dword & 0x000000f0) {
1269 if (rin->Dword & DNS_ZONE_REQUEST_FORWARD) {
1270 if (!(z->zoneinfo->fReverse)) {
1271 found2 = true;
1274 if (rin->Dword & DNS_ZONE_REQUEST_REVERSE) {
1275 if (z->zoneinfo->fReverse) {
1276 found2 = true;
1279 if (rin->Dword & DNS_ZONE_REQUEST_FORWARDER) {
1280 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_FORWARDER) {
1281 found2 = true;
1284 if (rin->Dword & DNS_ZONE_REQUEST_STUB) {
1285 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_STUB) {
1286 found2 = true;
1289 } else {
1290 found2 = true;
1293 /* Group 3 */
1294 found3 = false;
1295 if (rin->Dword & 0x00000f00) {
1296 if (rin->Dword & DNS_ZONE_REQUEST_DS) {
1297 if (z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED) {
1298 found3 = true;
1301 if (rin->Dword & DNS_ZONE_REQUEST_NON_DS) {
1302 if (!(z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED)) {
1303 found3 = true;
1306 if (rin->Dword & DNS_ZONE_REQUEST_DOMAIN_DP) {
1307 if (!(z->partition->dwDpFlags & DNS_DP_DOMAIN_DEFAULT)) {
1308 found3 = true;
1311 if (rin->Dword & DNS_ZONE_REQUEST_FOREST_DP) {
1312 if (!(z->partition->dwDpFlags & DNS_DP_FOREST_DEFAULT)) {
1313 found3 = true;
1316 } else {
1317 found3 = true;
1320 /* Group 4 */
1321 if (rin->Dword & 0x0000f000) {
1322 found4 = false;
1323 } else {
1324 found4 = true;
1327 if (found1 && found2 && found3 && found4) {
1328 zlist = talloc_realloc(mem_ctx, zlist, struct dnsserver_zone *, zcount+1);
1329 zlist[zcount] = z;
1330 zcount++;
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);
1338 if (zcount == 0) {
1339 rout->ZoneListW2K->dwZoneCount = 0;
1340 rout->ZoneListW2K->ZoneArray = NULL;
1342 return WERR_OK;
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;
1358 } else {
1359 *typeid_out = DNSSRV_TYPEID_ZONE_LIST;
1360 rout->ZoneList = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_DOTNET);
1362 if (zcount == 0) {
1363 rout->ZoneList->dwRpcStructureVersion = 1;
1364 rout->ZoneList->dwZoneCount = 0;
1365 rout->ZoneList->ZoneArray = NULL;
1367 return WERR_OK;
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;
1387 talloc_free(zlist);
1388 return WERR_OK;
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;
1402 } else {
1403 struct DNS_RPC_DP_ENUM **dplist;
1404 struct dnsserver_partition *p;
1405 int pcount = 2;
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;
1417 p = p->next;
1420 rout->DirectoryPartitionList->dwDpCount = pcount;
1421 rout->DirectoryPartitionList->DpArray = dplist;
1423 return WERR_OK;
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);
1453 } else {
1454 dpinfo->ReplicaArray = NULL;
1456 break;
1460 if (dpinfo == NULL) {
1461 return WERR_DNS_ERROR_DP_DOES_NOT_EXIST;
1464 rout->DirectoryPartition = dpinfo;
1465 return WERR_OK;
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) {
1500 return WERR_OK;
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) {
1522 WERROR status;
1523 if (z == NULL) {
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);
1530 return status;
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,
1585 rin->String,
1586 client_version,
1587 typeid_out,
1588 rout);
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;
1613 char **add_names;
1614 char *rname;
1615 int add_count;
1616 int i, ret, len;
1617 WERROR status;
1619 tmp_ctx = talloc_new(mem_ctx);
1620 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1622 z = dnsserver_find_zone(dsstate->zones, ".");
1623 if (z == NULL) {
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);
1641 add_names = NULL;
1642 add_count = 0;
1644 for (i=0; i<res->count; i++) {
1645 status = dns_fill_records_array(tmp_ctx, NULL, record_type,
1646 select_flag, NULL,
1647 res->msgs[i], 0, recs,
1648 &add_names, &add_count);
1649 if (!W_ERROR_IS_OK(status)) {
1650 talloc_free(tmp_ctx);
1651 return status;
1654 talloc_free(res);
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) {
1663 talloc_free(res);
1664 continue;
1667 len = strlen(add_names[i]);
1668 if (add_names[i][len-1] == '.') {
1669 rname = talloc_strdup(tmp_ctx, add_names[i]);
1670 } else {
1671 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1673 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1674 select_flag, rname,
1675 res->msgs[0], 0, recs,
1676 NULL, NULL);
1677 talloc_free(rname);
1678 talloc_free(res);
1682 talloc_free(tmp_ctx);
1684 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1685 *buffer = recs;
1687 return WERR_OK;
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;
1705 char *name;
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;
1710 char *rname;
1711 int add_count = 0;
1712 int i, ret, len;
1713 WERROR status;
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)");
1726 } else {
1727 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1728 LDB_SCOPE_ONELEVEL, attrs,
1729 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s)))",
1730 name, name);
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);
1751 } else {
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 */
1757 base = 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,
1765 select_flag, NULL,
1766 base->data, 0,
1767 recs, &add_names, &add_count);
1768 if (!W_ERROR_IS_OK(status)) {
1769 talloc_free(tmp_ctx);
1770 return status;
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);
1785 return status;
1790 talloc_free(res);
1791 talloc_free(tree);
1792 talloc_free(name);
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);
1805 talloc_free(name);
1806 if (ret != LDB_SUCCESS) {
1807 continue;
1809 if (res->count == 1) {
1810 break;
1811 } else {
1812 talloc_free(res);
1813 continue;
1817 len = strlen(add_names[i]);
1818 if (add_names[i][len-1] == '.') {
1819 rname = talloc_strdup(tmp_ctx, add_names[i]);
1820 } else {
1821 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1823 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1824 select_flag, rname,
1825 res->msgs[0], 0, recs,
1826 NULL, NULL);
1827 talloc_free(rname);
1828 talloc_free(res);
1832 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1833 *buffer = recs;
1835 return WERR_OK;
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;
1849 char *name;
1850 WERROR status;
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, "@");
1858 } else {
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) {
1865 /* Add record */
1866 status = dnsserver_db_add_record(tmp_ctx, dsstate->samdb,
1867 z, name,
1868 &add_buf->rec);
1869 } else {
1870 /* Update record */
1871 status = dnsserver_db_update_record(tmp_ctx, dsstate->samdb,
1872 z, name,
1873 &add_buf->rec,
1874 &del_buf->rec);
1876 } else {
1877 if (del_buf == NULL) {
1878 /* Add empty node */
1879 status = dnsserver_db_add_empty_node(tmp_ctx, dsstate->samdb,
1880 z, name);
1881 } else {
1882 /* Delete record */
1883 status = dnsserver_db_delete_record(tmp_ctx, dsstate->samdb,
1884 z, name,
1885 &del_buf->rec);
1889 talloc_free(tmp_ctx);
1890 return status;
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;
1901 WERROR ret;
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);
1911 } else {
1912 request_filter = r->in.dwContext;
1915 if (r->in.pszZone == NULL) {
1916 ret = dnsserver_operate_server(dsstate, mem_ctx,
1917 r->in.pszOperation,
1918 DNS_CLIENT_VERSION_W2K,
1919 r->in.dwTypeId,
1920 &r->in.pData);
1921 } else {
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,
1928 request_filter,
1929 r->in.pszOperation,
1930 DNS_CLIENT_VERSION_W2K,
1931 r->in.dwTypeId,
1932 &r->in.pData);
1935 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1936 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation, NDR_IN, r);
1938 return ret;
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;
1945 WERROR ret;
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,
1957 r->in.pszOperation,
1958 DNS_CLIENT_VERSION_W2K,
1959 r->out.pdwTypeId,
1960 r->out.ppData);
1961 } else {
1962 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1963 if (z == NULL) {
1964 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1967 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
1968 r->in.pszOperation,
1969 DNS_CLIENT_VERSION_W2K,
1970 r->out.pdwTypeId,
1971 r->out.ppData);
1974 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1975 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery, NDR_IN, r);
1977 return ret;
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;
1984 WERROR ret;
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,
1996 r->in.pszOperation,
1997 DNS_CLIENT_VERSION_W2K,
1998 r->in.dwTypeIn,
1999 &r->in.pDataIn,
2000 r->out.pdwTypeOut,
2001 r->out.ppDataOut);
2002 } else {
2003 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2004 if (z == NULL) {
2005 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2008 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2009 r->in.pszOperation,
2010 DNS_CLIENT_VERSION_W2K,
2011 r->in.dwTypeIn,
2012 &r->in.pDataIn,
2013 r->out.pdwTypeOut,
2014 r->out.ppDataOut);
2017 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2018 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation, NDR_IN, r);
2020 return ret;
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;
2027 WERROR ret;
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,
2043 r->in.pszNodeName,
2044 r->in.wRecordType,
2045 r->in.fSelectFlag,
2046 r->out.pdwBufferLength,
2047 r->out.pBuffer);
2048 } else {
2049 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2050 if (z == NULL) {
2051 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2054 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2055 DNS_CLIENT_VERSION_W2K,
2056 r->in.pszNodeName,
2057 r->in.pszStartChild,
2058 r->in.wRecordType,
2059 r->in.fSelectFlag,
2060 r->in.pszFilterStart,
2061 r->in.pszFilterStop,
2062 r->out.pdwBufferLength,
2063 r->out.pBuffer);
2066 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2067 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords, NDR_IN, r);
2069 return ret;
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;
2076 WERROR ret;
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);
2087 if (z == NULL) {
2088 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2091 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2092 DNS_CLIENT_VERSION_W2K,
2093 r->in.pszNodeName,
2094 r->in.pAddRecord,
2095 r->in.pDeleteRecord);
2097 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2098 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord, NDR_IN, r);
2100 return ret;
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;
2108 WERROR ret;
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);
2118 } else {
2119 request_filter = r->in.dwContext;
2122 if (r->in.pszZone == NULL) {
2123 ret = dnsserver_operate_server(dsstate, mem_ctx,
2124 r->in.pszOperation,
2125 r->in.dwClientVersion,
2126 r->in.dwTypeId,
2127 &r->in.pData);
2128 } else {
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,
2135 request_filter,
2136 r->in.pszOperation,
2137 r->in.dwClientVersion,
2138 r->in.dwTypeId,
2139 &r->in.pData);
2142 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2143 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation2, NDR_IN, r);
2145 return ret;
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;
2152 WERROR ret;
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,
2164 r->in.pszOperation,
2165 r->in.dwClientVersion,
2166 r->out.pdwTypeId,
2167 r->out.ppData);
2168 } else {
2169 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2170 if (z == NULL) {
2171 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2174 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
2175 r->in.pszOperation,
2176 r->in.dwClientVersion,
2177 r->out.pdwTypeId,
2178 r->out.ppData);
2181 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2182 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery2, NDR_IN, r);
2184 return ret;
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;
2191 WERROR ret;
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,
2203 r->in.pszOperation,
2204 r->in.dwClientVersion,
2205 r->in.dwTypeIn,
2206 &r->in.pDataIn,
2207 r->out.pdwTypeOut,
2208 r->out.ppDataOut);
2209 } else {
2211 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2212 if (z == NULL) {
2213 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2216 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2217 r->in.pszOperation,
2218 r->in.dwClientVersion,
2219 r->in.dwTypeIn,
2220 &r->in.pDataIn,
2221 r->out.pdwTypeOut,
2222 r->out.ppDataOut);
2225 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2226 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation2, NDR_IN, r);
2228 return ret;
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;
2235 WERROR ret;
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,
2251 r->in.pszNodeName,
2252 r->in.wRecordType,
2253 r->in.fSelectFlag,
2254 r->out.pdwBufferLength,
2255 r->out.pBuffer);
2256 } else {
2257 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2258 if (z == NULL) {
2259 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2262 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2263 r->in.dwClientVersion,
2264 r->in.pszNodeName,
2265 r->in.pszStartChild,
2266 r->in.wRecordType,
2267 r->in.fSelectFlag,
2268 r->in.pszFilterStart,
2269 r->in.pszFilterStop,
2270 r->out.pdwBufferLength,
2271 r->out.pBuffer);
2275 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2276 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords2, NDR_IN, r);
2278 return ret;
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;
2285 WERROR ret;
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);
2296 if (z == NULL) {
2297 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2300 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2301 r->in.dwClientVersion,
2302 r->in.pszNodeName,
2303 r->in.pAddRecord,
2304 r->in.pDeleteRecord);
2306 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2307 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord2, NDR_IN, r);
2309 return ret;
2312 /* include the generated boilerplate */
2313 #include "librpc/gen_ndr/ndr_dnsserver_s.c"