From: Volker Lendecke Date: Thu, 2 Jan 2025 08:37:32 +0000 (+0100) Subject: vfs: Fix streams_depot_lstat() X-Git-Tag: tdb-1.4.13~93 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7108b3b2e1b5d6858e839cf3bae2dc1129fba520;p=thirdparty%2Fsamba.git vfs: Fix streams_depot_lstat() When passing NULL as base_sbuf to stream_smb_fname(), it uses SMB_VFS_NEXT_STAT() to find the right stream directory. This will potentially dereference the last symlink. Make sure that in streams_depot_lstat() this is not done. Also, the current version did not return the stat struct at all. Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c index d2b8a02431f..cc69f7f21ed 100644 --- a/source3/modules/vfs_streams_depot.c +++ b/source3/modules/vfs_streams_depot.c @@ -623,6 +623,7 @@ static int streams_depot_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname) { struct smb_filename *smb_fname_stream = NULL; + struct smb_filename *base_fname = NULL; NTSTATUS status; int ret = -1; @@ -633,9 +634,20 @@ static int streams_depot_lstat(vfs_handle_struct *handle, return SMB_VFS_NEXT_LSTAT(handle, smb_fname); } - /* Stat the actual stream now. */ + base_fname = cp_smb_filename_nostream(talloc_tos(), smb_fname); + if (base_fname == NULL) { + errno = ENOMEM; + goto done; + } + + ret = SMB_VFS_NEXT_LSTAT(handle, base_fname); + if (ret == -1) { + goto done; + } + + /* lstat the actual stream now. */ status = stream_smb_fname( - handle, NULL, smb_fname, &smb_fname_stream, false); + handle, &base_fname->st, smb_fname, &smb_fname_stream, false); if (!NT_STATUS_IS_OK(status)) { ret = -1; errno = map_errno_from_nt_status(status); @@ -644,8 +656,17 @@ static int streams_depot_lstat(vfs_handle_struct *handle, ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname_stream); + if (ret == 0) { + smb_fname->st = smb_fname_stream->st; + } + done: - TALLOC_FREE(smb_fname_stream); + { + int err = errno; + TALLOC_FREE(smb_fname_stream); + TALLOC_FREE(base_fname); + errno = err; + } return ret; }