summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2004-08-20 20:13:05 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:52:25 -0500
commit19e949a91ba342ec1de2c01e5bfddf8392cb68b5 (patch)
treeb404cbcc6af35cb4ef16b594d8c1d141144fd6a1
parent3eb42d3b6e64c817396ee4391e0dcaacc5db0029 (diff)
downloadsamba-19e949a91ba342ec1de2c01e5bfddf8392cb68b5.tar.gz
samba-19e949a91ba342ec1de2c01e5bfddf8392cb68b5.tar.xz
samba-19e949a91ba342ec1de2c01e5bfddf8392cb68b5.zip
r1966: further work on and cleanup of the net-migration-tool.
It's now possible to migrate files preserving dos-attributes and correct timestamps. Also added some small docu- and syntax-fixes. Guenther (This used to be commit 0e990582a0416933a8671ca660d22e980f828402)
-rw-r--r--source3/utils/net.c14
-rw-r--r--source3/utils/net.h2
-rw-r--r--source3/utils/net_help.c28
-rw-r--r--source3/utils/net_rpc.c77
-rw-r--r--source3/utils/net_rpc_printer.c103
5 files changed, 164 insertions, 60 deletions
diff --git a/source3/utils/net.c b/source3/utils/net.c
index 6a1a97914a1..2c7ee7a224c 100644
--- a/source3/utils/net.c
+++ b/source3/utils/net.c
@@ -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
diff --git a/source3/utils/net.h b/source3/utils/net.h
index cb38907ff95..29498b91085 100644
--- a/source3/utils/net.h
+++ b/source3/utils/net.h
@@ -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;
diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c
index c17824cb271..a0fc07cb5a9 100644
--- a/source3/utils/net_help.c
+++ b/source3/utils/net_help.c
@@ -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;
}
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 47e47f079f9..26bcb51fa5e 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -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");
diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c
index e4197d72ce7..7684878677e 100644
--- a/source3/utils/net_rpc_printer.c
+++ b/source3/utils/net_rpc_printer.c
@@ -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;