The branch, master has been updated
       via  1b3d70e9ae9 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code 
check from call_trans2findfirst()
       via  5898f5769e0 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code 
check from copy_file()
       via  544767f72df smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code 
check from copy_file()
       via  8999c7d69c6 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code 
check from rename_internals()
       via  f21eb28cb87 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code 
check from rename_internals()
       via  6c2dad2aaef smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code 
check from reply_search()
       via  300d851a892 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code 
check from create_file_unixpath()
       via  f121374514e smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code 
check from open_streams_for_delete()
       via  fb82fac0f55 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code 
check from parent_pathref()
       via  5479f76e174 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code 
check from synthetic_pathref()
       via  0d454f34db5 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code 
check from get_file_handle_for_metadata()
       via  6e7142ba6c7 net: remove NT_STATUS_STOPPED_ON_SYMLINK status code 
check from openat_pathref_fsp()
       via  977f37643b2 smbd: don't return NT_STATUS_STOPPED_ON_SYMLINK in 
openat_pathref_fsp()
       via  cd3d970c84b smbd: simplify error codepath in openat_pathref_fsp()
       via  48bc561d1a8 smbd: expect valid stat info in openat_pathref_fsp()
       via  87e97e1b519 smbd: stat path before calling openat_pathref_fsp() in 
smbd_dirptr_get_entry()
       via  b3a0d6a1289 smbd: move smb_fname creation to earlier point in 
smbd_dirptr_get_entry()
       via  c31fe2f9e7d smbd: stat path before calling openat_pathref_fsp() in 
open_pathref_base_fsp()
       via  91edc50dc0a smbd: remove a redundant fstat()in 
create_file_unixpath()
       via  aa0ef26d1e9 smbd: call stat before openat_pathref_fsp() in 
create_file_unixpath()
       via  e636e20f90d smbd: fix a resource leak in create_file_unixpath()
       via  ab82dbc5ae4 smbd: stat path before calling openat_pathref_fsp() in 
unlink_internals()
       via  4f30c04462f s3/libadouble: stat path before calling 
openat_pathref_fsp() in ad_unconvert_open_ad()
       via  d78964c40b5 smbd: don't overwrite _mode if neither a msdfs symlink 
nor get_dosmode is requested
       via  5572ae296e7 CI: verify a symlink has FILE_ATTRIBUTE_NORMAL set
      from  0bdbe50fac6 lib:util: Avoid free'ing our own pointer

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


- Log -----------------------------------------------------------------
commit 1b3d70e9ae95892a70bd0f46ae5bf733c1bc9548
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Feb 2 16:01:19 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from 
call_trans2findfirst()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    
    Autobuild-User(master): Ralph Böhme <s...@samba.org>
    Autobuild-Date(master): Fri Feb  5 07:26:44 UTC 2021 on sn-devel-184

commit 5898f5769e0b126cca33ba0002f1e4c3eb80d21a
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Feb 2 16:00:32 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from copy_file()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 544767f72df366baf50be6d841e36dbcbe9f4065
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Feb 2 15:58:57 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from copy_file()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 8999c7d69c6312c7e7bef93417ecef93ddbdabf5
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Feb 2 15:58:42 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from 
rename_internals()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit f21eb28cb8737d3125e4c0c65545f93dd7ea863f
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Feb 2 15:58:30 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from 
rename_internals()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 6c2dad2aaef5eab75f3fe14219e9eca6724d6c99
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Feb 2 15:57:26 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from 
reply_search()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 300d851a89248ac9b220fbac55cd5daaebb7fbca
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Feb 2 15:57:09 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from 
create_file_unixpath()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit f121374514ed6957b9c6d022a17cc4e5c8aea9a6
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Feb 2 15:56:44 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from 
open_streams_for_delete()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit fb82fac0f554ad140e0b0fd7efac84a7c3dfa2e2
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Feb 2 15:56:26 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from 
parent_pathref()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 5479f76e174cf7454da2bad3f903070a8de84043
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Feb 2 15:56:16 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from 
synthetic_pathref()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 0d454f34db52d2903c830e1f1acd56a9a1dca04b
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Feb 2 15:54:43 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from 
get_file_handle_for_metadata()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 6e7142ba6c79c9c6f3ce299b6c7dd476cc229e6b
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Feb 2 15:54:02 2021 +0100

    net: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from 
