The branch, master has been updated
       via  d8e966da1c8 smbd: Remove a few vfs_stat() calls
       via  de439cd0304 smbd: Return ISLNK from non_widelink_open() in smb_fname
       via  e7b933100ee smbd: Don't require a valid stat for 
openat_pathref_fsp()
       via  2bbdaca8da8 smbd: No need to set O_DIRECTORY in openat_pathref_fsp()
       via  4e70b754a9c smbd: Mark fsp as directory after calling fstat()
       via  93d2defa426 smbd: Always use O_NONBLOCK in openat_pathref_fsp()
       via  e316f82bb73 smbd: Pass "dirfsp" and "smb_fname" to reopen_from_fsp()
       via  0fedcf5939a smbd: Pass dirfsp instead of fname to inherit_new_acl
       via  749c62ed2b2 smbd: Simplify dos_mode_from_name() with 
ISDOT()/ISDOTDOT()
       via  469a7ebf760 smbd: Simplify dos_mode_check_compressed()
       via  0e4cc565e67 smbd: get_acl_group_bits() needs a fsp, not a name
       via  8cee31c687f smbd: Fix a typo
       via  0dda30408fd smbd: Avoid an else
       via  7153c2c4454 smbd: Avoid two else statements
       via  1b304efef28 vfs: Format a comment
       via  ed9ee7ed895 printing: Fix a DBG message
       via  0c05ea15822 smbd: Avoid some casts
      from  9b48e7f7eda third_party/heimdal: import 
lorikeet-heimdal-202203101710 (commit df8d801544144949931cd742169be1207b239c3d)

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


- Log -----------------------------------------------------------------
commit d8e966da1c80f959ad65596e51cd66127014052b
Author: Volker Lendecke <[email protected]>
Date:   Thu Dec 30 16:58:58 2021 +0100

    smbd: Remove a few vfs_stat() calls
    
    openat_pathref_fsp() does not need them anymore
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>
    
    Autobuild-User(master): Ralph Böhme <[email protected]>
    Autobuild-Date(master): Fri Mar 11 19:19:21 UTC 2022 on sn-devel-184

