LCOV - code coverage report
Current view: top level - source3/rpcclient - cmd_fss.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 0 319 0.0 %
Date: 2024-04-21 15:09:00 Functions: 0 18 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Unix SMB/CIFS implementation.
       3             :  *
       4             :  * File Server Remote VSS Protocol (FSRVP) client
       5             :  *
       6             :  * Copyright (C) David Disseldorp 2012
       7             :  *
       8             :  * This program is free software; you can redistribute it and/or modify
       9             :  * it under the terms of the GNU General Public License as published by
      10             :  * the Free Software Foundation; either version 3 of the License, or
      11             :  * (at your option) any later version.
      12             :  *
      13             :  * This program is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :  * GNU General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU General Public License
      19             :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             :  */
      21             : 
      22             : #include "includes.h"
      23             : #include "rpcclient.h"
      24             : #include "../librpc/gen_ndr/ndr_fsrvp.h"
      25             : #include "../librpc/gen_ndr/ndr_fsrvp_c.h"
      26             : #include "../libcli/util/hresult.h"
      27             : 
      28             : static const struct {
      29             :         uint32_t error_code;
      30             :         const char *error_str;
      31             : } fss_errors[] = {
      32             :         {
      33             :                 FSRVP_E_BAD_STATE,
      34             :                 "A method call was invalid because of the state of the server."
      35             :         },
      36             :         {
      37             :                 FSRVP_E_SHADOW_COPY_SET_IN_PROGRESS,
      38             :                 "A call was made to either \'SetContext\' or \'StartShadowCopySet\' while the creation of another shadow copy set is in progress."
      39             :         },
      40             :         {
      41             :                 FSRVP_E_NOT_SUPPORTED,
      42             :                 "The file store which contains the share to be shadow copied is not supported by the server."
      43             :         },
      44             :         {
      45             :                 FSRVP_E_WAIT_TIMEOUT,
      46             :                 "The wait for a shadow copy commit or expose operation has timed out."
      47             :         },
      48             :         {
      49             :                 FSRVP_E_WAIT_FAILED,
      50             :                 "The wait for a shadow copy commit expose operation has failed."
      51             :         },
      52             :         {
      53             :                 FSRVP_E_OBJECT_NOT_FOUND,
      54             :                 "The specified object does not exist."
      55             :         },
      56             :         {
      57             :                 FSRVP_E_UNSUPPORTED_CONTEXT,
      58             :                 "The specified context value is invalid."
      59             :         },
      60             :         {
      61             :                 FSRVP_E_SHADOWCOPYSET_ID_MISMATCH,
      62             :                 "The provided ShadowCopySetId does not exist."
      63             :         },
      64             : };
      65             : 
      66             : struct fss_context_map {
      67             :         uint32_t ctx_val;
      68             :         const char *ctx_str;
      69             :         const char *ctx_desc;
      70             : };
      71             : struct fss_context_map ctx_map[] = {
      72             :         {
      73             :                 .ctx_val = FSRVP_CTX_BACKUP,
      74             :                 .ctx_str = "backup",
      75             :                 .ctx_desc = "auto-release, non-persistent shadow-copy.",
      76             :         },
      77             :         {
      78             :                 .ctx_val = FSRVP_CTX_FILE_SHARE_BACKUP,
      79             :                 .ctx_str = "file_share_backup",
      80             :                 .ctx_desc = "auto-release, non-persistent shadow-copy created "
      81             :                             "without writer involvement.",
      82             :         },
      83             :         {
      84             :                 .ctx_val = FSRVP_CTX_NAS_ROLLBACK,
      85             :                 .ctx_str = "nas_rollback",
      86             :                 .ctx_desc = "non-auto-release, persistent shadow-copy created "
      87             :                             "without writer involvement.",
      88             :         },
      89             :         {
      90             :                 .ctx_val = FSRVP_CTX_APP_ROLLBACK,
      91             :                 .ctx_str = "app_rollback",
      92             :                 .ctx_desc = "non-auto-release, persistent shadow-copy.",
      93             :         },
      94             :         { 0, NULL, NULL },
      95             : };
      96             : 
      97           0 : static const char *get_error_str(uint32_t code)
      98             : {
      99             :         static const char *default_err = "Unknown Error";
     100           0 :         const char *result = default_err;
     101             :         int i;
     102           0 :         for (i = 0; i < ARRAY_SIZE(fss_errors); ++i) {
     103           0 :                 if (code == fss_errors[i].error_code) {
     104           0 :                         result = fss_errors[i].error_str;
     105           0 :                         break;
     106             :                 }
     107             :         }
     108             :         /* error isn't specific fsrvp one, check hresult errors */
     109           0 :         if (result == default_err) {
     110           0 :                 const char *hres_err = hresult_errstr_const(HRES_ERROR(code));
     111           0 :                 if (hres_err) {
     112           0 :                         result = hres_err;
     113             :                 }
     114             :         }
     115           0 :         return result;
     116             : };
     117             : 
     118           0 : static bool map_fss_ctx_str(const char *ctx_str,
     119             :                             uint32_t *ctx_val)
     120             : {
     121             :         int i;
     122             : 
     123           0 :         for (i = 0; ctx_map[i].ctx_str != NULL; i++) {
     124           0 :                 if (!strcmp(ctx_map[i].ctx_str, ctx_str)) {
     125           0 :                         *ctx_val = ctx_map[i].ctx_val;
     126           0 :                         return true;
     127             :                 }
     128             :         }
     129           0 :         return false;
     130             : }
     131             : 
     132           0 : static void cmd_fss_is_path_sup_usage(const char *script_name)
     133             : {
     134           0 :         printf("usage: %s [share_name]\n", script_name);
     135           0 : }
     136             : 
     137           0 : static NTSTATUS cmd_fss_is_path_sup(struct rpc_pipe_client *cli,
     138             :                                     TALLOC_CTX *mem_ctx, int argc,
     139             :                                     const char **argv)
     140             : {
     141             :         NTSTATUS status;
     142             :         struct fss_IsPathSupported r;
     143           0 :         struct dcerpc_binding_handle *b = cli->binding_handle;
     144             : 
     145           0 :         if (argc != 2) {
     146           0 :                 cmd_fss_is_path_sup_usage(argv[0]);
     147           0 :                 return NT_STATUS_UNSUCCESSFUL;
     148             :         }
     149             : 
     150           0 :         ZERO_STRUCT(r);
     151           0 :         r.in.ShareName = talloc_asprintf(mem_ctx, "%s\\%s\\",
     152           0 :                                          cli->srv_name_slash, argv[1]);
     153           0 :         if (r.in.ShareName == NULL) {
     154           0 :                 return NT_STATUS_NO_MEMORY;
     155             :         }
     156             : 
     157           0 :         status = dcerpc_fss_IsPathSupported_r(b, mem_ctx, &r);
     158           0 :         if (!NT_STATUS_IS_OK(status)) {
     159           0 :                 DEBUG(0, ("IsPathSupported failed with UNC %s\n",
     160             :                           r.in.ShareName));
     161           0 :                 return NT_STATUS_UNSUCCESSFUL;
     162           0 :         } else if (r.out.result) {
     163           0 :                 DEBUG(0, ("failed IsPathSupported response: 0x%x - \"%s\"\n",
     164             :                           r.out.result, get_error_str(r.out.result)));
     165           0 :                 return NT_STATUS_UNSUCCESSFUL;
     166             :         }
     167           0 :         printf("UNC %s %s shadow copy requests\n", r.in.ShareName,
     168           0 :                *r.out.SupportedByThisProvider ? "supports" : "does not support");
     169             : 
     170           0 :         return NT_STATUS_OK;
     171             : }
     172             : 
     173           0 : static void cmd_fss_get_sup_version_usage(const char *script_name)
     174             : {
     175           0 :         printf("usage: %s\n", script_name);
     176           0 : }
     177             : 
     178           0 : static NTSTATUS cmd_fss_get_sup_version(struct rpc_pipe_client *cli,
     179             :                                     TALLOC_CTX *mem_ctx, int argc,
     180             :                                     const char **argv)
     181             : {
     182             :         NTSTATUS status;
     183             :         struct fss_GetSupportedVersion r;
     184           0 :         struct dcerpc_binding_handle *b = cli->binding_handle;
     185             : 
     186           0 :         if (argc != 1) {
     187           0 :                 cmd_fss_get_sup_version_usage(argv[0]);
     188           0 :                 return NT_STATUS_UNSUCCESSFUL;
     189             :         }
     190             : 
     191           0 :         ZERO_STRUCT(r);
     192           0 :         status = dcerpc_fss_GetSupportedVersion_r(b, mem_ctx, &r);
     193           0 :         if (!NT_STATUS_IS_OK(status) || (r.out.result != 0)) {
     194           0 :                 DEBUG(0, ("GetSupportedVersion failed: %s result: 0x%x\n",
     195             :                           nt_errstr(status), r.out.result));
     196           0 :                 return NT_STATUS_UNSUCCESSFUL;
     197             :         }
     198           0 :         printf("server %s supports FSRVP versions from %u to %u\n",
     199           0 :                cli->desthost, *r.out.MinVersion, *r.out.MaxVersion);
     200             : 
     201           0 :         return NT_STATUS_OK;
     202             : }
     203             : 
     204           0 : static void cmd_fss_create_expose_usage(const char *script_name)
     205             : {
     206             :         int i;
     207             : 
     208           0 :         printf("usage: %s [fss_context] [ro|rw] [share1] <share2> ...\n"
     209             :                "[fss_context] values:\n", script_name);
     210           0 :         for (i = 0; ctx_map[i].ctx_str != NULL; i++) {
     211           0 :                 printf("\t%s: %s\n", ctx_map[i].ctx_str, ctx_map[i].ctx_desc);
     212             :         }
     213           0 : }
     214             : 
     215           0 : static NTSTATUS cmd_fss_create_expose_parse(TALLOC_CTX *mem_ctx, int argc,
     216             :                                             const char **argv,
     217             :                                             const char *desthost,
     218             :                                             uint32_t *fss_ctx_val,
     219             :                                             int *num_maps,
     220             :                                          struct fssagent_share_mapping_1 **maps)
     221             : {
     222           0 :         int num_non_share_args = 3;
     223             :         int num_share_args;
     224             :         int i;
     225             :         struct fssagent_share_mapping_1 *map_array;
     226             : 
     227           0 :         if (argc < 4) {
     228           0 :                 return NT_STATUS_INVALID_PARAMETER;
     229             :         }
     230             : 
     231           0 :         if (!map_fss_ctx_str(argv[1], fss_ctx_val)) {
     232           0 :                 return NT_STATUS_INVALID_PARAMETER;
     233             :         }
     234             : 
     235           0 :         if (!strcmp(argv[2], "rw")) {
     236             :                 /* shadow-copy is created as read-write */
     237           0 :                 *fss_ctx_val |= ATTR_AUTO_RECOVERY;
     238           0 :         } else if (strcmp(argv[2], "ro")) {
     239           0 :                 return NT_STATUS_INVALID_PARAMETER;
     240             :         }
     241             : 
     242           0 :         num_share_args = argc - num_non_share_args;
     243           0 :         map_array = talloc_array(mem_ctx, struct fssagent_share_mapping_1,
     244             :                                  num_share_args);
     245           0 :         if (map_array == NULL) {
     246           0 :                 return NT_STATUS_NO_MEMORY;
     247             :         }
     248             : 
     249           0 :         for (i = 0; i < num_share_args; i++) {
     250             :                 /*
     251             :                  * A trailing slash should to be present in the request UNC,
     252             :                  * otherwise Windows Server 2012 FSRVP servers don't append
     253             :                  * a '$' to exposed hidden share shadow-copies. E.g.
     254             :                  *   AddToShadowCopySet(UNC=\\server\hidden$)
     255             :                  *   CommitShadowCopySet()
     256             :                  *   ExposeShadowCopySet()
     257             :                  *   -> new share = \\server\hidden$@{ShadowCopy.ShadowCopyId}
     258             :                  * But...
     259             :                  *   AddToShadowCopySet(UNC=\\server\hidden$\)
     260             :                  *   CommitShadowCopySet()
     261             :                  *   ExposeShadowCopySet()
     262             :                  *   -> new share = \\server\hidden$@{ShadowCopy.ShadowCopyId}$
     263             :                  */
     264           0 :                 map_array[i].ShareNameUNC = talloc_asprintf(mem_ctx,
     265             :                                                             "\\\\%s\\%s\\",
     266             :                                                             desthost,
     267           0 :                                                 argv[i + num_non_share_args]);
     268           0 :                 if (map_array[i].ShareNameUNC == NULL) {
     269           0 :                         return NT_STATUS_NO_MEMORY;
     270             :                 }
     271             :         }
     272           0 :         *num_maps = num_share_args;
     273           0 :         *maps = map_array;
     274             : 
     275           0 :         return NT_STATUS_OK;
     276             : }
     277             : 
     278           0 : static NTSTATUS cmd_fss_abort(TALLOC_CTX *mem_ctx,
     279             :                               struct dcerpc_binding_handle *b,
     280             :                               struct GUID *sc_set_id)
     281             : {
     282             :         NTSTATUS status;
     283             :         struct fss_AbortShadowCopySet r_scset_abort;
     284             : 
     285           0 :         ZERO_STRUCT(r_scset_abort);
     286           0 :         r_scset_abort.in.ShadowCopySetId = *sc_set_id;
     287           0 :         status = dcerpc_fss_AbortShadowCopySet_r(b, mem_ctx, &r_scset_abort);
     288           0 :         if (!NT_STATUS_IS_OK(status) || (r_scset_abort.out.result != 0)) {
     289           0 :                 DEBUG(0, ("AbortShadowCopySet failed: %s result: 0x%x\n",
     290             :                           nt_errstr(status), r_scset_abort.out.result));
     291           0 :                 return NT_STATUS_UNSUCCESSFUL;
     292             :         }
     293           0 :         return NT_STATUS_OK;
     294             : }
     295             : 
     296           0 : static NTSTATUS cmd_fss_create_expose(struct rpc_pipe_client *cli,
     297             :                                      TALLOC_CTX *mem_ctx, int argc,
     298             :                                      const char **argv)
     299             : {
     300             :         NTSTATUS status;
     301             :         struct fss_GetSupportedVersion r_version_get;
     302             :         struct fss_SetContext r_context_set;
     303             :         struct fss_StartShadowCopySet r_scset_start;
     304             :         struct fss_PrepareShadowCopySet r_scset_prep;
     305             :         struct fss_CommitShadowCopySet r_scset_commit;
     306             :         struct fss_ExposeShadowCopySet r_scset_expose;
     307           0 :         struct dcerpc_binding_handle *b = cli->binding_handle;
     308             :         time_t start_time;
     309             :         TALLOC_CTX *tmp_ctx;
     310             :         uint32_t fss_ctx_val;
     311             :         int num_maps;
     312             :         struct fssagent_share_mapping_1 *req_maps;
     313             :         int i;
     314             : 
     315           0 :         tmp_ctx = talloc_new(mem_ctx);
     316           0 :         if (tmp_ctx == NULL) {
     317           0 :                 return NT_STATUS_NO_MEMORY;
     318             :         }
     319             : 
     320           0 :         status = cmd_fss_create_expose_parse(tmp_ctx, argc, argv, cli->desthost,
     321             :                                             &fss_ctx_val, &num_maps, &req_maps);
     322           0 :         if (!NT_STATUS_IS_OK(status)) {
     323           0 :                 cmd_fss_create_expose_usage(argv[0]);
     324           0 :                 goto err_out;
     325             :         }
     326             : 
     327             :         /*
     328             :          * PrepareShadowCopySet & CommitShadowCopySet often exceed the default
     329             :          * 60 second dcerpc request timeout against Windows Server "8" Beta.
     330             :          * ACHTUNG! dcerpc_binding_handle_set_timeout() value is interpreted as
     331             :          * seconds on a source4 transport and as msecs here.
     332             :          */
     333           0 :         dcerpc_binding_handle_set_timeout(b, 240 * 1000);
     334             : 
     335           0 :         for (i = 0; i < num_maps; i++) {
     336             :                 struct fss_IsPathSupported r_pathsupport_get;
     337           0 :                 r_pathsupport_get.in.ShareName = req_maps[i].ShareNameUNC;
     338           0 :                 status = dcerpc_fss_IsPathSupported_r(b, tmp_ctx, &r_pathsupport_get);
     339           0 :                 if (!NT_STATUS_IS_OK(status) || (r_pathsupport_get.out.result != 0)) {
     340           0 :                         DEBUG(0, ("IsPathSupported failed: %s result: 0x%x\n",
     341             :                                   nt_errstr(status), r_pathsupport_get.out.result));
     342           0 :                         goto err_out;
     343             :                 }
     344           0 :                 if (!r_pathsupport_get.out.SupportedByThisProvider) {
     345           0 :                         printf("path %s does not supported shadow-copies\n",
     346           0 :                                req_maps[i].ShareNameUNC);
     347           0 :                         status = NT_STATUS_NOT_SUPPORTED;
     348           0 :                         goto err_out;
     349             :                 }
     350             :         }
     351             : 
     352           0 :         ZERO_STRUCT(r_version_get);
     353           0 :         status = dcerpc_fss_GetSupportedVersion_r(b, tmp_ctx, &r_version_get);
     354           0 :         if (!NT_STATUS_IS_OK(status) || (r_version_get.out.result != 0)) {
     355           0 :                 DEBUG(0, ("GetSupportedVersion failed: %s result: 0x%x\n",
     356             :                           nt_errstr(status), r_version_get.out.result));
     357           0 :                 goto err_out;
     358             :         }
     359             : 
     360           0 :         ZERO_STRUCT(r_context_set);
     361           0 :         r_context_set.in.Context = fss_ctx_val;
     362           0 :         status = dcerpc_fss_SetContext_r(b, tmp_ctx, &r_context_set);
     363           0 :         if (!NT_STATUS_IS_OK(status) || (r_context_set.out.result != 0)) {
     364           0 :                 DEBUG(0, ("SetContext failed: %s result: 0x%x\n",
     365             :                           nt_errstr(status), r_context_set.out.result));
     366           0 :                 goto err_out;
     367             :         }
     368             : 
     369           0 :         ZERO_STRUCT(r_scset_start);
     370           0 :         r_scset_start.in.ClientShadowCopySetId = GUID_random();
     371           0 :         status = dcerpc_fss_StartShadowCopySet_r(b, tmp_ctx, &r_scset_start);
     372           0 :         if (!NT_STATUS_IS_OK(status) || (r_scset_start.out.result != 0)) {
     373           0 :                 DEBUG(0, ("StartShadowCopySet failed: %s result: 0x%x\n",
     374             :                           nt_errstr(status), r_scset_start.out.result));
     375           0 :                 goto err_out;
     376             :         }
     377           0 :         printf("%s: shadow-copy set created\n",
     378           0 :                GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId));
     379             : 
     380           0 :         for (i = 0; i < num_maps; i++) {
     381             :                 struct fss_AddToShadowCopySet r_scset_add;
     382           0 :                 r_scset_add.in.ClientShadowCopyId = GUID_random();
     383           0 :                 r_scset_add.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
     384           0 :                 r_scset_add.in.ShareName = req_maps[i].ShareNameUNC;
     385           0 :                 status = dcerpc_fss_AddToShadowCopySet_r(b, tmp_ctx, &r_scset_add);
     386           0 :                 if (!NT_STATUS_IS_OK(status) || (r_scset_add.out.result != 0)) {
     387           0 :                         DEBUG(0, ("AddToShadowCopySet failed: %s result: 0x%x\n",
     388             :                                   nt_errstr(status), r_scset_add.out.result));
     389           0 :                         goto err_sc_set_abort;
     390             :                 }
     391           0 :                 printf("%s(%s): %s shadow-copy added to set\n",
     392           0 :                        GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId),
     393           0 :                        GUID_string(tmp_ctx, r_scset_add.out.pShadowCopyId),
     394             :                        r_scset_add.in.ShareName);
     395           0 :                 req_maps[i].ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
     396           0 :                 req_maps[i].ShadowCopyId = *r_scset_add.out.pShadowCopyId;
     397             :         }
     398             : 
     399           0 :         start_time = time_mono(NULL);
     400           0 :         ZERO_STRUCT(r_scset_prep);
     401           0 :         r_scset_prep.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
     402           0 :         r_scset_prep.in.TimeOutInMilliseconds = (240 * 1000);
     403           0 :         status = dcerpc_fss_PrepareShadowCopySet_r(b, tmp_ctx, &r_scset_prep);
     404           0 :         if (!NT_STATUS_IS_OK(status) || (r_scset_prep.out.result != 0)) {
     405           0 :                 DEBUG(0, ("PrepareShadowCopySet failed: %s result: 0x%x\n",
     406             :                           nt_errstr(status), r_scset_prep.out.result));
     407           0 :                 goto err_sc_set_abort;
     408             :         }
     409           0 :         printf("%s: prepare completed in %llu secs\n",
     410           0 :                GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId),
     411           0 :                (long long unsigned int)(time_mono(NULL) - start_time));
     412             : 
     413           0 :         start_time = time_mono(NULL);
     414           0 :         ZERO_STRUCT(r_scset_commit);
     415           0 :         r_scset_commit.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
     416           0 :         r_scset_commit.in.TimeOutInMilliseconds = (180 * 1000); /* win8 */
     417           0 :         status = dcerpc_fss_CommitShadowCopySet_r(b, tmp_ctx, &r_scset_commit);
     418           0 :         if (!NT_STATUS_IS_OK(status) || (r_scset_commit.out.result != 0)) {
     419           0 :                 DEBUG(0, ("CommitShadowCopySet failed: %s result: 0x%x\n",
     420             :                           nt_errstr(status), r_scset_commit.out.result));
     421           0 :                 goto err_sc_set_abort;
     422             :         }
     423           0 :         printf("%s: commit completed in %llu secs\n",
     424           0 :                GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId),
     425           0 :                (long long unsigned int)(time_mono(NULL) - start_time));
     426             : 
     427           0 :         ZERO_STRUCT(r_scset_expose);
     428           0 :         r_scset_expose.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
     429           0 :         r_scset_expose.in.TimeOutInMilliseconds = (120 * 1000); /* win8 */
     430           0 :         status = dcerpc_fss_ExposeShadowCopySet_r(b, tmp_ctx, &r_scset_expose);
     431           0 :         if (!NT_STATUS_IS_OK(status) || (r_scset_expose.out.result != 0)) {
     432           0 :                 DEBUG(0, ("ExposeShadowCopySet failed: %s result: 0x%x\n",
     433             :                           nt_errstr(status), r_scset_expose.out.result));
     434           0 :                 goto err_out;
     435             :         }
     436             : 
     437           0 :         for (i = 0; i < num_maps; i++) {
     438             :                 struct fss_GetShareMapping r_sharemap_get;
     439             :                 struct fssagent_share_mapping_1 *map;
     440           0 :                 r_sharemap_get.in.ShadowCopyId = req_maps[i].ShadowCopyId;
     441           0 :                 r_sharemap_get.in.ShadowCopySetId = req_maps[i].ShadowCopySetId;
     442           0 :                 r_sharemap_get.in.ShareName = req_maps[i].ShareNameUNC;
     443           0 :                 r_sharemap_get.in.Level = 1;
     444           0 :                 status = dcerpc_fss_GetShareMapping_r(b, tmp_ctx, &r_sharemap_get);
     445           0 :                 if (!NT_STATUS_IS_OK(status) || (r_sharemap_get.out.result != 0)) {
     446           0 :                         DEBUG(0, ("GetShareMapping failed: %s result: 0x%x\n",
     447             :                                   nt_errstr(status), r_sharemap_get.out.result));
     448           0 :                         goto err_out;
     449             :                 }
     450           0 :                 map = r_sharemap_get.out.ShareMapping->ShareMapping1;
     451           0 :                 printf("%s(%s): share %s exposed as a snapshot of %s\n",
     452           0 :                        GUID_string(tmp_ctx, &map->ShadowCopySetId),
     453           0 :                        GUID_string(tmp_ctx, &map->ShadowCopyId),
     454             :                        map->ShadowCopyShareName, map->ShareNameUNC);
     455             :         }
     456             : 
     457           0 :         talloc_free(tmp_ctx);
     458           0 :         return NT_STATUS_OK;
     459             : 
     460           0 : err_sc_set_abort:
     461           0 :         cmd_fss_abort(tmp_ctx, b, r_scset_start.out.pShadowCopySetId);
     462           0 : err_out:
     463           0 :         talloc_free(tmp_ctx);
     464           0 :         return status;
     465             : }
     466             : 
     467           0 : static void cmd_fss_delete_usage(const char *script_name)
     468             : {
     469           0 :         printf("usage: %s [base_share] [shadow_copy_set_id] [shadow_copy_id]\n",
     470             :                script_name);
     471           0 : }
     472             : 
     473           0 : static NTSTATUS cmd_fss_delete(struct rpc_pipe_client *cli,
     474             :                                TALLOC_CTX *mem_ctx, int argc,
     475             :                                const char **argv)
     476             : {
     477           0 :         struct dcerpc_binding_handle *b = cli->binding_handle;
     478             :         struct fss_DeleteShareMapping r_sharemap_del;
     479             :         const char *sc_set_id;
     480             :         const char *sc_id;
     481             :         NTSTATUS status;
     482             :         TALLOC_CTX *tmp_ctx;
     483             : 
     484           0 :         if (argc < 4) {
     485           0 :                 cmd_fss_delete_usage(argv[0]);
     486           0 :                 return NT_STATUS_UNSUCCESSFUL;
     487             :         }
     488           0 :         sc_set_id = argv[2];
     489           0 :         sc_id = argv[3];
     490             : 
     491           0 :         tmp_ctx = talloc_new(mem_ctx);
     492           0 :         if (tmp_ctx == NULL) {
     493           0 :                 return NT_STATUS_NO_MEMORY;
     494             :         }
     495             : 
     496           0 :         ZERO_STRUCT(r_sharemap_del);
     497           0 :         r_sharemap_del.in.ShareName = talloc_asprintf(tmp_ctx, "\\\\%s\\%s\\",
     498           0 :                                                       cli->desthost, argv[1]);
     499           0 :         if (r_sharemap_del.in.ShareName == NULL) {
     500           0 :                 status = NT_STATUS_NO_MEMORY;
     501           0 :                 goto err_out;
     502             :         }
     503           0 :         status = GUID_from_string(sc_set_id, &r_sharemap_del.in.ShadowCopySetId);
     504           0 :         if (!NT_STATUS_IS_OK(status)) {
     505           0 :                 DEBUG(0, ("Invalid shadow_copy_set_id parameter\n"));
     506           0 :                 goto err_out;
     507             :         }
     508           0 :         status = GUID_from_string(sc_id, &r_sharemap_del.in.ShadowCopyId);
     509           0 :         if (!NT_STATUS_IS_OK(status)) {
     510           0 :                 DEBUG(0, ("Invalid shadow_copy_id parameter\n"));
     511           0 :                 goto err_out;
     512             :         }
     513           0 :         status = dcerpc_fss_DeleteShareMapping_r(b, tmp_ctx, &r_sharemap_del);
     514           0 :         if (!NT_STATUS_IS_OK(status)) {
     515           0 :                 DEBUG(0, ("DeleteShareMapping failed\n"));
     516           0 :                 goto err_out;
     517           0 :         } else if (r_sharemap_del.out.result != 0) {
     518           0 :                 DEBUG(0, ("failed DeleteShareMapping response: 0x%x\n",
     519             :                           r_sharemap_del.out.result));
     520           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     521           0 :                 goto err_out;
     522             :         }
     523             : 
     524           0 :         printf("%s(%s): %s shadow-copy deleted\n",
     525             :                sc_set_id, sc_id, r_sharemap_del.in.ShareName);
     526             : 
     527           0 : err_out:
     528           0 :         talloc_free(tmp_ctx);
     529           0 :         return status;
     530             : }
     531             : 
     532           0 : static void cmd_fss_is_shadow_copied_usage(const char *script_name)
     533             : {
     534           0 :         printf("usage: %s [share_name]\n", script_name);
     535           0 : }
     536             : 
     537           0 : static NTSTATUS cmd_fss_is_shadow_copied(struct rpc_pipe_client *cli,
     538             :                                          TALLOC_CTX *mem_ctx, int argc,
     539             :                                          const char **argv)
     540             : {
     541             :         NTSTATUS status;
     542             :         struct fss_IsPathShadowCopied r;
     543           0 :         struct dcerpc_binding_handle *b = cli->binding_handle;
     544             : 
     545           0 :         if (argc != 2) {
     546           0 :                 cmd_fss_is_shadow_copied_usage(argv[0]);
     547           0 :                 return NT_STATUS_UNSUCCESSFUL;
     548             :         }
     549             : 
     550           0 :         ZERO_STRUCT(r);
     551           0 :         r.in.ShareName = talloc_asprintf(mem_ctx, "%s\\%s\\",
     552           0 :                                          cli->srv_name_slash, argv[1]);
     553           0 :         if (r.in.ShareName == NULL) {
     554           0 :                 return NT_STATUS_NO_MEMORY;
     555             :         }
     556             : 
     557           0 :         status = dcerpc_fss_IsPathShadowCopied_r(b, mem_ctx, &r);
     558           0 :         if (!NT_STATUS_IS_OK(status)) {
     559           0 :                 DEBUG(0, ("IsPathShadowCopied failed with UNC %s\n",
     560             :                           r.in.ShareName));
     561           0 :                 return NT_STATUS_UNSUCCESSFUL;
     562           0 :         } else if (r.out.result) {
     563           0 :                 DEBUG(0, ("failed IsPathShadowCopied response: 0x%x\n",
     564             :                           r.out.result));
     565           0 :                 return NT_STATUS_UNSUCCESSFUL;
     566             :         }
     567           0 :         printf("UNC %s %s an associated shadow-copy with compatibility 0x%x\n",
     568             :                r.in.ShareName,
     569           0 :                *r.out.ShadowCopyPresent ? "has" : "does not have",
     570           0 :                *r.out.ShadowCopyCompatibility);
     571             : 
     572           0 :         return NT_STATUS_OK;
     573             : }
     574             : 
     575           0 : static void cmd_fss_get_mapping_usage(const char *script_name)
     576             : {
     577           0 :         printf("usage: %s [base_share] [shadow_copy_set_id] [shadow_copy_id]\n",
     578             :                script_name);
     579           0 : }
     580             : 
     581           0 : static NTSTATUS cmd_fss_get_mapping(struct rpc_pipe_client *cli,
     582             :                                     TALLOC_CTX *mem_ctx, int argc,
     583             :                                     const char **argv)
     584             : {
     585           0 :         struct dcerpc_binding_handle *b = cli->binding_handle;
     586             :         struct fss_GetShareMapping r_sharemap_get;
     587             :         const char *sc_set_id;
     588             :         const char *sc_id;
     589             :         struct fssagent_share_mapping_1 *map;
     590             :         NTSTATUS status;
     591             :         TALLOC_CTX *tmp_ctx;
     592             : 
     593           0 :         if (argc < 4) {
     594           0 :                 cmd_fss_get_mapping_usage(argv[0]);
     595           0 :                 return NT_STATUS_UNSUCCESSFUL;
     596             :         }
     597           0 :         sc_set_id = argv[2];
     598           0 :         sc_id = argv[3];
     599             : 
     600           0 :         tmp_ctx = talloc_new(mem_ctx);
     601           0 :         if (tmp_ctx == NULL) {
     602           0 :                 return NT_STATUS_NO_MEMORY;
     603             :         }
     604             : 
     605           0 :         ZERO_STRUCT(r_sharemap_get);
     606           0 :         r_sharemap_get.in.ShareName = talloc_asprintf(tmp_ctx, "\\\\%s\\%s\\",
     607           0 :                                                       cli->desthost, argv[1]);
     608           0 :         if (r_sharemap_get.in.ShareName == NULL) {
     609           0 :                 status = NT_STATUS_NO_MEMORY;
     610           0 :                 goto err_out;
     611             :         }
     612           0 :         status = GUID_from_string(sc_set_id, &r_sharemap_get.in.ShadowCopySetId);
     613           0 :         if (!NT_STATUS_IS_OK(status)) {
     614           0 :                 DEBUG(0, ("Invalid shadow_copy_set_id parameter\n"));
     615           0 :                 goto err_out;
     616             :         }
     617           0 :         status = GUID_from_string(sc_id, &r_sharemap_get.in.ShadowCopyId);
     618           0 :         if (!NT_STATUS_IS_OK(status)) {
     619           0 :                 DEBUG(0, ("Invalid shadow_copy_id parameter\n"));
     620           0 :                 goto err_out;
     621             :         }
     622           0 :         r_sharemap_get.in.Level = 1;
     623           0 :         status = dcerpc_fss_GetShareMapping_r(b, tmp_ctx, &r_sharemap_get);
     624           0 :         if (!NT_STATUS_IS_OK(status)) {
     625           0 :                 DEBUG(0, ("GetShareMapping failed\n"));
     626           0 :                 goto err_out;
     627           0 :         } else if (r_sharemap_get.out.result != 0) {
     628           0 :                 DEBUG(0, ("failed GetShareMapping response: 0x%x\n",
     629             :                           r_sharemap_get.out.result));
     630           0 :                 status = NT_STATUS_UNSUCCESSFUL;
     631           0 :                 goto err_out;
     632             :         }
     633             : 
     634           0 :         map = r_sharemap_get.out.ShareMapping->ShareMapping1;
     635           0 :         printf("%s(%s): share %s is a shadow-copy of %s at %s\n",
     636           0 :                GUID_string(tmp_ctx, &map->ShadowCopySetId),
     637           0 :                GUID_string(tmp_ctx, &map->ShadowCopyId),
     638             :                map->ShadowCopyShareName, map->ShareNameUNC,
     639             :                nt_time_string(tmp_ctx, map->tstamp));
     640             : 
     641           0 : err_out:
     642           0 :         talloc_free(tmp_ctx);
     643           0 :         return status;
     644             : }
     645             : 
     646           0 : static void cmd_fss_recov_complete_usage(const char *script_name)
     647             : {
     648           0 :         printf("usage: %s [shadow_copy_set_id]\n", script_name);
     649           0 : }
     650             : 
     651           0 : static NTSTATUS cmd_fss_recov_complete(struct rpc_pipe_client *cli,
     652             :                                        TALLOC_CTX *mem_ctx, int argc,
     653             :                                        const char **argv)
     654             : {
     655             :         NTSTATUS status;
     656             :         struct fss_RecoveryCompleteShadowCopySet r;
     657           0 :         struct dcerpc_binding_handle *b = cli->binding_handle;
     658             :         const char *sc_set_id;
     659             : 
     660           0 :         if (argc != 2) {
     661           0 :                 cmd_fss_recov_complete_usage(argv[0]);
     662           0 :                 return NT_STATUS_UNSUCCESSFUL;
     663             :         }
     664           0 :         sc_set_id = argv[1];
     665             : 
     666           0 :         ZERO_STRUCT(r);
     667           0 :         status = GUID_from_string(sc_set_id, &r.in.ShadowCopySetId);
     668           0 :         if (!NT_STATUS_IS_OK(status)) {
     669           0 :                 DEBUG(0, ("Invalid shadow_copy_set_id\n"));
     670           0 :                 return NT_STATUS_INVALID_PARAMETER;
     671             :         }
     672             : 
     673           0 :         status = dcerpc_fss_RecoveryCompleteShadowCopySet_r(b, mem_ctx, &r);
     674           0 :         if (!NT_STATUS_IS_OK(status) || (r.out.result != 0)) {
     675           0 :                 DEBUG(0, ("RecoveryCompleteShadowCopySet failed: %s "
     676             :                           "result: 0x%x\n", nt_errstr(status), r.out.result));
     677           0 :                 return status;
     678             :         }
     679           0 :         printf("%s: shadow-copy set marked recovery complete\n", sc_set_id);
     680             : 
     681           0 :         return NT_STATUS_OK;
     682             : }
     683             : 
     684             : /* List of commands exported by this module */
     685             : struct cmd_set fss_commands[] = {
     686             : 
     687             :         {
     688             :                 .name = "FSRVP",
     689             :         },
     690             : 
     691             :         {
     692             :                 .name = "fss_is_path_sup",
     693             :                 .returntype = RPC_RTYPE_NTSTATUS,
     694             :                 .ntfn = cmd_fss_is_path_sup,
     695             :                 .table = &ndr_table_FileServerVssAgent,
     696             :                 .rpc_pipe = NULL,
     697             :                 .description = "Check whether a share supports shadow-copy "
     698             :                                "requests",
     699             :                 .usage = "",
     700             :         },
     701             :         {
     702             :                 .name = "fss_get_sup_version",
     703             :                 .returntype = RPC_RTYPE_NTSTATUS,
     704             :                 .ntfn = cmd_fss_get_sup_version,
     705             :                 .table = &ndr_table_FileServerVssAgent,
     706             :                 .rpc_pipe = NULL,
     707             :                 .description = "Get supported FSRVP version from server",
     708             :                 .usage = "",
     709             :         },
     710             :         {
     711             :                 .name = "fss_create_expose",
     712             :                 .returntype = RPC_RTYPE_NTSTATUS,
     713             :                 .ntfn = cmd_fss_create_expose,
     714             :                 .table = &ndr_table_FileServerVssAgent,
     715             :                 .rpc_pipe = NULL,
     716             :                 .description = "Request shadow-copy creation and exposure",
     717             :                 .usage = "",
     718             :         },
     719             :         {
     720             :                 .name = "fss_delete",
     721             :                 .returntype = RPC_RTYPE_NTSTATUS,
     722             :                 .ntfn = cmd_fss_delete,
     723             :                 .table = &ndr_table_FileServerVssAgent,
     724             :                 .rpc_pipe = NULL,
     725             :                 .description = "Request shadow-copy share deletion",
     726             :                 .usage = "",
     727             :         },
     728             :         {
     729             :                 .name = "fss_has_shadow_copy",
     730             :                 .returntype = RPC_RTYPE_NTSTATUS,
     731             :                 .ntfn = cmd_fss_is_shadow_copied,
     732             :                 .table = &ndr_table_FileServerVssAgent,
     733             :                 .rpc_pipe = NULL,
     734             :                 .description = "Check for an associated share shadow-copy",
     735             :                 .usage = "",
     736             :         },
     737             :         {
     738             :                 .name = "fss_get_mapping",
     739             :                 .returntype = RPC_RTYPE_NTSTATUS,
     740             :                 .ntfn = cmd_fss_get_mapping,
     741             :                 .table = &ndr_table_FileServerVssAgent,
     742             :                 .rpc_pipe = NULL,
     743             :                 .description = "Get shadow-copy share mapping information",
     744             :                 .usage = "",
     745             :         },
     746             :         {
     747             :                 .name = "fss_recovery_complete",
     748             :                 .returntype = RPC_RTYPE_NTSTATUS,
     749             :                 .ntfn = cmd_fss_recov_complete,
     750             :                 .table = &ndr_table_FileServerVssAgent,
     751             :                 .rpc_pipe = NULL,
     752             :                 .description = "Flag read-write snapshot as recovery complete, "
     753             :                                "allowing further shadow-copy requests",
     754             :                 .usage = "",
     755             :         },
     756             :         {
     757             :                 .name = NULL,
     758             :         },
     759             : };

Generated by: LCOV version 1.14