openat_pathref_fsp()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 977f37643b223e164fbbf6c3ba1d37aa546ddb7d
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Feb 2 11:18:54 2021 +0100

    smbd: don't return NT_STATUS_STOPPED_ON_SYMLINK in openat_pathref_fsp()
    
    NT_STATUS_STOPPED_ON_SYMLINK is returned when trying to open a symlink, most
    callers are not interested in this.
    
    Some callers that would want to know whether openat_pathref_fsp() failed
    specifically on a symlink are setup_close_full_information(),
    smbd_dirptr_get_entry(), unlink_internals() and 
filename_convert_internal(), so
    we fix those callers to handle the symlink case themselves.
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit cd3d970c84b340630745bc555a86ac2d1306baac
Author: Ralph Boehme <s...@samba.org>
Date:   Tue Feb 2 13:49:56 2021 +0100

    smbd: simplify error codepath in openat_pathref_fsp()
    
    No change in behaviour: the cleanup code at the fail label does the same as 
the
    cleanup this patch removes. It has an extra fd_close() that is not existing 
in
    the removed cleanup, but as fsp->fd is -1, that's a noop.
    
    And when previously the
    
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    
    returns an an explicit status code, when now doing goto fail status will 
also be
    set to NT_STATUS_OBJECT_NAME_NOT_FOUND.
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 48bc561d1a8bb5ce99663b58a2e5e9aa344af96a
Author: Ralph Boehme <s...@samba.org>
Date:   Mon Feb 1 10:17:13 2021 +0100

    smbd: expect valid stat info in openat_pathref_fsp()
    
    We're never creating files here, so instead of waiting for the underlying 
open()
    to return ENOENT, just check that we have valid stat info, expecting all 
callers
    to have called SMB_VFS_[L]STAT() on the smb_fname.
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 87e97e1b519159b5f4c5ed4ef684783855e79ac3
Author: Ralph Boehme <s...@samba.org>
Date:   Mon Feb 1 12:09:39 2021 +0100

    smbd: stat path before calling openat_pathref_fsp() in 
smbd_dirptr_get_entry()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit b3a0d6a128989b593f135c425dd59351d13b6120
Author: Ralph Boehme <s...@samba.org>
Date:   Mon Feb 1 12:04:49 2021 +0100

    smbd: move smb_fname creation to earlier point in smbd_dirptr_get_entry()
    
    No change in behaviour. Makes way for the next commit adding additional 
logic.
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit c31fe2f9e7d65409229b7ad73418793ab34d359d
Author: Ralph Boehme <s...@samba.org>
Date:   Mon Feb 1 12:04:01 2021 +0100

    smbd: stat path before calling openat_pathref_fsp() in 
open_pathref_base_fsp()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 91edc50dc0aaa82d9ede7a7f8cf0f63312eb8503
Author: Ralph Boehme <s...@samba.org>
Date:   Mon Feb 1 12:03:08 2021 +0100

    smbd: remove a redundant fstat()in create_file_unixpath()
    
    openat_pathref_fsp() deep inside already calls fstat().
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit aa0ef26d1e9dcef0bcb47974d7cf60db922d7d08
Author: Ralph Boehme <s...@samba.org>
Date:   Mon Feb 1 12:01:22 2021 +0100

    smbd: call stat before openat_pathref_fsp() in create_file_unixpath()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit e636e20f90d4ee221ce6e20cab15a3cecb03850f
Author: Ralph Boehme <s...@samba.org>
Date:   Mon Feb 1 12:01:01 2021 +0100

    smbd: fix a resource leak in create_file_unixpath()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit ab82dbc5ae43cdb661bf49627a84926163bc8998