commit de439cd0304773c59ebd33ddeddf675dd611944c
Author: Volker Lendecke <[email protected]>
Date:   Sat Jan 8 10:08:16 2022 +0100

    smbd: Return ISLNK from non_widelink_open() in smb_fname
    
    Soon we want to not require stat() calls before entering
    openat_pathref_fsp() anymore but rely on the fstat on the O_PATH file
    handle (alternatively the call to fstatat(AT_SYMLINK_NOFOLLOW)) done
    properly from within fd_openat(). The callers of non_widelink_open()
    expect the stat information to be correct in "smb_fname". Copy it in
    case of not opening a symlink in the posix case.
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit e7b933100ee487ae19cd2b3938f58056dca2115a
Author: Volker Lendecke <[email protected]>
Date:   Thu Dec 30 16:49:45 2021 +0100

    smbd: Don't require a valid stat for openat_pathref_fsp()
    
    With the simplifications in non_widelink_open() (don't depend on the
    is_directory fsp flag) the main reason for requiring a valid stat
    struct in openat_pathref_fsp() is gone. With this change
    openat_pathref_fsp() is now capable of being the very first (and
    authoritative) name-referencing operation with openat(O_PATH) for a
    name.
    
    Without having the stat information around before calling
    openat_pathref_fsp(), the call to check_same_dev_ino() becomes
    obsolete here.
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 2bbdaca8da8a0f4d4ff6bb5d4a98470db223b265
Author: Volker Lendecke <[email protected]>
Date:   Tue Mar 8 14:31:32 2022 +0100

    smbd: No need to set O_DIRECTORY in openat_pathref_fsp()
    
    If I read Linux' man 2 open right (and susv4 agrees), O_DIRECTORY is
    around to make sure opendir() is not raced against non-directory
    files. opendir() needs to make sure the underlying object is actually
    a directory. O_DIRECTORY is not required for opening directories in
    RDONLY mode, regardless of having O_PATH or not.
    
    At this point in openat_pathref_fsp() we don't care about the type of
    the underlying object, we do fstat() and distinguish between files and
    directories later according to the mode returned from fstat().
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 4e70b754a9cabb5d31d78e7d4a3f18028db07e99
Author: Volker Lendecke <[email protected]>
Date:   Tue Mar 8 12:57:13 2022 +0100

    smbd: Mark fsp as directory after calling fstat()
    
    Everything else is racy, and this is cheap to check.
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 93d2defa42683cd151b7a11075396aa911dbf0ae
Author: Volker Lendecke <[email protected]>
Date:   Tue Mar 8 12:44:33 2022 +0100

    smbd: Always use O_NONBLOCK in openat_pathref_fsp()
    
    There's no reason why we would ever want to block on open(O_PATH). The
    only cases that to me right now seem relevant is oplock breaks and
    FIFOs, which can block forever. Oplock breaks don't happen for
    O_PATH (hopefully...) but for the non-O_PATH case we don't want to
    block either but we do handle this higher up.
    
    We're handling EWOULDBLOCK for the oplock case correctly in
    open_file_ntcreate() by setting up polling. So far we haven't done
    this for the implicit openat_pathref_fsp() from filename_convert()
    yet. But as our kernel oplock implementation lacks in functionality
    big time anyway I would rather fail an open with NETWORK_BUSY than to
    sit waiting for an oplock break for 30 seconds.
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit e316f82bb734da840c1d7562c64c39acba48ec1b
Author: Volker Lendecke <[email protected]>
Date:   Tue Jan 18 21:19:40 2022 +0100

    smbd: Pass "dirfsp" and "smb_fname" to reopen_from_fsp()
    
    Lift the conn->cwd_fsp reference one level, we might want to pass in a
    real dirfsp in the future.
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 0fedcf5939aecee71bc1d0699d05a78812b5343a
Author: Volker Lendecke <[email protected]>
Date:   Tue Jan 18 19:46:43 2022 +0100

    smbd: Pass dirfsp instead of fname to inherit_new_acl
    
    Move to referencing directories via fsp's instead of names where we
    have them around
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 749c62ed2b2a712870d72105bf9b3524e1aec696
Author: Volker Lendecke <[email protected]>
Date:   Thu Mar 10 19:24:31 2022 +0100

    smbd: Simplify dos_mode_from_name() with ISDOT()/ISDOTDOT()
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 469a7ebf76011763267c9a14307d0606624643bf
Author: Volker Lendecke <[email protected]>
Date:   Thu Mar 10 19:18:44 2022 +0100

    smbd: Simplify dos_mode_check_compressed()
    
    btrfs_fget_compression() is the only real implementation of
    VFS_GET_COMPRESSION. It does not use the mem_ctx argument, so it seems
    unnecessary to do a full malloc()/free() cycle here. Moreover, if this
    was actually required, talloc_stackframe() would be more appropriate
    these days as deep within the smbd even loop it does not go through
    the libc malloc, but just increments a pointer.
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 0e4cc565e67fb4d95fc82a75c604db2bedbada29
Author: Volker Lendecke <[email protected]>
Date:   Thu Mar 10 19:30:28 2022 +0100

    smbd: get_acl_group_bits() needs a fsp, not a name
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 8cee31c687fa8fad3931e707c77cc05a60cbee34
Author: Volker Lendecke <[email protected]>
Date:   Thu Mar 10 16:44:44 2022 +0100

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

commit 0dda30408fd0deccf2435ddb9cce60bbdadc9ded
Author: Volker Lendecke <[email protected]>
Date:   Thu Mar 10 15:56:07 2022 +0100

    smbd: Avoid an else
    
    We continue; in the if clause
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 7153c2c4454ef680106c4865c11958430243baf8
Author: Volker Lendecke <[email protected]>
Date:   Thu Mar 10 15:50:42 2022 +0100

    smbd: Avoid two else statements
    
    We return in the if-clause
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 1b304efef2859a29c922b160762e14d866665c13
Author: Volker Lendecke <[email protected]>
Date:   Wed Mar 9 11:05:32 2022 +0100

    vfs: Format a comment
    
    I know, whitespace change, but this was just too ugly :-)
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit ed9ee7ed895f5cd67165a8074e7435abdfe3f1f7
Author: Volker Lendecke <[email protected]>
Date:   Tue Mar 8 15:16:04 2022 +0100

    printing: Fix a DBG message
    
    openat_pathref_fsp() returns NTSTATUS, errno might be wrong here
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 0c05ea158223240635222b60d5dceafb6eb77112
Author: Volker Lendecke <[email protected]>
Date:   Fri Mar 11 13:22:58 2022 +0100

    smbd: Avoid some casts
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

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

