]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s4:libcli/smb2: let smb2_deltree delete directory streams
authorStefan Metzmacher <metze@samba.org>
Thu, 18 Jul 2024 14:22:55 +0000 (16:22 +0200)
committerVolker Lendecke <vl@samba.org>
Thu, 29 Aug 2024 18:25:28 +0000 (18:25 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15656

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
source4/libcli/smb2/util.c

index f86a149c646a041f46bf6baf139559b86a10cadb..ef67d33c94b224711107eba29e8df156e54aacfc 100644 (file)
@@ -183,6 +183,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;
+       union smb_fileinfo finfo;
        bool did_delete;
 
        /* it might be a file */
@@ -223,7 +224,50 @@ int smb2_deltree(struct smb2_tree *tree, const char *dname)
                talloc_free(tmp_ctx);
                return -1;
        }
-       
+
+       ZERO_STRUCT(finfo);
+       finfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
+       finfo.generic.in.file.handle = create_parm.out.file.handle;
+
+       status = smb2_getinfo_file(tree, tmp_ctx, &finfo);
+       if (NT_STATUS_IS_OK(status)) {
+               /*
+                * For directories we need to cleanup
+                * streams manually
+                */
+               for (i = 0; i < finfo.stream_info.out.num_streams; i++) {
+                       const struct stream_struct *s =
+                               &finfo.stream_info.out.streams[i];
+                       union smb_unlink io;
+                       char *spath = NULL;
+
+                       if (strequal(s->stream_name.s, "::$DATA")) {
+                               /* should not happen for directories */
+                               continue;
+                       }
+
+                       spath = talloc_asprintf(tmp_ctx,
+                                               "%s%s",
+                                               dname,
+                                               s->stream_name.s);
+                       if (spath == NULL) {
+                               talloc_free(tmp_ctx);
+                               return -1;
+                       }
+
+                       ZERO_STRUCT(io);
+                       io.unlink.in.pattern = spath;
+                       if (s->alloc_size != 0) {
+                               io.unlink.in.truncate_if_needed = true;
+                       }
+
+                       status = smb2_composite_unlink(tree, &io);
+                       TALLOC_FREE(spath);
+                       if (NT_STATUS_IS_OK(status)) {
+                               total_deleted++;
+                       }
+               }
+       }
 
        do {
                did_delete = false;