ctdb-scripts: Support storing statd-callout state in cluster filesystem
[samba4-gss.git] / source4 / rpc_server / dnsserver / dcerpc_dnsserver.c
blobb1c7e2a9b239377acde278eca43e0e4480b2a789
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 "rpc_server/common/common.h"
26 #include "dsdb/samdb/samdb.h"
27 #include "lib/util/dlinklist.h"
28 #include "librpc/gen_ndr/ndr_dnsserver.h"
29 #include "dns_server/dnsserver_common.h"
30 #include "dnsserver.h"
32 #undef strcasecmp
34 #define DCESRV_INTERFACE_DNSSERVER_BIND(context, iface) \
35 dcesrv_interface_dnsserver_bind(context, iface)
36 static NTSTATUS dcesrv_interface_dnsserver_bind(struct dcesrv_connection_context *context,
37 const struct dcesrv_interface *iface)
39 return dcesrv_interface_bind_require_integrity(context, iface);
42 #define DNSSERVER_STATE_MAGIC 0xc9657ab4
43 struct dnsserver_state {
44 struct loadparm_context *lp_ctx;
45 struct ldb_context *samdb;
46 struct dnsserver_partition *partitions;
47 struct dnsserver_zone *zones;
48 int zones_count;
49 struct dnsserver_serverinfo *serverinfo;
53 /* Utility functions */
55 static void dnsserver_reload_zones(struct dnsserver_state *dsstate)
57 struct dnsserver_partition *p;
58 struct dnsserver_zone *zones, *z, *znext, *zmatch;
59 struct dnsserver_zone *old_list, *new_list;
61 old_list = dsstate->zones;
62 new_list = NULL;
64 for (p = dsstate->partitions; p; p = p->next) {
65 zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, p);
66 if (zones == NULL) {
67 continue;
69 for (z = zones; z; ) {
70 znext = z->next;
71 zmatch = dnsserver_find_zone(old_list, z->name);
72 if (zmatch == NULL) {
73 /* Missing zone */
74 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
75 if (z->zoneinfo == NULL) {
76 continue;
78 DLIST_ADD_END(new_list, z);
79 p->zones_count++;
80 dsstate->zones_count++;
81 } else {
82 /* Existing zone */
83 talloc_free(z);
84 DLIST_REMOVE(old_list, zmatch);
85 DLIST_ADD_END(new_list, zmatch);
87 z = znext;
91 if (new_list == NULL) {
92 return;
95 /* Deleted zones */
96 for (z = old_list; z; ) {
97 znext = z->next;
98 z->partition->zones_count--;
99 dsstate->zones_count--;
100 talloc_free(z);
101 z = znext;
104 dsstate->zones = new_list;
108 static struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_call)
110 struct dnsserver_state *dsstate;
111 struct dnsserver_zone *zones, *z, *znext;
112 struct dnsserver_partition *partitions, *p;
113 NTSTATUS status;
115 dsstate = dcesrv_iface_state_find_conn(dce_call,
116 DNSSERVER_STATE_MAGIC,
117 struct dnsserver_state);
118 if (dsstate != NULL) {
119 return dsstate;
122 dsstate = talloc_zero(dce_call, struct dnsserver_state);
123 if (dsstate == NULL) {
124 return NULL;
127 dsstate->lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
129 dsstate->samdb = dcesrv_samdb_connect_as_user(dsstate, dce_call);
130 if (dsstate->samdb == NULL) {
131 DEBUG(0,("dnsserver: Failed to open samdb\n"));
132 goto failed;
135 /* Initialize server info */
136 dsstate->serverinfo = dnsserver_init_serverinfo(dsstate,
137 dsstate->lp_ctx,
138 dsstate->samdb);
139 if (dsstate->serverinfo == NULL) {
140 goto failed;
143 /* Search for DNS partitions */
144 partitions = dnsserver_db_enumerate_partitions(dsstate, dsstate->serverinfo, dsstate->samdb);
145 if (partitions == NULL) {
146 goto failed;
148 dsstate->partitions = partitions;
150 /* Search for DNS zones */
151 for (p = partitions; p; p = p->next) {
152 zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, p);
153 if (zones == NULL) {
154 goto failed;
156 for (z = zones; z; ) {
157 znext = z->next;
158 if (dnsserver_find_zone(dsstate->zones, z->name) == NULL) {
159 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
160 if (z->zoneinfo == NULL) {
161 goto failed;
163 DLIST_ADD_END(dsstate->zones, z);
164 p->zones_count++;
165 dsstate->zones_count++;
166 } else {
167 /* Ignore duplicate zone */
168 DEBUG(3,("dnsserver: Ignoring duplicate zone '%s' from '%s'\n",
169 z->name, ldb_dn_get_linearized(z->zone_dn)));
171 z = znext;
175 status = dcesrv_iface_state_store_conn(dce_call,
176 DNSSERVER_STATE_MAGIC,
177 dsstate);
178 if (!NT_STATUS_IS_OK(status)) {
179 goto failed;
182 return dsstate;
184 failed:
185 talloc_free(dsstate);
186 dsstate = NULL;
187 return NULL;
191 /* dnsserver query functions */
193 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
194 static WERROR dnsserver_query_server(struct dnsserver_state *dsstate,
195 TALLOC_CTX *mem_ctx,
196 const char *operation,
197 const unsigned int client_version,
198 enum DNS_RPC_TYPEID *typeid,
199 union DNSSRV_RPC_UNION *r)
201 uint8_t is_integer, is_addresses, is_string, is_wstring, is_stringlist;
202 uint32_t answer_integer;
203 struct IP4_ARRAY *answer_iparray = NULL;
204 struct DNS_ADDR_ARRAY *answer_addrarray = NULL;
205 char *answer_string = NULL;
206 struct DNS_RPC_UTF8_STRING_LIST *answer_stringlist = NULL;
207 struct dnsserver_serverinfo *serverinfo;
209 serverinfo = dsstate->serverinfo;
211 if (strcasecmp(operation, "ServerInfo") == 0) {
212 if (client_version == DNS_CLIENT_VERSION_W2K) {
213 *typeid = DNSSRV_TYPEID_SERVER_INFO_W2K;
214 r->ServerInfoW2K = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_W2K);
216 r->ServerInfoW2K->dwVersion = serverinfo->dwVersion;
217 r->ServerInfoW2K->fBootMethod = serverinfo->fBootMethod;
218 r->ServerInfoW2K->fAdminConfigured = serverinfo->fAdminConfigured;
219 r->ServerInfoW2K->fAllowUpdate = serverinfo->fAllowUpdate;
220 r->ServerInfoW2K->fDsAvailable = serverinfo->fDsAvailable;
221 r->ServerInfoW2K->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
222 r->ServerInfoW2K->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
223 r->ServerInfoW2K->aipServerAddrs = dns_addr_array_to_ip4_array(mem_ctx,
224 serverinfo->aipServerAddrs);
225 r->ServerInfoW2K->aipListenAddrs = dns_addr_array_to_ip4_array(mem_ctx,
226 serverinfo->aipListenAddrs);
227 r->ServerInfoW2K->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
228 r->ServerInfoW2K->dwLogLevel = serverinfo->dwLogLevel;
229 r->ServerInfoW2K->dwDebugLevel = serverinfo->dwDebugLevel;
230 r->ServerInfoW2K->dwForwardTimeout = serverinfo->dwForwardTimeout;
231 r->ServerInfoW2K->dwRpcProtocol = serverinfo->dwRpcProtocol;
232 r->ServerInfoW2K->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
233 r->ServerInfoW2K->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
234 r->ServerInfoW2K->dwRecursionRetry = serverinfo->dwRecursionRetry;
235 r->ServerInfoW2K->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
236 r->ServerInfoW2K->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
237 r->ServerInfoW2K->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
238 r->ServerInfoW2K->dwScavengingInterval = serverinfo->dwScavengingInterval;
239 r->ServerInfoW2K->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
240 r->ServerInfoW2K->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
241 r->ServerInfoW2K->fAutoReverseZones = serverinfo->fAutoReverseZones;
242 r->ServerInfoW2K->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
243 r->ServerInfoW2K->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
244 r->ServerInfoW2K->fForwardDelegations = serverinfo->fForwardDelegations;
245 r->ServerInfoW2K->fNoRecursion = serverinfo->fNoRecursion;
246 r->ServerInfoW2K->fSecureResponses = serverinfo->fSecureResponses;
247 r->ServerInfoW2K->fRoundRobin = serverinfo->fRoundRobin;
248 r->ServerInfoW2K->fLocalNetPriority = serverinfo->fLocalNetPriority;
249 r->ServerInfoW2K->fBindSecondaries = serverinfo->fBindSecondaries;
250 r->ServerInfoW2K->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
251 r->ServerInfoW2K->fStrictFileParsing = serverinfo->fStrictFileParsing;
252 r->ServerInfoW2K->fLooseWildcarding = serverinfo->fLooseWildcarding;
253 r->ServerInfoW2K->fDefaultAgingState = serverinfo->fDefaultAgingState;
255 } else if (client_version == DNS_CLIENT_VERSION_DOTNET) {
256 *typeid = DNSSRV_TYPEID_SERVER_INFO_DOTNET;
257 r->ServerInfoDotNet = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_DOTNET);
259 r->ServerInfoDotNet->dwRpcStructureVersion = 0x01;
260 r->ServerInfoDotNet->dwVersion = serverinfo->dwVersion;
261 r->ServerInfoDotNet->fBootMethod = serverinfo->fBootMethod;
262 r->ServerInfoDotNet->fAdminConfigured = serverinfo->fAdminConfigured;
263 r->ServerInfoDotNet->fAllowUpdate = serverinfo->fAllowUpdate;
264 r->ServerInfoDotNet->fDsAvailable = serverinfo->fDsAvailable;
265 r->ServerInfoDotNet->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
266 r->ServerInfoDotNet->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
267 r->ServerInfoDotNet->aipServerAddrs = dns_addr_array_to_ip4_array(mem_ctx,
268 serverinfo->aipServerAddrs);
269 r->ServerInfoDotNet->aipListenAddrs = dns_addr_array_to_ip4_array(mem_ctx,
270 serverinfo->aipListenAddrs);
271 r->ServerInfoDotNet->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
272 r->ServerInfoDotNet->aipLogFilter = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
273 r->ServerInfoDotNet->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
274 r->ServerInfoDotNet->pszDomainName = talloc_strdup(mem_ctx, serverinfo->pszDomainName);
275 r->ServerInfoDotNet->pszForestName = talloc_strdup(mem_ctx, serverinfo->pszForestName);
276 r->ServerInfoDotNet->pszDomainDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszDomainDirectoryPartition);
277 r->ServerInfoDotNet->pszForestDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszForestDirectoryPartition);
278 r->ServerInfoDotNet->dwLogLevel = serverinfo->dwLogLevel;
279 r->ServerInfoDotNet->dwDebugLevel = serverinfo->dwDebugLevel;
280 r->ServerInfoDotNet->dwForwardTimeout = serverinfo->dwForwardTimeout;
281 r->ServerInfoDotNet->dwRpcProtocol = serverinfo->dwRpcProtocol;
282 r->ServerInfoDotNet->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
283 r->ServerInfoDotNet->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
284 r->ServerInfoDotNet->dwRecursionRetry = serverinfo->dwRecursionRetry;
285 r->ServerInfoDotNet->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
286 r->ServerInfoDotNet->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
287 r->ServerInfoDotNet->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
288 r->ServerInfoDotNet->dwLocalNetPriorityNetMask = serverinfo->dwLocalNetPriorityNetMask;
289 r->ServerInfoDotNet->dwScavengingInterval = serverinfo->dwScavengingInterval;
290 r->ServerInfoDotNet->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
291 r->ServerInfoDotNet->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
292 r->ServerInfoDotNet->dwLastScavengeTime = serverinfo->dwLastScavengeTime;
293 r->ServerInfoDotNet->dwEventLogLevel = serverinfo->dwEventLogLevel;
294 r->ServerInfoDotNet->dwLogFileMaxSize = serverinfo->dwLogFileMaxSize;
295 r->ServerInfoDotNet->dwDsForestVersion = serverinfo->dwDsForestVersion;
296 r->ServerInfoDotNet->dwDsDomainVersion = serverinfo->dwDsDomainVersion;
297 r->ServerInfoDotNet->dwDsDsaVersion = serverinfo->dwDsDsaVersion;
298 r->ServerInfoDotNet->fAutoReverseZones = serverinfo->fAutoReverseZones;
299 r->ServerInfoDotNet->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
300 r->ServerInfoDotNet->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
301 r->ServerInfoDotNet->fForwardDelegations = serverinfo->fForwardDelegations;
302 r->ServerInfoDotNet->fNoRecursion = serverinfo->fNoRecursion;
303 r->ServerInfoDotNet->fSecureResponses = serverinfo->fSecureResponses;
304 r->ServerInfoDotNet->fRoundRobin = serverinfo->fRoundRobin;
305 r->ServerInfoDotNet->fLocalNetPriority = serverinfo->fLocalNetPriority;
306 r->ServerInfoDotNet->fBindSecondaries = serverinfo->fBindSecondaries;
307 r->ServerInfoDotNet->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
308 r->ServerInfoDotNet->fStrictFileParsing = serverinfo->fStrictFileParsing;
309 r->ServerInfoDotNet->fLooseWildcarding = serverinfo->fLooseWildcarding;
310 r->ServerInfoDotNet->fDefaultAgingState = serverinfo->fDefaultAgingState;
312 } else if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
313 *typeid = DNSSRV_TYPEID_SERVER_INFO;
314 r->ServerInfo = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_LONGHORN);
316 r->ServerInfo->dwRpcStructureVersion = 0x02;
317 r->ServerInfo->dwVersion = serverinfo->dwVersion;
318 r->ServerInfo->fBootMethod = serverinfo->fBootMethod;
319 r->ServerInfo->fAdminConfigured = serverinfo->fAdminConfigured;
320 r->ServerInfo->fAllowUpdate = serverinfo->fAllowUpdate;
321 r->ServerInfo->fDsAvailable = serverinfo->fDsAvailable;
322 r->ServerInfo->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
323 r->ServerInfo->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
324 r->ServerInfo->aipServerAddrs = serverinfo->aipServerAddrs;
325 r->ServerInfo->aipListenAddrs = serverinfo->aipListenAddrs;
326 r->ServerInfo->aipForwarders = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders);
327 r->ServerInfo->aipLogFilter = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter);
328 r->ServerInfo->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
329 r->ServerInfo->pszDomainName = talloc_strdup(mem_ctx, serverinfo->pszDomainName);
330 r->ServerInfo->pszForestName = talloc_strdup(mem_ctx, serverinfo->pszForestName);
331 r->ServerInfo->pszDomainDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszDomainDirectoryPartition);
332 r->ServerInfo->pszForestDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszForestDirectoryPartition);
333 r->ServerInfo->dwLogLevel = serverinfo->dwLogLevel;
334 r->ServerInfo->dwDebugLevel = serverinfo->dwDebugLevel;
335 r->ServerInfo->dwForwardTimeout = serverinfo->dwForwardTimeout;
336 r->ServerInfo->dwRpcProtocol = serverinfo->dwRpcProtocol;
337 r->ServerInfo->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
338 r->ServerInfo->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
339 r->ServerInfo->dwRecursionRetry = serverinfo->dwRecursionRetry;
340 r->ServerInfo->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
341 r->ServerInfo->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
342 r->ServerInfo->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
343 r->ServerInfo->dwLocalNetPriorityNetMask = serverinfo->dwLocalNetPriorityNetMask;
344 r->ServerInfo->dwScavengingInterval = serverinfo->dwScavengingInterval;
345 r->ServerInfo->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
346 r->ServerInfo->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
347 r->ServerInfo->dwLastScavengeTime = serverinfo->dwLastScavengeTime;
348 r->ServerInfo->dwEventLogLevel = serverinfo->dwEventLogLevel;
349 r->ServerInfo->dwLogFileMaxSize = serverinfo->dwLogFileMaxSize;
350 r->ServerInfo->dwDsForestVersion = serverinfo->dwDsForestVersion;
351 r->ServerInfo->dwDsDomainVersion = serverinfo->dwDsDomainVersion;
352 r->ServerInfo->dwDsDsaVersion = serverinfo->dwDsDsaVersion;
353 r->ServerInfo->fReadOnlyDC = serverinfo->fReadOnlyDC;
354 r->ServerInfo->fAutoReverseZones = serverinfo->fAutoReverseZones;
355 r->ServerInfo->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
356 r->ServerInfo->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
357 r->ServerInfo->fForwardDelegations = serverinfo->fForwardDelegations;
358 r->ServerInfo->fNoRecursion = serverinfo->fNoRecursion;
359 r->ServerInfo->fSecureResponses = serverinfo->fSecureResponses;
360 r->ServerInfo->fRoundRobin = serverinfo->fRoundRobin;
361 r->ServerInfo->fLocalNetPriority = serverinfo->fLocalNetPriority;
362 r->ServerInfo->fBindSecondaries = serverinfo->fBindSecondaries;
363 r->ServerInfo->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
364 r->ServerInfo->fStrictFileParsing = serverinfo->fStrictFileParsing;
365 r->ServerInfo->fLooseWildcarding = serverinfo->fLooseWildcarding;
366 r->ServerInfo->fDefaultAgingState = serverinfo->fDefaultAgingState;
368 return WERR_OK;
371 is_integer = 0;
372 answer_integer = 0;
374 if (strcasecmp(operation, "AddressAnswerLimit") == 0) {
375 answer_integer = serverinfo->cAddressAnswerLimit;
376 is_integer = 1;
377 } else if (strcasecmp(operation, "AdminConfigured") == 0) {
378 answer_integer = serverinfo->fAdminConfigured;
379 is_integer = 1;
380 } else if (strcasecmp(operation, "AllowCNAMEAtNS") == 0) {
381 answer_integer = 0;
382 is_integer = 1;
383 } else if (strcasecmp(operation, "AllowUpdate") == 0) {
384 answer_integer = serverinfo->fAllowUpdate;
385 is_integer = 1;
386 } else if (strcasecmp(operation, "AutoCacheUpdate") == 0) {
387 answer_integer = serverinfo->fAutoCacheUpdate;
388 is_integer = 1;
389 } else if (strcasecmp(operation, "AutoConfigFileZones") == 0) {
390 answer_integer = 1;
391 is_integer = 1;
392 } else if (strcasecmp(operation, "BindSecondaries") == 0) {
393 answer_integer = serverinfo->fBindSecondaries;
394 is_integer = 1;
395 } else if (strcasecmp(operation, "BootMethod") == 0) {
396 answer_integer = serverinfo->fBootMethod;
397 is_integer = 1;
398 } else if (strcasecmp(operation, "DebugLevel") == 0) {
399 answer_integer = serverinfo->dwDebugLevel;
400 is_integer = 1;
401 } else if (strcasecmp(operation, "DefaultAgingState") == 0) {
402 answer_integer = serverinfo->fDefaultAgingState;
403 is_integer = 1;
404 } else if (strcasecmp(operation, "DefaultNoRefreshInterval") == 0) {
405 answer_integer = serverinfo->dwDefaultNoRefreshInterval;
406 is_integer = 1;
407 } else if (strcasecmp(operation, "DefaultRefreshInterval") == 0) {
408 answer_integer = serverinfo->dwDefaultRefreshInterval;
409 is_integer = 1;
410 } else if (strcasecmp(operation, "DeleteOutsideGlue") == 0) {
411 answer_integer = 0;
412 is_integer = 1;
413 } else if (strcasecmp(operation, "DisjointNets") == 0) {
414 answer_integer = 0;
415 is_integer = 1;
416 } else if (strcasecmp(operation, "DsLazyUpdateInterval") == 0) {
417 answer_integer = 3; /* seconds */
418 is_integer = 1;
419 } else if (strcasecmp(operation, "DsPollingInterval") == 0) {
420 answer_integer = serverinfo->dwDsPollingInterval;
421 is_integer = 1;
422 } else if (strcasecmp(operation, "DsTombstoneInterval") == 0) {
423 answer_integer = 0x00127500; /* 14 days */
424 is_integer = 1;
425 } else if (strcasecmp(operation, "EnableRegistryBoot") == 0) {
426 answer_integer = 0;
427 is_integer = 1;
428 } else if (strcasecmp(operation, "EventLogLevel") == 0) {
429 answer_integer = serverinfo->dwEventLogLevel;
430 is_integer = 1;
431 } else if (strcasecmp(operation, "ForceSoaSerial") == 0) {
432 answer_integer = 0;
433 is_integer = 1;
434 } else if (strcasecmp(operation, "ForceSaoRetry") == 0) {
435 answer_integer = 0;
436 is_integer = 1;
437 } else if (strcasecmp(operation, "ForceSoaRefresh") == 0) {
438 answer_integer = 0;
439 is_integer = 1;
440 } else if (strcasecmp(operation, "ForceSoaMinimumTtl") == 0) {
441 answer_integer = 0;
442 is_integer = 1;
443 } else if (strcasecmp(operation, "ForwardDelegations") == 0) {
444 answer_integer = 1;
445 is_integer = 1;
446 } else if (strcasecmp(operation, "ForwardingTimeout") == 0) {
447 answer_integer = serverinfo->dwForwardTimeout;
448 is_integer = 1;
449 } else if (strcasecmp(operation, "IsSlave") == 0) {
450 answer_integer = 0;
451 is_integer = 1;
452 } else if (strcasecmp(operation, "LocalNetPriority") == 0) {
453 answer_integer = serverinfo->fLocalNetPriority;
454 is_integer = 1;
455 } else if (strcasecmp(operation, "LogFileMaxSize") == 0) {
456 answer_integer = serverinfo->dwLogFileMaxSize;
457 is_integer = 1;
458 } else if (strcasecmp(operation, "LogLevel") == 0) {
459 answer_integer = serverinfo->dwLogLevel;
460 is_integer = 1;
461 } else if (strcasecmp(operation, "LooseWildcarding") == 0) {
462 answer_integer = serverinfo->fLooseWildcarding;
463 is_integer = 1;
464 } else if (strcasecmp(operation, "MaxCacheTtl") == 0) {
465 answer_integer = serverinfo->dwMaxCacheTtl;
466 is_integer = 1;
467 } else if (strcasecmp(operation, "MaxNegativeCacheTtl") == 0) {
468 answer_integer = 0x00000384; /* 15 minutes */
469 is_integer = 1;
470 } else if (strcasecmp(operation, "NameCheckFlag") == 0) {
471 answer_integer = serverinfo->dwNameCheckFlag;
472 is_integer = 1;
473 } else if (strcasecmp(operation, "NoRecursion") == 0) {
474 answer_integer = serverinfo->fNoRecursion;
475 is_integer = 1;
476 } else if (strcasecmp(operation, "NoUpdateDelegations") == 0) {
477 answer_integer = 1;
478 is_integer = 1;
479 } else if (strcasecmp(operation, "PublishAutonet") == 0) {
480 answer_integer = 0;
481 is_integer = 1;
482 } else if (strcasecmp(operation, "QuietRecvFaultInterval") == 0) {
483 answer_integer = 0;
484 is_integer = 1;
485 } else if (strcasecmp(operation, "QuietRecvLogInterval") == 0) {
486 answer_integer = 0;
487 is_integer = 1;
488 } else if (strcasecmp(operation, "RecursionRetry") == 0) {
489 answer_integer = serverinfo->dwRecursionRetry;
490 is_integer = 1;
491 } else if (strcasecmp(operation, "RecursionTimeout") == 0) {
492 answer_integer = serverinfo->dwRecursionTimeout;
493 is_integer = 1;
494 } else if (strcasecmp(operation, "ReloadException") == 0) {
495 answer_integer = 0;
496 is_integer = 1;
497 } else if (strcasecmp(operation, "RoundRobin") == 0) {
498 answer_integer = serverinfo->fRoundRobin;
499 is_integer = 1;
500 } else if (strcasecmp(operation, "RpcProtocol") == 0) {
501 answer_integer = serverinfo->dwRpcProtocol;
502 is_integer = 1;
503 } else if (strcasecmp(operation, "SecureResponses") == 0) {
504 answer_integer = serverinfo->fSecureResponses;
505 is_integer = 1;
506 } else if (strcasecmp(operation, "SendPort") == 0) {
507 answer_integer = 0;
508 is_integer = 1;
509 } else if (strcasecmp(operation, "ScavengingInterval") == 0) {
510 answer_integer = serverinfo->dwScavengingInterval;
511 is_integer = 1;
512 } else if (strcasecmp(operation, "SocketPoolSize") == 0) {
513 answer_integer = 0x000009C4;
514 is_integer = 1;
515 } else if (strcasecmp(operation, "StrictFileParsing") == 0) {
516 answer_integer = serverinfo->fStrictFileParsing;
517 is_integer = 1;
518 } else if (strcasecmp(operation, "SyncDnsZoneSerial") == 0) {
519 answer_integer = 2; /* ZONE_SERIAL_SYNC_XFER */
520 is_integer = 1;
521 } else if (strcasecmp(operation, "UpdateOptions") == 0) {
522 answer_integer = 0x0000030F; /* DNS_DEFAULT_UPDATE_OPTIONS */
523 is_integer = 1;
524 } else if (strcasecmp(operation, "UseSystemEvengLog") == 0) {
525 answer_integer = 0;
526 is_integer = 1;
527 } else if (strcasecmp(operation, "Version") == 0) {
528 answer_integer = serverinfo->dwVersion;
529 is_integer = 1;
530 } else if (strcasecmp(operation, "XfrConnectTimeout") == 0) {
531 answer_integer = 0x0000001E;
532 is_integer = 1;
533 } else if (strcasecmp(operation, "WriteAuthorityNs") == 0) {
534 answer_integer = serverinfo->fWriteAuthorityNs;
535 is_integer = 1;
536 } else if (strcasecmp(operation, "AdditionalRecursionTimeout") == 0) {
537 answer_integer = 0x00000004;
538 is_integer = 1;
539 } else if (strcasecmp(operation, "AppendMsZoneTransferFlag") == 0) {
540 answer_integer = 0;
541 is_integer = 1;
542 } else if (strcasecmp(operation, "AutoCreateDelegations") == 0) {
543 answer_integer = 0; /* DNS_ACD_DONT_CREATE */
544 is_integer = 1;
545 } else if (strcasecmp(operation, "BreakOnAscFailure") == 0) {
546 answer_integer = 0;
547 is_integer = 1;
548 } else if (strcasecmp(operation, "CacheEmptyAuthResponses") == 0) {
549 answer_integer = 0;
550 is_integer = 1;
551 } else if (strcasecmp(operation, "DirectoryPartitionAutoEnlistInterval") == 0) {
552 answer_integer = 0x00015180; /* 1 day */
553 is_integer = 1;
554 } else if (strcasecmp(operation, "DisableAutoReverseZones") == 0) {
555 answer_integer = ~serverinfo->fAutoReverseZones;
556 is_integer = 1;
557 } else if (strcasecmp(operation, "EDnsCacheTimeout") == 0) {
558 answer_integer = 0x00000384; /* 15 minutes */
559 is_integer = 1;
560 } else if (strcasecmp(operation, "EnableDirectoryPartitions") == 0) {
561 answer_integer = serverinfo->fDsAvailable;
562 is_integer = 1;
563 } else if (strcasecmp(operation, "EnableDnsSec") == 0) {
564 answer_integer = 0;
565 is_integer = 1;
566 } else if (strcasecmp(operation, "EnableEDnsProbes") == 0) {
567 answer_integer = 0;
568 is_integer = 1;
569 } else if (strcasecmp(operation, "EnableEDnsReception") == 0) {
570 answer_integer = 0;
571 is_integer = 1;
572 } else if (strcasecmp(operation, "EnableIPv6") == 0) {
573 answer_integer = 0;
574 is_integer = 1;
575 } else if (strcasecmp(operation, "EnableIQueryResponseGeneration") == 0) {
576 answer_integer = 0;
577 is_integer = 1;
578 } else if (strcasecmp(operation, "EnableSendErrorSuppression") == 0) {
579 answer_integer = 0;
580 is_integer = 1;
581 } else if (strcasecmp(operation, "EnableUpdateForwarding") == 0) {
582 answer_integer = 0;
583 is_integer = 1;
584 } else if (strcasecmp(operation, "EnableWinsR") == 0) {
585 answer_integer = 0;
586 is_integer = 1;
587 } else if (strcasecmp(operation, "ForceDsaBehaviorVersion") == 0) {
588 answer_integer = serverinfo->dwDsDsaVersion;
589 is_integer = 1;
590 } else if (strcasecmp(operation, "ForceDomainBehaviorVersion") == 0) {
591 answer_integer = serverinfo->dwDsDsaVersion;
592 is_integer = 1;
593 } else if (strcasecmp(operation, "ForceForestBehaviorVersion") == 0) {
594 answer_integer = serverinfo->dwDsDsaVersion;
595 is_integer = 1;
596 } else if (strcasecmp(operation, "HeapDebug") == 0) {
597 answer_integer = 0;
598 is_integer = 1;
599 } else if (strcasecmp(operation, "LameDelegationTtl") == 0) {
600 answer_integer = 0; /* seconds */
601 is_integer = 1;
602 } else if (strcasecmp(operation, "LocalNetPriorityNetMask") == 0) {
603 answer_integer = serverinfo->dwLocalNetPriorityNetMask;
604 is_integer = 1;
605 } else if (strcasecmp(operation, "MaxCacheSize") == 0) {
606 answer_integer = 0;
607 is_integer = 1;
608 } else if (strcasecmp(operation, "MaxResourceRecordsInNonSecureUpdate") == 0) {
609 answer_integer = 0x0000001E;
610 is_integer = 1;
611 } else if (strcasecmp(operation, "OperationsLogLevel") == 0) {
612 answer_integer = 0;
613 is_integer = 1;
614 } else if (strcasecmp(operation, "OperationsLogLevel2") == 0) {
615 answer_integer = 0;
616 is_integer = 1;
617 } else if (strcasecmp(operation, "MaximumUdpPacketSize") == 0) {
618 answer_integer = 0x00004000; /* maximum possible */
619 is_integer = 1;
620 } else if (strcasecmp(operation, "RecurseToInternetRootMask") == 0) {
621 answer_integer = 0;
622 is_integer = 1;
623 } else if (strcasecmp(operation, "SelfTest") == 0) {
624 answer_integer = 0;
625 is_integer = 1;
626 } else if (strcasecmp(operation, "SilentlyIgnoreCNameUpdateConflicts") == 0) {
627 answer_integer = 1;
628 is_integer = 1;
629 } else if (strcasecmp(operation, "TcpReceivePacketSize") == 0) {
630 answer_integer = 0x00010000;
631 is_integer = 1;
632 } else if (strcasecmp(operation, "XfrThrottleMultiplier") == 0) {
633 answer_integer = 0x0000000A;
634 is_integer = 1;
635 } else if (strcasecmp(operation, "AllowMsdcsLookupRetry") == 0) {
636 answer_integer = 1;
637 is_integer = 1;
638 } else if (strcasecmp(operation, "AllowReadOnlyZoneTransfer") == 0) {
639 answer_integer = 0;
640 is_integer = 1;
641 } else if (strcasecmp(operation, "DsBackGroundLoadPaused") == 0) {
642 answer_integer = 0;
643 is_integer = 1;
644 } else if (strcasecmp(operation, "DsMinimumBackgroundLoadThreads") == 0) {
645 answer_integer = 0;
646 is_integer = 1;
647 } else if (strcasecmp(operation, "DsRemoteReplicationDelay") == 0) {
648 answer_integer = 0x0000001E; /* 30 seconds */
649 is_integer = 1;
650 } else if (strcasecmp(operation, "EnableDuplicateQuerySuppresion") == 0) {
651 answer_integer = 0;
652 is_integer = 1;
653 } else if (strcasecmp(operation, "EnableGlobalNamesSupport") == 0) {
654 answer_integer = 0;
655 is_integer = 1;
656 } else if (strcasecmp(operation, "EnableVersionQuery") == 0) {
657 answer_integer = 1; /* DNS_VERSION_QUERY_FULL */
658 is_integer = 1;
659 } else if (strcasecmp(operation, "EnableRsoForRodc") == 0) {
660 answer_integer = 0;
661 is_integer = 1;
662 } else if (strcasecmp(operation, "ForceRODCMode") == 0) {
663 answer_integer = 0;
664 is_integer = 1;
665 } else if (strcasecmp(operation, "GlobalNamesAlwaysQuerySrv") == 0) {
666 answer_integer = 1;
667 is_integer = 1;
668 } else if (strcasecmp(operation, "GlobalNamesBlockUpdates") == 0) {
669 answer_integer = 0;
670 is_integer = 1;
671 } else if (strcasecmp(operation, "GlobalNamesEnableEDnsProbes") == 0) {
672 answer_integer = 0;
673 is_integer = 1;
674 } else if (strcasecmp(operation, "GlobalNamesPreferAAAA") == 0) {
675 answer_integer = 0;
676 is_integer = 1;
677 } else if (strcasecmp(operation, "GlobalNamesQueryOrder") == 0) {
678 answer_integer = 1;
679 is_integer = 1;
680 } else if (strcasecmp(operation, "GlobalNamesSendTimeout") == 0) {
681 answer_integer = 3; /* seconds */
682 is_integer = 1;
683 } else if (strcasecmp(operation, "GlobalNamesServerQueryInterval") == 0) {
684 answer_integer = 0x00005460; /* 6 hours */
685 is_integer = 1;
686 } else if (strcasecmp(operation, "RemoteIPv4RankBoost") == 0) {
687 answer_integer = 0;
688 is_integer = 1;
689 } else if (strcasecmp(operation, "RemoteIPv6RankBoost") == 0) {
690 answer_integer = 0;
691 is_integer = 1;
692 } else if (strcasecmp(operation, "MaximumRodcRsoAttemptsPerCycle") == 0) {
693 answer_integer = 0x00000064;
694 is_integer = 1;
695 } else if (strcasecmp(operation, "MaximumRodcRsoQueueLength") == 0) {
696 answer_integer = 0x0000012C;
697 is_integer = 1;
698 } else if (strcasecmp(operation, "EnableGlobalQueryBlockList") == 0) {
699 answer_integer = 0;
700 is_integer = 1;
701 } else if (strcasecmp(operation, "OpenACLOnProxyUpdates") == 0) {
702 answer_integer = 0;
703 is_integer = 1;
704 } else if (strcasecmp(operation, "CacheLockingPercent") == 0) {
705 answer_integer = 0x00000064;
706 is_integer = 1;
709 if (is_integer == 1) {
710 *typeid = DNSSRV_TYPEID_DWORD;
711 r->Dword = answer_integer;
712 return WERR_OK;
715 is_addresses = 0;
717 if (strcasecmp(operation, "Forwarders") == 0) {
718 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
719 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders);
720 } else {
721 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
723 is_addresses = 1;
724 } else if (strcasecmp(operation, "ListenAddresses") == 0) {
725 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
726 answer_addrarray = serverinfo->aipListenAddrs;
727 } else {
728 answer_iparray = dns_addr_array_to_ip4_array(mem_ctx, serverinfo->aipListenAddrs);
730 is_addresses = 1;
731 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
732 is_addresses = 1;
733 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
734 is_addresses = 1;
735 } else if (strcasecmp(operation, "LogIPFilterList") == 0) {
736 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
737 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter);
738 } else {
739 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
741 is_addresses = 1;
744 if (is_addresses == 1) {
745 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
746 *typeid = DNSSRV_TYPEID_ADDRARRAY;
747 r->AddrArray = answer_addrarray;
748 } else {
749 *typeid = DNSSRV_TYPEID_IPARRAY;
750 r->IpArray = answer_iparray;
752 return WERR_OK;
755 is_string = is_wstring = 0;
757 if (strcasecmp(operation, "DomainDirectoryPartitionBaseName") == 0) {
758 answer_string = talloc_strdup(mem_ctx, "DomainDnsZones");
759 if (! answer_string) {
760 return WERR_OUTOFMEMORY;
762 is_string = 1;
763 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
764 answer_string = talloc_strdup(mem_ctx, "ForestDnsZones");
765 if (! answer_string) {
766 return WERR_OUTOFMEMORY;
768 is_string = 1;
769 } else if (strcasecmp(operation, "LogFilePath") == 0) {
770 answer_string = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
771 is_wstring = 1;
772 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
773 is_wstring = 1;
774 } else if (strcasecmp(operation, "DsBackgroundPauseName") == 0) {
775 is_string = 1;
776 } else if (strcasecmp(operation, "DsNotRoundRobinTypes") == 0) {
777 is_string = 1;
780 if (is_string == 1) {
781 *typeid = DNSSRV_TYPEID_LPSTR;
782 r->String = answer_string;
783 return WERR_OK;
784 } else if (is_wstring == 1) {
785 *typeid = DNSSRV_TYPEID_LPWSTR;
786 r->WideString = answer_string;
787 return WERR_OK;
790 is_stringlist = 0;
792 if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
793 is_stringlist = 1;
794 } else if (strcasecmp(operation, "SocketPoolExcludedPortRanges") == 0) {
795 is_stringlist = 1;
798 if (is_stringlist == 1) {
799 *typeid = DNSSRV_TYPEID_UTF8_STRING_LIST;
800 r->Utf8StringList = answer_stringlist;
801 return WERR_OK;
804 DEBUG(0,("dnsserver: Invalid server operation %s\n", operation));
805 return WERR_DNS_ERROR_INVALID_PROPERTY;
808 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
809 static WERROR dnsserver_query_zone(struct dnsserver_state *dsstate,
810 TALLOC_CTX *mem_ctx,
811 struct dnsserver_zone *z,
812 const char *operation,
813 const unsigned int client_version,
814 enum DNS_RPC_TYPEID *typeid,
815 union DNSSRV_RPC_UNION *r)
817 uint8_t is_integer, is_addresses, is_string;
818 uint32_t answer_integer = 0;
819 struct IP4_ARRAY *answer_iparray = NULL;
820 struct DNS_ADDR_ARRAY *answer_addrarray = NULL;
821 char *answer_string = NULL;
822 struct dnsserver_zoneinfo *zoneinfo;
824 zoneinfo = z->zoneinfo;
826 if (strcasecmp(operation, "Zone") == 0) {
827 if (client_version == DNS_CLIENT_VERSION_W2K) {
828 *typeid = DNSSRV_TYPEID_ZONE_W2K;
829 r->ZoneW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
831 r->ZoneW2K->pszZoneName = talloc_strdup(mem_ctx, z->name);
832 r->ZoneW2K->Flags = zoneinfo->Flags;
833 r->ZoneW2K->ZoneType = zoneinfo->dwZoneType;
834 r->ZoneW2K->Version = zoneinfo->Version;
835 } else {
836 *typeid = DNSSRV_TYPEID_ZONE;
837 r->Zone = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
839 r->Zone->dwRpcStructureVersion = 0x01;
840 r->Zone->pszZoneName = talloc_strdup(mem_ctx, z->name);
841 r->Zone->Flags = zoneinfo->Flags;
842 r->Zone->ZoneType = zoneinfo->dwZoneType;
843 r->Zone->Version = zoneinfo->Version;
844 r->Zone->dwDpFlags = z->partition->dwDpFlags;
845 r->Zone->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
847 return WERR_OK;
850 if (strcasecmp(operation, "ZoneInfo") == 0) {
851 if (client_version == DNS_CLIENT_VERSION_W2K) {
852 *typeid = DNSSRV_TYPEID_ZONE_INFO_W2K;
853 r->ZoneInfoW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_W2K);
855 r->ZoneInfoW2K->pszZoneName = talloc_strdup(mem_ctx, z->name);
856 r->ZoneInfoW2K->dwZoneType = zoneinfo->dwZoneType;
857 r->ZoneInfoW2K->fReverse = zoneinfo->fReverse;
858 r->ZoneInfoW2K->fAllowUpdate = zoneinfo->fAllowUpdate;
859 r->ZoneInfoW2K->fPaused = zoneinfo->fPaused;
860 r->ZoneInfoW2K->fShutdown = zoneinfo->fShutdown;
861 r->ZoneInfoW2K->fAutoCreated = zoneinfo->fAutoCreated;
862 r->ZoneInfoW2K->fUseDatabase = zoneinfo->fUseDatabase;
863 r->ZoneInfoW2K->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
864 r->ZoneInfoW2K->aipMasters = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
865 r->ZoneInfoW2K->fSecureSecondaries = zoneinfo->fSecureSecondaries;
866 r->ZoneInfoW2K->fNotifyLevel = zoneinfo->fNotifyLevel;
867 r->ZoneInfoW2K->aipSecondaries = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
868 r->ZoneInfoW2K->aipNotify = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
869 r->ZoneInfoW2K->fUseWins = zoneinfo->fUseWins;
870 r->ZoneInfoW2K->fUseNbstat = zoneinfo->fUseNbstat;
871 r->ZoneInfoW2K->fAging = zoneinfo->fAging;
872 r->ZoneInfoW2K->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
873 r->ZoneInfoW2K->dwRefreshInterval = zoneinfo->dwRefreshInterval;
874 r->ZoneInfoW2K->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
875 r->ZoneInfoW2K->aipScavengeServers = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
877 } else if (client_version == DNS_CLIENT_VERSION_DOTNET) {
878 *typeid = DNSSRV_TYPEID_ZONE_INFO_DOTNET;
879 r->ZoneInfoDotNet = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_DOTNET);
881 r->ZoneInfoDotNet->dwRpcStructureVersion = 0x01;
882 r->ZoneInfoDotNet->pszZoneName = talloc_strdup(mem_ctx, z->name);
883 r->ZoneInfoDotNet->dwZoneType = zoneinfo->dwZoneType;
884 r->ZoneInfoDotNet->fReverse = zoneinfo->fReverse;
885 r->ZoneInfoDotNet->fAllowUpdate = zoneinfo->fAllowUpdate;
886 r->ZoneInfoDotNet->fPaused = zoneinfo->fPaused;
887 r->ZoneInfoDotNet->fShutdown = zoneinfo->fShutdown;
888 r->ZoneInfoDotNet->fAutoCreated = zoneinfo->fAutoCreated;
889 r->ZoneInfoDotNet->fUseDatabase = zoneinfo->fUseDatabase;
890 r->ZoneInfoDotNet->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
891 r->ZoneInfoDotNet->aipMasters = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
892 r->ZoneInfoDotNet->fSecureSecondaries = zoneinfo->fSecureSecondaries;
893 r->ZoneInfoDotNet->fNotifyLevel = zoneinfo->fNotifyLevel;
894 r->ZoneInfoDotNet->aipSecondaries = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
895 r->ZoneInfoDotNet->aipNotify = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
896 r->ZoneInfoDotNet->fUseWins = zoneinfo->fUseWins;
897 r->ZoneInfoDotNet->fUseNbstat = zoneinfo->fUseNbstat;
898 r->ZoneInfoDotNet->fAging = zoneinfo->fAging;
899 r->ZoneInfoDotNet->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
900 r->ZoneInfoDotNet->dwRefreshInterval = zoneinfo->dwRefreshInterval;
901 r->ZoneInfoDotNet->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
902 r->ZoneInfoDotNet->aipScavengeServers = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
903 r->ZoneInfoDotNet->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
904 r->ZoneInfoDotNet->fForwarderSlave = zoneinfo->fForwarderSlave;
905 r->ZoneInfoDotNet->aipLocalMasters = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
906 r->ZoneInfoDotNet->dwDpFlags = z->partition->dwDpFlags;
907 r->ZoneInfoDotNet->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
908 r->ZoneInfoDotNet->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
909 r->ZoneInfoDotNet->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
910 r->ZoneInfoDotNet->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
912 } else {
913 *typeid = DNSSRV_TYPEID_ZONE_INFO;
914 r->ZoneInfo = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_LONGHORN);
916 r->ZoneInfo->dwRpcStructureVersion = 0x02;
917 r->ZoneInfo->pszZoneName = talloc_strdup(mem_ctx, z->name);
918 r->ZoneInfo->dwZoneType = zoneinfo->dwZoneType;
919 r->ZoneInfo->fReverse = zoneinfo->fReverse;
920 r->ZoneInfo->fAllowUpdate = zoneinfo->fAllowUpdate;
921 r->ZoneInfo->fPaused = zoneinfo->fPaused;
922 r->ZoneInfo->fShutdown = zoneinfo->fShutdown;
923 r->ZoneInfo->fAutoCreated = zoneinfo->fAutoCreated;
924 r->ZoneInfo->fUseDatabase = zoneinfo->fUseDatabase;
925 r->ZoneInfo->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
926 r->ZoneInfo->aipMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipMasters);
927 r->ZoneInfo->fSecureSecondaries = zoneinfo->fSecureSecondaries;
928 r->ZoneInfo->fNotifyLevel = zoneinfo->fNotifyLevel;
929 r->ZoneInfo->aipSecondaries = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipSecondaries);
930 r->ZoneInfo->aipNotify = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipNotify);
931 r->ZoneInfo->fUseWins = zoneinfo->fUseWins;
932 r->ZoneInfo->fUseNbstat = zoneinfo->fUseNbstat;
933 r->ZoneInfo->fAging = zoneinfo->fAging;
934 r->ZoneInfo->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
935 r->ZoneInfo->dwRefreshInterval = zoneinfo->dwRefreshInterval;
936 r->ZoneInfo->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
937 r->ZoneInfo->aipScavengeServers = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipScavengeServers);
938 r->ZoneInfo->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
939 r->ZoneInfo->fForwarderSlave = zoneinfo->fForwarderSlave;
940 r->ZoneInfo->aipLocalMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
941 r->ZoneInfo->dwDpFlags = z->partition->dwDpFlags;
942 r->ZoneInfo->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
943 r->ZoneInfo->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
944 r->ZoneInfo->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
945 r->ZoneInfo->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
947 r->ZoneInfo->fQueuedForBackgroundLoad = zoneinfo->fQueuedForBackgroundLoad;
948 r->ZoneInfo->fBackgroundLoadInProgress = zoneinfo->fBackgroundLoadInProgress;
949 r->ZoneInfo->fReadOnlyZone = zoneinfo->fReadOnlyZone;
950 r->ZoneInfo->dwLastXfrAttempt = zoneinfo->dwLastXfrAttempt;
951 r->ZoneInfo->dwLastXfrResult = zoneinfo->dwLastXfrResult;
954 return WERR_OK;
957 is_integer = 0;
959 if (strcasecmp(operation, "AllowUpdate") == 0) {
960 answer_integer = zoneinfo->fAllowUpdate;
961 is_integer = 1;
962 } else if (strcasecmp(operation, "Secured") == 0) {
963 answer_integer = 0;
964 is_integer = 1;
965 } else if (strcasecmp(operation, "DsIntegrated") == 0) {
966 answer_integer = zoneinfo->fUseDatabase;
967 is_integer = 1;
968 } else if (strcasecmp(operation, "LogUpdates") == 0) {
969 answer_integer = 0;
970 is_integer = 1;
971 } else if (strcasecmp(operation, "NoRefreshInterval") == 0) {
972 answer_integer = zoneinfo->dwNoRefreshInterval;
973 is_integer = 1;
974 } else if (strcasecmp(operation, "NotifyLevel") == 0) {
975 answer_integer = zoneinfo->fNotifyLevel;
976 is_integer = 1;
977 } else if (strcasecmp(operation, "RefreshInterval") == 0) {
978 answer_integer = zoneinfo->dwRefreshInterval;
979 is_integer = 1;
980 } else if (strcasecmp(operation, "SecureSecondaries") == 0) {
981 answer_integer = zoneinfo->fSecureSecondaries;
982 is_integer = 1;
983 } else if (strcasecmp(operation, "Type") == 0) {
984 answer_integer = zoneinfo->dwZoneType;
985 is_integer = 1;
986 } else if (strcasecmp(operation, "Aging") == 0) {
987 answer_integer = zoneinfo->fAging;
988 is_integer = 1;
989 } else if (strcasecmp(operation, "ForwarderSlave") == 0) {
990 answer_integer = zoneinfo->fForwarderSlave;
991 is_integer = 1;
992 } else if (strcasecmp(operation, "ForwarderTimeout") == 0) {
993 answer_integer = zoneinfo->dwForwarderTimeout;
994 is_integer = 1;
995 } else if (strcasecmp(operation, "Unicode") == 0) {
996 answer_integer = 0;
997 is_integer = 1;
1000 if (is_integer == 1) {
1001 *typeid = DNSSRV_TYPEID_DWORD;
1002 r->Dword = answer_integer;
1003 return WERR_OK;
1006 is_addresses = 0;
1008 if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
1009 is_addresses = 1;
1010 } else if (strcasecmp(operation, "ScavengeServers") == 0) {
1011 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1012 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipScavengeServers);
1013 } else {
1014 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
1016 is_addresses = 1;
1017 } else if (strcasecmp(operation, "MasterServers") == 0) {
1018 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1019 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipMasters);
1020 } else {
1021 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
1023 is_addresses = 1;
1024 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
1025 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1026 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
1027 } else {
1028 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
1030 is_addresses = 1;
1031 } else if (strcasecmp(operation, "NotifyServers") == 0) {
1032 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1033 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipNotify);
1034 } else {
1035 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
1037 is_addresses = 1;
1038 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
1039 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1040 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipSecondaries);
1041 } else {
1042 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
1044 is_addresses = 1;
1047 if (is_addresses == 1) {
1048 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
1049 *typeid = DNSSRV_TYPEID_ADDRARRAY;
1050 r->AddrArray = answer_addrarray;
1051 } else {
1052 *typeid = DNSSRV_TYPEID_IPARRAY;
1053 r->IpArray = answer_iparray;
1055 return WERR_OK;
1058 is_string = 0;
1060 if (strcasecmp(operation, "DatabaseFile") == 0) {
1061 answer_string = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
1062 is_string = 1;
1063 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1064 answer_string = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
1065 is_string = 1;
1066 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1067 is_string = 1;
1070 if (is_string == 1) {
1071 *typeid = DNSSRV_TYPEID_LPSTR;
1072 r->String = answer_string;
1073 return WERR_OK;
1076 DEBUG(0,("dnsserver: Invalid zone operation %s\n", operation));
1077 return WERR_DNS_ERROR_INVALID_PROPERTY;
1081 /* dnsserver operation functions */
1083 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
1084 static WERROR dnsserver_operate_server(struct dnsserver_state *dsstate,
1085 TALLOC_CTX *mem_ctx,
1086 const char *operation,
1087 const unsigned int client_version,
1088 enum DNS_RPC_TYPEID typeid,
1089 union DNSSRV_RPC_UNION *r)
1091 bool valid_operation = false;
1093 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1094 valid_operation = true;
1095 } else if (strcasecmp(operation, "Restart") == 0) {
1096 valid_operation = true;
1097 } else if (strcasecmp(operation, "ClearDebugLog") == 0) {
1098 valid_operation = true;
1099 } else if (strcasecmp(operation, "ClearCache") == 0) {
1100 valid_operation = true;
1101 } else if (strcasecmp(operation, "WriteDirtyZones") == 0) {
1102 valid_operation = true;
1103 } else if (strcasecmp(operation, "ZoneCreate") == 0) {
1104 struct dnsserver_zone *z, *z2;
1105 WERROR status;
1106 size_t len;
1107 const char *name;
1108 z = talloc_zero(mem_ctx, struct dnsserver_zone);
1109 W_ERROR_HAVE_NO_MEMORY(z);
1110 z->partition = talloc_zero(z, struct dnsserver_partition);
1111 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z->partition, z);
1112 z->zoneinfo = talloc_zero(z, struct dnsserver_zoneinfo);
1113 W_ERROR_HAVE_NO_MEMORY_AND_FREE(z->zoneinfo, z);
1115 if (typeid == DNSSRV_TYPEID_ZONE_CREATE_W2K) {
1116 name = r->ZoneCreateW2K->pszZoneName;
1117 z->zoneinfo->dwZoneType = r->ZoneCreateW2K->dwZoneType;
1118 z->zoneinfo->fAllowUpdate = r->ZoneCreateW2K->fAllowUpdate;
1119 z->zoneinfo->fAging = r->ZoneCreateW2K->fAging;
1120 z->zoneinfo->Flags = r->ZoneCreateW2K->dwFlags;
1121 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE_DOTNET) {
1122 name = r->ZoneCreateDotNet->pszZoneName;
1123 z->zoneinfo->dwZoneType = r->ZoneCreateDotNet->dwZoneType;
1124 z->zoneinfo->fAllowUpdate = r->ZoneCreateDotNet->fAllowUpdate;
1125 z->zoneinfo->fAging = r->ZoneCreateDotNet->fAging;
1126 z->zoneinfo->Flags = r->ZoneCreateDotNet->dwFlags;
1127 z->partition->dwDpFlags = r->ZoneCreateDotNet->dwDpFlags;
1128 } else if (typeid == DNSSRV_TYPEID_ZONE_CREATE) {
1129 name = r->ZoneCreate->pszZoneName;
1130 z->zoneinfo->dwZoneType = r->ZoneCreate->dwZoneType;
1131 z->zoneinfo->fAllowUpdate = r->ZoneCreate->fAllowUpdate;
1132 z->zoneinfo->fAging = r->ZoneCreate->fAging;
1133 z->zoneinfo->Flags = r->ZoneCreate->dwFlags;
1134 z->partition->dwDpFlags = r->ZoneCreate->dwDpFlags;
1135 } else {
1136 talloc_free(z);
1137 return WERR_DNS_ERROR_INVALID_PROPERTY;
1140 len = strlen(name);
1141 if (name[len-1] == '.') {
1142 len -= 1;
1144 z->name = talloc_strndup(z, name, len);
1145 if (z->name == NULL) {
1146 talloc_free(z);
1147 return WERR_NOT_ENOUGH_MEMORY;
1150 z2 = dnsserver_find_zone(dsstate->zones, z->name);
1151 if (z2 != NULL) {
1152 talloc_free(z);
1153 return WERR_DNS_ERROR_ZONE_ALREADY_EXISTS;
1156 status = dnsserver_db_create_zone(dsstate->samdb, dsstate->partitions, z,
1157 dsstate->lp_ctx);
1158 talloc_free(z);
1160 if (W_ERROR_IS_OK(status)) {
1161 dnsserver_reload_zones(dsstate);
1163 return status;
1164 } else if (strcasecmp(operation, "ClearStatistics") == 0) {
1165 valid_operation = true;
1166 } else if (strcasecmp(operation, "EnlistDirectoryPartition") == 0) {
1167 valid_operation = true;
1168 } else if (strcasecmp(operation, "StartScavenging") == 0) {
1169 valid_operation = true;
1170 } else if (strcasecmp(operation, "AbortScavenging") == 0) {
1171 valid_operation = true;
1172 } else if (strcasecmp(operation, "AutoConfigure") == 0) {
1173 valid_operation = true;
1174 } else if (strcasecmp(operation, "ExportSettings") == 0) {
1175 valid_operation = true;
1176 } else if (strcasecmp(operation, "PrepareForDemotion") == 0) {
1177 valid_operation = true;
1178 } else if (strcasecmp(operation, "PrepareForUninstall") == 0) {
1179 valid_operation = true;
1180 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1181 valid_operation = true;
1182 } else if (strcasecmp(operation, "DeleteRecord") == 0) {
1183 valid_operation = true;
1184 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1185 valid_operation = true;
1186 } else if (strcasecmp(operation, "ListenAddresses") == 0) {
1187 valid_operation = true;
1188 } else if (strcasecmp(operation, "Forwarders") == 0) {
1189 valid_operation = true;
1190 } else if (strcasecmp(operation, "LogFilePath") == 0) {
1191 valid_operation = true;
1192 } else if (strcasecmp(operation, "LogIpFilterList") == 0) {
1193 valid_operation = true;
1194 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
1195 valid_operation = true;
1196 } else if (strcasecmp(operation, "DomainDirectoryPartitionBaseName") == 0) {
1197 valid_operation = true;
1198 } else if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
1199 valid_operation = true;
1200 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
1201 valid_operation = true;
1202 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
1203 valid_operation = true;
1204 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
1205 valid_operation = true;
1208 if (valid_operation) {
1209 DEBUG(0, ("dnsserver: server operation '%s' not implemented\n", operation));
1210 return WERR_CALL_NOT_IMPLEMENTED;
1213 DEBUG(0, ("dnsserver: invalid server operation '%s'\n", operation));
1214 return WERR_DNS_ERROR_INVALID_PROPERTY;
1217 static WERROR dnsserver_complex_operate_server(struct dnsserver_state *dsstate,
1218 TALLOC_CTX *mem_ctx,
1219 const char *operation,
1220 const unsigned int client_version,
1221 enum DNS_RPC_TYPEID typeid_in,
1222 union DNSSRV_RPC_UNION *rin,
1223 enum DNS_RPC_TYPEID *typeid_out,
1224 union DNSSRV_RPC_UNION *rout)
1226 int valid_operation = 0;
1227 struct dnsserver_zone *z, **zlist;
1228 size_t zcount;
1229 bool found1, found2, found3, found4;
1230 size_t i;
1232 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1233 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1234 return dnsserver_query_server(dsstate, mem_ctx,
1235 rin->String,
1236 client_version,
1237 typeid_out,
1238 rout);
1240 } else if (strcasecmp(operation, "EnumZones") == 0) {
1241 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1242 return WERR_DNS_ERROR_INVALID_PROPERTY;
1245 zcount = 0;
1246 zlist = talloc_zero_array(mem_ctx, struct dnsserver_zone *, 0);
1247 for (z = dsstate->zones; z; z = z->next) {
1249 /* Match the flags in groups
1251 * Group1 : PRIMARY, SECONDARY, CACHE, AUTO
1252 * Group2 : FORWARD, REVERSE, FORWARDER, STUB
1253 * Group3 : DS, NON_DS, DOMAIN_DP, FOREST_DP
1254 * Group4 : CUSTOM_DP, LEGACY_DP
1257 /* Group 1 */
1258 found1 = false;
1259 if (rin->Dword & 0x0000000f) {
1260 if (rin->Dword & DNS_ZONE_REQUEST_PRIMARY) {
1261 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_PRIMARY) {
1262 found1 = true;
1265 if (rin->Dword & DNS_ZONE_REQUEST_SECONDARY) {
1266 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_SECONDARY) {
1267 found1 = true;
1270 if (rin->Dword & DNS_ZONE_REQUEST_CACHE) {
1271 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_CACHE) {
1272 found1 = true;
1275 if (rin->Dword & DNS_ZONE_REQUEST_AUTO) {
1276 if (z->zoneinfo->fAutoCreated
1277 || z->partition->dwDpFlags & DNS_DP_AUTOCREATED) {
1278 found1 = true;
1281 } else {
1282 found1 = true;
1285 /* Group 2 */
1286 found2 = false;
1287 if (rin->Dword & 0x000000f0) {
1288 if (rin->Dword & DNS_ZONE_REQUEST_FORWARD) {
1289 if (!(z->zoneinfo->fReverse)) {
1290 found2 = true;
1293 if (rin->Dword & DNS_ZONE_REQUEST_REVERSE) {
1294 if (z->zoneinfo->fReverse) {
1295 found2 = true;
1298 if (rin->Dword & DNS_ZONE_REQUEST_FORWARDER) {
1299 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_FORWARDER) {
1300 found2 = true;
1303 if (rin->Dword & DNS_ZONE_REQUEST_STUB) {
1304 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_STUB) {
1305 found2 = true;
1308 } else {
1309 found2 = true;
1312 /* Group 3 */
1313 found3 = false;
1314 if (rin->Dword & 0x00000f00) {
1315 if (rin->Dword & DNS_ZONE_REQUEST_DS) {
1316 if (z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED) {
1317 found3 = true;
1320 if (rin->Dword & DNS_ZONE_REQUEST_NON_DS) {
1321 if (!(z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED)) {
1322 found3 = true;
1325 if (rin->Dword & DNS_ZONE_REQUEST_DOMAIN_DP) {
1326 if (!(z->partition->dwDpFlags & DNS_DP_DOMAIN_DEFAULT)) {
1327 found3 = true;
1330 if (rin->Dword & DNS_ZONE_REQUEST_FOREST_DP) {
1331 if (!(z->partition->dwDpFlags & DNS_DP_FOREST_DEFAULT)) {
1332 found3 = true;
1335 } else {
1336 found3 = true;
1339 /* Group 4 */
1340 if (rin->Dword & 0x0000f000) {
1341 found4 = false;
1342 } else {
1343 found4 = true;
1346 if (found1 && found2 && found3 && found4) {
1347 zlist = talloc_realloc(mem_ctx, zlist, struct dnsserver_zone *, zcount+1);
1348 zlist[zcount] = z;
1349 zcount++;
1353 if (client_version == DNS_CLIENT_VERSION_W2K) {
1354 *typeid_out = DNSSRV_TYPEID_ZONE_LIST_W2K;
1355 rout->ZoneListW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_W2K);
1357 if (zcount == 0) {
1358 rout->ZoneListW2K->dwZoneCount = 0;
1359 rout->ZoneListW2K->ZoneArray = NULL;
1361 return WERR_OK;
1364 rout->ZoneListW2K->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_W2K *, zcount);
1365 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout->ZoneListW2K->ZoneArray, zlist);
1367 for (i=0; i<zcount; i++) {
1368 rout->ZoneListW2K->ZoneArray[i] = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
1370 rout->ZoneListW2K->ZoneArray[i]->pszZoneName = talloc_strdup(mem_ctx, zlist[i]->name);
1371 rout->ZoneListW2K->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
1372 rout->ZoneListW2K->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
1373 rout->ZoneListW2K->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
1375 rout->ZoneListW2K->dwZoneCount = zcount;
1377 } else {
1378 *typeid_out = DNSSRV_TYPEID_ZONE_LIST;
1379 rout->ZoneList = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_DOTNET);
1381 if (zcount == 0) {
1382 rout->ZoneList->dwRpcStructureVersion = 1;
1383 rout->ZoneList->dwZoneCount = 0;
1384 rout->ZoneList->ZoneArray = NULL;
1386 return WERR_OK;
1389 rout->ZoneList->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_DOTNET *, zcount);
1390 W_ERROR_HAVE_NO_MEMORY_AND_FREE(rout->ZoneList->ZoneArray, zlist);
1392 for (i=0; i<zcount; i++) {
1393 rout->ZoneList->ZoneArray[i] = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
1395 rout->ZoneList->ZoneArray[i]->dwRpcStructureVersion = 1;
1396 rout->ZoneList->ZoneArray[i]->pszZoneName = talloc_strdup(mem_ctx, zlist[i]->name);
1397 rout->ZoneList->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
1398 rout->ZoneList->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
1399 rout->ZoneList->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
1400 rout->ZoneList->ZoneArray[i]->dwDpFlags = zlist[i]->partition->dwDpFlags;
1401 rout->ZoneList->ZoneArray[i]->pszDpFqdn = talloc_strdup(mem_ctx, zlist[i]->partition->pszDpFqdn);
1403 rout->ZoneList->dwRpcStructureVersion = 1;
1404 rout->ZoneList->dwZoneCount = zcount;
1406 talloc_free(zlist);
1407 return WERR_OK;
1408 } else if (strcasecmp(operation, "EnumZones2") == 0) {
1409 valid_operation = true;
1410 } else if (strcasecmp(operation, "EnumDirectoryPartitions") == 0) {
1411 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1412 return WERR_DNS_ERROR_INVALID_PROPERTY;
1415 *typeid_out = DNSSRV_TYPEID_DP_LIST;
1416 rout->DirectoryPartitionList = talloc_zero(mem_ctx, struct DNS_RPC_DP_LIST);
1418 if (rin->Dword != 0) {
1419 rout->DirectoryPartitionList->dwDpCount = 0;
1420 rout->DirectoryPartitionList->DpArray = NULL;
1421 } else {
1422 struct DNS_RPC_DP_ENUM **dplist;
1423 struct dnsserver_partition *p;
1424 int pcount = 2;
1426 dplist = talloc_zero_array(mem_ctx, struct DNS_RPC_DP_ENUM *, pcount);
1427 W_ERROR_HAVE_NO_MEMORY(dplist);
1429 p = dsstate->partitions;
1430 for (i=0; i<pcount; i++) {
1431 dplist[i] = talloc_zero(dplist, struct DNS_RPC_DP_ENUM);
1433 dplist[i]->pszDpFqdn = talloc_strdup(mem_ctx, p->pszDpFqdn);
1434 dplist[i]->dwFlags = p->dwDpFlags;
1435 dplist[i]->dwZoneCount = p->zones_count;
1436 p = p->next;
1439 rout->DirectoryPartitionList->dwDpCount = pcount;
1440 rout->DirectoryPartitionList->DpArray = dplist;
1442 return WERR_OK;
1443 } else if (strcasecmp(operation, "DirectoryPartitionInfo") == 0) {
1444 struct dnsserver_partition *p;
1445 struct dnsserver_partition_info *partinfo;
1446 struct DNS_RPC_DP_INFO *dpinfo = NULL;
1448 if (typeid_in != DNSSRV_TYPEID_LPSTR) {
1449 return WERR_DNS_ERROR_INVALID_PROPERTY;
1452 *typeid_out = DNSSRV_TYPEID_DP_INFO;
1454 for (p = dsstate->partitions; p; p = p->next) {
1455 if (strcasecmp(p->pszDpFqdn, rin->String) == 0) {
1456 dpinfo = talloc_zero(mem_ctx, struct DNS_RPC_DP_INFO);
1457 W_ERROR_HAVE_NO_MEMORY(dpinfo);
1459 partinfo = dnsserver_db_partition_info(mem_ctx, dsstate->samdb, p);
1460 W_ERROR_HAVE_NO_MEMORY(partinfo);
1462 dpinfo->pszDpFqdn = talloc_strdup(dpinfo, p->pszDpFqdn);
1463 dpinfo->pszDpDn = talloc_strdup(dpinfo, ldb_dn_get_linearized(p->partition_dn));
1464 dpinfo->pszCrDn = talloc_steal(dpinfo, partinfo->pszCrDn);
1465 dpinfo->dwFlags = p->dwDpFlags;
1466 dpinfo->dwZoneCount = p->zones_count;
1467 dpinfo->dwState = partinfo->dwState;
1468 dpinfo->dwReplicaCount = partinfo->dwReplicaCount;
1469 if (partinfo->dwReplicaCount > 0) {
1470 dpinfo->ReplicaArray = talloc_steal(dpinfo,
1471 partinfo->ReplicaArray);
1472 } else {
1473 dpinfo->ReplicaArray = NULL;
1475 break;
1479 if (dpinfo == NULL) {
1480 return WERR_DNS_ERROR_DP_DOES_NOT_EXIST;
1483 rout->DirectoryPartition = dpinfo;
1484 return WERR_OK;
1485 } else if (strcasecmp(operation, "Statistics") == 0) {
1486 valid_operation = true;
1487 } else if (strcasecmp(operation, "IpValidate") == 0) {
1488 valid_operation = true;
1491 if (valid_operation) {
1492 DEBUG(0, ("dnsserver: server complex operation '%s' not implemented\n", operation));
1493 return WERR_CALL_NOT_IMPLEMENTED;
1496 DEBUG(0, ("dnsserver: invalid server complex operation '%s'\n", operation));
1497 return WERR_DNS_ERROR_INVALID_PROPERTY;
1500 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
1501 static WERROR dnsserver_operate_zone(struct dnsserver_state *dsstate,
1502 TALLOC_CTX *mem_ctx,
1503 struct dnsserver_zone *z,
1504 unsigned int request_filter,
1505 const char *operation,
1506 const unsigned int client_version,
1507 enum DNS_RPC_TYPEID typeid,
1508 union DNSSRV_RPC_UNION *r)
1510 bool valid_operation = false;
1512 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1514 if (typeid != DNSSRV_TYPEID_NAME_AND_PARAM) {
1515 return WERR_DNS_ERROR_INVALID_PROPERTY;
1518 return dnsserver_db_do_reset_dword(dsstate->samdb, z,
1519 r->NameAndParam);
1521 } else if (strcasecmp(operation, "ZoneTypeReset") == 0) {
1522 valid_operation = true;
1523 } else if (strcasecmp(operation, "PauseZone") == 0) {
1524 valid_operation = true;
1525 } else if (strcasecmp(operation, "ResumeZone") == 0) {
1526 valid_operation = true;
1527 } else if (strcasecmp(operation, "DeleteZone") == 0) {
1528 valid_operation = true;
1529 } else if (strcasecmp(operation, "ReloadZone") == 0) {
1530 valid_operation = true;
1531 } else if (strcasecmp(operation, "RefreshZone") == 0) {
1532 valid_operation = true;
1533 } else if (strcasecmp(operation, "ExpireZone") == 0) {
1534 valid_operation = true;
1535 } else if (strcasecmp(operation, "IncrementVersion") == 0) {
1536 valid_operation = true;
1537 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1538 valid_operation = true;
1539 } else if (strcasecmp(operation, "DeleteZoneFromDs") == 0) {
1540 WERROR status;
1541 if (z == NULL) {
1542 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1544 status = dnsserver_db_delete_zone(dsstate->samdb, z);
1545 if (W_ERROR_IS_OK(status)) {
1546 dnsserver_reload_zones(dsstate);
1548 return status;
1549 } else if (strcasecmp(operation, "UpdateZoneFromDs") == 0) {
1550 valid_operation = true;
1551 } else if (strcasecmp(operation, "ZoneExport") == 0) {
1552 valid_operation = true;
1553 } else if (strcasecmp(operation, "ZoneChangeDirectoryPartition") == 0) {
1554 valid_operation = true;
1555 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1556 valid_operation = true;
1557 } else if (strcasecmp(operation, "DeleteRecordSet") == 0) {
1558 valid_operation = true;
1559 } else if (strcasecmp(operation, "ForceAgingOnNode") == 0) {
1560 valid_operation = true;
1561 } else if (strcasecmp(operation, "DatabaseFile") == 0) {
1562 valid_operation = true;
1563 } else if (strcasecmp(operation, "MasterServers") == 0) {
1564 valid_operation = true;
1565 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
1566 valid_operation = true;
1567 } else if (strcasecmp(operation, "NotifyServers") == 0) {
1568 valid_operation = true;
1569 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
1570 valid_operation = true;
1571 } else if (strcasecmp(operation, "ScavengingServers") == 0) {
1572 valid_operation = true;
1573 } else if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
1574 valid_operation = true;
1575 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1576 valid_operation = true;
1577 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1578 valid_operation = true;
1581 if (valid_operation) {
1582 DEBUG(0, ("dnsserver: zone operation '%s' not implemented\n", operation));
1583 return WERR_CALL_NOT_IMPLEMENTED;
1586 DEBUG(0, ("dnsserver: invalid zone operation '%s'\n", operation));
1587 return WERR_DNS_ERROR_INVALID_PROPERTY;
1590 static WERROR dnsserver_complex_operate_zone(struct dnsserver_state *dsstate,
1591 TALLOC_CTX *mem_ctx,
1592 struct dnsserver_zone *z,
1593 const char *operation,
1594 const unsigned int client_version,
1595 enum DNS_RPC_TYPEID typeid_in,
1596 union DNSSRV_RPC_UNION *rin,
1597 enum DNS_RPC_TYPEID *typeid_out,
1598 union DNSSRV_RPC_UNION *rout)
1600 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1601 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1602 return dnsserver_query_zone(dsstate, mem_ctx, z,
1603 rin->String,
1604 client_version,
1605 typeid_out,
1606 rout);
1611 DEBUG(0,("dnsserver: Invalid zone operation %s\n", operation));
1612 return WERR_DNS_ERROR_INVALID_PROPERTY;
1615 /* dnsserver enumerate function */
1617 static WERROR dnsserver_enumerate_root_records(struct dnsserver_state *dsstate,
1618 TALLOC_CTX *mem_ctx,
1619 unsigned int client_version,
1620 const char *node_name,
1621 enum dns_record_type record_type,
1622 unsigned int select_flag,
1623 unsigned int *buffer_length,
1624 struct DNS_RPC_RECORDS_ARRAY **buffer)
1626 TALLOC_CTX *tmp_ctx;
1627 struct dnsserver_zone *z;
1628 const char * const attrs[] = { "name", "dnsRecord", NULL };
1629 struct ldb_result *res;
1630 struct DNS_RPC_RECORDS_ARRAY *recs;
1631 char **add_names;
1632 char *rname;
1633 int add_count;
1634 int i, ret, len;
1635 WERROR status;
1637 tmp_ctx = talloc_new(mem_ctx);
1638 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1640 z = dnsserver_find_zone(dsstate->zones, ".");
1641 if (z == NULL) {
1642 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1645 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1646 LDB_SCOPE_ONELEVEL, attrs,
1647 "(&(objectClass=dnsNode)(name=@)(!(dNSTombstoned=TRUE)))");
1648 if (ret != LDB_SUCCESS) {
1649 talloc_free(tmp_ctx);
1650 return WERR_INTERNAL_DB_ERROR;
1652 if (res->count == 0) {
1653 talloc_free(tmp_ctx);
1654 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1657 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1658 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1660 add_names = NULL;
1661 add_count = 0;
1663 for (i=0; i<res->count; i++) {
1664 status = dns_fill_records_array(tmp_ctx, NULL, record_type,
1665 select_flag, NULL,
1666 res->msgs[i], 0, recs,
1667 &add_names, &add_count);
1668 if (!W_ERROR_IS_OK(status)) {
1669 talloc_free(tmp_ctx);
1670 return status;
1673 talloc_free(res);
1675 /* Add any additional records */
1676 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1677 for (i=0; i<add_count; i++) {
1678 char *encoded_name
1679 = ldb_binary_encode_string(tmp_ctx,
1680 add_names[i]);
1681 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1682 LDB_SCOPE_ONELEVEL, attrs,
1683 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1684 encoded_name);
1685 if (ret != LDB_SUCCESS || res->count == 0) {
1686 talloc_free(res);
1687 continue;
1690 len = strlen(add_names[i]);
1691 if (add_names[i][len-1] == '.') {
1692 rname = talloc_strdup(tmp_ctx, add_names[i]);
1693 } else {
1694 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1696 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1697 select_flag, rname,
1698 res->msgs[0], 0, recs,
1699 NULL, NULL);
1700 talloc_free(rname);
1701 talloc_free(res);
1702 if (!W_ERROR_IS_OK(status)) {
1703 talloc_free(tmp_ctx);
1704 return status;
1709 talloc_free(tmp_ctx);
1711 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1712 *buffer = recs;
1714 return WERR_OK;
1718 static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
1719 TALLOC_CTX *mem_ctx,
1720 struct dnsserver_zone *z,
1721 unsigned int client_version,
1722 const char *node_name,
1723 const char *start_child,
1724 enum dns_record_type record_type,
1725 unsigned int select_flag,
1726 const char *filter_start,
1727 const char *filter_stop,
1728 unsigned int *buffer_length,
1729 struct DNS_RPC_RECORDS_ARRAY **buffer)
1731 TALLOC_CTX *tmp_ctx;
1732 char *name;
1733 const char * const attrs[] = { "name", "dnsRecord", NULL };
1734 struct ldb_result *res = NULL;
1735 struct DNS_RPC_RECORDS_ARRAY *recs = NULL;
1736 char **add_names = NULL;
1737 char *rname = NULL;
1738 const char *preference_name = NULL;
1739 int add_count = 0;
1740 int i, ret, len;
1741 WERROR status;
1742 struct dns_tree *tree = NULL;
1743 struct dns_tree *base = NULL;
1744 struct dns_tree *node = NULL;
1746 tmp_ctx = talloc_new(mem_ctx);
1747 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1749 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1750 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1752 /* search all records under parent tree */
1753 if (strcasecmp(name, z->name) == 0) {
1754 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1755 LDB_SCOPE_ONELEVEL, attrs,
1756 "(&(objectClass=dnsNode)(!(dNSTombstoned=TRUE)))");
1757 preference_name = "@";
1758 } else {
1759 char *encoded_name
1760 = ldb_binary_encode_string(tmp_ctx, name);
1761 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1762 LDB_SCOPE_ONELEVEL, attrs,
1763 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s))(!(dNSTombstoned=TRUE)))",
1764 encoded_name, encoded_name);
1765 preference_name = name;
1767 if (ret != LDB_SUCCESS) {
1768 talloc_free(tmp_ctx);
1769 return WERR_INTERNAL_DB_ERROR;
1771 if (res->count == 0) {
1772 talloc_free(tmp_ctx);
1773 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1776 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1777 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1780 * Sort the names, so that the records are in order by the child
1781 * component below "name".
1783 * A full tree sort is not required, so we pass in "name" so
1784 * we know which level to sort, as only direct children are
1785 * eventually returned
1787 LDB_TYPESAFE_QSORT(res->msgs, res->count, name, dns_name_compare);
1789 /* Build a tree of name components from dns name */
1790 tree = dns_build_tree(tmp_ctx, preference_name, res);
1791 W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree, tmp_ctx);
1793 /* Find the parent record in the tree */
1794 base = tree;
1795 while (base->level != -1) {
1796 base = base->children[0];
1799 /* Add the parent record with blank name */
1800 if (!(select_flag & DNS_RPC_VIEW_ONLY_CHILDREN)) {
1801 status = dns_fill_records_array(tmp_ctx, z, record_type,
1802 select_flag, NULL,
1803 base->data, 0,
1804 recs, &add_names, &add_count);
1805 if (!W_ERROR_IS_OK(status)) {
1806 talloc_free(tmp_ctx);
1807 return status;
1811 /* Add all the children records */
1812 if (!(select_flag & DNS_RPC_VIEW_NO_CHILDREN)) {
1813 for (i=0; i<base->num_children; i++) {
1814 node = base->children[i];
1816 status = dns_fill_records_array(tmp_ctx, z, record_type,
1817 select_flag, node->name,
1818 node->data, node->num_children,
1819 recs, &add_names, &add_count);
1820 if (!W_ERROR_IS_OK(status)) {
1821 talloc_free(tmp_ctx);
1822 return status;
1827 TALLOC_FREE(res);
1828 TALLOC_FREE(tree);
1829 TALLOC_FREE(name);
1831 /* Add any additional records */
1832 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1833 for (i=0; i<add_count; i++) {
1834 struct dnsserver_zone *z2 = NULL;
1835 struct ldb_message *msg = NULL;
1836 /* Search all the available zones for additional name */
1837 for (z2 = dsstate->zones; z2; z2 = z2->next) {
1838 char *encoded_name;
1839 name = dns_split_node_name(tmp_ctx, add_names[i], z2->name);
1840 encoded_name
1841 = ldb_binary_encode_string(tmp_ctx,
1842 name);
1843 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z2->zone_dn,
1844 LDB_SCOPE_ONELEVEL, attrs,
1845 "(&(objectClass=dnsNode)(name=%s)(!(dNSTombstoned=TRUE)))",
1846 encoded_name);
1847 TALLOC_FREE(name);
1848 if (ret != LDB_SUCCESS) {
1849 continue;
1851 if (res->count == 1) {
1852 msg = res->msgs[0];
1853 break;
1854 } else {
1855 TALLOC_FREE(res);
1856 continue;
1860 len = strlen(add_names[i]);
1861 if (add_names[i][len-1] == '.') {
1862 rname = talloc_strdup(tmp_ctx, add_names[i]);
1863 } else {
1864 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1866 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1867 select_flag, rname,
1868 msg, 0, recs,
1869 NULL, NULL);
1870 TALLOC_FREE(rname);
1871 TALLOC_FREE(res);
1872 if (!W_ERROR_IS_OK(status)) {
1873 talloc_free(tmp_ctx);
1874 return status;
1879 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1880 *buffer = recs;
1882 return WERR_OK;
1886 * Check str1 + '.' + str2 = name, for example:
1887 * ("dc0", "example.com", "dc0.example.com") = true
1889 static bool cname_self_reference(const char* node_name,
1890 const char* zone_name,
1891 struct DNS_RPC_NAME name) {
1892 size_t node_len, zone_len;
1894 if (node_name == NULL || zone_name == NULL) {
1895 return false;
1898 node_len = strlen(node_name);
1899 zone_len = strlen(zone_name);
1901 if (node_len == 0 ||
1902 zone_len == 0 ||
1903 (name.len != node_len + zone_len + 1)) {
1904 return false;
1907 if (strncmp(node_name, name.str, node_len) == 0 &&
1908 name.str[node_len] == '.' &&
1909 strncmp(zone_name, name.str + node_len + 1, zone_len) == 0) {
1910 return true;
1913 return false;
1916 /* dnsserver update function */
1918 static WERROR dnsserver_update_record(struct dnsserver_state *dsstate,
1919 TALLOC_CTX *mem_ctx,
1920 struct dnsserver_zone *z,
1921 unsigned int client_version,
1922 const char *node_name,
1923 struct DNS_RPC_RECORD_BUF *add_buf,
1924 struct DNS_RPC_RECORD_BUF *del_buf)
1926 TALLOC_CTX *tmp_ctx;
1927 char *name;
1928 WERROR status;
1930 tmp_ctx = talloc_new(mem_ctx);
1931 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1933 /* If node_name is @ or zone name, dns record is @ */
1934 if (strcmp(node_name, "@") == 0 ||
1935 strcmp(node_name, ".") == 0 ||
1936 strcasecmp(node_name, z->name) == 0) {
1937 name = talloc_strdup(tmp_ctx, "@");
1938 } else {
1939 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1941 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1943 /* CNAMEs can't point to themselves */
1944 if (add_buf != NULL && add_buf->rec.wType == DNS_TYPE_CNAME) {
1945 if (cname_self_reference(node_name, z->name, add_buf->rec.data.name)) {
1946 return WERR_DNS_ERROR_CNAME_LOOP;
1950 if (add_buf != NULL) {
1951 if (del_buf == NULL) {
1952 /* Add record */
1953 status = dnsserver_db_add_record(tmp_ctx, dsstate->samdb,
1954 z, name,
1955 &add_buf->rec);
1956 } else {
1957 /* Update record */
1958 status = dnsserver_db_update_record(tmp_ctx, dsstate->samdb,
1959 z, name,
1960 &add_buf->rec,
1961 &del_buf->rec);
1963 } else {
1964 if (del_buf == NULL) {
1965 /* Add empty node */
1966 status = dnsserver_db_add_empty_node(tmp_ctx, dsstate->samdb,
1967 z, name);
1968 } else {
1969 /* Delete record */
1970 status = dnsserver_db_delete_record(tmp_ctx, dsstate->samdb,
1971 z, name,
1972 &del_buf->rec);
1976 talloc_free(tmp_ctx);
1977 return status;
1981 /* dnsserver interface functions */
1983 static WERROR dcesrv_DnssrvOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation *r)
1985 struct dnsserver_state *dsstate;
1986 struct dnsserver_zone *z = NULL;
1987 uint32_t request_filter = 0;
1988 WERROR ret;
1990 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1991 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1994 if (r->in.dwContext == 0) {
1995 if (r->in.pszZone != NULL) {
1996 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
1998 } else {
1999 request_filter = r->in.dwContext;
2002 if (r->in.pszZone == NULL) {
2003 ret = dnsserver_operate_server(dsstate, mem_ctx,
2004 r->in.pszOperation,
2005 DNS_CLIENT_VERSION_W2K,
2006 r->in.dwTypeId,
2007 &r->in.pData);
2008 } else {
2009 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2011 * In the case that request_filter is not 0 and z is NULL,
2012 * the request is for a multizone operation, which we do not
2013 * yet support, so just error on NULL zone name.
2015 if (z == NULL) {
2016 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2019 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
2020 request_filter,
2021 r->in.pszOperation,
2022 DNS_CLIENT_VERSION_W2K,
2023 r->in.dwTypeId,
2024 &r->in.pData);
2027 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2028 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation, NDR_IN, r);
2030 return ret;
2033 static WERROR dcesrv_DnssrvQuery(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery *r)
2035 struct dnsserver_state *dsstate;
2036 struct dnsserver_zone *z;
2037 WERROR ret;
2039 ZERO_STRUCTP(r->out.pdwTypeId);
2040 ZERO_STRUCTP(r->out.ppData);
2042 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2043 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2046 if (r->in.pszZone == NULL) {
2047 /* FIXME: DNS Server Configuration Access Control List */
2048 ret = dnsserver_query_server(dsstate, mem_ctx,
2049 r->in.pszOperation,
2050 DNS_CLIENT_VERSION_W2K,
2051 r->out.pdwTypeId,
2052 r->out.ppData);
2053 } else {
2054 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2055 if (z == NULL) {
2056 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2059 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
2060 r->in.pszOperation,
2061 DNS_CLIENT_VERSION_W2K,
2062 r->out.pdwTypeId,
2063 r->out.ppData);
2066 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2067 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery, NDR_IN, r);
2069 return ret;
2072 static WERROR dcesrv_DnssrvComplexOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation *r)
2074 struct dnsserver_state *dsstate;
2075 struct dnsserver_zone *z;
2076 WERROR ret;
2078 ZERO_STRUCTP(r->out.pdwTypeOut);
2079 ZERO_STRUCTP(r->out.ppDataOut);
2081 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2082 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2085 if (r->in.pszZone == NULL) {
2086 /* Server operation */
2087 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
2088 r->in.pszOperation,
2089 DNS_CLIENT_VERSION_W2K,
2090 r->in.dwTypeIn,
2091 &r->in.pDataIn,
2092 r->out.pdwTypeOut,
2093 r->out.ppDataOut);
2094 } else {
2095 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2096 if (z == NULL) {
2097 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2100 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2101 r->in.pszOperation,
2102 DNS_CLIENT_VERSION_W2K,
2103 r->in.dwTypeIn,
2104 &r->in.pDataIn,
2105 r->out.pdwTypeOut,
2106 r->out.ppDataOut);
2109 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2110 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation, NDR_IN, r);
2112 return ret;
2115 static WERROR dcesrv_DnssrvEnumRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords *r)
2117 struct dnsserver_state *dsstate;
2118 struct dnsserver_zone *z;
2119 WERROR ret;
2121 ZERO_STRUCTP(r->out.pdwBufferLength);
2122 ZERO_STRUCTP(r->out.pBuffer);
2124 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2125 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2128 if (r->in.pszZone == NULL) {
2129 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2132 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
2133 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
2134 DNS_CLIENT_VERSION_W2K,
2135 r->in.pszNodeName,
2136 r->in.wRecordType,
2137 r->in.fSelectFlag,
2138 r->out.pdwBufferLength,
2139 r->out.pBuffer);
2140 } else {
2141 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2142 if (z == NULL) {
2143 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2146 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2147 DNS_CLIENT_VERSION_W2K,
2148 r->in.pszNodeName,
2149 r->in.pszStartChild,
2150 r->in.wRecordType,
2151 r->in.fSelectFlag,
2152 r->in.pszFilterStart,
2153 r->in.pszFilterStop,
2154 r->out.pdwBufferLength,
2155 r->out.pBuffer);
2158 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2159 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords, NDR_IN, r);
2161 return ret;
2164 static WERROR dcesrv_DnssrvUpdateRecord(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord *r)
2166 struct dnsserver_state *dsstate;
2167 struct dnsserver_zone *z;
2168 WERROR ret;
2170 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2171 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2174 if (r->in.pszZone == NULL) {
2175 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2178 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2179 if (z == NULL) {
2180 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2183 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2184 DNS_CLIENT_VERSION_W2K,
2185 r->in.pszNodeName,
2186 r->in.pAddRecord,
2187 r->in.pDeleteRecord);
2189 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2190 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord, NDR_IN, r);
2192 return ret;
2195 static WERROR dcesrv_DnssrvOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation2 *r)
2197 struct dnsserver_state *dsstate;
2198 struct dnsserver_zone *z = NULL;
2199 uint32_t request_filter = 0;
2200 WERROR ret;
2202 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2203 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2206 if (r->in.dwContext == 0) {
2207 if (r->in.pszZone != NULL) {
2208 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
2210 } else {
2211 request_filter = r->in.dwContext;
2214 if (r->in.pszZone == NULL) {
2215 ret = dnsserver_operate_server(dsstate, mem_ctx,
2216 r->in.pszOperation,
2217 r->in.dwClientVersion,
2218 r->in.dwTypeId,
2219 &r->in.pData);
2220 } else {
2221 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2223 * In the case that request_filter is not 0 and z is NULL,
2224 * the request is for a multizone operation, which we do not
2225 * yet support, so just error on NULL zone name.
2227 if (z == NULL) {
2228 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2231 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
2232 request_filter,
2233 r->in.pszOperation,
2234 r->in.dwClientVersion,
2235 r->in.dwTypeId,
2236 &r->in.pData);
2239 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2240 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation2, NDR_IN, r);
2242 return ret;
2245 static WERROR dcesrv_DnssrvQuery2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery2 *r)
2247 struct dnsserver_state *dsstate;
2248 struct dnsserver_zone *z;
2249 WERROR ret;
2251 ZERO_STRUCTP(r->out.pdwTypeId);
2252 ZERO_STRUCTP(r->out.ppData);
2254 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2255 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2258 if (r->in.pszZone == NULL) {
2259 /* FIXME: DNS Server Configuration Access Control List */
2260 ret = dnsserver_query_server(dsstate, mem_ctx,
2261 r->in.pszOperation,
2262 r->in.dwClientVersion,
2263 r->out.pdwTypeId,
2264 r->out.ppData);
2265 } else {
2266 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2267 if (z == NULL) {
2268 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2271 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
2272 r->in.pszOperation,
2273 r->in.dwClientVersion,
2274 r->out.pdwTypeId,
2275 r->out.ppData);
2278 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2279 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery2, NDR_IN, r);
2281 return ret;
2284 static WERROR dcesrv_DnssrvComplexOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation2 *r)
2286 struct dnsserver_state *dsstate;
2287 struct dnsserver_zone *z;
2288 WERROR ret;
2290 ZERO_STRUCTP(r->out.pdwTypeOut);
2291 ZERO_STRUCTP(r->out.ppDataOut);
2293 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2294 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2297 if (r->in.pszZone == NULL) {
2298 /* Server operation */
2299 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
2300 r->in.pszOperation,
2301 r->in.dwClientVersion,
2302 r->in.dwTypeIn,
2303 &r->in.pDataIn,
2304 r->out.pdwTypeOut,
2305 r->out.ppDataOut);
2306 } else {
2308 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2309 if (z == NULL) {
2310 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2313 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2314 r->in.pszOperation,
2315 r->in.dwClientVersion,
2316 r->in.dwTypeIn,
2317 &r->in.pDataIn,
2318 r->out.pdwTypeOut,
2319 r->out.ppDataOut);
2322 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2323 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation2, NDR_IN, r);
2325 return ret;
2328 static WERROR dcesrv_DnssrvEnumRecords2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords2 *r)
2330 struct dnsserver_state *dsstate;
2331 struct dnsserver_zone *z;
2332 WERROR ret;
2334 ZERO_STRUCTP(r->out.pdwBufferLength);
2335 ZERO_STRUCTP(r->out.pBuffer);
2337 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2338 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2341 if (r->in.pszZone == NULL) {
2342 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2345 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
2346 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
2347 r->in.dwClientVersion,
2348 r->in.pszNodeName,
2349 r->in.wRecordType,
2350 r->in.fSelectFlag,
2351 r->out.pdwBufferLength,
2352 r->out.pBuffer);
2353 } else {
2354 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2355 if (z == NULL) {
2356 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2359 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2360 r->in.dwClientVersion,
2361 r->in.pszNodeName,
2362 r->in.pszStartChild,
2363 r->in.wRecordType,
2364 r->in.fSelectFlag,
2365 r->in.pszFilterStart,
2366 r->in.pszFilterStop,
2367 r->out.pdwBufferLength,
2368 r->out.pBuffer);
2372 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2373 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords2, NDR_IN, r);
2375 return ret;
2378 static WERROR dcesrv_DnssrvUpdateRecord2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord2 *r)
2380 struct dnsserver_state *dsstate;
2381 struct dnsserver_zone *z;
2382 WERROR ret;
2384 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2385 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2388 if (r->in.pszZone == NULL) {
2389 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2392 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2393 if (z == NULL) {
2394 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2397 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2398 r->in.dwClientVersion,
2399 r->in.pszNodeName,
2400 r->in.pAddRecord,
2401 r->in.pDeleteRecord);
2403 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2404 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord2, NDR_IN, r);
2406 return ret;
2409 /* include the generated boilerplate */
2410 #include "librpc/gen_ndr/ndr_dnsserver_s.c"