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