The branch, v4-21-test has been updated
       via  7202467477d pam_winbind: Fix Bug 15771
       via  884500cb316 s4:drs:test:getncchanges skips some tests with 
reserved_usn = 0
       via  5842ec1d056 s4:drs:test:getncchanges: remove timeout failure
       via  28626e763ee s4:drsuapi:getncchanges: allow 0 reserved_usn reply
       via  6c66d01c6df s4:drsuapi:getncchanges: use DBG_ERR() macro
       via  9954fd8994f s4:drsuapi:getncchanges: fix whitespace
       via  b43b7a9ac1b s4:drs:tests: repeat getncchanges test with zero 
reserved_usn
       via  ec6263a3f0e s4:drs:tests: add hook for changing highwatermark
       via  9b7f1ce151b s4:drs:test:getncchanges: add a timeout failure
       via  ba4363a7277 selftest: Add test for vfs crossrename module
       via  bab50c88c7d docs:manpage: vfs_crossrename is not fully stackable 
VFS module
       via  6b37df9e58e s3:vfs_crossrename: add back checking for errno ENOENT
       via  bca095a71a3 s3:vfs_crossrename: crossrename_renameat() needs to 
return 0 if copy_reg() is successful
       via  7219acad073 s3:vfs_crossrename: avoid locking panic in copy_reg()
      from  aee855de33b s4:rpc_server: make use of 
dcesrv_assoc_group_common_destructor()

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-21-test


- Log -----------------------------------------------------------------
commit 7202467477de13e9c960677de6792ec42f92ac0c
Author: Volker Lendecke <[email protected]>
Date:   Mon Dec 16 17:49:43 2024 +0100

    pam_winbind: Fix Bug 15771
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=15771
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    (cherry picked from commit 7e8bfe738a3d91b0724d57ed54acf40ebe026c14)
    
    Autobuild-User(v4-21-test): Jule Anger <[email protected]>
    Autobuild-Date(v4-21-test): Thu Dec 19 10:13:37 UTC 2024 on atb-devel-224

commit 884500cb316c80c9a530756e6aa73ff77b8973a3
Author: Douglas Bagnall <[email protected]>
Date:   Fri Aug 9 11:48:06 2024 +1200

    s4:drs:test:getncchanges skips some tests with reserved_usn = 0
    
    These tests are not affected by the reserved_usn change, so there is
    no need to run them twice.
    
    The test_repl_get_tgt_multivalued_links fails with or without
    reserved_usn set to zero, but it fails differently in either case.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15701
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>
    (cherry picked from commit 7dac035896b368bf3a86acf58260eef39d195d19)

commit 5842ec1d0565f62b28c66534606823731c73d33e
Author: Douglas Bagnall <[email protected]>
Date:   Fri Aug 9 11:29:11 2024 +1200

    s4:drs:test:getncchanges: remove timeout failure
    
    We don't need a timeout failure any more, since replication should
    always work. Leaving the timeout in might sometimes cause a flapping
    test if replication is being slow for some reason.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15701
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>
    (cherry picked from commit 44a478038b6ec78aaec832d9dbde7fa6b2cdd639)

commit 28626e763eef4642d02024d0d28b2235a2cba826
Author: Douglas Bagnall <[email protected]>
Date:   Wed Aug 7 17:25:30 2024 +1200

    s4:drsuapi:getncchanges: allow 0 reserved_usn reply
    
    Azure AD will set reserved_usn to zero when we expect it to be
    the number we gave them.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15701
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>
    (cherry picked from commit 7a623d8d5626b4e6c88ffb85e36f0934d89ed830)

commit 6c66d01c6df1010a85ea96e5d7a41cc4965b581b
Author: Douglas Bagnall <[email protected]>
Date:   Thu Jun 13 17:23:23 2024 +1200

    s4:drsuapi:getncchanges: use DBG_ERR() macro
    
    The next commit will indent this more, so it's a bit squished up.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15701
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>
    (cherry picked from commit 5ef27019033fd73decd111f9426e7f8982cbb806)

