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