s4:rpc-dnsserver: Implement EnumDirectoryPartition operation
[Samba.git] / source4 / rpc_server / dnsserver / dcerpc_dnsserver.c
blob2d9fadd91e868ccd1f1003e8ade4bb3da1d77c45
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 struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_call)
45 struct dnsserver_state *dsstate;
46 struct dnsserver_zone *zones, *z, *znext;
47 struct dnsserver_partition *partitions, *p;
49 dsstate = talloc_get_type(dce_call->context->private_data, struct dnsserver_state);
50 if (dsstate != NULL) {
51 return dsstate;
54 dsstate = talloc_zero(dce_call->context, struct dnsserver_state);
55 if (dsstate == NULL) {
56 return NULL;
59 dsstate->lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
61 /* FIXME: create correct auth_session_info for connecting user */
62 dsstate->samdb = samdb_connect(dsstate, dce_call->event_ctx, dsstate->lp_ctx,
63 dce_call->conn->auth_state.session_info, 0);
64 if (dsstate->samdb == NULL) {
65 DEBUG(0,("dnsserver: Failed to open samdb"));
66 goto failed;
69 /* Initialize server info */
70 dsstate->serverinfo = dnsserver_init_serverinfo(dsstate,
71 dsstate->lp_ctx,
72 dsstate->samdb);
73 if (dsstate->serverinfo == NULL) {
74 goto failed;
77 /* Search for DNS partitions */
78 partitions = dnsserver_db_enumerate_partitions(dsstate, dsstate->serverinfo, dsstate->samdb);
79 if (partitions == NULL) {
80 goto failed;
82 dsstate->partitions = partitions;
84 /* Search for DNS zones */
85 for (p = partitions; p; p = p->next) {
86 zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, p);
87 if (zones == NULL) {
88 goto failed;
90 for (z = zones; z; ) {
91 znext = z->next;
92 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
93 if (z->zoneinfo == NULL) {
94 goto failed;
96 DLIST_ADD_END(dsstate->zones, z, NULL);
97 p->zones_count++;
98 dsstate->zones_count++;
99 z = znext;
103 dce_call->context->private_data = dsstate;
105 return dsstate;
107 failed:
108 talloc_free(dsstate);
109 dsstate = NULL;
110 return NULL;
114 /* dnsserver query functions */
116 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
117 static WERROR dnsserver_query_server(struct dnsserver_state *dsstate,
118 TALLOC_CTX *mem_ctx,
119 const char *operation,
120 const unsigned int client_version,
121 enum DNS_RPC_TYPEID *typeid,
122 union DNSSRV_RPC_UNION *r)
124 uint8_t is_integer, is_addresses, is_string, is_wstring, is_stringlist;
125 uint32_t answer_integer;
126 struct IP4_ARRAY *answer_iparray;
127 struct DNS_ADDR_ARRAY *answer_addrarray;
128 char *answer_string;
129 struct DNS_RPC_UTF8_STRING_LIST *answer_stringlist;
130 struct dnsserver_serverinfo *serverinfo;
132 serverinfo = dsstate->serverinfo;
134 if (strcasecmp(operation, "ServerInfo") == 0) {
135 if (client_version == DNS_CLIENT_VERSION_W2K) {
136 *typeid = DNSSRV_TYPEID_SERVER_INFO_W2K;
137 r->ServerInfoW2K = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_W2K);
139 r->ServerInfoW2K->dwVersion = serverinfo->dwVersion;
140 r->ServerInfoW2K->fBootMethod = serverinfo->fBootMethod;
141 r->ServerInfoW2K->fAdminConfigured = serverinfo->fAdminConfigured;
142 r->ServerInfoW2K->fAllowUpdate = serverinfo->fAllowUpdate;
143 r->ServerInfoW2K->fDsAvailable = serverinfo->fDsAvailable;
144 r->ServerInfoW2K->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
145 r->ServerInfoW2K->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
146 r->ServerInfoW2K->aipServerAddrs = ip4_array_copy(mem_ctx, serverinfo->aipServerAddrs);
147 r->ServerInfoW2K->aipListenAddrs = ip4_array_copy(mem_ctx, serverinfo->aipListenAddrs);
148 r->ServerInfoW2K->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
149 r->ServerInfoW2K->dwLogLevel = serverinfo->dwLogLevel;
150 r->ServerInfoW2K->dwDebugLevel = serverinfo->dwDebugLevel;
151 r->ServerInfoW2K->dwForwardTimeout = serverinfo->dwForwardTimeout;
152 r->ServerInfoW2K->dwRpcProtocol = serverinfo->dwRpcProtocol;
153 r->ServerInfoW2K->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
154 r->ServerInfoW2K->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
155 r->ServerInfoW2K->dwRecursionRetry = serverinfo->dwRecursionRetry;
156 r->ServerInfoW2K->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
157 r->ServerInfoW2K->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
158 r->ServerInfoW2K->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
159 r->ServerInfoW2K->dwScavengingInterval = serverinfo->dwScavengingInterval;
160 r->ServerInfoW2K->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
161 r->ServerInfoW2K->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
162 r->ServerInfoW2K->fAutoReverseZones = serverinfo->fAutoReverseZones;
163 r->ServerInfoW2K->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
164 r->ServerInfoW2K->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
165 r->ServerInfoW2K->fForwardDelegations = serverinfo->fForwardDelegations;
166 r->ServerInfoW2K->fNoRecursion = serverinfo->fNoRecursion;
167 r->ServerInfoW2K->fSecureResponses = serverinfo->fSecureResponses;
168 r->ServerInfoW2K->fRoundRobin = serverinfo->fRoundRobin;
169 r->ServerInfoW2K->fLocalNetPriority = serverinfo->fLocalNetPriority;
170 r->ServerInfoW2K->fBindSecondaries = serverinfo->fBindSecondaries;
171 r->ServerInfoW2K->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
172 r->ServerInfoW2K->fStrictFileParsing = serverinfo->fStrictFileParsing;
173 r->ServerInfoW2K->fLooseWildcarding = serverinfo->fLooseWildcarding;
174 r->ServerInfoW2K->fDefaultAgingState = serverinfo->fDefaultAgingState;
176 } else if (client_version == DNS_CLIENT_VERSION_DOTNET) {
177 *typeid = DNSSRV_TYPEID_SERVER_INFO_DOTNET;
178 r->ServerInfoDotNet = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_DOTNET);
180 r->ServerInfoDotNet->dwRpcStructureVersion = 0x01;
181 r->ServerInfoDotNet->dwVersion = serverinfo->dwVersion;
182 r->ServerInfoDotNet->fBootMethod = serverinfo->fBootMethod;
183 r->ServerInfoDotNet->fAdminConfigured = serverinfo->fAdminConfigured;
184 r->ServerInfoDotNet->fAllowUpdate = serverinfo->fAllowUpdate;
185 r->ServerInfoDotNet->fDsAvailable = serverinfo->fDsAvailable;
186 r->ServerInfoDotNet->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
187 r->ServerInfoDotNet->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
188 r->ServerInfoDotNet->aipServerAddrs = ip4_array_copy(mem_ctx, serverinfo->aipServerAddrs);
189 r->ServerInfoDotNet->aipListenAddrs = ip4_array_copy(mem_ctx, serverinfo->aipListenAddrs);
190 r->ServerInfoDotNet->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
191 r->ServerInfoDotNet->aipLogFilter = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
192 r->ServerInfoDotNet->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
193 r->ServerInfoDotNet->pszDomainName = talloc_strdup(mem_ctx, serverinfo->pszDomainName);
194 r->ServerInfoDotNet->pszForestName = talloc_strdup(mem_ctx, serverinfo->pszForestName);
195 r->ServerInfoDotNet->pszDomainDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszDomainDirectoryPartition);
196 r->ServerInfoDotNet->pszForestDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszForestDirectoryPartition);
197 r->ServerInfoDotNet->dwLogLevel = serverinfo->dwLogLevel;
198 r->ServerInfoDotNet->dwDebugLevel = serverinfo->dwDebugLevel;
199 r->ServerInfoDotNet->dwForwardTimeout = serverinfo->dwForwardTimeout;
200 r->ServerInfoDotNet->dwRpcProtocol = serverinfo->dwRpcProtocol;
201 r->ServerInfoDotNet->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
202 r->ServerInfoDotNet->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
203 r->ServerInfoDotNet->dwRecursionRetry = serverinfo->dwRecursionRetry;
204 r->ServerInfoDotNet->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
205 r->ServerInfoDotNet->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
206 r->ServerInfoDotNet->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
207 r->ServerInfoDotNet->dwLocalNetPriorityNetMask = serverinfo->dwLocalNetPriorityNetMask;
208 r->ServerInfoDotNet->dwScavengingInterval = serverinfo->dwScavengingInterval;
209 r->ServerInfoDotNet->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
210 r->ServerInfoDotNet->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
211 r->ServerInfoDotNet->dwLastScavengeTime = serverinfo->dwLastScavengeTime;
212 r->ServerInfoDotNet->dwEventLogLevel = serverinfo->dwEventLogLevel;
213 r->ServerInfoDotNet->dwLogFileMaxSize = serverinfo->dwLogFileMaxSize;
214 r->ServerInfoDotNet->dwDsForestVersion = serverinfo->dwDsForestVersion;
215 r->ServerInfoDotNet->dwDsDomainVersion = serverinfo->dwDsDomainVersion;
216 r->ServerInfoDotNet->dwDsDsaVersion = serverinfo->dwDsDsaVersion;
217 r->ServerInfoDotNet->fAutoReverseZones = serverinfo->fAutoReverseZones;
218 r->ServerInfoDotNet->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
219 r->ServerInfoDotNet->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
220 r->ServerInfoDotNet->fForwardDelegations = serverinfo->fForwardDelegations;
221 r->ServerInfoDotNet->fNoRecursion = serverinfo->fNoRecursion;
222 r->ServerInfoDotNet->fSecureResponses = serverinfo->fSecureResponses;
223 r->ServerInfoDotNet->fRoundRobin = serverinfo->fRoundRobin;
224 r->ServerInfoDotNet->fLocalNetPriority = serverinfo->fLocalNetPriority;
225 r->ServerInfoDotNet->fBindSecondaries = serverinfo->fBindSecondaries;
226 r->ServerInfoDotNet->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
227 r->ServerInfoDotNet->fStrictFileParsing = serverinfo->fStrictFileParsing;
228 r->ServerInfoDotNet->fLooseWildcarding = serverinfo->fLooseWildcarding;
229 r->ServerInfoDotNet->fDefaultAgingState = serverinfo->fDefaultAgingState;
231 } else if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
232 *typeid = DNSSRV_TYPEID_SERVER_INFO;
233 r->ServerInfo = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_LONGHORN);
235 r->ServerInfo->dwRpcStructureVersion = 0x02;
236 r->ServerInfo->dwVersion = serverinfo->dwVersion;
237 r->ServerInfo->fBootMethod = serverinfo->fBootMethod;
238 r->ServerInfo->fAdminConfigured = serverinfo->fAdminConfigured;
239 r->ServerInfo->fAllowUpdate = serverinfo->fAllowUpdate;
240 r->ServerInfo->fDsAvailable = serverinfo->fDsAvailable;
241 r->ServerInfo->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
242 r->ServerInfo->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
243 r->ServerInfo->aipServerAddrs = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipServerAddrs);
244 r->ServerInfo->aipListenAddrs = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipListenAddrs);
245 r->ServerInfo->aipForwarders = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders);
246 r->ServerInfo->aipLogFilter = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter);
247 r->ServerInfo->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
248 r->ServerInfo->pszDomainName = talloc_strdup(mem_ctx, serverinfo->pszDomainName);
249 r->ServerInfo->pszForestName = talloc_strdup(mem_ctx, serverinfo->pszForestName);
250 r->ServerInfo->pszDomainDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszDomainDirectoryPartition);
251 r->ServerInfo->pszForestDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszForestDirectoryPartition);
252 r->ServerInfo->dwLogLevel = serverinfo->dwLogLevel;
253 r->ServerInfo->dwDebugLevel = serverinfo->dwDebugLevel;
254 r->ServerInfo->dwForwardTimeout = serverinfo->dwForwardTimeout;
255 r->ServerInfo->dwRpcProtocol = serverinfo->dwRpcProtocol;
256 r->ServerInfo->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
257 r->ServerInfo->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
258 r->ServerInfo->dwRecursionRetry = serverinfo->dwRecursionRetry;
259 r->ServerInfo->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
260 r->ServerInfo->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
261 r->ServerInfo->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
262 r->ServerInfo->dwLocalNetPriorityNetMask = serverinfo->dwLocalNetPriorityNetMask;
263 r->ServerInfo->dwScavengingInterval = serverinfo->dwScavengingInterval;
264 r->ServerInfo->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
265 r->ServerInfo->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
266 r->ServerInfo->dwLastScavengeTime = serverinfo->dwLastScavengeTime;
267 r->ServerInfo->dwEventLogLevel = serverinfo->dwEventLogLevel;
268 r->ServerInfo->dwLogFileMaxSize = serverinfo->dwLogFileMaxSize;
269 r->ServerInfo->dwDsForestVersion = serverinfo->dwDsForestVersion;
270 r->ServerInfo->dwDsDomainVersion = serverinfo->dwDsDomainVersion;
271 r->ServerInfo->dwDsDsaVersion = serverinfo->dwDsDsaVersion;
272 r->ServerInfo->fReadOnlyDC = serverinfo->fReadOnlyDC;
273 r->ServerInfo->fAutoReverseZones = serverinfo->fAutoReverseZones;
274 r->ServerInfo->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
275 r->ServerInfo->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
276 r->ServerInfo->fForwardDelegations = serverinfo->fForwardDelegations;
277 r->ServerInfo->fNoRecursion = serverinfo->fNoRecursion;
278 r->ServerInfo->fSecureResponses = serverinfo->fSecureResponses;
279 r->ServerInfo->fRoundRobin = serverinfo->fRoundRobin;
280 r->ServerInfo->fLocalNetPriority = serverinfo->fLocalNetPriority;
281 r->ServerInfo->fBindSecondaries = serverinfo->fBindSecondaries;
282 r->ServerInfo->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
283 r->ServerInfo->fStrictFileParsing = serverinfo->fStrictFileParsing;
284 r->ServerInfo->fLooseWildcarding = serverinfo->fLooseWildcarding;
285 r->ServerInfo->fDefaultAgingState = serverinfo->fDefaultAgingState;
287 return WERR_OK;
290 is_integer = 0;
292 if (strcasecmp(operation, "AddressAnswerLimit") == 0) {
293 answer_integer = serverinfo->cAddressAnswerLimit;
294 is_integer = 1;
295 } else if (strcasecmp(operation, "AdminConfigured") == 0) {
296 answer_integer = serverinfo->fAdminConfigured;
297 is_integer = 1;
298 } else if (strcasecmp(operation, "AllowCNAMEAtNS") == 0) {
299 answer_integer = 0;
300 is_integer = 1;
301 } else if (strcasecmp(operation, "AllowUpdate") == 0) {
302 answer_integer = serverinfo->fAllowUpdate;
303 is_integer = 1;
304 } else if (strcasecmp(operation, "AutoCacheUpdate") == 0) {
305 answer_integer = serverinfo->fAutoCacheUpdate;
306 is_integer = 1;
307 } else if (strcasecmp(operation, "AutoConfigFileZones") == 0) {
308 answer_integer = 1;
309 is_integer = 1;
310 } else if (strcasecmp(operation, "BindSecondaries") == 0) {
311 answer_integer = serverinfo->fBindSecondaries;
312 is_integer = 1;
313 } else if (strcasecmp(operation, "BootMethod") == 0) {
314 answer_integer = serverinfo->fBootMethod;
315 is_integer = 1;
316 } else if (strcasecmp(operation, "DebugLevel") == 0) {
317 answer_integer = serverinfo->dwDebugLevel;
318 is_integer = 1;
319 } else if (strcasecmp(operation, "DefaultAgingState") == 0) {
320 answer_integer = serverinfo->fDefaultAgingState;
321 is_integer = 1;
322 } else if (strcasecmp(operation, "DefaultNoRefreshInterval") == 0) {
323 answer_integer = serverinfo->dwDefaultNoRefreshInterval;
324 is_integer = 1;
325 } else if (strcasecmp(operation, "DefaultRefreshInterval") == 0) {
326 answer_integer = serverinfo->dwDefaultRefreshInterval;
327 is_integer = 1;
328 } else if (strcasecmp(operation, "DeleteOutsideGlue") == 0) {
329 answer_integer = 0;
330 is_integer = 1;
331 } else if (strcasecmp(operation, "DisjointNets") == 0) {
332 answer_integer = 0;
333 is_integer = 1;
334 } else if (strcasecmp(operation, "DsLazyUpdateInterval") == 0) {
335 answer_integer = 3; /* seconds */
336 is_integer = 1;
337 } else if (strcasecmp(operation, "DsPollingInterval") == 0) {
338 answer_integer = serverinfo->dwDsPollingInterval;
339 is_integer = 1;
340 } else if (strcasecmp(operation, "DsTombstoneInterval") == 0) {
341 answer_integer = 0x00127500; /* 14 days */
342 is_integer = 1;
343 } else if (strcasecmp(operation, "EnableRegistryBoot") == 0) {
344 answer_integer = 0;
345 is_integer = 1;
346 } else if (strcasecmp(operation, "EventLogLevel") == 0) {
347 answer_integer = serverinfo->dwEventLogLevel;
348 is_integer = 1;
349 } else if (strcasecmp(operation, "ForceSoaSerial") == 0) {
350 answer_integer = 0;
351 is_integer = 1;
352 } else if (strcasecmp(operation, "ForceSaoRetry") == 0) {
353 answer_integer = 0;
354 is_integer = 1;
355 } else if (strcasecmp(operation, "ForceSoaRefresh") == 0) {
356 answer_integer = 0;
357 is_integer = 1;
358 } else if (strcasecmp(operation, "ForceSoaMinimumTtl") == 0) {
359 answer_integer = 0;
360 is_integer = 1;
361 } else if (strcasecmp(operation, "ForwardDelegations") == 0) {
362 answer_integer = 1;
363 is_integer = 1;
364 } else if (strcasecmp(operation, "ForwardingTimeout") == 0) {
365 answer_integer = serverinfo->dwForwardTimeout;
366 is_integer = 1;
367 } else if (strcasecmp(operation, "IsSlave") == 0) {
368 answer_integer = 0;
369 is_integer = 1;
370 } else if (strcasecmp(operation, "LocalNetPriority") == 0) {
371 answer_integer = serverinfo->fLocalNetPriority;
372 is_integer = 1;
373 } else if (strcasecmp(operation, "LogFileMaxSize") == 0) {
374 answer_integer = serverinfo->dwLogFileMaxSize;
375 is_integer = 1;
376 } else if (strcasecmp(operation, "LogLevel") == 0) {
377 answer_integer = serverinfo->dwLogLevel;
378 is_integer = 1;
379 } else if (strcasecmp(operation, "LooseWildcarding") == 0) {
380 answer_integer = serverinfo->fLooseWildcarding;
381 is_integer = 1;
382 } else if (strcasecmp(operation, "MaxCacheTtl") == 0) {
383 answer_integer = serverinfo->dwMaxCacheTtl;
384 is_integer = 1;
385 } else if (strcasecmp(operation, "MaxNegativeCacheTtl") == 0) {
386 answer_integer = 0x00000384; /* 15 minutes */
387 is_integer = 1;
388 } else if (strcasecmp(operation, "NameCheckFlag") == 0) {
389 answer_integer = serverinfo->dwNameCheckFlag;
390 is_integer = 1;
391 } else if (strcasecmp(operation, "NoRecursion") == 0) {
392 answer_integer = serverinfo->fNoRecursion;
393 is_integer = 1;
394 } else if (strcasecmp(operation, "NoUpdateDelegations") == 0) {
395 answer_integer = 1;
396 is_integer = 1;
397 } else if (strcasecmp(operation, "PublishAutonet") == 0) {
398 answer_integer = 0;
399 is_integer = 1;
400 } else if (strcasecmp(operation, "QuietRecvFaultInterval") == 0) {
401 answer_integer = 0;
402 is_integer = 1;
403 } else if (strcasecmp(operation, "QuietRecvLogInterval") == 0) {
404 answer_integer = 0;
405 is_integer = 1;
406 } else if (strcasecmp(operation, "RecursionRetry") == 0) {
407 answer_integer = serverinfo->dwRecursionRetry;
408 is_integer = 1;
409 } else if (strcasecmp(operation, "RecursionTimeout") == 0) {
410 answer_integer = serverinfo->dwRecursionTimeout;
411 is_integer = 1;
412 } else if (strcasecmp(operation, "ReloadException") == 0) {
413 answer_integer = 0;
414 is_integer = 1;
415 } else if (strcasecmp(operation, "RoundRobin") == 0) {
416 answer_integer = serverinfo->fRoundRobin;
417 is_integer = 1;
418 } else if (strcasecmp(operation, "RpcProtocol") == 0) {
419 answer_integer = serverinfo->dwRpcProtocol;
420 is_integer = 1;
421 } else if (strcasecmp(operation, "SecureResponses") == 0) {
422 answer_integer = serverinfo->fSecureResponses;
423 is_integer = 1;
424 } else if (strcasecmp(operation, "SendPort") == 0) {
425 answer_integer = 0;
426 is_integer = 1;
427 } else if (strcasecmp(operation, "ScavengingInterval") == 0) {
428 answer_integer = serverinfo->dwScavengingInterval;
429 is_integer = 1;
430 } else if (strcasecmp(operation, "SocketPoolSize") == 0) {
431 answer_integer = 0x000009C4;
432 is_integer = 1;
433 } else if (strcasecmp(operation, "StrictFileParsing") == 0) {
434 answer_integer = serverinfo->fStrictFileParsing;
435 is_integer = 1;
436 } else if (strcasecmp(operation, "SyncDnsZoneSerial") == 0) {
437 answer_integer = 2; /* ZONE_SERIAL_SYNC_XFER */
438 is_integer = 1;
439 } else if (strcasecmp(operation, "UpdateOptions") == 0) {
440 answer_integer = 0x0000030F; /* DNS_DEFAULT_UPDATE_OPTIONS */
441 is_integer = 1;
442 } else if (strcasecmp(operation, "UseSystemEvengLog") == 0) {
443 answer_integer = 0;
444 is_integer = 1;
445 } else if (strcasecmp(operation, "Version") == 0) {
446 answer_integer = serverinfo->dwVersion;
447 is_integer = 1;
448 } else if (strcasecmp(operation, "XfrConnectTimeout") == 0) {
449 answer_integer = 0x0000001E;
450 is_integer = 1;
451 } else if (strcasecmp(operation, "WriteAuthorityNs") == 0) {
452 answer_integer = serverinfo->fWriteAuthorityNs;
453 is_integer = 1;
454 } else if (strcasecmp(operation, "AdditionalRecursionTimeout") == 0) {
455 answer_integer = 0x00000004;
456 is_integer = 1;
457 } else if (strcasecmp(operation, "AppendMsZoneTransferFlag") == 0) {
458 answer_integer = 0;
459 is_integer = 1;
460 } else if (strcasecmp(operation, "AutoCreateDelegations") == 0) {
461 answer_integer = 0; /* DNS_ACD_DONT_CREATE */
462 is_integer = 1;
463 } else if (strcasecmp(operation, "BreakOnAscFailure") == 0) {
464 answer_integer = 0;
465 is_integer = 1;
466 } else if (strcasecmp(operation, "CacheEmptyAuthResponses") == 0) {
467 answer_integer = 0;
468 is_integer = 1;
469 } else if (strcasecmp(operation, "DirectoryPartitionAutoEnlistInterval") == 0) {
470 answer_integer = 0x00015180; /* 1 day */
471 is_integer = 1;
472 } else if (strcasecmp(operation, "DisableAutoReverseZones") == 0) {
473 answer_integer = ~serverinfo->fAutoReverseZones;
474 is_integer = 1;
475 } else if (strcasecmp(operation, "EDnsCacheTimeout") == 0) {
476 answer_integer = 0x00000384; /* 15 minutes */
477 is_integer = 1;
478 } else if (strcasecmp(operation, "EnableDirectoryPartitions") == 0) {
479 answer_integer = serverinfo->fDsAvailable;
480 is_integer = 1;
481 } else if (strcasecmp(operation, "EnableDnsSec") == 0) {
482 answer_integer = 0;
483 is_integer = 1;
484 } else if (strcasecmp(operation, "EnableEDnsProbes") == 0) {
485 answer_integer = 0;
486 is_integer = 1;
487 } else if (strcasecmp(operation, "EnableEDnsReception") == 0) {
488 answer_integer = 0;
489 is_integer = 1;
490 } else if (strcasecmp(operation, "EnableIPv6") == 0) {
491 answer_integer = 0;
492 is_integer = 1;
493 } else if (strcasecmp(operation, "EnableIQueryResponseGeneration") == 0) {
494 answer_integer = 0;
495 is_integer = 1;
496 } else if (strcasecmp(operation, "EnableSendErrorSuppression") == 0) {
497 answer_integer = 0;
498 is_integer = 1;
499 } else if (strcasecmp(operation, "EnableUpdateForwarding") == 0) {
500 answer_integer = 0;
501 is_integer = 1;
502 } else if (strcasecmp(operation, "EnableWinsR") == 0) {
503 answer_integer = 0;
504 is_integer = 1;
505 } else if (strcasecmp(operation, "ForceDsaBehaviorVersion") == 0) {
506 answer_integer = serverinfo->dwDsDsaVersion;
507 is_integer = 1;
508 } else if (strcasecmp(operation, "ForceDomainBehaviorVersion") == 0) {
509 answer_integer = serverinfo->dwDsDsaVersion;
510 is_integer = 1;
511 } else if (strcasecmp(operation, "ForceForestBehaviorVersion") == 0) {
512 answer_integer = serverinfo->dwDsDsaVersion;
513 is_integer = 1;
514 } else if (strcasecmp(operation, "HeapDebug") == 0) {
515 answer_integer = 0;
516 is_integer = 1;
517 } else if (strcasecmp(operation, "LameDelegationTtl") == 0) {
518 answer_integer = 0; /* seconds */
519 is_integer = 1;
520 } else if (strcasecmp(operation, "LocalNetPriorityNetMask") == 0) {
521 answer_integer = serverinfo->dwLocalNetPriorityNetMask;
522 is_integer = 1;
523 } else if (strcasecmp(operation, "MaxCacheSize") == 0) {
524 answer_integer = 0;
525 is_integer = 1;
526 } else if (strcasecmp(operation, "MaxResourceRecordsInNonSecureUpdate") == 0) {
527 answer_integer = 0x0000001E;
528 is_integer = 1;
529 } else if (strcasecmp(operation, "OperationsLogLevel") == 0) {
530 answer_integer = 0;
531 is_integer = 1;
532 } else if (strcasecmp(operation, "OperationsLogLevel2") == 0) {
533 answer_integer = 0;
534 is_integer = 1;
535 } else if (strcasecmp(operation, "MaximumUdpPacketSize") == 0) {
536 answer_integer = 0x00004000; /* maximum possible */
537 is_integer = 1;
538 } else if (strcasecmp(operation, "RecurseToInternetRootMask") == 0) {
539 answer_integer = 0;
540 is_integer = 1;
541 } else if (strcasecmp(operation, "SelfTest") == 0) {
542 answer_integer = 0;
543 is_integer = 1;
544 } else if (strcasecmp(operation, "SilentlyIgnoreCNameUpdateConflicts") == 0) {
545 answer_integer = 1;
546 is_integer = 1;
547 } else if (strcasecmp(operation, "TcpReceivePacketSize") == 0) {
548 answer_integer = 0x00010000;
549 is_integer = 1;
550 } else if (strcasecmp(operation, "XfrThrottleMultiplier") == 0) {
551 answer_integer = 0x0000000A;
552 is_integer = 1;
553 } else if (strcasecmp(operation, "AllowMsdcsLookupRetry") == 0) {
554 answer_integer = 1;
555 is_integer = 1;
556 } else if (strcasecmp(operation, "AllowReadOnlyZoneTransfer") == 0) {
557 answer_integer = 0;
558 is_integer = 1;
559 } else if (strcasecmp(operation, "DsBackGroundLoadPaused") == 0) {
560 answer_integer = 0;
561 is_integer = 1;
562 } else if (strcasecmp(operation, "DsMinimumBackgroundLoadThreads") == 0) {
563 answer_integer = 0;
564 is_integer = 1;
565 } else if (strcasecmp(operation, "DsRemoteReplicationDelay") == 0) {
566 answer_integer = 0x0000001E; /* 30 seconds */
567 is_integer = 1;
568 } else if (strcasecmp(operation, "EnableDuplicateQuerySuppresion") == 0) {
569 answer_integer = 0;
570 is_integer = 1;
571 } else if (strcasecmp(operation, "EnableGlobalNamesSupport") == 0) {
572 answer_integer = 0;
573 is_integer = 1;
574 } else if (strcasecmp(operation, "EnableVersionQuery") == 0) {
575 answer_integer = 1; /* DNS_VERSION_QUERY_FULL */
576 is_integer = 1;
577 } else if (strcasecmp(operation, "EnableRsoForRodc") == 0) {
578 answer_integer = 0;
579 is_integer = 1;
580 } else if (strcasecmp(operation, "ForceRODCMode") == 0) {
581 answer_integer = 0;
582 is_integer = 1;
583 } else if (strcasecmp(operation, "GlobalNamesAlwaysQuerySrv") == 0) {
584 answer_integer = 1;
585 is_integer = 1;
586 } else if (strcasecmp(operation, "GlobalNamesBlockUpdates") == 0) {
587 answer_integer = 0;
588 is_integer = 1;
589 } else if (strcasecmp(operation, "GlobalNamesEnableEDnsProbes") == 0) {
590 answer_integer = 0;
591 is_integer = 1;
592 } else if (strcasecmp(operation, "GlobalNamesPreferAAAA") == 0) {
593 answer_integer = 0;
594 is_integer = 1;
595 } else if (strcasecmp(operation, "GlobalNamesQueryOrder") == 0) {
596 answer_integer = 1;
597 is_integer = 1;
598 } else if (strcasecmp(operation, "GlobalNamesSendTimeout") == 0) {
599 answer_integer = 3; /* seconds */
600 is_integer = 1;
601 } else if (strcasecmp(operation, "GlobalNamesServerQueryInterval") == 0) {
602 answer_integer = 0x00005460; /* 6 hours */
603 is_integer = 1;
604 } else if (strcasecmp(operation, "RemoteIPv4RankBoost") == 0) {
605 answer_integer = 0;
606 is_integer = 1;
607 } else if (strcasecmp(operation, "RemoteIPv6RankBoost") == 0) {
608 answer_integer = 0;
609 is_integer = 1;
610 } else if (strcasecmp(operation, "MaximumRodcRsoAttemptsPerCycle") == 0) {
611 answer_integer = 0x00000064;
612 is_integer = 1;
613 } else if (strcasecmp(operation, "MaximumRodcRsoQueueLength") == 0) {
614 answer_integer = 0x0000012C;
615 is_integer = 1;
616 } else if (strcasecmp(operation, "EnableGlobalQueryBlockList") == 0) {
617 answer_integer = 0;
618 is_integer = 1;
619 } else if (strcasecmp(operation, "OpenACLOnProxyUpdates") == 0) {
620 answer_integer = 0;
621 is_integer = 1;
622 } else if (strcasecmp(operation, "CacheLockingPercent") == 0) {
623 answer_integer = 0x00000064;
624 is_integer = 1;
627 if (is_integer == 1) {
628 *typeid = DNSSRV_TYPEID_DWORD;
629 r->Dword = answer_integer;
630 return WERR_OK;
633 is_addresses = 0;
635 if (strcasecmp(operation, "Forwarders") == 0) {
636 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
637 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders);
638 } else {
639 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
641 is_addresses = 1;
642 } else if (strcasecmp(operation, "ListenAddresses") == 0) {
643 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
644 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipListenAddrs);
645 } else {
646 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipListenAddrs);
648 is_addresses = 1;
649 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
650 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
651 answer_addrarray = NULL;
652 } else {
653 answer_iparray = NULL;
655 is_addresses = 1;
656 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
657 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
658 answer_addrarray = NULL;
659 } else {
660 answer_iparray = NULL;
662 is_addresses = 1;
663 } else if (strcasecmp(operation, "LogIPFilterList") == 0) {
664 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
665 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter);
666 } else {
667 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
669 is_addresses = 1;
672 if (is_addresses == 1) {
673 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
674 *typeid = DNSSRV_TYPEID_ADDRARRAY;
675 r->AddrArray = answer_addrarray;
676 } else {
677 *typeid = DNSSRV_TYPEID_IPARRAY;
678 r->IpArray = answer_iparray;
680 return WERR_OK;
683 is_string = is_wstring = 0;
685 if (strcasecmp(operation, "DomainDirectoryPartitionBaseName") == 0) {
686 answer_string = talloc_strdup(mem_ctx, "DomainDnsZones");
687 if (! answer_string) {
688 return WERR_OUTOFMEMORY;
690 is_string = 1;
691 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
692 answer_string = talloc_strdup(mem_ctx, "ForestDnsZones");
693 if (! answer_string) {
694 return WERR_OUTOFMEMORY;
696 is_string = 1;
697 } else if (strcasecmp(operation, "LogFilePath") == 0) {
698 answer_string = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
699 is_wstring = 1;
700 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
701 answer_string = NULL;
702 is_wstring = 1;
703 } else if (strcasecmp(operation, "DsBackgroundPauseName") == 0) {
704 answer_string = NULL;
705 is_string = 1;
706 } else if (strcasecmp(operation, "DsNotRoundRobinTypes") == 0) {
707 answer_string = NULL;
708 is_string = 1;
711 if (is_string == 1) {
712 *typeid = DNSSRV_TYPEID_LPSTR;
713 r->String = answer_string;
714 return WERR_OK;
715 } else if (is_wstring == 1) {
716 *typeid = DNSSRV_TYPEID_LPWSTR;
717 r->WideString = answer_string;
718 return WERR_OK;
721 is_stringlist = 0;
723 if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
724 answer_stringlist = NULL;
725 is_stringlist = 1;
726 } else if (strcasecmp(operation, "SocketPoolExcludedPortRanges") == 0) {
727 answer_stringlist = NULL;
728 is_stringlist = 1;
731 if (is_stringlist == 1) {
732 *typeid = DNSSRV_TYPEID_UTF8_STRING_LIST;
733 r->Utf8StringList = answer_stringlist;
734 return WERR_OK;
737 DEBUG(0,("dnsserver: Invalid server operation %s", operation));
738 return WERR_DNS_ERROR_INVALID_PROPERTY;
741 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
742 static WERROR dnsserver_query_zone(struct dnsserver_state *dsstate,
743 TALLOC_CTX *mem_ctx,
744 struct dnsserver_zone *z,
745 const char *operation,
746 const unsigned int client_version,
747 enum DNS_RPC_TYPEID *typeid,
748 union DNSSRV_RPC_UNION *r)
750 uint8_t is_integer, is_addresses, is_string;
751 uint32_t answer_integer;
752 struct IP4_ARRAY *answer_iparray;
753 struct DNS_ADDR_ARRAY *answer_addrarray;
754 char *answer_string;
755 struct dnsserver_zoneinfo *zoneinfo;
757 zoneinfo = z->zoneinfo;
759 if (strcasecmp(operation, "Zone") == 0) {
760 if (client_version == DNS_CLIENT_VERSION_W2K) {
761 *typeid = DNSSRV_TYPEID_ZONE_W2K;
762 r->ZoneW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
764 r->ZoneW2K->pszZoneName = talloc_strdup(mem_ctx, z->name);
765 r->ZoneW2K->Flags = zoneinfo->Flags;
766 r->ZoneW2K->ZoneType = zoneinfo->dwZoneType;
767 r->ZoneW2K->Version = zoneinfo->Version;
768 } else {
769 *typeid = DNSSRV_TYPEID_ZONE;
770 r->Zone = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
772 r->Zone->dwRpcStructureVersion = 0x01;
773 r->Zone->pszZoneName = talloc_strdup(mem_ctx, z->name);
774 r->Zone->Flags = zoneinfo->Flags;
775 r->Zone->ZoneType = zoneinfo->dwZoneType;
776 r->Zone->Version = zoneinfo->Version;
777 r->Zone->dwDpFlags = z->partition->dwDpFlags;
778 r->Zone->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
780 return WERR_OK;
783 if (strcasecmp(operation, "ZoneInfo") == 0) {
784 if (client_version == DNS_CLIENT_VERSION_W2K) {
785 *typeid = DNSSRV_TYPEID_ZONE_INFO_W2K;
786 r->ZoneInfoW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_W2K);
788 r->ZoneInfoW2K->pszZoneName = talloc_strdup(mem_ctx, z->name);
789 r->ZoneInfoW2K->dwZoneType = zoneinfo->dwZoneType;
790 r->ZoneInfoW2K->fReverse = zoneinfo->fReverse;
791 r->ZoneInfoW2K->fAllowUpdate = zoneinfo->fAllowUpdate;
792 r->ZoneInfoW2K->fPaused = zoneinfo->fPaused;
793 r->ZoneInfoW2K->fShutdown = zoneinfo->fShutdown;
794 r->ZoneInfoW2K->fAutoCreated = zoneinfo->fAutoCreated;
795 r->ZoneInfoW2K->fUseDatabase = zoneinfo->fUseDatabase;
796 r->ZoneInfoW2K->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
797 r->ZoneInfoW2K->aipMasters = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
798 r->ZoneInfoW2K->fSecureSecondaries = zoneinfo->fSecureSecondaries;
799 r->ZoneInfoW2K->fNotifyLevel = zoneinfo->fNotifyLevel;
800 r->ZoneInfoW2K->aipSecondaries = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
801 r->ZoneInfoW2K->aipNotify = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
802 r->ZoneInfoW2K->fUseWins = zoneinfo->fUseWins;
803 r->ZoneInfoW2K->fUseNbstat = zoneinfo->fUseNbstat;
804 r->ZoneInfoW2K->fAging = zoneinfo->fAging;
805 r->ZoneInfoW2K->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
806 r->ZoneInfoW2K->dwRefreshInterval = zoneinfo->dwRefreshInterval;
807 r->ZoneInfoW2K->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
808 r->ZoneInfoW2K->aipScavengeServers = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
810 } else if (client_version == DNS_CLIENT_VERSION_DOTNET) {
811 *typeid = DNSSRV_TYPEID_ZONE_INFO_DOTNET;
812 r->ZoneInfoDotNet = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_DOTNET);
814 r->ZoneInfoDotNet->dwRpcStructureVersion = 0x01;
815 r->ZoneInfoDotNet->pszZoneName = talloc_strdup(mem_ctx, z->name);
816 r->ZoneInfoDotNet->dwZoneType = zoneinfo->dwZoneType;
817 r->ZoneInfoDotNet->fReverse = zoneinfo->fReverse;
818 r->ZoneInfoDotNet->fAllowUpdate = zoneinfo->fAllowUpdate;
819 r->ZoneInfoDotNet->fPaused = zoneinfo->fPaused;
820 r->ZoneInfoDotNet->fShutdown = zoneinfo->fShutdown;
821 r->ZoneInfoDotNet->fAutoCreated = zoneinfo->fAutoCreated;
822 r->ZoneInfoDotNet->fUseDatabase = zoneinfo->fUseDatabase;
823 r->ZoneInfoDotNet->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
824 r->ZoneInfoDotNet->aipMasters = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
825 r->ZoneInfoDotNet->fSecureSecondaries = zoneinfo->fSecureSecondaries;
826 r->ZoneInfoDotNet->fNotifyLevel = zoneinfo->fNotifyLevel;
827 r->ZoneInfoDotNet->aipSecondaries = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
828 r->ZoneInfoDotNet->aipNotify = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
829 r->ZoneInfoDotNet->fUseWins = zoneinfo->fUseWins;
830 r->ZoneInfoDotNet->fUseNbstat = zoneinfo->fUseNbstat;
831 r->ZoneInfoDotNet->fAging = zoneinfo->fAging;
832 r->ZoneInfoDotNet->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
833 r->ZoneInfoDotNet->dwRefreshInterval = zoneinfo->dwRefreshInterval;
834 r->ZoneInfoDotNet->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
835 r->ZoneInfoDotNet->aipScavengeServers = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
836 r->ZoneInfoDotNet->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
837 r->ZoneInfoDotNet->fForwarderSlave = zoneinfo->fForwarderSlave;
838 r->ZoneInfoDotNet->aipLocalMasters = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
839 r->ZoneInfoDotNet->dwDpFlags = z->partition->dwDpFlags;
840 r->ZoneInfoDotNet->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
841 r->ZoneInfoDotNet->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
842 r->ZoneInfoDotNet->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
843 r->ZoneInfoDotNet->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
845 } else {
846 *typeid = DNSSRV_TYPEID_ZONE_INFO;
847 r->ZoneInfo = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_LONGHORN);
849 r->ZoneInfo->dwRpcStructureVersion = 0x02;
850 r->ZoneInfo->pszZoneName = talloc_strdup(mem_ctx, z->name);
851 r->ZoneInfo->dwZoneType = zoneinfo->dwZoneType;
852 r->ZoneInfo->fReverse = zoneinfo->fReverse;
853 r->ZoneInfo->fAllowUpdate = zoneinfo->fAllowUpdate;
854 r->ZoneInfo->fPaused = zoneinfo->fPaused;
855 r->ZoneInfo->fShutdown = zoneinfo->fShutdown;
856 r->ZoneInfo->fAutoCreated = zoneinfo->fAutoCreated;
857 r->ZoneInfo->fUseDatabase = zoneinfo->fUseDatabase;
858 r->ZoneInfo->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
859 r->ZoneInfo->aipMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipMasters);
860 r->ZoneInfo->fSecureSecondaries = zoneinfo->fSecureSecondaries;
861 r->ZoneInfo->fNotifyLevel = zoneinfo->fNotifyLevel;
862 r->ZoneInfo->aipSecondaries = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipSecondaries);
863 r->ZoneInfo->aipNotify = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipNotify);
864 r->ZoneInfo->fUseWins = zoneinfo->fUseWins;
865 r->ZoneInfo->fUseNbstat = zoneinfo->fUseNbstat;
866 r->ZoneInfo->fAging = zoneinfo->fAging;
867 r->ZoneInfo->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
868 r->ZoneInfo->dwRefreshInterval = zoneinfo->dwRefreshInterval;
869 r->ZoneInfo->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
870 r->ZoneInfo->aipScavengeServers = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipScavengeServers);
871 r->ZoneInfo->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
872 r->ZoneInfo->fForwarderSlave = zoneinfo->fForwarderSlave;
873 r->ZoneInfo->aipLocalMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
874 r->ZoneInfo->dwDpFlags = z->partition->dwDpFlags;
875 r->ZoneInfo->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
876 r->ZoneInfo->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
877 r->ZoneInfo->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
878 r->ZoneInfo->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
880 r->ZoneInfo->fQueuedForBackgroundLoad = zoneinfo->fQueuedForBackgroundLoad;
881 r->ZoneInfo->fBackgroundLoadInProgress = zoneinfo->fBackgroundLoadInProgress;
882 r->ZoneInfo->fReadOnlyZone = zoneinfo->fReadOnlyZone;
883 r->ZoneInfo->dwLastXfrAttempt = zoneinfo->dwLastXfrAttempt;
884 r->ZoneInfo->dwLastXfrResult = zoneinfo->dwLastXfrResult;
887 return WERR_OK;
890 is_integer = 0;
892 if (strcasecmp(operation, "AllowUpdate") == 0) {
893 answer_integer = zoneinfo->fAllowUpdate;
894 is_integer = 1;
895 } else if (strcasecmp(operation, "Secured") == 0) {
896 answer_integer = 0;
897 is_integer = 1;
898 } else if (strcasecmp(operation, "DsIntegrated") == 0) {
899 answer_integer = zoneinfo->fUseDatabase;
900 is_integer = 1;
901 } else if (strcasecmp(operation, "LogUpdates") == 0) {
902 answer_integer = 0;
903 is_integer = 1;
904 } else if (strcasecmp(operation, "NoRefreshInterval") == 0) {
905 answer_integer = zoneinfo->dwNoRefreshInterval;
906 is_integer = 1;
907 } else if (strcasecmp(operation, "NotifyLevel") == 0) {
908 answer_integer = zoneinfo->fNotifyLevel;
909 is_integer = 1;
910 } else if (strcasecmp(operation, "RefreshInterval") == 0) {
911 answer_integer = zoneinfo->dwRefreshInterval;
912 is_integer = 1;
913 } else if (strcasecmp(operation, "SecureSecondaries") == 0) {
914 answer_integer = zoneinfo->fSecureSecondaries;
915 is_integer = 1;
916 } else if (strcasecmp(operation, "Type") == 0) {
917 answer_integer = zoneinfo->dwZoneType;
918 is_integer = 1;
919 } else if (strcasecmp(operation, "Aging") == 0) {
920 answer_integer = zoneinfo->fAging;
921 is_integer = 1;
922 } else if (strcasecmp(operation, "ForwarderSlave") == 0) {
923 answer_integer = zoneinfo->fForwarderSlave;
924 is_integer = 1;
925 } else if (strcasecmp(operation, "ForwarderTimeout") == 0) {
926 answer_integer = zoneinfo->dwForwarderTimeout;
927 is_integer = 1;
928 } else if (strcasecmp(operation, "Unicode") == 0) {
929 answer_integer = 0;
930 is_integer = 1;
933 if (is_integer == 1) {
934 *typeid = DNSSRV_TYPEID_DWORD;
935 r->Dword = answer_integer;
936 return WERR_OK;
939 is_addresses = 0;
941 if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
942 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
943 answer_addrarray = NULL;
944 } else {
945 answer_iparray = NULL;
947 is_addresses = 1;
948 } else if (strcasecmp(operation, "ScavengeServers") == 0) {
949 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
950 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipScavengeServers);
951 } else {
952 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
954 is_addresses = 1;
955 } else if (strcasecmp(operation, "MasterServers") == 0) {
956 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
957 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipMasters);
958 } else {
959 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
961 is_addresses = 1;
962 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
963 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
964 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
965 } else {
966 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
968 is_addresses = 1;
969 } else if (strcasecmp(operation, "NotifyServers") == 0) {
970 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
971 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipNotify);
972 } else {
973 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
975 is_addresses = 1;
976 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
977 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
978 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipSecondaries);
979 } else {
980 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
982 is_addresses = 1;
985 if (is_addresses == 1) {
986 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
987 *typeid = DNSSRV_TYPEID_ADDRARRAY;
988 r->AddrArray = answer_addrarray;
989 } else {
990 *typeid = DNSSRV_TYPEID_IPARRAY;
991 r->IpArray = answer_iparray;
993 return WERR_OK;
996 is_string = 0;
998 if (strcasecmp(operation, "DatabaseFile") == 0) {
999 answer_string = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
1000 is_string = 1;
1001 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1002 answer_string = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
1003 is_string = 1;
1004 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1005 answer_string = NULL;
1006 is_string = 1;
1009 if (is_string == 1) {
1010 *typeid = DNSSRV_TYPEID_LPSTR;
1011 r->String = answer_string;
1012 return WERR_OK;
1015 DEBUG(0,("dnsserver: Invalid zone operation %s", operation));
1016 return WERR_DNS_ERROR_INVALID_PROPERTY;
1020 /* dnsserver operation functions */
1022 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
1023 static WERROR dnsserver_operate_server(struct dnsserver_state *dsstate,
1024 TALLOC_CTX *mem_ctx,
1025 const char *operation,
1026 const unsigned int client_version,
1027 enum DNS_RPC_TYPEID typeid,
1028 union DNSSRV_RPC_UNION *r)
1030 bool valid_operation = false;
1032 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1033 valid_operation = true;
1034 } else if (strcasecmp(operation, "Restart") == 0) {
1035 valid_operation = true;
1036 } else if (strcasecmp(operation, "ClearDebugLog") == 0) {
1037 valid_operation = true;
1038 } else if (strcasecmp(operation, "ClearCache") == 0) {
1039 valid_operation = true;
1040 } else if (strcasecmp(operation, "WriteDirtyZones") == 0) {
1041 valid_operation = true;
1042 } else if (strcasecmp(operation, "ZoneCreate") == 0) {
1043 valid_operation = true;
1044 } else if (strcasecmp(operation, "ClearStatistics") == 0) {
1045 valid_operation = true;
1046 } else if (strcasecmp(operation, "EnlistDirectoryPartition") == 0) {
1047 valid_operation = true;
1048 } else if (strcasecmp(operation, "StartScavenging") == 0) {
1049 valid_operation = true;
1050 } else if (strcasecmp(operation, "AbortScavenging") == 0) {
1051 valid_operation = true;
1052 } else if (strcasecmp(operation, "AutoConfigure") == 0) {
1053 valid_operation = true;
1054 } else if (strcasecmp(operation, "ExportSettings") == 0) {
1055 valid_operation = true;
1056 } else if (strcasecmp(operation, "PrepareForDemotion") == 0) {
1057 valid_operation = true;
1058 } else if (strcasecmp(operation, "PrepareForUninstall") == 0) {
1059 valid_operation = true;
1060 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1061 valid_operation = true;
1062 } else if (strcasecmp(operation, "DeleteRecord") == 0) {
1063 valid_operation = true;
1064 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1065 valid_operation = true;
1066 } else if (strcasecmp(operation, "ListenAddresses") == 0) {
1067 valid_operation = true;
1068 } else if (strcasecmp(operation, "Forwarders") == 0) {
1069 valid_operation = true;
1070 } else if (strcasecmp(operation, "LogFilePath") == 0) {
1071 valid_operation = true;
1072 } else if (strcasecmp(operation, "LogIpFilterList") == 0) {
1073 valid_operation = true;
1074 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
1075 valid_operation = true;
1076 } else if (strcasecmp(operation, "DomainDirectoryPartitionBaseName") == 0) {
1077 valid_operation = true;
1078 } else if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
1079 valid_operation = true;
1080 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
1081 valid_operation = true;
1082 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
1083 valid_operation = true;
1084 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
1085 valid_operation = true;
1088 if (valid_operation) {
1089 DEBUG(0, ("dnsserver: server operation '%s' not implemented", operation));
1090 return WERR_CALL_NOT_IMPLEMENTED;
1093 DEBUG(0, ("dnsserver: invalid server operation '%s'", operation));
1094 return WERR_DNS_ERROR_INVALID_PROPERTY;
1097 static WERROR dnsserver_complex_operate_server(struct dnsserver_state *dsstate,
1098 TALLOC_CTX *mem_ctx,
1099 const char *operation,
1100 const unsigned int client_version,
1101 enum DNS_RPC_TYPEID typeid_in,
1102 union DNSSRV_RPC_UNION *rin,
1103 enum DNS_RPC_TYPEID *typeid_out,
1104 union DNSSRV_RPC_UNION *rout)
1106 int valid_operation = 0;
1107 struct dnsserver_zone *z, **zlist;
1108 int zcount;
1109 bool found1, found2, found3, found4;
1110 int i;
1112 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1113 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1114 return dnsserver_query_server(dsstate, mem_ctx,
1115 rin->String,
1116 client_version,
1117 typeid_out,
1118 rout);
1120 } else if (strcasecmp(operation, "EnumZones") == 0) {
1121 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1122 return WERR_DNS_ERROR_INVALID_PROPERTY;
1125 zcount = 0;
1126 zlist = talloc_zero_array(mem_ctx, struct dnsserver_zone *, 0);
1127 for (z = dsstate->zones; z; z = z->next) {
1129 /* Match the flags in groups
1131 * Group1 : PRIMARY, SECONDARY, CACHE, AUTO
1132 * Group2 : FORWARD, REVERSE, FORWARDER, STUB
1133 * Group3 : DS, NON_DS, DOMAIN_DP, FOREST_DP
1134 * Group4 : CUSTOM_DP, LEGACY_DP
1137 /* Group 1 */
1138 found1 = false;
1139 if (rin->Dword & 0x0000000f) {
1140 if (rin->Dword & DNS_ZONE_REQUEST_PRIMARY) {
1141 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_PRIMARY) {
1142 found1 = true;
1145 if (rin->Dword & DNS_ZONE_REQUEST_SECONDARY) {
1146 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_SECONDARY) {
1147 found1 = true;
1150 if (rin->Dword & DNS_ZONE_REQUEST_CACHE) {
1151 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_CACHE) {
1152 found1 = true;
1155 if (rin->Dword & DNS_ZONE_REQUEST_AUTO) {
1156 if (z->zoneinfo->fAutoCreated
1157 || z->partition->dwDpFlags & DNS_DP_AUTOCREATED) {
1158 found1 = true;
1161 } else {
1162 found1 = true;
1165 /* Group 2 */
1166 found2 = false;
1167 if (rin->Dword & 0x000000f0) {
1168 if (rin->Dword & DNS_ZONE_REQUEST_FORWARD) {
1169 if (!(z->zoneinfo->fReverse)) {
1170 found2 = true;
1173 if (rin->Dword & DNS_ZONE_REQUEST_REVERSE) {
1174 if (z->zoneinfo->fReverse) {
1175 found2 = true;
1178 if (rin->Dword & DNS_ZONE_REQUEST_FORWARDER) {
1179 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_FORWARDER) {
1180 found2 = true;
1183 if (rin->Dword & DNS_ZONE_REQUEST_STUB) {
1184 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_STUB) {
1185 found2 = true;
1188 } else {
1189 found2 = true;
1192 /* Group 3 */
1193 found3 = false;
1194 if (rin->Dword & 0x00000f00) {
1195 if (rin->Dword & DNS_ZONE_REQUEST_DS) {
1196 if (z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED) {
1197 found3 = true;
1200 if (rin->Dword & DNS_ZONE_REQUEST_NON_DS) {
1201 if (!(z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED)) {
1202 found3 = true;
1205 if (rin->Dword & DNS_ZONE_REQUEST_DOMAIN_DP) {
1206 if (!(z->partition->dwDpFlags & DNS_DP_DOMAIN_DEFAULT)) {
1207 found3 = true;
1210 if (rin->Dword & DNS_ZONE_REQUEST_FOREST_DP) {
1211 if (!(z->partition->dwDpFlags & DNS_DP_FOREST_DEFAULT)) {
1212 found3 = true;
1215 } else {
1216 found3 = true;
1219 /* Group 4 */
1220 if (rin->Dword & 0x0000f000) {
1221 found4 = false;
1222 } else {
1223 found4 = true;
1226 if (found1 && found2 && found3 && found4) {
1227 zlist = talloc_realloc(mem_ctx, zlist, struct dnsserver_zone *, zcount+1);
1228 zlist[zcount] = z;
1229 zcount++;
1233 if (client_version == DNS_CLIENT_VERSION_W2K) {
1234 *typeid_out = DNSSRV_TYPEID_ZONE_LIST_W2K;
1235 rout->ZoneListW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_W2K);
1237 if (zcount == 0) {
1238 rout->ZoneListW2K->dwZoneCount = 0;
1239 rout->ZoneListW2K->ZoneArray = NULL;
1241 return WERR_OK;
1244 rout->ZoneListW2K->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_W2K *, zcount);
1245 if (rout->ZoneListW2K->ZoneArray == NULL) {
1246 talloc_free(zlist);
1247 return WERR_NOMEM;
1250 for (i=0; i<zcount; i++) {
1251 rout->ZoneListW2K->ZoneArray[i] = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
1253 rout->ZoneListW2K->ZoneArray[i]->pszZoneName = talloc_strdup(mem_ctx, zlist[i]->name);
1254 rout->ZoneListW2K->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
1255 rout->ZoneListW2K->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
1256 rout->ZoneListW2K->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
1258 rout->ZoneListW2K->dwZoneCount = zcount;
1260 } else {
1261 *typeid_out = DNSSRV_TYPEID_ZONE_LIST;
1262 rout->ZoneList = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_DOTNET);
1264 if (zcount == 0) {
1265 rout->ZoneList->dwRpcStructureVersion = 1;
1266 rout->ZoneList->dwZoneCount = 0;
1267 rout->ZoneList->ZoneArray = NULL;
1269 return WERR_OK;
1272 rout->ZoneList->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_DOTNET *, zcount);
1273 if (rout->ZoneList->ZoneArray == NULL) {
1274 talloc_free(zlist);
1275 return WERR_NOMEM;
1278 for (i=0; i<zcount; i++) {
1279 rout->ZoneList->ZoneArray[i] = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
1281 rout->ZoneList->ZoneArray[i]->dwRpcStructureVersion = 1;
1282 rout->ZoneList->ZoneArray[i]->pszZoneName = talloc_strdup(mem_ctx, zlist[i]->name);
1283 rout->ZoneList->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
1284 rout->ZoneList->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
1285 rout->ZoneList->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
1286 rout->ZoneList->ZoneArray[i]->dwDpFlags = zlist[i]->partition->dwDpFlags;
1287 rout->ZoneList->ZoneArray[i]->pszDpFqdn = talloc_strdup(mem_ctx, zlist[i]->partition->pszDpFqdn);
1289 rout->ZoneList->dwRpcStructureVersion = 1;
1290 rout->ZoneList->dwZoneCount = zcount;
1292 talloc_free(zlist);
1293 return WERR_OK;
1294 } else if (strcasecmp(operation, "EnumZones2") == 0) {
1295 valid_operation = true;
1296 } else if (strcasecmp(operation, "EnumDirectoryPartitions") == 0) {
1297 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1298 return WERR_DNS_ERROR_INVALID_PROPERTY;
1301 *typeid_out = DNSSRV_TYPEID_DP_LIST;
1302 rout->DirectoryPartitionList = talloc_zero(mem_ctx, struct DNS_RPC_DP_LIST);
1304 if (rin->Dword != 0) {
1305 rout->DirectoryPartitionList->dwDpCount = 0;
1306 rout->DirectoryPartitionList->DpArray = NULL;
1307 } else {
1308 struct DNS_RPC_DP_ENUM **dplist;
1309 struct dnsserver_partition *p;
1310 int pcount = 2;
1312 dplist = talloc_zero_array(mem_ctx, struct DNS_RPC_DP_ENUM *, pcount);
1313 if (dplist == NULL) {
1314 return WERR_NOMEM;
1317 p = dsstate->partitions;
1318 for (i=0; i<pcount; i++) {
1319 dplist[i] = talloc_zero(dplist, struct DNS_RPC_DP_ENUM);
1321 dplist[i]->pszDpFqdn = talloc_strdup(mem_ctx, p->pszDpFqdn);
1322 dplist[i]->dwFlags = p->dwDpFlags;
1323 dplist[i]->dwZoneCount = p->zones_count;
1324 p = p->next;
1327 rout->DirectoryPartitionList->dwDpCount = pcount;
1328 rout->DirectoryPartitionList->DpArray = dplist;
1330 return WERR_OK;
1331 } else if (strcasecmp(operation, "DirectoryPartitionInfo") == 0) {
1332 valid_operation = true;
1333 } else if (strcasecmp(operation, "Statistics") == 0) {
1334 valid_operation = true;
1335 } else if (strcasecmp(operation, "IpValidate") == 0) {
1336 valid_operation = true;
1339 if (valid_operation) {
1340 DEBUG(0, ("dnsserver: server complex operation '%s' not implemented", operation));
1341 return WERR_CALL_NOT_IMPLEMENTED;
1344 DEBUG(0, ("dnsserver: invalid server complex operation '%s'", operation));
1345 return WERR_DNS_ERROR_INVALID_PROPERTY;
1348 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
1349 static WERROR dnsserver_operate_zone(struct dnsserver_state *dsstate,
1350 TALLOC_CTX *mem_ctx,
1351 struct dnsserver_zone *z,
1352 unsigned int request_filter,
1353 const char *operation,
1354 const unsigned int client_version,
1355 enum DNS_RPC_TYPEID typeid,
1356 union DNSSRV_RPC_UNION *r)
1358 bool valid_operation = false;
1360 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1361 valid_operation = true;
1362 } else if (strcasecmp(operation, "ZoneTypeReset") == 0) {
1363 valid_operation = true;
1364 } else if (strcasecmp(operation, "PauseZone") == 0) {
1365 valid_operation = true;
1366 } else if (strcasecmp(operation, "ResumeZone") == 0) {
1367 valid_operation = true;
1368 } else if (strcasecmp(operation, "DeleteZone") == 0) {
1369 valid_operation = true;
1370 } else if (strcasecmp(operation, "ReloadZone") == 0) {
1371 valid_operation = true;
1372 } else if (strcasecmp(operation, "RefreshZone") == 0) {
1373 valid_operation = true;
1374 } else if (strcasecmp(operation, "ExpireZone") == 0) {
1375 valid_operation = true;
1376 } else if (strcasecmp(operation, "IncrementVersion") == 0) {
1377 valid_operation = true;
1378 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1379 valid_operation = true;
1380 } else if (strcasecmp(operation, "DeleteZoneFromDs") == 0) {
1381 valid_operation = true;
1382 } else if (strcasecmp(operation, "UpdateZoneFromDs") == 0) {
1383 valid_operation = true;
1384 } else if (strcasecmp(operation, "ZoneExport") == 0) {
1385 valid_operation = true;
1386 } else if (strcasecmp(operation, "ZoneChangeDirectoryPartition") == 0) {
1387 valid_operation = true;
1388 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1389 valid_operation = true;
1390 } else if (strcasecmp(operation, "DeleteRecordSet") == 0) {
1391 valid_operation = true;
1392 } else if (strcasecmp(operation, "ForceAgingOnNode") == 0) {
1393 valid_operation = true;
1394 } else if (strcasecmp(operation, "DatabaseFile") == 0) {
1395 valid_operation = true;
1396 } else if (strcasecmp(operation, "MasterServers") == 0) {
1397 valid_operation = true;
1398 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
1399 valid_operation = true;
1400 } else if (strcasecmp(operation, "NotifyServers") == 0) {
1401 valid_operation = true;
1402 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
1403 valid_operation = true;
1404 } else if (strcasecmp(operation, "ScavengingServers") == 0) {
1405 valid_operation = true;
1406 } else if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
1407 valid_operation = true;
1408 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1409 valid_operation = true;
1410 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1411 valid_operation = true;
1414 if (valid_operation) {
1415 DEBUG(0, ("dnsserver: zone operation '%s' not implemented", operation));
1416 return WERR_CALL_NOT_IMPLEMENTED;
1419 DEBUG(0, ("dnsserver: invalid zone operation '%s'", operation));
1420 return WERR_DNS_ERROR_INVALID_PROPERTY;
1423 static WERROR dnsserver_complex_operate_zone(struct dnsserver_state *dsstate,
1424 TALLOC_CTX *mem_ctx,
1425 struct dnsserver_zone *z,
1426 const char *operation,
1427 const unsigned int client_version,
1428 enum DNS_RPC_TYPEID typeid_in,
1429 union DNSSRV_RPC_UNION *rin,
1430 enum DNS_RPC_TYPEID *typeid_out,
1431 union DNSSRV_RPC_UNION *rout)
1433 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1434 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1435 return dnsserver_query_zone(dsstate, mem_ctx, z,
1436 rin->String,
1437 client_version,
1438 typeid_out,
1439 rout);
1444 DEBUG(0,("dnsserver: Invalid zone operation %s", operation));
1445 return WERR_DNS_ERROR_INVALID_PROPERTY;
1448 /* dnsserver enumerate function */
1450 static WERROR dnsserver_enumerate_root_records(struct dnsserver_state *dsstate,
1451 TALLOC_CTX *mem_ctx,
1452 unsigned int client_version,
1453 const char *node_name,
1454 enum dns_record_type record_type,
1455 unsigned int select_flag,
1456 unsigned int *buffer_length,
1457 struct DNS_RPC_RECORDS_ARRAY **buffer)
1459 TALLOC_CTX *tmp_ctx;
1460 const char * const attrs[] = { "name", "dnsRecord", NULL };
1461 struct ldb_result *res;
1462 struct ldb_dn *dn;
1463 struct DNS_RPC_RECORDS_ARRAY *recs;
1464 char **add_names;
1465 char *rname;
1466 int add_count;
1467 int i, ret, len;
1468 WERROR status;
1470 tmp_ctx = talloc_new(mem_ctx);
1471 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1473 dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(dsstate->samdb));
1474 W_ERROR_HAVE_NO_MEMORY_AND_FREE(dn, tmp_ctx);
1476 if (!ldb_dn_add_child_fmt(dn, "DC=RootDNSServers,CN=MicrosoftDNS,DC=DomainDnsZones")) {
1477 talloc_free(tmp_ctx);
1478 return WERR_NOMEM;
1481 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, dn,
1482 LDB_SCOPE_ONELEVEL, attrs, "(&(objectClass=dnsNode)(name=@))");
1483 if (ret != LDB_SUCCESS) {
1484 talloc_free(tmp_ctx);
1485 return WERR_INTERNAL_DB_ERROR;
1487 if (res->count == 0) {
1488 talloc_free(tmp_ctx);
1489 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1492 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1493 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1495 add_names = NULL;
1496 add_count = 0;
1498 for (i=0; i<res->count; i++) {
1499 status = dns_fill_records_array(tmp_ctx, NULL, record_type,
1500 select_flag, NULL,
1501 res->msgs[i], 0, recs,
1502 &add_names, &add_count);
1503 if (!W_ERROR_IS_OK(status)) {
1504 talloc_free(tmp_ctx);
1505 return status;
1508 talloc_free(res);
1510 /* Add any additional records */
1511 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1512 for (i=0; i<add_count; i++) {
1513 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, dn,
1514 LDB_SCOPE_ONELEVEL, attrs,
1515 "(&(objectClass=dnsNode)(name=%s))", add_names[i]);
1516 if (ret != LDB_SUCCESS || res->count == 0) {
1517 talloc_free(res);
1518 continue;
1521 len = strlen(add_names[i]);
1522 if (add_names[i][len-1] == '.') {
1523 rname = talloc_strdup(tmp_ctx, add_names[i]);
1524 } else {
1525 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1527 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1528 select_flag, rname,
1529 res->msgs[0], 0, recs,
1530 NULL, NULL);
1531 talloc_free(rname);
1532 talloc_free(res);
1536 talloc_free(tmp_ctx);
1538 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1539 *buffer = recs;
1541 return WERR_OK;
1545 static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
1546 TALLOC_CTX *mem_ctx,
1547 struct dnsserver_zone *z,
1548 unsigned int client_version,
1549 const char *node_name,
1550 const char *start_child,
1551 enum dns_record_type record_type,
1552 unsigned int select_flag,
1553 const char *filter_start,
1554 const char *filter_stop,
1555 unsigned int *buffer_length,
1556 struct DNS_RPC_RECORDS_ARRAY **buffer)
1558 TALLOC_CTX *tmp_ctx;
1559 char *name;
1560 const char * const attrs[] = { "name", "dnsRecord", NULL };
1561 struct ldb_result *res;
1562 struct DNS_RPC_RECORDS_ARRAY *recs;
1563 char **add_names = NULL;
1564 char *rname;
1565 int add_count = 0;
1566 int i, ret, len;
1567 WERROR status;
1568 struct dns_tree *tree, *base, *node;
1570 tmp_ctx = talloc_new(mem_ctx);
1571 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1573 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1574 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1576 /* search all records under parent tree */
1577 if (strcmp(name, z->name) == 0) {
1578 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1579 LDB_SCOPE_ONELEVEL, attrs, "(objectClass=dnsNode)");
1580 } else {
1581 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1582 LDB_SCOPE_ONELEVEL, attrs,
1583 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s)))",
1584 name, name);
1586 if (ret != LDB_SUCCESS) {
1587 talloc_free(tmp_ctx);
1588 return WERR_INTERNAL_DB_ERROR;
1590 if (res->count == 0) {
1591 talloc_free(tmp_ctx);
1592 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1595 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1596 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1598 /* Sort the names, so that the first record is the parent record */
1599 ldb_qsort(res->msgs, res->count, sizeof(struct ldb_message *), name,
1600 (ldb_qsort_cmp_fn_t)dns_name_compare);
1602 /* Build a tree of name components from dns name */
1603 if (strcmp(name, z->name) == 0) {
1604 tree = dns_build_tree(tmp_ctx, "@", res);
1605 } else {
1606 tree = dns_build_tree(tmp_ctx, name, res);
1608 W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree, tmp_ctx);
1610 /* Find the parent record in the tree */
1611 base = tree;
1612 while (base->level != -1) {
1613 base = base->children[0];
1616 /* Add the parent record with blank name */
1617 if (!(select_flag & DNS_RPC_VIEW_ONLY_CHILDREN)) {
1618 status = dns_fill_records_array(tmp_ctx, z, record_type,
1619 select_flag, NULL,
1620 base->data, 0,
1621 recs, &add_names, &add_count);
1622 if (!W_ERROR_IS_OK(status)) {
1623 talloc_free(tmp_ctx);
1624 return status;
1628 /* Add all the children records */
1629 if (!(select_flag & DNS_RPC_VIEW_NO_CHILDREN)) {
1630 for (i=0; i<base->num_children; i++) {
1631 node = base->children[i];
1633 status = dns_fill_records_array(tmp_ctx, z, record_type,
1634 select_flag, node->name,
1635 node->data, node->num_children,
1636 recs, &add_names, &add_count);
1637 if (!W_ERROR_IS_OK(status)) {
1638 talloc_free(tmp_ctx);
1639 return status;
1644 talloc_free(res);
1645 talloc_free(tree);
1646 talloc_free(name);
1648 /* Add any additional records */
1649 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1650 for (i=0; i<add_count; i++) {
1651 struct dnsserver_zone *z2;
1653 /* Search all the available zones for additional name */
1654 for (z2 = dsstate->zones; z2; z2 = z2->next) {
1655 name = dns_split_node_name(tmp_ctx, add_names[i], z2->name);
1656 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z2->zone_dn,
1657 LDB_SCOPE_ONELEVEL, attrs,
1658 "(&(objectClass=dnsNode)(name=%s))", name);
1659 talloc_free(name);
1660 if (ret != LDB_SUCCESS) {
1661 continue;
1663 if (res->count == 1) {
1664 break;
1665 } else {
1666 talloc_free(res);
1667 continue;
1671 len = strlen(add_names[i]);
1672 if (add_names[i][len-1] == '.') {
1673 rname = talloc_strdup(tmp_ctx, add_names[i]);
1674 } else {
1675 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1677 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1678 select_flag, rname,
1679 res->msgs[0], 0, recs,
1680 NULL, NULL);
1681 talloc_free(rname);
1682 talloc_free(res);
1686 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1687 *buffer = recs;
1689 return WERR_OK;
1692 /* dnsserver update function */
1694 static WERROR dnsserver_update_record(struct dnsserver_state *dsstate,
1695 TALLOC_CTX *mem_ctx,
1696 struct dnsserver_zone *z,
1697 unsigned int client_version,
1698 const char *node_name,
1699 struct DNS_RPC_RECORD_BUF *add_buf,
1700 struct DNS_RPC_RECORD_BUF *del_buf)
1702 TALLOC_CTX *tmp_ctx;
1703 char *name;
1704 WERROR status;
1706 tmp_ctx = talloc_new(mem_ctx);
1707 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1709 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1710 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1712 if (add_buf != NULL) {
1713 if (del_buf == NULL) {
1714 /* Add record */
1715 status = dnsserver_db_add_record(tmp_ctx, dsstate->samdb,
1716 z, name,
1717 &add_buf->rec);
1718 } else {
1719 /* Update record */
1720 status = dnsserver_db_update_record(tmp_ctx, dsstate->samdb,
1721 z, name,
1722 &add_buf->rec,
1723 &del_buf->rec);
1725 } else {
1726 if (del_buf == NULL) {
1727 /* Add empty node */
1728 status = dnsserver_db_add_empty_node(tmp_ctx, dsstate->samdb,
1729 z, name);
1730 } else {
1731 /* Delete record */
1732 status = dnsserver_db_delete_record(tmp_ctx, dsstate->samdb,
1733 z, name,
1734 &del_buf->rec);
1738 talloc_free(tmp_ctx);
1739 return status;
1743 /* dnsserver interface functions */
1745 static WERROR dcesrv_DnssrvOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation *r)
1747 struct dnsserver_state *dsstate;
1748 struct dnsserver_zone *z = NULL;
1749 uint32_t request_filter = 0;
1750 WERROR ret;
1752 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1753 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1756 if (r->in.dwContext == 0) {
1757 if (r->in.pszZone != NULL) {
1758 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
1760 } else {
1761 request_filter = r->in.dwContext;
1764 if (r->in.pszZone == NULL) {
1765 ret = dnsserver_operate_server(dsstate, mem_ctx,
1766 r->in.pszOperation,
1767 DNS_CLIENT_VERSION_W2K,
1768 r->in.dwTypeId,
1769 &r->in.pData);
1770 } else {
1771 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
1772 request_filter,
1773 r->in.pszOperation,
1774 DNS_CLIENT_VERSION_W2K,
1775 r->in.dwTypeId,
1776 &r->in.pData);
1779 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1780 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation, NDR_IN, r);
1782 return ret;
1785 static WERROR dcesrv_DnssrvQuery(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery *r)
1787 struct dnsserver_state *dsstate;
1788 struct dnsserver_zone *z;
1789 WERROR ret;
1791 ZERO_STRUCTP(r->out.pdwTypeId);
1792 ZERO_STRUCTP(r->out.ppData);
1794 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1795 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1798 if (r->in.pszZone == NULL) {
1799 /* FIXME: DNS Server Configuration Access Control List */
1800 ret = dnsserver_query_server(dsstate, mem_ctx,
1801 r->in.pszOperation,
1802 DNS_CLIENT_VERSION_W2K,
1803 r->out.pdwTypeId,
1804 r->out.ppData);
1805 } else {
1806 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1807 if (z == NULL) {
1808 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1811 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
1812 r->in.pszOperation,
1813 DNS_CLIENT_VERSION_W2K,
1814 r->out.pdwTypeId,
1815 r->out.ppData);
1818 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1819 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery, NDR_IN, r);
1821 return ret;
1824 static WERROR dcesrv_DnssrvComplexOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation *r)
1826 struct dnsserver_state *dsstate;
1827 struct dnsserver_zone *z;
1828 WERROR ret;
1830 ZERO_STRUCTP(r->out.pdwTypeOut);
1831 ZERO_STRUCTP(r->out.ppDataOut);
1833 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1834 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1837 if (r->in.pszZone == NULL) {
1838 /* Server operation */
1839 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
1840 r->in.pszOperation,
1841 DNS_CLIENT_VERSION_W2K,
1842 r->in.dwTypeIn,
1843 &r->in.pDataIn,
1844 r->out.pdwTypeOut,
1845 r->out.ppDataOut);
1846 } else {
1847 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1848 if (z == NULL) {
1849 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1852 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
1853 r->in.pszOperation,
1854 DNS_CLIENT_VERSION_W2K,
1855 r->in.dwTypeIn,
1856 &r->in.pDataIn,
1857 r->out.pdwTypeOut,
1858 r->out.ppDataOut);
1861 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1862 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation, NDR_IN, r);
1864 return ret;
1867 static WERROR dcesrv_DnssrvEnumRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords *r)
1869 struct dnsserver_state *dsstate;
1870 struct dnsserver_zone *z;
1871 WERROR ret;
1873 ZERO_STRUCTP(r->out.pdwBufferLength);
1874 ZERO_STRUCTP(r->out.pBuffer);
1876 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1877 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1880 if (r->in.pszZone == NULL) {
1881 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1884 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
1885 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
1886 DNS_CLIENT_VERSION_W2K,
1887 r->in.pszNodeName,
1888 r->in.wRecordType,
1889 r->in.fSelectFlag,
1890 r->out.pdwBufferLength,
1891 r->out.pBuffer);
1892 } else {
1893 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1894 if (z == NULL) {
1895 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1898 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
1899 DNS_CLIENT_VERSION_W2K,
1900 r->in.pszNodeName,
1901 r->in.pszStartChild,
1902 r->in.wRecordType,
1903 r->in.fSelectFlag,
1904 r->in.pszFilterStart,
1905 r->in.pszFilterStop,
1906 r->out.pdwBufferLength,
1907 r->out.pBuffer);
1910 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1911 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords, NDR_IN, r);
1913 return ret;
1916 static WERROR dcesrv_DnssrvUpdateRecord(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord *r)
1918 struct dnsserver_state *dsstate;
1919 struct dnsserver_zone *z;
1920 WERROR ret;
1922 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1923 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1926 if (r->in.pszZone == NULL) {
1927 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1930 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1931 if (z == NULL) {
1932 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1935 ret = dnsserver_update_record(dsstate, mem_ctx, z,
1936 DNS_CLIENT_VERSION_W2K,
1937 r->in.pszNodeName,
1938 r->in.pAddRecord,
1939 r->in.pDeleteRecord);
1941 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1942 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord, NDR_IN, r);
1944 return ret;
1947 static WERROR dcesrv_DnssrvOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation2 *r)
1949 struct dnsserver_state *dsstate;
1950 struct dnsserver_zone *z = NULL;
1951 uint32_t request_filter = 0;
1952 WERROR ret;
1954 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1955 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1958 if (r->in.dwContext == 0) {
1959 if (r->in.pszZone != NULL) {
1960 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
1962 } else {
1963 request_filter = r->in.dwContext;
1966 if (r->in.pszZone == NULL) {
1967 ret = dnsserver_operate_server(dsstate, mem_ctx,
1968 r->in.pszOperation,
1969 r->in.dwClientVersion,
1970 r->in.dwTypeId,
1971 &r->in.pData);
1972 } else {
1973 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
1974 request_filter,
1975 r->in.pszOperation,
1976 r->in.dwClientVersion,
1977 r->in.dwTypeId,
1978 &r->in.pData);
1981 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1982 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation2, NDR_IN, r);
1984 return ret;
1987 static WERROR dcesrv_DnssrvQuery2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery2 *r)
1989 struct dnsserver_state *dsstate;
1990 struct dnsserver_zone *z;
1991 WERROR ret;
1993 ZERO_STRUCTP(r->out.pdwTypeId);
1994 ZERO_STRUCTP(r->out.ppData);
1996 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1997 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2000 if (r->in.pszZone == NULL) {
2001 /* FIXME: DNS Server Configuration Access Control List */
2002 ret = dnsserver_query_server(dsstate, mem_ctx,
2003 r->in.pszOperation,
2004 r->in.dwClientVersion,
2005 r->out.pdwTypeId,
2006 r->out.ppData);
2007 } else {
2008 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2009 if (z == NULL) {
2010 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2013 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
2014 r->in.pszOperation,
2015 r->in.dwClientVersion,
2016 r->out.pdwTypeId,
2017 r->out.ppData);
2020 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2021 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery2, NDR_IN, r);
2023 return ret;
2026 static WERROR dcesrv_DnssrvComplexOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation2 *r)
2028 struct dnsserver_state *dsstate;
2029 struct dnsserver_zone *z;
2030 WERROR ret;
2032 ZERO_STRUCTP(r->out.pdwTypeOut);
2033 ZERO_STRUCTP(r->out.ppDataOut);
2035 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2036 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2039 if (r->in.pszZone == NULL) {
2040 /* Server operation */
2041 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
2042 r->in.pszOperation,
2043 r->in.dwClientVersion,
2044 r->in.dwTypeIn,
2045 &r->in.pDataIn,
2046 r->out.pdwTypeOut,
2047 r->out.ppDataOut);
2048 } else {
2050 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2051 if (z == NULL) {
2052 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2055 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2056 r->in.pszOperation,
2057 r->in.dwClientVersion,
2058 r->in.dwTypeIn,
2059 &r->in.pDataIn,
2060 r->out.pdwTypeOut,
2061 r->out.ppDataOut);
2064 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2065 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation2, NDR_IN, r);
2067 return ret;
2070 static WERROR dcesrv_DnssrvEnumRecords2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords2 *r)
2072 struct dnsserver_state *dsstate;
2073 struct dnsserver_zone *z;
2074 WERROR ret;
2076 ZERO_STRUCTP(r->out.pdwBufferLength);
2077 ZERO_STRUCTP(r->out.pBuffer);
2079 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2080 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2083 if (r->in.pszZone == NULL) {
2084 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2087 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
2088 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
2089 r->in.dwClientVersion,
2090 r->in.pszNodeName,
2091 r->in.wRecordType,
2092 r->in.fSelectFlag,
2093 r->out.pdwBufferLength,
2094 r->out.pBuffer);
2095 } else {
2096 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2097 if (z == NULL) {
2098 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2101 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2102 r->in.dwClientVersion,
2103 r->in.pszNodeName,
2104 r->in.pszStartChild,
2105 r->in.wRecordType,
2106 r->in.fSelectFlag,
2107 r->in.pszFilterStart,
2108 r->in.pszFilterStop,
2109 r->out.pdwBufferLength,
2110 r->out.pBuffer);
2114 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2115 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords2, NDR_IN, r);
2117 return ret;
2120 static WERROR dcesrv_DnssrvUpdateRecord2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord2 *r)
2122 struct dnsserver_state *dsstate;
2123 struct dnsserver_zone *z;
2124 WERROR ret;
2126 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2127 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2130 if (r->in.pszZone == NULL) {
2131 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2134 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2135 if (z == NULL) {
2136 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2139 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2140 r->in.dwClientVersion,
2141 r->in.pszNodeName,
2142 r->in.pAddRecord,
2143 r->in.pDeleteRecord);
2145 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2146 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord2, NDR_IN, r);
2148 return ret;
2151 /* include the generated boilerplate */
2152 #include "librpc/gen_ndr/ndr_dnsserver_s.c"