commit 9954fd8994ff72c4c3f0dd7bb8b8aab93c1e23e7
Author: Douglas Bagnall <[email protected]>
Date:   Wed Aug 7 17:05:48 2024 +1200

    s4:drsuapi:getncchanges: fix whitespace
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15701
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>
    (cherry picked from commit 2e1ccb35239fc6fe129c943bb7305bd4612d72d7)

commit b43b7a9ac1bc2a75064c0261b81fc18275bfd482
Author: Douglas Bagnall <[email protected]>
Date:   Wed Aug 14 13:26:37 2024 +1200

    s4:drs:tests: repeat getncchanges test with zero reserved_usn
    
    This emulates the behaviour of Azure AD.
    
    As this is quite slow we will later reduce the test load in this case,
    but for now we want to run all the getncchanges tests this way.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15701
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>
    (cherry picked from commit 67c7609ab755291de27c620120a1c71b557452e4)

commit ec6263a3f0e5cd1c50f460aea9a85562d6e9e500
Author: Douglas Bagnall <[email protected]>
Date:   Fri Aug 9 10:16:29 2024 +1200

    s4:drs:tests: add hook for changing highwatermark
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15701
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>
    (cherry picked from commit 796e92a530004406dcb3fea33f54833c722480a0)

commit 9b7f1ce151ba24804f337d24de71965c6b8eccc7
Author: Douglas Bagnall <[email protected]>
Date:   Fri Aug 9 11:20:38 2024 +1200

    s4:drs:test:getncchanges: add a timeout failure
    
    In the next commit we are going to add tests in which the client
    modifies the highwatermark in a way that resets replication (on Samba
    only). After that we'll fix it.
    
    If we leave the test in an eternal loop, the commit history will not
    be bisectable, so we are temporarily going to turn long waits into
    failures.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15701
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>
    (cherry picked from commit 4b4a7c3fd465267c43d9586ab79ca8f84c0cad24)

commit ba4363a7277ef98fca1e8a47da5c53cadbac6127
Author: Pavel Filipenský <[email protected]>
Date:   Wed Dec 4 11:02:18 2024 +0100

    selftest: Add test for vfs crossrename module
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15724
    
    Signed-off-by: Pavel Filipenský <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>
    (cherry picked from commit 02d4f58a2f7ac2db60dd2e4d16a3cbf71b3f08a9)

commit bab50c88c7dbc79d6c62ffd14822432fd6c48ed2
Author: Pavel Filipenský <[email protected]>
Date:   Mon Dec 2 22:27:39 2024 +0100

    docs:manpage: vfs_crossrename is not fully stackable VFS module
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15724
    
    Signed-off-by: Pavel Filipenský <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>
    (cherry picked from commit 94c9a99c56db438c391a966c927ec2f862c373e7)

