LCOV - code coverage report
Current view: top level - source4/torture/rpc - drsuapi.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 287 548 52.4 %
Date: 2024-04-21 15:09:00 Functions: 17 19 89.5 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    DRSUapi tests
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2003
       7             :    Copyright (C) Stefan (metze) Metzmacher 2004
       8             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2006
       9             : 
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             :    
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             :    
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "includes.h"
      25             : #include "lib/cmdline/cmdline.h"
      26             : #include "librpc/gen_ndr/ndr_drsuapi_c.h"
      27             : #include "torture/rpc/torture_rpc.h"
      28             : #include "libcli/security/dom_sid.h"
      29             : #include "param/param.h"
      30             : 
      31             : #define TEST_MACHINE_NAME "torturetest"
      32             : 
      33           7 : static bool test_DsBind(struct dcerpc_pipe *p,
      34             :                         struct torture_context *tctx,
      35             :                         struct policy_handle *bind_handle,
      36             :                         struct drsuapi_DsBindInfo28 *srv_info28)
      37             : {
      38           0 :         NTSTATUS status;
      39           0 :         struct drsuapi_DsBind r;
      40           0 :         struct GUID bind_guid;
      41           0 :         struct drsuapi_DsBindInfo28 *bind_info28;
      42           0 :         struct drsuapi_DsBindInfoCtr bind_info_ctr;
      43             : 
      44           7 :         ZERO_STRUCT(bind_info_ctr);
      45           7 :         bind_info_ctr.length = 28;
      46             : 
      47           7 :         bind_info28 = &bind_info_ctr.info.info28;
      48           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_BASE;
      49           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION;
      50           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI;
      51           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2;
      52           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS;
      53           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1;
      54           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION;
      55           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE;
      56           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2;
      57           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION;
      58           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2;
      59           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD;
      60           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND;
      61           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO;
      62           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION;
      63           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01;
      64           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP;
      65           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY;
      66           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3;
      67           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2;
      68           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6;
      69           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS;
      70           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8;
      71           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5;
      72           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6;
      73           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3;
      74           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7;
      75           7 :         bind_info28->supported_extensions    |= DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT;
      76             : 
      77           7 :         GUID_from_string(DRSUAPI_DS_BIND_GUID, &bind_guid);
      78             : 
      79           7 :         r.in.bind_guid = &bind_guid;
      80           7 :         r.in.bind_info = &bind_info_ctr;
      81           7 :         r.out.bind_handle = bind_handle;
      82             : 
      83           7 :         torture_comment(tctx, "Testing DsBind\n");
      84             : 
      85           7 :         status = dcerpc_drsuapi_DsBind_r(p->binding_handle, tctx, &r);
      86           7 :         torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsBind");
      87             : 
      88           5 :         if (srv_info28 != NULL) {
      89           2 :                 *srv_info28 = r.out.bind_info->info.info28;
      90             :         }
      91             : 
      92           5 :         return true;
      93             : }
      94             : 
      95           1 : static bool test_DsGetDomainControllerInfo(struct torture_context *tctx,
      96             :                                            struct DsPrivate *priv)
      97             : {
      98           0 :         NTSTATUS status;
      99           1 :         struct dcerpc_pipe *p = priv->drs_pipe;
     100           0 :         struct drsuapi_DsGetDomainControllerInfo r;
     101           0 :         union drsuapi_DsGetDCInfoCtr ctr;
     102           0 :         union drsuapi_DsGetDCInfoRequest req;
     103           1 :         int32_t level_out = 0;
     104           1 :         bool found = false;
     105           0 :         int i, j, k;
     106             :         
     107           0 :         struct {
     108             :                 const char *name;
     109             :                 WERROR expected;
     110           2 :         } names[] = { 
     111             :                 {       
     112           1 :                         .name = torture_join_dom_netbios_name(priv->join),
     113             :                         .expected = WERR_OK
     114             :                 },
     115             :                 {
     116           1 :                         .name = torture_join_dom_dns_name(priv->join),
     117             :                         .expected = WERR_OK
     118             :                 },
     119             :                 {
     120             :                         .name = "__UNKNOWN_DOMAIN__",
     121             :                         .expected = WERR_DS_OBJ_NOT_FOUND
     122             :                 },
     123             :                 {
     124             :                         .name = "unknown.domain.samba.example.com",
     125             :                         .expected = WERR_DS_OBJ_NOT_FOUND
     126             :                 },
     127             :         };
     128           1 :         int levels[] = {1, 2};
     129           0 :         int level;
     130             : 
     131           1 :         for (i=0; i < ARRAY_SIZE(levels); i++) {
     132           3 :                 for (j=0; j < ARRAY_SIZE(names); j++) {
     133           3 :                         level = levels[i];
     134           3 :                         r.in.bind_handle = &priv->bind_handle;
     135           3 :                         r.in.level = 1;
     136           3 :                         r.in.req = &req;
     137             :                         
     138           3 :                         r.in.req->req1.domain_name = names[j].name;
     139           3 :                         r.in.req->req1.level = level;
     140             : 
     141           3 :                         r.out.ctr = &ctr;
     142           3 :                         r.out.level_out = &level_out;
     143             :                         
     144           3 :                         torture_comment(tctx,
     145             :                                    "Testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
     146           3 :                                r.in.req->req1.level, r.in.req->req1.domain_name);
     147             :                 
     148           3 :                         status = dcerpc_drsuapi_DsGetDomainControllerInfo_r(p->binding_handle, tctx, &r);
     149           3 :                         torture_assert_ntstatus_ok(tctx, status,
     150             :                                    "dcerpc_drsuapi_DsGetDomainControllerInfo with dns domain failed");
     151           3 :                         torture_assert_werr_equal(tctx,
     152             :                                                                           r.out.result, names[j].expected, 
     153             :                                            "DsGetDomainControllerInfo level with dns domain failed");
     154             :                 
     155           2 :                         if (!W_ERROR_IS_OK(r.out.result)) {
     156             :                                 /* If this was an error, we can't read the result structure */
     157           0 :                                 continue;
     158             :                         }
     159             : 
     160           2 :                         torture_assert_int_equal(tctx,
     161             :                                                  r.in.req->req1.level, *r.out.level_out,
     162             :                                                  "dcerpc_drsuapi_DsGetDomainControllerInfo in/out level differs");
     163             : 
     164           2 :                         switch (level) {
     165           2 :                         case 1:
     166           2 :                                 for (k=0; k < r.out.ctr->ctr1.count; k++) {
     167           2 :                                         if (strcasecmp_m(r.out.ctr->ctr1.array[k].netbios_name,
     168             :                                                          torture_join_netbios_name(priv->join)) == 0) {
     169           2 :                                                 found = true;
     170           2 :                                                 break;
     171             :                                         }
     172             :                                 }
     173           2 :                                 break;
     174           0 :                         case 2:
     175           0 :                                 for (k=0; k < r.out.ctr->ctr2.count; k++) {
     176           0 :                                         if (strcasecmp_m(r.out.ctr->ctr2.array[k].netbios_name,
     177             :                                                          torture_join_netbios_name(priv->join)) == 0) {
     178           0 :                                                 found = true;
     179           0 :                                                 priv->dcinfo = r.out.ctr->ctr2.array[k];
     180           0 :                                                 break;
     181             :                                         }
     182             :                                 }
     183           0 :                                 break;
     184             :                         }
     185           2 :                         torture_assert(tctx, found,
     186             :                                  "dcerpc_drsuapi_DsGetDomainControllerInfo: Failed to find the domain controller we just created during the join");
     187             :                 }
     188             :         }
     189             : 
     190           0 :         r.in.bind_handle = &priv->bind_handle;
     191           0 :         r.in.level = 1;
     192             : 
     193           0 :         r.out.ctr = &ctr;
     194           0 :         r.out.level_out = &level_out;
     195             : 
     196           0 :         r.in.req->req1.domain_name = "__UNKNOWN_DOMAIN__"; /* This is clearly ignored for this level */
     197           0 :         r.in.req->req1.level = -1;
     198             :         
     199           0 :         torture_comment(tctx, "Testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
     200           0 :                         r.in.req->req1.level, r.in.req->req1.domain_name);
     201             :         
     202           0 :         status = dcerpc_drsuapi_DsGetDomainControllerInfo_r(p->binding_handle, tctx, &r);
     203             : 
     204           0 :         torture_assert_ntstatus_ok(tctx, status,
     205             :                                    "dcerpc_drsuapi_DsGetDomainControllerInfo with dns domain failed");
     206           0 :         torture_assert_werr_ok(tctx, r.out.result,
     207             :                                 "DsGetDomainControllerInfo with dns domain failed");
     208             :         
     209             :         {
     210           0 :                 const char *dc_account = talloc_asprintf(tctx, "%s\\%s$",
     211             :                                                          torture_join_dom_netbios_name(priv->join), 
     212             :                                                          priv->dcinfo.netbios_name);
     213           0 :                 torture_comment(tctx, "%s: Enum active LDAP sessions searching for %s\n", __func__, dc_account);
     214           0 :                 for (k=0; k < r.out.ctr->ctr01.count; k++) {
     215           0 :                         if (strcasecmp_m(r.out.ctr->ctr01.array[k].client_account,
     216             :                                          dc_account)) {
     217           0 :                                 found = true;
     218           0 :                                 break;
     219             :                         }
     220             :                 }
     221           0 :                 torture_assert(tctx, found,
     222             :                         "dcerpc_drsuapi_DsGetDomainControllerInfo level: Failed to find the domain controller in last logon records");
     223             :         }
     224             : 
     225             : 
     226           0 :         return true;
     227             : }
     228             : 
     229           1 : static bool test_DsWriteAccountSpn(struct torture_context *tctx,
     230             :                                    struct DsPrivate *priv)
     231             : {
     232           0 :         NTSTATUS status;
     233           1 :         struct dcerpc_pipe *p = priv->drs_pipe;
     234           0 :         struct drsuapi_DsWriteAccountSpn r;
     235           0 :         union drsuapi_DsWriteAccountSpnRequest req;
     236           0 :         struct drsuapi_DsNameString names[2];
     237           0 :         union drsuapi_DsWriteAccountSpnResult res;
     238           0 :         uint32_t level_out;
     239             : 
     240           1 :         r.in.bind_handle                = &priv->bind_handle;
     241           1 :         r.in.level                      = 1;
     242           1 :         r.in.req                        = &req;
     243             : 
     244           1 :         torture_comment(tctx, "Testing DsWriteAccountSpn\n");
     245             : 
     246           1 :         r.in.req->req1.operation     = DRSUAPI_DS_SPN_OPERATION_ADD;
     247           1 :         r.in.req->req1.unknown1      = 0;
     248           1 :         r.in.req->req1.object_dn     = priv->dcinfo.computer_dn;
     249           1 :         r.in.req->req1.count         = 2;
     250           1 :         r.in.req->req1.spn_names     = names;
     251           1 :         names[0].str = talloc_asprintf(tctx, "smbtortureSPN/%s",priv->dcinfo.netbios_name);
     252           1 :         names[1].str = talloc_asprintf(tctx, "smbtortureSPN/%s",priv->dcinfo.dns_name);
     253             : 
     254           1 :         r.out.res                       = &res;
     255           1 :         r.out.level_out                 = &level_out;
     256             : 
     257           1 :         status = dcerpc_drsuapi_DsWriteAccountSpn_r(p->binding_handle, tctx, &r);
     258           1 :         torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsWriteAccountSpn");
     259             : 
     260           1 :         r.in.req->req1.operation     = DRSUAPI_DS_SPN_OPERATION_DELETE;
     261           1 :         r.in.req->req1.unknown1              = 0;
     262             : 
     263           1 :         status = dcerpc_drsuapi_DsWriteAccountSpn_r(p->binding_handle, tctx, &r);
     264           1 :         torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsWriteAccountSpn");
     265             : 
     266           1 :         return true;
     267             : }
     268             : 
     269           1 : static bool test_DsReplicaGetInfo(struct torture_context *tctx,
     270             :                                   struct DsPrivate *priv)
     271             : {
     272           0 :         NTSTATUS status;
     273           1 :         struct dcerpc_pipe *p = priv->drs_pipe;
     274           0 :         struct drsuapi_DsReplicaGetInfo r;
     275           0 :         union drsuapi_DsReplicaGetInfoRequest req;
     276           0 :         union drsuapi_DsReplicaInfo info;
     277           0 :         enum drsuapi_DsReplicaInfoType info_type;
     278           0 :         int i;
     279           0 :         struct {
     280             :                 int32_t level;
     281             :                 int32_t infotype;
     282             :                 const char *obj_dn;
     283           1 :         } array[] = {
     284             :                 {       
     285             :                         DRSUAPI_DS_REPLICA_GET_INFO,
     286             :                         DRSUAPI_DS_REPLICA_INFO_NEIGHBORS,
     287             :                         NULL
     288             :                 },{
     289             :                         DRSUAPI_DS_REPLICA_GET_INFO,
     290             :                         DRSUAPI_DS_REPLICA_INFO_CURSORS,
     291             :                         NULL
     292             :                 },{
     293             :                         DRSUAPI_DS_REPLICA_GET_INFO,
     294             :                         DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA,
     295             :                         NULL
     296             :                 },{
     297             :                         DRSUAPI_DS_REPLICA_GET_INFO,
     298             :                         DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES,
     299             :                         NULL
     300             :                 },{
     301             :                         DRSUAPI_DS_REPLICA_GET_INFO,
     302             :                         DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES,
     303             :                         NULL
     304             :                 },{
     305             :                         DRSUAPI_DS_REPLICA_GET_INFO,
     306             :                         DRSUAPI_DS_REPLICA_INFO_PENDING_OPS,
     307             :                         NULL
     308             :                 },{
     309             :                         DRSUAPI_DS_REPLICA_GET_INFO2,
     310             :                         DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA,
     311             :                         NULL
     312             :                 },{
     313             :                         DRSUAPI_DS_REPLICA_GET_INFO2,
     314             :                         DRSUAPI_DS_REPLICA_INFO_CURSORS2,
     315             :                         NULL
     316             :                 },{
     317             :                         DRSUAPI_DS_REPLICA_GET_INFO2,
     318             :                         DRSUAPI_DS_REPLICA_INFO_CURSORS3,
     319             :                         NULL
     320             :                 },{
     321             :                         DRSUAPI_DS_REPLICA_GET_INFO2,
     322             :                         DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2,
     323             :                         NULL
     324             :                 },{
     325             :                         DRSUAPI_DS_REPLICA_GET_INFO2,
     326             :                         DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2,
     327             :                         NULL
     328             :                 },{
     329             :                         DRSUAPI_DS_REPLICA_GET_INFO2,
     330             :                         DRSUAPI_DS_REPLICA_INFO_REPSTO,
     331             :                         NULL
     332             :                 },{
     333             :                         DRSUAPI_DS_REPLICA_GET_INFO2,
     334             :                         DRSUAPI_DS_REPLICA_INFO_CLIENT_CONTEXTS,
     335             :                         "__IGNORED__"
     336             :                 },{
     337             :                         DRSUAPI_DS_REPLICA_GET_INFO2,
     338             :                         DRSUAPI_DS_REPLICA_INFO_UPTODATE_VECTOR_V1,
     339             :                         NULL
     340             :                 },{
     341             :                         DRSUAPI_DS_REPLICA_GET_INFO2,
     342             :                         DRSUAPI_DS_REPLICA_INFO_SERVER_OUTGOING_CALLS,
     343             :                         NULL
     344             :                 }
     345             :         };
     346             : 
     347           1 :         if (torture_setting_bool(tctx, "samba4", false)) {
     348           1 :                 torture_comment(tctx, "skipping DsReplicaGetInfo test against Samba4\n");
     349           1 :                 return true;
     350             :         }
     351             : 
     352           0 :         r.in.bind_handle        = &priv->bind_handle;
     353           0 :         r.in.req                = &req;
     354             : 
     355           0 :         for (i=0; i < ARRAY_SIZE(array); i++) {
     356           0 :                 const char *object_dn;
     357             : 
     358           0 :                 torture_comment(tctx, "Testing DsReplicaGetInfo level %d infotype %d\n",
     359             :                                 array[i].level, array[i].infotype);
     360             : 
     361           0 :                 object_dn = (array[i].obj_dn ? array[i].obj_dn : priv->domain_obj_dn);
     362             : 
     363           0 :                 r.in.level = array[i].level;
     364           0 :                 switch(r.in.level) {
     365           0 :                 case DRSUAPI_DS_REPLICA_GET_INFO:
     366           0 :                         r.in.req->req1.info_type     = array[i].infotype;
     367           0 :                         r.in.req->req1.object_dn     = object_dn;
     368           0 :                         ZERO_STRUCT(r.in.req->req1.source_dsa_guid);
     369           0 :                         break;
     370           0 :                 case DRSUAPI_DS_REPLICA_GET_INFO2:
     371           0 :                         r.in.req->req2.info_type     = array[i].infotype;
     372           0 :                         r.in.req->req2.object_dn     = object_dn;
     373           0 :                         ZERO_STRUCT(r.in.req->req2.source_dsa_guid);
     374           0 :                         r.in.req->req2.flags         = 0;
     375           0 :                         r.in.req->req2.attribute_name        = NULL;
     376           0 :                         r.in.req->req2.value_dn_str  = NULL;
     377           0 :                         r.in.req->req2.enumeration_context = 0;
     378           0 :                         break;
     379             :                 }
     380             : 
     381           0 :                 r.out.info              = &info;
     382           0 :                 r.out.info_type         = &info_type;
     383             : 
     384           0 :                 status = dcerpc_drsuapi_DsReplicaGetInfo_r(p->binding_handle, tctx, &r);
     385           0 :                 torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsReplicaGetInfo");
     386           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE)) {
     387           0 :                         torture_comment(tctx,
     388             :                                         "DsReplicaGetInfo level %d and/or infotype %d not supported by server\n",
     389             :                                         array[i].level, array[i].infotype);
     390             :                 } else {
     391           0 :                         torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsReplicaGetInfo");
     392             :                 }
     393             :         }
     394             : 
     395           0 :         return true;
     396             : }
     397             : 
     398           1 : static bool test_DsReplicaSync(struct torture_context *tctx,
     399             :                                 struct DsPrivate *priv)
     400             : {
     401           0 :         NTSTATUS status;
     402           1 :         struct dcerpc_pipe *p = priv->drs_pipe;
     403           0 :         int i;
     404           0 :         struct drsuapi_DsReplicaSync r;
     405           0 :         union drsuapi_DsReplicaSyncRequest sync_req;
     406           0 :         struct drsuapi_DsReplicaObjectIdentifier nc;
     407           0 :         struct dom_sid null_sid;
     408           0 :         struct {
     409             :                 int32_t level;
     410           1 :         } array[] = {
     411             :                 {       
     412             :                         1
     413             :                 }
     414             :         };
     415             : 
     416           1 :         if (!torture_setting_bool(tctx, "dangerous", false)) {
     417           1 :                 torture_comment(tctx, "DsReplicaSync disabled - enable dangerous tests to use\n");
     418           1 :                 return true;
     419             :         }
     420             : 
     421           0 :         if (torture_setting_bool(tctx, "samba4", false)) {
     422           0 :                 torture_comment(tctx, "skipping DsReplicaSync test against Samba4\n");
     423           0 :                 return true;
     424             :         }
     425             : 
     426           0 :         ZERO_STRUCT(null_sid);
     427             : 
     428           0 :         r.in.bind_handle        = &priv->bind_handle;
     429             : 
     430           0 :         for (i=0; i < ARRAY_SIZE(array); i++) {
     431           0 :                 torture_comment(tctx, "Testing DsReplicaSync level %d\n",
     432             :                                 array[i].level);
     433             : 
     434           0 :                 r.in.level = array[i].level;
     435           0 :                 switch(r.in.level) {
     436           0 :                 case 1:
     437           0 :                         nc.guid                                 = GUID_zero();
     438           0 :                         nc.sid                                  = null_sid;
     439           0 :                         nc.dn                                   = priv->domain_obj_dn?priv->domain_obj_dn:"";
     440             : 
     441           0 :                         sync_req.req1.naming_context            = &nc;
     442           0 :                         sync_req.req1.source_dsa_guid           = priv->dcinfo.ntds_guid;
     443           0 :                         sync_req.req1.source_dsa_dns            = NULL;
     444           0 :                         sync_req.req1.options                   = 16;
     445             : 
     446           0 :                         r.in.req                                = &sync_req;
     447           0 :                         break;
     448             :                 }
     449             : 
     450           0 :                 status = dcerpc_drsuapi_DsReplicaSync_r(p->binding_handle, tctx, &r);
     451           0 :                 torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsReplicaSync");
     452             :         }
     453             : 
     454           0 :         return true;
     455             : }
     456             : 
     457           1 : static bool test_DsReplicaUpdateRefs(struct torture_context *tctx,
     458             :                                      struct DsPrivate *priv)
     459             : {
     460           0 :         NTSTATUS status;
     461           1 :         struct dcerpc_pipe *p = priv->drs_pipe;
     462           0 :         struct drsuapi_DsReplicaUpdateRefs r;
     463           0 :         struct drsuapi_DsReplicaObjectIdentifier nc;
     464           0 :         struct GUID dest_dsa_guid;
     465           0 :         const char *dest_dsa_guid_str;
     466           0 :         struct dom_sid null_sid;
     467             : 
     468           1 :         ZERO_STRUCT(null_sid);
     469           1 :         dest_dsa_guid = GUID_random();
     470           1 :         dest_dsa_guid_str = GUID_string(tctx, &dest_dsa_guid);
     471             : 
     472           1 :         r.in.bind_handle = &priv->bind_handle;
     473           1 :         r.in.level       = 1; /* Only version 1 is defined presently */
     474             : 
     475             :         /* setup NC */
     476           1 :         nc.guid         = priv->domain_obj_dn ? GUID_zero():priv->domain_guid;
     477           1 :         nc.sid          = null_sid;
     478           1 :         nc.dn           = priv->domain_obj_dn ? priv->domain_obj_dn : "";
     479             : 
     480             :         /* default setup for request */
     481           1 :         r.in.req.req1.naming_context    = &nc;
     482           1 :         r.in.req.req1.dest_dsa_dns_name = talloc_asprintf(tctx, "%s._msdn.%s",
     483             :                                                                 dest_dsa_guid_str,
     484             :                                                                 priv->domain_dns_name);
     485           1 :         r.in.req.req1.dest_dsa_guid     = dest_dsa_guid;
     486             : 
     487             :         /* 1. deleting replica dest should fail */
     488           1 :         torture_comment(tctx, "delete: %s\n", r.in.req.req1.dest_dsa_dns_name);
     489           1 :         r.in.req.req1.options           = DRSUAPI_DRS_DEL_REF;
     490           1 :         status = dcerpc_drsuapi_DsReplicaUpdateRefs_r(p->binding_handle, tctx, &r);
     491           1 :         torture_drsuapi_assert_call_werr(tctx, p,
     492             :                                          status, WERR_DS_DRA_REF_NOT_FOUND, &r,
     493             :                                          "dcerpc_drsuapi_DsReplicaUpdateRefs");
     494             : 
     495             :         /* 2. hopefully adding random replica dest should succeed */
     496           1 :         torture_comment(tctx, "add    : %s\n", r.in.req.req1.dest_dsa_dns_name);
     497           1 :         r.in.req.req1.options           = DRSUAPI_DRS_ADD_REF;
     498           1 :         status = dcerpc_drsuapi_DsReplicaUpdateRefs_r(p->binding_handle, tctx, &r);
     499           1 :         torture_drsuapi_assert_call_werr(tctx, p,
     500             :                                          status, WERR_OK, &r,
     501             :                                          "dcerpc_drsuapi_DsReplicaUpdateRefs");
     502             : 
     503             :         /* 3. try adding same replica dest - should fail */
     504           1 :         torture_comment(tctx, "add    : %s\n", r.in.req.req1.dest_dsa_dns_name);
     505           1 :         r.in.req.req1.options           = DRSUAPI_DRS_ADD_REF;
     506           1 :         status = dcerpc_drsuapi_DsReplicaUpdateRefs_r(p->binding_handle, tctx, &r);
     507           1 :         torture_drsuapi_assert_call_werr(tctx, p,
     508             :                                          status, WERR_DS_DRA_REF_ALREADY_EXISTS, &r,
     509             :                                          "dcerpc_drsuapi_DsReplicaUpdateRefs");
     510             : 
     511             :         /* 4. try resetting same replica dest - should succeed */
     512           1 :         torture_comment(tctx, "reset : %s\n", r.in.req.req1.dest_dsa_dns_name);
     513           1 :         r.in.req.req1.options           = DRSUAPI_DRS_DEL_REF | DRSUAPI_DRS_ADD_REF;
     514           1 :         status = dcerpc_drsuapi_DsReplicaUpdateRefs_r(p->binding_handle, tctx, &r);
     515           1 :         torture_drsuapi_assert_call_werr(tctx, p,
     516             :                                          status, WERR_OK, &r,
     517             :                                          "dcerpc_drsuapi_DsReplicaUpdateRefs");
     518             : 
     519             :         /* 5. delete random replicate added at step 2. */
     520           1 :         torture_comment(tctx, "delete : %s\n", r.in.req.req1.dest_dsa_dns_name);
     521           1 :         r.in.req.req1.options           = DRSUAPI_DRS_DEL_REF;
     522           1 :         status = dcerpc_drsuapi_DsReplicaUpdateRefs_r(p->binding_handle, tctx, &r);
     523           1 :         torture_drsuapi_assert_call_werr(tctx, p,
     524             :                                          status, WERR_OK, &r,
     525             :                                          "dcerpc_drsuapi_DsReplicaUpdateRefs");
     526             : 
     527             :         /* 6. try replace on non-existing replica dest - should succeed */
     528           1 :         torture_comment(tctx, "replace: %s\n", r.in.req.req1.dest_dsa_dns_name);
     529           1 :         r.in.req.req1.options           = DRSUAPI_DRS_DEL_REF | DRSUAPI_DRS_ADD_REF;
     530           1 :         status = dcerpc_drsuapi_DsReplicaUpdateRefs_r(p->binding_handle, tctx, &r);
     531           1 :         torture_drsuapi_assert_call_werr(tctx, p,
     532             :                                          status, WERR_OK, &r,
     533             :                                          "dcerpc_drsuapi_DsReplicaUpdateRefs");
     534             : 
     535             :         /* 7. delete random replicate added at step 6. */
     536           1 :         torture_comment(tctx, "delete : %s\n", r.in.req.req1.dest_dsa_dns_name);
     537           1 :         r.in.req.req1.options           = DRSUAPI_DRS_DEL_REF;
     538           1 :         status = dcerpc_drsuapi_DsReplicaUpdateRefs_r(p->binding_handle, tctx, &r);
     539           1 :         torture_drsuapi_assert_call_werr(tctx, p,
     540             :                                          status, WERR_OK, &r,
     541             :                                          "dcerpc_drsuapi_DsReplicaUpdateRefs");
     542             : 
     543           1 :         return true;
     544             : }
     545             : 
     546           1 : static bool test_DsGetNCChanges(struct torture_context *tctx,
     547             :                                 struct DsPrivate *priv)
     548             : {
     549           0 :         NTSTATUS status;
     550           1 :         struct dcerpc_pipe *p = priv->drs_pipe;
     551           0 :         int i;
     552           0 :         struct drsuapi_DsGetNCChanges r;
     553           0 :         union drsuapi_DsGetNCChangesRequest req;
     554           0 :         union drsuapi_DsGetNCChangesCtr ctr;
     555           0 :         struct drsuapi_DsReplicaObjectIdentifier nc;
     556           0 :         struct dom_sid null_sid;
     557           0 :         uint32_t level_out;
     558           0 :         struct {
     559             :                 uint32_t level;
     560           1 :         } array[] = {
     561             :                 {       
     562             :                         5
     563             :                 },
     564             :                 {       
     565             :                         8
     566             :                 }
     567             :         };
     568             : 
     569           1 :         if (torture_setting_bool(tctx, "samba4", false)) {
     570           1 :                 torture_comment(tctx, "skipping DsGetNCChanges test against Samba4\n");
     571           1 :                 return true;
     572             :         }
     573             : 
     574           0 :         ZERO_STRUCT(null_sid);
     575             : 
     576           0 :         for (i=0; i < ARRAY_SIZE(array); i++) {
     577           0 :                 torture_comment(tctx,
     578             :                                 "Testing DsGetNCChanges level %d\n",
     579             :                                 array[i].level);
     580             : 
     581           0 :                 r.in.bind_handle        = &priv->bind_handle;
     582           0 :                 r.in.level              = array[i].level;
     583           0 :                 r.out.level_out         = &level_out;
     584           0 :                 r.out.ctr               = &ctr;
     585             : 
     586           0 :                 switch (r.in.level) {
     587           0 :                 case 5:
     588           0 :                         nc.guid = GUID_zero();
     589           0 :                         nc.sid  = null_sid;
     590           0 :                         nc.dn   = priv->domain_obj_dn ? priv->domain_obj_dn : "";
     591             : 
     592           0 :                         r.in.req                                        = &req;
     593           0 :                         r.in.req->req5.destination_dsa_guid          = GUID_random();
     594           0 :                         r.in.req->req5.source_dsa_invocation_id      = GUID_zero();
     595           0 :                         r.in.req->req5.naming_context                        = &nc;
     596           0 :                         r.in.req->req5.highwatermark.tmp_highest_usn = 0;
     597           0 :                         r.in.req->req5.highwatermark.reserved_usn    = 0;
     598           0 :                         r.in.req->req5.highwatermark.highest_usn     = 0;
     599           0 :                         r.in.req->req5.uptodateness_vector           = NULL;
     600           0 :                         r.in.req->req5.replica_flags                 = 0;
     601           0 :                         if (lpcfg_parm_bool(tctx->lp_ctx, NULL, "drsuapi", "compression", false)) {
     602           0 :                                 r.in.req->req5.replica_flags         |= DRSUAPI_DRS_USE_COMPRESSION;
     603             :                         }
     604           0 :                         r.in.req->req5.max_object_count                      = 0;
     605           0 :                         r.in.req->req5.max_ndr_size                  = 0;
     606           0 :                         r.in.req->req5.extended_op                   = DRSUAPI_EXOP_NONE;
     607           0 :                         r.in.req->req5.fsmo_info                     = 0;
     608             : 
     609           0 :                         break;
     610           0 :                 case 8:
     611           0 :                         nc.guid = GUID_zero();
     612           0 :                         nc.sid  = null_sid;
     613           0 :                         nc.dn   = priv->domain_obj_dn ? priv->domain_obj_dn : "";
     614             : 
     615           0 :                         r.in.req                                        = &req;
     616           0 :                         r.in.req->req8.destination_dsa_guid          = GUID_random();
     617           0 :                         r.in.req->req8.source_dsa_invocation_id      = GUID_zero();
     618           0 :                         r.in.req->req8.naming_context                        = &nc;
     619           0 :                         r.in.req->req8.highwatermark.tmp_highest_usn = 0;
     620           0 :                         r.in.req->req8.highwatermark.reserved_usn    = 0;
     621           0 :                         r.in.req->req8.highwatermark.highest_usn     = 0;
     622           0 :                         r.in.req->req8.uptodateness_vector           = NULL;
     623           0 :                         r.in.req->req8.replica_flags                 = 0;
     624           0 :                         if (lpcfg_parm_bool(tctx->lp_ctx, NULL, "drsuapi", "compression", false)) {
     625           0 :                                 r.in.req->req8.replica_flags         |= DRSUAPI_DRS_USE_COMPRESSION;
     626             :                         }
     627           0 :                         if (lpcfg_parm_bool(tctx->lp_ctx, NULL, "drsuapi", "neighbour_writeable", true)) {
     628           0 :                                 r.in.req->req8.replica_flags         |= DRSUAPI_DRS_WRIT_REP;
     629             :                         }
     630           0 :                         r.in.req->req8.replica_flags                 |= DRSUAPI_DRS_INIT_SYNC
     631             :                                                                         | DRSUAPI_DRS_PER_SYNC
     632             :                                                                         | DRSUAPI_DRS_GET_ANC
     633             :                                                                         | DRSUAPI_DRS_NEVER_SYNCED
     634             :                                                                         ;
     635           0 :                         r.in.req->req8.max_object_count                      = 402;
     636           0 :                         r.in.req->req8.max_ndr_size                  = 402116;
     637           0 :                         r.in.req->req8.extended_op                   = DRSUAPI_EXOP_NONE;
     638           0 :                         r.in.req->req8.fsmo_info                     = 0;
     639           0 :                         r.in.req->req8.partial_attribute_set         = NULL;
     640           0 :                         r.in.req->req8.partial_attribute_set_ex              = NULL;
     641           0 :                         r.in.req->req8.mapping_ctr.num_mappings              = 0;
     642           0 :                         r.in.req->req8.mapping_ctr.mappings          = NULL;
     643             : 
     644           0 :                         break;
     645             :                 }
     646             : 
     647           0 :                 status = dcerpc_drsuapi_DsGetNCChanges_r(p->binding_handle, tctx, &r);
     648           0 :                 torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsGetNCChanges");
     649             :         }
     650             : 
     651           0 :         return true;
     652             : }
     653             : 
     654           0 : bool test_QuerySitesByCost(struct torture_context *tctx,
     655             :                            struct DsPrivate *priv)
     656             : {
     657           0 :         NTSTATUS status;
     658           0 :         struct dcerpc_pipe *p = priv->drs_pipe;
     659           0 :         struct drsuapi_QuerySitesByCost r;
     660           0 :         union drsuapi_QuerySitesByCostRequest req;
     661             : 
     662           0 :         const char *my_site = "Default-First-Site-Name";
     663           0 :         const char *remote_site1 = "smbtorture-nonexisting-site1";
     664           0 :         const char *remote_site2 = "smbtorture-nonexisting-site2";
     665             : 
     666           0 :         req.req1.site_from = talloc_strdup(tctx, my_site);
     667           0 :         req.req1.num_req = 2;
     668           0 :         req.req1.site_to = talloc_zero_array(tctx, const char *, 2);
     669           0 :         req.req1.site_to[0] = talloc_strdup(tctx, remote_site1);
     670           0 :         req.req1.site_to[1] = talloc_strdup(tctx, remote_site2);
     671           0 :         req.req1.flags = 0;
     672             : 
     673           0 :         r.in.bind_handle = &priv->bind_handle;
     674           0 :         r.in.level = 1;
     675           0 :         r.in.req = &req;
     676             : 
     677           0 :         status = dcerpc_drsuapi_QuerySitesByCost_r(p->binding_handle, tctx, &r);
     678           0 :         torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_QuerySitesByCost");
     679             : 
     680           0 :         if (W_ERROR_IS_OK(r.out.result)) {
     681           0 :                 torture_assert_werr_equal(tctx,
     682             :                                           r.out.ctr->ctr1.info[0].error_code, WERR_DS_OBJ_NOT_FOUND,
     683             :                                           "dcerpc_drsuapi_QuerySitesByCost");
     684           0 :                 torture_assert_werr_equal(tctx,
     685             :                                           r.out.ctr->ctr1.info[1].error_code, WERR_DS_OBJ_NOT_FOUND,
     686             :                                           "dcerpc_drsuapi_QuerySitesByCost expected error_code WERR_DS_OBJ_NOT_FOUND");
     687             : 
     688           0 :                 torture_assert_int_equal(tctx,
     689             :                                          r.out.ctr->ctr1.info[0].site_cost, -1,
     690             :                                          "dcerpc_drsuapi_QuerySitesByCost");
     691           0 :                 torture_assert_int_equal(tctx,
     692             :                                          r.out.ctr->ctr1.info[1].site_cost, -1,
     693             :                                          "dcerpc_drsuapi_QuerySitesByCost expected site cost");
     694             :         }
     695             : 
     696           0 :         return true;
     697             : 
     698             : 
     699             : }
     700             : 
     701           0 : bool test_DsUnbind(struct dcerpc_pipe *p,
     702             :                    struct torture_context *tctx,
     703             :                    struct DsPrivate *priv)
     704             : {
     705           0 :         NTSTATUS status;
     706           0 :         struct drsuapi_DsUnbind r;
     707             : 
     708           0 :         r.in.bind_handle = &priv->bind_handle;
     709           0 :         r.out.bind_handle = &priv->bind_handle;
     710             : 
     711           0 :         torture_comment(tctx, "Testing DsUnbind\n");
     712             : 
     713           0 :         status = dcerpc_drsuapi_DsUnbind_r(p->binding_handle, tctx, &r);
     714           0 :         torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsUnbind");
     715             : 
     716           0 :         return true;
     717             : }
     718             : 
     719             : 
     720             : /**
     721             :  * Helper func to collect DC information for testing purposes.
     722             :  * This function is almost identical to test_DsGetDomainControllerInfo
     723             :  */
     724           2 : bool torture_rpc_drsuapi_get_dcinfo(struct torture_context *torture,
     725             :                                     struct DsPrivate *priv)
     726             : {
     727           0 :         NTSTATUS status;
     728           2 :         int32_t level_out = 0;
     729           0 :         struct drsuapi_DsGetDomainControllerInfo r;
     730           0 :         union drsuapi_DsGetDCInfoCtr ctr;
     731           0 :         int j, k;
     732           4 :         const char *names[] = {
     733           2 :                                 torture_join_dom_netbios_name(priv->join),
     734           2 :                                 torture_join_dom_dns_name(priv->join)};
     735             : 
     736           2 :         for (j=0; j < ARRAY_SIZE(names); j++) {
     737           0 :                 union drsuapi_DsGetDCInfoRequest req;
     738           2 :                 struct dcerpc_binding_handle *b = priv->drs_pipe->binding_handle;
     739           2 :                 r.in.bind_handle = &priv->bind_handle;
     740           2 :                 r.in.level = 1;
     741           2 :                 r.in.req = &req;
     742             : 
     743           2 :                 r.in.req->req1.domain_name = names[j];
     744           2 :                 r.in.req->req1.level = 2;
     745             : 
     746           2 :                 r.out.ctr = &ctr;
     747           2 :                 r.out.level_out = &level_out;
     748             : 
     749           2 :                 status = dcerpc_drsuapi_DsGetDomainControllerInfo_r(b, torture, &r);
     750           2 :                 if (!NT_STATUS_IS_OK(status)) {
     751           0 :                         continue;
     752             :                 }
     753           2 :                 if (!W_ERROR_IS_OK(r.out.result)) {
     754             :                         /* If this was an error, we can't read the result structure */
     755           0 :                         continue;
     756             :                 }
     757             : 
     758           2 :                 for (k=0; k < r.out.ctr->ctr2.count; k++) {
     759           2 :                         if (strcasecmp_m(r.out.ctr->ctr2.array[k].netbios_name,
     760             :                                          torture_join_netbios_name(priv->join)) == 0) {
     761           2 :                                 priv->dcinfo = r.out.ctr->ctr2.array[k];
     762           2 :                                 return true;
     763             :                         }
     764             :                 }
     765             :         }
     766             : 
     767           0 :         return false;
     768             : }
     769             : 
     770             : /**
     771             :  * Common test case setup function to be used
     772             :  * in DRS suit of test when appropriate
     773             :  */
     774           4 : bool torture_drsuapi_tcase_setup_common(struct torture_context *tctx, struct DsPrivate *priv)
     775             : {
     776           0 :         NTSTATUS status;
     777           4 :         int rnd = rand() % 1000;
     778           4 :         char *name = talloc_asprintf(tctx, "%s%d", TEST_MACHINE_NAME, rnd);
     779             : 
     780           4 :         torture_assert(tctx, priv, "Invalid argument");
     781             : 
     782           4 :         priv->admin_credentials = samba_cmdline_get_creds();
     783             : 
     784           4 :         torture_comment(tctx, "Create DRSUAPI pipe\n");
     785           4 :         status = torture_rpc_connection(tctx,
     786             :                                         &priv->drs_pipe,
     787             :                                         &ndr_table_drsuapi);
     788           4 :         torture_assert(tctx, NT_STATUS_IS_OK(status), "Unable to connect to DRSUAPI pipe");
     789             : 
     790           4 :         torture_comment(tctx, "About to join domain with name %s\n", name);
     791           4 :         priv->join = torture_join_domain(tctx, name, ACB_SVRTRUST,
     792             :                                          &priv->dc_credentials);
     793           4 :         torture_assert(tctx, priv->join, "Failed to join as BDC");
     794             : 
     795           4 :         if (!test_DsBind(priv->drs_pipe, tctx,
     796             :                          &priv->bind_handle,
     797             :                          &priv->srv_bind_info))
     798             :         {
     799             :                 /* clean up */
     800           2 :                 torture_drsuapi_tcase_teardown_common(tctx, priv);
     801           2 :                 torture_fail(tctx, "Failed execute test_DsBind()");
     802             :         }
     803             : 
     804             :         /* try collect some information for testing */
     805           2 :         torture_rpc_drsuapi_get_dcinfo(tctx, priv);
     806             : 
     807           2 :         return true;
     808             : }
     809             : 
     810             : /**
     811             :  * Common test case teardown function to be used
     812             :  * in DRS suit of test when appropriate
     813             :  */
     814           4 : bool torture_drsuapi_tcase_teardown_common(struct torture_context *tctx, struct DsPrivate *priv)
     815             : {
     816           4 :         if (priv->join) {
     817           4 :                 torture_leave_domain(tctx, priv->join);
     818             :         }
     819             : 
     820           4 :         return true;
     821             : }
     822             : 
     823             : /**
     824             :  * Test case setup for DRSUAPI test case
     825             :  */
     826           3 : static bool torture_drsuapi_tcase_setup(struct torture_context *tctx, void **data)
     827             : {
     828           0 :         struct DsPrivate *priv;
     829             : 
     830           3 :         *data = priv = talloc_zero(tctx, struct DsPrivate);
     831             : 
     832           3 :         return torture_drsuapi_tcase_setup_common(tctx, priv);
     833             : }
     834             : 
     835             : /**
     836             :  * Test case tear-down for DRSUAPI test case
     837             :  */
     838           1 : static bool torture_drsuapi_tcase_teardown(struct torture_context *tctx, void *data)
     839             : {
     840           0 :         bool ret;
     841           1 :         struct DsPrivate *priv = talloc_get_type(data, struct DsPrivate);
     842             : 
     843           1 :         ret = torture_drsuapi_tcase_teardown_common(tctx, priv);
     844             : 
     845           1 :         talloc_free(priv);
     846           1 :         return ret;
     847             : }
     848             : 
     849           3 : static bool __test_DsBind_assoc_group(struct torture_context *tctx,
     850             :                                       const char *testname,
     851             :                                       struct DsPrivate *priv,
     852             :                                       struct cli_credentials *creds)
     853             : {
     854           0 :         NTSTATUS status;
     855           0 :         const char *err_msg;
     856           0 :         struct drsuapi_DsCrackNames r;
     857           0 :         union drsuapi_DsNameRequest req;
     858           0 :         uint32_t level_out;
     859           0 :         union drsuapi_DsNameCtr ctr;
     860           0 :         struct drsuapi_DsNameString names[1];
     861           3 :         const char *dom_sid = NULL;
     862           3 :         struct dcerpc_pipe *p1 = NULL;
     863           3 :         struct dcerpc_pipe *p2 = NULL;
     864           3 :         TALLOC_CTX *mem_ctx = priv;
     865           3 :         struct dcerpc_binding *binding = NULL;
     866           3 :         struct policy_handle ds_bind_handle = { .handle_type = 0, };
     867             : 
     868           3 :         torture_comment(tctx, "%s: starting...\n", testname);
     869             : 
     870           3 :         torture_assert_ntstatus_ok(tctx,
     871             :                                    torture_rpc_binding(tctx, &binding),
     872             :                                    "torture_rpc_binding");
     873             : 
     874           3 :         torture_assert_ntstatus_ok(tctx,
     875             :                                    dcerpc_pipe_connect_b(tctx,
     876             :                                                          &p1,
     877             :                                                          binding,
     878             :                                                          &ndr_table_drsuapi,
     879             :                                                          creds,
     880             :                                                          tctx->ev,
     881             :                                                          tctx->lp_ctx),
     882             :                                    "connect p1");
     883             : 
     884           3 :         torture_assert_ntstatus_ok(tctx,
     885             :                                    dcerpc_pipe_connect_b(tctx,
     886             :                                                          &p2,
     887             :                                                          p1->binding,
     888             :                                                          &ndr_table_drsuapi,
     889             :                                                          creds,
     890             :                                                          tctx->ev,
     891             :                                                          tctx->lp_ctx),
     892             :                                    "connect p2");
     893             : 
     894           3 :         torture_assert(tctx, test_DsBind(p1, tctx, &ds_bind_handle, NULL), "DsBind");
     895             : 
     896           3 :         ZERO_STRUCT(r);
     897           3 :         r.in.bind_handle                = &ds_bind_handle;
     898           3 :         r.in.level                      = 1;
     899           3 :         r.in.req                        = &req;
     900           3 :         r.in.req->req1.codepage              = 1252; /* german */
     901           3 :         r.in.req->req1.language              = 0x00000407; /* german */
     902           3 :         r.in.req->req1.count         = 1;
     903           3 :         r.in.req->req1.names         = names;
     904           3 :         r.in.req->req1.format_flags  = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
     905             : 
     906           3 :         r.in.req->req1.format_offered        = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY;
     907           3 :         r.in.req->req1.format_desired        = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
     908             : 
     909           3 :         r.out.level_out                 = &level_out;
     910           3 :         r.out.ctr                       = &ctr;
     911             : 
     912           3 :         dom_sid = dom_sid_string(mem_ctx, torture_join_sid(priv->join));
     913             : 
     914           3 :         names[0].str = dom_sid;
     915             : 
     916           3 :         torture_comment(tctx, "Testing DsCrackNames on p1 with name '%s'"
     917             :                               " offered format: %d desired format:%d\n",
     918             :                         names[0].str,
     919           3 :                         r.in.req->req1.format_offered,
     920           3 :                         r.in.req->req1.format_desired);
     921           3 :         status = dcerpc_drsuapi_DsCrackNames_r(p1->binding_handle, mem_ctx, &r);
     922           3 :         if (!NT_STATUS_IS_OK(status)) {
     923           0 :                 const char *errstr = nt_errstr(status);
     924           0 :                 err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
     925           0 :                 torture_fail(tctx, err_msg);
     926           3 :         } else if (!W_ERROR_IS_OK(r.out.result)) {
     927           0 :                 err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
     928           0 :                 torture_fail(tctx, err_msg);
     929           3 :         } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
     930           0 :                 err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
     931           0 :                                           r.out.ctr->ctr1->array[0].status);
     932           0 :                 torture_fail(tctx, err_msg);
     933             :         }
     934             : 
     935           3 :         torture_comment(tctx, "Testing DsCrackNames on p2 with name '%s'"
     936             :                               " offered format: %d desired format:%d\n",
     937             :                         names[0].str,
     938           3 :                         r.in.req->req1.format_offered,
     939           3 :                         r.in.req->req1.format_desired);
     940           3 :         status = dcerpc_drsuapi_DsCrackNames_r(p2->binding_handle, mem_ctx, &r);
     941           3 :         if (!NT_STATUS_IS_OK(status)) {
     942           0 :                 const char *errstr = nt_errstr(status);
     943           0 :                 err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
     944           0 :                 torture_fail(tctx, err_msg);
     945           3 :         } else if (!W_ERROR_IS_OK(r.out.result)) {
     946           0 :                 err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
     947           0 :                 torture_fail(tctx, err_msg);
     948           3 :         } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
     949           0 :                 err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
     950           0 :                                           r.out.ctr->ctr1->array[0].status);
     951           0 :                 torture_fail(tctx, err_msg);
     952             :         }
     953             : 
     954           3 :         TALLOC_FREE(p1);
     955             : 
     956           3 :         torture_comment(tctx, "Testing DsCrackNames on p2 (with p1 closed) with name '%s'"
     957             :                               " offered format: %d desired format:%d\n",
     958             :                         names[0].str,
     959           3 :                         r.in.req->req1.format_offered,
     960           3 :                         r.in.req->req1.format_desired);
     961           3 :         status = dcerpc_drsuapi_DsCrackNames_r(p2->binding_handle, mem_ctx, &r);
     962           3 :         if (!NT_STATUS_IS_OK(status)) {
     963           0 :                 const char *errstr = nt_errstr(status);
     964           0 :                 err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
     965           0 :                 torture_fail(tctx, err_msg);
     966           3 :         } else if (!W_ERROR_IS_OK(r.out.result)) {
     967           0 :                 err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
     968           0 :                 torture_fail(tctx, err_msg);
     969           3 :         } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
     970           0 :                 err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
     971           0 :                                           r.out.ctr->ctr1->array[0].status);
     972           0 :                 torture_fail(tctx, err_msg);
     973             :         }
     974             : 
     975           3 :         torture_comment(tctx, "%s: ... finished\n", testname);
     976           3 :         return true;
     977             : }
     978             : 
     979           1 : static bool test_DsBindAssocGroupAdmin(struct torture_context *tctx,
     980             :                                        struct DsPrivate *priv,
     981             :                                        struct cli_credentials *creds)
     982             : {
     983           1 :         return __test_DsBind_assoc_group(tctx, __func__, priv,
     984             :                                          priv->admin_credentials);
     985             : }
     986             : 
     987           1 : static bool test_DsBindAssocGroupDC(struct torture_context *tctx,
     988             :                                     struct DsPrivate *priv,
     989             :                                     struct cli_credentials *creds)
     990             : {
     991           1 :         return __test_DsBind_assoc_group(tctx, __func__, priv,
     992             :                                          priv->dc_credentials);
     993             : }
     994             : 
     995           1 : static bool test_DsBindAssocGroupWS(struct torture_context *tctx,
     996             :                                     struct DsPrivate *priv,
     997             :                                     struct cli_credentials *creds)
     998             : {
     999           1 :         struct test_join *wks_join = NULL;
    1000           1 :         struct cli_credentials *wks_credentials = NULL;
    1001           1 :         int rnd = rand() % 1000;
    1002           1 :         char *wks_name = talloc_asprintf(tctx, "WKS%s%d", TEST_MACHINE_NAME, rnd);
    1003           0 :         bool ret;
    1004             : 
    1005           1 :         torture_comment(tctx, "%s: About to join workstation with name %s\n",
    1006             :                         __func__, wks_name);
    1007           1 :         wks_join = torture_join_domain(tctx, wks_name, ACB_WSTRUST,
    1008             :                                        &wks_credentials);
    1009           1 :         torture_assert(tctx, wks_join, "Failed to join as WORKSTATION");
    1010           1 :         ret = __test_DsBind_assoc_group(tctx, __func__, priv,
    1011             :                                         wks_credentials);
    1012           1 :         torture_leave_domain(tctx, wks_join);
    1013           1 :         return ret;
    1014             : }
    1015             : 
    1016             : /**
    1017             :  * DRSUAPI test case implementation
    1018             :  */
    1019        2354 : void torture_rpc_drsuapi_tcase(struct torture_suite *suite)
    1020             : {
    1021         125 :         typedef bool (*run_func) (struct torture_context *test, void *tcase_data);
    1022             : 
    1023        2354 :         struct torture_tcase *tcase = torture_suite_add_tcase(suite, "drsuapi");
    1024             : 
    1025        2354 :         torture_tcase_set_fixture(tcase, torture_drsuapi_tcase_setup,
    1026             :                                   torture_drsuapi_tcase_teardown);
    1027             : 
    1028             : #if 0
    1029             :         test = torture_tcase_add_simple_test(tcase, "QuerySitesByCost", (run_func)test_QuerySitesByCost);
    1030             : #endif
    1031             : 
    1032        2354 :         torture_tcase_add_simple_test(tcase, "DsGetDomainControllerInfo", (run_func)test_DsGetDomainControllerInfo);
    1033             : 
    1034        2354 :         torture_tcase_add_simple_test(tcase, "DsCrackNames", (run_func)test_DsCrackNames);
    1035             : 
    1036        2354 :         torture_tcase_add_simple_test(tcase, "DsWriteAccountSpn", (run_func)test_DsWriteAccountSpn);
    1037             : 
    1038        2354 :         torture_tcase_add_simple_test(tcase, "DsReplicaGetInfo", (run_func)test_DsReplicaGetInfo);
    1039             : 
    1040        2354 :         torture_tcase_add_simple_test(tcase, "DsReplicaSync", (run_func)test_DsReplicaSync);
    1041             : 
    1042        2354 :         torture_tcase_add_simple_test(tcase, "DsReplicaUpdateRefs", (run_func)test_DsReplicaUpdateRefs);
    1043             : 
    1044        2354 :         torture_tcase_add_simple_test(tcase, "DsGetNCChanges", (run_func)test_DsGetNCChanges);
    1045             : 
    1046        2354 :         torture_tcase_add_simple_test(tcase, "DsBindAssocGroupAdmin", (run_func)test_DsBindAssocGroupAdmin);
    1047        2354 :         torture_tcase_add_simple_test(tcase, "DsBindAssocGroupDC", (run_func)test_DsBindAssocGroupDC);
    1048        2354 :         torture_tcase_add_simple_test(tcase, "DsBindAssocGroupWS", (run_func)test_DsBindAssocGroupWS);
    1049        2354 : }

Generated by: LCOV version 1.14