rpcclient: append a trailing slash to FSRVP request UNCs
authorDavid Disseldorp <ddiss@samba.org>
Sat, 29 Mar 2014 01:18:18 +0000 (02:18 +0100)
committerJeremy Allison <jra@samba.org>
Mon, 31 Mar 2014 20:52:14 +0000 (22:52 +0200)
The Windows Server 2012 FSRVP server exhibits strange behaviour when
exposing hidden shadow copy shares. If the hidden share UNC in the
AddToShadowCopySet request includes a trailing backslash (e.g.
"\\server\share$\"), then the new shadow-copy share will also be hidden
(e.g. "\\server\share$@{ShadowCopy.ShadowCopyId}$").
However, if the UNC does not include a trailing backslash, which until
now was rpcclient's default behaviour, then the exposed shadow-copy
share is not hidden.

Thanks to the MS Open Specifications team for helping me track down this
one.

bug: https://bugzilla.samba.org/show_bug.cgi?id=10521

Signed-off-by: David Disseldorp <ddiss@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/rpcclient/cmd_fss.c

index 238bd79f29424b16c12f35f17395adab6d2661a3..a2e26c66fcea56fb10f83a1064166674ce716464 100644 (file)
@@ -136,7 +136,7 @@ static NTSTATUS cmd_fss_is_path_sup(struct rpc_pipe_client *cli,
        }
 
        ZERO_STRUCT(r);
-       r.in.ShareName = talloc_asprintf(mem_ctx, "%s\\%s",
+       r.in.ShareName = talloc_asprintf(mem_ctx, "%s\\%s\\",
                                         cli->srv_name_slash, argv[1]);
        if (r.in.ShareName == NULL) {
                return NT_STATUS_NO_MEMORY;
@@ -235,8 +235,24 @@ static NTSTATUS cmd_fss_create_expose_parse(TALLOC_CTX *mem_ctx, int argc,
        }
 
        for (i = 0; i < num_share_args; i++) {
-               map_array[i].ShareNameUNC = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
-                                       desthost, argv[i + num_non_share_args]);
+               /*
+                * A trailing slash should to be present in the request UNC,
+                * otherwise Windows Server 2012 FSRVP servers don't append
+                * a '$' to exposed hidden share shadow-copies. E.g.
+                *   AddToShadowCopySet(UNC=\\server\hidden$)
+                *   CommitShadowCopySet()
+                *   ExposeShadowCopySet()
+                *   -> new share = \\server\hidden$@{ShadowCopy.ShadowCopyId}
+                * But...
+                *   AddToShadowCopySet(UNC=\\server\hidden$\)
+                *   CommitShadowCopySet()
+                *   ExposeShadowCopySet()
+                *   -> new share = \\server\hidden$@{ShadowCopy.ShadowCopyId}$
+                */
+               map_array[i].ShareNameUNC = talloc_asprintf(mem_ctx,
+                                                           "\\\\%s\\%s\\",
+                                                           desthost,
+                                               argv[i + num_non_share_args]);
                if (map_array[i].ShareNameUNC == NULL) {
                        return NT_STATUS_NO_MEMORY;
                }
@@ -443,7 +459,7 @@ static NTSTATUS cmd_fss_delete(struct rpc_pipe_client *cli,
        }
 
        ZERO_STRUCT(r_sharemap_del);
-       r_sharemap_del.in.ShareName = talloc_asprintf(tmp_ctx, "\\\\%s\\%s",
+       r_sharemap_del.in.ShareName = talloc_asprintf(tmp_ctx, "\\\\%s\\%s\\",
                                                      cli->desthost, argv[1]);
        if (r_sharemap_del.in.ShareName == NULL) {
                status = NT_STATUS_NO_MEMORY;
@@ -497,7 +513,7 @@ static NTSTATUS cmd_fss_is_shadow_copied(struct rpc_pipe_client *cli,
        }
 
        ZERO_STRUCT(r);
-       r.in.ShareName = talloc_asprintf(mem_ctx, "%s\\%s",
+       r.in.ShareName = talloc_asprintf(mem_ctx, "%s\\%s\\",
                                         cli->srv_name_slash, argv[1]);
        if (r.in.ShareName == NULL) {
                return NT_STATUS_NO_MEMORY;
@@ -552,7 +568,7 @@ static NTSTATUS cmd_fss_get_mapping(struct rpc_pipe_client *cli,
        }
 
        ZERO_STRUCT(r_sharemap_get);
-       r_sharemap_get.in.ShareName = talloc_asprintf(tmp_ctx, "\\\\%s\\%s",
+       r_sharemap_get.in.ShareName = talloc_asprintf(tmp_ctx, "\\\\%s\\%s\\",
                                                      cli->desthost, argv[1]);
        if (r_sharemap_get.in.ShareName == NULL) {
                status = NT_STATUS_NO_MEMORY;