The branch, master has been updated
       via  398cb8a56d8 s3: smbd: Fix the SMB2 server to pass SMB2-PATH-SLASH.
       via  5642f288c89 s3: torture: Add MS-FSA style terminating '/' and '\' 
test - SMB2-PATH-SLASH.
       via  32d6cc84cf8 dbwrap_watch: Don't alert ourselves, fix 
raw.oplock.batch26 race
       via  64da66a75c6 dbwrap_watch: Remove "addwatch" handling from 
dbwrap_watched_save()
       via  491b71f29b9 dbwrap_watch: Move reallocating watchers to 
dbwrap_watched_watch_send()
       via  88f8edf69ba dbwrap_watch: Slightly simplify 
dbwrap_watched_fetch_locked()
       via  86672659c6a epmapper: Fix printf specifiers
       via  e3e5894b854 torture: Fix a comment
       via  9dc2cd86f69 lib: Fix a typo
       via  5d8493f5b45 rpc_client: Don't pass a NULL string to talloc_asprintf
       via  34a35ac15ef smbd: Fix CID 1453984: Null pointer dereferences 
(REVERSE_INULL)
       via  b66b8a74b10 lib: Fix CID 1453985: Null pointer dereferences 
(FORWARD_NULL)
       via  f21af2ace22 lib: Remove some unneeded #includes from tftw.c
       via  993d327f5d2 s3:smbd: use is_named_stream() in a a few places
       via  4b2e44a6ed7 vfs_default: use is_named_stream() for stream check
       via  c190f3efa9e s3:smbd: add a comment explaining the File-ID semantics 
when a file is created
       via  90a14c90c4b s3:smbd: ensure a created stream picks up the File-ID 
from the basefile
       via  091e3fdab61 s3:lib: add is_named_stream()
       via  780a8dcba99 s3:lib: use strequal_m() in 
is_ntfs_default_stream_smb_fname()
       via  3f8bc1ce3e0 s3:lib: implement logic directly in 
is_ntfs_default_stream_smb_fname()
       via  2584b4cdeae s3:lib: expand a comment with the function doc for 
is_ntfs_stream_smb_fname
       via  f9fdb8a2a6b s3:lib: factor out stream name asserts to helper 
function
       via  6c1647ca7a2 s3:lib: assert stream_name is NULL for POSIX paths
       via  d7dc85990a1 s3:lib: rework a return expression into an if block
       via  49a754b82d3 s3:smbd: when storing DOS attribute call dos_mode() 
beforehand
       via  e1dfaa2b038 s3:smbd: change the place where we call dos_mode() when 
processing SMB2_CREATE
       via  300b47442b0 torture:smb2: add a File-ID test on directories
       via  432202413f4 torture:smb2: extend test for File-IDs
      from  84fae0ed1bb s3: passdb: ret doesn't seem to be needed at all

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 398cb8a56d83a7978836ee0b65b4747d190ab630
Author: Jeremy Allison <[email protected]>
Date:   Thu Sep 26 12:37:15 2019 -0700

    s3: smbd: Fix the SMB2 server to pass SMB2-PATH-SLASH.
    
    [MS-FSA] 2.1.5.1 Server Requests an Open of a File
    
    Windows pathname specific processing.
    
    Always disallow trailing /, and also \\ on FILE_NON_DIRECTORY_FILE.
    
    We need to check this before the generic pathname parser
    as the generic pathname parser removes any trailing '/' and '\\'.
    
    Currently this is SMB2 only, but we could also add this
    check to the SMB1 NTCreateX calls if ultimately neded.
    
    Signed-off-by: Jeremy Allison <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>
    
    Autobuild-User(master): Ralph Böhme <[email protected]>
    Autobuild-Date(master): Wed Oct  2 09:31:40 UTC 2019 on sn-devel-184

commit 5642f288c895467e32a39430af709cc48198e7c1
Author: Jeremy Allison <[email protected]>
Date:   Thu Sep 26 12:36:18 2019 -0700

    s3: torture: Add MS-FSA style terminating '/' and '\\' test - 
SMB2-PATH-SLASH.
    
    [MS-FSA] 2.1.5.1 Server Requests an Open of a File.
    
    Checks how to behave on both files and directories.
    
    Tested against Windows 10 server - passes. Currently smbd fails this.
    
    Signed-off-by: Jeremy Allison <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 32d6cc84cf8e0cf278b5715b8a9d66b7c0a2a6d2
