]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
r1966: further work on and cleanup of the net-migration-tool.
authorGünther Deschner <gd@samba.org>
Fri, 20 Aug 2004 20:13:05 +0000 (20:13 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:52:25 +0000 (10:52 -0500)
It's now possible to migrate files preserving dos-attributes and correct
timestamps. Also added some small docu- and syntax-fixes.

Guenther

source/utils/net.c
source/utils/net.h
source/utils/net_help.c
source/utils/net_rpc.c
source/utils/net_rpc_printer.c

index 6a1a97914a19b8d99df39cd5d1c9277e58dd8104..2c7ee7a224c999a30480465932a92acd982d2491 100644 (file)
@@ -79,6 +79,8 @@ BOOL opt_domaingroup = False;
 const char *opt_newntname = "";
 int opt_rid = 0;
 int opt_acls = 0;
+int opt_attrs = 0;
+int opt_timestamps = 0;
 const char *opt_exclude = NULL;
 
 BOOL opt_have_ip = False;
@@ -209,9 +211,9 @@ NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
 /**
  * Connect the local server and open a given pipe
  *
- * @param cli_local            A cli_state to the local spoolss-server
+ * @param cli_local            A cli_state 
  * @param pipe                 The pipe to open
- * @param got_pipe             boolean to that stores if got a pipe
+ * @param got_pipe             boolean that stores if we got a pipe
  *
  * @return Normal NTSTATUS return.
  **/
@@ -222,13 +224,13 @@ NTSTATUS connect_local_pipe(struct cli_state **cli_local, int pipe_num, BOOL *go
        char *server_name = strdup("127.0.0.1");
        struct cli_state *cli_tmp = NULL;
 
-       /* make a connection to smbd via loopback */
+       /* make a connection to local named pipe via loopback */
        nt_status = connect_to_ipc(&cli_tmp, &loopback_ip, server_name);
        if (!NT_STATUS_IS_OK(nt_status)) 
                return nt_status;
 
        if (!cli_nt_session_open(cli_tmp, pipe_num)) {
-               DEBUG(0, ("couldn't not initialise spoolss pipe\n"));
+               DEBUG(0, ("couldn't not initialize pipe\n"));
                cli_shutdown(cli_tmp);
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -738,7 +740,9 @@ static struct functable net_func[] = {
                {"ntname",      'N', POPT_ARG_STRING, &opt_newntname},
                {"rid",         'R', POPT_ARG_INT,    &opt_rid},
                /* Options for 'net rpc share migrate' */
-               {"acls",        'a', POPT_ARG_NONE,   &opt_acls},
+               {"acls",        0, POPT_ARG_NONE,   &opt_acls},
+               {"attrs",       0, POPT_ARG_NONE,   &opt_attrs},
+               {"timestamps",  0, POPT_ARG_NONE,   &opt_timestamps},
                {"exclude",     'e', POPT_ARG_STRING, &opt_exclude},
 
                POPT_COMMON_SAMBA
index cb38907ff95da46903a3f8f627734f4c2e8bc517..29498b9108514f5b8ca180698aa60c7b858cc26e 100644 (file)
@@ -63,6 +63,8 @@ extern BOOL opt_domaingroup;
 extern const char *opt_newntname;
 extern int opt_rid;
 extern int opt_acls;
+extern int opt_attrs;
+extern int opt_timestamps;
 extern const char *opt_exclude;
 
 extern BOOL opt_have_ip;
index c17824cb27107c98f385a92c989ffcd76d34be11..a0fc07cb5a9cdcb1b72637e839136b9cb82c2d40 100644 (file)
@@ -139,8 +139,11 @@ int net_help_share(int argc, const char **argv)
        d_printf(
         "\t-C or --comment=<comment>\tdescriptive comment (for add only)\n"
         "\t-M or --maxusers=<num>\t\tmax users allowed for share\n"
-        "\t-a or --acls\t\t\tcopies ACLs as well\n"
-        "\t-e or --exclude\t\t\tlist of shares to be excluded from mirroring\n");
+        "\t      --acls\t\t\tcopies ACLs as well\n"
+        "\t      --attrs\t\t\tcopies DOS Attributes as well\n"
+        "\t      --timestampes\t\tpreserve timestampes while copying files\n"
+        "\t-e or --exclude\t\t\tlist of shares to be excluded from mirroring\n"
+        "\t-v or --verbose\t\t\tgive verbose output\n");
        return -1;
 }
 
@@ -163,25 +166,28 @@ int net_help_file(int argc, const char **argv)
 
 int net_help_printer(int argc, const char **argv)
 {
-       d_printf("net rpc printer LIST [printer]\n"\
+       d_printf("net rpc printer LIST [printer] [misc. options] [targets]\n"\
                 "\tlists all printers on print-server\n\n");
-       d_printf("net rpc printer DRIVER [printer]\n"\
+       d_printf("net rpc printer DRIVER [printer] [misc. options] [targets]\n"\
                 "\tlists all printer-drivers on print-server\n\n");
-       d_printf("net rpc printer MIGRATE PRINTERS [printer]"\
+       d_printf("net rpc printer MIGRATE PRINTERS [printer] [misc. options] [targets]"\
                 "\n\tmigrates printers from remote to local server\n\n");
-       d_printf("net rpc printer MIGRATE SETTINGS [printer]"\
+       d_printf("net rpc printer MIGRATE SETTINGS [printer] [misc. options] [targets]"\
                 "\n\tmigrates printer-settings from remote to local server\n\n");
-       d_printf("net rpc printer MIGRATE DRIVERS [printer]"\
+       d_printf("net rpc printer MIGRATE DRIVERS [printer] [misc. options] [targets]"\
                 "\n\tmigrates printer-drivers from remote to local server\n\n");
-       d_printf("net rpc printer MIGRATE FORMS [printer]"\
+       d_printf("net rpc printer MIGRATE FORMS [printer] [misc. options] [targets]"\
                 "\n\tmigrates printer-forms from remote to local server\n\n");
-       d_printf("net rpc printer MIGRATE SECURITY [printer]"\
+       d_printf("net rpc printer MIGRATE SECURITY [printer] [misc. options] [targets]"\
                 "\n\tmigrates printer-ACLs from remote to local server\n\n");
-       d_printf("net rpc printer MIGRATE ALL [printer]\n"\
-                "\tmigrates drivers, forms, queues, settings and acls from\n"\
+       d_printf("net rpc printer MIGRATE ALL [printer] [misc. options] [targets]"\
+                "\n\tmigrates drivers, forms, queues, settings and acls from\n"\
                 "\tremote to local print-server\n\n");
        net_common_methods_usage(argc, argv);
        net_common_flags_usage(argc, argv);
+       d_printf(
+        "\t-v or --verbose\t\t\tgive verbose output\n");
+
        return -1;
 }
 
index 47e47f079f94786e7b0aecb6fa16e9467c02790c..26bcb51fa5ee008ccd5643139b7d6adb365f16c7 100644 (file)
@@ -2576,7 +2576,7 @@ rpc_share_migrate_shares_internals(const DOM_SID *domain_sid, const char *domain
 
                /* only work with file-shares */
                if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
-                       d_printf("skipping [%s]. not a file share.\n", netname);
+                       d_printf("skipping   [%s]: not a file share.\n", netname);
                        continue;
                }
 
@@ -2600,10 +2600,10 @@ rpc_share_migrate_shares_internals(const DOM_SID *domain_sid, const char *domain
                                                  level, share_sd);
        
                 if (W_ERROR_V(result) == W_ERROR_V(WERR_ALREADY_EXISTS)) {
-                       printf("share does already exist\n");
+                       printf("           [%s] does already exist\n", netname);
                        continue;
-                }
-       
+               }
+
                if (!W_ERROR_IS_OK(result)) {
                        printf("cannot add share: %s\n", dos_errstr(result));
                        goto done;
@@ -2635,6 +2635,11 @@ done:
 static int rpc_share_migrate_shares(int argc, const char **argv)
 {
 
+       if (!opt_host) {
+               printf("no server to migrate\n");
+               return -1;
+       }
+
        return run_rpc_command(NULL, PI_SRVSVC, 0, 
                               rpc_share_migrate_shares_internals,
                               argc, argv);
@@ -2681,7 +2686,10 @@ static void copy_fn(file_info *f, const char *mask, void *state)
                                          local_state->cli_share_src, 
                                          local_state->cli_share_dst, 
                                          dir, dir, 
-                                         opt_acls? True : False, False);
+                                         opt_acls? True : False, 
+                                         opt_attrs? True : False,
+                                         opt_timestamps? True : False,
+                                         False);
 
                if (!NT_STATUS_IS_OK(nt_status)) 
                        printf("could not copy dir %s: %s\n", 
@@ -2713,7 +2721,10 @@ static void copy_fn(file_info *f, const char *mask, void *state)
                                  local_state->cli_share_src, 
                                  local_state->cli_share_dst, 
                                  filename, filename, 
-                                 opt_acls? True : False, True);
+                                 opt_acls? True : False, 
+                                 opt_attrs? True : False,
+                                 opt_timestamps? True: False,
+                                 True);
 
        if (!NT_STATUS_IS_OK(nt_status)) 
                printf("could not copy file %s: %s\n", 
@@ -2826,26 +2837,29 @@ rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_
                        continue;
                
                if (strequal(netname, "print$") || netname[1] == '$') {
-                       d_printf("skipping  [%s]: builtin/hidden share\n", netname);
+                       d_printf("skipping   [%s]: builtin/hidden share\n", netname);
                        continue;
                }
 
                if (opt_exclude && in_list(netname, (char *)opt_exclude, False)) {
-                       printf("excluding [%s]\n", netname);
+                       printf("excluding  [%s]\n", netname);
                        continue;
                } 
 
                /* only work with file-shares */
                if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
-                       d_printf("skipping  [%s]: not a file share.\n", netname);
+                       d_printf("skipping   [%s]: not a file share.\n", netname);
                        continue;
                }
 
                if (!cli_tdis(cli))
                        return NT_STATUS_UNSUCCESSFUL;
 
-               printf("syncing   [%s] files and directories %s ACLs\n", 
-                       netname, opt_acls ? "including" : "without");
+               printf("syncing    [%s] files and directories %s ACLs, %s DOS Attributes %s\n", 
+                       netname, 
+                       opt_acls ? "including" : "without", 
+                       opt_attrs ? "including" : "without",
+                       opt_timestamps ? "(preserving timestamps)" : "");
 
 
                /* open share source */
@@ -2893,13 +2907,19 @@ done:
 
 static int rpc_share_migrate_files(int argc, const char **argv)
 {
+
+       if (!opt_host) {
+               printf("no server to migrate\n");
+               return -1;
+       }
+
        return run_rpc_command(NULL, PI_SRVSVC, 0, 
                               rpc_share_migrate_files_internals,
                               argc, argv);
 }
 
 /** 
- * Migrate shares (including share-definitions, share-acls and files with acls)
+ * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
  * from one server to another
  *
  * @param argc  Standard main() style argc
@@ -2913,6 +2933,11 @@ static int rpc_share_migrate_all(int argc, const char **argv)
 {
        int ret;
 
+       if (!opt_host) {
+               printf("no server to migrate\n");
+               return -1;
+       }
+
        ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_shares_internals, argc, argv);
        if (ret)
                return ret;
@@ -2937,6 +2962,7 @@ static int rpc_share_migrate(int argc, const char **argv)
        struct functable func[] = {
                {"all",         rpc_share_migrate_all},
                {"files",       rpc_share_migrate_files},
+               {"help",        rpc_share_usage},
 /*             {"security",    rpc_share_migrate_security},*/
                {"shares",      rpc_share_migrate_shares},
                {NULL, NULL}
@@ -4044,6 +4070,11 @@ static int rpc_printer_migrate_all(int argc, const char **argv)
 {
        int ret;
 
+       if (!opt_host) {
+               printf("no server to migrate\n");
+               return -1;
+       }
+
        ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_printers_internals, argc, argv);
        if (ret)
                return ret;
@@ -4075,6 +4106,10 @@ static int rpc_printer_migrate_all(int argc, const char **argv)
  **/
 static int rpc_printer_migrate_drivers(int argc, const char **argv)
 {
+       if (!opt_host) {
+               printf("no server to migrate\n");
+               return -1;
+       }
 
        return run_rpc_command(NULL, PI_SPOOLSS, 0, 
                               rpc_printer_migrate_drivers_internals,
@@ -4092,6 +4127,10 @@ static int rpc_printer_migrate_drivers(int argc, const char **argv)
  **/
 static int rpc_printer_migrate_forms(int argc, const char **argv)
 {
+       if (!opt_host) {
+               printf("no server to migrate\n");
+               return -1;
+       }
 
        return run_rpc_command(NULL, PI_SPOOLSS, 0, 
                               rpc_printer_migrate_forms_internals,
@@ -4109,6 +4148,10 @@ static int rpc_printer_migrate_forms(int argc, const char **argv)
  **/
 static int rpc_printer_migrate_printers(int argc, const char **argv)
 {
+       if (!opt_host) {
+               printf("no server to migrate\n");
+               return -1;
+       }
 
        return run_rpc_command(NULL, PI_SPOOLSS, 0, 
                               rpc_printer_migrate_printers_internals,
@@ -4126,6 +4169,10 @@ static int rpc_printer_migrate_printers(int argc, const char **argv)
  **/
 static int rpc_printer_migrate_security(int argc, const char **argv)
 {
+       if (!opt_host) {
+               printf("no server to migrate\n");
+               return -1;
+       }
 
        return run_rpc_command(NULL, PI_SPOOLSS, 0, 
                               rpc_printer_migrate_security_internals,
@@ -4143,6 +4190,10 @@ static int rpc_printer_migrate_security(int argc, const char **argv)
  **/
 static int rpc_printer_migrate_settings(int argc, const char **argv)
 {
+       if (!opt_host) {
+               printf("no server to migrate\n");
+               return -1;
+       }
 
        return run_rpc_command(NULL, PI_SPOOLSS, 0, 
                               rpc_printer_migrate_settings_internals,
@@ -4265,7 +4316,7 @@ int net_rpc_usage(int argc, const char **argv)
        d_printf("  net rpc user \t\t\tto add, delete and list users\n");
         d_printf("  net rpc password <username> [<password>] -Uadmin_username%%admin_pass");
        d_printf("  net rpc group \t\tto list groups\n");
-       d_printf("  net rpc share \t\tto add, delete, and list shares\n");
+       d_printf("  net rpc share \t\tto add, delete, list and migrate shares\n");
        d_printf("  net rpc printer \t\tto list and migrate printers\n");
        d_printf("  net rpc file \t\t\tto list open files\n");
        d_printf("  net rpc changetrustpw \tto change the trust account password\n");
index e4197d72ce7f627c03ddf96cbb0bf12a86672ab9..7684878677e177e9da823d033ac767f88c077574 100644 (file)
@@ -283,6 +283,8 @@ static void display_reg_value(pstring subkey, REGISTRY_VALUE value)
  * @param src_file             The source file-name
  * @param dst_file             The destination file-name
  * @param copy_acls            Whether to copy acls
+ * @param copy_attrs           Whether to copy DOS attributes
+ * @param copy_timestamps      Whether to preserve timestamps
  * @param is_file              Whether this file is a file or a dir
  *
  * @return Normal NTSTATUS return.
@@ -291,7 +293,8 @@ NTSTATUS net_copy_file(TALLOC_CTX *mem_ctx,
                       struct cli_state *cli_share_src,
                       struct cli_state *cli_share_dst, 
                       char *src_name, char *dst_name,
-                      BOOL copy_acls, BOOL is_file)
+                      BOOL copy_acls, BOOL copy_attrs,
+                      BOOL copy_timestamps, BOOL is_file)
 {
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
        int fnum_src = 0;
@@ -302,6 +305,8 @@ NTSTATUS net_copy_file(TALLOC_CTX *mem_ctx,
        off_t start = 0;
        off_t nread = 0;
        SEC_DESC *sd = NULL;
+       uint16 attr;
+       time_t atime, ctime, mtime;
 
 
        /* open on the originating server */
@@ -349,7 +354,20 @@ NTSTATUS net_copy_file(TALLOC_CTX *mem_ctx,
                /* get the security descriptor */
                sd = cli_query_secdesc(cli_share_src, fnum_src, mem_ctx);
                if (!sd) {
-                       DEBUG(0, ("failed to get security descriptor\n"));
+                       DEBUG(0, ("failed to get security descriptor: %s\n",
+                               cli_errstr(cli_share_src)));
+                       nt_status = cli_nt_error(cli_share_src);
+                       goto out;
+               }
+       }
+
+       if (copy_attrs || copy_timestamps) {
+
+               /* get dos attributes */
+               if (!cli_getattrE(cli_share_src, fnum_src, &attr, NULL, 
+                       &ctime, &atime, &mtime)) {
+                       DEBUG(0, ("failed to get file-attrs: %s\n", 
+                               cli_errstr(cli_share_src)));
                        nt_status = cli_nt_error(cli_share_src);
                        goto out;
                }
@@ -358,10 +376,13 @@ NTSTATUS net_copy_file(TALLOC_CTX *mem_ctx,
        /* copying file */
        if (opt_verbose) {
 
-               d_printf("copying [\\\\%s\\%s%s] => [\\\\%s\\%s%s] %s acls.\n", 
-                       cli_share_src->desthost, cli_share_src->share, src_name, 
+               d_printf("copying [\\\\%s\\%s%s] => [\\\\%s\\%s%s] "
+                        "%s acls and %s DOS Attributes %s\n", 
+                       cli_share_src->desthost, cli_share_src->share, src_name,
                        cli_share_dst->desthost, cli_share_dst->share, dst_name,
-                       copy_acls ? "with" : "without" );
+                       copy_acls ?  "with" : "without", 
+                       copy_attrs ? "with" : "without",
+                       copy_timestamps ? "(preserving timestamps)" : "" );
 
                if (DEBUGLEVEL >= 3 && copy_acls)
                        display_sec_desc(sd);
@@ -392,7 +413,7 @@ NTSTATUS net_copy_file(TALLOC_CTX *mem_ctx,
        /* creating dir */
        if (!is_file && !cli_chkpath(cli_share_dst, dst_name)) {
 
-               DEBUGADD(1,("creating dir %s on the destination server\n", 
+               DEBUGADD(3,("creating dir %s on the destination server\n", 
                        dst_name));
 
                if (!cli_mkdir(cli_share_dst, dst_name)) {
@@ -408,47 +429,67 @@ NTSTATUS net_copy_file(TALLOC_CTX *mem_ctx,
                 }
        }
 
-
-       /* closing files */
-       if (!cli_close(cli_share_src, fnum_src)) {
-               d_printf("could not close file on originating server: %s\n", 
-                       cli_errstr(cli_share_src));
-               nt_status = cli_nt_error(cli_share_src);
-               goto out;
-       }
-
-       if (is_file && !cli_close(cli_share_dst, fnum_dst)) {
-               d_printf("could not close file on destinantion server: %s\n", 
-                       cli_errstr(cli_share_dst));
+       /* open the file/dir a second time */ 
+       fnum_dst = cli_nt_create(cli_share_dst, dst_name, 
+                       WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS);
+       
+       if (fnum_dst == -1) {
+               DEBUG(0,("failed to open file/dir again: %s: %s\n",
+                       dst_name, cli_errstr(cli_share_dst)));
                nt_status = cli_nt_error(cli_share_dst);
                goto out;
        }
 
+       /* set timestamps */
+       if (copy_timestamps) {
+       
+               if (!cli_setattrE(cli_share_dst, fnum_dst, ctime, atime, mtime)) {
+                       DEBUG(0,("failed to set file-attrs (timestamps): %s\n",
+                               cli_errstr(cli_share_dst)));
+                       nt_status = cli_nt_error(cli_share_dst);
+                       goto out;
+               }
+       }
 
-       /* finally set acls */
+       /* set acls */
        if (copy_acls) {
 
-               /* Open the file/dir a second time */ 
-               fnum_dst = cli_nt_create(cli_share_dst, dst_name, 
-                               WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS);
-
-               if (fnum_dst == -1) {
-                       DEBUG(0, ("failed to open file/dir again: %s: %s\n",
-                                 dst_name, cli_errstr(cli_share_dst)));
+               if (!cli_set_secdesc(cli_share_dst, fnum_dst, sd)) {
+                       DEBUG(0,("could not set secdesc on %s %s: %s\n", 
+                               is_file? "file":"dir", dst_name, 
+                               cli_errstr(cli_share_dst)));
                        nt_status = cli_nt_error(cli_share_dst);
                        goto out;
                }
+       }
 
-               if (!cli_set_secdesc(cli_share_dst, fnum_dst, sd)) {
-                       DEBUG(0, ("could not set secdesc on %s %s: %s\n", 
-                               is_file? "file":"dir", dst_name, 
+       /* set attrs */
+       if (copy_attrs) {
+
+               if (!cli_setatr(cli_share_dst, dst_name, attr, 0)) {
+                       DEBUG(0,("failed to set file-attrs: %s\n",
                                cli_errstr(cli_share_dst)));
                        nt_status = cli_nt_error(cli_share_dst);
                        goto out;
                }
        }
 
-       
+       /* closing files */
+       if (!cli_close(cli_share_src, fnum_src)) {
+               d_printf("could not close file on originating server: %s\n", 
+                       cli_errstr(cli_share_src));
+               nt_status = cli_nt_error(cli_share_src);
+               goto out;
+       }
+
+       if (is_file && !cli_close(cli_share_dst, fnum_dst)) {
+               d_printf("could not close file on destination server: %s\n", 
+                       cli_errstr(cli_share_dst));
+               nt_status = cli_nt_error(cli_share_dst);
+               goto out;
+       }
+
+
        nt_status = NT_STATUS_OK;
 
 out:
@@ -520,7 +561,7 @@ static NTSTATUS net_copy_driverfile(TALLOC_CTX *mem_ctx,
 
        /* finally copy the file */
        nt_status = net_copy_file(mem_ctx, cli_share_src, cli_share_dst, 
-                                 src_name, dst_name, False, True);
+                                 src_name, dst_name, False, False, False, True);
        if (!NT_STATUS_IS_OK(nt_status))
                goto out;