r7512: Fix net share migrate files to also migrate the ACLs of the top level
authorLars Müller <lmuelle@samba.org>
Sun, 12 Jun 2005 21:18:16 +0000 (21:18 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:57:10 +0000 (10:57 -0500)
dir of a share.  Till now we excluded '.' and '..' in general.  For the
fix the information about top or lower level dir is stored in the
copy_clistate.  src and dst share are now also part of this struct and
we only pass a pointer to the struct to the functions.

This bug was found by Bill Calero of Novell.  Thanks Bill!

With this checkin no new functionality was added.  But the copy_clistate
already knows about a mode. Later beside the migrate an additional
report mode will be added.

This changes are coordinated with Günther <gd>.

Lars
(This used to be commit 506aaefa3716c7683eef9afe0d1bb5b6e2533c4b)

source3/utils/net.h
source3/utils/net_rpc.c
source3/utils/net_rpc_printer.c

index 2d9fbd16448fcab7f8515d175a131900969d33ff..ebabf605dd3a72e7ef25216d9d3b606ead8845f0 100644 (file)
 typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, const char *, 
                                   struct cli_state *, TALLOC_CTX *, int, const char **);
                                   
+typedef struct copy_clistate {
+       TALLOC_CTX *mem_ctx;
+       struct cli_state *cli_share_src;
+       struct cli_state *cli_share_dst;
+       char *cwd;
+       BOOL top_level_dir;
+       uint16 attribute;
+       int mode;
+}copy_clistate; 
+
 /* INCLUDE FILES */
 
 #include "utils/net_proto.h"
@@ -51,6 +61,9 @@ typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, const char *,
 /* don't open an RPC pipe */
 #define NET_FLAGS_NO_PIPE 32
 
+/* net share operation modes */
+#define NET_MODE_SHARE_MIGRATE 1
+
 extern int opt_maxusers;
 extern const char *opt_comment;
 extern const char *opt_container;
index 000e77345efe56f5f6fb62115125e1806234d212..f559fa296cb2e02c66bac479a02d30749b2fb37b 100644 (file)
@@ -2779,14 +2779,6 @@ static int rpc_share_migrate_shares(int argc, const char **argv)
                               argc, argv);
 }
 
