LCOV - code coverage report
Current view: top level - source4/torture/rpc - fsrvp.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 442 511 86.5 %
Date: 2024-04-21 15:09:00 Functions: 15 15 100.0 %

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

Generated by: LCOV version 1.14