commit 6b37df9e58ee771a5a1409ae20e8b8c0ae3683a9
Author: Jones Syue <[email protected]>
Date:   Thu Sep 26 17:17:14 2024 +0800

    s3:vfs_crossrename: add back checking for errno ENOENT
    
    strace gives a clue: samba try to remove 'file.txt' in the dst folder but
    actually it is not existed yet, and got an errno = ENOENT,
    
    renameat(32, "file.txt", 31, "file.txt") = -1 EXDEV (Invalid cross-device 
link)
    unlinkat(31, "file.txt", 0)             = -1 ENOENT (No such file or 
directory)
    
    Commit 5c18f074be92 ("s3: VFS: crossrename. Use real dirfsp for
    SMB_VFS_RENAMEAT()") seems unintentionally removed errno ENOENT checking,
    so add it back could address 1st issue.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15724
    
    Signed-off-by: Jones Syue <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>
    (cherry picked from commit 1a089a16c40e0b3bc5d4fcde559157cf137056c2)

commit bca095a71a371f721a74bb6fbea04622efe5321a
Author: Pavel Filipenský <[email protected]>
Date:   Thu Nov 28 18:32:25 2024 +0100

    s3:vfs_crossrename: crossrename_renameat() needs to return 0 if copy_reg() 
is successful
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15724
    
    Signed-off-by: Pavel Filipenský <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>
    (cherry picked from commit 0a9adc85e77bc557bb8be12237fa31c4142dd3d5)

commit 7219acad07398c470d7a6a0dddcb94da10df383e
Author: Pavel Filipenský <[email protected]>
Date:   Thu Nov 28 18:39:53 2024 +0100

    s3:vfs_crossrename: avoid locking panic in copy_reg()
    
    Use low level backend functions that don't go through the FSA layer.
    Done via calling transfer_file() as it was in version before 5c18f07
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15724
    
    Signed-off-by: Pavel Filipenský <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>
    (cherry picked from commit 0a5da82f75a43838be3419cab10a50750fa500d7)

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

Summary of changes:
 docs-xml/manpages/vfs_crossrename.8.xml    |   5 +-
 nsswitch/pam_winbind.c                     |   1 +
 selftest/knownfail.d/getncchanges          |   3 +
 selftest/target/Samba3.pm                  |  12 +++
 source3/modules/vfs_crossrename.c          | 126 +++++++++++++++++++----------
 source3/script/tests/test_recycle.sh       |  80 +++++++++++++++++-
 source3/selftest/tests.py                  |   2 +-
 source4/rpc_server/drsuapi/getncchanges.c  |  83 +++++++++++++++----
 source4/torture/drs/python/drs_base.py     |   7 ++
 source4/torture/drs/python/getncchanges.py |  49 +++++++++++
 10 files changed, 309 insertions(+), 59 deletions(-)


Changeset truncated at 500 lines:

diff --git a/docs-xml/manpages/vfs_crossrename.8.xml 
b/docs-xml/manpages/vfs_crossrename.8.xml
index 72d67d685b1..7ea0b50cc9b 100644
--- a/docs-xml/manpages/vfs_crossrename.8.xml
+++ b/docs-xml/manpages/vfs_crossrename.8.xml
@@ -62,7 +62,10 @@
                </varlistentry>
        </variablelist>
 
-       <para>This module is stackable.</para>
+       <para> This module is not fully stackable. It can be combined with other
+       modules, but should be the last module in the <command>vfs 
objects</command>
+       list. It directly access the files in the OS filesystem.
+       </para>
 
 </refsect1>
 
diff --git a/nsswitch/pam_winbind.c b/nsswitch/pam_winbind.c
index 968a72bccc0..652ceddc85e 100644
--- a/nsswitch/pam_winbind.c
+++ b/nsswitch/pam_winbind.c
@@ -2527,6 +2527,7 @@ static char* winbind_upn_to_username(struct pwb_context 
*ctx,
        /* Convert the UPN to a SID */
 
        wbc_status = wbcCtxLookupName(ctx->wbc_ctx, domain, name, &sid, &type);
+       TALLOC_FREE(name);
        if (!WBC_ERROR_IS_OK(wbc_status)) {
                return NULL;
        }
diff --git a/selftest/knownfail.d/getncchanges 
b/selftest/knownfail.d/getncchanges
index bda9b31a1b1..7288309c32a 100644
--- a/selftest/knownfail.d/getncchanges
+++ b/selftest/knownfail.d/getncchanges
@@ -6,3 +6,6 @@ 
samba4.drs.getncchanges.python\(promoted_dc\).getncchanges.DrsReplicaSyncIntegri
 
samba4.drs.getncchanges.python\(promoted_dc\).getncchanges.DrsReplicaSyncIntegrityTestCase.test_repl_get_tgt_multivalued_links\(promoted_dc\)
 # Samba chooses to always increment the USN for the NC root at the point where 
it would otherwise show up.
 
samba4.drs.getncchanges.python\(.*\).getncchanges.DrsReplicaSyncIntegrityTestCase.test_repl_nc_is_first_nc_change_only\(
+
+# test_repl_get_tgt_multivalued_links also fails with 
DrsReplicaSyncFakeAzureAdTests on promoted_dc
+samba4.drs.getncchanges.python\(promoted_dc\).getncchanges.DrsReplicaSyncFakeAzureAdTests.test_repl_get_tgt_multivalued_links\(promoted_dc\)
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index a7dd1b20e66..17343e63e52 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -2780,6 +2780,9 @@ sub provision($$)
        my $recycle_shrdir="$shrdir/recycle";
        push(@dirs,$recycle_shrdir);
 
+       my $recycle_shrdir2="$shrdir/recycle2";
+       push(@dirs,$recycle_shrdir2);
+
        my $fakedircreatetimes_shrdir="$shrdir/fakedircreatetimes";
        push(@dirs,$fakedircreatetimes_shrdir);
 
@@ -3715,6 +3718,15 @@ sub provision($$)
        recycle : exclude = *.tmp
        recycle : directory_mode = 755
 
+[recycle2]
+       copy = tmp
+       path = $recycle_shrdir2
+       vfs objects = recycle crossrename
+       recycle : repository = .trash
+       recycle : exclude = *.tmp
+       recycle : directory_mode = 755
+       wide links = yes
+
 [fakedircreatetimes]
        copy = tmp
        path = $fakedircreatetimes_shrdir
diff --git a/source3/modules/vfs_crossrename.c 
b/source3/modules/vfs_crossrename.c
index 042144bfc4d..1da36706ecb 100644
--- a/source3/modules/vfs_crossrename.c
+++ b/source3/modules/vfs_crossrename.c
@@ -54,10 +54,12 @@ static NTSTATUS copy_reg(vfs_handle_struct *handle,
                         struct files_struct *dstfsp,
                         const struct smb_filename *dest)
 {
-       NTSTATUS status;
-       struct smb_filename *full_fname_src = NULL;
-       struct smb_filename *full_fname_dst = NULL;
+       NTSTATUS status = NT_STATUS_OK;
        int ret;
+       off_t off;
+       int ifd = -1;
+       int ofd = -1;
+       struct timespec ts[2];
 
        if (!VALID_STAT(source->st)) {
                status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
@@ -79,64 +81,105 @@ static NTSTATUS copy_reg(vfs_handle_struct *handle,
                goto out;
        }
 
-       full_fname_src = full_path_from_dirfsp_atname(talloc_tos(),
-                                                     srcfsp,
-                                                     source);
-       if (full_fname_src == NULL) {
-               status = NT_STATUS_NO_MEMORY;
+       ret = SMB_VFS_NEXT_UNLINKAT(handle,
+                                   dstfsp,
+                                   dest,
+                                   0);
+       if (ret == -1 && errno != ENOENT) {
+               status = map_nt_error_from_unix(errno);
                goto out;
        }
-       full_fname_dst = full_path_from_dirfsp_atname(talloc_tos(),
-                                                     dstfsp,
-                                                     dest);
-       if (full_fname_dst == NULL) {
-               status = NT_STATUS_NO_MEMORY;
+
+       ifd = openat(fsp_get_pathref_fd(srcfsp),
+                    source->base_name,
+                    O_RDONLY,
+                    0);
+       if (ifd < 0) {
+               status = map_nt_error_from_unix(errno);
                goto out;
        }
 
-       ret = SMB_VFS_NEXT_UNLINKAT(handle,
-                                   dstfsp,
-                                   dest,
-                                   0);
-       if (ret == -1) {
+       ofd = openat(fsp_get_pathref_fd(dstfsp),
+                    dest->base_name,
+                    O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW,
+                    0600);
+       if (ofd < 0) {
+               status = map_nt_error_from_unix(errno);
+               goto out;
+       }
+
+       off = transfer_file(ifd, ofd, source->st.st_ex_size);
+       if (off == -1) {
+               status = map_nt_error_from_unix(errno);
+               goto out;
+       }
+
+       ret = fchown(ofd, source->st.st_ex_uid, source->st.st_ex_gid);
+       if (ret == -1 && errno != EPERM) {
                status = map_nt_error_from_unix(errno);
                goto out;
        }
 
        /*
-        * copy_internals() takes attribute values from the NTrename call.
-        *
-        * From MS-CIFS:
-        *
-        * "If the attribute is 0x0000, then only normal files are renamed.
-        * If the system file or hidden attributes are specified, then the
-        * rename is inclusive of both special types."
+        * fchown turns off set[ug]id bits for non-root,
+        * so do the chmod last.
         */
-       status = copy_internals(talloc_tos(),
-                               handle->conn,
-                               NULL,
-                               srcfsp, /* src_dirfsp */
-                               full_fname_src,
-                               dstfsp, /* dst_dirfsp */
-                               full_fname_dst,
-                               FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
-       if (!NT_STATUS_IS_OK(status)) {
+       ret = fchmod(ofd, source->st.st_ex_mode & 07777);
+       if (ret == -1 && errno != EPERM) {
+               status = map_nt_error_from_unix(errno);
                goto out;
        }
 
-       ret = SMB_VFS_NEXT_UNLINKAT(handle,
-                                   srcfsp,
-                                   source,
-                                   0);
+       /* Try to copy the old file's modtime and access time.  */
+       ts[0] = source->st.st_ex_atime;
+       ts[1] = source->st.st_ex_mtime;
+       ret = futimens(ofd, ts);
+       if (ret == -1) {
+               DBG_DEBUG("Updating the time stamp on destinaton '%s' failed "
+                         "with '%s'. Rename operation can continue.\n",
+                         dest->base_name,
+                         strerror(errno));
+       }
+
+       ret = close(ifd);
        if (ret == -1) {
                status = map_nt_error_from_unix(errno);
                goto out;
        }
+       ifd = -1;
 
-  out:
+       ret = close(ofd);
+       if (ret == -1) {
+               status = map_nt_error_from_unix(errno);
+               goto out;
+       }
+       ofd = -1;
+
+       ret = SMB_VFS_NEXT_UNLINKAT(handle, srcfsp, source, 0);
+       if (ret == -1) {
+               status = map_nt_error_from_unix(errno);
+       }
+
+out:
+       if (ifd != -1) {
+               ret = close(ifd);
+               if (ret == -1) {
+                       DBG_DEBUG("Failed to close %s (%d): %s.\n",
+                                 source->base_name,
+                                 ifd,
+                                 strerror(errno));
+               }
+       }
+       if (ofd != -1) {
+               ret = close(ofd);
+               if (ret == -1) {
+                       DBG_DEBUG("Failed to close %s (%d): %s.\n",
+                                 dest->base_name,
+                                 ofd,
+                                 strerror(errno));
+               }
+       }
 
-       TALLOC_FREE(full_fname_src);
-       TALLOC_FREE(full_fname_dst);
        return status;
 }
 
@@ -168,6 +211,7 @@ static int crossrename_renameat(vfs_handle_struct *handle,
                                           smb_fname_src,
                                           dstfsp,
                                           smb_fname_dst);
+               result = 0;
                if (!NT_STATUS_IS_OK(status)) {
                        errno = map_errno_from_nt_status(status);
                        result = -1;
diff --git a/source3/script/tests/test_recycle.sh 
b/source3/script/tests/test_recycle.sh
index ba1d0a598b1..779683f4822 100755
--- a/source3/script/tests/test_recycle.sh
+++ b/source3/script/tests/test_recycle.sh
@@ -29,7 +29,8 @@ export SAMBA_DEPRECATED_SUPPRESS
 
 # Define the test environment/filenames.
 #
-share_test_dir="$LOCAL_PATH"
+share_test_dir="$LOCAL_PATH/recycle"
+share_test_dir2="$LOCAL_PATH/recycle2"
 
 #
 # Cleanup function.
@@ -43,6 +44,13 @@ do_cleanup()
                rm -f testfile2.tmp
                rm -rf .trash
        )
+       (
+               #subshell.
+               cd "$share_test_dir2" || return
+               rm -f testfile3
+               rm -f testfile4.tmp
+               rm -rf .trash
+       )
 }
 
 #
@@ -50,6 +58,25 @@ do_cleanup()
 #
 do_cleanup
 
+# Setup .trash on a different filesystem to test crossrename
+# /tmp or /dev/shm should provide tmpfs
+#
+for T in /tmp /dev/shm
+do
+       if df --portability --print-type $T 2>/dev/null | grep -q tmpfs; then
+               TRASHDIR=$T
+               break
+       fi
+done
+
+if [ -z $TRASHDIR ]; then
+       echo "No tmpfs filesystem found."
+       exit 1
+fi
+
+TRASHDIR=$(mktemp -d /$TRASHDIR/.trash_XXXXXX)
+chmod 0755 $TRASHDIR
+ln -s $TRASHDIR $share_test_dir2/.trash
 
 test_recycle()
 {
@@ -90,12 +117,61 @@ quit
        return 0
 }
 
+test_recycle_crossrename()
+{
+       tmpfile=$PREFIX/smbclient_interactive_prompt_commands
+       echo "
+put $tmpfile testfile3
+put $tmpfile testfile4.tmp
+del testfile3
+del testfile4.tmp
+quit
+" > $tmpfile
+       cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT -U$USERNAME%$PASSWORD 
//$SERVER/recycle2 -I$SERVER_IP $ADDARGS < $tmpfile 2>&1'
+       eval echo "$cmd"
+       out=$(eval "$cmd")
+       ret=$?
+       rm -f "$tmpfile"
+
+       if [ $ret != 0 ]; then
+               printf "%s\n" "$out"
+               printf "failed recycle smbclient run with error %s\n" "$ret"
+               return 1
+       fi
+
+       test -e "$share_test_dir2/.trash/testfile3" || {
+               printf ".trash/testfile3 expected to exist but does NOT exist\n"
+               return 1
+       }
+       test -e "$share_test_dir2/.trash/testfile4.tmp" && {
+               printf ".trash/testfile4.tmp not expected to exist but DOES 
exist\n"
+               return 1
+       }
+       deviceid1=`stat -c '%d' "$share_test_dir2/"`
+       deviceid2=`stat -c '%d' "$share_test_dir2/.trash/"`
+       test "$deviceid1=" != "$deviceid2" || {
+               printf ".trash/ should be on a different filesystem!\n"
+               return 1
+       }
+       perm_want=755
+       perm_is=`stat -c '%a' "$share_test_dir2/.trash/"`
+       test "$perm_is" = "$perm_want" || {
+               printf ".trash/ permission should be $perm_want but is 
$perm_is\n"
+               return 1
+       }
+       return 0
+}
+
 panic_count_0=$(grep -c PANIC $SMBD_TEST_LOG)
 
 testit "recycle" \
        test_recycle ||
        failed=$((failed + 1))
 
+testit "recycle_crossrename" \
+       test_recycle_crossrename ||
+       failed=$((failed + 1))
+
 panic_count_1=$(grep -c PANIC $SMBD_TEST_LOG)
 
 testit "check_panic" test $panic_count_0 -eq $panic_count_1 || failed=$(expr 
$failed + 1)
@@ -103,5 +179,7 @@ testit "check_panic" test $panic_count_0 -eq $panic_count_1 
|| failed=$(expr $fa
 #
 # Cleanup.
 do_cleanup
+# Cleanup above only deletes a symlink, delete also /tmp/.trash_XXXXXX dir
+rm -rf "$TRASHDIR"
 
 testok "$0" "$failed"
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 88151caea11..fe67a4df896 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -784,7 +784,7 @@ for env in ["fileserver"]:
     plantestsuite("samba3.blackbox.force_create_mode", env, 
[os.path.join(samba3srcdir, "script/tests/test_force_create_mode.sh"), 
'$SERVER', '$DOMAIN', '$USERNAME', '$PASSWORD', '$PREFIX', env, smbclient3])
     plantestsuite("samba3.blackbox.dropbox", env, [os.path.join(samba3srcdir, 
"script/tests/test_dropbox.sh"), '$SERVER', '$DOMAIN', 'gooduser', '$PASSWORD', 
'$PREFIX', env, smbclient3])
     plantestsuite("samba3.blackbox.offline", env, [os.path.join(samba3srcdir, 
"script/tests/test_offline.sh"), '$SERVER', '$SERVER_IP', '$DOMAIN', 
'$USERNAME', '$PASSWORD', '$LOCAL_PATH/offline', smbclient3])
-    plantestsuite("samba3.blackbox.recycle", env, [os.path.join(samba3srcdir, 
"script/tests/test_recycle.sh"), '$SERVER', '$SERVER_IP', '$USERNAME', 
'$PASSWORD', '$LOCAL_PATH/recycle', '$PREFIX', smbclient3])
+    plantestsuite("samba3.blackbox.recycle", env, [os.path.join(samba3srcdir, 
"script/tests/test_recycle.sh"), '$SERVER', '$SERVER_IP', '$USERNAME', 
'$PASSWORD', '$LOCAL_PATH', '$PREFIX', smbclient3])
     plantestsuite("samba3.blackbox.fakedircreatetimes", env, 
[os.path.join(samba3srcdir, "script/tests/test_fakedircreatetimes.sh"), 
'$SERVER', '$SERVER_IP', '$USERNAME', '$PASSWORD', 
'$LOCAL_PATH/fakedircreatetimes', '$PREFIX', smbclient3])
     plantestsuite("samba3.blackbox.shadow_copy2.NT1", env + "_smb1_done", 
[os.path.join(samba3srcdir, "script/tests/test_shadow_copy.sh"), '$SERVER', 
'$SERVER_IP', '$DOMAIN', '$USERNAME', '$PASSWORD', '$LOCAL_PATH/shadow', 
smbclient3, '-m', 'NT1'])
     plantestsuite("samba3.blackbox.shadow_copy2.SMB3", env, 
[os.path.join(samba3srcdir, "script/tests/test_shadow_copy.sh"), '$SERVER', 
'$SERVER_IP', '$DOMAIN', '$USERNAME', '$PASSWORD', '$LOCAL_PATH/shadow', 
smbclient3, '-m', 'SMB3'])
diff --git a/source4/rpc_server/drsuapi/getncchanges.c 
b/source4/rpc_server/drsuapi/getncchanges.c
index 0ae6aa510cf..a73efe93eb9 100644
--- a/source4/rpc_server/drsuapi/getncchanges.c
+++ b/source4/rpc_server/drsuapi/getncchanges.c
@@ -1,4 +1,4 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
 
    implement the DSGetNCChanges call
@@ -11,12 +11,12 @@
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -443,7 +443,7 @@ static WERROR get_nc_changes_filter_attrs(struct 
drsuapi_DsReplicaObjectListItem
        return WERR_OK;
 }
 
-/* 
+/*
   drsuapi_DsGetNCChanges for one object
 */
 static WERROR get_nc_changes_build_object(struct 
drsuapi_DsReplicaObjectListItemEx *obj,
@@ -698,7 +698,7 @@ static WERROR get_nc_changes_build_object(struct 
drsuapi_DsReplicaObjectListItem
                        }
                        /* some attributes needs to be encrypted
                           before being sent */
-                       werr = drsuapi_encrypt_attribute(obj, session_key, rid, 
+                       werr = drsuapi_encrypt_attribute(obj, session_key, rid,
                                                         
&obj->object.attribute_ctr.attributes[i]);
                        if (!W_ERROR_IS_OK(werr)) {
                                DEBUG(0,("Unable to encrypt %s on %s in DRS 
object - %s\n",
@@ -2760,7 +2760,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct 
dcesrv_call_state *dce_call, TALLOC_
        r->out.ctr->ctr6.source_dsa_invocation_id = 
*(samdb_ntds_invocation_id(sam_ctx));
        r->out.ctr->ctr6.first_object = NULL;
 
-       /* Check request revision. 
+       /* Check request revision.
         */
        switch (r->in.level) {
        case 8:
@@ -3029,13 +3029,67 @@ allowed:
                ret = drsuapi_DsReplicaHighWaterMark_cmp(&getnc_state->last_hwm,
                                                         &req10->highwatermark);
                if (ret != 0) {
-                       DEBUG(0,(__location__ ": DsGetNCChanges 2nd replication 
"
-                                "on DN %s %s highwatermark (last_dn %s)\n",
-                                ldb_dn_get_linearized(getnc_state->ncRoot_dn),
-                                (ret > 0) ? "older" : "newer",
-                                ldb_dn_get_linearized(getnc_state->last_dn)));
-                       TALLOC_FREE(getnc_state);
-                       b_state->getncchanges_full_repl_state = NULL;
+                       if (req10->highwatermark.reserved_usn == 0) {
+                               /*
+                                * Entra ID Connect / Azure AD is known to set
+                                * reserved_usn to zero in replies, when we
+                                * were expecting it to be returned unchanged
+                                * (it is supposed to be an opaque cookie).
+                                *
+                                * If the only difference is in the
+                                * reserved_usn, and it is 0 on the return, we
+                                * assume it is Azure AD and treat the
+                                * highwatermarks as equal.
+                                */
+                               req10->highwatermark.reserved_usn =
+                                       getnc_state->last_hwm.reserved_usn;
+
+                               ret = drsuapi_DsReplicaHighWaterMark_cmp(
+                                       &getnc_state->last_hwm,
+                                       &req10->highwatermark);
+
+                               /* put things as they were */
+                               req10->highwatermark.reserved_usn = 0;
+
+                               if (ret != 0) {
+                                       /* we will start again */
+                                       DBG_ERR("DsGetNCChanges 2nd replication 
"
+                                               "on DN %s %s highwatermark "
+                                               "(last_dn %s) after Azure AD "
+                                               "reserved_usn adjustment\n",
+                                               ldb_dn_get_linearized(
+                                                       getnc_state->ncRoot_dn),
+                                               (ret > 0) ? "older" : "newer",
+                                               ldb_dn_get_linearized(
+                                                       getnc_state->last_dn));
+                                       TALLOC_FREE(getnc_state);
+                                       b_state->getncchanges_full_repl_state =
+                                               NULL;
+                               } else {
+                                       /* log and continue as normal */
+                                       DBG_NOTICE(
+                                               "DsGetNCChanges 2nd replication 
"
+                                               "on DN %s: highwatermark "
+                                               "matches only after Azure AD "
+                                               "reserved_usn adjustment "
+                                               "(last_dn %s)\n",
+                                               ldb_dn_get_linearized(
+                                                       getnc_state->ncRoot_dn),
+                                               ldb_dn_get_linearized(
+                                                       getnc_state->last_dn));
+                               }
+                       } else {
+                               DBG_ERR("DsGetNCChanges 2nd replication "
+                                       "on DN %s %s highwatermark "
+                                       "(last_dn %s)\n",
+                                       ldb_dn_get_linearized(
+                                               getnc_state->ncRoot_dn),
+                                       (ret > 0) ? "older" : "newer",
+                                       ldb_dn_get_linearized(
+                                               getnc_state->last_dn));
+                               TALLOC_FREE(getnc_state);


-- 
Samba Shared Repository

Reply via email to