From: Noel Power Date: Tue, 27 Apr 2021 14:49:36 +0000 (+0100) Subject: s3: VFS: catia: Implement SMB_VFS_FSTREAMINFO X-Git-Tag: tevent-0.11.0~929 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f2a243512fabdc6302e909f133eee7d900204a12;p=thirdparty%2Fsamba.git s3: VFS: catia: Implement SMB_VFS_FSTREAMINFO Signed-off-by: Noel Power Reviewed-by: Jeremy Allison --- diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index 7cb9a8a1433..59adf63148e 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -999,6 +999,107 @@ catia_streaminfo(struct vfs_handle_struct *handle, return NT_STATUS_OK; } +static NTSTATUS +catia_fstreaminfo(struct vfs_handle_struct *handle, + struct files_struct *fsp, + TALLOC_CTX *mem_ctx, + unsigned int *_num_streams, + struct stream_struct **_streams) +{ + char *mapped_name = NULL; + NTSTATUS status; + unsigned int i; + struct smb_filename *catia_smb_fname = NULL; + struct smb_filename *smb_fname = NULL; + unsigned int num_streams = 0; + struct stream_struct *streams = NULL; + + smb_fname = fsp->fsp_name; + *_num_streams = 0; + *_streams = NULL; + + status = catia_string_replace_allocate(handle->conn, + smb_fname->base_name, + &mapped_name, + vfs_translate_to_unix); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = synthetic_pathref(talloc_tos(), + handle->conn->cwd_fsp, + mapped_name, + NULL, + &smb_fname->st, + smb_fname->twrp, + smb_fname->flags, + &catia_smb_fname); + + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(mapped_name); + return status; + } + + status = SMB_VFS_NEXT_FSTREAMINFO(handle, + catia_smb_fname->fsp, + mem_ctx, + &num_streams, + &streams); + TALLOC_FREE(mapped_name); + TALLOC_FREE(catia_smb_fname); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* + * Translate stream names just like the base names + */ + for (i = 0; i < num_streams; i++) { + /* + * Strip ":" prefix and ":$DATA" suffix to get a + * "pure" stream name and only translate that. + */ + void *old_ptr = streams[i].name; + char *stream_name = streams[i].name + 1; + char *stream_type = strrchr_m(stream_name, ':'); + + if (stream_type != NULL) { + *stream_type = '\0'; + stream_type += 1; + } + + status = catia_string_replace_allocate(handle->conn, + stream_name, + &mapped_name, + vfs_translate_to_windows); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(streams); + return status; + } + + if (stream_type != NULL) { + streams[i].name = talloc_asprintf(streams, + ":%s:%s", + mapped_name, + stream_type); + } else { + streams[i].name = talloc_asprintf(streams, + ":%s", + mapped_name); + } + TALLOC_FREE(mapped_name); + TALLOC_FREE(old_ptr); + if (streams[i].name == NULL) { + TALLOC_FREE(streams); + return NT_STATUS_NO_MEMORY; + } + } + + *_num_streams = num_streams; + *_streams = streams; + return NT_STATUS_OK; +} + static NTSTATUS catia_get_nt_acl_at(struct vfs_handle_struct *handle, struct files_struct *dirfsp, const struct smb_filename *smb_fname, @@ -2147,6 +2248,7 @@ static struct vfs_fn_pointers vfs_catia_fns = { .realpath_fn = catia_realpath, .chflags_fn = catia_chflags, .streaminfo_fn = catia_streaminfo, + .fstreaminfo_fn = catia_fstreaminfo, .strict_lock_check_fn = catia_strict_lock_check, .translate_name_fn = catia_translate_name, .fsctl_fn = catia_fsctl,