Author: Ralph Boehme <s...@samba.org>
Date:   Mon Feb 1 12:00:35 2021 +0100

    smbd: stat path before calling openat_pathref_fsp() in unlink_internals()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 4f30c04462fb1536323606dd4216fe5e32458ba5
Author: Ralph Boehme <s...@samba.org>
Date:   Mon Feb 1 11:59:37 2021 +0100

    s3/libadouble: stat path before calling openat_pathref_fsp() in 
ad_unconvert_open_ad()
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit d78964c40b5ca5ee0658c46d492b3dcd6f6b4b94
Author: Ralph Boehme <s...@samba.org>
Date:   Mon Feb 1 12:37:10 2021 +0100

    smbd: don't overwrite _mode if neither a msdfs symlink nor get_dosmode is 
requested
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14629
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 5572ae296e720a00ab438d7b50cfc458af631f69
Author: Ralph Boehme <s...@samba.org>
Date:   Mon Feb 1 14:44:03 2021 +0100

    CI: verify a symlink has FILE_ATTRIBUTE_NORMAL set
    
    Not that it really makes sense to set FILE_ATTRIBUTE_NORMAL for symlinks in
    POSIX client context, but that's what we had before 4.14.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14629
    
    Signed-off-by: Ralph Boehme <s...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

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

Summary of changes:
 source3/lib/adouble.c        |  13 +++--
 source3/smbd/dir.c           | 116 ++++++++++++++++++++-----------------------
 source3/smbd/dosmode.c       |   3 --
 source3/smbd/filename.c      |  15 ++----
 source3/smbd/files.c         |  53 ++++++++------------
 source3/smbd/open.c          |  40 ++++++---------
 source3/smbd/reply.c         |  34 ++++++-------
 source3/smbd/smb2_close.c    |   5 +-
 source3/smbd/trans2.c        |  19 ++++---
 source3/torture/test_posix.c |  14 ++++++
 source3/utils/net_vfs.c      |   3 --
 11 files changed, 146 insertions(+), 169 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c
index 3be6f353bd8..6fd290a31b8 100644
--- a/source3/lib/adouble.c
+++ b/source3/lib/adouble.c
@@ -1505,13 +1505,18 @@ static bool ad_unconvert_open_ad(TALLOC_CTX *mem_ctx,
        NTSTATUS status;
        int ret;
 
-       status = openat_pathref_fsp(handle->conn->cwd_fsp, adpath);
-       if (!NT_STATUS_IS_OK(status) &&
-           !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND))
-       {
+       ret = vfs_stat(handle->conn, adpath);
+       if (ret == -1 && errno != ENOENT) {
                return false;
        }
 
+       if (VALID_STAT(adpath->st)) {
+               status = openat_pathref_fsp(handle->conn->cwd_fsp, adpath);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return false;
+               }
+       }
+
        status = SMB_VFS_CREATE_FILE(
                handle->conn,
                NULL,                           /* req */
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index f70bc6cc56d..9d5244e3c4e 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -798,6 +798,7 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
        const char *dpath = dirptr->smb_dname->base_name;
        bool dirptr_path_is_dot = ISDOT(dpath);
        NTSTATUS status;
+       int ret;
 
        *_smb_fname = NULL;
        *_mode = 0;
@@ -865,17 +866,60 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
                        return false;
                }
 