Author: Volker Lendecke <[email protected]>
Date:   Mon Sep 30 11:39:11 2019 +0200

    dbwrap_watch: Don't alert ourselves, fix raw.oplock.batch26 race
    
    This fixes the following flaky test:
    
    UNEXPECTED(failure): samba3.raw.oplock.batch26(nt4_dc)
    REASON: Exception: Exception: (../../source4/torture/raw/oplock.c:3718): 
wrong value for break_info.count got 0x2 - should be 0x1
    
    You can reproduce it with two small msleeps, which means it's a race
    condition:
    
    diff --git a/source3/smbd/open.c b/source3/smbd/open.c
    index 20b5a3e294c..126c7fc021d 100644
    --- a/source3/smbd/open.c
    +++ b/source3/smbd/open.c
    @@ -1917,6 +1917,14 @@ NTSTATUS send_break_message(struct messaging_context 
*msg_ctx,
        DATA_BLOB blob;
        NTSTATUS status;
    
    +   {
    +           static bool sent = false;
    +           if (sent) {
    +                   smb_msleep(500);
    +           }
    +           sent = true;
    +   }
    +
        if (DEBUGLVL(10)) {
                struct server_id_buf buf;
                DBG_DEBUG("Sending break message to %s\n",
    diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
    index b3da84b1269..d9c4dbb9487 100644
    --- a/source3/smbd/oplock.c
    +++ b/source3/smbd/oplock.c
    @@ -858,6 +858,8 @@ static void process_oplock_break_message(struct 
messaging_context *msg_ctx,
        uint16_t break_to;
        bool break_needed = true;
    
    +   smb_msleep(100);
    +
        msg = talloc(talloc_tos(), struct oplock_break_message);
        if (msg == NULL) {
                DBG_WARNING("talloc failed\n");
    
    15a8af075a2 introduced a bug where we immediately wake up ourselves
    after doing a watch_send, leading to two inter-smbd oplock break
    messages for this case. In theory, this should not matter, as in the
    oplock break handler in the destination smbd we check
    
    (fsp->sent_oplock_break != NO_BREAK_SENT)
    
    so that the break does not get sent twice. However, with the above two
    sleeps the oplock holding client could send out its oplock downgrade
    while the second inter-smbd break messages was on its way.
    
    The real fix would be to note in the share mode array that the
    inter-smbd message has already been sent, but as other users of
    dbwrap_watched_watch_send might also be affected by this bug, this fix
    should be sufficient to get rid of this flaky test.
    
    Unfortunately, dbwrap_watch.c is now pretty complex and needs some
    serious refactoring to become understandable again. But that's
    something for another day, sorry.
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 64da66a75c688b0443b5d5afa4f73ac51b96c504
Author: Volker Lendecke <[email protected]>
Date:   Mon Sep 30 11:32:26 2019 +0200

    dbwrap_watch: Remove "addwatch" handling from dbwrap_watched_save()
    
    This has been moved to dbwrap_watched_watch_send()
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 491b71f29b966d1fed65d5db1463353a19306db8
Author: Volker Lendecke <[email protected]>
Date:   Mon Sep 30 11:25:59 2019 +0200

    dbwrap_watch: Move reallocating watchers to dbwrap_watched_watch_send()
    
    Before 15a8af075a2 we did not have a separately allocated watchers
    array and dbwrap_watched_save() could play (too) smart tricks with
    dbwrap_record_storev(). Now that we always have watchers talloc'ed, we
    can remove those smart tricks from dbwrap_watched_save() in the next
    commit.
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 88f8edf69ba04b4df28d4986199fa13730d3a165
Author: Volker Lendecke <[email protected]>
Date:   Mon Sep 30 07:48:34 2019 +0200

    dbwrap_watch: Slightly simplify dbwrap_watched_fetch_locked()
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 86672659c6a757263c7bf64d152f95d89222a3e7
Author: Volker Lendecke <[email protected]>
Date:   Fri Sep 27 17:20:26 2019 -0700

    epmapper: Fix printf specifiers
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit e3e5894b854b9fe5680f1028f2bcbb2a2cc01069
Author: Volker Lendecke <[email protected]>
Date:   Tue Sep 24 11:53:31 2019 -0700

    torture: Fix a comment
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 9dc2cd86f6993fd681513b1b251f5bbdb01212d4
Author: Volker Lendecke <[email protected]>
Date:   Tue Sep 24 10:51:38 2019 -0700

    lib: Fix a typo
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 5d8493f5b459a7b91f9a5ca9dee00c968fab3d67
Author: Volker Lendecke <[email protected]>
Date:   Tue Sep 24 10:29:07 2019 -0700

    rpc_client: Don't pass a NULL string to talloc_asprintf
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 34a35ac15efee431a7848da51409f7dcdf95b48b
Author: Volker Lendecke <[email protected]>
Date:   Tue Sep 24 09:51:08 2019 -0700

    smbd: Fix CID 1453984: Null pointer dereferences (REVERSE_INULL)
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit b66b8a74b100be85101a7383c634d0d96cf6b0ee
Author: Volker Lendecke <[email protected]>
Date:   Tue Sep 24 09:24:54 2019 -0700

    lib: Fix CID 1453985: Null pointer dereferences (FORWARD_NULL)
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit f21af2ace2261fb6e4d4762bcd70784135b62ddb
Author: Volker Lendecke <[email protected]>
Date:   Tue Sep 24 07:30:15 2019 -0700

    lib: Remove some unneeded #includes from tftw.c
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 993d327f5d24305d96781afeb11855487323975d
Author: Ralph Boehme <[email protected]>
Date:   Thu Sep 26 10:31:51 2019 -0700

    s3:smbd: use is_named_stream() in a a few places
    
    This simplifies (and corrects) things in the VFS as there the caller is only
    interested in whether a name is pointing to a real named stream most of the 
times.
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 4b2e44a6ed7de9b1a25c3bf08de24dd49c7f6c1d
Author: Ralph Boehme <[email protected]>
Date:   Thu Sep 26 12:19:31 2019 -0700

    vfs_default: use is_named_stream() for stream check
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit c190f3efa9eb4f633df28074b481ff884b67e65f
Author: Ralph Boehme <[email protected]>
Date:   Thu Sep 26 10:41:37 2019 -0700

    s3:smbd: add a comment explaining the File-ID semantics when a file is 
created
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 90a14c90c4bcede1ef5414e0800aa4c84cbcf1c9
Author: Ralph Boehme <[email protected]>
Date:   Tue Sep 24 12:49:38 2019 -0700

    s3:smbd: ensure a created stream picks up the File-ID from the basefile
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 091e3fdab61217251de1cf5111f070ff295d1649
Author: Ralph Boehme <[email protected]>
Date:   Thu Sep 26 10:05:40 2019 -0700

    s3:lib: add is_named_stream()
    
    Add a new utility functions that checks whether a struct smb_filename 
points to
    a real named stream, excluding the default stream "::$DATA".
    
      foo           -> false
      foo::$DATA    -> false
      foo:bar       -> true
      foo:bar:$DATA -> true
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 780a8dcba998471bb154e8bae4391786b793e332
Author: Ralph Boehme <[email protected]>
Date:   Wed Sep 25 11:29:04 2019 -0700

    s3:lib: use strequal_m() in is_ntfs_default_stream_smb_fname()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 3f8bc1ce3e094f943363921c46803fd5ec9f73bb
Author: Ralph Boehme <[email protected]>
Date:   Wed Sep 25 11:19:26 2019 -0700

    s3:lib: implement logic directly in is_ntfs_default_stream_smb_fname()
    
    This allows changing the semantics of is_ntfs_stream_smb_fname() in the next
    commit.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 2584b4cdeae3f83962cd11538cd4e441104c8274
Author: Ralph Boehme <[email protected]>
Date:   Thu Sep 26 10:38:06 2019 -0700

    s3:lib: expand a comment with the function doc for is_ntfs_stream_smb_fname
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit f9fdb8a2a6b9ad0fbb89a9734e81a8b1f527966f
Author: Ralph Boehme <[email protected]>
Date:   Wed Sep 25 10:18:03 2019 -0700

    s3:lib: factor out stream name asserts to helper function
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 6c1647ca7a2f68825c34e9ccc18b86ef911e14ac
Author: Ralph Boehme <[email protected]>
Date:   Wed Sep 25 10:15:27 2019 -0700

    s3:lib: assert stream_name is NULL for POSIX paths
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit d7dc85990a177954925644f9ff332b3481a03cc7
Author: Ralph Boehme <[email protected]>
Date:   Wed Sep 25 08:53:29 2019 -0700

    s3:lib: rework a return expression into an if block
    
    Needed to add additional stuff after the if block in the next commit.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 49a754b82d33fb523cda4151a865584ae52a2e2f
Author: Ralph Boehme <[email protected]>
Date:   Mon Sep 23 15:16:58 2019 -0700

    s3:smbd: when storing DOS attribute call dos_mode() beforehand
    
    This is required to ensure File-ID info is populated with the correct 
on-disk
    value, before calling file_set_dosmode() which will update the on-disk 
value.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit e1dfaa2b038d91e43d8d34bf1526b7728dba58a5
Author: Ralph Boehme <[email protected]>
Date:   Mon Sep 23 15:15:31 2019 -0700

    s3:smbd: change the place where we call dos_mode() when processing 
SMB2_CREATE
    
    This is needed for ordinary file or directory opens so the QFID create 
context
    response gets the correct File-ID value via dos_mode() from the DOS 
attributes
    xattr.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 300b47442b023532bd65417fcec04d811f40ef76
Author: Ralph Boehme <[email protected]>
Date:   Tue Sep 24 13:09:03 2019 -0700

    torture:smb2: add a File-ID test on directories
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 432202413f4d11d761c62f46a50747fcb9b6f0cf
Author: Ralph Boehme <[email protected]>
Date:   Mon Sep 23 15:15:01 2019 -0700

    torture:smb2: extend test for File-IDs
    
    This now hopefully covers most possible combinations of creating and opening
    files plus, checking the file's File-ID after every operation.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 lib/util/tfork.h                           |   2 +-
 lib/util/tftw.c                            |  15 +-
 selftest/knownfail                         |   1 +
 source3/include/proto.h                    |   1 +
 source3/lib/dbwrap/dbwrap_watch.c          |  78 ++--
 source3/lib/filename_util.c                |  53 ++-
 source3/lib/tallocmsg.c                    |   1 +
 source3/locking/share_mode_lock.c          |   8 +-
 source3/modules/vfs_default.c              |  12 +-
 source3/modules/vfs_fruit.c                |  17 +-
 source3/modules/vfs_gpfs.c                 |   3 +-
 source3/modules/vfs_streams_depot.c        |  53 +--
 source3/modules/vfs_streams_xattr.c        |  59 +--
 source3/modules/vfs_virusfilter.c          |  11 +-
 source3/rpc_client/cli_pipe.c              |  30 +-
 source3/rpc_server/epmapper/srv_epmapper.c |   4 +-
 source3/selftest/tests.py                  |   1 +
 source3/smbd/dosmode.c                     |   9 +-
 source3/smbd/open.c                        |  12 +-
 source3/smbd/smb2_create.c                 |  50 ++-
 source3/torture/proto.h                    |   1 +
 source3/torture/test_smb2.c                | 205 ++++++++++
 source3/torture/torture.c                  |   4 +
 source4/torture/raw/oplock.c               |   5 +-
 source4/torture/smb2/create.c              | 613 +++++++++++++++++++++++++++--
 25 files changed, 1006 insertions(+), 242 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/util/tfork.h b/lib/util/tfork.h
index 89c9f7295a8..7b2ecd1eb89 100644
--- a/lib/util/tfork.h
+++ b/lib/util/tfork.h
@@ -27,7 +27,7 @@ struct tfork;
  * @brief a fork() that avoids SIGCHLD and waitpid
  *
  * This function is a solution to the problem of fork() requiring special
- * preperations in the caller to handle SIGCHLD signals and to reap the child 
by
+ * preparations in the caller to handle SIGCHLD signals and to reap the child 
by
  * wait()ing for it.
  *
  * The advantage over fork() is that the child process termination is signalled
diff --git a/lib/util/tftw.c b/lib/util/tftw.c
index b731a2ef03a..c59bb6a3b1b 100644
--- a/lib/util/tftw.c
+++ b/lib/util/tftw.c
@@ -18,20 +18,9 @@
  */
 
 #include "replace.h"
-#include <errno.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include "memory.h"
-#include "debug.h"
-#include "replace.h"
-#include "system/locale.h"
-#include "lib/util/asn1.h"
+#include "system/filesys.h"
+#include "system/dir.h"
 #include "lib/util/debug.h"
-#include "lib/util/samba_util.h"
 
 #include "tftw.h"
 
diff --git a/selftest/knownfail b/selftest/knownfail
index 7b54b77a708..82259dcfe90 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -9,6 +9,7 @@
  ^samba3.smbtorture_s3.crypt_server\(nt4_dc\).SMB2-SESSION-REAUTH # expected 
to give ACCESS_DENIED SMB2.1 doesn't have encryption
 ^samba3.smbtorture_s3.crypt_server\(nt4_dc\).SMB2-SESSION-RECONNECT # expected 
to give CONNECTION_DISCONNECTED, we need to fix the test
 ^samba3.smbtorture_s3.plain.*SMB2-DIR-FSYNC.*\(ad_dc_ntvfs\)
+^samba3.smbtorture_s3.plain.*SMB2-PATH-SLASH.*\(ad_dc_ntvfs\)
 ^samba3.smbtorture_s3.plain.LOCK11.*\(ad_dc_ntvfs\)
 ^samba3.smb2.session enc.reconnect # expected to give CONNECTION_DISCONNECTED, 
we need to fix the test
 ^samba3.raw.session enc # expected to give ACCESS_DENIED as SMB1 encryption 
isn't used
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 0d02f38fc8b..91a7c00fef2 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -985,6 +985,7 @@ struct smb_filename *cp_smb_filename_nostream(TALLOC_CTX 
*mem_ctx,
                                     const struct smb_filename *in);
 bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname);
 bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname);
+bool is_named_stream(const struct smb_filename *smb_fname);
 bool is_invalid_windows_ea_name(const char *name);
 bool ea_list_has_invalid_name(struct ea_list *ea_list);
 bool split_stream_filename(TALLOC_CTX *ctx,
diff --git a/source3/lib/dbwrap/dbwrap_watch.c 
b/source3/lib/dbwrap/dbwrap_watch.c
index b1a82d86006..36e445a4fd3 100644
--- a/source3/lib/dbwrap/dbwrap_watch.c
+++ b/source3/lib/dbwrap/dbwrap_watch.c
@@ -196,6 +196,7 @@ struct db_watched_ctx {
 struct db_watched_subrec {
        struct db_record *subrec;
        struct dbwrap_watch_rec wrec;
+       bool added_watcher;
 };
 
 static NTSTATUS dbwrap_watched_subrec_storev(
@@ -211,7 +212,6 @@ static void dbwrap_watched_subrec_wakeup(
        struct db_record *rec, struct db_watched_subrec *subrec);
 static NTSTATUS dbwrap_watched_save(struct db_record *rec,
                                    struct dbwrap_watch_rec *wrec,
-                                   struct server_id *addwatch,
                                    const TDB_DATA *databufs,
                                    size_t num_databufs,
                                    int flags);
@@ -255,6 +255,7 @@ static struct db_record *dbwrap_watched_fetch_locked(
        if (!ok) {
                return rec;     /* fresh record */
        }
+       rec->value = subrec->wrec.data;
 
        /*
         * subrec->wrec.watchers points *directly* into the
@@ -272,10 +273,6 @@ static struct db_record *dbwrap_watched_fetch_locked(
        }
        subrec->wrec.watchers = watchers;
 
-       if (ok) {
-               rec->value = subrec->wrec.data;
-       }
-
        return rec;
 }
 
@@ -389,7 +386,7 @@ static void dbwrap_watched_subrec_wakeup(
        struct db_context *db = rec->db;
        struct db_watched_ctx *ctx = talloc_get_type_abort(
                db->private_data, struct db_watched_ctx);
-       size_t i;
+       size_t i, num_to_wakeup;
        size_t db_id_len = dbwrap_db_id(db, NULL, 0);
        uint8_t db_id[db_id_len];
        uint8_t len_buf[4];
@@ -407,7 +404,17 @@ static void dbwrap_watched_subrec_wakeup(
 
        i = 0;
 
-       while (i < wrec->num_watchers) {
+       num_to_wakeup = wrec->num_watchers;
+
+       if (subrec->added_watcher) {
+               /*
+                * Don't alert our own watcher that we just added to
+                * the end of the array.
+                */
+               num_to_wakeup -= 1;
+       }
+
+       while (i < num_to_wakeup) {
                struct server_id watcher;
                NTSTATUS status;
                struct server_id_buf tmp;
@@ -435,7 +442,6 @@ static void dbwrap_watched_subrec_wakeup(
 
 static NTSTATUS dbwrap_watched_save(struct db_record *rec,
                                    struct dbwrap_watch_rec *wrec,
-                                   struct server_id *addwatch,
                                    const TDB_DATA *databufs,
                                    size_t num_databufs,
                                    int flags)
@@ -449,24 +455,6 @@ static NTSTATUS dbwrap_watched_save(struct db_record *rec,
                .dptr = sizebuf, .dsize = sizeof(sizebuf)
        };
 
-       if (addwatch != NULL) {
-               uint8_t *watchers, *new_watch;
-
-               watchers = talloc_realloc(
-                       NULL,
-                       wrec->watchers,
-                       uint8_t,
-                       (wrec->num_watchers+1) * SERVER_ID_BUF_LENGTH);
-               if (watchers == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               wrec->watchers = watchers;
-
-               new_watch = &watchers[wrec->num_watchers*SERVER_ID_BUF_LENGTH];
-               server_id_put(new_watch, *addwatch);
-               wrec->num_watchers += 1;
-       }
-
        dbufs[1] = (TDB_DATA) {
                .dptr = wrec->watchers,
                .dsize = wrec->num_watchers * SERVER_ID_BUF_LENGTH
@@ -497,8 +485,8 @@ static NTSTATUS dbwrap_watched_subrec_storev(
 
        subrec->wrec.deleted = false;
 
-       status = dbwrap_watched_save(subrec->subrec, &subrec->wrec, NULL,
-                                    dbufs, num_dbufs, flags);
+       status = dbwrap_watched_save(
+               subrec->subrec, &subrec->wrec, dbufs, num_dbufs, flags);
        return status;
 }
 
@@ -528,8 +516,8 @@ static NTSTATUS dbwrap_watched_subrec_delete(
 
        subrec->wrec.deleted = true;
 
-       status = dbwrap_watched_save(subrec->subrec, &subrec->wrec,
-                                    NULL, NULL, 0, 0);
+       status = dbwrap_watched_save(
+               subrec->subrec, &subrec->wrec, NULL, 0, 0);
        return status;
 }
 
@@ -862,6 +850,8 @@ struct tevent_req *dbwrap_watched_watch_send(TALLOC_CTX 
*mem_ctx,
        struct db_watched_ctx *ctx = talloc_get_type_abort(
                db->private_data, struct db_watched_ctx);
        struct db_watched_subrec *subrec = NULL;
+       struct dbwrap_watch_rec *wrec = NULL;
+       uint8_t *watchers = NULL;
        struct tevent_req *req, *subreq;
        struct dbwrap_watched_watch_state *state;
        ssize_t needed;
@@ -923,8 +913,24 @@ struct tevent_req *dbwrap_watched_watch_send(TALLOC_CTX 
*mem_ctx,
        }
        tevent_req_set_callback(subreq, dbwrap_watched_watch_done, req);
 
-       status = dbwrap_watched_save(subrec->subrec, &subrec->wrec, &state->me,
-                                    &subrec->wrec.data, 1, 0);
+       wrec = &subrec->wrec;
+
+       watchers = talloc_realloc(
+               NULL,
+               wrec->watchers,
+               uint8_t,
+               (wrec->num_watchers + 1) * SERVER_ID_BUF_LENGTH);
+       if (tevent_req_nomem(watchers, req)) {
+               return tevent_req_post(req, ev);
+       }
+       server_id_put(&watchers[wrec->num_watchers * SERVER_ID_BUF_LENGTH],
+                     state->me);
+       wrec->watchers = watchers;
+       wrec->num_watchers += 1;
+       subrec->added_watcher = true;
+
+       status = dbwrap_watched_save(
+               subrec->subrec, wrec, &wrec->data, 1, 0);
        if (tevent_req_nterror(req, status)) {
                return tevent_req_post(req, ev);
        }
@@ -990,6 +996,7 @@ static int dbwrap_watched_watch_state_destructor(
 {
        struct db_record *rec;
        struct db_watched_subrec *subrec;
+       struct dbwrap_watch_rec *wrec = NULL;
        TDB_DATA key;
        bool ok;
 
@@ -1007,12 +1014,13 @@ static int dbwrap_watched_watch_state_destructor(
 
        subrec = talloc_get_type_abort(
                rec->private_data, struct db_watched_subrec);
+       wrec = &subrec->wrec;
 
-       ok = dbwrap_watched_remove_waiter(&subrec->wrec, state->me);
+       ok = dbwrap_watched_remove_waiter(wrec, state->me);
        if (ok) {
                NTSTATUS status;
-               status = dbwrap_watched_save(subrec->subrec, &subrec->wrec,
-                                            NULL, &subrec->wrec.data, 1, 0);
+               status = dbwrap_watched_save(
+                       subrec->subrec, wrec, &wrec->data, 1, 0);
                if (!NT_STATUS_IS_OK(status)) {
                        DBG_WARNING("dbwrap_watched_save failed: %s\n",
                                    nt_errstr(status));
diff --git a/source3/lib/filename_util.c b/source3/lib/filename_util.c
index 8a16bacddbe..66c07001eba 100644
--- a/source3/lib/filename_util.c
+++ b/source3/lib/filename_util.c
@@ -239,10 +239,7 @@ struct smb_filename *cp_smb_filename(TALLOC_CTX *mem_ctx,
        return out;
 }
 
-/****************************************************************************
- Simple check to determine if the filename is a stream.
- ***************************************************************************/
-bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname)
+static void assert_valid_stream_smb_fname(const struct smb_filename *smb_fname)
 {
        /* stream_name must always be NULL if there is no stream. */
        if (smb_fname->stream_name) {
@@ -250,10 +247,50 @@ bool is_ntfs_stream_smb_fname(const struct smb_filename 
*smb_fname)
        }
 
        if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
+               SMB_ASSERT(smb_fname->stream_name == NULL);
+       }
+}
+
+/****************************************************************************
+ Simple check to determine if a smb_fname is a real named stream or the
+ default stream.
+ ***************************************************************************/
+
+bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname)
+{
+       assert_valid_stream_smb_fname(smb_fname);
+
+       if (smb_fname->stream_name == NULL) {
+               return false;
+       }
+
+       return true;
+}
+
+/****************************************************************************
+ Simple check to determine if a smb_fname is pointing to a normal file or
+ a named stream that is not the default stream "::$DATA".
+
+  foo           -> false
+  foo::$DATA    -> false
+  foo:bar       -> true
+  foo:bar:$DATA -> true
+
+ ***************************************************************************/
+
+bool is_named_stream(const struct smb_filename *smb_fname)
+{
+       assert_valid_stream_smb_fname(smb_fname);
+
+       if (smb_fname->stream_name == NULL) {
                return false;
        }
 
-       return smb_fname->stream_name != NULL;
+       if (strequal_m(smb_fname->stream_name, "::$DATA")) {
+               return false;
+       }
+
+       return true;
 }
 
 /****************************************************************************
@@ -261,11 +298,13 @@ bool is_ntfs_stream_smb_fname(const struct smb_filename 
*smb_fname)
  ***************************************************************************/
 bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname)
 {
-       if (!is_ntfs_stream_smb_fname(smb_fname)) {
+       assert_valid_stream_smb_fname(smb_fname);
+
+       if (smb_fname->stream_name == NULL) {
                return false;
        }
 
-       return strcasecmp_m(smb_fname->stream_name, "::$DATA") == 0;
+       return strequal_m(smb_fname->stream_name, "::$DATA");
 }
 
 /****************************************************************************
diff --git a/source3/lib/tallocmsg.c b/source3/lib/tallocmsg.c
index 42cbe2d9c02..1e243e77781 100644
--- a/source3/lib/tallocmsg.c
+++ b/source3/lib/tallocmsg.c
@@ -61,6 +61,7 @@ static void msg_pool_usage_do(struct tevent_req *req)
                close(rec->fds[0]);
                TALLOC_FREE(rec);
                DBG_DEBUG("fdopen failed: %s\n", strerror(errno));
+               return;
        }
 
        TALLOC_FREE(rec);
diff --git a/source3/locking/share_mode_lock.c 
b/source3/locking/share_mode_lock.c
index abd911f4be2..aeb9fd4b18b 100644
--- a/source3/locking/share_mode_lock.c
+++ b/source3/locking/share_mode_lock.c
@@ -2031,9 +2031,7 @@ static void mark_share_mode_disconnected_fn(
 bool mark_share_mode_disconnected(struct share_mode_lock *lck,
                                  struct files_struct *fsp)
 {
-       struct mark_share_mode_disconnected_state state = {
-               .open_persistent_id = fsp->op->global->open_persistent_id,
-       };
+       struct mark_share_mode_disconnected_state state;
        bool ok;
 
        if (lck->data->num_share_modes != 1) {
@@ -2047,6 +2045,10 @@ bool mark_share_mode_disconnected(struct share_mode_lock 
*lck,
                return false;
        }
 
+       state = (struct mark_share_mode_disconnected_state) {
+               .open_persistent_id = fsp->op->global->open_persistent_id,
+       };
+
        ok = share_mode_entry_do(
                lck,
                messaging_server_id(fsp->conn->sconn->msg_ctx),
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 781c5e06fad..738be3bf2d6 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -551,7 +551,7 @@ static int vfswrap_open(vfs_handle_struct *handle,
 
        START_PROFILE(syscall_open);
 
-       if (smb_fname->stream_name) {
+       if (is_named_stream(smb_fname)) {
                errno = ENOENT;
                goto out;
        }
@@ -1080,7 +1080,7 @@ static int vfswrap_renameat(vfs_handle_struct *handle,
 
        START_PROFILE(syscall_renameat);
 
-       if (smb_fname_src->stream_name || smb_fname_dst->stream_name) {
+       if (is_named_stream(smb_fname_src) || is_named_stream(smb_fname_dst)) {
                errno = ENOENT;
                goto out;
        }
@@ -1102,7 +1102,7 @@ static int vfswrap_stat(vfs_handle_struct *handle,
 
        START_PROFILE(syscall_stat);
 
-       if (smb_fname->stream_name) {
+       if (is_named_stream(smb_fname)) {
                errno = ENOENT;
                goto out;
        }
@@ -1132,7 +1132,7 @@ static int vfswrap_lstat(vfs_handle_struct *handle,
 
        START_PROFILE(syscall_lstat);
 
-       if (smb_fname->stream_name) {
+       if (is_named_stream(smb_fname)) {
                errno = ENOENT;
                goto out;
        }
@@ -2215,7 +2215,7 @@ static int vfswrap_unlinkat(vfs_handle_struct *handle,
 
        SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp);
 
-       if (smb_fname->stream_name) {
+       if (is_named_stream(smb_fname)) {
                errno = ENOENT;
                goto out;
        }
@@ -2348,7 +2348,7 @@ static int vfswrap_ntimes(vfs_handle_struct *handle,
 
        START_PROFILE(syscall_ntimes);
 
-       if (smb_fname->stream_name) {
+       if (is_named_stream(smb_fname)) {
                errno = ENOENT;
                goto out;
        }
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index 5f789604b23..a863f47fe1e 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -1613,7 +1613,7 @@ static int fruit_open(vfs_handle_struct *handle,
 
        DBG_DEBUG("Path [%s]\n", smb_fname_str_dbg(smb_fname));
 
-       if (!is_ntfs_stream_smb_fname(smb_fname)) {
+       if (!is_named_stream(smb_fname)) {
                return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
        }
 
@@ -1696,7 +1696,7 @@ static int fruit_close(vfs_handle_struct *handle,
 
        DBG_DEBUG("Path [%s] fd [%d]\n", smb_fname_str_dbg(fsp->fsp_name), fd);
 
-       if (!is_ntfs_stream_smb_fname(fsp->fsp_name)) {
+       if (!is_named_stream(fsp->fsp_name)) {
                return SMB_VFS_NEXT_CLOSE(handle, fsp);
        }
 
@@ -1993,7 +1993,7 @@ static int fruit_unlink_internal(vfs_handle_struct 
*handle,
                                dirfsp,
                                smb_fname,
                                false);
-       } else if (is_ntfs_stream_smb_fname(smb_fname)) {
+       } else if (is_named_stream(smb_fname)) {
                return SMB_VFS_NEXT_UNLINKAT(handle,
                                dirfsp,
                                smb_fname,
@@ -3202,8 +3202,7 @@ static int fruit_stat(vfs_handle_struct *handle,
        DEBUG(10, ("fruit_stat called for %s\n",
                   smb_fname_str_dbg(smb_fname)));
 
-       if (!is_ntfs_stream_smb_fname(smb_fname)
-           || is_ntfs_default_stream_smb_fname(smb_fname)) {
+       if (!is_named_stream(smb_fname)) {
                rc = SMB_VFS_NEXT_STAT(handle, smb_fname);
                if (rc == 0) {
                        update_btime(handle, smb_fname);
@@ -3244,8 +3243,7 @@ static int fruit_lstat(vfs_handle_struct *handle,
        DEBUG(10, ("fruit_lstat called for %s\n",
                   smb_fname_str_dbg(smb_fname)));
 
-       if (!is_ntfs_stream_smb_fname(smb_fname)
-           || is_ntfs_default_stream_smb_fname(smb_fname)) {
+       if (!is_named_stream(smb_fname)) {
                rc = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
                if (rc == 0) {
                        update_btime(handle, smb_fname);
@@ -4117,8 +4115,7 @@ static NTSTATUS fruit_create_file(vfs_handle_struct 
*handle,
        if (global_fruit_config.nego_aapl &&
            create_disposition == FILE_OPEN &&
            smb_fname->st.st_ex_size == 0 &&
-           is_ntfs_stream_smb_fname(smb_fname) &&
-           !(is_ntfs_default_stream_smb_fname(smb_fname)))
+           is_named_stream(smb_fname))
        {
                status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
                goto fail;
@@ -4129,7 +4126,7 @@ static NTSTATUS fruit_create_file(vfs_handle_struct 
*handle,
                fio->created = true;
        }
 
-       if (is_ntfs_stream_smb_fname(smb_fname)
+       if (is_named_stream(smb_fname)
            || fsp->is_directory) {
                return status;
        }
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index d8e9a3231bf..b17a0fdd6c6 100644
--- a/source3/modules/vfs_gpfs.c


-- 
Samba Shared Repository

Reply via email to