summaryrefslogtreecommitdiff
path: root/source4/libcli
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libcli')
-rw-r--r--source4/libcli/clideltree.c17
-rw-r--r--source4/libcli/smb2/util.c6
2 files changed, 22 insertions, 1 deletions
diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c
index 2c306e501e..d59a03f194 100644
--- a/source4/libcli/clideltree.c
+++ b/source4/libcli/clideltree.c
@@ -84,6 +84,7 @@ int smbcli_deltree(struct smbcli_tree *tree, const char *dname)
{
char *mask;
struct delete_state dstate;
+ NTSTATUS status;
dstate.tree = tree;
dstate.total_deleted = 0;
@@ -98,6 +99,13 @@ int smbcli_deltree(struct smbcli_tree *tree, const char *dname)
NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_NO_SUCH_FILE)) {
return 0;
}
+ if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
+ /* it could be read-only */
+ status = smbcli_setatr(tree, dname, FILE_ATTRIBUTE_NORMAL, 0);
+ if (NT_STATUS_IS_OK(smbcli_unlink(tree, dname))) {
+ return 1;
+ }
+ }
asprintf(&mask, "%s\\*", dname);
smbcli_unlink(dstate.tree, mask);
@@ -105,7 +113,14 @@ int smbcli_deltree(struct smbcli_tree *tree, const char *dname)
FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
delete_fn, &dstate);
free(mask);
- if (NT_STATUS_IS_ERR(smbcli_rmdir(dstate.tree, dname))) {
+
+ status = smbcli_rmdir(dstate.tree, dname);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
+ /* it could be read-only */
+ status = smbcli_setatr(dstate.tree, dname, FILE_ATTRIBUTE_NORMAL, 0);
+ status = smbcli_rmdir(dstate.tree, dname);
+ }
+ if (NT_STATUS_IS_ERR(status)) {
DEBUG(2,("Failed to delete %s - %s\n",
dname, smbcli_errstr(dstate.tree)));
return -1;
diff --git a/source4/libcli/smb2/util.c b/source4/libcli/smb2/util.c
index 311cea94a0..b149b3d6ce 100644
--- a/source4/libcli/smb2/util.c
+++ b/source4/libcli/smb2/util.c
@@ -197,6 +197,12 @@ int smb2_deltree(struct smb2_tree *tree, const char *dname)
smb2_util_close(tree, create_parm.out.file.handle);
status = smb2_util_rmdir(tree, dname);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
+ /* it could be read-only */
+ status = smb2_util_setatr(tree, dname, FILE_ATTRIBUTE_NORMAL);
+ status = smb2_util_rmdir(tree, dname);
+ }
+
if (NT_STATUS_IS_ERR(status)) {
DEBUG(2,("Failed to delete %s - %s\n",
dname, nt_errstr(status)));