smbd: Fix open_pathref_base_fsp()'s implicit conn_cwd assumption
authorVolker Lendecke <vl@samba.org>
Thu, 30 Dec 2021 17:06:18 +0000 (18:06 +0100)
committerJeremy Allison <jra@samba.org>
Mon, 7 Feb 2022 19:00:34 +0000 (19:00 +0000)
Opening a stream base file only worked if "dirfsp == conn->cwd_fsp":
We have replaced fsp->fsp_name with the full dirfsp->relative pathname
at the point where open_pathref_base_fsp() is called. In case dirfsp
is already a subdirectory in a share, this breaks because the
open_pathref_base_fsp() uses fsp->fsp_name, not the original
dirfsp-relative one.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/smbd/files.c

index 36d4497b3d8ef44e9dfec57130b90431e5461066..4113779f9636d8f2543a46a71a5428e10379950a 100644 (file)
@@ -392,6 +392,7 @@ static int smb_fname_fsp_destructor(struct smb_filename *smb_fname)
  * fsp's as well.
  */
 static NTSTATUS open_pathref_base_fsp(const struct files_struct *dirfsp,
+                                     struct smb_filename *smb_fname,
                                      struct files_struct *fsp)
 {
        struct smb_filename *smb_fname_base = NULL;
@@ -399,11 +400,11 @@ static NTSTATUS open_pathref_base_fsp(const struct files_struct *dirfsp,
        int ret;
 
        smb_fname_base = synthetic_smb_fname(talloc_tos(),
-                                            fsp->fsp_name->base_name,
+                                            smb_fname->base_name,
                                             NULL,
                                             NULL,
-                                            fsp->fsp_name->twrp,
-                                            fsp->fsp_name->flags);
+                                            smb_fname->twrp,
+                                            smb_fname->flags);
        if (smb_fname_base == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -498,7 +499,13 @@ NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp,
        if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
            && is_ntfs_stream_smb_fname(fsp->fsp_name))
        {
-               status = open_pathref_base_fsp(dirfsp, fsp);
+               /*
+                * We must use smb_fname here, not fsp->fsp_name
+                * as smb_fname is relative to dirfsp, whereas
+                * fsp->fsp_name has been changed above to be
+                * full_fname, relative to the base of the share.
+                */
+               status = open_pathref_base_fsp(dirfsp, smb_fname, fsp);
                if (!NT_STATUS_IS_OK(status)) {
                        goto fail;
                }