-typedef struct copy_clistate {
-       TALLOC_CTX *mem_ctx;
-       struct cli_state *cli_share_src;
-       struct cli_state *cli_share_dst;
-       const char *cwd;
-} copy_clistate;
-
-
 /**
  * Copy a file/dir 
  *
@@ -2797,11 +2789,22 @@ typedef struct copy_clistate {
  **/
 static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state)
 {
-       NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-       struct copy_clistate *local_state = (struct copy_clistate *)state;
-       fstring filename, new_mask, dir;
-
-       if (strequal(f->name, ".") || strequal(f->name, "..")) 
+       static NTSTATUS nt_status;
+       static struct copy_clistate *local_state;
+       static fstring filename, new_mask;
+       fstring dir;
+       char *old_dir;
+
+       local_state = (struct copy_clistate *)state;
+       nt_status = NT_STATUS_UNSUCCESSFUL;
+
+       if (strequal(f->name, ".")) {
+               if (local_state->top_level_dir)
+                       f->name[0] = '\0';
+               else
+                       return;
+       }
+       if (strequal(f->name, ".."))
                return;
 
        DEBUG(3,("got mask: %s, name: %s\n", mask, f->name));
@@ -2815,30 +2818,40 @@ static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state
                fstrcat(dir, "\\");
                fstrcat(dir, f->name);
 
-               /* create that directory */
-               nt_status = net_copy_file(local_state->mem_ctx, 
-                                         local_state->cli_share_src, 
-                                         local_state->cli_share_dst, 
-                                         dir, dir, 
-                                         opt_acls? True : False, 
-                                         opt_attrs? True : False,
-                                         opt_timestamps? True : False,
-                                         False);
+               switch (local_state->mode)
+               {
+               case NET_MODE_SHARE_MIGRATE:
+                       /* create that directory */
+                       nt_status = net_copy_file(local_state->mem_ctx,
+                                                 local_state->cli_share_src,
+                                                 local_state->cli_share_dst,
+                                                 dir, dir,
+                                                 opt_acls? True : False,
+                                                 opt_attrs? True : False,
+                                                 opt_timestamps? True : False,
+                                                 False);
+                       break;
+               default:
+                       DEBUG(0,( "Unsupported mode %d", local_state->mode));
+                       return;
+               }
 
                if (!NT_STATUS_IS_OK(nt_status)) 
-                       printf("could not copy dir %s: %s\n", 
+                       printf("could not handle dir %s: %s\n", 
                                dir, nt_errstr(nt_status));
 
-               /* search below that directory */
-               fstrcpy(new_mask, dir);
-               fstrcat(new_mask, "\\*");
-
-               if (!sync_files(local_state->mem_ctx, 
-                               local_state->cli_share_src, 
-                               local_state->cli_share_dst, 
-                               new_mask, dir))
-
-                       printf("could not sync files\n");
+               if (!local_state->top_level_dir) {
+                       /* search below that directory */
+                       fstrcpy(new_mask, dir);
+                       fstrcat(new_mask, "\\*");
+
+                       old_dir = local_state->cwd;
+                        local_state->cwd = dir;
+                       if (!sync_files(local_state, new_mask))
+                               printf("could not handle files\n");
+                       local_state->cwd = old_dir;
+               } else
+                       local_state->top_level_dir = False;
                        
                return;
        }
@@ -2851,17 +2864,25 @@ static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state
 
        DEBUG(3,("got file: %s\n", filename));
 
-       nt_status = net_copy_file(local_state->mem_ctx, 
-                                 local_state->cli_share_src, 
-                                 local_state->cli_share_dst, 
-                                 filename, filename, 
-                                 opt_acls? True : False, 
-                                 opt_attrs? True : False,
-                                 opt_timestamps? True: False,
-                                 True);
+       switch (local_state->mode)
+       {
+       case NET_MODE_SHARE_MIGRATE:
+               nt_status = net_copy_file(local_state->mem_ctx, 
+                                         local_state->cli_share_src, 
+                                         local_state->cli_share_dst, 
+                                         filename, filename, 
+                                         opt_acls? True : False, 
+                                         opt_attrs? True : False,
+                                         opt_timestamps? True: False,
+                                         True);
+               break;
+       default:
+               DEBUG(0,( "Unsupported file mode %d", local_state->mode));
+               return;
+       }
 
        if (!NT_STATUS_IS_OK(nt_status)) 
-               printf("could not copy file %s: %s\n", 
+               printf("could not handle file %s: %s\n", 
                        filename, nt_errstr(nt_status));
 
 }
@@ -2870,34 +2891,19 @@ static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state
  * sync files, can be called recursivly to list files 
  * and then call copy_fn for each file 
  *
- * @param mem_ctx      TALLOC_CTX
- * @param cli_share_src        a connected share on the originating server
- * @param cli_share_dst        a connected share on the destination server
+ * @param cp_clistate  pointer to the copy_clistate we work with
  * @param mask         the current search mask
- * @param cwd          the current path
  *
  * @return             Boolean result
  **/
-BOOL sync_files(TALLOC_CTX *mem_ctx, 
-               struct cli_state *cli_share_src, 
-               struct cli_state *cli_share_dst,
-               pstring mask, fstring cwd)
-
+BOOL sync_files(struct copy_clistate *cp_clistate, pstring mask)
 {
 
-       uint16 attribute = aSYSTEM | aHIDDEN | aDIR;
-       struct copy_clistate clistate;
-
-       clistate.mem_ctx        = mem_ctx;
-       clistate.cli_share_src  = cli_share_src;
-       clistate.cli_share_dst  = cli_share_dst;
-       clistate.cwd            = cwd;
-
        DEBUG(3,("calling cli_list with mask: %s\n", mask));
 
-       if (cli_list(cli_share_src, mask, attribute, copy_fn, &clistate) == -1) {
+       if (cli_list(cp_clistate->cli_share_src, mask, cp_clistate->attribute, copy_fn, cp_clistate) == -1) {
                d_printf("listing %s failed with error: %s\n", 
-                       mask, cli_errstr(cli_share_src));
+                       mask, cli_errstr(cp_clistate->cli_share_src));
                return False;
        }
 
@@ -2931,13 +2937,15 @@ rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_
        ENUM_HND hnd;
        uint32 preferred_len = 0xffffffff, i;
        uint32 level = 2;
-       struct cli_state *cli_share_src = NULL;
-       struct cli_state *cli_share_dst = NULL;
+       struct copy_clistate cp_clistate;
        BOOL got_src_share = False;
        BOOL got_dst_share = False;
        pstring mask;
        char *dst = NULL;
 
+       /* decrese argc and safe mode */
+       cp_clistate.mode = argv[--argc][0];
+
        dst = SMB_STRDUP(opt_destination?opt_destination:"127.0.0.1");
 
        init_enum_hnd(&hnd, 0);
@@ -2991,40 +2999,57 @@ rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_
                if (!cli_tdis(cli))
                        return NT_STATUS_UNSUCCESSFUL;
 
-               printf("syncing    [%s] files and directories %s ACLs, %s DOS Attributes %s\n", 
+               switch (cp_clistate.mode)
+               {
+               case NET_MODE_SHARE_MIGRATE:
+                       printf("syncing");
+                       break;
+               default:
+                       DEBUG(0,("Unsupported mode %s", cp_clistate.mode));
+                       break;
+               }
+               printf("    [%s] files and directories %s ACLs, %s DOS Attributes %s\n", 
                        netname, 
                        opt_acls ? "including" : "without", 
                        opt_attrs ? "including" : "without",
                        opt_timestamps ? "(preserving timestamps)" : "");
 
+               cp_clistate.mem_ctx = mem_ctx;
+               cp_clistate.cli_share_src = NULL;
+               cp_clistate.cli_share_dst = NULL;
+               cp_clistate.cwd = NULL;
+               cp_clistate.top_level_dir = True;
+               cp_clistate.attribute = aSYSTEM | aHIDDEN | aDIR;
 
                /* open share source */
-               nt_status = connect_to_service(&cli_share_src, &cli->dest_ip, 
-                                              cli->desthost, netname, "A:");
+               nt_status = connect_to_service(&cp_clistate.cli_share_src,
+                                              &cli->dest_ip, cli->desthost,
+                                              netname, "A:");
                if (!NT_STATUS_IS_OK(nt_status))
                        goto done;
 
                got_src_share = True;
 
+               if (cp_clistate.mode == NET_MODE_SHARE_MIGRATE) {
+                       /* open share destination */
+                       nt_status = connect_to_service(&cp_clistate.cli_share_dst,
+                                                      NULL, dst, netname, "A:");
+                       if (!NT_STATUS_IS_OK(nt_status))
+                               goto done;
 
-               /* open share destination */
-               nt_status = connect_to_service(&cli_share_dst, NULL, 
-                                              dst, netname, "A:");
-               if (!NT_STATUS_IS_OK(nt_status))
-                       goto done;
-
-               got_dst_share = True;
+                       got_dst_share = True;
+               }
 
 
                /* now call the filesync */
                pstrcpy(mask, "\\*");
 
-               if (!sync_files(mem_ctx, cli_share_src, cli_share_dst, mask, NULL)) {
-                       d_printf("could not sync files for share: %s\n", netname);
+
+               if (!sync_files(&cp_clistate, mask)) {
+                       d_printf("could not handle files for share: %s\n", netname);
                        nt_status = NT_STATUS_UNSUCCESSFUL;
                        goto done;
                }
-               
        }
 
        nt_status = NT_STATUS_OK;
@@ -3032,11 +3057,11 @@ rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_
 done:
 
        if (got_src_share)
-               cli_shutdown(cli_share_src);
+               cli_shutdown(cp_clistate.cli_share_src);
 
        if (got_dst_share)
-               cli_shutdown(cli_share_dst);
-               
+               cli_shutdown(cp_clistate.cli_share_dst);
+
        return nt_status;
 
 }
@@ -3104,6 +3129,9 @@ static int rpc_share_migrate(int argc, const char **argv)
                {NULL, NULL}
        };
 
+       char mode = NET_MODE_SHARE_MIGRATE;
+       argv[argc++] = &mode;
+
        return net_run_function(argc, argv, func, rpc_share_usage);
 }
 
index b348c2b4e8c5bbc097653393306d690a253deaec..5cc89b41dd99f28fd0a11fa1c69d1b69a41e0ee8 100644 (file)
@@ -479,7 +479,8 @@ NTSTATUS net_copy_file(TALLOC_CTX *mem_ctx,
                fnum_src = cli_nt_create(cli_share_src, src_name, READ_CONTROL_ACCESS);
 
        if (fnum_src == -1) {
-               DEBUGADD(0,("cannot open file %s on originating server %s\n", 
+               DEBUGADD(0,("cannot open %s %s on originating server %s\n",
+                       is_file ? "file":"dir",
                        src_name, cli_errstr(cli_share_src)));
                nt_status = cli_nt_error(cli_share_src);
                goto out;