LCOV - code coverage report
Current view: top level - source4/torture/rpc - fsrvp.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 22 440 5.0 %
Date: 2024-06-13 04:01:37 Functions: 2 15 13.3 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    test suite for File Server Remote VSS Protocol operations
       5             : 
       6             :    Copyright (C) David Disseldorp 2012-2013
       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             : /*
      23             :  * Windows Server "8" Beta is very picky in how it accepts FSRVP requests, the
      24             :  * client must be a member of the same AD domain, ndr64 and signing must be
      25             :  * negotiated for the DCE/RPC bind. E.g.
      26             :  *
      27             :  * smbtorture ncacn_np:LUTZE[/pipe/FssagentRpc,smb2,ndr64,sign] \
      28             :  *            -U 'DOM\user%pw' rpc.fsrvp
      29             :  *
      30             :  * This test suite requires a snapshotable share named FSHARE (see #def below).
      31             :  */
      32             : #include "includes.h"
      33             : #include "lib/param/param.h"
      34             : #include "libcli/smb2/smb2.h"
      35             : #include "libcli/smb2/smb2_calls.h"
      36             : #include "libcli/smb_composite/smb_composite.h"
      37             : #include "libcli/resolve/resolve.h"
      38             : #include "libcli/util/hresult.h"
      39             : #include "libcli/security/dom_sid.h"
      40             : #include "libcli/security/security_descriptor.h"
      41             : #include "torture/torture.h"
      42             : #include "torture/smb2/proto.h"
      43             : #include "torture/rpc/torture_rpc.h"
      44             : #include "librpc/gen_ndr/ndr_security.h"
      45             : #include "librpc/gen_ndr/ndr_srvsvc_c.h"
      46             : #include "librpc/gen_ndr/ndr_fsrvp_c.h"
      47             : #include "lib/cmdline/cmdline.h"
      48             : 
      49             : #define FSHARE  "fsrvp_share"
      50             : #define FNAME   "testfss.dat"
      51             : 
      52           0 : static bool test_fsrvp_is_path_supported(struct torture_context *tctx,
      53             :                                          struct dcerpc_pipe *p)
      54             : {
      55             :         struct fss_IsPathSupported r;
      56           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
      57             :         NTSTATUS status;
      58             : 
      59           0 :         ZERO_STRUCT(r);
      60           0 :         r.in.ShareName = talloc_asprintf(tctx,"\\\\%s\\%s\\",
      61             :                                          dcerpc_server_name(p),
      62             :                                          FSHARE);
      63           0 :         status = dcerpc_fss_IsPathSupported_r(b, tctx, &r);
      64           0 :         torture_assert_ntstatus_ok(tctx, status,
      65             :                                    "IsPathSupported failed");
      66             : 
      67           0 :         torture_assert(tctx, *r.out.SupportedByThisProvider,
      68             :                        "path not supported");
      69             : 
      70           0 :         torture_comment(tctx, "path %s is supported by fsrvp server %s\n",
      71           0 :                         r.in.ShareName, *r.out.OwnerMachineName);
      72             : 
      73           0 :         return true;
      74             : }
      75             : 
      76           0 : static bool test_fsrvp_get_version(struct torture_context *tctx,
      77             :                                    struct dcerpc_pipe *p)
      78             : {
      79             :         struct fss_GetSupportedVersion r;
      80           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
      81             :         NTSTATUS status;
      82             : 
      83           0 :         ZERO_STRUCT(r);
      84           0 :         status = dcerpc_fss_GetSupportedVersion_r(b, tctx, &r);
      85           0 :         torture_assert_ntstatus_ok(tctx, status,
      86             :                                    "GetSupportedVersion failed");
      87             : 
      88           0 :         torture_comment(tctx, "got MinVersion %u\n", *r.out.MinVersion);
      89           0 :         torture_comment(tctx, "got MaxVersion %u\n", *r.out.MaxVersion);
      90             : 
      91           0 :         return true;
      92             : }
      93             : 
      94           0 : static bool test_fsrvp_set_ctx(struct torture_context *tctx,
      95             :                                struct dcerpc_pipe *p)
      96             : {
      97             :         struct fss_SetContext r;
      98           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
      99             :         NTSTATUS status;
     100             : 
     101           0 :         ZERO_STRUCT(r);
     102           0 :         r.in.Context = FSRVP_CTX_BACKUP;
     103           0 :         status = dcerpc_fss_SetContext_r(b, tctx, &r);
     104           0 :         torture_assert_ntstatus_ok(tctx, status, "SetContext failed");
     105             : 
     106           0 :         return true;
     107             : }
     108             : 
     109             : enum test_fsrvp_inject {
     110             :         TEST_FSRVP_TOUT_NONE = 0,
     111             :         TEST_FSRVP_TOUT_SET_CTX,
     112             :         TEST_FSRVP_TOUT_START_SET,
     113             :         TEST_FSRVP_TOUT_ADD_TO_SET,
     114             :         TEST_FSRVP_TOUT_PREPARE,
     115             :         TEST_FSRVP_TOUT_COMMIT,
     116             : 
     117             :         TEST_FSRVP_STOP_B4_EXPOSE,
     118             : };
     119             : 
     120           0 : static bool test_fsrvp_sc_create(struct torture_context *tctx,
     121             :                                  struct dcerpc_pipe *p,
     122             :                                  const char *share,
     123             :                                  enum test_fsrvp_inject inject,
     124             :                                  struct fssagent_share_mapping_1 **sc_map)
     125             : {
     126             :         struct fss_IsPathSupported r_pathsupport_get;
     127             :         struct fss_GetSupportedVersion r_version_get;
     128             :         struct fss_SetContext r_context_set;
     129             :         struct fss_StartShadowCopySet r_scset_start;
     130             :         struct fss_AddToShadowCopySet r_scset_add1;
     131             :         struct fss_AddToShadowCopySet r_scset_add2;
     132             :         struct fss_PrepareShadowCopySet r_scset_prep;
     133             :         struct fss_CommitShadowCopySet r_scset_commit;
     134             :         struct fss_ExposeShadowCopySet r_scset_expose;
     135             :         struct fss_GetShareMapping r_sharemap_get;
     136           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     137             :         NTSTATUS status;
     138             :         time_t start_time;
     139           0 :         TALLOC_CTX *tmp_ctx = talloc_new(tctx);
     140           0 :         struct fssagent_share_mapping_1 *map = NULL;
     141             :         int sleep_time;
     142             : 
     143             :         /*
     144             :          * PrepareShadowCopySet & CommitShadowCopySet often exceed the default
     145             :          * 60 second dcerpc request timeout against Windows Server "8" Beta.
     146             :          */
     147           0 :         dcerpc_binding_handle_set_timeout(b, 240);
     148             : 
     149           0 :         ZERO_STRUCT(r_pathsupport_get);
     150           0 :         r_pathsupport_get.in.ShareName = share;
     151           0 :         status = dcerpc_fss_IsPathSupported_r(b, tmp_ctx, &r_pathsupport_get);
     152           0 :         torture_assert_ntstatus_ok(tctx, status,
     153             :                                    "IsPathSupported failed");
     154           0 :         torture_assert_int_equal(tctx, r_pathsupport_get.out.result, 0,
     155             :                                  "failed IsPathSupported response");
     156           0 :         torture_assert(tctx, r_pathsupport_get.out.SupportedByThisProvider,
     157             :                        "path not supported");
     158             : 
     159           0 :         ZERO_STRUCT(r_version_get);
     160           0 :         status = dcerpc_fss_GetSupportedVersion_r(b, tmp_ctx, &r_version_get);
     161           0 :         torture_assert_ntstatus_ok(tctx, status,
     162             :                                    "GetSupportedVersion failed");
     163           0 :         torture_assert_int_equal(tctx, r_version_get.out.result, 0,
     164             :                                  "failed GetSupportedVersion response");
     165             : 
     166           0 :         ZERO_STRUCT(r_context_set);
     167           0 :         r_context_set.in.Context = FSRVP_CTX_BACKUP;
     168           0 :         status = dcerpc_fss_SetContext_r(b, tmp_ctx, &r_context_set);
     169           0 :         torture_assert_ntstatus_ok(tctx, status, "SetContext failed");
     170           0 :         torture_assert_int_equal(tctx, r_context_set.out.result, 0,
     171             :                                  "failed SetContext response");
     172             : 
     173           0 :         if (inject == TEST_FSRVP_TOUT_SET_CTX) {
     174           0 :                 sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss",
     175             :                                             "sequence timeout", 180);
     176           0 :                 torture_comment(tctx, "sleeping for %d\n", sleep_time);
     177           0 :                 smb_msleep((sleep_time * 1000) + 500);
     178             :         }
     179             : 
     180           0 :         ZERO_STRUCT(r_scset_start);
     181           0 :         r_scset_start.in.ClientShadowCopySetId = GUID_random();
     182           0 :         status = dcerpc_fss_StartShadowCopySet_r(b, tmp_ctx, &r_scset_start);
     183           0 :         torture_assert_ntstatus_ok(tctx, status,
     184             :                                    "StartShadowCopySet failed");
     185           0 :         if (inject == TEST_FSRVP_TOUT_SET_CTX) {
     186             :                 /* expect error due to message sequence timeout after set_ctx */
     187           0 :                 torture_assert_int_equal(tctx, r_scset_start.out.result,
     188             :                                          FSRVP_E_BAD_STATE,
     189             :                                          "StartShadowCopySet timeout response");
     190           0 :                 goto done;
     191             :         }
     192           0 :         torture_assert_int_equal(tctx, r_scset_start.out.result, 0,
     193             :                                  "failed StartShadowCopySet response");
     194           0 :         torture_comment(tctx, "%s: shadow-copy set created\n",
     195           0 :                         GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId));
     196             : 
     197           0 :         if (inject == TEST_FSRVP_TOUT_START_SET) {
     198           0 :                 sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss",
     199             :                                             "sequence timeout", 180);
     200           0 :                 torture_comment(tctx, "sleeping for %d\n", sleep_time);
     201           0 :                 smb_msleep((sleep_time * 1000) + 500);
     202             :         }
     203             : 
     204           0 :         ZERO_STRUCT(r_scset_add1);
     205           0 :         r_scset_add1.in.ClientShadowCopyId = GUID_random();
     206           0 :         r_scset_add1.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
     207           0 :         r_scset_add1.in.ShareName = share;
     208           0 :         status = dcerpc_fss_AddToShadowCopySet_r(b, tmp_ctx, &r_scset_add1);
     209           0 :         torture_assert_ntstatus_ok(tctx, status,
     210             :                                    "AddToShadowCopySet failed");
     211           0 :         if (inject == TEST_FSRVP_TOUT_START_SET) {
     212           0 :                 torture_assert_int_equal(tctx, r_scset_add1.out.result,
     213             :                                          HRES_ERROR_V(HRES_E_INVALIDARG),
     214             :                                          "AddToShadowCopySet timeout response");
     215           0 :                 goto done;
     216             :         }
     217           0 :         torture_assert_int_equal(tctx, r_scset_add1.out.result, 0,
     218             :                                  "failed AddToShadowCopySet response");
     219           0 :         torture_comment(tctx, "%s(%s): %s added to shadow-copy set\n",
     220           0 :                         GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId),
     221           0 :                         GUID_string(tmp_ctx, r_scset_add1.out.pShadowCopyId),
     222             :                         r_scset_add1.in.ShareName);
     223             : 
     224             :         /* attempts to add the same share twice should fail */
     225           0 :         ZERO_STRUCT(r_scset_add2);
     226           0 :         r_scset_add2.in.ClientShadowCopyId = GUID_random();
     227           0 :         r_scset_add2.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
     228           0 :         r_scset_add2.in.ShareName = share;
     229           0 :         status = dcerpc_fss_AddToShadowCopySet_r(b, tmp_ctx, &r_scset_add2);
     230           0 :         torture_assert_ntstatus_ok(tctx, status,
     231             :                                    "AddToShadowCopySet failed");
     232           0 :         torture_assert_int_equal(tctx, r_scset_add2.out.result,
     233             :                                  FSRVP_E_OBJECT_ALREADY_EXISTS,
     234             :                                  "failed AddToShadowCopySet response");
     235             : 
     236           0 :         if (inject == TEST_FSRVP_TOUT_ADD_TO_SET) {
     237           0 :                 sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss",
     238             :                                             "sequence timeout", 1800);
     239           0 :                 torture_comment(tctx, "sleeping for %d\n", sleep_time);
     240           0 :                 smb_msleep((sleep_time * 1000) + 500);
     241             :         }
     242             : 
     243           0 :         start_time = time_mono(NULL);
     244           0 :         ZERO_STRUCT(r_scset_prep);
     245           0 :         r_scset_prep.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
     246             : //      r_scset_prep.in.TimeOutInMilliseconds = (1800 * 1000);  /* win8 */
     247           0 :         r_scset_prep.in.TimeOutInMilliseconds = (240 * 1000);
     248           0 :         status = dcerpc_fss_PrepareShadowCopySet_r(b, tmp_ctx, &r_scset_prep);
     249           0 :         torture_assert_ntstatus_ok(tctx, status,
     250             :                                    "PrepareShadowCopySet failed");
     251           0 :         if (inject == TEST_FSRVP_TOUT_ADD_TO_SET) {
     252           0 :                 torture_assert_int_equal(tctx, r_scset_prep.out.result,
     253             :                                          HRES_ERROR_V(HRES_E_INVALIDARG),
     254             :                                          "PrepareShadowCopySet tout response");
     255           0 :                 goto done;
     256             :         }
     257           0 :         torture_assert_int_equal(tctx, r_scset_prep.out.result, 0,
     258             :                                  "failed PrepareShadowCopySet response");
     259           0 :         torture_comment(tctx, "%s: prepare completed in %llu secs\n",
     260           0 :                         GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId),
     261           0 :                         (unsigned long long)(time_mono(NULL) - start_time));
     262             : 
     263           0 :         if (inject == TEST_FSRVP_TOUT_PREPARE) {
     264           0 :                 sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss",
     265             :                                             "sequence timeout", 1800);
     266           0 :                 torture_comment(tctx, "sleeping for %d\n", sleep_time);
     267           0 :                 smb_msleep((sleep_time * 1000) + 500);
     268             :         }
     269             : 
     270           0 :         start_time = time_mono(NULL);
     271           0 :         ZERO_STRUCT(r_scset_commit);
     272           0 :         r_scset_commit.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
     273           0 :         r_scset_commit.in.TimeOutInMilliseconds = (180 * 1000); /* win8 */
     274           0 :         status = dcerpc_fss_CommitShadowCopySet_r(b, tmp_ctx, &r_scset_commit);
     275           0 :         torture_assert_ntstatus_ok(tctx, status,
     276             :                                    "CommitShadowCopySet failed");
     277           0 :         if (inject == TEST_FSRVP_TOUT_PREPARE) {
     278           0 :                 torture_assert_int_equal(tctx, r_scset_commit.out.result,
     279             :                                          HRES_ERROR_V(HRES_E_INVALIDARG),
     280             :                                          "CommitShadowCopySet tout response");
     281           0 :                 goto done;
     282             :         }
     283           0 :         torture_assert_int_equal(tctx, r_scset_commit.out.result, 0,
     284             :                                  "failed CommitShadowCopySet response");
     285           0 :         torture_comment(tctx, "%s: commit completed in %llu secs\n",
     286           0 :                         GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId),
     287           0 :                         (unsigned long long)(time_mono(NULL) - start_time));
     288             : 
     289           0 :         if (inject == TEST_FSRVP_TOUT_COMMIT) {
     290           0 :                 sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss",
     291             :                                             "sequence timeout", 180);
     292           0 :                 torture_comment(tctx, "sleeping for %d\n", sleep_time);
     293           0 :                 smb_msleep((sleep_time * 1000) + 500);
     294           0 :         } else if (inject == TEST_FSRVP_STOP_B4_EXPOSE) {
     295             :                 /* return partial snapshot information */
     296           0 :                 map = talloc_zero(tctx, struct fssagent_share_mapping_1);
     297           0 :                 map->ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
     298           0 :                 map->ShadowCopyId = *r_scset_add1.out.pShadowCopyId;
     299           0 :                 goto done;
     300             :         }
     301             : 
     302           0 :         start_time = time_mono(NULL);
     303           0 :         ZERO_STRUCT(r_scset_expose);
     304           0 :         r_scset_expose.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
     305           0 :         r_scset_expose.in.TimeOutInMilliseconds = (120 * 1000); /* win8 */
     306           0 :         status = dcerpc_fss_ExposeShadowCopySet_r(b, tmp_ctx, &r_scset_expose);
     307           0 :         torture_assert_ntstatus_ok(tctx, status,
     308             :                                    "ExposeShadowCopySet failed");
     309           0 :         if (inject == TEST_FSRVP_TOUT_COMMIT) {
     310           0 :                 torture_assert_int_equal(tctx, r_scset_expose.out.result,
     311             :                                          HRES_ERROR_V(HRES_E_INVALIDARG),
     312             :                                          "ExposeShadowCopySet tout response");
     313           0 :                 goto done;
     314             :         }
     315           0 :         torture_assert_int_equal(tctx, r_scset_expose.out.result, 0,
     316             :                                  "failed ExposeShadowCopySet response");
     317           0 :         torture_comment(tctx, "%s: expose completed in %llu secs\n",
     318           0 :                         GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId),
     319           0 :                         (unsigned long long)(time_mono(NULL) - start_time));
     320             : 
     321           0 :         ZERO_STRUCT(r_sharemap_get);
     322           0 :         r_sharemap_get.in.ShadowCopyId = *r_scset_add1.out.pShadowCopyId;
     323           0 :         r_sharemap_get.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
     324           0 :         r_sharemap_get.in.ShareName = r_scset_add1.in.ShareName;
     325           0 :         r_sharemap_get.in.Level = 1;
     326           0 :         status = dcerpc_fss_GetShareMapping_r(b, tmp_ctx, &r_sharemap_get);
     327           0 :         torture_assert_ntstatus_ok(tctx, status, "GetShareMapping failed");
     328           0 :         torture_assert_int_equal(tctx, r_sharemap_get.out.result, 0,
     329             :                                  "failed GetShareMapping response");
     330           0 :         torture_comment(tctx, "%s(%s): %s is a snapshot of %s at %s\n",
     331           0 :                         GUID_string(tmp_ctx, &r_sharemap_get.out.ShareMapping->ShareMapping1->ShadowCopySetId),
     332           0 :                         GUID_string(tmp_ctx, &r_sharemap_get.out.ShareMapping->ShareMapping1->ShadowCopyId),
     333           0 :                         r_sharemap_get.out.ShareMapping->ShareMapping1->ShadowCopyShareName,
     334           0 :                         r_sharemap_get.out.ShareMapping->ShareMapping1->ShareNameUNC,
     335           0 :                         nt_time_string(tmp_ctx, r_sharemap_get.out.ShareMapping->ShareMapping1->tstamp));
     336             : 
     337           0 :         map = talloc_zero(tctx, struct fssagent_share_mapping_1);
     338           0 :         map->ShadowCopySetId = r_sharemap_get.out.ShareMapping->ShareMapping1->ShadowCopySetId;
     339           0 :         map->ShadowCopyId = r_sharemap_get.out.ShareMapping->ShareMapping1->ShadowCopyId;
     340             :         map->ShadowCopyShareName
     341           0 :                 = talloc_strdup(tctx, r_sharemap_get.out.ShareMapping->ShareMapping1->ShadowCopyShareName);
     342             :         map->ShareNameUNC
     343           0 :                 = talloc_strdup(tctx, r_sharemap_get.out.ShareMapping->ShareMapping1->ShareNameUNC);
     344           0 :         map->tstamp = r_sharemap_get.out.ShareMapping->ShareMapping1->tstamp;
     345             : 
     346           0 :         torture_assert(tctx, !GUID_compare(&r_sharemap_get.in.ShadowCopySetId,
     347             :                                            &map->ShadowCopySetId),
     348             :                        "sc_set GUID mismatch in GetShareMapping");
     349           0 :         torture_assert(tctx, !GUID_compare(&r_sharemap_get.in.ShadowCopyId,
     350             :                                            &map->ShadowCopyId),
     351             :                        "sc GUID mismatch in GetShareMapping");
     352             : 
     353           0 : done:
     354           0 :         talloc_free(tmp_ctx);
     355           0 :         *sc_map = map;
     356             : 
     357           0 :         return true;
     358             : }
     359             : 
     360           0 : static bool test_fsrvp_sc_delete(struct torture_context *tctx,
     361             :                                  struct dcerpc_pipe *p,
     362             :                                  struct fssagent_share_mapping_1 *sc_map)
     363             : {
     364           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     365             :         struct fss_DeleteShareMapping r_sharemap_del;
     366             :         NTSTATUS status;
     367             : 
     368           0 :         ZERO_STRUCT(r_sharemap_del);
     369           0 :         r_sharemap_del.in.ShadowCopySetId = sc_map->ShadowCopySetId;
     370           0 :         r_sharemap_del.in.ShadowCopyId = sc_map->ShadowCopyId;
     371           0 :         r_sharemap_del.in.ShareName = sc_map->ShareNameUNC;
     372           0 :         status = dcerpc_fss_DeleteShareMapping_r(b, tctx, &r_sharemap_del);
     373           0 :         torture_assert_ntstatus_ok(tctx, status, "DeleteShareMapping failed");
     374           0 :         torture_assert_int_equal(tctx, r_sharemap_del.out.result, 0,
     375             :                                  "failed DeleteShareMapping response");
     376             : 
     377           0 :         return true;
     378             : }
     379             : 
     380           0 : static bool test_fsrvp_sc_create_simple(struct torture_context *tctx,
     381             :                                          struct dcerpc_pipe *p)
     382             : {
     383             :         struct fssagent_share_mapping_1 *sc_map;
     384             :         /* no trailing backslash - should work. See note in cmd_fss.c */
     385           0 :         char *share_unc = talloc_asprintf(tctx, "\\\\%s\\%s",
     386             :                                           dcerpc_server_name(p), FSHARE);
     387             : 
     388           0 :         torture_assert(tctx, test_fsrvp_sc_create(tctx, p, share_unc, TEST_FSRVP_TOUT_NONE, &sc_map),
     389             :                        "sc create");
     390             : 
     391           0 :         torture_assert(tctx, test_fsrvp_sc_delete(tctx, p, sc_map), "sc del");
     392             : 
     393           0 :         return true;
     394             : }
     395             : 
     396           0 : static bool test_fsrvp_sc_set_abort(struct torture_context *tctx,
     397             :                                     struct dcerpc_pipe *p)
     398             : {
     399           0 :         char *share_unc = talloc_asprintf(tctx, "\\\\%s\\%s\\",
     400             :                                           dcerpc_server_name(p), FSHARE);
     401           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     402             :         struct fss_IsPathSupported r_pathsupport_get;
     403             :         struct fss_GetSupportedVersion r_version_get;
     404             :         struct fss_SetContext r_context_set;
     405             :         struct fss_StartShadowCopySet r_scset_start;
     406             :         struct fss_AbortShadowCopySet r_scset_abort;
     407             :         struct fss_AddToShadowCopySet r_scset_add;
     408             :         NTSTATUS status;
     409           0 :         TALLOC_CTX *tmp_ctx = talloc_new(tctx);
     410             : 
     411           0 :         ZERO_STRUCT(r_pathsupport_get);
     412           0 :         r_pathsupport_get.in.ShareName = share_unc;
     413           0 :         status = dcerpc_fss_IsPathSupported_r(b, tmp_ctx, &r_pathsupport_get);
     414           0 :         torture_assert_ntstatus_ok(tctx, status,
     415             :                                    "IsPathSupported failed");
     416           0 :         torture_assert(tctx, r_pathsupport_get.out.SupportedByThisProvider,
     417             :                        "path not supported");
     418             : 
     419           0 :         ZERO_STRUCT(r_version_get);
     420           0 :         status = dcerpc_fss_GetSupportedVersion_r(b, tmp_ctx, &r_version_get);
     421           0 :         torture_assert_ntstatus_ok(tctx, status,
     422             :                                    "GetSupportedVersion failed");
     423             : 
     424           0 :         ZERO_STRUCT(r_context_set);
     425           0 :         r_context_set.in.Context = FSRVP_CTX_BACKUP;
     426           0 :         status = dcerpc_fss_SetContext_r(b, tmp_ctx, &r_context_set);
     427           0 :         torture_assert_ntstatus_ok(tctx, status, "SetContext failed");
     428             : 
     429           0 :         ZERO_STRUCT(r_scset_start);
     430           0 :         r_scset_start.in.ClientShadowCopySetId = GUID_random();
     431           0 :         status = dcerpc_fss_StartShadowCopySet_r(b, tmp_ctx, &r_scset_start);
     432           0 :         torture_assert_ntstatus_ok(tctx, status,
     433             :                                    "StartShadowCopySet failed");
     434             : 
     435           0 :         ZERO_STRUCT(r_scset_abort);
     436           0 :         r_scset_abort.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
     437           0 :         status = dcerpc_fss_AbortShadowCopySet_r(b, tmp_ctx, &r_scset_abort);
     438           0 :         torture_assert_ntstatus_ok(tctx, status,
     439             :                                    "AbortShadowCopySet failed");
     440             : 
     441           0 :         ZERO_STRUCT(r_scset_add);
     442           0 :         r_scset_add.in.ClientShadowCopyId = GUID_random();
     443           0 :         r_scset_add.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
     444           0 :         r_scset_add.in.ShareName = share_unc;
     445           0 :         status = dcerpc_fss_AddToShadowCopySet_r(b, tmp_ctx, &r_scset_add);
     446           0 :         torture_assert_ntstatus_ok(tctx, status, "AddToShadowCopySet failed "
     447             :                                    "following abort");
     448             :         /*
     449             :          * XXX Windows 8 server beta returns FSRVP_E_BAD_STATE here rather than
     450             :          * FSRVP_E_BAD_ID / HRES_E_INVALIDARG.
     451             :          */
     452           0 :         torture_assert(tctx, (r_scset_add.out.result != 0),
     453             :                        "incorrect AddToShadowCopySet response following abort");
     454             : 
     455           0 :         talloc_free(tmp_ctx);
     456           0 :         return true;
     457             : }
     458             : 
     459           0 : static bool test_fsrvp_bad_id(struct torture_context *tctx,
     460             :                               struct dcerpc_pipe *p)
     461             : {
     462             :         struct fssagent_share_mapping_1 *sc_map;
     463           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     464             :         struct fss_DeleteShareMapping r_sharemap_del;
     465             :         NTSTATUS status;
     466           0 :         TALLOC_CTX *tmp_ctx = talloc_new(tctx);
     467           0 :         char *share_unc = talloc_asprintf(tmp_ctx, "\\\\%s\\%s\\",
     468             :                                           dcerpc_server_name(p), FSHARE);
     469             : 
     470           0 :         torture_assert(tctx, test_fsrvp_sc_create(tctx, p, share_unc, TEST_FSRVP_TOUT_NONE, &sc_map),
     471             :                        "sc create");
     472             : 
     473           0 :         ZERO_STRUCT(r_sharemap_del);
     474           0 :         r_sharemap_del.in.ShadowCopySetId = sc_map->ShadowCopySetId;
     475           0 :         r_sharemap_del.in.ShadowCopySetId.time_low++;   /* bogus */
     476           0 :         r_sharemap_del.in.ShadowCopyId = sc_map->ShadowCopyId;
     477           0 :         r_sharemap_del.in.ShareName = sc_map->ShareNameUNC;
     478           0 :         status = dcerpc_fss_DeleteShareMapping_r(b, tmp_ctx, &r_sharemap_del);
     479           0 :         torture_assert_ntstatus_ok(tctx, status,
     480             :                                    "DeleteShareMapping failed");
     481           0 :         torture_assert_int_equal(tctx, r_sharemap_del.out.result,
     482             :                                  FSRVP_E_OBJECT_NOT_FOUND,
     483             :                                  "incorrect DeleteShareMapping response");
     484             : 
     485           0 :         r_sharemap_del.in.ShadowCopySetId = sc_map->ShadowCopySetId;
     486           0 :         r_sharemap_del.in.ShadowCopyId.time_mid++;      /* bogus */
     487           0 :         status = dcerpc_fss_DeleteShareMapping_r(b, tmp_ctx, &r_sharemap_del);
     488           0 :         torture_assert_ntstatus_ok(tctx, status,
     489             :                                    "DeleteShareMapping failed");
     490           0 :         torture_assert_int_equal(tctx, r_sharemap_del.out.result,
     491             :                                  HRES_ERROR_V(HRES_E_INVALIDARG),
     492             :                                  "incorrect DeleteShareMapping response");
     493             : 
     494           0 :         torture_assert(tctx, test_fsrvp_sc_delete(tctx, p, sc_map), "sc del");
     495             : 
     496           0 :         talloc_free(sc_map);
     497           0 :         talloc_free(tmp_ctx);
     498             : 
     499           0 :         return true;
     500             : }
     501             : 
     502           0 : static bool test_fsrvp_sc_share_io(struct torture_context *tctx,
     503             :                                    struct dcerpc_pipe *p)
     504             : {
     505             :         struct fssagent_share_mapping_1 *sc_map;
     506             :         NTSTATUS status;
     507           0 :         TALLOC_CTX *tmp_ctx = talloc_new(tctx);
     508           0 :         char *share_unc = talloc_asprintf(tmp_ctx, "\\\\%s\\%s",
     509             :                                           dcerpc_server_name(p), FSHARE);
     510             :         struct smb2_tree *tree_base;
     511             :         struct smb2_tree *tree_snap;
     512             :         struct smbcli_options options;
     513             :         struct smb2_handle base_fh;
     514             :         struct smb2_read r;
     515             :         struct smb2_create io;
     516           0 :         lpcfg_smbcli_options(tctx->lp_ctx, &options);
     517             : 
     518           0 :         status = smb2_connect(tmp_ctx,
     519             :                               dcerpc_server_name(p),
     520             :                               lpcfg_smb_ports(tctx->lp_ctx),
     521             :                               FSHARE,
     522             :                               lpcfg_resolve_context(tctx->lp_ctx),
     523             :                               samba_cmdline_get_creds(),
     524             :                               &tree_base,
     525             :                               tctx->ev,
     526             :                               &options,
     527             :                               lpcfg_socket_options(tctx->lp_ctx),
     528             :                               lpcfg_gensec_settings(tctx, tctx->lp_ctx));
     529           0 :         torture_assert_ntstatus_ok(tctx, status,
     530             :                                    "Failed to connect to SMB2 share");
     531             : 
     532           0 :         smb2_util_unlink(tree_base, FNAME);
     533           0 :         status = torture_smb2_testfile(tree_base, FNAME, &base_fh);
     534           0 :         torture_assert_ntstatus_ok(tctx, status, "base write open");
     535             : 
     536           0 :         status = smb2_util_write(tree_base, base_fh, "pre-snap", 0,
     537             :                                  sizeof("pre-snap"));
     538           0 :         torture_assert_ntstatus_ok(tctx, status, "src write");
     539             : 
     540             : 
     541           0 :         torture_assert(tctx, test_fsrvp_sc_create(tctx, p, share_unc, TEST_FSRVP_TOUT_NONE, &sc_map),
     542             :                        "sc create");
     543             : 
     544           0 :         status = smb2_util_write(tree_base, base_fh, "post-snap", 0,
     545             :                                  sizeof("post-snap"));
     546           0 :         torture_assert_ntstatus_ok(tctx, status, "base write");
     547             : 
     548             :         /* connect to snapshot share and verify pre-snapshot data */
     549           0 :         status = smb2_connect(tmp_ctx,
     550             :                               dcerpc_server_name(p),
     551             :                               lpcfg_smb_ports(tctx->lp_ctx),
     552           0 :                               sc_map->ShadowCopyShareName,
     553             :                               lpcfg_resolve_context(tctx->lp_ctx),
     554             :                               samba_cmdline_get_creds(),
     555             :                               &tree_snap,
     556             :                               tctx->ev,
     557             :                               &options,
     558             :                               lpcfg_socket_options(tctx->lp_ctx),
     559             :                               lpcfg_gensec_settings(tctx, tctx->lp_ctx));
     560           0 :         torture_assert_ntstatus_ok(tctx, status,
     561             :                                    "Failed to connect to SMB2 shadow-copy share");
     562             :         /* Windows server 8 allows RW open to succeed here for a ro snapshot */
     563           0 :         ZERO_STRUCT(io);
     564           0 :         io.in.desired_access = SEC_RIGHTS_FILE_READ;
     565           0 :         io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
     566           0 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     567           0 :         io.in.share_access =
     568             :                 NTCREATEX_SHARE_ACCESS_DELETE|
     569             :                 NTCREATEX_SHARE_ACCESS_READ|
     570             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     571           0 :         io.in.create_options = 0;
     572           0 :         io.in.fname = FNAME;
     573           0 :         status = smb2_create(tree_snap, tmp_ctx, &io);
     574           0 :         torture_assert_ntstatus_ok(tctx, status, "snap read open");
     575             : 
     576           0 :         ZERO_STRUCT(r);
     577           0 :         r.in.file.handle = io.out.file.handle;
     578           0 :         r.in.length      = sizeof("pre-snap");
     579           0 :         status = smb2_read(tree_snap, tmp_ctx, &r);
     580           0 :         torture_assert_ntstatus_ok(tctx, status, "read");
     581           0 :         torture_assert_u64_equal(tctx, r.out.data.length, r.in.length,
     582             :                                  "read data len mismatch");
     583           0 :         torture_assert_str_equal(tctx, (char *)r.out.data.data, "pre-snap",
     584             :                                  "bad snapshot data");
     585             : 
     586           0 :         torture_assert(tctx, test_fsrvp_sc_delete(tctx, p, sc_map), "sc del");
     587             : 
     588           0 :         talloc_free(sc_map);
     589           0 :         talloc_free(tmp_ctx);
     590             : 
     591           0 :         return true;
     592             : }
     593             : 
     594           0 : static bool test_fsrvp_enum_snaps(struct torture_context *tctx,
     595             :                                   TALLOC_CTX *mem_ctx,
     596             :                                   struct smb2_tree *tree,
     597             :                                   struct smb2_handle fh,
     598             :                                   int *_count)
     599             : {
     600             :         struct smb2_ioctl io;
     601             :         NTSTATUS status;
     602             : 
     603           0 :         ZERO_STRUCT(io);
     604           0 :         io.level = RAW_IOCTL_SMB2;
     605           0 :         io.in.file.handle = fh;
     606           0 :         io.in.function = FSCTL_SRV_ENUM_SNAPS;
     607           0 :         io.in.max_output_response = 16;
     608           0 :         io.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
     609             : 
     610           0 :         status = smb2_ioctl(tree, mem_ctx, &io);
     611           0 :         torture_assert_ntstatus_ok(tctx, status, "enum ioctl");
     612             : 
     613           0 :         *_count = IVAL(io.out.out.data, 0);
     614             : 
     615             :         /* with max_output_response=16, no labels should be sent */
     616           0 :         torture_assert_int_equal(tctx, IVAL(io.out.out.data, 4), 0,
     617             :                                  "enum snaps labels");
     618             : 
     619             :         /* TODO with 0 snaps, needed_data_count should be 0? */
     620           0 :         if (*_count != 0) {
     621           0 :                 torture_assert(tctx, IVAL(io.out.out.data, 8) != 0,
     622             :                                "enum snaps needed non-zero");
     623             :         }
     624             : 
     625           0 :         return true;
     626             : }
     627             : 
     628           0 : static bool test_fsrvp_enum_created(struct torture_context *tctx,
     629             :                                     struct dcerpc_pipe *p)
     630             : {
     631             :         struct fssagent_share_mapping_1 *sc_map;
     632             :         NTSTATUS status;
     633           0 :         TALLOC_CTX *tmp_ctx = talloc_new(tctx);
     634           0 :         char *share_unc = talloc_asprintf(tmp_ctx, "\\\\%s\\%s\\",
     635             :                                           dcerpc_server_name(p), FSHARE);
     636             :         struct smb2_tree *tree_base;
     637             :         struct smbcli_options options;
     638             :         struct smb2_handle base_fh;
     639             :         int count;
     640           0 :         lpcfg_smbcli_options(tctx->lp_ctx, &options);
     641             : 
     642           0 :         status = smb2_connect(tmp_ctx,
     643             :                               dcerpc_server_name(p),
     644             :                               lpcfg_smb_ports(tctx->lp_ctx),
     645             :                               FSHARE,
     646             :                               lpcfg_resolve_context(tctx->lp_ctx),
     647             :                               samba_cmdline_get_creds(),
     648             :                               &tree_base,
     649             :                               tctx->ev,
     650             :                               &options,
     651             :                               lpcfg_socket_options(tctx->lp_ctx),
     652             :                               lpcfg_gensec_settings(tctx, tctx->lp_ctx));
     653           0 :         torture_assert_ntstatus_ok(tctx, status,
     654             :                                    "Failed to connect to SMB2 share");
     655             : 
     656           0 :         smb2_util_unlink(tree_base, FNAME);
     657           0 :         status = torture_smb2_testfile(tree_base, FNAME, &base_fh);
     658           0 :         torture_assert_ntstatus_ok(tctx, status, "base write open");
     659             : 
     660           0 :         status = smb2_util_write(tree_base, base_fh, "pre-snap", 0,
     661             :                                  sizeof("pre-snap"));
     662           0 :         torture_assert_ntstatus_ok(tctx, status, "src write");
     663             : 
     664           0 :         torture_assert(tctx,
     665             :                        test_fsrvp_enum_snaps(tctx, tmp_ctx, tree_base, base_fh,
     666             :                                              &count),
     667             :                        "count");
     668           0 :         torture_assert_int_equal(tctx, count, 0, "num snaps");
     669             : 
     670           0 :         torture_assert(tctx, test_fsrvp_sc_create(tctx, p, share_unc, TEST_FSRVP_TOUT_NONE, &sc_map),
     671             :                        "sc create");
     672           0 :         talloc_free(sc_map);
     673             : 
     674           0 :         torture_assert(tctx,
     675             :                        test_fsrvp_enum_snaps(tctx, tmp_ctx, tree_base, base_fh,
     676             :                                              &count),
     677             :                        "count");
     678             :         /*
     679             :          * Snapshots created via FSRVP on Windows Server 2012 are not added to
     680             :          * the previous versions list, so it will fail here...
     681             :          */
     682           0 :         torture_assert_int_equal(tctx, count, 1, "num snaps");
     683             : 
     684           0 :         smb_msleep(1100);       /* @GMT tokens have a 1 second resolution */
     685           0 :         torture_assert(tctx, test_fsrvp_sc_create(tctx, p, share_unc, TEST_FSRVP_TOUT_NONE, &sc_map),
     686             :                        "sc create");
     687           0 :         talloc_free(sc_map);
     688             : 
     689           0 :         torture_assert(tctx,
     690             :                        test_fsrvp_enum_snaps(tctx, tmp_ctx, tree_base, base_fh,
     691             :                                              &count),
     692             :                        "count");
     693           0 :         torture_assert_int_equal(tctx, count, 2, "num snaps");
     694             : 
     695           0 :         talloc_free(tmp_ctx);
     696             : 
     697           0 :         return true;
     698             : }
     699             : 
     700           0 : static bool test_fsrvp_seq_timeout(struct torture_context *tctx,
     701             :                                    struct dcerpc_pipe *p)
     702             : {
     703             :         int i;
     704             :         struct fssagent_share_mapping_1 *sc_map;
     705           0 :         char *share_unc = talloc_asprintf(tctx, "\\\\%s\\%s",
     706             :                                           dcerpc_server_name(p), FSHARE);
     707             : 
     708           0 :         for (i = TEST_FSRVP_TOUT_NONE; i <= TEST_FSRVP_TOUT_COMMIT; i++) {
     709           0 :                 torture_assert(tctx, test_fsrvp_sc_create(tctx, p, share_unc,
     710             :                                                           i, &sc_map),
     711             :                                "sc create");
     712             : 
     713             :                 /* only need to delete if create process didn't timeout */
     714           0 :                 if (i == TEST_FSRVP_TOUT_NONE) {
     715           0 :                         torture_assert(tctx, test_fsrvp_sc_delete(tctx, p, sc_map),
     716             :                                        "sc del");
     717             :                 }
     718             :         }
     719             : 
     720           0 :         return true;
     721             : }
     722             : 
     723           0 : static bool test_fsrvp_share_sd(struct torture_context *tctx,
     724             :                                 struct dcerpc_pipe *p)
     725             : {
     726             :         NTSTATUS status;
     727             :         struct dcerpc_pipe *srvsvc_p;
     728             :         struct srvsvc_NetShareGetInfo q;
     729             :         struct srvsvc_NetShareSetInfo s;
     730             :         struct srvsvc_NetShareInfo502 *info502;
     731             :         struct fssagent_share_mapping_1 *sc_map;
     732             :         struct fss_ExposeShadowCopySet r_scset_expose;
     733             :         struct fss_GetShareMapping r_sharemap_get;
     734             :         struct security_descriptor *sd_old;
     735             :         struct security_descriptor *sd_base;
     736             :         struct security_descriptor *sd_snap;
     737             :         struct security_ace *ace;
     738             :         int i;
     739             :         int aces_found;
     740           0 :         char *share_unc = talloc_asprintf(tctx, "\\\\%s\\%s",
     741             :                                           dcerpc_server_name(p), FSHARE);
     742           0 :         ZERO_STRUCT(q);
     743           0 :         q.in.server_unc = dcerpc_server_name(p);
     744           0 :         q.in.share_name = FSHARE;
     745           0 :         q.in.level = 502;
     746             : 
     747           0 :         status = torture_rpc_connection(tctx, &srvsvc_p, &ndr_table_srvsvc);
     748           0 :         torture_assert_ntstatus_ok(tctx, status, "srvsvc rpc conn failed");
     749             : 
     750             :         /* ensure srvsvc out pointers are allocated during unmarshalling */
     751           0 :         srvsvc_p->conn->flags |= DCERPC_NDR_REF_ALLOC;
     752             : 
     753             :         /* obtain the existing DACL for the base share */
     754           0 :         status = dcerpc_srvsvc_NetShareGetInfo_r(srvsvc_p->binding_handle,
     755             :                                                  tctx, &q);
     756           0 :         torture_assert_ntstatus_ok(tctx, status, "NetShareGetInfo failed");
     757           0 :         torture_assert_werr_ok(tctx, q.out.result, "NetShareGetInfo failed");
     758             : 
     759           0 :         info502 = q.out.info->info502;
     760             : 
     761             :         /* back up the existing share SD, so it can be restored on completion */
     762           0 :         sd_old = info502->sd_buf.sd;
     763           0 :         sd_base = security_descriptor_copy(tctx, info502->sd_buf.sd);
     764           0 :         torture_assert(tctx, sd_base != NULL, "sd dup");
     765           0 :         torture_assert(tctx, sd_base->dacl != NULL, "no existing share DACL");
     766             : 
     767             :         /* the Builtin_X_Operators placeholder ACEs need to be unique */
     768           0 :         for (i = 0; i < sd_base->dacl->num_aces; i++) {
     769           0 :                 ace = &sd_base->dacl->aces[i];
     770           0 :                 if (dom_sid_equal(&ace->trustee,
     771             :                                   &global_sid_Builtin_Backup_Operators)
     772           0 :                  || dom_sid_equal(&ace->trustee,
     773             :                                   &global_sid_Builtin_Print_Operators)) {
     774           0 :                         torture_skip(tctx, "placeholder ACE already exists\n");
     775             :                 }
     776             :         }
     777             : 
     778             :         /* add Backup_Operators placeholder ACE and set base share DACL */
     779           0 :         ace = talloc_zero(tctx, struct security_ace);
     780           0 :         ace->type = SEC_ACE_TYPE_ACCESS_ALLOWED;
     781           0 :         ace->access_mask = SEC_STD_SYNCHRONIZE;
     782           0 :         ace->trustee = global_sid_Builtin_Backup_Operators;
     783             : 
     784           0 :         status = security_descriptor_dacl_add(sd_base, ace);
     785           0 :         torture_assert_ntstatus_ok(tctx, status,
     786             :                                    "failed to add placeholder ACE to DACL");
     787             : 
     788           0 :         info502->sd_buf.sd = sd_base;
     789           0 :         info502->sd_buf.sd_size = ndr_size_security_descriptor(sd_base, 0);
     790             : 
     791           0 :         ZERO_STRUCT(s);
     792           0 :         s.in.server_unc = dcerpc_server_name(p);
     793           0 :         s.in.share_name = FSHARE;
     794           0 :         s.in.level = 502;
     795           0 :         s.in.info = q.out.info;
     796             : 
     797           0 :         status = dcerpc_srvsvc_NetShareSetInfo_r(srvsvc_p->binding_handle,
     798             :                                                  tctx, &s);
     799           0 :         torture_assert_ntstatus_ok(tctx, status, "NetShareSetInfo failed");
     800           0 :         torture_assert_werr_ok(tctx, s.out.result, "NetShareSetInfo failed");
     801             : 
     802             :         /* create a snapshot, but don't expose yet */
     803           0 :         torture_assert(tctx,
     804             :                        test_fsrvp_sc_create(tctx, p, share_unc,
     805             :                                             TEST_FSRVP_STOP_B4_EXPOSE, &sc_map),
     806             :                        "sc create");
     807             : 
     808             :         /*
     809             :          * Add another unique placeholder ACE.
     810             :          * By changing the share DACL between snapshot creation and exposure we
     811             :          * can determine at which point the server clones the base share DACL.
     812             :          */
     813           0 :         ace = talloc_zero(tctx, struct security_ace);
     814           0 :         ace->type = SEC_ACE_TYPE_ACCESS_ALLOWED;
     815           0 :         ace->access_mask = SEC_STD_SYNCHRONIZE;
     816           0 :         ace->trustee = global_sid_Builtin_Print_Operators;
     817             : 
     818           0 :         status = security_descriptor_dacl_add(sd_base, ace);
     819           0 :         torture_assert_ntstatus_ok(tctx, status,
     820             :                                    "failed to add placeholder ACE to DACL");
     821             : 
     822           0 :         info502->sd_buf.sd = sd_base;
     823           0 :         info502->sd_buf.sd_size = ndr_size_security_descriptor(sd_base, 0);
     824             : 
     825           0 :         ZERO_STRUCT(s);
     826           0 :         s.in.server_unc = dcerpc_server_name(p);
     827           0 :         s.in.share_name = FSHARE;
     828           0 :         s.in.level = 502;
     829           0 :         s.in.info = q.out.info;
     830             : 
     831           0 :         status = dcerpc_srvsvc_NetShareSetInfo_r(srvsvc_p->binding_handle,
     832             :                                                  tctx, &s);
     833           0 :         torture_assert_ntstatus_ok(tctx, status, "NetShareSetInfo failed");
     834           0 :         torture_assert_werr_ok(tctx, s.out.result, "NetShareSetInfo failed");
     835             : 
     836             :         /* expose the snapshot share and get the new share details */
     837           0 :         ZERO_STRUCT(r_scset_expose);
     838           0 :         r_scset_expose.in.ShadowCopySetId = sc_map->ShadowCopySetId;
     839           0 :         r_scset_expose.in.TimeOutInMilliseconds = (120 * 1000); /* win8 */
     840           0 :         status = dcerpc_fss_ExposeShadowCopySet_r(p->binding_handle, tctx,
     841             :                                                   &r_scset_expose);
     842           0 :         torture_assert_ntstatus_ok(tctx, status,
     843             :                                    "ExposeShadowCopySet failed");
     844           0 :         torture_assert_int_equal(tctx, r_scset_expose.out.result, 0,
     845             :                                  "failed ExposeShadowCopySet response");
     846             : 
     847           0 :         ZERO_STRUCT(r_sharemap_get);
     848           0 :         r_sharemap_get.in.ShadowCopyId = sc_map->ShadowCopyId;
     849           0 :         r_sharemap_get.in.ShadowCopySetId = sc_map->ShadowCopySetId;
     850           0 :         r_sharemap_get.in.ShareName = share_unc;
     851           0 :         r_sharemap_get.in.Level = 1;
     852           0 :         status = dcerpc_fss_GetShareMapping_r(p->binding_handle, tctx,
     853             :                                               &r_sharemap_get);
     854           0 :         torture_assert_ntstatus_ok(tctx, status, "GetShareMapping failed");
     855           0 :         torture_assert_int_equal(tctx, r_sharemap_get.out.result, 0,
     856             :                                  "failed GetShareMapping response");
     857           0 :         talloc_free(sc_map);
     858           0 :         sc_map = r_sharemap_get.out.ShareMapping->ShareMapping1;
     859             : 
     860             :         /* restore the original base share ACL */
     861           0 :         info502->sd_buf.sd = sd_old;
     862           0 :         info502->sd_buf.sd_size = ndr_size_security_descriptor(sd_old, 0);
     863           0 :         status = dcerpc_srvsvc_NetShareSetInfo_r(srvsvc_p->binding_handle,
     864             :                                                  tctx, &s);
     865           0 :         torture_assert_ntstatus_ok(tctx, status, "NetShareSetInfo failed");
     866           0 :         torture_assert_werr_ok(tctx, s.out.result, "NetShareSetInfo failed");
     867             : 
     868             :         /* check for placeholder ACEs in the snapshot share DACL */
     869           0 :         ZERO_STRUCT(q);
     870           0 :         q.in.server_unc = dcerpc_server_name(p);
     871           0 :         q.in.share_name = sc_map->ShadowCopyShareName;
     872           0 :         q.in.level = 502;
     873           0 :         status = dcerpc_srvsvc_NetShareGetInfo_r(srvsvc_p->binding_handle,
     874             :                                                  tctx, &q);
     875           0 :         torture_assert_ntstatus_ok(tctx, status, "NetShareGetInfo failed");
     876           0 :         torture_assert_werr_ok(tctx, q.out.result, "NetShareGetInfo failed");
     877           0 :         info502 = q.out.info->info502;
     878             : 
     879           0 :         sd_snap = info502->sd_buf.sd;
     880           0 :         torture_assert(tctx, sd_snap != NULL, "sd");
     881           0 :         torture_assert(tctx, sd_snap->dacl != NULL, "no snap share DACL");
     882             : 
     883           0 :         aces_found = 0;
     884           0 :         for (i = 0; i < sd_snap->dacl->num_aces; i++) {
     885           0 :                 ace = &sd_snap->dacl->aces[i];
     886           0 :                 if (dom_sid_equal(&ace->trustee,
     887             :                                   &global_sid_Builtin_Backup_Operators)) {
     888           0 :                         torture_comment(tctx,
     889             :                                 "found share ACE added before snapshot\n");
     890           0 :                         aces_found++;
     891           0 :                 } else if (dom_sid_equal(&ace->trustee,
     892             :                                          &global_sid_Builtin_Print_Operators)) {
     893           0 :                         torture_comment(tctx,
     894             :                                 "found share ACE added after snapshot\n");
     895           0 :                         aces_found++;
     896             :                 }
     897             :         }
     898             :         /*
     899             :          * Expect snapshot share to match the base share DACL at the time of
     900             :          * exposure, not at the time of snapshot creation. This is in line with
     901             :          * Windows Server 2012 behaviour.
     902             :          */
     903           0 :         torture_assert_int_equal(tctx, aces_found, 2,
     904             :                                 "placeholder ACE missing from snap share DACL");
     905             : 
     906           0 :         torture_assert(tctx, test_fsrvp_sc_delete(tctx, p, sc_map), "sc del");
     907             : 
     908           0 :         return true;
     909             : }
     910             : 
     911           3 : static bool fsrvp_rpc_setup(struct torture_context *tctx, void **data)
     912             : {
     913             :         NTSTATUS status;
     914           3 :         struct torture_rpc_tcase *tcase = talloc_get_type(
     915             :                                                 tctx->active_tcase, struct torture_rpc_tcase);
     916             :         struct torture_rpc_tcase_data *tcase_data;
     917             : 
     918           3 :         *data = tcase_data = talloc_zero(tctx, struct torture_rpc_tcase_data);
     919           3 :         tcase_data->credentials = samba_cmdline_get_creds();
     920             : 
     921           3 :         status = torture_rpc_connection(tctx,
     922             :                                 &(tcase_data->pipe),
     923             :                                 tcase->table);
     924             : 
     925           3 :         torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
     926             : 
     927             :         /* XXX required, otherwise ndr out ptrs are not allocated */
     928           0 :         tcase_data->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC;
     929             : 
     930           0 :         return true;
     931             : }
     932             : 
     933             : /*
     934             :    testing of FSRVP (FSS agent)
     935             : */
     936         964 : struct torture_suite *torture_rpc_fsrvp(TALLOC_CTX *mem_ctx)
     937             : {
     938         964 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "fsrvp");
     939             : 
     940         738 :         struct torture_rpc_tcase *tcase
     941         226 :                 = torture_suite_add_rpc_iface_tcase(suite, "fsrvp",
     942             :                                                 &ndr_table_FileServerVssAgent);
     943             :         /* override torture_rpc_setup() to set DCERPC_NDR_REF_ALLOC */
     944         964 :         tcase->tcase.setup = fsrvp_rpc_setup;
     945             : 
     946         964 :         torture_rpc_tcase_add_test(tcase, "share_sd",
     947             :                                    test_fsrvp_share_sd);
     948         964 :         torture_rpc_tcase_add_test(tcase, "enum_created",
     949             :                                    test_fsrvp_enum_created);
     950         964 :         torture_rpc_tcase_add_test(tcase, "sc_share_io",
     951             :                                    test_fsrvp_sc_share_io);
     952         964 :         torture_rpc_tcase_add_test(tcase, "bad_id",
     953             :                                    test_fsrvp_bad_id);
     954         964 :         torture_rpc_tcase_add_test(tcase, "sc_set_abort",
     955             :                                    test_fsrvp_sc_set_abort);
     956         964 :         torture_rpc_tcase_add_test(tcase, "create_simple",
     957             :                                    test_fsrvp_sc_create_simple);
     958         964 :         torture_rpc_tcase_add_test(tcase, "set_ctx",
     959             :                                    test_fsrvp_set_ctx);
     960         964 :         torture_rpc_tcase_add_test(tcase, "get_version",
     961             :                                    test_fsrvp_get_version);
     962         964 :         torture_rpc_tcase_add_test(tcase, "is_path_supported",
     963             :                                    test_fsrvp_is_path_supported);
     964         964 :         torture_rpc_tcase_add_test(tcase, "seq_timeout",
     965             :                                    test_fsrvp_seq_timeout);
     966             : 
     967         964 :         return suite;
     968             : }

Generated by: LCOV version 1.13