VFS: Add SMB_VFS_FSTREAMINFO
authorNoel Power <noel.power@suse.com>
Fri, 7 May 2021 23:11:46 +0000 (16:11 -0700)
committerJeremy Allison <jra@samba.org>
Tue, 11 May 2021 15:49:28 +0000 (15:49 +0000)
Signed-off-by: Noel Power <noel.power@suse.com>
Reviewed-by: Jeremy Allison <jra@samba.org>
examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/include/vfs.h
source3/include/vfs_macros.h
source3/modules/vfs_default.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_not_implemented.c
source3/modules/vfs_time_audit.c
source3/smbd/vfs.c

index 56d2e42d160d98dd8852d48ca3b9047058a23b71..ce3672c752fe98a180517d83bc995b2c1f84275b 100644 (file)
@@ -638,6 +638,15 @@ static NTSTATUS skel_streaminfo(struct vfs_handle_struct *handle,
        return NT_STATUS_NOT_IMPLEMENTED;
 }
 
+static NTSTATUS skel_fstreaminfo(struct vfs_handle_struct *handle,
+                                struct files_struct *fsp,
+                                TALLOC_CTX *mem_ctx,
+                                unsigned int *num_streams,
+                                struct stream_struct **streams)
+{
+       return NT_STATUS_NOT_IMPLEMENTED;
+}
+
 static int skel_get_real_filename(struct vfs_handle_struct *handle,
                                  const struct smb_filename *path,
                                  const char *name,
@@ -1058,6 +1067,7 @@ static struct vfs_fn_pointers skel_opaque_fns = {
        .set_compression_fn = skel_set_compression,
 
        .streaminfo_fn = skel_streaminfo,
+       .fstreaminfo_fn = skel_fstreaminfo,
        .get_real_filename_fn = skel_get_real_filename,
        .connectpath_fn = skel_connectpath,
        .brl_lock_windows_fn = skel_brl_lock_windows,
index c5bcc5314d8234d2142a457a1ddbcffd13e27d97..02b3c75969f6e8fb77161aa38d2598650f65db5d 100644 (file)
@@ -855,6 +855,19 @@ static NTSTATUS skel_streaminfo(struct vfs_handle_struct *handle,
                                streams);
 }
 
+static NTSTATUS skel_fstreaminfo(struct vfs_handle_struct *handle,
+                                struct files_struct *fsp,
+                                TALLOC_CTX *mem_ctx,
+                                unsigned int *num_streams,
+                                struct stream_struct **streams)
+{
+       return SMB_VFS_NEXT_FSTREAMINFO(handle,
+                               fsp,
+                               mem_ctx,
+                               num_streams,
+                               streams);
+}
+
 static int skel_get_real_filename(struct vfs_handle_struct *handle,
                                  const struct smb_filename *path,
                                  const char *name,
@@ -1364,6 +1377,7 @@ static struct vfs_fn_pointers skel_transparent_fns = {
        .set_compression_fn = skel_set_compression,
 
        .streaminfo_fn = skel_streaminfo,
+       .fstreaminfo_fn = skel_fstreaminfo,
        .get_real_filename_fn = skel_get_real_filename,
        .connectpath_fn = skel_connectpath,
        .brl_lock_windows_fn = skel_brl_lock_windows,
index eaa816d8becc6dfc82757f257bb4b45b5fd664bc..dfba1cf7608dbb0e50f53353256443c557c101bb 100644 (file)
  * Version 45 - Remove SMB_VFS_CHMOD
  * Version 45 - Add SMB_VFS_FNTIMES
  * Version 45 - Remove SMB_VFS_NTIMES
+ * Version 45 - ADD SMB_VFS_FSTREAMINFO
  */
 
 #define SMB_VFS_INTERFACE_VERSION 45
@@ -1119,6 +1120,12 @@ struct vfs_fn_pointers {
                                  unsigned int *num_streams,
                                  struct stream_struct **streams);
 
+       NTSTATUS (*fstreaminfo_fn)(struct vfs_handle_struct *handle,
+                                  struct files_struct *fsp,
+                                  TALLOC_CTX *mem_ctx,
+                                  unsigned int *num_streams,
+                                  struct stream_struct **streams);
+
        int (*get_real_filename_fn)(struct vfs_handle_struct *handle,
                                    const struct smb_filename *path,
                                    const char *name,
@@ -1592,6 +1599,11 @@ NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
                                 TALLOC_CTX *mem_ctx,
                                 unsigned int *num_streams,
                                 struct stream_struct **streams);
+NTSTATUS smb_vfs_call_fstreaminfo(struct vfs_handle_struct *handle,
+                                 struct files_struct *fsp,
+                                 TALLOC_CTX *mem_ctx,
+                                 unsigned int *num_streams,
+                                 struct stream_struct **streams);
 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
                                   const struct smb_filename *path,
                                   const char *name,
@@ -2053,6 +2065,11 @@ NTSTATUS vfs_not_implemented_streaminfo(struct vfs_handle_struct *handle,
                                        TALLOC_CTX *mem_ctx,
                                        unsigned int *num_streams,
                                        struct stream_struct **streams);
+NTSTATUS vfs_not_implemented_fstreaminfo(struct vfs_handle_struct *handle,
+                                        struct files_struct *fsp,
+                                        TALLOC_CTX *mem_ctx,
+                                        unsigned int *num_streams,
+                                        struct stream_struct **streams);
 int vfs_not_implemented_get_real_filename(struct vfs_handle_struct *handle,
                                          const struct smb_filename *path,
                                          const char *name,
index 40ff68aedab3caa8cd3224457f1104c22418c7b1..3769593c2e427a02ab4a195705138f9529f4f707 100644 (file)
 #define SMB_VFS_NEXT_STREAMINFO(handle, fsp, smb_fname, mem_ctx, num_streams, streams) \
        smb_vfs_call_streaminfo((handle)->next, (fsp), (smb_fname), (mem_ctx), (num_streams), (streams))
 
+#define SMB_VFS_FSTREAMINFO(fsp, mem_ctx, num_streams, streams) \
+       smb_vfs_call_fstreaminfo((fsp)->conn->vfs_handles, (fsp), (mem_ctx), (num_streams), (streams))
+#define SMB_VFS_NEXT_FSTREAMINFO(handle, fsp, mem_ctx, num_streams, streams) \
+       smb_vfs_call_fstreaminfo(handle->next, (fsp), (mem_ctx), (num_streams), (streams))
+
 #define SMB_VFS_GET_REAL_FILENAME(conn, path, name, mem_ctx, found_name) \
        smb_vfs_call_get_real_filename((conn)->vfs_handles, (path), (name), (mem_ctx), (found_name))
 #define SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name, mem_ctx, found_name) \
index 1bb927f5a4748b6ff14d007ee0aaeb09253372f9..a5fee959dc822119a13f076aeee0133416406c5d 100644 (file)
@@ -3081,6 +3081,57 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
        return NT_STATUS_OK;
 }
 
+static NTSTATUS vfswrap_fstreaminfo(vfs_handle_struct *handle,
+                                  struct files_struct *fsp,
+                                  TALLOC_CTX *mem_ctx,
+                                  unsigned int *pnum_streams,
+                                  struct stream_struct **pstreams)
+{
+       struct stream_struct *tmp_streams = NULL;
+       unsigned int num_streams = *pnum_streams;
+       struct stream_struct *streams = *pstreams;
+       NTSTATUS status;
+
+       if (fsp->fsp_flags.is_directory) {
+               /*
+                * No default streams on directories
+                */
+               goto done;
+       }
+       status = vfs_stat_fsp(fsp);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       if (num_streams + 1 < 1) {
+               /* Integer wrap. */
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       tmp_streams = talloc_realloc(mem_ctx,
+                                       streams,
+                                       struct stream_struct,
+                                       num_streams + 1);
+       if (tmp_streams == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       tmp_streams[num_streams].name = talloc_strdup(tmp_streams, "::$DATA");
+       if (tmp_streams[num_streams].name == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       tmp_streams[num_streams].size = fsp->fsp_name->st.st_ex_size;
+       tmp_streams[num_streams].alloc_size = SMB_VFS_GET_ALLOC_SIZE(
+                                               handle->conn,
+                                               fsp,
+                                               &fsp->fsp_name->st);
+       num_streams += 1;
+
+       *pnum_streams = num_streams;
+       *pstreams = tmp_streams;
+ done:
+       return NT_STATUS_OK;
+}
+
 static int vfswrap_get_real_filename(struct vfs_handle_struct *handle,
                                     const struct smb_filename *path,
                                     const char *name,
@@ -3828,6 +3879,7 @@ static struct vfs_fn_pointers vfs_default_fns = {
        .file_id_create_fn = vfswrap_file_id_create,
        .fs_file_id_fn = vfswrap_fs_file_id,
        .streaminfo_fn = vfswrap_streaminfo,
+       .fstreaminfo_fn = vfswrap_fstreaminfo,
        .get_real_filename_fn = vfswrap_get_real_filename,
        .connectpath_fn = vfswrap_connectpath,
        .brl_lock_windows_fn = vfswrap_brl_lock_windows,
index 060fecfba40200a576b7c03db5e09462925540a5..f52a519e68d08e3ed2cace92ecb73e1dcb4ece36 100644 (file)
@@ -164,6 +164,7 @@ typedef enum _vfs_op_type {
        SMB_VFS_OP_FILE_ID_CREATE,
        SMB_VFS_OP_FS_FILE_ID,
        SMB_VFS_OP_STREAMINFO,
+       SMB_VFS_OP_FSTREAMINFO,
        SMB_VFS_OP_GET_REAL_FILENAME,
        SMB_VFS_OP_CONNECTPATH,
        SMB_VFS_OP_BRL_LOCK_WINDOWS,
@@ -303,6 +304,7 @@ static struct {
        { SMB_VFS_OP_FILE_ID_CREATE,    "file_id_create" },
        { SMB_VFS_OP_FS_FILE_ID,        "fs_file_id" },
        { SMB_VFS_OP_STREAMINFO,        "streaminfo" },
+       { SMB_VFS_OP_FSTREAMINFO,       "fstreaminfo" },
        { SMB_VFS_OP_GET_REAL_FILENAME, "get_real_filename" },
        { SMB_VFS_OP_CONNECTPATH,       "connectpath" },
        { SMB_VFS_OP_BRL_LOCK_WINDOWS,  "brl_lock_windows" },
@@ -2005,7 +2007,6 @@ static uint64_t smb_full_audit_fs_file_id(struct vfs_handle_struct *handle,
 
        return result;
 }
-
 static NTSTATUS smb_full_audit_streaminfo(vfs_handle_struct *handle,
                                          struct files_struct *fsp,
                                          const struct smb_filename *smb_fname,
@@ -2027,6 +2028,26 @@ static NTSTATUS smb_full_audit_streaminfo(vfs_handle_struct *handle,
        return result;
 }
 
+static NTSTATUS smb_full_audit_fstreaminfo(vfs_handle_struct *handle,
+                                          struct files_struct *fsp,
+                                          TALLOC_CTX *mem_ctx,
+                                          unsigned int *pnum_streams,
+                                          struct stream_struct **pstreams)
+{
+        NTSTATUS result;
+
+        result = SMB_VFS_NEXT_FSTREAMINFO(handle, fsp, mem_ctx,
+                                         pnum_streams, pstreams);
+
+        do_log(SMB_VFS_OP_FSTREAMINFO,
+               NT_STATUS_IS_OK(result),
+               handle,
+               "%s",
+               smb_fname_str_do_log(handle->conn, fsp->fsp_name));
+
+        return result;
+}
+
 static int smb_full_audit_get_real_filename(struct vfs_handle_struct *handle,
                                            const struct smb_filename *path,
                                            const char *name,
@@ -2982,6 +3003,7 @@ static struct vfs_fn_pointers vfs_full_audit_fns = {
        .snap_create_fn = smb_full_audit_snap_create,
        .snap_delete_fn = smb_full_audit_snap_delete,
        .streaminfo_fn = smb_full_audit_streaminfo,
+       .fstreaminfo_fn = smb_full_audit_fstreaminfo,
        .get_real_filename_fn = smb_full_audit_get_real_filename,
        .connectpath_fn = smb_full_audit_connectpath,
        .brl_lock_windows_fn = smb_full_audit_brl_lock_windows,
index 1b76427dc75ff5cb8bbb0e2d7d3efa7c49d78104..230ae35ca05297e5b5e24039bfaa6d952edd7d77 100644 (file)
@@ -640,6 +640,15 @@ NTSTATUS vfs_not_implemented_streaminfo(struct vfs_handle_struct *handle,
        return NT_STATUS_NOT_IMPLEMENTED;
 }
 
+NTSTATUS vfs_not_implemented_fstreaminfo(struct vfs_handle_struct *handle,
+                                       struct files_struct *fsp,
+                                       TALLOC_CTX *mem_ctx,
+                                       unsigned int *num_streams,
+                                       struct stream_struct **streams)
+{
+       return NT_STATUS_NOT_IMPLEMENTED;
+}
+
 int vfs_not_implemented_get_real_filename(struct vfs_handle_struct *handle,
                                          const struct smb_filename *path,
                                          const char *name,
@@ -1062,6 +1071,7 @@ static struct vfs_fn_pointers vfs_not_implemented_fns = {
        .set_compression_fn = vfs_not_implemented_set_compression,
 
        .streaminfo_fn = vfs_not_implemented_streaminfo,
+       .fstreaminfo_fn = vfs_not_implemented_fstreaminfo,
        .get_real_filename_fn = vfs_not_implemented_get_real_filename,
        .connectpath_fn = vfs_not_implemented_connectpath,
        .brl_lock_windows_fn = vfs_not_implemented_brl_lock_windows,
index 5b08ce9493525e4e3b3fd84346f256cb7b18b096..c2bf905a152dc31ffcd63ecc4e53a6c326936734 100644 (file)
@@ -1669,6 +1669,29 @@ static NTSTATUS smb_time_audit_streaminfo(vfs_handle_struct *handle,
        return result;
 }
 
+static NTSTATUS smb_time_audit_fstreaminfo(vfs_handle_struct *handle,
+                                         struct files_struct *fsp,
+                                         TALLOC_CTX *mem_ctx,
+                                         unsigned int *pnum_streams,
+                                         struct stream_struct **pstreams)
+{
+       NTSTATUS result;
+       struct timespec ts1,ts2;
+       double timediff;
+
+       clock_gettime_mono(&ts1);
+       result = SMB_VFS_NEXT_FSTREAMINFO(handle, fsp, mem_ctx,
+                                        pnum_streams, pstreams);
+       clock_gettime_mono(&ts2);
+       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+
+       if (timediff > audit_timeout) {
+               smb_time_audit_log_fsp("fstreaminfo", timediff, fsp);
+       }
+
+       return result;
+}
+
 static int smb_time_audit_get_real_filename(struct vfs_handle_struct *handle,
                                            const struct smb_filename *path,
                                            const char *name,
@@ -2817,6 +2840,7 @@ static struct vfs_fn_pointers vfs_time_audit_fns = {
        .snap_create_fn = smb_time_audit_snap_create,
        .snap_delete_fn = smb_time_audit_snap_delete,
        .streaminfo_fn = smb_time_audit_streaminfo,
+       .fstreaminfo_fn = smb_time_audit_fstreaminfo,
        .get_real_filename_fn = smb_time_audit_get_real_filename,
        .connectpath_fn = smb_time_audit_connectpath,
        .brl_lock_windows_fn = smb_time_audit_brl_lock_windows,
index d081a8935bf13992d84206b59f03e111bc3bd53d..9104db06690864daa815316f7ae8cf593487dd1a 100644 (file)
@@ -2399,6 +2399,17 @@ NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
                                          num_streams, streams);
 }
 
+NTSTATUS smb_vfs_call_fstreaminfo(struct vfs_handle_struct *handle,
+                                struct files_struct *fsp,
+                                TALLOC_CTX *mem_ctx,
+                                unsigned int *num_streams,
+                                struct stream_struct **streams)
+{
+       VFS_FIND(fstreaminfo);
+       return handle->fns->fstreaminfo_fn(handle, fsp, mem_ctx,
+                                         num_streams, streams);
+}
+
 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
                                   const struct smb_filename *path,
                                   const char *name,