LCOV - code coverage report
Current view: top level - source4/rpc_server/dnsserver - dcerpc_dnsserver.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 575 1521 37.8 %
Date: 2021-09-23 10:06:22 Functions: 18 32 56.2 %

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

Generated by: LCOV version 1.13