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_zone *zones;
36 struct dnsserver_serverinfo *serverinfo;
40 /* Utility functions */
42 static struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_call)
44 struct dnsserver_state *dsstate;
45 struct dnsserver_zone *zones, *z;
47 dsstate = talloc_get_type(dce_call->context->private_data, struct dnsserver_state);
48 if (dsstate != NULL) {
52 dsstate = talloc_zero(dce_call->context, struct dnsserver_state);
53 if (dsstate == NULL) {
57 dsstate->lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
59 /* FIXME: create correct auth_session_info for connecting user */
60 dsstate->samdb = samdb_connect(dsstate, dce_call->event_ctx, dsstate->lp_ctx,
61 dce_call->conn->auth_state.session_info, 0);
62 if (dsstate->samdb == NULL) {
63 DEBUG(0,("dnsserver: Failed to open samdb"));
67 /* Initialize server info */
68 dsstate->serverinfo = dnsserver_init_serverinfo(dsstate,
71 if (dsstate->serverinfo == NULL) {
75 /* Search for DNS zones */
76 zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, true);
80 for (z = zones; z; z = z->next) {
81 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo, true);
82 if (z->zoneinfo == NULL) {
85 DLIST_ADD_END(dsstate->zones, z, NULL);
86 dsstate->zones_count++;
89 zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, false);
93 for (z = zones; z; z = z->next) {
94 z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo, false);
95 if (z->zoneinfo == NULL) {
98 DLIST_ADD_END(dsstate->zones, z, NULL);
99 dsstate->zones_count++;
102 dce_call->context->private_data = dsstate;
107 talloc_free(dsstate);
113 /* dnsserver query functions */
115 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
116 static WERROR dnsserver_query_server(struct dnsserver_state *dsstate,
118 const char *operation,
119 const unsigned int client_version,
120 enum DNS_RPC_TYPEID *typeid,
121 union DNSSRV_RPC_UNION *r)
123 uint8_t is_integer, is_addresses, is_string, is_wstring, is_stringlist;
124 uint32_t answer_integer;
125 struct IP4_ARRAY *answer_iparray;
126 struct DNS_ADDR_ARRAY *answer_addrarray;
128 struct DNS_RPC_UTF8_STRING_LIST *answer_stringlist;
129 struct dnsserver_serverinfo *serverinfo;
131 serverinfo = dsstate->serverinfo;
133 if (strcasecmp(operation, "ServerInfo") == 0) {
134 if (client_version == DNS_CLIENT_VERSION_W2K) {
135 *typeid = DNSSRV_TYPEID_SERVER_INFO_W2K;
136 r->ServerInfoW2K = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_W2K);
138 r->ServerInfoW2K->dwVersion = serverinfo->dwVersion;
139 r->ServerInfoW2K->fBootMethod = serverinfo->fBootMethod;
140 r->ServerInfoW2K->fAdminConfigured = serverinfo->fAdminConfigured;
141 r->ServerInfoW2K->fAllowUpdate = serverinfo->fAllowUpdate;
142 r->ServerInfoW2K->fDsAvailable = serverinfo->fDsAvailable;
143 r->ServerInfoW2K->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
144 r->ServerInfoW2K->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
145 r->ServerInfoW2K->aipServerAddrs = ip4_array_copy(mem_ctx, serverinfo->aipServerAddrs);
146 r->ServerInfoW2K->aipListenAddrs = ip4_array_copy(mem_ctx, serverinfo->aipListenAddrs);
147 r->ServerInfoW2K->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
148 r->ServerInfoW2K->dwLogLevel = serverinfo->dwLogLevel;
149 r->ServerInfoW2K->dwDebugLevel = serverinfo->dwDebugLevel;
150 r->ServerInfoW2K->dwForwardTimeout = serverinfo->dwForwardTimeout;
151 r->ServerInfoW2K->dwRpcProtocol = serverinfo->dwRpcProtocol;
152 r->ServerInfoW2K->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
153 r->ServerInfoW2K->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
154 r->ServerInfoW2K->dwRecursionRetry = serverinfo->dwRecursionRetry;
155 r->ServerInfoW2K->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
156 r->ServerInfoW2K->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
157 r->ServerInfoW2K->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
158 r->ServerInfoW2K->dwScavengingInterval = serverinfo->dwScavengingInterval;
159 r->ServerInfoW2K->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
160 r->ServerInfoW2K->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
161 r->ServerInfoW2K->fAutoReverseZones = serverinfo->fAutoReverseZones;
162 r->ServerInfoW2K->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
163 r->ServerInfoW2K->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
164 r->ServerInfoW2K->fForwardDelegations = serverinfo->fForwardDelegations;
165 r->ServerInfoW2K->fNoRecursion = serverinfo->fNoRecursion;
166 r->ServerInfoW2K->fSecureResponses = serverinfo->fSecureResponses;
167 r->ServerInfoW2K->fRoundRobin = serverinfo->fRoundRobin;
168 r->ServerInfoW2K->fLocalNetPriority = serverinfo->fLocalNetPriority;
169 r->ServerInfoW2K->fBindSecondaries = serverinfo->fBindSecondaries;
170 r->ServerInfoW2K->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
171 r->ServerInfoW2K->fStrictFileParsing = serverinfo->fStrictFileParsing;
172 r->ServerInfoW2K->fLooseWildcarding = serverinfo->fLooseWildcarding;
173 r->ServerInfoW2K->fDefaultAgingState = serverinfo->fDefaultAgingState;
175 } else if (client_version == DNS_CLIENT_VERSION_DOTNET) {
176 *typeid = DNSSRV_TYPEID_SERVER_INFO_DOTNET;
177 r->ServerInfoDotNet = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_DOTNET);
179 r->ServerInfoDotNet->dwRpcStructureVersion = 0x01;
180 r->ServerInfoDotNet->dwVersion = serverinfo->dwVersion;
181 r->ServerInfoDotNet->fBootMethod = serverinfo->fBootMethod;
182 r->ServerInfoDotNet->fAdminConfigured = serverinfo->fAdminConfigured;
183 r->ServerInfoDotNet->fAllowUpdate = serverinfo->fAllowUpdate;
184 r->ServerInfoDotNet->fDsAvailable = serverinfo->fDsAvailable;
185 r->ServerInfoDotNet->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
186 r->ServerInfoDotNet->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
187 r->ServerInfoDotNet->aipServerAddrs = ip4_array_copy(mem_ctx, serverinfo->aipServerAddrs);
188 r->ServerInfoDotNet->aipListenAddrs = ip4_array_copy(mem_ctx, serverinfo->aipListenAddrs);
189 r->ServerInfoDotNet->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
190 r->ServerInfoDotNet->aipLogFilter = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
191 r->ServerInfoDotNet->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
192 r->ServerInfoDotNet->pszDomainName = talloc_strdup(mem_ctx, serverinfo->pszDomainName);
193 r->ServerInfoDotNet->pszForestName = talloc_strdup(mem_ctx, serverinfo->pszForestName);
194 r->ServerInfoDotNet->pszDomainDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszDomainDirectoryPartition);
195 r->ServerInfoDotNet->pszForestDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszForestDirectoryPartition);
196 r->ServerInfoDotNet->dwLogLevel = serverinfo->dwLogLevel;
197 r->ServerInfoDotNet->dwDebugLevel = serverinfo->dwDebugLevel;
198 r->ServerInfoDotNet->dwForwardTimeout = serverinfo->dwForwardTimeout;
199 r->ServerInfoDotNet->dwRpcProtocol = serverinfo->dwRpcProtocol;
200 r->ServerInfoDotNet->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
201 r->ServerInfoDotNet->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
202 r->ServerInfoDotNet->dwRecursionRetry = serverinfo->dwRecursionRetry;
203 r->ServerInfoDotNet->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
204 r->ServerInfoDotNet->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
205 r->ServerInfoDotNet->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
206 r->ServerInfoDotNet->dwLocalNetPriorityNetMask = serverinfo->dwLocalNetPriorityNetMask;
207 r->ServerInfoDotNet->dwScavengingInterval = serverinfo->dwScavengingInterval;
208 r->ServerInfoDotNet->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
209 r->ServerInfoDotNet->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
210 r->ServerInfoDotNet->dwLastScavengeTime = serverinfo->dwLastScavengeTime;
211 r->ServerInfoDotNet->dwEventLogLevel = serverinfo->dwEventLogLevel;
212 r->ServerInfoDotNet->dwLogFileMaxSize = serverinfo->dwLogFileMaxSize;
213 r->ServerInfoDotNet->dwDsForestVersion = serverinfo->dwDsForestVersion;
214 r->ServerInfoDotNet->dwDsDomainVersion = serverinfo->dwDsDomainVersion;
215 r->ServerInfoDotNet->dwDsDsaVersion = serverinfo->dwDsDsaVersion;
216 r->ServerInfoDotNet->fAutoReverseZones = serverinfo->fAutoReverseZones;
217 r->ServerInfoDotNet->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
218 r->ServerInfoDotNet->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
219 r->ServerInfoDotNet->fForwardDelegations = serverinfo->fForwardDelegations;
220 r->ServerInfoDotNet->fNoRecursion = serverinfo->fNoRecursion;
221 r->ServerInfoDotNet->fSecureResponses = serverinfo->fSecureResponses;
222 r->ServerInfoDotNet->fRoundRobin = serverinfo->fRoundRobin;
223 r->ServerInfoDotNet->fLocalNetPriority = serverinfo->fLocalNetPriority;
224 r->ServerInfoDotNet->fBindSecondaries = serverinfo->fBindSecondaries;
225 r->ServerInfoDotNet->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
226 r->ServerInfoDotNet->fStrictFileParsing = serverinfo->fStrictFileParsing;
227 r->ServerInfoDotNet->fLooseWildcarding = serverinfo->fLooseWildcarding;
228 r->ServerInfoDotNet->fDefaultAgingState = serverinfo->fDefaultAgingState;
230 } else if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
231 *typeid = DNSSRV_TYPEID_SERVER_INFO;
232 r->ServerInfo = talloc_zero(mem_ctx, struct DNS_RPC_SERVER_INFO_LONGHORN);
234 r->ServerInfo->dwRpcStructureVersion = 0x02;
235 r->ServerInfo->dwVersion = serverinfo->dwVersion;
236 r->ServerInfo->fBootMethod = serverinfo->fBootMethod;
237 r->ServerInfo->fAdminConfigured = serverinfo->fAdminConfigured;
238 r->ServerInfo->fAllowUpdate = serverinfo->fAllowUpdate;
239 r->ServerInfo->fDsAvailable = serverinfo->fDsAvailable;
240 r->ServerInfo->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName);
241 r->ServerInfo->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer);
242 r->ServerInfo->aipServerAddrs = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipServerAddrs);
243 r->ServerInfo->aipListenAddrs = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipListenAddrs);
244 r->ServerInfo->aipForwarders = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders);
245 r->ServerInfo->aipLogFilter = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter);
246 r->ServerInfo->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
247 r->ServerInfo->pszDomainName = talloc_strdup(mem_ctx, serverinfo->pszDomainName);
248 r->ServerInfo->pszForestName = talloc_strdup(mem_ctx, serverinfo->pszForestName);
249 r->ServerInfo->pszDomainDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszDomainDirectoryPartition);
250 r->ServerInfo->pszForestDirectoryPartition = talloc_strdup(mem_ctx, serverinfo->pszForestDirectoryPartition);
251 r->ServerInfo->dwLogLevel = serverinfo->dwLogLevel;
252 r->ServerInfo->dwDebugLevel = serverinfo->dwDebugLevel;
253 r->ServerInfo->dwForwardTimeout = serverinfo->dwForwardTimeout;
254 r->ServerInfo->dwRpcProtocol = serverinfo->dwRpcProtocol;
255 r->ServerInfo->dwNameCheckFlag = serverinfo->dwNameCheckFlag;
256 r->ServerInfo->cAddressAnswerLimit = serverinfo->cAddressAnswerLimit;
257 r->ServerInfo->dwRecursionRetry = serverinfo->dwRecursionRetry;
258 r->ServerInfo->dwRecursionTimeout = serverinfo->dwRecursionTimeout;
259 r->ServerInfo->dwMaxCacheTtl = serverinfo->dwMaxCacheTtl;
260 r->ServerInfo->dwDsPollingInterval = serverinfo->dwDsPollingInterval;
261 r->ServerInfo->dwLocalNetPriorityNetMask = serverinfo->dwLocalNetPriorityNetMask;
262 r->ServerInfo->dwScavengingInterval = serverinfo->dwScavengingInterval;
263 r->ServerInfo->dwDefaultRefreshInterval = serverinfo->dwDefaultRefreshInterval;
264 r->ServerInfo->dwDefaultNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
265 r->ServerInfo->dwLastScavengeTime = serverinfo->dwLastScavengeTime;
266 r->ServerInfo->dwEventLogLevel = serverinfo->dwEventLogLevel;
267 r->ServerInfo->dwLogFileMaxSize = serverinfo->dwLogFileMaxSize;
268 r->ServerInfo->dwDsForestVersion = serverinfo->dwDsForestVersion;
269 r->ServerInfo->dwDsDomainVersion = serverinfo->dwDsDomainVersion;
270 r->ServerInfo->dwDsDsaVersion = serverinfo->dwDsDsaVersion;
271 r->ServerInfo->fReadOnlyDC = serverinfo->fReadOnlyDC;
272 r->ServerInfo->fAutoReverseZones = serverinfo->fAutoReverseZones;
273 r->ServerInfo->fAutoCacheUpdate = serverinfo->fAutoCacheUpdate;
274 r->ServerInfo->fRecurseAfterForwarding = serverinfo->fRecurseAfterForwarding;
275 r->ServerInfo->fForwardDelegations = serverinfo->fForwardDelegations;
276 r->ServerInfo->fNoRecursion = serverinfo->fNoRecursion;
277 r->ServerInfo->fSecureResponses = serverinfo->fSecureResponses;
278 r->ServerInfo->fRoundRobin = serverinfo->fRoundRobin;
279 r->ServerInfo->fLocalNetPriority = serverinfo->fLocalNetPriority;
280 r->ServerInfo->fBindSecondaries = serverinfo->fBindSecondaries;
281 r->ServerInfo->fWriteAuthorityNs = serverinfo->fWriteAuthorityNs;
282 r->ServerInfo->fStrictFileParsing = serverinfo->fStrictFileParsing;
283 r->ServerInfo->fLooseWildcarding = serverinfo->fLooseWildcarding;
284 r->ServerInfo->fDefaultAgingState = serverinfo->fDefaultAgingState;
291 if (strcasecmp(operation, "AddressAnswerLimit") == 0) {
292 answer_integer = serverinfo->cAddressAnswerLimit;
294 } else if (strcasecmp(operation, "AdminConfigured") == 0) {
295 answer_integer = serverinfo->fAdminConfigured;
297 } else if (strcasecmp(operation, "AllowCNAMEAtNS") == 0) {
300 } else if (strcasecmp(operation, "AllowUpdate") == 0) {
301 answer_integer = serverinfo->fAllowUpdate;
303 } else if (strcasecmp(operation, "AutoCacheUpdate") == 0) {
304 answer_integer = serverinfo->fAutoCacheUpdate;
306 } else if (strcasecmp(operation, "AutoConfigFileZones") == 0) {
309 } else if (strcasecmp(operation, "BindSecondaries") == 0) {
310 answer_integer = serverinfo->fBindSecondaries;
312 } else if (strcasecmp(operation, "BootMethod") == 0) {
313 answer_integer = serverinfo->fBootMethod;
315 } else if (strcasecmp(operation, "DebugLevel") == 0) {
316 answer_integer = serverinfo->dwDebugLevel;
318 } else if (strcasecmp(operation, "DefaultAgingState") == 0) {
319 answer_integer = serverinfo->fDefaultAgingState;
321 } else if (strcasecmp(operation, "DefaultNoRefreshInterval") == 0) {
322 answer_integer = serverinfo->dwDefaultNoRefreshInterval;
324 } else if (strcasecmp(operation, "DefaultRefreshInterval") == 0) {
325 answer_integer = serverinfo->dwDefaultRefreshInterval;
327 } else if (strcasecmp(operation, "DeleteOutsideGlue") == 0) {
330 } else if (strcasecmp(operation, "DisjointNets") == 0) {
333 } else if (strcasecmp(operation, "DsLazyUpdateInterval") == 0) {
334 answer_integer = 3; /* seconds */
336 } else if (strcasecmp(operation, "DsPollingInterval") == 0) {
337 answer_integer = serverinfo->dwDsPollingInterval;
339 } else if (strcasecmp(operation, "DsTombstoneInterval") == 0) {
340 answer_integer = 0x00127500; /* 14 days */
342 } else if (strcasecmp(operation, "EnableRegistryBoot") == 0) {
345 } else if (strcasecmp(operation, "EventLogLevel") == 0) {
346 answer_integer = serverinfo->dwEventLogLevel;
348 } else if (strcasecmp(operation, "ForceSoaSerial") == 0) {
351 } else if (strcasecmp(operation, "ForceSaoRetry") == 0) {
354 } else if (strcasecmp(operation, "ForceSoaRefresh") == 0) {
357 } else if (strcasecmp(operation, "ForceSoaMinimumTtl") == 0) {
360 } else if (strcasecmp(operation, "ForwardDelegations") == 0) {
363 } else if (strcasecmp(operation, "ForwardingTimeout") == 0) {
364 answer_integer = serverinfo->dwForwardTimeout;
366 } else if (strcasecmp(operation, "IsSlave") == 0) {
369 } else if (strcasecmp(operation, "LocalNetPriority") == 0) {
370 answer_integer = serverinfo->fLocalNetPriority;
372 } else if (strcasecmp(operation, "LogFileMaxSize") == 0) {
373 answer_integer = serverinfo->dwLogFileMaxSize;
375 } else if (strcasecmp(operation, "LogLevel") == 0) {
376 answer_integer = serverinfo->dwLogLevel;
378 } else if (strcasecmp(operation, "LooseWildcarding") == 0) {
379 answer_integer = serverinfo->fLooseWildcarding;
381 } else if (strcasecmp(operation, "MaxCacheTtl") == 0) {
382 answer_integer = serverinfo->dwMaxCacheTtl;
384 } else if (strcasecmp(operation, "MaxNegativeCacheTtl") == 0) {
385 answer_integer = 0x00000384; /* 15 minutes */
387 } else if (strcasecmp(operation, "NameCheckFlag") == 0) {
388 answer_integer = serverinfo->dwNameCheckFlag;
390 } else if (strcasecmp(operation, "NoRecursion") == 0) {
391 answer_integer = serverinfo->fNoRecursion;
393 } else if (strcasecmp(operation, "NoUpdateDelegations") == 0) {
396 } else if (strcasecmp(operation, "PublishAutonet") == 0) {
399 } else if (strcasecmp(operation, "QuietRecvFaultInterval") == 0) {
402 } else if (strcasecmp(operation, "QuietRecvLogInterval") == 0) {
405 } else if (strcasecmp(operation, "RecursionRetry") == 0) {
406 answer_integer = serverinfo->dwRecursionRetry;
408 } else if (strcasecmp(operation, "RecursionTimeout") == 0) {
409 answer_integer = serverinfo->dwRecursionTimeout;
411 } else if (strcasecmp(operation, "ReloadException") == 0) {
414 } else if (strcasecmp(operation, "RoundRobin") == 0) {
415 answer_integer = serverinfo->fRoundRobin;
417 } else if (strcasecmp(operation, "RpcProtocol") == 0) {
418 answer_integer = serverinfo->dwRpcProtocol;
420 } else if (strcasecmp(operation, "SecureResponses") == 0) {
421 answer_integer = serverinfo->fSecureResponses;
423 } else if (strcasecmp(operation, "SendPort") == 0) {
426 } else if (strcasecmp(operation, "ScavengingInterval") == 0) {
427 answer_integer = serverinfo->dwScavengingInterval;
429 } else if (strcasecmp(operation, "SocketPoolSize") == 0) {
430 answer_integer = 0x000009C4;
432 } else if (strcasecmp(operation, "StrictFileParsing") == 0) {
433 answer_integer = serverinfo->fStrictFileParsing;
435 } else if (strcasecmp(operation, "SyncDnsZoneSerial") == 0) {
436 answer_integer = 2; /* ZONE_SERIAL_SYNC_XFER */
438 } else if (strcasecmp(operation, "UpdateOptions") == 0) {
439 answer_integer = 0x0000030F; /* DNS_DEFAULT_UPDATE_OPTIONS */
441 } else if (strcasecmp(operation, "UseSystemEvengLog") == 0) {
444 } else if (strcasecmp(operation, "Version") == 0) {
445 answer_integer = serverinfo->dwVersion;
447 } else if (strcasecmp(operation, "XfrConnectTimeout") == 0) {
448 answer_integer = 0x0000001E;
450 } else if (strcasecmp(operation, "WriteAuthorityNs") == 0) {
451 answer_integer = serverinfo->fWriteAuthorityNs;
453 } else if (strcasecmp(operation, "AdditionalRecursionTimeout") == 0) {
454 answer_integer = 0x00000004;
456 } else if (strcasecmp(operation, "AppendMsZoneTransferFlag") == 0) {
459 } else if (strcasecmp(operation, "AutoCreateDelegations") == 0) {
460 answer_integer = 0; /* DNS_ACD_DONT_CREATE */
462 } else if (strcasecmp(operation, "BreakOnAscFailure") == 0) {
465 } else if (strcasecmp(operation, "CacheEmptyAuthResponses") == 0) {
468 } else if (strcasecmp(operation, "DirectoryPartitionAutoEnlistInterval") == 0) {
469 answer_integer = 0x00015180; /* 1 day */
471 } else if (strcasecmp(operation, "DisableAutoReverseZones") == 0) {
472 answer_integer = ~serverinfo->fAutoReverseZones;
474 } else if (strcasecmp(operation, "EDnsCacheTimeout") == 0) {
475 answer_integer = 0x00000384; /* 15 minutes */
477 } else if (strcasecmp(operation, "EnableDirectoryPartitions") == 0) {
478 answer_integer = serverinfo->fDsAvailable;
480 } else if (strcasecmp(operation, "EnableDnsSec") == 0) {
483 } else if (strcasecmp(operation, "EnableEDnsProbes") == 0) {
486 } else if (strcasecmp(operation, "EnableEDnsReception") == 0) {
489 } else if (strcasecmp(operation, "EnableIPv6") == 0) {
492 } else if (strcasecmp(operation, "EnableIQueryResponseGeneration") == 0) {
495 } else if (strcasecmp(operation, "EnableSendErrorSuppression") == 0) {
498 } else if (strcasecmp(operation, "EnableUpdateForwarding") == 0) {
501 } else if (strcasecmp(operation, "EnableWinsR") == 0) {
504 } else if (strcasecmp(operation, "ForceDsaBehaviorVersion") == 0) {
505 answer_integer = serverinfo->dwDsDsaVersion;
507 } else if (strcasecmp(operation, "ForceDomainBehaviorVersion") == 0) {
508 answer_integer = serverinfo->dwDsDsaVersion;
510 } else if (strcasecmp(operation, "ForceForestBehaviorVersion") == 0) {
511 answer_integer = serverinfo->dwDsDsaVersion;
513 } else if (strcasecmp(operation, "HeapDebug") == 0) {
516 } else if (strcasecmp(operation, "LameDelegationTtl") == 0) {
517 answer_integer = 0; /* seconds */
519 } else if (strcasecmp(operation, "LocalNetPriorityNetMask") == 0) {
520 answer_integer = serverinfo->dwLocalNetPriorityNetMask;
522 } else if (strcasecmp(operation, "MaxCacheSize") == 0) {
525 } else if (strcasecmp(operation, "MaxResourceRecordsInNonSecureUpdate") == 0) {
526 answer_integer = 0x0000001E;
528 } else if (strcasecmp(operation, "OperationsLogLevel") == 0) {
531 } else if (strcasecmp(operation, "OperationsLogLevel2") == 0) {
534 } else if (strcasecmp(operation, "MaximumUdpPacketSize") == 0) {
535 answer_integer = 0x00004000; /* maximum possible */
537 } else if (strcasecmp(operation, "RecurseToInternetRootMask") == 0) {
540 } else if (strcasecmp(operation, "SelfTest") == 0) {
543 } else if (strcasecmp(operation, "SilentlyIgnoreCNameUpdateConflicts") == 0) {
546 } else if (strcasecmp(operation, "TcpReceivePacketSize") == 0) {
547 answer_integer = 0x00010000;
549 } else if (strcasecmp(operation, "XfrThrottleMultiplier") == 0) {
550 answer_integer = 0x0000000A;
552 } else if (strcasecmp(operation, "AllowMsdcsLookupRetry") == 0) {
555 } else if (strcasecmp(operation, "AllowReadOnlyZoneTransfer") == 0) {
558 } else if (strcasecmp(operation, "DsBackGroundLoadPaused") == 0) {
561 } else if (strcasecmp(operation, "DsMinimumBackgroundLoadThreads") == 0) {
564 } else if (strcasecmp(operation, "DsRemoteReplicationDelay") == 0) {
565 answer_integer = 0x0000001E; /* 30 seconds */
567 } else if (strcasecmp(operation, "EnableDuplicateQuerySuppresion") == 0) {
570 } else if (strcasecmp(operation, "EnableGlobalNamesSupport") == 0) {
573 } else if (strcasecmp(operation, "EnableVersionQuery") == 0) {
574 answer_integer = 1; /* DNS_VERSION_QUERY_FULL */
576 } else if (strcasecmp(operation, "EnableRsoForRodc") == 0) {
579 } else if (strcasecmp(operation, "ForceRODCMode") == 0) {
582 } else if (strcasecmp(operation, "GlobalNamesAlwaysQuerySrv") == 0) {
585 } else if (strcasecmp(operation, "GlobalNamesBlockUpdates") == 0) {
588 } else if (strcasecmp(operation, "GlobalNamesEnableEDnsProbes") == 0) {
591 } else if (strcasecmp(operation, "GlobalNamesPreferAAAA") == 0) {
594 } else if (strcasecmp(operation, "GlobalNamesQueryOrder") == 0) {
597 } else if (strcasecmp(operation, "GlobalNamesSendTimeout") == 0) {
598 answer_integer = 3; /* seconds */
600 } else if (strcasecmp(operation, "GlobalNamesServerQueryInterval") == 0) {
601 answer_integer = 0x00005460; /* 6 hours */
603 } else if (strcasecmp(operation, "RemoteIPv4RankBoost") == 0) {
606 } else if (strcasecmp(operation, "RemoteIPv6RankBoost") == 0) {
609 } else if (strcasecmp(operation, "MaximumRodcRsoAttemptsPerCycle") == 0) {
610 answer_integer = 0x00000064;
612 } else if (strcasecmp(operation, "MaximumRodcRsoQueueLength") == 0) {
613 answer_integer = 0x0000012C;
615 } else if (strcasecmp(operation, "EnableGlobalQueryBlockList") == 0) {
618 } else if (strcasecmp(operation, "OpenACLOnProxyUpdates") == 0) {
621 } else if (strcasecmp(operation, "CacheLockingPercent") == 0) {
622 answer_integer = 0x00000064;
626 if (is_integer == 1) {
627 *typeid = DNSSRV_TYPEID_DWORD;
628 r->Dword = answer_integer;
634 if (strcasecmp(operation, "Forwarders") == 0) {
635 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
636 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders);
638 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipForwarders);
641 } else if (strcasecmp(operation, "ListenAddresses") == 0) {
642 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
643 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipListenAddrs);
645 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipListenAddrs);
648 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
649 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
650 answer_addrarray = NULL;
652 answer_iparray = NULL;
655 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
656 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
657 answer_addrarray = NULL;
659 answer_iparray = NULL;
662 } else if (strcasecmp(operation, "LogIPFilterList") == 0) {
663 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
664 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter);
666 answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter);
671 if (is_addresses == 1) {
672 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
673 *typeid = DNSSRV_TYPEID_ADDRARRAY;
674 r->AddrArray = answer_addrarray;
676 *typeid = DNSSRV_TYPEID_IPARRAY;
677 r->IpArray = answer_iparray;
682 is_string = is_wstring = 0;
684 if (strcasecmp(operation, "DomainDirectoryPartitionBaseName") == 0) {
685 answer_string = talloc_strdup(mem_ctx, "DomainDnsZones");
686 if (! answer_string) {
687 return WERR_OUTOFMEMORY;
690 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
691 answer_string = talloc_strdup(mem_ctx, "ForestDnsZones");
692 if (! answer_string) {
693 return WERR_OUTOFMEMORY;
696 } else if (strcasecmp(operation, "LogFilePath") == 0) {
697 answer_string = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath);
699 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
700 answer_string = NULL;
702 } else if (strcasecmp(operation, "DsBackgroundPauseName") == 0) {
703 answer_string = NULL;
705 } else if (strcasecmp(operation, "DsNotRoundRobinTypes") == 0) {
706 answer_string = NULL;
710 if (is_string == 1) {
711 *typeid = DNSSRV_TYPEID_LPSTR;
712 r->String = answer_string;
714 } else if (is_wstring == 1) {
715 *typeid = DNSSRV_TYPEID_LPWSTR;
716 r->WideString = answer_string;
722 if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
723 answer_stringlist = NULL;
725 } else if (strcasecmp(operation, "SocketPoolExcludedPortRanges") == 0) {
726 answer_stringlist = NULL;
730 if (is_stringlist == 1) {
731 *typeid = DNSSRV_TYPEID_UTF8_STRING_LIST;
732 r->Utf8StringList = answer_stringlist;
736 DEBUG(0,("dnsserver: Invalid server operation %s", operation));
737 return WERR_DNS_ERROR_INVALID_PROPERTY;
740 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
741 static WERROR dnsserver_query_zone(struct dnsserver_state *dsstate,
743 struct dnsserver_zone *z,
744 const char *operation,
745 const unsigned int client_version,
746 enum DNS_RPC_TYPEID *typeid,
747 union DNSSRV_RPC_UNION *r)
749 uint8_t is_integer, is_addresses, is_string;
750 uint32_t answer_integer;
751 struct IP4_ARRAY *answer_iparray;
752 struct DNS_ADDR_ARRAY *answer_addrarray;
754 struct dnsserver_zoneinfo *zoneinfo;
756 zoneinfo = z->zoneinfo;
758 if (strcasecmp(operation, "Zone") == 0) {
759 if (client_version == DNS_CLIENT_VERSION_W2K) {
760 *typeid = DNSSRV_TYPEID_ZONE_W2K;
761 r->ZoneW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
763 r->ZoneW2K->pszZoneName = talloc_strdup(mem_ctx, z->name);
764 r->ZoneW2K->Flags = zoneinfo->Flags;
765 r->ZoneW2K->ZoneType = zoneinfo->dwZoneType;
766 r->ZoneW2K->Version = zoneinfo->Version;
768 *typeid = DNSSRV_TYPEID_ZONE;
769 r->Zone = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
771 r->Zone->dwRpcStructureVersion = 0x01;
772 r->Zone->pszZoneName = talloc_strdup(mem_ctx, z->name);
773 r->Zone->Flags = zoneinfo->Flags;
774 r->Zone->ZoneType = zoneinfo->dwZoneType;
775 r->Zone->Version = zoneinfo->Version;
776 r->Zone->dwDpFlags = zoneinfo->dwDpFlags;
777 r->Zone->pszDpFqdn = talloc_strdup(mem_ctx, zoneinfo->pszDpFqdn);
782 if (strcasecmp(operation, "ZoneInfo") == 0) {
783 if (client_version == DNS_CLIENT_VERSION_W2K) {
784 *typeid = DNSSRV_TYPEID_ZONE_INFO_W2K;
785 r->ZoneInfoW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_W2K);
787 r->ZoneInfoW2K->pszZoneName = talloc_strdup(mem_ctx, z->name);
788 r->ZoneInfoW2K->dwZoneType = zoneinfo->dwZoneType;
789 r->ZoneInfoW2K->fReverse = zoneinfo->fReverse;
790 r->ZoneInfoW2K->fAllowUpdate = zoneinfo->fAllowUpdate;
791 r->ZoneInfoW2K->fPaused = zoneinfo->fPaused;
792 r->ZoneInfoW2K->fShutdown = zoneinfo->fShutdown;
793 r->ZoneInfoW2K->fAutoCreated = zoneinfo->fAutoCreated;
794 r->ZoneInfoW2K->fUseDatabase = zoneinfo->fUseDatabase;
795 r->ZoneInfoW2K->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
796 r->ZoneInfoW2K->aipMasters = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
797 r->ZoneInfoW2K->fSecureSecondaries = zoneinfo->fSecureSecondaries;
798 r->ZoneInfoW2K->fNotifyLevel = zoneinfo->fNotifyLevel;
799 r->ZoneInfoW2K->aipSecondaries = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
800 r->ZoneInfoW2K->aipNotify = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
801 r->ZoneInfoW2K->fUseWins = zoneinfo->fUseWins;
802 r->ZoneInfoW2K->fUseNbstat = zoneinfo->fUseNbstat;
803 r->ZoneInfoW2K->fAging = zoneinfo->fAging;
804 r->ZoneInfoW2K->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
805 r->ZoneInfoW2K->dwRefreshInterval = zoneinfo->dwRefreshInterval;
806 r->ZoneInfoW2K->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
807 r->ZoneInfoW2K->aipScavengeServers = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
809 } else if (client_version == DNS_CLIENT_VERSION_DOTNET) {
810 *typeid = DNSSRV_TYPEID_ZONE_INFO_DOTNET;
811 r->ZoneInfoDotNet = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_DOTNET);
813 r->ZoneInfoDotNet->dwRpcStructureVersion = 0x01;
814 r->ZoneInfoDotNet->pszZoneName = talloc_strdup(mem_ctx, z->name);
815 r->ZoneInfoDotNet->dwZoneType = zoneinfo->dwZoneType;
816 r->ZoneInfoDotNet->fReverse = zoneinfo->fReverse;
817 r->ZoneInfoDotNet->fAllowUpdate = zoneinfo->fAllowUpdate;
818 r->ZoneInfoDotNet->fPaused = zoneinfo->fPaused;
819 r->ZoneInfoDotNet->fShutdown = zoneinfo->fShutdown;
820 r->ZoneInfoDotNet->fAutoCreated = zoneinfo->fAutoCreated;
821 r->ZoneInfoDotNet->fUseDatabase = zoneinfo->fUseDatabase;
822 r->ZoneInfoDotNet->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
823 r->ZoneInfoDotNet->aipMasters = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
824 r->ZoneInfoDotNet->fSecureSecondaries = zoneinfo->fSecureSecondaries;
825 r->ZoneInfoDotNet->fNotifyLevel = zoneinfo->fNotifyLevel;
826 r->ZoneInfoDotNet->aipSecondaries = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
827 r->ZoneInfoDotNet->aipNotify = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
828 r->ZoneInfoDotNet->fUseWins = zoneinfo->fUseWins;
829 r->ZoneInfoDotNet->fUseNbstat = zoneinfo->fUseNbstat;
830 r->ZoneInfoDotNet->fAging = zoneinfo->fAging;
831 r->ZoneInfoDotNet->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
832 r->ZoneInfoDotNet->dwRefreshInterval = zoneinfo->dwRefreshInterval;
833 r->ZoneInfoDotNet->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
834 r->ZoneInfoDotNet->aipScavengeServers = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
835 r->ZoneInfoDotNet->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
836 r->ZoneInfoDotNet->fForwarderSlave = zoneinfo->fForwarderSlave;
837 r->ZoneInfoDotNet->aipLocalMasters = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
838 r->ZoneInfoDotNet->dwDpFlags = zoneinfo->dwDpFlags;
839 r->ZoneInfoDotNet->pszDpFqdn = talloc_strdup(mem_ctx, zoneinfo->pszDpFqdn);
840 r->ZoneInfoDotNet->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
841 r->ZoneInfoDotNet->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
842 r->ZoneInfoDotNet->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
845 *typeid = DNSSRV_TYPEID_ZONE_INFO;
846 r->ZoneInfo = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_INFO_LONGHORN);
848 r->ZoneInfo->dwRpcStructureVersion = 0x02;
849 r->ZoneInfo->pszZoneName = talloc_strdup(mem_ctx, z->name);
850 r->ZoneInfo->dwZoneType = zoneinfo->dwZoneType;
851 r->ZoneInfo->fReverse = zoneinfo->fReverse;
852 r->ZoneInfo->fAllowUpdate = zoneinfo->fAllowUpdate;
853 r->ZoneInfo->fPaused = zoneinfo->fPaused;
854 r->ZoneInfo->fShutdown = zoneinfo->fShutdown;
855 r->ZoneInfo->fAutoCreated = zoneinfo->fAutoCreated;
856 r->ZoneInfo->fUseDatabase = zoneinfo->fUseDatabase;
857 r->ZoneInfo->pszDataFile = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
858 r->ZoneInfo->aipMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipMasters);
859 r->ZoneInfo->fSecureSecondaries = zoneinfo->fSecureSecondaries;
860 r->ZoneInfo->fNotifyLevel = zoneinfo->fNotifyLevel;
861 r->ZoneInfo->aipSecondaries = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipSecondaries);
862 r->ZoneInfo->aipNotify = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipNotify);
863 r->ZoneInfo->fUseWins = zoneinfo->fUseWins;
864 r->ZoneInfo->fUseNbstat = zoneinfo->fUseNbstat;
865 r->ZoneInfo->fAging = zoneinfo->fAging;
866 r->ZoneInfo->dwNoRefreshInterval = zoneinfo->dwNoRefreshInterval;
867 r->ZoneInfo->dwRefreshInterval = zoneinfo->dwRefreshInterval;
868 r->ZoneInfo->dwAvailForScavengeTime = zoneinfo->dwAvailForScavengeTime;
869 r->ZoneInfo->aipScavengeServers = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipScavengeServers);
870 r->ZoneInfo->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
871 r->ZoneInfo->fForwarderSlave = zoneinfo->fForwarderSlave;
872 r->ZoneInfo->aipLocalMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
873 r->ZoneInfo->dwDpFlags = zoneinfo->dwDpFlags;
874 r->ZoneInfo->pszDpFqdn = talloc_strdup(mem_ctx, zoneinfo->pszDpFqdn);
875 r->ZoneInfo->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
876 r->ZoneInfo->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
877 r->ZoneInfo->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
879 r->ZoneInfo->fQueuedForBackgroundLoad = zoneinfo->fQueuedForBackgroundLoad;
880 r->ZoneInfo->fBackgroundLoadInProgress = zoneinfo->fBackgroundLoadInProgress;
881 r->ZoneInfo->fReadOnlyZone = zoneinfo->fReadOnlyZone;
882 r->ZoneInfo->dwLastXfrAttempt = zoneinfo->dwLastXfrAttempt;
883 r->ZoneInfo->dwLastXfrResult = zoneinfo->dwLastXfrResult;
891 if (strcasecmp(operation, "AllowUpdate") == 0) {
892 answer_integer = zoneinfo->fAllowUpdate;
894 } else if (strcasecmp(operation, "Secured") == 0) {
897 } else if (strcasecmp(operation, "DsIntegrated") == 0) {
898 answer_integer = zoneinfo->fUseDatabase;
900 } else if (strcasecmp(operation, "LogUpdates") == 0) {
903 } else if (strcasecmp(operation, "NoRefreshInterval") == 0) {
904 answer_integer = zoneinfo->dwNoRefreshInterval;
906 } else if (strcasecmp(operation, "NotifyLevel") == 0) {
907 answer_integer = zoneinfo->fNotifyLevel;
909 } else if (strcasecmp(operation, "RefreshInterval") == 0) {
910 answer_integer = zoneinfo->dwRefreshInterval;
912 } else if (strcasecmp(operation, "SecureSecondaries") == 0) {
913 answer_integer = zoneinfo->fSecureSecondaries;
915 } else if (strcasecmp(operation, "Type") == 0) {
916 answer_integer = zoneinfo->dwZoneType;
918 } else if (strcasecmp(operation, "Aging") == 0) {
919 answer_integer = zoneinfo->fAging;
921 } else if (strcasecmp(operation, "ForwarderSlave") == 0) {
922 answer_integer = zoneinfo->fForwarderSlave;
924 } else if (strcasecmp(operation, "ForwarderTimeout") == 0) {
925 answer_integer = zoneinfo->dwForwarderTimeout;
927 } else if (strcasecmp(operation, "Unicode") == 0) {
932 if (is_integer == 1) {
933 *typeid = DNSSRV_TYPEID_DWORD;
934 r->Dword = answer_integer;
940 if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
941 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
942 answer_addrarray = NULL;
944 answer_iparray = NULL;
947 } else if (strcasecmp(operation, "ScavengeServers") == 0) {
948 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
949 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipScavengeServers);
951 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipScavengeServers);
954 } else if (strcasecmp(operation, "MasterServers") == 0) {
955 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
956 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipMasters);
958 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipMasters);
961 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
962 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
963 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
965 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
968 } else if (strcasecmp(operation, "NotifyServers") == 0) {
969 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
970 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipNotify);
972 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipNotify);
975 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
976 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
977 answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipSecondaries);
979 answer_iparray = ip4_array_copy(mem_ctx, zoneinfo->aipSecondaries);
984 if (is_addresses == 1) {
985 if (client_version == DNS_CLIENT_VERSION_LONGHORN) {
986 *typeid = DNSSRV_TYPEID_ADDRARRAY;
987 r->AddrArray = answer_addrarray;
989 *typeid = DNSSRV_TYPEID_IPARRAY;
990 r->IpArray = answer_iparray;
997 if (strcasecmp(operation, "DatabaseFile") == 0) {
998 answer_string = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
1000 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1001 answer_string = talloc_strdup(mem_ctx, zoneinfo->pszDpFqdn);
1003 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1004 answer_string = NULL;
1008 if (is_string == 1) {
1009 *typeid = DNSSRV_TYPEID_LPSTR;
1010 r->String = answer_string;
1014 DEBUG(0,("dnsserver: Invalid zone operation %s", operation));
1015 return WERR_DNS_ERROR_INVALID_PROPERTY;
1019 /* dnsserver operation functions */
1021 /* [MS-DNSP].pdf Section 3.1.1.1 DNS Server Configuration Information */
1022 static WERROR dnsserver_operate_server(struct dnsserver_state *dsstate,
1023 TALLOC_CTX *mem_ctx,
1024 const char *operation,
1025 const unsigned int client_version,
1026 enum DNS_RPC_TYPEID typeid,
1027 union DNSSRV_RPC_UNION *r)
1029 bool valid_operation = false;
1031 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1032 valid_operation = true;
1033 } else if (strcasecmp(operation, "Restart") == 0) {
1034 valid_operation = true;
1035 } else if (strcasecmp(operation, "ClearDebugLog") == 0) {
1036 valid_operation = true;
1037 } else if (strcasecmp(operation, "ClearCache") == 0) {
1038 valid_operation = true;
1039 } else if (strcasecmp(operation, "WriteDirtyZones") == 0) {
1040 valid_operation = true;
1041 } else if (strcasecmp(operation, "ZoneCreate") == 0) {
1042 valid_operation = true;
1043 } else if (strcasecmp(operation, "ClearStatistics") == 0) {
1044 valid_operation = true;
1045 } else if (strcasecmp(operation, "EnlistDirectoryPartition") == 0) {
1046 valid_operation = true;
1047 } else if (strcasecmp(operation, "StartScavenging") == 0) {
1048 valid_operation = true;
1049 } else if (strcasecmp(operation, "AbortScavenging") == 0) {
1050 valid_operation = true;
1051 } else if (strcasecmp(operation, "AutoConfigure") == 0) {
1052 valid_operation = true;
1053 } else if (strcasecmp(operation, "ExportSettings") == 0) {
1054 valid_operation = true;
1055 } else if (strcasecmp(operation, "PrepareForDemotion") == 0) {
1056 valid_operation = true;
1057 } else if (strcasecmp(operation, "PrepareForUninstall") == 0) {
1058 valid_operation = true;
1059 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1060 valid_operation = true;
1061 } else if (strcasecmp(operation, "DeleteRecord") == 0) {
1062 valid_operation = true;
1063 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1064 valid_operation = true;
1065 } else if (strcasecmp(operation, "ListenAddresses") == 0) {
1066 valid_operation = true;
1067 } else if (strcasecmp(operation, "Forwarders") == 0) {
1068 valid_operation = true;
1069 } else if (strcasecmp(operation, "LogFilePath") == 0) {
1070 valid_operation = true;
1071 } else if (strcasecmp(operation, "LogIpFilterList") == 0) {
1072 valid_operation = true;
1073 } else if (strcasecmp(operation, "ForestDirectoryPartitionBaseName") == 0) {
1074 valid_operation = true;
1075 } else if (strcasecmp(operation, "DomainDirectoryPartitionBaseName") == 0) {
1076 valid_operation = true;
1077 } else if (strcasecmp(operation, "GlobalQueryBlockList") == 0) {
1078 valid_operation = true;
1079 } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) {
1080 valid_operation = true;
1081 } else if (strcasecmp(operation, "BreakOnUpdateFrom") == 0) {
1082 valid_operation = true;
1083 } else if (strcasecmp(operation, "ServerLevelPluginDll") == 0) {
1084 valid_operation = true;
1087 if (valid_operation) {
1088 DEBUG(0, ("dnsserver: server operation '%s' not implemented", operation));
1089 return WERR_CALL_NOT_IMPLEMENTED;
1092 DEBUG(0, ("dnsserver: invalid server operation '%s'", operation));
1093 return WERR_DNS_ERROR_INVALID_PROPERTY;
1096 static WERROR dnsserver_complex_operate_server(struct dnsserver_state *dsstate,
1097 TALLOC_CTX *mem_ctx,
1098 const char *operation,
1099 const unsigned int client_version,
1100 enum DNS_RPC_TYPEID typeid_in,
1101 union DNSSRV_RPC_UNION *rin,
1102 enum DNS_RPC_TYPEID *typeid_out,
1103 union DNSSRV_RPC_UNION *rout)
1105 int valid_operation = 0;
1106 struct dnsserver_zone *z, **zlist;
1108 bool found1, found2, found3, found4;
1111 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1112 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1113 return dnsserver_query_server(dsstate, mem_ctx,
1119 } else if (strcasecmp(operation, "EnumZones") == 0) {
1120 if (typeid_in != DNSSRV_TYPEID_DWORD) {
1121 return WERR_DNS_ERROR_INVALID_PROPERTY;
1125 zlist = talloc_zero_array(mem_ctx, struct dnsserver_zone *, 0);
1126 for (z = dsstate->zones; z; z = z->next) {
1128 /* Match the flags in groups
1130 * Group1 : PRIMARY, SECONDARY, CACHE, AUTO
1131 * Group2 : FORWARD, REVERSE, FORWARDER, STUB
1132 * Group3 : DS, NON_DS, DOMAIN_DP, FOREST_DP
1133 * Group4 : CUSTOM_DP, LEGACY_DP
1138 if (rin->Dword & 0x0000000f) {
1139 if (rin->Dword & DNS_ZONE_REQUEST_PRIMARY) {
1140 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_PRIMARY) {
1144 if (rin->Dword & DNS_ZONE_REQUEST_SECONDARY) {
1145 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_SECONDARY) {
1149 if (rin->Dword & DNS_ZONE_REQUEST_CACHE) {
1150 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_CACHE) {
1154 if (rin->Dword & DNS_ZONE_REQUEST_AUTO) {
1155 if (z->zoneinfo->fAutoCreated
1156 || z->zoneinfo->dwDpFlags & DNS_DP_AUTOCREATED) {
1166 if (rin->Dword & 0x000000f0) {
1167 if (rin->Dword & DNS_ZONE_REQUEST_FORWARD) {
1168 if (!(z->zoneinfo->fReverse)) {
1172 if (rin->Dword & DNS_ZONE_REQUEST_REVERSE) {
1173 if (z->zoneinfo->fReverse) {
1177 if (rin->Dword & DNS_ZONE_REQUEST_FORWARDER) {
1178 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_FORWARDER) {
1182 if (rin->Dword & DNS_ZONE_REQUEST_STUB) {
1183 if (z->zoneinfo->dwZoneType == DNS_ZONE_TYPE_STUB) {
1193 if (rin->Dword & 0x00000f00) {
1194 if (rin->Dword & DNS_ZONE_REQUEST_DS) {
1195 if (z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED) {
1199 if (rin->Dword & DNS_ZONE_REQUEST_NON_DS) {
1200 if (!(z->zoneinfo->Flags & DNS_RPC_ZONE_DSINTEGRATED)) {
1204 if (rin->Dword & DNS_ZONE_REQUEST_DOMAIN_DP) {
1205 if (!(z->zoneinfo->dwDpFlags & DNS_DP_DOMAIN_DEFAULT)) {
1209 if (rin->Dword & DNS_ZONE_REQUEST_FOREST_DP) {
1210 if (!(z->zoneinfo->dwDpFlags & DNS_DP_FOREST_DEFAULT)) {
1219 if (rin->Dword & 0x0000f000) {
1225 if (found1 && found2 && found3 && found4) {
1226 zlist = talloc_realloc(mem_ctx, zlist, struct dnsserver_zone *, zcount+1);
1232 if (client_version == DNS_CLIENT_VERSION_W2K) {
1233 *typeid_out = DNSSRV_TYPEID_ZONE_LIST_W2K;
1234 rout->ZoneListW2K = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_W2K);
1237 rout->ZoneListW2K->dwZoneCount = 0;
1238 rout->ZoneListW2K->ZoneArray = NULL;
1243 rout->ZoneListW2K->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_W2K *, zcount);
1244 if (rout->ZoneListW2K->ZoneArray == NULL) {
1249 for (i=0; i<zcount; i++) {
1250 rout->ZoneListW2K->ZoneArray[i] = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_W2K);
1252 rout->ZoneListW2K->ZoneArray[i]->pszZoneName = talloc_strdup(mem_ctx, zlist[i]->name);
1253 rout->ZoneListW2K->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
1254 rout->ZoneListW2K->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
1255 rout->ZoneListW2K->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
1257 rout->ZoneListW2K->dwZoneCount = zcount;
1260 *typeid_out = DNSSRV_TYPEID_ZONE_LIST;
1261 rout->ZoneList = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_LIST_DOTNET);
1264 rout->ZoneList->dwRpcStructureVersion = 1;
1265 rout->ZoneList->dwZoneCount = 0;
1266 rout->ZoneList->ZoneArray = NULL;
1271 rout->ZoneList->ZoneArray = talloc_zero_array(mem_ctx, struct DNS_RPC_ZONE_DOTNET *, zcount);
1272 if (rout->ZoneList->ZoneArray == NULL) {
1277 for (i=0; i<zcount; i++) {
1278 rout->ZoneList->ZoneArray[i] = talloc_zero(mem_ctx, struct DNS_RPC_ZONE_DOTNET);
1280 rout->ZoneList->ZoneArray[i]->dwRpcStructureVersion = 1;
1281 rout->ZoneList->ZoneArray[i]->pszZoneName = talloc_strdup(mem_ctx, zlist[i]->name);
1282 rout->ZoneList->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
1283 rout->ZoneList->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
1284 rout->ZoneList->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
1285 rout->ZoneList->ZoneArray[i]->dwDpFlags = zlist[i]->zoneinfo->dwDpFlags;
1286 rout->ZoneList->ZoneArray[i]->pszDpFqdn = talloc_strdup(mem_ctx, zlist[i]->zoneinfo->pszDpFqdn);
1288 rout->ZoneList->dwRpcStructureVersion = 1;
1289 rout->ZoneList->dwZoneCount = zcount;
1293 } else if (strcasecmp(operation, "EnumZones2") == 0) {
1294 valid_operation = true;
1295 } else if (strcasecmp(operation, "EnumDirectoryPartitions") == 0) {
1296 valid_operation = true;
1297 } else if (strcasecmp(operation, "DirectoryPartitionInfo") == 0) {
1298 valid_operation = true;
1299 } else if (strcasecmp(operation, "Statistics") == 0) {
1300 valid_operation = true;
1301 } else if (strcasecmp(operation, "IpValidate") == 0) {
1302 valid_operation = true;
1305 if (valid_operation) {
1306 DEBUG(0, ("dnsserver: server complex operation '%s' not implemented", operation));
1307 return WERR_CALL_NOT_IMPLEMENTED;
1310 DEBUG(0, ("dnsserver: invalid server complex operation '%s'", operation));
1311 return WERR_DNS_ERROR_INVALID_PROPERTY;
1314 /* [MS-DNSP].pdf Section 3.1.1.2 Zone Configuration Information */
1315 static WERROR dnsserver_operate_zone(struct dnsserver_state *dsstate,
1316 TALLOC_CTX *mem_ctx,
1317 struct dnsserver_zone *z,
1318 unsigned int request_filter,
1319 const char *operation,
1320 const unsigned int client_version,
1321 enum DNS_RPC_TYPEID typeid,
1322 union DNSSRV_RPC_UNION *r)
1324 bool valid_operation = false;
1326 if (strcasecmp(operation, "ResetDwordProperty") == 0) {
1327 valid_operation = true;
1328 } else if (strcasecmp(operation, "ZoneTypeReset") == 0) {
1329 valid_operation = true;
1330 } else if (strcasecmp(operation, "PauseZone") == 0) {
1331 valid_operation = true;
1332 } else if (strcasecmp(operation, "ResumeZone") == 0) {
1333 valid_operation = true;
1334 } else if (strcasecmp(operation, "DeleteZone") == 0) {
1335 valid_operation = true;
1336 } else if (strcasecmp(operation, "ReloadZone") == 0) {
1337 valid_operation = true;
1338 } else if (strcasecmp(operation, "RefreshZone") == 0) {
1339 valid_operation = true;
1340 } else if (strcasecmp(operation, "ExpireZone") == 0) {
1341 valid_operation = true;
1342 } else if (strcasecmp(operation, "IncrementVersion") == 0) {
1343 valid_operation = true;
1344 } else if (strcasecmp(operation, "WriteBackFile") == 0) {
1345 valid_operation = true;
1346 } else if (strcasecmp(operation, "DeleteZoneFromDs") == 0) {
1347 valid_operation = true;
1348 } else if (strcasecmp(operation, "UpdateZoneFromDs") == 0) {
1349 valid_operation = true;
1350 } else if (strcasecmp(operation, "ZoneExport") == 0) {
1351 valid_operation = true;
1352 } else if (strcasecmp(operation, "ZoneChangeDirectoryPartition") == 0) {
1353 valid_operation = true;
1354 } else if (strcasecmp(operation, "DeleteNode") == 0) {
1355 valid_operation = true;
1356 } else if (strcasecmp(operation, "DeleteRecordSet") == 0) {
1357 valid_operation = true;
1358 } else if (strcasecmp(operation, "ForceAgingOnNode") == 0) {
1359 valid_operation = true;
1360 } else if (strcasecmp(operation, "DatabaseFile") == 0) {
1361 valid_operation = true;
1362 } else if (strcasecmp(operation, "MasterServers") == 0) {
1363 valid_operation = true;
1364 } else if (strcasecmp(operation, "LocalMasterServers") == 0) {
1365 valid_operation = true;
1366 } else if (strcasecmp(operation, "NotifyServers") == 0) {
1367 valid_operation = true;
1368 } else if (strcasecmp(operation, "SecondaryServers") == 0) {
1369 valid_operation = true;
1370 } else if (strcasecmp(operation, "ScavengingServers") == 0) {
1371 valid_operation = true;
1372 } else if (strcasecmp(operation, "AllowNSRecordsAutoCreation") == 0) {
1373 valid_operation = true;
1374 } else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
1375 valid_operation = true;
1376 } else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
1377 valid_operation = true;
1380 if (valid_operation) {
1381 DEBUG(0, ("dnsserver: zone operation '%s' not implemented", operation));
1382 return WERR_CALL_NOT_IMPLEMENTED;
1385 DEBUG(0, ("dnsserver: invalid zone operation '%s'", operation));
1386 return WERR_DNS_ERROR_INVALID_PROPERTY;
1389 static WERROR dnsserver_complex_operate_zone(struct dnsserver_state *dsstate,
1390 TALLOC_CTX *mem_ctx,
1391 struct dnsserver_zone *z,
1392 const char *operation,
1393 const unsigned int client_version,
1394 enum DNS_RPC_TYPEID typeid_in,
1395 union DNSSRV_RPC_UNION *rin,
1396 enum DNS_RPC_TYPEID *typeid_out,
1397 union DNSSRV_RPC_UNION *rout)
1399 if (strcasecmp(operation, "QueryDwordProperty") == 0) {
1400 if (typeid_in == DNSSRV_TYPEID_LPSTR) {
1401 return dnsserver_query_zone(dsstate, mem_ctx, z,
1410 DEBUG(0,("dnsserver: Invalid zone operation %s", operation));
1411 return WERR_DNS_ERROR_INVALID_PROPERTY;
1414 /* dnsserver enumerate function */
1416 static WERROR dnsserver_enumerate_root_records(struct dnsserver_state *dsstate,
1417 TALLOC_CTX *mem_ctx,
1418 unsigned int client_version,
1419 const char *node_name,
1420 enum dns_record_type record_type,
1421 unsigned int select_flag,
1422 unsigned int *buffer_length,
1423 struct DNS_RPC_RECORDS_ARRAY **buffer)
1425 TALLOC_CTX *tmp_ctx;
1426 const char * const attrs[] = { "name", "dnsRecord", NULL };
1427 struct ldb_result *res;
1429 struct DNS_RPC_RECORDS_ARRAY *recs;
1436 tmp_ctx = talloc_new(mem_ctx);
1437 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1439 dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(dsstate->samdb));
1440 W_ERROR_HAVE_NO_MEMORY_AND_FREE(dn, tmp_ctx);
1442 if (!ldb_dn_add_child_fmt(dn, "DC=RootDNSServers,CN=MicrosoftDNS,DC=DomainDnsZones")) {
1443 talloc_free(tmp_ctx);
1447 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, dn,
1448 LDB_SCOPE_ONELEVEL, attrs, "(&(objectClass=dnsNode)(name=@))");
1449 if (ret != LDB_SUCCESS) {
1450 talloc_free(tmp_ctx);
1451 return WERR_INTERNAL_DB_ERROR;
1453 if (res->count == 0) {
1454 talloc_free(tmp_ctx);
1455 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1458 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1459 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1464 for (i=0; i<res->count; i++) {
1465 status = dns_fill_records_array(tmp_ctx, NULL, record_type,
1467 res->msgs[i], 0, recs,
1468 &add_names, &add_count);
1469 if (!W_ERROR_IS_OK(status)) {
1470 talloc_free(tmp_ctx);
1476 /* Add any additional records */
1477 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1478 for (i=0; i<add_count; i++) {
1479 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, dn,
1480 LDB_SCOPE_ONELEVEL, attrs,
1481 "(&(objectClass=dnsNode)(name=%s))", add_names[i]);
1482 if (ret != LDB_SUCCESS || res->count == 0) {
1487 len = strlen(add_names[i]);
1488 if (add_names[i][len-1] == '.') {
1489 rname = talloc_strdup(tmp_ctx, add_names[i]);
1491 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1493 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1495 res->msgs[0], 0, recs,
1502 talloc_free(tmp_ctx);
1504 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1511 static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
1512 TALLOC_CTX *mem_ctx,
1513 struct dnsserver_zone *z,
1514 unsigned int client_version,
1515 const char *node_name,
1516 const char *start_child,
1517 enum dns_record_type record_type,
1518 unsigned int select_flag,
1519 const char *filter_start,
1520 const char *filter_stop,
1521 unsigned int *buffer_length,
1522 struct DNS_RPC_RECORDS_ARRAY **buffer)
1524 TALLOC_CTX *tmp_ctx;
1526 const char * const attrs[] = { "name", "dnsRecord", NULL };
1527 struct ldb_result *res;
1528 struct DNS_RPC_RECORDS_ARRAY *recs;
1529 char **add_names = NULL;
1534 struct dns_tree *tree, *base, *node;
1536 tmp_ctx = talloc_new(mem_ctx);
1537 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1539 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1540 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1542 /* search all records under parent tree */
1543 if (strcmp(name, z->name) == 0) {
1544 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1545 LDB_SCOPE_ONELEVEL, attrs, "(objectClass=dnsNode)");
1547 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
1548 LDB_SCOPE_ONELEVEL, attrs,
1549 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s)))",
1552 if (ret != LDB_SUCCESS) {
1553 talloc_free(tmp_ctx);
1554 return WERR_INTERNAL_DB_ERROR;
1556 if (res->count == 0) {
1557 talloc_free(tmp_ctx);
1558 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1561 recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
1562 W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
1564 /* Sort the names, so that the first record is the parent record */
1565 ldb_qsort(res->msgs, res->count, sizeof(struct ldb_message *), name,
1566 (ldb_qsort_cmp_fn_t)dns_name_compare);
1568 /* Build a tree of name components from dns name */
1569 if (strcmp(name, z->name) == 0) {
1570 tree = dns_build_tree(tmp_ctx, "@", res);
1572 tree = dns_build_tree(tmp_ctx, name, res);
1574 W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree, tmp_ctx);
1576 /* Find the parent record in the tree */
1578 while (base->level != -1) {
1579 base = base->children[0];
1582 /* Add the parent record with blank name */
1583 if (!(select_flag & DNS_RPC_VIEW_ONLY_CHILDREN)) {
1584 status = dns_fill_records_array(tmp_ctx, z, record_type,
1587 recs, &add_names, &add_count);
1588 if (!W_ERROR_IS_OK(status)) {
1589 talloc_free(tmp_ctx);
1594 /* Add all the children records */
1595 if (!(select_flag & DNS_RPC_VIEW_NO_CHILDREN)) {
1596 for (i=0; i<base->num_children; i++) {
1597 node = base->children[i];
1599 status = dns_fill_records_array(tmp_ctx, z, record_type,
1600 select_flag, node->name,
1601 node->data, node->num_children,
1602 recs, &add_names, &add_count);
1603 if (!W_ERROR_IS_OK(status)) {
1604 talloc_free(tmp_ctx);
1614 /* Add any additional records */
1615 if (select_flag & DNS_RPC_VIEW_ADDITIONAL_DATA) {
1616 for (i=0; i<add_count; i++) {
1617 struct dnsserver_zone *z2;
1619 /* Search all the available zones for additional name */
1620 for (z2 = dsstate->zones; z2; z2 = z2->next) {
1621 name = dns_split_node_name(tmp_ctx, add_names[i], z2->name);
1622 ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z2->zone_dn,
1623 LDB_SCOPE_ONELEVEL, attrs,
1624 "(&(objectClass=dnsNode)(name=%s))", name);
1626 if (ret != LDB_SUCCESS) {
1629 if (res->count == 1) {
1637 len = strlen(add_names[i]);
1638 if (add_names[i][len-1] == '.') {
1639 rname = talloc_strdup(tmp_ctx, add_names[i]);
1641 rname = talloc_asprintf(tmp_ctx, "%s.", add_names[i]);
1643 status = dns_fill_records_array(tmp_ctx, NULL, DNS_TYPE_A,
1645 res->msgs[0], 0, recs,
1652 *buffer_length = ndr_size_DNS_RPC_RECORDS_ARRAY(recs, 0);
1658 /* dnsserver update function */
1660 static WERROR dnsserver_update_record(struct dnsserver_state *dsstate,
1661 TALLOC_CTX *mem_ctx,
1662 struct dnsserver_zone *z,
1663 unsigned int client_version,
1664 const char *node_name,
1665 struct DNS_RPC_RECORD_BUF *add_buf,
1666 struct DNS_RPC_RECORD_BUF *del_buf)
1668 TALLOC_CTX *tmp_ctx;
1672 tmp_ctx = talloc_new(mem_ctx);
1673 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
1675 name = dns_split_node_name(tmp_ctx, node_name, z->name);
1676 W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
1678 if (add_buf != NULL) {
1679 if (del_buf == NULL) {
1681 status = dnsserver_db_add_record(tmp_ctx, dsstate->samdb,
1686 status = dnsserver_db_update_record(tmp_ctx, dsstate->samdb,
1692 if (del_buf == NULL) {
1693 /* Add empty node */
1694 status = dnsserver_db_add_empty_node(tmp_ctx, dsstate->samdb,
1698 status = dnsserver_db_delete_record(tmp_ctx, dsstate->samdb,
1704 talloc_free(tmp_ctx);
1709 /* dnsserver interface functions */
1711 static WERROR dcesrv_DnssrvOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation *r)
1713 struct dnsserver_state *dsstate;
1714 struct dnsserver_zone *z = NULL;
1715 uint32_t request_filter = 0;
1718 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1719 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1722 if (r->in.dwContext == 0) {
1723 if (r->in.pszZone != NULL) {
1724 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
1727 request_filter = r->in.dwContext;
1730 if (r->in.pszZone == NULL) {
1731 ret = dnsserver_operate_server(dsstate, mem_ctx,
1733 DNS_CLIENT_VERSION_W2K,
1737 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
1740 DNS_CLIENT_VERSION_W2K,
1745 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1746 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation, NDR_IN, r);
1751 static WERROR dcesrv_DnssrvQuery(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery *r)
1753 struct dnsserver_state *dsstate;
1754 struct dnsserver_zone *z;
1757 ZERO_STRUCTP(r->out.pdwTypeId);
1758 ZERO_STRUCTP(r->out.ppData);
1760 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1761 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1764 if (r->in.pszZone == NULL) {
1765 /* FIXME: DNS Server Configuration Access Control List */
1766 ret = dnsserver_query_server(dsstate, mem_ctx,
1768 DNS_CLIENT_VERSION_W2K,
1772 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1774 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1777 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
1779 DNS_CLIENT_VERSION_W2K,
1784 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1785 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery, NDR_IN, r);
1790 static WERROR dcesrv_DnssrvComplexOperation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation *r)
1792 struct dnsserver_state *dsstate;
1793 struct dnsserver_zone *z;
1796 ZERO_STRUCTP(r->out.pdwTypeOut);
1797 ZERO_STRUCTP(r->out.ppDataOut);
1799 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1800 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1803 if (r->in.pszZone == NULL) {
1804 /* Server operation */
1805 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
1807 DNS_CLIENT_VERSION_W2K,
1813 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1815 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1818 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
1820 DNS_CLIENT_VERSION_W2K,
1827 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1828 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation, NDR_IN, r);
1833 static WERROR dcesrv_DnssrvEnumRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords *r)
1835 struct dnsserver_state *dsstate;
1836 struct dnsserver_zone *z;
1839 ZERO_STRUCTP(r->out.pdwBufferLength);
1840 ZERO_STRUCTP(r->out.pBuffer);
1842 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1843 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1846 if (r->in.pszZone == NULL) {
1847 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1850 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
1851 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
1852 DNS_CLIENT_VERSION_W2K,
1856 r->out.pdwBufferLength,
1859 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1861 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1864 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
1865 DNS_CLIENT_VERSION_W2K,
1867 r->in.pszStartChild,
1870 r->in.pszFilterStart,
1871 r->in.pszFilterStop,
1872 r->out.pdwBufferLength,
1876 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1877 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords, NDR_IN, r);
1882 static WERROR dcesrv_DnssrvUpdateRecord(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord *r)
1884 struct dnsserver_state *dsstate;
1885 struct dnsserver_zone *z;
1888 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1889 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1892 if (r->in.pszZone == NULL) {
1893 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1896 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1898 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
1901 ret = dnsserver_update_record(dsstate, mem_ctx, z,
1902 DNS_CLIENT_VERSION_W2K,
1905 r->in.pDeleteRecord);
1907 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1908 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord, NDR_IN, r);
1913 static WERROR dcesrv_DnssrvOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvOperation2 *r)
1915 struct dnsserver_state *dsstate;
1916 struct dnsserver_zone *z = NULL;
1917 uint32_t request_filter = 0;
1920 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1921 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1924 if (r->in.dwContext == 0) {
1925 if (r->in.pszZone != NULL) {
1926 request_filter = dnsserver_zone_to_request_filter(r->in.pszZone);
1929 request_filter = r->in.dwContext;
1932 if (r->in.pszZone == NULL) {
1933 ret = dnsserver_operate_server(dsstate, mem_ctx,
1935 r->in.dwClientVersion,
1939 ret = dnsserver_operate_zone(dsstate, mem_ctx, z,
1942 r->in.dwClientVersion,
1947 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1948 NDR_PRINT_FUNCTION_DEBUG(DnssrvOperation2, NDR_IN, r);
1953 static WERROR dcesrv_DnssrvQuery2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvQuery2 *r)
1955 struct dnsserver_state *dsstate;
1956 struct dnsserver_zone *z;
1959 ZERO_STRUCTP(r->out.pdwTypeId);
1960 ZERO_STRUCTP(r->out.ppData);
1962 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
1963 return WERR_DNS_ERROR_DS_UNAVAILABLE;
1966 if (r->in.pszZone == NULL) {
1967 /* FIXME: DNS Server Configuration Access Control List */
1968 ret = dnsserver_query_server(dsstate, mem_ctx,
1970 r->in.dwClientVersion,
1974 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
1976 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
1979 ret = dnsserver_query_zone(dsstate, mem_ctx, z,
1981 r->in.dwClientVersion,
1986 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
1987 NDR_PRINT_FUNCTION_DEBUG(DnssrvQuery2, NDR_IN, r);
1992 static WERROR dcesrv_DnssrvComplexOperation2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvComplexOperation2 *r)
1994 struct dnsserver_state *dsstate;
1995 struct dnsserver_zone *z;
1998 ZERO_STRUCTP(r->out.pdwTypeOut);
1999 ZERO_STRUCTP(r->out.ppDataOut);
2001 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2002 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2005 if (r->in.pszZone == NULL) {
2006 /* Server operation */
2007 ret = dnsserver_complex_operate_server(dsstate, mem_ctx,
2009 r->in.dwClientVersion,
2016 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2018 return WERR_DNS_ERROR_ZONE_DOES_NOT_EXIST;
2021 ret = dnsserver_complex_operate_zone(dsstate, mem_ctx, z,
2023 r->in.dwClientVersion,
2030 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2031 NDR_PRINT_FUNCTION_DEBUG(DnssrvComplexOperation2, NDR_IN, r);
2036 static WERROR dcesrv_DnssrvEnumRecords2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvEnumRecords2 *r)
2038 struct dnsserver_state *dsstate;
2039 struct dnsserver_zone *z;
2042 ZERO_STRUCTP(r->out.pdwBufferLength);
2043 ZERO_STRUCTP(r->out.pBuffer);
2045 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2046 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2049 if (r->in.pszZone == NULL) {
2050 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2053 if (strcasecmp(r->in.pszZone, "..RootHints") == 0) {
2054 ret = dnsserver_enumerate_root_records(dsstate, mem_ctx,
2055 r->in.dwClientVersion,
2059 r->out.pdwBufferLength,
2062 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2064 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2067 ret = dnsserver_enumerate_records(dsstate, mem_ctx, z,
2068 r->in.dwClientVersion,
2070 r->in.pszStartChild,
2073 r->in.pszFilterStart,
2074 r->in.pszFilterStop,
2075 r->out.pdwBufferLength,
2080 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2081 NDR_PRINT_FUNCTION_DEBUG(DnssrvEnumRecords2, NDR_IN, r);
2086 static WERROR dcesrv_DnssrvUpdateRecord2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct DnssrvUpdateRecord2 *r)
2088 struct dnsserver_state *dsstate;
2089 struct dnsserver_zone *z;
2092 if ((dsstate = dnsserver_connect(dce_call)) == NULL) {
2093 return WERR_DNS_ERROR_DS_UNAVAILABLE;
2096 if (r->in.pszZone == NULL) {
2097 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2100 z = dnsserver_find_zone(dsstate->zones, r->in.pszZone);
2102 return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST;
2105 ret = dnsserver_update_record(dsstate, mem_ctx, z,
2106 r->in.dwClientVersion,
2109 r->in.pDeleteRecord);
2111 if (W_ERROR_EQUAL(ret, WERR_CALL_NOT_IMPLEMENTED)) {
2112 NDR_PRINT_FUNCTION_DEBUG(DnssrvUpdateRecord2, NDR_IN, r);
2117 /* include the generated boilerplate */
2118 #include "librpc/gen_ndr/ndr_dnsserver_s.c"