]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3/modules: Ensure vfs_streaminfo gets passed valid pathref smb_filename
authorNoel Power <noel.power@suse.com>
Mon, 8 Feb 2021 10:42:22 +0000 (10:42 +0000)
committerJeremy Allison <jra@samba.org>
Fri, 26 Feb 2021 21:28:33 +0000 (21:28 +0000)
the smb_filename/smb_filename->fsp passed to vfs_streaminfo
eventually is passed to SMB_VFS_FLISTXATTR, we need to ensure this is
properly setup and not NULL

Signed-off-by: Noel Power <noel.power@suse.com>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/modules/vfs_catia.c
source3/smbd/filename.c
source3/smbd/open.c

index d7e53e4fa12e54b763faf13ba5cb547c41ed1f55..81c24a8cfd141608a34af4f7999e7397d9d386c5 100644 (file)
@@ -982,19 +982,21 @@ catia_streaminfo(struct vfs_handle_struct *handle,
                                &mapped_name,
                                vfs_translate_to_unix);
        if (!NT_STATUS_IS_OK(status)) {
-               errno = map_errno_from_nt_status(status);
                return status;
        }
 
-       catia_smb_fname = synthetic_smb_fname(talloc_tos(),
+       status = synthetic_pathref(talloc_tos(),
+                                       handle->conn->cwd_fsp,
                                        mapped_name,
                                        NULL,
                                        &smb_fname->st,
                                        smb_fname->twrp,
-                                       smb_fname->flags);
-       if (catia_smb_fname == NULL) {
+                                       smb_fname->flags,
+                                       &catia_smb_fname);
+
+       if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(mapped_name);
-               return NT_STATUS_NO_MEMORY;
+               return status;
        }
 
        status = SMB_VFS_NEXT_STREAMINFO(handle, fsp, catia_smb_fname,
index 9035c7e82c72cba90dfd55db319508d0cb3fc481..3560837ad1e7ae788cebcc15e778e5d2232a7eeb 100644 (file)
@@ -1720,6 +1720,7 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
        NTSTATUS status;
        unsigned int i, num_streams = 0;
        struct stream_struct *streams = NULL;
+       struct smb_filename *pathref = NULL;
 
        if (SMB_VFS_STAT(conn, smb_fname) == 0) {
                DEBUG(10, ("'%s' exists\n", smb_fname_str_dbg(smb_fname)));
@@ -1732,12 +1733,36 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
                goto fail;
        }
 
+       if (smb_fname->fsp == NULL) {
+               status = synthetic_pathref(mem_ctx,
+                                       conn->cwd_fsp,
+                                       smb_fname->base_name,
+                                       NULL,
+                                       NULL,
+                                       smb_fname->twrp,
+                                       smb_fname->flags,
+                                       &pathref);
+               if (!NT_STATUS_IS_OK(status)) {
+                       if (NT_STATUS_EQUAL(status,
+                               NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+                               TALLOC_FREE(pathref);
+                               SET_STAT_INVALID(smb_fname->st);
+                               return NT_STATUS_OK;
+                       }
+                       DBG_DEBUG("synthetic_pathref failed: %s\n",
+                                 nt_errstr(status));
+                       goto fail;
+               }
+       } else {
+               pathref = smb_fname;
+       }
+
        /* Fall back to a case-insensitive scan of all streams on the file. */
-       status = vfs_streaminfo(conn, NULL, smb_fname, mem_ctx,
+       status = vfs_streaminfo(conn, NULL, pathref, mem_ctx,
                                &num_streams, &streams);
-
        if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
                SET_STAT_INVALID(smb_fname->st);
+               TALLOC_FREE(pathref);
                return NT_STATUS_OK;
        }
 
@@ -1760,6 +1785,7 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
        /* Couldn't find the stream. */
        if (i == num_streams) {
                SET_STAT_INVALID(smb_fname->st);
+               TALLOC_FREE(pathref);
                TALLOC_FREE(streams);
                return NT_STATUS_OK;
        }
@@ -1782,6 +1808,7 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
        }
        status = NT_STATUS_OK;
  fail:
+       TALLOC_FREE(pathref);
        TALLOC_FREE(streams);
        return status;
 }
index 92b0a507760ec1d119dfc442d3a9726ead3ab4af..5b3dc246e8a253a661d65dac88215f2855369360 100644 (file)
@@ -4919,9 +4919,36 @@ static NTSTATUS open_streams_for_delete(connection_struct *conn,
        int j;
        unsigned int i, num_streams = 0;
        TALLOC_CTX *frame = talloc_stackframe();
+       const struct smb_filename *pathref = NULL;
        NTSTATUS status;
 
-       status = vfs_streaminfo(conn, NULL, smb_fname, talloc_tos(),
+       if (smb_fname->fsp == NULL) {
+               struct smb_filename *tmp = NULL;
+               status = synthetic_pathref(frame,
+                                       conn->cwd_fsp,
+                                       smb_fname->base_name,
+                                       NULL,
+                                       NULL,
+                                       smb_fname->twrp,
+                                       smb_fname->flags,
+                                       &tmp);
+               if (!NT_STATUS_IS_OK(status)) {
+                       if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
+                           || NT_STATUS_EQUAL(status,
+                                      NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+                               DBG_DEBUG("no streams around\n");
+                               TALLOC_FREE(frame);
+                               return NT_STATUS_OK;
+                       }
+                       DBG_DEBUG("synthetic_pathref failed: %s\n",
+                          nt_errstr(status));
+                       goto fail;
+               }
+               pathref = tmp;
+       } else {
+               pathref = smb_fname;
+       }
+       status = vfs_streaminfo(conn, NULL, pathref, talloc_tos(),
                                &num_streams, &stream_info);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)