Summary of changes:
 source3/lib/adouble.c              | 36 ++---------------------
 source3/modules/vfs_shadow_copy2.c |  4 +--
 source3/printing/nt_printing.c     |  5 ++--
 source3/smbd/dir.c                 | 10 +++++--
 source3/smbd/dosmode.c             | 26 +++++------------
 source3/smbd/files.c               | 58 ++-----------------------------------
 source3/smbd/open.c                | 59 ++++++++++++++++++++++----------------
 source3/smbd/posix_acls.c          |  8 +++---
 source3/smbd/proto.h               |  6 ++--
 source3/smbd/pysmbd.c              | 19 ------------
 source3/smbd/reply.c               |  7 -----
 11 files changed, 67 insertions(+), 171 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c
index ef48d1aa73a..ddc43fab0f4 100644
--- a/source3/lib/adouble.c
+++ b/source3/lib/adouble.c
@@ -1208,12 +1208,6 @@ static bool ad_convert_xattr(vfs_handle_struct *handle,
 
                DBG_DEBUG("stream_name: %s\n", smb_fname_str_dbg(stream_name));
 
-               rc = vfs_stat(handle->conn, stream_name);
-               if (rc == -1 && errno != ENOENT) {
-                       ok = false;
-                       goto fail;
-               }
-
                status = openat_pathref_fsp(handle->conn->cwd_fsp, stream_name);
                if (!NT_STATUS_IS_OK(status) &&
                    !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND))
