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 valid_operation = true;
1298 } else if (strcasecmp(operation, "DirectoryPartitionInfo") == 0) {
1299 valid_operation = true;
1300 } else if (strcasecmp(operation, "Statistics") == 0) {
1301 valid_operation = true;
1302 } else if (strcasecmp(operation, "IpValidate") == 0) {
1303 valid_operation = true;
1306 if (valid_operation) {
1307 DEBUG(0, ("dnsserver: server complex operation '%s' not implemented", operation));
1308 return WERR_CALL_NOT_IMPLEMENTED;
1311 DEBUG(0, ("dnsserver: invalid server complex operation '%s'", operation));
1312 return WERR_DNS_ERROR_INVALID_PROPERTY;
1315 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
1316 static WERROR dnsserver_operate_zone(struct dnsserver_state *dsstate,
1317 TALLOC_CTX *mem_ctx,
1318 struct dnsserver_zone *z,
1319 unsigned int request_filter,
1320 const char *operation,
1321 const unsigned int client_version,
1322 enum DNS_RPC_TYPEID typeid,
1323 union DNSSRV_RPC_UNION *r)
1325 bool valid_operation = false;
1327 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1328 valid_operation = true;
1329 } else if (strcasecmp(operation, "ZoneTypeReset") == 0) {
1330 valid_operation = true;
1331 } else if (strcasecmp(operation, "PauseZone") == 0) {
1332 valid_operation = true;
1333 } else if (strcasecmp(operation, "ResumeZone") == 0) {
1334 valid_operation = true;
1335 } else if (strcasecmp(operation, "DeleteZone") == 0) {
1336 valid_operation = true;
1337 } else if (strcasecmp(operation, "ReloadZone") == 0) {
1338 valid_operation = true;
1339 } else if (strcasecmp(operation, "RefreshZone") == 0) {
1340 valid_operation = true;
1341 } else if (strcasecmp(operation, "ExpireZone") == 0) {
1342 valid_operation = true;
1343 } else if (strcasecmp(operation, "IncrementVersion") == 0) {
1344 valid_operation = true;
1345 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1346 valid_operation = true;
1347 } else if (strcasecmp(operation, "DeleteZoneFromDs") == 0) {
1348 valid_operation = true;
1349 } else if (strcasecmp(operation, "UpdateZoneFromDs") == 0) {
1350 valid_operation = true;
1351 } else if (strcasecmp(operation, "ZoneExport") == 0) {
1352 valid_operation = true;
1353 } else if (strcasecmp(operation, "ZoneChangeDirectoryPartition") == 0) {
1354 valid_operation = true;
1355 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1356 valid_operation = true;
1357 } else if (strcasecmp(operation, "DeleteRecordSet") == 0) {
1358 valid_operation = true;
1359 } else if (strcasecmp(operation, "ForceAgingOnNode") == 0) {
1360 valid_operation = true;
1361 } else if (strcasecmp(operation, "DatabaseFile") == 0) {
1362 valid_operation = true;
1363 } else if (strcasecmp(operation, "MasterServers") == 0) {
1364 valid_operation = true;
1365 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
1366 valid_operation = true;
1367 } else if (strcasecmp(operation, "NotifyServers") == 0) {
1368 valid_operation = true;
1369 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
1370 valid_operation = true;
1371 } else if (strcasecmp(operation, "ScavengingServers") == 0) {
1372 valid_operation = true;
1373 } else if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
1374 valid_operation = true;
1375 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1376 valid_operation = true;
1377 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1378 valid_operation = true;
1381 if (valid_operation) {
1382 DEBUG(0, ("dnsserver: zone operation '%s' not implemented", operation));
1383 return WERR_CALL_NOT_IMPLEMENTED;
1386 DEBUG(0, ("dnsserver: invalid zone operation '%s'", operation));
1387 return WERR_DNS_ERROR_INVALID_PROPERTY;
1390 static WERROR dnsserver_complex_operate_zone(struct dnsserver_state *dsstate,
1391 TALLOC_CTX *mem_ctx,
1392 struct dnsserver_zone *z,
1393 const char *operation,
1394 const unsigned int client_version,
1395 enum DNS_RPC_TYPEID typeid_in,
1396 union DNSSRV_RPC_UNION *rin,
1397 enum DNS_RPC_TYPEID *typeid_out,
1398 union DNSSRV_RPC_UNION *rout)
1400 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1401 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1402 return dnsserver_query_zone(dsstate, mem_ctx, z,
1411 DEBUG(0,("dnsserver: Invalid zone operation %s", operation));
1412 return WERR_DNS_ERROR_INVALID_PROPERTY;
1415 /* dnsserver enumerate function */
1417 static WERROR dnsserver_enumerate_root_records(struct dnsserver_state *dsstate,
1418 TALLOC_CTX *mem_ctx,
1419 unsigned int client_version,
1420 const char *node_name,
1421 enum dns_record_type record_type,
1422 unsigned int select_flag,
1423 unsigned int *buffer_length,
1424 struct DNS_RPC_RECORDS_ARRAY **buffer)
1426 TALLOC_CTX *tmp_ctx;
1427 const char * const attrs[] = { "name", "dnsRecord", NULL };
1428 struct ldb_result *res;
1430 struct DNS_RPC_RECORDS_ARRAY *recs;
1437 tmp_ctx = talloc_new(mem_ctx);
1438 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1440 dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(dsstate->samdb));
1441 W_ERROR_HAVE_NO_MEMORY_AND_FREE(dn, tmp_ctx);
1443 if (!ldb_dn_add_child_fmt(dn, "DC=RootDNSServers,CN=MicrosoftDNS,DC=DomainDnsZones")) {
1444 talloc_free(tmp_ctx);
1448 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, dn,
1449 LDB_SCOPE_ONELEVEL, attrs, "(&(objectClass=dnsNode)(name=@))");
1450 if (ret != LDB_SUCCESS) {
1451 talloc_free(tmp_ctx);
1452 return WERR_INTERNAL_DB_ERROR;
1454 if (res->count == 0) {
1455 talloc_free(tmp_ctx);
1456 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1459 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1460 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1465 for (i=0; i<res->count; i++) {
1466 status = dns_fill_records_array(tmp_ctx, NULL, record_type,
1468 res->msgs[i], 0, recs,
1469 &add_names, &add_count);
1470 if (!W_ERROR_IS_OK(status)) {
1471 talloc_free(tmp_ctx);
1477 /* Add any additional records */
1478 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1479 for (i=0; i<add_count; i++) {
1480 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, dn,
1481 LDB_SCOPE_ONELEVEL, attrs,
1482 "(&(objectClass=dnsNode)(name=%s))", add_names[i]);
1483 if (ret != LDB_SUCCESS || res->count == 0) {
1488 len = strlen(add_names[i]);
1489 if (add_names[i][len-1] == '.') {
1490 rname = talloc_strdup(tmp_ctx, add_names[i]);
1492 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1494 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1496 res->msgs[0], 0, recs,
1503 talloc_free(tmp_ctx);
1505 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1512 static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
1513 TALLOC_CTX *mem_ctx,
1514 struct dnsserver_zone *z,
1515 unsigned int client_version,
1516 const char *node_name,
1517 const char *start_child,
1518 enum dns_record_type record_type,
1519 unsigned int select_flag,
1520 const char *filter_start,
1521 const char *filter_stop,
1522 unsigned int *buffer_length,
1523 struct DNS_RPC_RECORDS_ARRAY **buffer)
1525 TALLOC_CTX *tmp_ctx;
1527 const char * const attrs[] = { "name", "dnsRecord", NULL };
1528 struct ldb_result *res;
1529 struct DNS_RPC_RECORDS_ARRAY *recs;
1530 char **add_names = NULL;
1535 struct dns_tree *tree, *base, *node;
1537 tmp_ctx = talloc_new(mem_ctx);
1538 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1540 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1541 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1543 /* search all records under parent tree */
1544 if (strcmp(name, z->name) == 0) {
1545 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1546 LDB_SCOPE_ONELEVEL, attrs, "(objectClass=dnsNode)");
1548 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1549 LDB_SCOPE_ONELEVEL, attrs,
1550 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s)))",
1553 if (ret != LDB_SUCCESS) {
1554 talloc_free(tmp_ctx);
1555 return WERR_INTERNAL_DB_ERROR;
1557 if (res->count == 0) {
1558 talloc_free(tmp_ctx);
1559 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1562 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1563 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1565 /* Sort the names, so that the first record is the parent record */
1566 ldb_qsort(res->msgs, res->count, sizeof(struct ldb_message *), name,
1567 (ldb_qsort_cmp_fn_t)dns_name_compare);
1569 /* Build a tree of name components from dns name */
1570 if (strcmp(name, z->name) == 0) {
1571 tree = dns_build_tree(tmp_ctx, "@", res);
1573 tree = dns_build_tree(tmp_ctx, name, res);
1575 W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree, tmp_ctx);
1577 /* Find the parent record in the tree */
1579 while (base->level != -1) {
1580 base = base->children[0];
1583 /* Add the parent record with blank name */
1584 if (!(select_flag & DNS_RPC_VIEW_ONLY_CHILDREN)) {
1585 status = dns_fill_records_array(tmp_ctx, z, record_type,
1588 recs, &add_names, &add_count);
1589 if (!W_ERROR_IS_OK(status)) {
1590 talloc_free(tmp_ctx);
1595 /* Add all the children records */
1596 if (!(select_flag & DNS_RPC_VIEW_NO_CHILDREN)) {
1597 for (i=0; i<base->num_children; i++) {
1598 node = base->children[i];
1600 status = dns_fill_records_array(tmp_ctx, z, record_type,
1601 select_flag, node->name,
1602 node->data, node->num_children,
1603 recs, &add_names, &add_count);
1604 if (!W_ERROR_IS_OK(status)) {
1605 talloc_free(tmp_ctx);
1615 /* Add any additional records */
1616 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1617 for (i=0; i<add_count; i++) {
1618 struct dnsserver_zone *z2;
1620 /* Search all the available zones for additional name */
1621 for (z2 = dsstate->zones; z2; z2 = z2->next) {
1622 name = dns_split_node_name(tmp_ctx, add_names[i], z2->name);
1623 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z2->zone_dn,
1624 LDB_SCOPE_ONELEVEL, attrs,
1625 "(&(objectClass=dnsNode)(name=%s))", name);
1627 if (ret != LDB_SUCCESS) {
1630 if (res->count == 1) {
1638 len = strlen(add_names[i]);
1639 if (add_names[i][len-1] == '.') {
1640 rname = talloc_strdup(tmp_ctx, add_names[i]);
1642 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1644 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1646 res->msgs[0], 0, recs,
1653 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1659 /* dnsserver update function */
1661 static WERROR dnsserver_update_record(struct dnsserver_state *dsstate,
1662 TALLOC_CTX *mem_ctx,
1663 struct dnsserver_zone *z,
1664 unsigned int client_version,
1665 const char *node_name,
1666 struct DNS_RPC_RECORD_BUF *add_buf,
1667 struct DNS_RPC_RECORD_BUF *del_buf)
1669 TALLOC_CTX *tmp_ctx;
1673 tmp_ctx = talloc_new(mem_ctx);
1674 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1676 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1677 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1679 if (add_buf != NULL) {
1680 if (del_buf == NULL) {
1682 status = dnsserver_db_add_record(tmp_ctx, dsstate->samdb,
1687 status = dnsserver_db_update_record(tmp_ctx, dsstate->samdb,
1693 if (del_buf == NULL) {
1694 /* Add empty node */
1695 status = dnsserver_db_add_empty_node(tmp_ctx, dsstate->samdb,
1699 status = dnsserver_db_delete_record(tmp_ctx, dsstate->samdb,
1705 talloc_free(tmp_ctx);
1710 /* dnsserver interface functions */
1712 static WERROR dcesrv_DnssrvOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation *r)
1714 struct dnsserver_state *dsstate;
1715 struct dnsserver_zone *z = NULL;
1716 uint32_t request_filter = 0;
1719 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1720 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1723 if (r->in.dwContext == 0) {
1724 if (r->in.pszZone != NULL) {
1725 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
1728 request_filter = r->in.dwContext;
1731 if (r->in.pszZone == NULL) {
1732 ret = dnsserver_operate_server(dsstate, mem_ctx,
1734 DNS_CLIENT_VERSION_W2K,
1738 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
1741 DNS_CLIENT_VERSION_W2K,
1746 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1747 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation, NDR_IN, r);
1752 static WERROR dcesrv_DnssrvQuery(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery *r)
1754 struct dnsserver_state *dsstate;
1755 struct dnsserver_zone *z;
1758 ZERO_STRUCTP(r->out.pdwTypeId);
1759 ZERO_STRUCTP(r->out.ppData);
1761 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1762 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1765 if (r->in.pszZone == NULL) {
1766 /* FIXME: DNS Server Configuration Access Control List */
1767 ret = dnsserver_query_server(dsstate, mem_ctx,
1769 DNS_CLIENT_VERSION_W2K,
1773 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1775 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1778 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
1780 DNS_CLIENT_VERSION_W2K,
1785 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1786 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery, NDR_IN, r);
1791 static WERROR dcesrv_DnssrvComplexOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation *r)
1793 struct dnsserver_state *dsstate;
1794 struct dnsserver_zone *z;
1797 ZERO_STRUCTP(r->out.pdwTypeOut);
1798 ZERO_STRUCTP(r->out.ppDataOut);
1800 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1801 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1804 if (r->in.pszZone == NULL) {
1805 /* Server operation */
1806 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
1808 DNS_CLIENT_VERSION_W2K,
1814 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1816 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1819 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
1821 DNS_CLIENT_VERSION_W2K,
1828 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1829 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation, NDR_IN, r);
1834 static WERROR dcesrv_DnssrvEnumRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords *r)
1836 struct dnsserver_state *dsstate;
1837 struct dnsserver_zone *z;
1840 ZERO_STRUCTP(r->out.pdwBufferLength);
1841 ZERO_STRUCTP(r->out.pBuffer);
1843 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1844 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1847 if (r->in.pszZone == NULL) {
1848 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1851 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
1852 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
1853 DNS_CLIENT_VERSION_W2K,
1857 r->out.pdwBufferLength,
1860 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1862 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1865 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
1866 DNS_CLIENT_VERSION_W2K,
1868 r->in.pszStartChild,
1871 r->in.pszFilterStart,
1872 r->in.pszFilterStop,
1873 r->out.pdwBufferLength,
1877 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1878 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords, NDR_IN, r);
1883 static WERROR dcesrv_DnssrvUpdateRecord(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord *r)
1885 struct dnsserver_state *dsstate;
1886 struct dnsserver_zone *z;
1889 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1890 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1893 if (r->in.pszZone == NULL) {
1894 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1897 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1899 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1902 ret = dnsserver_update_record(dsstate, mem_ctx, z,
1903 DNS_CLIENT_VERSION_W2K,
1906 r->in.pDeleteRecord);
1908 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1909 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord, NDR_IN, r);
1914 static WERROR dcesrv_DnssrvOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation2 *r)
1916 struct dnsserver_state *dsstate;
1917 struct dnsserver_zone *z = NULL;
1918 uint32_t request_filter = 0;
1921 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1922 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1925 if (r->in.dwContext == 0) {
1926 if (r->in.pszZone != NULL) {
1927 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
1930 request_filter = r->in.dwContext;
1933 if (r->in.pszZone == NULL) {
1934 ret = dnsserver_operate_server(dsstate, mem_ctx,
1936 r->in.dwClientVersion,
1940 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
1943 r->in.dwClientVersion,
1948 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1949 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation2, NDR_IN, r);
1954 static WERROR dcesrv_DnssrvQuery2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery2 *r)
1956 struct dnsserver_state *dsstate;
1957 struct dnsserver_zone *z;
1960 ZERO_STRUCTP(r->out.pdwTypeId);
1961 ZERO_STRUCTP(r->out.ppData);
1963 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1964 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1967 if (r->in.pszZone == NULL) {
1968 /* FIXME: DNS Server Configuration Access Control List */
1969 ret = dnsserver_query_server(dsstate, mem_ctx,
1971 r->in.dwClientVersion,
1975 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1977 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1980 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
1982 r->in.dwClientVersion,
1987 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1988 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery2, NDR_IN, r);
1993 static WERROR dcesrv_DnssrvComplexOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation2 *r)
1995 struct dnsserver_state *dsstate;
1996 struct dnsserver_zone *z;
1999 ZERO_STRUCTP(r->out.pdwTypeOut);
2000 ZERO_STRUCTP(r->out.ppDataOut);
2002 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2003 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2006 if (r->in.pszZone == NULL) {
2007 /* Server operation */
2008 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
2010 r->in.dwClientVersion,
2017 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2019 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2022 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2024 r->in.dwClientVersion,
2031 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2032 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation2, NDR_IN, r);
2037 static WERROR dcesrv_DnssrvEnumRecords2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords2 *r)
2039 struct dnsserver_state *dsstate;
2040 struct dnsserver_zone *z;
2043 ZERO_STRUCTP(r->out.pdwBufferLength);
2044 ZERO_STRUCTP(r->out.pBuffer);
2046 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2047 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2050 if (r->in.pszZone == NULL) {
2051 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2054 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
2055 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
2056 r->in.dwClientVersion,
2060 r->out.pdwBufferLength,
2063 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2065 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2068 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2069 r->in.dwClientVersion,
2071 r->in.pszStartChild,
2074 r->in.pszFilterStart,
2075 r->in.pszFilterStop,
2076 r->out.pdwBufferLength,
2081 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2082 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords2, NDR_IN, r);
2087 static WERROR dcesrv_DnssrvUpdateRecord2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord2 *r)
2089 struct dnsserver_state *dsstate;
2090 struct dnsserver_zone *z;
2093 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2094 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2097 if (r->in.pszZone == NULL) {
2098 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2101 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2103 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2106 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2107 r->in.dwClientVersion,
2110 r->in.pDeleteRecord);
2112 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2113 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord2, NDR_IN, r);
2118 /* include the generated boilerplate */
2119 #include "librpc/gen_ndr/ndr_dnsserver_s.c"