LCOV - code coverage report
Current view: top level - source4/rpc_server/dnsserver - dcerpc_dnsserver.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 572 1518 37.7 %
Date: 2024-06-13 04:01:37 Functions: 18 23 78.3 %

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

Generated by: LCOV version 1.13