smbd: use fsp_get_pathref_fd() for fstat() calls
authorRalph Boehme <slow@samba.org>
Mon, 5 Oct 2020 05:50:16 +0000 (07:50 +0200)
committerRalph Boehme <slow@samba.org>
Wed, 16 Dec 2020 09:08:30 +0000 (09:08 +0000)
If we can access the path to a file, by default we have FILE_READ_ATTRIBUTES
from the containing directory. See the section: "Algorithm to Check Access to an
Existing File" in MS-FSA.pdf.

So it's also safe to use a root opened pathref fd, as the root open is done on
the final component after a chdir() to the parent directory was done while still
impersonating the use. Qed.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/modules/vfs_afsacl.c
source3/modules/vfs_default.c
source3/modules/vfs_gpfs.c
source3/modules/vfs_streams_depot.c
source3/smbd/smb2_getinfo.c
source3/smbd/smb2_setinfo.c
source3/smbd/trans2.c
source3/smbd/vfs.c

index c4aa200cc7eccf3d87bd78ef896feb5d8e948c65..6024ae103fb67bb8a74be7218e05f079978a7bfe 100644 (file)
@@ -691,7 +691,7 @@ static size_t afs_fto_nt_acl(struct afs_acl *afs_acl,
 {
        SMB_STRUCT_STAT sbuf;
 
-       if (fsp->fh->fd == -1) {
+       if (fsp_get_pathref_fd(fsp) == -1) {
                /* Get the stat struct for the owner info. */
                return afs_to_nt_acl(afs_acl, fsp->conn, fsp->fsp_name,
                                     security_info, mem_ctx, ppdesc);
index 926ee51475c4dce20796b45b375104bc1d4c3ac7..a438ae3cca40237b50711c21bae5d3094f93863e 100644 (file)
@@ -3032,7 +3032,7 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
                goto done;
        }
 
-       if ((fsp != NULL) && (fsp->fh->fd != -1)) {
+       if ((fsp != NULL) && (fsp_get_pathref_fd(fsp) != -1)) {
                ret = SMB_VFS_FSTAT(fsp, &sbuf);
        }
        else {
index 4f3f8bed0cebbed8418a148b1ff765570e74c115..4a8418aa726c7368e92c2a010fa1950d31db217b 100644 (file)
@@ -1783,7 +1783,7 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle,
                return SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
        }
 
-       ret = gpfswrap_fstat_x(fsp->fh->fd, &litemask, &iattr, sizeof(iattr));
+       ret = gpfswrap_fstat_x(fsp_get_pathref_fd(fsp), &litemask, &iattr, sizeof(iattr));
        if (ret == -1 && errno == ENOSYS) {
                return SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
        }
@@ -1800,7 +1800,7 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle,
 
                set_effective_capability(DAC_OVERRIDE_CAPABILITY);
 
-               ret = gpfswrap_fstat_x(fsp->fh->fd, &litemask,
+               ret = gpfswrap_fstat_x(fsp_get_pathref_fd(fsp), &litemask,
                                       &iattr, sizeof(iattr));
                if (ret == -1) {
                        saved_errno = errno;
index da14a0d98a59c9fb40b3bd0076657f505292d8a3..a5e02d5a0698bfcd642bf4f4b436648273c16134 100644 (file)
@@ -1051,7 +1051,7 @@ static NTSTATUS streams_depot_streaminfo(vfs_handle_struct *handle,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if ((fsp != NULL) && (fsp->fh->fd != -1)) {
+       if ((fsp != NULL) && (fsp_get_pathref_fd(fsp) != -1)) {
                ret = SMB_VFS_NEXT_FSTAT(handle, fsp, &smb_fname_base->st);
        }
        else {
index d673709fc672d747d0157bdb52a874f6222ecb99..6df4a37af179b3ba2ac14e26fd5ba4fe42a52dee 100644 (file)
@@ -334,7 +334,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
 
                        /* We know this name is ok, it's already passed the checks. */
 
-               } else if (fsp->fh->fd == -1) {
+               } else if (fsp_get_pathref_fd(fsp) == -1) {
                        /*
                         * This is actually a QFILEINFO on a directory
                         * handle (returned from an NT SMB). NT5.0 seems
index c8071a73498a36b9be5606cde472236ca38e1f37..6177028158349edb701e286ff8bccec4771190bd 100644 (file)
@@ -415,7 +415,7 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx,
                        file_info_level = SMB2_FILE_RENAME_INFORMATION_INTERNAL;
                }
 
-               if (fsp->fh->fd == -1) {
+               if (fsp_get_pathref_fd(fsp) == -1) {
                        /*
                         * This is actually a SETFILEINFO on a directory
                         * handle (returned from an NT SMB). NT5.0 seems
index 2469daa3209f5fd99d04097bccfcdaf52d2f9a75..fa2255a4d5aa0417d07862cd662923904d73d8d2 100644 (file)
@@ -6061,7 +6061,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
 
                        /* We know this name is ok, it's already passed the checks. */
 
-               } else if(fsp->fh->fd == -1) {
+               } else if(fsp_get_pathref_fd(fsp) == -1) {
                        /*
                         * This is actually a QFILEINFO on a directory
                         * handle (returned from an NT SMB). NT5.0 seems
@@ -9350,7 +9350,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
 
                smb_fname = fsp->fsp_name;
 
-               if(fsp->fh->fd == -1) {
+               if (fsp_get_pathref_fd(fsp) == -1) {
                        /*
                         * This is actually a SETFILEINFO on a directory
                         * handle (returned from an NT SMB). NT5.0 seems
index cd7212d0e9be08cd854c1ddbd87bf1b196e90934..9bc640174b4c3346b08c2ca11c4091d7776b3b51 100644 (file)
@@ -1525,7 +1525,7 @@ NTSTATUS vfs_stat_fsp(files_struct *fsp)
        int ret;
        struct stat_ex saved_stat = fsp->fsp_name->st;
 
-       if(fsp->fh->fd == -1) {
+       if (fsp_get_pathref_fd(fsp) == -1) {
                if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
                        ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
                } else {