]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: smbd: Fix delete operations enumerating streams inside a file. This must always...
authorJeremy Allison <jra@samba.org>
Wed, 20 Jul 2016 18:34:48 +0000 (11:34 -0700)
committerKarolin Seeger <kseeger@samba.org>
Wed, 3 Aug 2016 09:19:13 +0000 (11:19 +0200)
When using UNIX extensions to delete a file containing streams,
the open for delete and close operations need to enumerate the
contained streams and do CREATE and UNLINK operations on the
stream names. These must always be done as Windows operations
(use lp_set_posix_pathnames(false) to flip the processing) as
the stream names are Windows paths.

Without this the create operation under the unlink will
recurse and cause the client to time out (or a server crash).

This (hack) is only needed for 4.4.x and below, it is fixed
correctly in 4.5.x.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12021

Signed-off-by: Jeremy Allison <jra@samba.org>
source3/smbd/close.c
source3/smbd/open.c

index 1cb546055d09d35524757eede01949057dd32c6d..66840aed5f31129f9e4619551a39ff8b1febfcb1 100644 (file)
@@ -168,6 +168,7 @@ NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
        unsigned int num_streams = 0;
        TALLOC_CTX *frame = talloc_stackframe();
        NTSTATUS status;
+       bool saved_posix_pathnames;
 
        status = vfs_streaminfo(conn, NULL, fname, talloc_tos(),
                                &num_streams, &stream_info);
@@ -192,6 +193,13 @@ NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
                return NT_STATUS_OK;
        }
 
+       /*
+        * Any stream names *must* be treated as Windows
+        * pathnames, even if we're using UNIX extensions.
+        */
+
+       saved_posix_pathnames = lp_set_posix_pathnames(false);
+
        for (i=0; i<num_streams; i++) {
                int res;
                struct smb_filename *smb_fname_stream;
@@ -223,6 +231,8 @@ NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
        }
 
  fail:
+
+       (void)lp_set_posix_pathnames(saved_posix_pathnames);
        TALLOC_FREE(frame);
        return status;
 }
index 0a6ec0df99ba283c4a5e4ff0b2dede50958bda51..590561ebce81beaee87df4b490686a7862015bbc 100644 (file)
@@ -3867,6 +3867,7 @@ NTSTATUS open_streams_for_delete(connection_struct *conn,
        unsigned int num_streams = 0;
        TALLOC_CTX *frame = talloc_stackframe();
        NTSTATUS status;
+       bool saved_posix_pathnames;
 
        status = vfs_streaminfo(conn, NULL, fname, talloc_tos(),
                                &num_streams, &stream_info);
@@ -3899,6 +3900,13 @@ NTSTATUS open_streams_for_delete(connection_struct *conn,
                goto fail;
        }
 
+       /*
+        * Any stream names *must* be treated as Windows
+        * pathnames, even if we're using UNIX extensions.
+        */
+
+       saved_posix_pathnames = lp_set_posix_pathnames(false);
+
        for (i=0; i<num_streams; i++) {
                struct smb_filename *smb_fname;
 
@@ -3966,6 +3974,8 @@ NTSTATUS open_streams_for_delete(connection_struct *conn,
        }
 
  fail:
+
+       (void)lp_set_posix_pathnames(saved_posix_pathnames);
        TALLOC_FREE(frame);
        return status;
 }