+               /*
+                * We don't want to pass ./xxx to modules below us so don't
+                * add the path if it is just . by itself.
+                */
+               if (dirptr_path_is_dot) {
+                       memcpy(pathreal, dname, talloc_get_size(dname));
+               } else {
+                       memcpy(pathreal, dpath, pathlen);
+                       pathreal[pathlen] = '/';
+                       memcpy(pathreal + slashlen + pathlen, dname,
+                              talloc_get_size(dname));
+               }
+
+               /* Create smb_fname with NULL stream_name. */
+               smb_fname = synthetic_smb_fname(talloc_tos(),
+                                               pathreal,
+                                               NULL,
+                                               &sbuf,
+                                               dirptr->smb_dname->twrp,
+                                               dirptr->smb_dname->flags);
+               TALLOC_FREE(pathreal);
+               if (smb_fname == NULL) {
+                       TALLOC_FREE(dname);
+                       TALLOC_FREE(fname);
+                       return false;
+               }
+
+               if (!VALID_STAT(smb_fname->st)) {
+                       /*
+                        * If stat() fails with ENOENT it might be a
+                        * msdfs-symlink in Windows context, this is checked
+                        * below, for now we just want to fill stat info as good
+                        * as we can.
+                        */
+                       ret = vfs_stat(conn, smb_fname);
+                       if (ret != 0 && errno != ENOENT) {
+                               TALLOC_FREE(smb_fname);
+                               TALLOC_FREE(dname);
+                               TALLOC_FREE(fname);
+                               continue;
+                       }
+               }
+
                /* Create smb_fname with NULL stream_name. */
                atname = synthetic_smb_fname(talloc_tos(),
                                             dname,
                                             NULL,
-                                            &sbuf,
+                                            &smb_fname->st,
                                             dirptr->smb_dname->twrp,
                                             dirptr->smb_dname->flags);
                if (atname == NULL) {
                        TALLOC_FREE(dname);
                        TALLOC_FREE(fname);
-                       TALLOC_FREE(pathreal);
+                       TALLOC_FREE(smb_fname);
                        return false;
                }
 
@@ -892,72 +936,25 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
                 */
                status = openat_pathref_fsp(dirptr->dir_hnd->fsp, atname);
                if (!NT_STATUS_IS_OK(status) &&
-                   !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
-                   !NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK))
+                   !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND))
                {
                        TALLOC_FREE(atname);
                        TALLOC_FREE(dname);
                        TALLOC_FREE(fname);
-                       TALLOC_FREE(pathreal);
+                       TALLOC_FREE(smb_fname);
                        continue;
-               } else if (NT_STATUS_EQUAL(status, 
NT_STATUS_STOPPED_ON_SYMLINK)) {
+               } else if (NT_STATUS_EQUAL(status, 
NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
                        if (!(atname->flags & SMB_FILENAME_POSIX_PATH)) {
-                               TALLOC_FREE(atname);
-                               TALLOC_FREE(dname);
-                               TALLOC_FREE(fname);
-                               TALLOC_FREE(pathreal);
-                               continue;
+                               check_dfs_symlink = true;
                        }
                        /*
-                        * It's a symlink, disable getting dosmode in the
-                        * mode_fn() and prime the mode as
-                        * FILE_ATTRIBUTE_NORMAL.
+                        * Check if it's a symlink. We only want to return this
+                        * if it's a DFS symlink or in POSIX mode. Disable
+                        * getting dosmode in the mode_fn() and prime the mode
+                        * as FILE_ATTRIBUTE_NORMAL.
                         */
                        mode = FILE_ATTRIBUTE_NORMAL;
                        get_dosmode = false;
-               } else if (NT_STATUS_EQUAL(status, 
NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
-                       if (atname->flags & SMB_FILENAME_POSIX_PATH) {
-                               TALLOC_FREE(atname);
-                               TALLOC_FREE(dname);
-                               TALLOC_FREE(fname);
-                               TALLOC_FREE(pathreal);
-                               continue;
-                       }
-                       /*
-                        * Likely a dangling symlink. We only want to return
-                        * this if it's a DFS symlink, so we need to check for
-                        * that. Set get_dosmode to skip getting dosmode.
-                        */
-                       get_dosmode = false;
-                       check_dfs_symlink = true;
-               }
-
-               /*
-                * We don't want to pass ./xxx to modules below us so don't
-                * add the path if it is just . by itself.
-                */
-               if (dirptr_path_is_dot) {
-                       memcpy(pathreal, dname, talloc_get_size(dname));
-               } else {
-                       memcpy(pathreal, dpath, pathlen);
-                       pathreal[pathlen] = '/';
-                       memcpy(pathreal + slashlen + pathlen, dname,
-                              talloc_get_size(dname));
-               }
-
-               /* Create smb_fname with NULL stream_name. */
-               smb_fname = synthetic_smb_fname(talloc_tos(),
-                                               pathreal,
-                                               NULL,
-                                               &sbuf,
-                                               dirptr->smb_dname->twrp,
-                                               dirptr->smb_dname->flags);
-               if (smb_fname == NULL) {
-                       TALLOC_FREE(atname);
-                       TALLOC_FREE(dname);
-                       TALLOC_FREE(fname);
-                       TALLOC_FREE(pathreal);
-                       return false;
                }
 
                status = move_smb_fname_fsp_link(smb_fname, atname);
@@ -969,7 +966,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
                        TALLOC_FREE(smb_fname);
                        TALLOC_FREE(dname);
                        TALLOC_FREE(fname);
-                       TALLOC_FREE(pathreal);
                        continue;
                }
 
@@ -978,7 +974,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
                        TALLOC_FREE(smb_fname);
                        TALLOC_FREE(dname);
                        TALLOC_FREE(fname);
-                       TALLOC_FREE(pathreal);
                        continue;
                }
 
