2 Unix SMB/CIFS implementation.
6 Copyright (C) Amitay Isaacs 2011
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "rpc_server/dcerpc_server.h"
25 #include "dsdb/samdb/samdb.h"
26 #include "lib/util/dlinklist.h"
27 #include "librpc/gen_ndr/ndr_dnsserver.h"
28 #include "dnsserver.h"
29 #include "lib/ldb/include/ldb_private.h"
31 struct dnsserver_state {
32 struct loadparm_context *lp_ctx;
33 struct ldb_context *samdb;
34 struct dnsserver_partition *partitions;
35 struct dnsserver_zone *zones;
37 struct dnsserver_serverinfo *serverinfo;
41 /* Utility functions */
43 static 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) {
54 dsstate = talloc_zero(dce_call->context, struct dnsserver_state);
55 if (dsstate == 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"));
69 /* Initialize server info */
70 dsstate->serverinfo = dnsserver_init_serverinfo(dsstate,
73 if (dsstate->serverinfo == NULL) {
77 /* Search for DNS partitions */
78 partitions = dnsserver_db_enumerate_partitions(dsstate, dsstate->serverinfo, dsstate->samdb);
79 if (partitions == NULL) {
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);
90 for (z = zones; z; ) {
92 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
93 if (z->zoneinfo == NULL) {
96 DLIST_ADD_END(dsstate->zones, z, NULL);
98 dsstate->zones_count++;
103 dce_call->context->private_data = dsstate;
108 talloc_free(dsstate);
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,
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;
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;
292 if (strcasecmp(operation, "AddressAnswerLimit") == 0) {
293 answer_integer = serverinfo->cAddressAnswerLimit;
295 } else if (strcasecmp(operation, "AdminConfigured") == 0) {
296 answer_integer = serverinfo->fAdminConfigured;
298 } else if (strcasecmp(operation, "AllowCNAMEAtNS") == 0) {
301 } else if (strcasecmp(operation, "AllowUpdate") == 0) {
302 answer_integer = serverinfo->fAllowUpdate;
304 } else if (strcasecmp(operation, "AutoCacheUpdate") == 0) {
305 answer_integer = serverinfo->fAutoCacheUpdate;
307 } else if (strcasecmp(operation, "AutoConfigFileZones") == 0) {
310 } else if (strcasecmp(operation, "BindSecondaries") == 0) {
311 answer_integer = serverinfo->fBindSecondaries;
313 } else if (strcasecmp(operation, "BootMethod") == 0) {
314 answer_integer = serverinfo->fBootMethod;
316 } else if (strcasecmp(operation, "DebugLevel") == 0) {
317 answer_integer = serverinfo->dwDebugLevel;
319 } else if (strcasecmp(operation, "DefaultAgingState") == 0) {
320 answer_integer = serverinfo->fDefaultAgingState;
322 } else if (strcasecmp(operation, "DefaultNoRefreshInterval") == 0) {
323 answer_integer = serverinfo->dwDefaultNoRefreshInterval;
325 } else if (strcasecmp(operation, "DefaultRefreshInterval") == 0) {
326 answer_integer = serverinfo->dwDefaultRefreshInterval;
328 } else if (strcasecmp(operation, "DeleteOutsideGlue") == 0) {
331 } else if (strcasecmp(operation, "DisjointNets") == 0) {
334 } else if (strcasecmp(operation, "DsLazyUpdateInterval") == 0) {
335 answer_integer = 3; /* seconds */
337 } else if (strcasecmp(operation, "DsPollingInterval") == 0) {
338 answer_integer = serverinfo->dwDsPollingInterval;
340 } else if (strcasecmp(operation, "DsTombstoneInterval") == 0) {
341 answer_integer = 0x00127500; /* 14 days */
343 } else if (strcasecmp(operation, "EnableRegistryBoot") == 0) {
346 } else if (strcasecmp(operation, "EventLogLevel") == 0) {
347 answer_integer = serverinfo->dwEventLogLevel;
349 } else if (strcasecmp(operation, "ForceSoaSerial") == 0) {
352 } else if (strcasecmp(operation, "ForceSaoRetry") == 0) {
355 } else if (strcasecmp(operation, "ForceSoaRefresh") == 0) {
358 } else if (strcasecmp(operation, "ForceSoaMinimumTtl") == 0) {
361 } else if (strcasecmp(operation, "ForwardDelegations") == 0) {
364 } else if (strcasecmp(operation, "ForwardingTimeout") == 0) {
365 answer_integer = serverinfo->dwForwardTimeout;
367 } else if (strcasecmp(operation, "IsSlave") == 0) {
370 } else if (strcasecmp(operation, "LocalNetPriority") == 0) {
371 answer_integer = serverinfo->fLocalNetPriority;
373 } else if (strcasecmp(operation, "LogFileMaxSize") == 0) {
374 answer_integer = serverinfo->dwLogFileMaxSize;
376 } else if (strcasecmp(operation, "LogLevel") == 0) {
377 answer_integer = serverinfo->dwLogLevel;
379 } else if (strcasecmp(operation, "LooseWildcarding") == 0) {
380 answer_integer = serverinfo->fLooseWildcarding;
382 } else if (strcasecmp(operation, "MaxCacheTtl") == 0) {
383 answer_integer = serverinfo->dwMaxCacheTtl;
385 } else if (strcasecmp(operation, "MaxNegativeCacheTtl") == 0) {
386 answer_integer = 0x00000384; /* 15 minutes */
388 } else if (strcasecmp(operation, "NameCheckFlag") == 0) {
389 answer_integer = serverinfo->dwNameCheckFlag;
391 } else if (strcasecmp(operation, "NoRecursion") == 0) {
392 answer_integer = serverinfo->fNoRecursion;
394 } else if (strcasecmp(operation, "NoUpdateDelegations") == 0) {
397 } else if (strcasecmp(operation, "PublishAutonet") == 0) {
400 } else if (strcasecmp(operation, "QuietRecvFaultInterval") == 0) {
403 } else if (strcasecmp(operation, "QuietRecvLogInterval") == 0) {
406 } else if (strcasecmp(operation, "RecursionRetry") == 0) {
407 answer_integer = serverinfo->dwRecursionRetry;
409 } else if (strcasecmp(operation, "RecursionTimeout") == 0) {
410 answer_integer = serverinfo->dwRecursionTimeout;
412 } else if (strcasecmp(operation, "ReloadException") == 0) {
415 } else if (strcasecmp(operation, "RoundRobin") == 0) {
416 answer_integer = serverinfo->fRoundRobin;
418 } else if (strcasecmp(operation, "RpcProtocol") == 0) {
419 answer_integer = serverinfo->dwRpcProtocol;
421 } else if (strcasecmp(operation, "SecureResponses") == 0) {
422 answer_integer = serverinfo->fSecureResponses;
424 } else if (strcasecmp(operation, "SendPort") == 0) {
427 } else if (strcasecmp(operation, "ScavengingInterval") == 0) {
428 answer_integer = serverinfo->dwScavengingInterval;
430 } else if (strcasecmp(operation, "SocketPoolSize") == 0) {
431 answer_integer = 0x000009C4;
433 } else if (strcasecmp(operation, "StrictFileParsing") == 0) {
434 answer_integer = serverinfo->fStrictFileParsing;
436 } else if (strcasecmp(operation, "SyncDnsZoneSerial") == 0) {
437 answer_integer = 2; /* ZONE_SERIAL_SYNC_XFER */
439 } else if (strcasecmp(operation, "UpdateOptions") == 0) {
440 answer_integer = 0x0000030F; /* DNS_DEFAULT_UPDATE_OPTIONS */
442 } else if (strcasecmp(operation, "UseSystemEvengLog") == 0) {
445 } else if (strcasecmp(operation, "Version") == 0) {
446 answer_integer = serverinfo->dwVersion;
448 } else if (strcasecmp(operation, "XfrConnectTimeout") == 0) {
449 answer_integer = 0x0000001E;
451 } else if (strcasecmp(operation, "WriteAuthorityNs") == 0) {
452 answer_integer = serverinfo->fWriteAuthorityNs;
454 } else if (strcasecmp(operation, "AdditionalRecursionTimeout") == 0) {
455 answer_integer = 0x00000004;
457 } else if (strcasecmp(operation, "AppendMsZoneTransferFlag") == 0) {
460 } else if (strcasecmp(operation, "AutoCreateDelegations") == 0) {
461 answer_integer = 0; /* DNS_ACD_DONT_CREATE */
463 } else if (strcasecmp(operation, "BreakOnAscFailure") == 0) {
466 } else if (strcasecmp(operation, "CacheEmptyAuthResponses") == 0) {
469 } else if (strcasecmp(operation, "DirectoryPartitionAutoEnlistInterval") == 0) {
470 answer_integer = 0x00015180; /* 1 day */
472 } else if (strcasecmp(operation, "DisableAutoReverseZones") == 0) {
473 answer_integer = ~serverinfo->fAutoReverseZones;
475 } else if (strcasecmp(operation, "EDnsCacheTimeout") == 0) {
476 answer_integer = 0x00000384; /* 15 minutes */
478 } else if (strcasecmp(operation, "EnableDirectoryPartitions") == 0) {
479 answer_integer = serverinfo->fDsAvailable;
481 } else if (strcasecmp(operation, "EnableDnsSec") == 0) {
484 } else if (strcasecmp(operation, "EnableEDnsProbes") == 0) {
487 } else if (strcasecmp(operation, "EnableEDnsReception") == 0) {
490 } else if (strcasecmp(operation, "EnableIPv6") == 0) {
493 } else if (strcasecmp(operation, "EnableIQueryResponseGeneration") == 0) {
496 } else if (strcasecmp(operation, "EnableSendErrorSuppression") == 0) {
499 } else if (strcasecmp(operation, "EnableUpdateForwarding") == 0) {
502 } else if (strcasecmp(operation, "EnableWinsR") == 0) {
505 } else if (strcasecmp(operation, "ForceDsaBehaviorVersion") == 0) {
506 answer_integer = serverinfo->dwDsDsaVersion;
508 } else if (strcasecmp(operation, "ForceDomainBehaviorVersion") == 0) {
509 answer_integer = serverinfo->dwDsDsaVersion;
511 } else if (strcasecmp(operation, "ForceForestBehaviorVersion") == 0) {
512 answer_integer = serverinfo->dwDsDsaVersion;
514 } else if (strcasecmp(operation, "HeapDebug") == 0) {
517 } else if (strcasecmp(operation, "LameDelegationTtl") == 0) {
518 answer_integer = 0; /* seconds */
520 } else if (strcasecmp(operation, "LocalNetPriorityNetMask") == 0) {
521 answer_integer = serverinfo->dwLocalNetPriorityNetMask;
523 } else if (strcasecmp(operation, "MaxCacheSize") == 0) {
526 } else if (strcasecmp(operation, "MaxResourceRecordsInNonSecureUpdate") == 0) {
527 answer_integer = 0x0000001E;
529 } else if (strcasecmp(operation, "OperationsLogLevel") == 0) {
532 } else if (strcasecmp(operation, "OperationsLogLevel2") == 0) {
535 } else if (strcasecmp(operation, "MaximumUdpPacketSize") == 0) {
536 answer_integer = 0x00004000; /* maximum possible */
538 } else if (strcasecmp(operation, "RecurseToInternetRootMask") == 0) {
541 } else if (strcasecmp(operation, "SelfTest") == 0) {
544 } else if (strcasecmp(operation, "SilentlyIgnoreCNameUpdateConflicts") == 0) {
547 } else if (strcasecmp(operation, "TcpReceivePacketSize") == 0) {
548 answer_integer = 0x00010000;
550 } else if (strcasecmp(operation, "XfrThrottleMultiplier") == 0) {
551 answer_integer = 0x0000000A;
553 } else if (strcasecmp(operation, "AllowMsdcsLookupRetry") == 0) {
556 } else if (strcasecmp(operation, "AllowReadOnlyZoneTransfer") == 0) {
559 } else if (strcasecmp(operation, "DsBackGroundLoadPaused") == 0) {
562 } else if (strcasecmp(operation, "DsMinimumBackgroundLoadThreads") == 0) {
565 } else if (strcasecmp(operation, "DsRemoteReplicationDelay") == 0) {
566 answer_integer = 0x0000001E; /* 30 seconds */
568 } else if (strcasecmp(operation, "EnableDuplicateQuerySuppresion") == 0) {
571 } else if (strcasecmp(operation, "EnableGlobalNamesSupport") == 0) {
574 } else if (strcasecmp(operation, "EnableVersionQuery") == 0) {
575 answer_integer = 1; /* DNS_VERSION_QUERY_FULL */
577 } else if (strcasecmp(operation, "EnableRsoForRodc") == 0) {
580 } else if (strcasecmp(operation, "ForceRODCMode") == 0) {
583 } else if (strcasecmp(operation, "GlobalNamesAlwaysQuerySrv") == 0) {
586 } else if (strcasecmp(operation, "GlobalNamesBlockUpdates") == 0) {
589 } else if (strcasecmp(operation, "GlobalNamesEnableEDnsProbes") == 0) {
592 } else if (strcasecmp(operation, "GlobalNamesPreferAAAA") == 0) {
595 } else if (strcasecmp(operation, "GlobalNamesQueryOrder") == 0) {
598 } else if (strcasecmp(operation, "GlobalNamesSendTimeout") == 0) {
599 answer_integer = 3; /* seconds */
601 } else if (strcasecmp(operation, "GlobalNamesServerQueryInterval") == 0) {
602 answer_integer = 0x00005460; /* 6 hours */
604 } else if (strcasecmp(operation, "RemoteIPv4RankBoost") == 0) {
607 } else if (strcasecmp(operation, "RemoteIPv6RankBoost") == 0) {
610 } else if (strcasecmp(operation, "MaximumRodcRsoAttemptsPerCycle") == 0) {
611 answer_integer = 0x00000064;
613 } else if (strcasecmp(operation, "MaximumRodcRsoQueueLength") == 0) {
614 answer_integer = 0x0000012C;
616 } else if (strcasecmp(operation, "EnableGlobalQueryBlockList") == 0) {
619 } else if (strcasecmp(operation, "OpenACLOnProxyUpdates") == 0) {
622 } else if (strcasecmp(operation, "CacheLockingPercent") == 0) {
623 answer_integer = 0x00000064;
627 if (is_integer == 1) {
628 *typeid = DNSSRV_TYPEID_DWORD;
629 r->Dword = answer_integer;
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);
639 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
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);
646 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipListenAddrs);
649 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
650 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
651 answer_addrarray = NULL;
653 answer_iparray = NULL;
656 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
657 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
658 answer_addrarray = NULL;
660 answer_iparray = NULL;
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);
667 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
672 if (is_addresses == 1) {
673 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
674 *typeid = DNSSRV_TYPEID_ADDRARRAY;
675 r->AddrArray = answer_addrarray;
677 *typeid = DNSSRV_TYPEID_IPARRAY;
678 r->IpArray = answer_iparray;
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;
691 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
692 answer_string = talloc_strdup(mem_ctx, "ForestDnsZones");
693 if (! answer_string) {
694 return WERR_OUTOFMEMORY;
697 } else if (strcasecmp(operation, "LogFilePath") == 0) {
698 answer_string = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
700 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
701 answer_string = NULL;
703 } else if (strcasecmp(operation, "DsBackgroundPauseName") == 0) {
704 answer_string = NULL;
706 } else if (strcasecmp(operation, "DsNotRoundRobinTypes") == 0) {
707 answer_string = NULL;
711 if (is_string == 1) {
712 *typeid = DNSSRV_TYPEID_LPSTR;
713 r->String = answer_string;
715 } else if (is_wstring == 1) {
716 *typeid = DNSSRV_TYPEID_LPWSTR;
717 r->WideString = answer_string;
723 if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
724 answer_stringlist = NULL;
726 } else if (strcasecmp(operation, "SocketPoolExcludedPortRanges") == 0) {
727 answer_stringlist = NULL;
731 if (is_stringlist == 1) {
732 *typeid = DNSSRV_TYPEID_UTF8_STRING_LIST;
733 r->Utf8StringList = answer_stringlist;
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,
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;
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;
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);
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;
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;
892 if (strcasecmp(operation, "AllowUpdate") == 0) {
893 answer_integer = zoneinfo->fAllowUpdate;
895 } else if (strcasecmp(operation, "Secured") == 0) {
898 } else if (strcasecmp(operation, "DsIntegrated") == 0) {
899 answer_integer = zoneinfo->fUseDatabase;
901 } else if (strcasecmp(operation, "LogUpdates") == 0) {
904 } else if (strcasecmp(operation, "NoRefreshInterval") == 0) {
905 answer_integer = zoneinfo->dwNoRefreshInterval;
907 } else if (strcasecmp(operation, "NotifyLevel") == 0) {
908 answer_integer = zoneinfo->fNotifyLevel;
910 } else if (strcasecmp(operation, "RefreshInterval") == 0) {
911 answer_integer = zoneinfo->dwRefreshInterval;
913 } else if (strcasecmp(operation, "SecureSecondaries") == 0) {
914 answer_integer = zoneinfo->fSecureSecondaries;
916 } else if (strcasecmp(operation, "Type") == 0) {
917 answer_integer = zoneinfo->dwZoneType;
919 } else if (strcasecmp(operation, "Aging") == 0) {
920 answer_integer = zoneinfo->fAging;
922 } else if (strcasecmp(operation, "ForwarderSlave") == 0) {
923 answer_integer = zoneinfo->fForwarderSlave;
925 } else if (strcasecmp(operation, "ForwarderTimeout") == 0) {
926 answer_integer = zoneinfo->dwForwarderTimeout;
928 } else if (strcasecmp(operation, "Unicode") == 0) {
933 if (is_integer == 1) {
934 *typeid = DNSSRV_TYPEID_DWORD;
935 r->Dword = answer_integer;
941 if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
942 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
943 answer_addrarray = NULL;
945 answer_iparray = NULL;
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);
952 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
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);
959 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
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);
966 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
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);
973 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
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);
980 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
985 if (is_addresses == 1) {
986 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
987 *typeid = DNSSRV_TYPEID_ADDRARRAY;
988 r->AddrArray = answer_addrarray;
990 *typeid = DNSSRV_TYPEID_IPARRAY;
991 r->IpArray = answer_iparray;
998 if (strcasecmp(operation, "DatabaseFile") == 0) {
999 answer_string = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
1001 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1002 answer_string = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
1004 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1005 answer_string = NULL;
1009 if (is_string == 1) {
1010 *typeid = DNSSRV_TYPEID_LPSTR;
1011 r->String = answer_string;
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;
1109 bool found1, found2, found3, found4;
1112 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1113 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1114 return dnsserver_query_server(dsstate, mem_ctx,
1120 } else if (strcasecmp(operation, "EnumZones") == 0) {
1121 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1122 return WERR_DNS_ERROR_INVALID_PROPERTY;
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
1139 if (rin->Dword & 0x0000000f) {
1140 if (rin->Dword & DNS_ZONE_REQUEST_PRIMARY) {
1141 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_PRIMARY) {
1145 if (rin->Dword & DNS_ZONE_REQUEST_SECONDARY) {
1146 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_SECONDARY) {
1150 if (rin->Dword & DNS_ZONE_REQUEST_CACHE) {
1151 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_CACHE) {
1155 if (rin->Dword & DNS_ZONE_REQUEST_AUTO) {
1156 if (z->zoneinfo->fAutoCreated
1157 || z->partition->dwDpFlags & DNS_DP_AUTOCREATED) {
1167 if (rin->Dword & 0x000000f0) {
1168 if (rin->Dword & DNS_ZONE_REQUEST_FORWARD) {
1169 if (!(z->zoneinfo->fReverse)) {
1173 if (rin->Dword & DNS_ZONE_REQUEST_REVERSE) {
1174 if (z->zoneinfo->fReverse) {
1178 if (rin->Dword & DNS_ZONE_REQUEST_FORWARDER) {
1179 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_FORWARDER) {
1183 if (rin->Dword & DNS_ZONE_REQUEST_STUB) {
1184 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_STUB) {
1194 if (rin->Dword & 0x00000f00) {
1195 if (rin->Dword & DNS_ZONE_REQUEST_DS) {
1196 if (z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED) {
1200 if (rin->Dword & DNS_ZONE_REQUEST_NON_DS) {
1201 if (!(z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED)) {
1205 if (rin->Dword & DNS_ZONE_REQUEST_DOMAIN_DP) {
1206 if (!(z->partition->dwDpFlags & DNS_DP_DOMAIN_DEFAULT)) {
1210 if (rin->Dword & DNS_ZONE_REQUEST_FOREST_DP) {
1211 if (!(z->partition->dwDpFlags & DNS_DP_FOREST_DEFAULT)) {
1220 if (rin->Dword & 0x0000f000) {
1226 if (found1 && found2 && found3 && found4) {
1227 zlist = talloc_realloc(mem_ctx, zlist, struct dnsserver_zone *, zcount+1);
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);
1238 rout->ZoneListW2K->dwZoneCount = 0;
1239 rout->ZoneListW2K->ZoneArray = NULL;
1244 rout->ZoneListW2K->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_W2K *, zcount);
1245 if (rout->ZoneListW2K->ZoneArray == NULL) {
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;
1261 *typeid_out = DNSSRV_TYPEID_ZONE_LIST;
1262 rout->ZoneList = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_DOTNET);
1265 rout->ZoneList->dwRpcStructureVersion = 1;
1266 rout->ZoneList->dwZoneCount = 0;
1267 rout->ZoneList->ZoneArray = NULL;
1272 rout->ZoneList->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_DOTNET *, zcount);
1273 if (rout->ZoneList->ZoneArray == NULL) {
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;
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;
1308 struct DNS_RPC_DP_ENUM **dplist;
1309 struct dnsserver_partition *p;
1312 dplist = talloc_zero_array(mem_ctx, struct DNS_RPC_DP_ENUM *, pcount);
1313 if (dplist == NULL) {
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;
1327 rout->DirectoryPartitionList->dwDpCount = pcount;
1328 rout->DirectoryPartitionList->DpArray = dplist;
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,
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 struct dnsserver_zone *z;
1461 const char * const attrs[] = { "name", "dnsRecord", NULL };
1462 struct ldb_result *res;
1463 struct DNS_RPC_RECORDS_ARRAY *recs;
1470 tmp_ctx = talloc_new(mem_ctx);
1471 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1473 z = dnsserver_find_zone(dsstate->zones, ".");
1475 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1478 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1479 LDB_SCOPE_ONELEVEL, attrs, "(&(objectClass=dnsNode)(name=@))");
1480 if (ret != LDB_SUCCESS) {
1481 talloc_free(tmp_ctx);
1482 return WERR_INTERNAL_DB_ERROR;
1484 if (res->count == 0) {
1485 talloc_free(tmp_ctx);
1486 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1489 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1490 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1495 for (i=0; i<res->count; i++) {
1496 status = dns_fill_records_array(tmp_ctx, NULL, record_type,
1498 res->msgs[i], 0, recs,
1499 &add_names, &add_count);
1500 if (!W_ERROR_IS_OK(status)) {
1501 talloc_free(tmp_ctx);
1507 /* Add any additional records */
1508 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1509 for (i=0; i<add_count; i++) {
1510 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1511 LDB_SCOPE_ONELEVEL, attrs,
1512 "(&(objectClass=dnsNode)(name=%s))", add_names[i]);
1513 if (ret != LDB_SUCCESS || res->count == 0) {
1518 len = strlen(add_names[i]);
1519 if (add_names[i][len-1] == '.') {
1520 rname = talloc_strdup(tmp_ctx, add_names[i]);
1522 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1524 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1526 res->msgs[0], 0, recs,
1533 talloc_free(tmp_ctx);
1535 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1542 static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
1543 TALLOC_CTX *mem_ctx,
1544 struct dnsserver_zone *z,
1545 unsigned int client_version,
1546 const char *node_name,
1547 const char *start_child,
1548 enum dns_record_type record_type,
1549 unsigned int select_flag,
1550 const char *filter_start,
1551 const char *filter_stop,
1552 unsigned int *buffer_length,
1553 struct DNS_RPC_RECORDS_ARRAY **buffer)
1555 TALLOC_CTX *tmp_ctx;
1557 const char * const attrs[] = { "name", "dnsRecord", NULL };
1558 struct ldb_result *res;
1559 struct DNS_RPC_RECORDS_ARRAY *recs;
1560 char **add_names = NULL;
1565 struct dns_tree *tree, *base, *node;
1567 tmp_ctx = talloc_new(mem_ctx);
1568 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1570 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1571 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1573 /* search all records under parent tree */
1574 if (strcmp(name, z->name) == 0) {
1575 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1576 LDB_SCOPE_ONELEVEL, attrs, "(objectClass=dnsNode)");
1578 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1579 LDB_SCOPE_ONELEVEL, attrs,
1580 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s)))",
1583 if (ret != LDB_SUCCESS) {
1584 talloc_free(tmp_ctx);
1585 return WERR_INTERNAL_DB_ERROR;
1587 if (res->count == 0) {
1588 talloc_free(tmp_ctx);
1589 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1592 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1593 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1595 /* Sort the names, so that the first record is the parent record */
1596 ldb_qsort(res->msgs, res->count, sizeof(struct ldb_message *), name,
1597 (ldb_qsort_cmp_fn_t)dns_name_compare);
1599 /* Build a tree of name components from dns name */
1600 if (strcmp(name, z->name) == 0) {
1601 tree = dns_build_tree(tmp_ctx, "@", res);
1603 tree = dns_build_tree(tmp_ctx, name, res);
1605 W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree, tmp_ctx);
1607 /* Find the parent record in the tree */
1609 while (base->level != -1) {
1610 base = base->children[0];
1613 /* Add the parent record with blank name */
1614 if (!(select_flag & DNS_RPC_VIEW_ONLY_CHILDREN)) {
1615 status = dns_fill_records_array(tmp_ctx, z, record_type,
1618 recs, &add_names, &add_count);
1619 if (!W_ERROR_IS_OK(status)) {
1620 talloc_free(tmp_ctx);
1625 /* Add all the children records */
1626 if (!(select_flag & DNS_RPC_VIEW_NO_CHILDREN)) {
1627 for (i=0; i<base->num_children; i++) {
1628 node = base->children[i];
1630 status = dns_fill_records_array(tmp_ctx, z, record_type,
1631 select_flag, node->name,
1632 node->data, node->num_children,
1633 recs, &add_names, &add_count);
1634 if (!W_ERROR_IS_OK(status)) {
1635 talloc_free(tmp_ctx);
1645 /* Add any additional records */
1646 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1647 for (i=0; i<add_count; i++) {
1648 struct dnsserver_zone *z2;
1650 /* Search all the available zones for additional name */
1651 for (z2 = dsstate->zones; z2; z2 = z2->next) {
1652 name = dns_split_node_name(tmp_ctx, add_names[i], z2->name);
1653 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z2->zone_dn,
1654 LDB_SCOPE_ONELEVEL, attrs,
1655 "(&(objectClass=dnsNode)(name=%s))", name);
1657 if (ret != LDB_SUCCESS) {
1660 if (res->count == 1) {
1668 len = strlen(add_names[i]);
1669 if (add_names[i][len-1] == '.') {
1670 rname = talloc_strdup(tmp_ctx, add_names[i]);
1672 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1674 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1676 res->msgs[0], 0, recs,
1683 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1689 /* dnsserver update function */
1691 static WERROR dnsserver_update_record(struct dnsserver_state *dsstate,
1692 TALLOC_CTX *mem_ctx,
1693 struct dnsserver_zone *z,
1694 unsigned int client_version,
1695 const char *node_name,
1696 struct DNS_RPC_RECORD_BUF *add_buf,
1697 struct DNS_RPC_RECORD_BUF *del_buf)
1699 TALLOC_CTX *tmp_ctx;
1703 tmp_ctx = talloc_new(mem_ctx);
1704 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1706 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1707 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1709 if (add_buf != NULL) {
1710 if (del_buf == NULL) {
1712 status = dnsserver_db_add_record(tmp_ctx, dsstate->samdb,
1717 status = dnsserver_db_update_record(tmp_ctx, dsstate->samdb,
1723 if (del_buf == NULL) {
1724 /* Add empty node */
1725 status = dnsserver_db_add_empty_node(tmp_ctx, dsstate->samdb,
1729 status = dnsserver_db_delete_record(tmp_ctx, dsstate->samdb,
1735 talloc_free(tmp_ctx);
1740 /* dnsserver interface functions */
1742 static WERROR dcesrv_DnssrvOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation *r)
1744 struct dnsserver_state *dsstate;
1745 struct dnsserver_zone *z = NULL;
1746 uint32_t request_filter = 0;
1749 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1750 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1753 if (r->in.dwContext == 0) {
1754 if (r->in.pszZone != NULL) {
1755 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
1758 request_filter = r->in.dwContext;
1761 if (r->in.pszZone == NULL) {
1762 ret = dnsserver_operate_server(dsstate, mem_ctx,
1764 DNS_CLIENT_VERSION_W2K,
1768 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
1771 DNS_CLIENT_VERSION_W2K,
1776 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1777 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation, NDR_IN, r);
1782 static WERROR dcesrv_DnssrvQuery(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery *r)
1784 struct dnsserver_state *dsstate;
1785 struct dnsserver_zone *z;
1788 ZERO_STRUCTP(r->out.pdwTypeId);
1789 ZERO_STRUCTP(r->out.ppData);
1791 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1792 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1795 if (r->in.pszZone == NULL) {
1796 /* FIXME: DNS Server Configuration Access Control List */
1797 ret = dnsserver_query_server(dsstate, mem_ctx,
1799 DNS_CLIENT_VERSION_W2K,
1803 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1805 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1808 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
1810 DNS_CLIENT_VERSION_W2K,
1815 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1816 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery, NDR_IN, r);
1821 static WERROR dcesrv_DnssrvComplexOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation *r)
1823 struct dnsserver_state *dsstate;
1824 struct dnsserver_zone *z;
1827 ZERO_STRUCTP(r->out.pdwTypeOut);
1828 ZERO_STRUCTP(r->out.ppDataOut);
1830 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1831 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1834 if (r->in.pszZone == NULL) {
1835 /* Server operation */
1836 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
1838 DNS_CLIENT_VERSION_W2K,
1844 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1846 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1849 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
1851 DNS_CLIENT_VERSION_W2K,
1858 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1859 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation, NDR_IN, r);
1864 static WERROR dcesrv_DnssrvEnumRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords *r)
1866 struct dnsserver_state *dsstate;
1867 struct dnsserver_zone *z;
1870 ZERO_STRUCTP(r->out.pdwBufferLength);
1871 ZERO_STRUCTP(r->out.pBuffer);
1873 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1874 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1877 if (r->in.pszZone == NULL) {
1878 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1881 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
1882 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
1883 DNS_CLIENT_VERSION_W2K,
1887 r->out.pdwBufferLength,
1890 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1892 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1895 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
1896 DNS_CLIENT_VERSION_W2K,
1898 r->in.pszStartChild,
1901 r->in.pszFilterStart,
1902 r->in.pszFilterStop,
1903 r->out.pdwBufferLength,
1907 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1908 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords, NDR_IN, r);
1913 static WERROR dcesrv_DnssrvUpdateRecord(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord *r)
1915 struct dnsserver_state *dsstate;
1916 struct dnsserver_zone *z;
1919 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1920 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1923 if (r->in.pszZone == NULL) {
1924 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1927 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1929 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1932 ret = dnsserver_update_record(dsstate, mem_ctx, z,
1933 DNS_CLIENT_VERSION_W2K,
1936 r->in.pDeleteRecord);
1938 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1939 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord, NDR_IN, r);
1944 static WERROR dcesrv_DnssrvOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation2 *r)
1946 struct dnsserver_state *dsstate;
1947 struct dnsserver_zone *z = NULL;
1948 uint32_t request_filter = 0;
1951 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1952 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1955 if (r->in.dwContext == 0) {
1956 if (r->in.pszZone != NULL) {
1957 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
1960 request_filter = r->in.dwContext;
1963 if (r->in.pszZone == NULL) {
1964 ret = dnsserver_operate_server(dsstate, mem_ctx,
1966 r->in.dwClientVersion,
1970 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
1973 r->in.dwClientVersion,
1978 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1979 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation2, NDR_IN, r);
1984 static WERROR dcesrv_DnssrvQuery2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery2 *r)
1986 struct dnsserver_state *dsstate;
1987 struct dnsserver_zone *z;
1990 ZERO_STRUCTP(r->out.pdwTypeId);
1991 ZERO_STRUCTP(r->out.ppData);
1993 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1994 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1997 if (r->in.pszZone == NULL) {
1998 /* FIXME: DNS Server Configuration Access Control List */
1999 ret = dnsserver_query_server(dsstate, mem_ctx,
2001 r->in.dwClientVersion,
2005 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2007 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2010 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
2012 r->in.dwClientVersion,
2017 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2018 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery2, NDR_IN, r);
2023 static WERROR dcesrv_DnssrvComplexOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation2 *r)
2025 struct dnsserver_state *dsstate;
2026 struct dnsserver_zone *z;
2029 ZERO_STRUCTP(r->out.pdwTypeOut);
2030 ZERO_STRUCTP(r->out.ppDataOut);
2032 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2033 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2036 if (r->in.pszZone == NULL) {
2037 /* Server operation */
2038 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
2040 r->in.dwClientVersion,
2047 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2049 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2052 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2054 r->in.dwClientVersion,
2061 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2062 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation2, NDR_IN, r);
2067 static WERROR dcesrv_DnssrvEnumRecords2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords2 *r)
2069 struct dnsserver_state *dsstate;
2070 struct dnsserver_zone *z;
2073 ZERO_STRUCTP(r->out.pdwBufferLength);
2074 ZERO_STRUCTP(r->out.pBuffer);
2076 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2077 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2080 if (r->in.pszZone == NULL) {
2081 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2084 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
2085 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
2086 r->in.dwClientVersion,
2090 r->out.pdwBufferLength,
2093 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2095 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2098 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2099 r->in.dwClientVersion,
2101 r->in.pszStartChild,
2104 r->in.pszFilterStart,
2105 r->in.pszFilterStop,
2106 r->out.pdwBufferLength,
2111 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2112 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords2, NDR_IN, r);
2117 static WERROR dcesrv_DnssrvUpdateRecord2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord2 *r)
2119 struct dnsserver_state *dsstate;
2120 struct dnsserver_zone *z;
2123 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2124 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2127 if (r->in.pszZone == NULL) {
2128 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2131 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2133 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2136 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2137 r->in.dwClientVersion,
2140 r->in.pDeleteRecord);
2142 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2143 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord2, NDR_IN, r);
2148 /* include the generated boilerplate */
2149 #include "librpc/gen_ndr/ndr_dnsserver_s.c"