From 13a82f48059359869a7754e4a69b157ff0313f27 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Jul 2017 17:21:18 -0700 Subject: [PATCH 1/6] s3: smbclient: Add new command deltree. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12914 Signed-off-by: Jeremy Allison Reviewed-by: Alexander Bokovoy Reviewed-by: Andreas Schneider (cherry picked from commit b6f484ae9ca737a0772b279b88fc285fe1cec0e9) --- source3/client/client.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) diff --git a/source3/client/client.c b/source3/client/client.c index c431a01..2522b8a 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -2432,6 +2432,183 @@ static int cmd_del(void) } /**************************************************************************** + Delete some files. +****************************************************************************/ + +static NTSTATUS delete_remote_files_list(struct cli_state *cli_state, + struct file_list *flist) +{ + NTSTATUS status = NT_STATUS_OK; + struct file_list *deltree_list_iter = NULL; + + for (deltree_list_iter = flist; + deltree_list_iter != NULL; + deltree_list_iter = deltree_list_iter->next) { + if (CLI_DIRSEP_CHAR == '/') { + /* POSIX. */ + status = cli_posix_unlink(cli_state, + deltree_list_iter->file_path); + } else if (deltree_list_iter->isdir) { + status = cli_rmdir(cli_state, + deltree_list_iter->file_path); + } else { + status = cli_unlink(cli_state, + deltree_list_iter->file_path, + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN); + } + if (!NT_STATUS_IS_OK(status)) { + d_printf("%s deleting remote %s %s\n", + nt_errstr(status), + deltree_list_iter->isdir ? + "directory" : "file", + deltree_list_iter->file_path); + return status; + } + } + return NT_STATUS_OK; +} + +/**************************************************************************** + Save a list of files to delete. +****************************************************************************/ + +static struct file_list *deltree_list_head; + +static NTSTATUS do_deltree_list(struct cli_state *cli_state, + struct file_info *finfo, + const char *dir) +{ + struct file_list **file_list_head_pp = &deltree_list_head; + struct file_list *dt = NULL; + + if (!do_this_one(finfo)) { + return NT_STATUS_OK; + } + + /* skip if this is . or .. */ + if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) { + return NT_STATUS_OK; + } + + dt = talloc_zero(NULL, struct file_list); + if (dt == NULL) { + return NT_STATUS_NO_MEMORY; + } + + /* create absolute filename for cli_ntcreate() */ + dt->file_path = talloc_asprintf(dt, + "%s%s%s", + dir, + CLI_DIRSEP_STR, + finfo->name); + if (dt->file_path == NULL) { + TALLOC_FREE(dt); + return NT_STATUS_NO_MEMORY; + } + + if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) { + dt->isdir = true; + } + + DLIST_ADD(*file_list_head_pp, dt); + return NT_STATUS_OK; +} + +static int cmd_deltree(void) +{ + TALLOC_CTX *ctx = talloc_tos(); + char *buf = NULL; + NTSTATUS status = NT_STATUS_OK; + struct file_list *deltree_list_norecurse = NULL; + struct file_list *deltree_list_iter = NULL; + uint16_t attribute = FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_DIRECTORY; + bool ok; + char *mask = talloc_strdup(ctx, client_get_cur_dir()); + if (mask == NULL) { + return 1; + } + ok = next_token_talloc(ctx, &cmd_ptr, &buf, NULL); + if (!ok) { + d_printf("deltree \n"); + return 1; + } + mask = talloc_asprintf_append(mask, "%s", buf); + if (mask == NULL) { + return 1; + } + + deltree_list_head = NULL; + + /* + * Get the list of directories to + * delete (in case mask has a wildcard). + */ + status = do_list(mask, attribute, do_deltree_list, false, true); + if (!NT_STATUS_IS_OK(status)) { + goto err; + } + deltree_list_norecurse = deltree_list_head; + deltree_list_head = NULL; + + for (deltree_list_iter = deltree_list_norecurse; + deltree_list_iter != NULL; + deltree_list_iter = deltree_list_iter->next) { + + if (deltree_list_iter->isdir == false) { + /* Just a regular file. */ + if (CLI_DIRSEP_CHAR == '/') { + /* POSIX. */ + status = cli_posix_unlink(cli, + deltree_list_iter->file_path); + } else { + status = cli_unlink(cli, + deltree_list_iter->file_path, + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN); + } + if (!NT_STATUS_IS_OK(status)) { + goto err; + } + continue; + } + + /* + * Get the list of files or directories to + * delete in depth order. + */ + status = do_list(deltree_list_iter->file_path, + attribute, + do_deltree_list, + true, + true); + if (!NT_STATUS_IS_OK(status)) { + goto err; + } + status = delete_remote_files_list(cli, deltree_list_head); + free_file_list(deltree_list_head); + deltree_list_head = NULL; + if (!NT_STATUS_IS_OK(status)) { + goto err; + } + } + + free_file_list(deltree_list_norecurse); + free_file_list(deltree_list_head); + return 0; + + err: + + free_file_list(deltree_list_norecurse); + free_file_list(deltree_list_head); + deltree_list_head = NULL; + return 1; +} + + +/**************************************************************************** Wildcard delete some files. ****************************************************************************/ @@ -4998,6 +5175,7 @@ static struct { {"chown",cmd_chown," chown a file using UNIX uids and gids",{COMPL_REMOTE,COMPL_NONE}}, {"close",cmd_close," close a file given a fid",{COMPL_REMOTE,COMPL_NONE}}, {"del",cmd_del," delete all matching files",{COMPL_REMOTE,COMPL_NONE}}, + {"deltree",cmd_deltree," recursively delete all matching files and directories",{COMPL_REMOTE,COMPL_NONE}}, {"dir",cmd_dir," list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}}, {"du",cmd_du," computes the total size of the current directory",{COMPL_REMOTE,COMPL_NONE}}, {"echo",cmd_echo,"ping the server",{COMPL_NONE,COMPL_NONE}}, -- 1.9.1 From 01070c21e8b3811f0ed1aa46148125b8b84b23e1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Jul 2017 17:23:48 -0700 Subject: [PATCH 2/6] docs: Document new smbclient deltree command. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12914 Signed-off-by: Jeremy Allison Reviewed-by: Alexander Bokovoy Reviewed-by: Andreas Schneider (cherry picked from commit f2f9f51fef8e264fdad11018e3c447db0ad03cc1) --- docs-xml/manpages/smbclient.1.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs-xml/manpages/smbclient.1.xml b/docs-xml/manpages/smbclient.1.xml index 2b712fe..432f60d 100644 --- a/docs-xml/manpages/smbclient.1.xml +++ b/docs-xml/manpages/smbclient.1.xml @@ -655,6 +655,16 @@ + deltree <mask> + The client will request that the server attempt + to delete all files and directories matching mask from the current working + directory on the server. Note this will recursively delete files and directories within + the directories selected even without the recurse command being set. If any of the delete + requests fail the command will stop processing at that point, leaving files and directories + not yet processed untouched. This is by design. + + + dir <mask> A list of the files matching mask in the current working directory on the server will be retrieved from the server -- 1.9.1 From d9666d0431c14566638d3cac193d1c5aa1a4df30 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 Jul 2017 10:52:45 -0700 Subject: [PATCH 3/6] s3: tests: Add test for new smbclient "deltree" command. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12914 Signed-off-by: Jeremy Allison Reviewed-by: Alexander Bokovoy Reviewed-by: Andreas Schneider Autobuild-User(master): Andreas Schneider Autobuild-Date(master): Fri Jul 7 13:38:24 CEST 2017 on sn-devel-144 (cherry picked from commit b21ee14e2265a6dd11dd83c8e252a40de394585a) --- source3/script/tests/test_smbclient_s3.sh | 47 +++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh index 4cfd054..3cbe6f5 100755 --- a/source3/script/tests/test_smbclient_s3.sh +++ b/source3/script/tests/test_smbclient_s3.sh @@ -1189,6 +1189,49 @@ EOF fi } +# Test smbclient deltree command +test_deltree() +{ + tmpfile=$PREFIX/smbclient_interactive_prompt_commands + deltree_dir=$PREFIX/deltree_dir + + rm -rf $deltree_dir + cat > $tmpfile < Date: Tue, 18 Jul 2017 12:03:32 +0200 Subject: [PATCH 4/6] s3:tests: Fix directory creation and deletion of test_local_symlinks() This should fix flakey autobuild. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12914 Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit b594e0cdd2b68d262377cfe438253244b89d089c) --- source3/script/tests/test_smbclient_s3.sh | 85 ++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 8 deletions(-) diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh index 3cbe6f5..b82d89b 100755 --- a/source3/script/tests/test_smbclient_s3.sh +++ b/source3/script/tests/test_smbclient_s3.sh @@ -1148,21 +1148,60 @@ test_local_symlinks() LOCAL_RAWARGS="${CONFIGURATION} -mSMB3" LOCAL_ADDARGS="${LOCAL_RAWARGS} $*" - test_dir="$LOCAL_PATH/local_symlinks/test" + share_test_dir="test" + share_slink_target_dir="$share_test_dir/dir1" - slink_name="$test_dir/sym_name" - slink_target_dir="$test_dir/dir1" + local_test_dir="$LOCAL_PATH/local_symlinks/$share_test_dir" + local_slink_name="$local_test_dir/sym_name" + local_slink_target_dir="$local_test_dir/dir1" - rm -rf $test_dir + rm -rf $local_test_dir - mkdir -p $test_dir - mkdir $slink_target_dir - ln -s $slink_target_dir $slink_name +# Create the initial directories + tmpfile=$PREFIX/smbclient_interactive_prompt_commands + cat > $tmpfile < $tmpfile < $tmpfile < Date: Tue, 18 Jul 2017 12:29:16 +0200 Subject: [PATCH 5/6] s3:tests: Fix directory creation and deletion of test_nosymlinks() This should fix flakey autobuild. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12914 Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Wed Jul 19 11:59:52 CEST 2017 on sn-devel-144 (cherry picked from commit bd7eab1639bb5eb70ff04b8f4b89373ca47daf08) --- source3/script/tests/test_smbclient_s3.sh | 89 +++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 11 deletions(-) diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh index b82d89b..59d742f 100755 --- a/source3/script/tests/test_smbclient_s3.sh +++ b/source3/script/tests/test_smbclient_s3.sh @@ -1042,21 +1042,61 @@ EOF test_nosymlinks() { # Setup test dirs. - test_dir="$LOCAL_PATH/nosymlinks/test" + local_test_dir="$LOCAL_PATH/nosymlinks/test" + local_slink_name="$local_test_dir/source" + local_slink_target="$local_test_dir/nosymlink_target_file" - slink_name="$test_dir/source" - slink_target="$test_dir/target" - foobar_dir="$test_dir/foo/bar" - get_target="$test_dir/foo/bar/testfile" + share_test_dir="test" + share_foo_dir="$share_test_dir/foo" + share_foobar_dir="$share_test_dir/foo/bar" + share_target_file="$share_test_dir/foo/bar/testfile" + + rm -rf $local_test_dir - rm -rf $test_dir + local_nosymlink_target_file="nosymlink_target_file" + echo "$local_slink_target" > $local_nosymlink_target_file - mkdir -p $test_dir - echo "$slink_target" > $slink_target - ln -s $slink_target $slink_name + local_foobar_target_file="testfile" + echo "$share_target_file" > $local_foobar_target_file + + tmpfile=$PREFIX/smbclient_interactive_prompt_commands + cat > $tmpfile < $get_target +# Create the symlink locally + ln -s $local_slink_target $local_slink_name # Getting a file through a symlink name should fail. tmpfile=$PREFIX/smbclient_interactive_prompt_commands @@ -1136,6 +1176,33 @@ EOF echo "failed - NT_STATUS_XXXX doing cd foo\\bar; get testfile on \\nosymlinks" return 1 fi + +# CLEANUP + rm -f $local_slink_name + + cat > $tmpfile < Date: Wed, 19 Jul 2017 22:04:44 +0200 Subject: [PATCH 6/6] WHATSNEW: add a note about the new 'smbclient deltree' command. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12914 Signed-off-by: Stefan Metzmacher --- WHATSNEW.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/WHATSNEW.txt b/WHATSNEW.txt index d43f376..5d49bb7 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -41,6 +41,9 @@ getfacl and symlink. Using "-mNT1" reenabled them, if the server supports SMB1. Note the default ("CORE") for "client min protocol" hasn't changed, so it's still possible to connect to SMB1-only servers by default. +smbclient learned a new command "deltree" that is able to do +a recursive deletion of a directory tree. + NEW FEATURES/CHANGES ==================== -- 1.9.1