@@ -997,7 +992,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
                        TALLOC_FREE(smb_fname);
                        TALLOC_FREE(dname);
                        TALLOC_FREE(fname);
-                       TALLOC_FREE(pathreal);
                        continue;
                }
 
@@ -1007,7 +1001,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
                        TALLOC_FREE(smb_fname);
                        TALLOC_FREE(dname);
                        TALLOC_FREE(fname);
-                       TALLOC_FREE(pathreal);
                        continue;
                }
 
@@ -1042,7 +1035,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
                TALLOC_FREE(dname);
 
                *_smb_fname = talloc_move(ctx, &smb_fname);
-               TALLOC_FREE(pathreal);
                if (*_smb_fname == NULL) {
                        return false;
                }
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index ccfeaca124d..ea225a9b1ef 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -1378,9 +1378,6 @@ static NTSTATUS 
get_file_handle_for_metadata(connection_struct *conn,
        }
 
        status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
-       if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
-               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
        if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(smb_fname_cp);
                return status;
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 184a293f205..9035c7e82c7 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -1982,14 +1982,9 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX 
*ctx,
        }
 
        status = openat_pathref_fsp(conn->cwd_fsp, smb_fname);
-       if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
+       if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
                /*
-                * Don't leak NT_STATUS_STOPPED_ON_SYMLINK into the callers:
-                * it's a special SMB2 error that needs an extended SMB2 error
-                * response. We don't support that for SMB2 and it doesn't exist
-                * at all in SMB1.
-                *
-                * So we deal with symlinks here as we do in
+                * We deal with symlinks here as we do in
                 * SMB_VFS_CREATE_FILE(): return success for POSIX clients with
                 * the notable difference that there will be no fsp in
                 * smb_fname->fsp.
@@ -1997,10 +1992,10 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX 
*ctx,
                 * For Windows (non POSIX) clients fail with
                 * NT_STATUS_OBJECT_NAME_NOT_FOUND.
                 */