@@ -1307,7 +1301,6 @@ static bool ad_convert_finderinfo(vfs_handle_struct 
*handle,
        NTSTATUS status;
        int saved_errno = 0;
        int cmp;
-       int rc;
 
        cmp = memcmp(ad->ad_filler, AD_FILLER_TAG_OSX, ADEDLEN_FILLER);
        if (cmp != 0) {
@@ -1352,11 +1345,6 @@ static bool ad_convert_finderinfo(vfs_handle_struct 
*handle,
 
        DBG_DEBUG("stream_name: %s\n", smb_fname_str_dbg(stream_name));
 
-       rc = vfs_stat(handle->conn, stream_name);
-       if (rc == -1 && errno != ENOENT) {
-               return false;
-       }
-
        status = openat_pathref_fsp(handle->conn->cwd_fsp, stream_name);
        if (!NT_STATUS_IS_OK(status) &&
            !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND))
@@ -1607,18 +1595,12 @@ static bool ad_unconvert_open_ad(TALLOC_CTX *mem_ctx,
        NTSTATUS status;
        int ret;
 
-       ret = vfs_stat(handle->conn, adpath);
-       if (ret == -1 && errno != ENOENT) {
+       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)) {
                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 */
@@ -1670,10 +1652,6 @@ static bool ad_unconvert_get_streams(struct 
vfs_handle_struct *handle,
        files_struct *fsp = NULL;
        NTSTATUS status;
 
-       if (!VALID_STAT(smb_fname->st)) {
-               return false;
-       }
-
        status = openat_pathref_fsp(handle->conn->cwd_fsp, smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                return false;
@@ -1749,7 +1727,6 @@ static bool ad_collect_one_stream(struct 
vfs_handle_struct *handle,
        size_t needed_size;
        ssize_t nread;
        NTSTATUS status;
-       int ret;
        bool ok;
 
        sname = synthetic_smb_fname(ad,
@@ -1769,13 +1746,6 @@ static bool ad_collect_one_stream(struct 
vfs_handle_struct *handle,
 
        DBG_DEBUG("Collecting stream [%s]\n", smb_fname_str_dbg(sname));
 
-       ret = SMB_VFS_STAT(handle->conn, sname);
-       if (ret != 0) {
-               DBG_ERR("SMB_VFS_STAT [%s] failed\n", smb_fname_str_dbg(sname));
-               ok = false;
-               goto out;
-       }
-
        status = openat_pathref_fsp(handle->conn->cwd_fsp, sname);
        if (!NT_STATUS_IS_OK(status)) {
                ok = false;
diff --git a/source3/modules/vfs_shadow_copy2.c 
b/source3/modules/vfs_shadow_copy2.c
index 8f77b395d53..8e92cc71e18 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -572,13 +572,13 @@ static int check_for_converted_path(TALLOC_CTX *mem_ctx,
  * This function does two things.
  *
  * 1). Checks if an incoming filename is already a
- * snapshot converted pathname.
+ *     snapshot converted pathname.
  *     If so, it returns the pathname truncated
  *     at the snapshot point which will be used
  *     as the connectpath, and then does an early return.
  *
  * 2). Checks if an incoming filename contains an
- * SMB-layer @GMT- style timestamp.
+ *     SMB-layer @GMT- style timestamp.
  *     If so, it strips the timestamp, and returns
  *     both the timestamp and the stripped path
  *     (making it cwd-relative).
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 1e35e017fb2..c1d6458e36a 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -1098,8 +1098,9 @@ static uint32_t get_correct_cversion(const struct 
auth_session_info *session_inf
 
        nt_status = openat_pathref_fsp(conn->cwd_fsp, smb_fname);
        if (!NT_STATUS_IS_OK(nt_status)) {
-               DBG_NOTICE("Can't open file [%s], errno =%d\n",
-                          smb_fname_str_dbg(smb_fname), errno);
+               DBG_NOTICE("Can't open file [%s]: %s\n",
+                          smb_fname_str_dbg(smb_fname),
+                          nt_errstr(nt_status));
                *perr = WERR_ACCESS_DENIED;
                goto error_exit;
        }
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index d0d0ec2a43f..6180eba2fac 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -561,9 +561,11 @@ static uint32_t map_dir_offset_to_wire(struct dptr_struct 
*dptr, long offset)
 
        if (offset == END_OF_DIRECTORY_OFFSET) {
                return WIRE_END_OF_DIRECTORY_OFFSET;
-       } else if(offset == START_OF_DIRECTORY_OFFSET) {
+       }
+       if (offset == START_OF_DIRECTORY_OFFSET) {
                return WIRE_START_OF_DIRECTORY_OFFSET;
-       } else if (offset == DOT_DOT_DIRECTORY_OFFSET) {
+       }
+       if (offset == DOT_DOT_DIRECTORY_OFFSET) {
                return WIRE_DOT_DOT_DIRECTORY_OFFSET;
        }
        if (sizeof(long) == 4) {
@@ -925,7 +927,9 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
                        TALLOC_FREE(fname);
                        TALLOC_FREE(smb_fname);
                        continue;
-               } else if (NT_STATUS_EQUAL(status, 
NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+               }
+
+               if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
                        if (!(atname->flags & SMB_FILENAME_POSIX_PATH)) {
                                check_dfs_symlink = true;
                        }
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 43bb48d38c5..659066642c2 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -598,16 +598,11 @@ static NTSTATUS dos_mode_check_compressed(struct 
files_struct *fsp,
 {
        NTSTATUS status;
        uint16_t compression_fmt;
-       TALLOC_CTX *tmp_ctx = talloc_new(NULL);
-       if (tmp_ctx == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto err_out;
-       }
 
-       status = SMB_VFS_FGET_COMPRESSION(fsp->conn, tmp_ctx, fsp,
-                                        &compression_fmt);
+       status = SMB_VFS_FGET_COMPRESSION(
+               fsp->conn, talloc_tos(), fsp, &compression_fmt);
        if (!NT_STATUS_IS_OK(status)) {
-               goto err_ctx_free;
+               return status;
        }
 
        if (compression_fmt == COMPRESSION_FORMAT_LZNT1) {
@@ -615,12 +610,7 @@ static NTSTATUS dos_mode_check_compressed(struct 
files_struct *fsp,
        } else {
                *is_compressed = false;
        }
-       status = NT_STATUS_OK;
-
-err_ctx_free:
-       talloc_free(tmp_ctx);
-err_out:
-       return status;
+       return NT_STATUS_OK;
 }
 
 static uint32_t dos_mode_from_name(connection_struct *conn,
@@ -641,9 +631,7 @@ static uint32_t dos_mode_from_name(connection_struct *conn,
                }
 
                /* Only . and .. are not hidden. */
-               if ((p[0] == '.') &&
-                   !((p[1] == '\0') || (p[1] == '.' && p[2] == '\0')))
-               {
+               if ((p[0] == '.') && !(ISDOT(p) || ISDOTDOT(p))) {
                        result |= FILE_ATTRIBUTE_HIDDEN;
                }
        }
@@ -939,8 +927,8 @@ int file_set_dosmode(connection_struct *conn,
        unixmode = smb_fname->st.st_ex_mode;
 
        if (smb_fname->fsp != NULL) {
-               get_acl_group_bits(conn, smb_fname,
-                       &smb_fname->st.st_ex_mode);
+               get_acl_group_bits(
+                       conn, smb_fname->fsp, &smb_fname->st.st_ex_mode);
        }
 
        if (S_ISDIR(smb_fname->st.st_ex_mode))
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index da792a41c6e..5c0525441ca 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -397,7 +397,6 @@ 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(),
                                             smb_fname->base_name,
@@ -409,11 +408,6 @@ 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);
@@ -456,14 +450,6 @@ NTSTATUS openat_pathref_fsp(const struct files_struct 
*dirfsp,
                return NT_STATUS_OK;
        }
 
-       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);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -474,10 +460,6 @@ NTSTATUS openat_pathref_fsp(const struct files_struct 
*dirfsp,
        ZERO_STRUCT(conn->sconn->fsp_fi_cache);
 
        fsp->fsp_flags.is_pathref = true;
-       if (S_ISDIR(smb_fname->st.st_ex_mode)) {
-               fsp->fsp_flags.is_directory = true;
-               open_flags |= O_DIRECTORY;
-       }
 
        full_fname = full_path_from_dirfsp_atname(fsp,
                                                  dirfsp,
@@ -511,9 +493,7 @@ NTSTATUS openat_pathref_fsp(const struct files_struct 
*dirfsp,
                }
        }
 
-       if (S_ISFIFO(smb_fname->st.st_ex_mode)) {
-               open_flags |= O_NONBLOCK;
-       }
+       open_flags |= O_NONBLOCK;
 
        status = fd_openat(dirfsp, smb_fname, fsp, open_flags, 0);
        if (!NT_STATUS_IS_OK(status)) {
@@ -541,19 +521,6 @@ NTSTATUS openat_pathref_fsp(const struct files_struct 
*dirfsp,
                goto fail;
        }
 
-       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",
-                         smb_fname_str_dbg(smb_fname),
-                         (uintmax_t)smb_fname->st.st_ex_dev,
-                         (uintmax_t)smb_fname->st.st_ex_ino,
-                         (uintmax_t)fsp->fsp_name->st.st_ex_dev,
-                         (uintmax_t)fsp->fsp_name->st.st_ex_ino);
-               status = NT_STATUS_ACCESS_DENIED;
-               goto fail;
-       }
-
        /*
         * fd_openat() has done an FSTAT on the handle
         * so update the smb_fname stat info with "truth".
@@ -561,6 +528,8 @@ NTSTATUS openat_pathref_fsp(const struct files_struct 
*dirfsp,
         */
        smb_fname->st = fsp->fsp_name->st;
 
+       fsp->fsp_flags.is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode);
+
        fsp->file_id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
 
        status = fsp_smb_fname_link(fsp,
@@ -651,7 +620,6 @@ NTSTATUS synthetic_pathref(TALLOC_CTX *mem_ctx,
 {
        struct smb_filename *smb_fname = NULL;
        NTSTATUS status;
-       int ret;
 
        smb_fname = synthetic_smb_fname(mem_ctx,
                                        base_name,
@@ -663,19 +631,6 @@ NTSTATUS synthetic_pathref(TALLOC_CTX *mem_ctx,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (!VALID_STAT(smb_fname->st)) {
-               ret = vfs_stat(dirfsp->conn, smb_fname);
-               if (ret != 0) {
-                       int err = errno;
-                       int lvl = err == ENOENT ? DBGLVL_INFO : DBGLVL_ERR;
-                       DBG_PREFIX(lvl, ("stat [%s] failed: %s\n",
-                               smb_fname_str_dbg(smb_fname),
-                               strerror(err)));
-                       TALLOC_FREE(smb_fname);
-                       return map_nt_error_from_unix(err);
-               }
-       }
-
        status = openat_pathref_fsp(dirfsp, smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                DBG_ERR("opening [%s] failed\n",
@@ -711,7 +666,6 @@ NTSTATUS parent_pathref(TALLOC_CTX *mem_ctx,
        struct smb_filename *parent = NULL;
        struct smb_filename *atname = NULL;
        NTSTATUS status;
-       int ret;
 
        status = SMB_VFS_PARENT_PATHNAME(dirfsp->conn,
                                         mem_ctx,
@@ -732,12 +686,6 @@ NTSTATUS parent_pathref(TALLOC_CTX *mem_ctx,
         */
        parent->flags &= ~SMB_FILENAME_POSIX_PATH;
 
-       ret = vfs_stat(dirfsp->conn, parent);
-       if (ret != 0) {
-               TALLOC_FREE(parent);
-               return map_nt_error_from_unix(errno);
-       }
-
        status = openat_pathref_fsp(dirfsp, parent);
        if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(parent);
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index b3df0985239..d01b5ae65f4 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -112,10 +112,11 @@ static NTSTATUS smbd_check_access_rights_sd(
        rejected_share_access = access_mask & ~(conn->share_access);
 
        if (rejected_share_access) {
-               DBG_DEBUG("rejected share access 0x%x on %s (0x%x)\n",
-                         (unsigned int)access_mask,
+               DBG_DEBUG("rejected share access 0x%"PRIx32" on "
+                         "%s (0x%"PRIx32")\n",
+                         access_mask,
                          smb_fname_str_dbg(smb_fname),
-                         (unsigned int)rejected_share_access);
+                         rejected_share_access);
                return NT_STATUS_ACCESS_DENIED;
        }
 
@@ -131,9 +132,9 @@ static NTSTATUS smbd_check_access_rights_sd(
            !lp_acl_check_permissions(SNUM(conn)))
        {
                DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
-                         "Granting 0x%x\n",
+                         "Granting 0x%"PRIx32"\n",
                          smb_fname_str_dbg(smb_fname),
-                         (unsigned int)access_mask);
+                         access_mask);
                return NT_STATUS_OK;
        }
 
@@ -180,10 +181,11 @@ static NTSTATUS smbd_check_access_rights_sd(
                                (access_mask & ~do_not_check_mask),
                                &rejected_mask);
 
-       DBG_DEBUG("File [%s] requesting [0x%x] returning [0x%x] (%s)\n",
+       DBG_DEBUG("File [%s] requesting [0x%"PRIx32"] "
+                 "returning [0x%"PRIx32"] (%s)\n",
                  smb_fname_str_dbg(smb_fname),
-                 (unsigned int)access_mask,
-                 (unsigned int)rejected_mask,
+                 access_mask,
+                 rejected_mask,
                  nt_errstr(status));
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -265,7 +267,7 @@ NTSTATUS smbd_check_access_rights_fsp(struct files_struct 
*dirfsp,
        if (fsp_get_pathref_fd(fsp) == -1) {
                /*
                 * This is a POSIX open on a symlink. For the pathname
-                * verison of this function we used to return the st_mode
+                * version of this function we used to return the st_mode
                 * bits turned into an NT ACL. For a symlink the mode bits
                 * are always rwxrwxrwx which means the pathname version always
                 * returned NT_STATUS_OK for a symlink. For the handle reference
@@ -856,7 +858,11 @@ static NTSTATUS non_widelink_open(const struct 
files_struct *dirfsp,
                saved_status = status;
 
                if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
-                       /* Never follow symlinks on posix open. */
+                       /* Never follow symlinks on posix open, .. but
+                        * pass the fact it's a symlink in
+                        * smb_fname->st
+                        */
+                       smb_fname->st = fsp->fsp_name->st;
                        goto out;
                }
                if (!lp_follow_symlinks(SNUM(conn))) {
@@ -1239,7 +1245,9 @@ static NTSTATUS reopen_from_procfd(struct files_struct 
*fsp,
        return NT_STATUS_OK;
 }
 
-static NTSTATUS reopen_from_fsp(struct files_struct *fsp,
+static NTSTATUS reopen_from_fsp(struct files_struct *dirfsp,
+                               struct smb_filename *smb_fname,
+                               struct files_struct *fsp,
                                int flags,
                                mode_t mode,
                                bool *p_file_created)
@@ -1275,8 +1283,8 @@ static NTSTATUS reopen_from_fsp(struct files_struct *fsp,
        fsp->fsp_flags.is_pathref = false;
 
        status = fd_open_atomic(
-               fsp->conn->cwd_fsp,
-               fsp->fsp_name,
+               dirfsp,
+               smb_fname,
                fsp,
                flags,
                mode,
@@ -1470,7 +1478,9 @@ static NTSTATUS open_file(files_struct *fsp,
                 * Actually do the open - if O_TRUNC is needed handle it
                 * below under the share mode lock.
                 */
-               status = reopen_from_fsp(fsp,
+               status = reopen_from_fsp(fsp->conn->cwd_fsp,
+                                        fsp->fsp_name,
+                                        fsp,
                                         local_flags & ~O_TRUNC,
                                         unx_mode,
                                         p_file_created);
@@ -4644,7 +4654,13 @@ static NTSTATUS open_directory(connection_struct *conn,
                FILE_ADD_SUBDIRECTORY;
 
        if (access_mask & need_fd_access) {
-               status = reopen_from_fsp(fsp, O_RDONLY | O_DIRECTORY, 0, NULL);
+               status = reopen_from_fsp(
+                       fsp->conn->cwd_fsp,
+                       fsp->fsp_name,
+                       fsp,
+                       O_RDONLY | O_DIRECTORY,
+                       0,
+                       NULL);
                if (!NT_STATUS_IS_OK(status)) {
                        DBG_INFO("Could not open fd for [%s]: %s\n",
                                 smb_fname_str_dbg(smb_dname),
@@ -4993,11 +5009,6 @@ static NTSTATUS 
open_streams_for_delete(connection_struct *conn,
                        goto fail;
                }
 
-               if (SMB_VFS_STAT(conn, smb_fname_cp) == -1) {
-                       DEBUG(10, ("Unable to stat stream: %s\n",
-                                  smb_fname_str_dbg(smb_fname_cp)));
-               }
-
                status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
                if (!NT_STATUS_IS_OK(status)) {
                        DBG_DEBUG("Unable to open stream [%s]: %s\n",
@@ -5064,8 +5075,7 @@ static NTSTATUS open_streams_for_delete(connection_struct 
*conn,
  as the NT ACL when read.
 *********************************************************************/
 
-static NTSTATUS inherit_new_acl(struct smb_filename *parent_dir_fname,
-                               files_struct *fsp)
+static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
 {
        TALLOC_CTX *frame = talloc_stackframe();
        struct security_descriptor *parent_desc = NULL;
@@ -5087,7 +5097,7 @@ static NTSTATUS inherit_new_acl(struct smb_filename 
*parent_dir_fname,
        size_t size = 0;
        bool ok;
 
-       status = SMB_VFS_FGET_NT_ACL(parent_dir_fname->fsp,
+       status = SMB_VFS_FGET_NT_ACL(dirfsp,


-- 
Samba Shared Repository

Reply via email to