diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/libcli/smb2/util.c | 78 |
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); |