-               if (ucf_flags & UCF_POSIX_PATHNAMES) {
+               if (smb_fname->flags & SMB_FILENAME_POSIX_PATH &&
+                   S_ISLNK(smb_fname->st.st_ex_mode))
+               {
                        status = NT_STATUS_OK;
-               } else {
-                       status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
                }
        }
        if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 448a284780b..3254d728ad6 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -392,6 +392,7 @@ static NTSTATUS open_pathref_base_fsp(const struct 
files_struct *dirfsp,
 {
        struct smb_filename *smb_fname_base = NULL;
        NTSTATUS status;
+       int ret;
 
        smb_fname_base = synthetic_smb_fname(talloc_tos(),
                                             fsp->fsp_name->base_name,
@@ -403,6 +404,11 @@ static NTSTATUS open_pathref_base_fsp(const struct 
files_struct *dirfsp,
                return NT_STATUS_NO_MEMORY;
        }
 
+       ret = vfs_stat(fsp->conn, smb_fname_base);
+       if (ret != 0) {
+               return map_nt_error_from_unix(errno);
+       }
+
        status = openat_pathref_fsp(dirfsp, smb_fname_base);
        if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(smb_fname_base);
@@ -432,7 +438,6 @@ NTSTATUS openat_pathref_fsp(const struct files_struct 
*dirfsp,
 {
        connection_struct *conn = dirfsp->conn;
        struct smb_filename *full_fname = NULL;
-       bool file_existed = VALID_STAT(smb_fname->st);
        struct files_struct *fsp = NULL;
        int open_flags = O_RDONLY;
        NTSTATUS status;
@@ -446,8 +451,12 @@ NTSTATUS openat_pathref_fsp(const struct files_struct 
*dirfsp,
                return NT_STATUS_OK;
        }
 
-       if (file_existed && S_ISLNK(smb_fname->st.st_ex_mode)) {
-               return NT_STATUS_STOPPED_ON_SYMLINK;
+       if (!VALID_STAT(smb_fname->st)) {
+               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
+
+       if (S_ISLNK(smb_fname->st.st_ex_mode)) {
+               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
        status = fsp_new(conn, conn, &fsp);
@@ -493,23 +502,9 @@ NTSTATUS openat_pathref_fsp(const struct files_struct 
*dirfsp,
 
        status = fd_openat(dirfsp, smb_fname, fsp, open_flags, 0);
        if (!NT_STATUS_IS_OK(status)) {
-               DBG_DEBUG("Could not open fd for [%s]: %s\n",
-                         fsp_str_dbg(fsp),
-                         nt_errstr(status));
-
-               if (fsp->base_fsp != NULL) {
-                       struct files_struct *tmp_base_fsp = fsp->base_fsp;
-
-                       fsp_set_base_fsp(fsp, NULL);
-
-                       fd_close(tmp_base_fsp);
-                       file_free(NULL, tmp_base_fsp);
-               }
-               file_free(NULL, fsp);
-               fsp = NULL;
-
                if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) ||
-                   NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
+                   NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND) ||
+                   NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK))
                {
                        /*
                         * streams_xattr return NT_STATUS_NOT_FOUND for
@@ -521,19 +516,17 @@ NTSTATUS openat_pathref_fsp(const struct files_struct 
*dirfsp,
                         *
                         * NT_STATUS_OBJECT_NAME_NOT_FOUND is the simple
                         * ENOENT case.
+                        *
+                        * NT_STATUS_STOPPED_ON_SYMLINK is returned when trying
+                        * to open a symlink, our callers are not interested in
+                        * this.
                         */
                        status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
                }
-               if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
-                       goto fail;
-               }
-
-               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               goto fail;
        }
 
-       if (file_existed &&
-           !check_same_dev_ino(&smb_fname->st, &fsp->fsp_name->st))
-       {
+       if (!check_same_dev_ino(&smb_fname->st, &fsp->fsp_name->st)) {
                DBG_DEBUG("file [%s] - dev/ino mismatch. "
                          "Old (dev=%ju, ino=%ju). "
                          "New (dev=%ju, ino=%ju).\n",
@@ -660,9 +653,6 @@ NTSTATUS synthetic_pathref(TALLOC_CTX *mem_ctx,
        }
 
        status = openat_pathref_fsp(dirfsp, smb_fname);
-       if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
-               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
        if (!NT_STATUS_IS_OK(status)) {
                DBG_ERR("opening [%s] failed\n",
                        smb_fname_str_dbg(smb_fname));
@@ -715,9 +705,6 @@ NTSTATUS parent_pathref(TALLOC_CTX *mem_ctx,
        }
 
        status = openat_pathref_fsp(dirfsp, parent);
-       if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
-               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
        if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(parent);
                return status;
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 721a48f3b5a..92b0a507760 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -4978,9 +4978,6 @@ static NTSTATUS open_streams_for_delete(connection_struct 
*conn,
                }
 
                status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
-               if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
-                       status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
-               }
                if (!NT_STATUS_IS_OK(status)) {
                        DBG_DEBUG("Unable to open stream [%s]: %s\n",
                                  smb_fname_str_dbg(smb_fname_cp),
@@ -5568,6 +5565,7 @@ static NTSTATUS create_file_unixpath(connection_struct 
*conn,
        files_struct *base_fsp = NULL;
        files_struct *fsp = NULL;
        NTSTATUS status;
+       int ret;
 
        DBG_DEBUG("create_file_unixpath: access_mask = 0x%x "
                  "file_attributes = 0x%x, share_access = 0x%x, "
@@ -5715,37 +5713,28 @@ static NTSTATUS create_file_unixpath(connection_struct 
*conn,
                        goto fail;
                }
 
-               SET_STAT_INVALID(smb_fname_base->st);
-
                /*
                 * We may be creating the basefile as part of creating the
                 * stream, so it's legal if the basefile doesn't exist at this
                 * point, the create_file_unixpath() below will create it. But
                 * if the basefile exists we want a handle so we can fstat() it.
                 */
-               status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_base);
-               if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
-                       status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
-               }
-               if (!NT_STATUS_IS_OK(status) &&
-                   !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND))
-               {
-                       DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
-                               smb_fname_str_dbg(smb_fname_base),
-                               nt_errstr(status));
+
+               ret = vfs_stat(conn, smb_fname_base);
+               if (ret == -1 && errno != ENOENT) {
+                       status = map_nt_error_from_unix(errno);
                        TALLOC_FREE(smb_fname_base);
                        goto fail;
                }
-
-               if (smb_fname_base->fsp != NULL) {
-                       int ret;
-
-                       ret = SMB_VFS_FSTAT(smb_fname_base->fsp,
-                                           &smb_fname_base->st);
-                       if (ret != 0) {
-                               DBG_DEBUG("Unable to stat stream [%s]: %s\n",
-                                         smb_fname_str_dbg(smb_fname_base),
-                                         strerror(errno));
+               if (ret == 0) {
+                       status = openat_pathref_fsp(conn->cwd_fsp,
+                                                   smb_fname_base);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
+                                       smb_fname_str_dbg(smb_fname_base),
+                                       nt_errstr(status));
+                               TALLOC_FREE(smb_fname_base);
+                               goto fail;
                        }
 
                        /*
@@ -5764,6 +5753,7 @@ static NTSTATUS create_file_unixpath(connection_struct 
*conn,
                                        "for base %s failed: "
                                        "%s\n", smb_fname->base_name,
                                        nt_errstr(status)));
+                               TALLOC_FREE(smb_fname_base);
                                goto fail;
                        }
                }
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index c418f39cf3b..45a2a298f65 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1834,9 +1834,6 @@ void reply_search(struct smb_request *req)
                }
 
                nt_status = openat_pathref_fsp(conn->cwd_fsp, smb_dname);
-               if (NT_STATUS_EQUAL(nt_status, NT_STATUS_STOPPED_ON_SYMLINK)) {
-                       nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
-               }
                if (!NT_STATUS_IS_OK(nt_status)) {
                        reply_nterror(req, nt_status);
                        goto out;
@@ -3281,6 +3278,7 @@ NTSTATUS unlink_internals(connection_struct *conn,
        NTSTATUS status = NT_STATUS_OK;
        struct smb_filename *smb_fname_dir = NULL;
        TALLOC_CTX *ctx = talloc_tos();
+       int ret;
 
        /* Split up the directory from the filename/mask. */
        status = split_fname_dir_mask(ctx, smb_fname->base_name,
@@ -3457,10 +3455,23 @@ NTSTATUS unlink_internals(connection_struct *conn,
                                goto out;
                        }
 
+                       ret = vfs_stat(conn, f);
+                       if (ret != 0) {


-- 
Samba Shared Repository

Reply via email to