summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/smb2/util.c78
1 files changed, 42 insertions, 36 deletions
diff --git a/source4/libcli/smb2/util.c b/source4/libcli/smb2/util.c
index a360d8fbdf..8602c91a9f 100644
--- a/source4/libcli/smb2/util.c
+++ b/source4/libcli/smb2/util.c
@@ -113,6 +113,7 @@ int smb2_deltree(struct smb2_tree *tree, const char *dname)
TALLOC_CTX *tmp_ctx = talloc_new(tree);
struct smb2_find f;
struct smb2_create create_parm;
+ bool did_delete;
/* it might be a file */
status = smb2_util_unlink(tree, dname);
@@ -154,45 +155,50 @@ int smb2_deltree(struct smb2_tree *tree, const char *dname)
}
- ZERO_STRUCT(f);
- f.in.file.handle = create_parm.out.file.handle;
- f.in.max_response_size = 0x10000;
- f.in.level = SMB2_FIND_NAME_INFO;
- f.in.pattern = "*";
-
- status = smb2_find_level(tree, tmp_ctx, &f, &count, &list);
- if (NT_STATUS_IS_ERR(status)) {
- DEBUG(2,("Failed to list %s - %s\n",
- dname, nt_errstr(status)));
- smb2_util_close(tree, create_parm.out.file.handle);
- talloc_free(tmp_ctx);
- return -1;
- }
-
- for (i=0;i<count;i++) {
- char *name;
- if (strcmp(".", list[i].name_info.name.s) == 0 ||
- strcmp("..", list[i].name_info.name.s) == 0) {
- continue;
+ do {
+ did_delete = false;
+
+ ZERO_STRUCT(f);
+ f.in.file.handle = create_parm.out.file.handle;
+ f.in.max_response_size = 0x10000;
+ f.in.level = SMB2_FIND_NAME_INFO;
+ f.in.pattern = "*";
+
+ status = smb2_find_level(tree, tmp_ctx, &f, &count, &list);
+ if (NT_STATUS_IS_ERR(status)) {
+ DEBUG(2,("Failed to list %s - %s\n",
+ dname, nt_errstr(status)));
+ smb2_util_close(tree, create_parm.out.file.handle);
+ talloc_free(tmp_ctx);
+ return -1;
}
- name = talloc_asprintf(tmp_ctx, "%s\\%s", dname, list[i].name_info.name.s);
- status = smb2_util_unlink(tree, name);
- if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
- /* it could be read-only */
- status = smb2_util_setatr(tree, name, FILE_ATTRIBUTE_NORMAL);
+
+ for (i=0;i<count;i++) {
+ char *name;
+ if (strcmp(".", list[i].name_info.name.s) == 0 ||
+ strcmp("..", list[i].name_info.name.s) == 0) {
+ continue;
+ }
+ name = talloc_asprintf(tmp_ctx, "%s\\%s", dname, list[i].name_info.name.s);
status = smb2_util_unlink(tree, name);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
+ /* it could be read-only */
+ status = smb2_util_setatr(tree, name, FILE_ATTRIBUTE_NORMAL);
+ status = smb2_util_unlink(tree, name);
+ }
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
+ int ret;
+ ret = smb2_deltree(tree, name);
+ if (ret > 0) total_deleted += ret;
+ }
+ talloc_free(name);
+ if (NT_STATUS_IS_OK(status)) {
+ total_deleted++;
+ did_delete = true;
+ }
}
-
- if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
- int ret;
- ret = smb2_deltree(tree, name);
- if (ret > 0) total_deleted += ret;
- }
- talloc_free(name);
- if (NT_STATUS_IS_OK(status)) {
- total_deleted++;
- }
- }
+ } while (did_delete);
smb2_util_close(tree, create_parm.out.file.handle);