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