From: Ralph Boehme Date: Wed, 20 May 2020 21:07:20 +0000 (+0200) Subject: vfs_streams_depot: implement SMB_VFS_OPENAT() X-Git-Tag: ldb-2.2.0~380 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dcddc45c4c8272e236fa2ca918f376ff0b698f1d;p=thirdparty%2Fsamba.git vfs_streams_depot: implement SMB_VFS_OPENAT() Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison --- diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c index e408cbdc492..7a3402606d1 100644 --- a/source3/modules/vfs_streams_depot.c +++ b/source3/modules/vfs_streams_depot.c @@ -661,6 +661,80 @@ static int streams_depot_open(vfs_handle_struct *handle, return ret; } +static int streams_depot_openat(struct vfs_handle_struct *handle, + const struct files_struct *dirfsp, + const struct smb_filename *smb_fname, + struct files_struct *fsp, + int flags, + mode_t mode) +{ + struct smb_filename *smb_fname_stream = NULL; + struct smb_filename *smb_fname_base = NULL; + struct files_struct *fspcwd = NULL; + NTSTATUS status; + int ret = -1; + + /* + * For now assert this so the below SMB_VFS_STAT() is ok. + */ + SMB_ASSERT(dirfsp->fh->fd == AT_FDCWD); + + if (!is_named_stream(smb_fname)) { + return SMB_VFS_NEXT_OPENAT(handle, + dirfsp, + smb_fname, + fsp, + flags, + mode); + } + + /* Ensure the base file still exists. */ + smb_fname_base = synthetic_smb_fname(talloc_tos(), + smb_fname->base_name, + NULL, + NULL, + smb_fname->twrp, + smb_fname->flags); + if (smb_fname_base == NULL) { + ret = -1; + errno = ENOMEM; + goto done; + } + + ret = SMB_VFS_NEXT_STAT(handle, smb_fname_base); + if (ret == -1) { + goto done; + } + + /* Determine the stream name, and then open it. */ + status = stream_smb_fname(handle, smb_fname, &smb_fname_stream, true); + if (!NT_STATUS_IS_OK(status)) { + ret = -1; + errno = map_errno_from_nt_status(status); + goto done; + } + + status = vfs_at_fspcwd(talloc_tos(), handle->conn, &fspcwd); + if (!NT_STATUS_IS_OK(status)) { + ret = -1; + errno = map_errno_from_nt_status(status); + goto done; + } + + ret = SMB_VFS_NEXT_OPENAT(handle, + fspcwd, + smb_fname_stream, + fsp, + flags, + mode); + + done: + TALLOC_FREE(smb_fname_stream); + TALLOC_FREE(smb_fname_base); + TALLOC_FREE(fspcwd); + return ret; +} + static int streams_depot_unlink_internal(vfs_handle_struct *handle, struct files_struct *dirfsp, const struct smb_filename *smb_fname, @@ -1094,6 +1168,7 @@ static uint32_t streams_depot_fs_capabilities(struct vfs_handle_struct *handle, static struct vfs_fn_pointers vfs_streams_depot_fns = { .fs_capabilities_fn = streams_depot_fs_capabilities, .open_fn = streams_depot_open, + .openat_fn = streams_depot_openat, .stat_fn = streams_depot_stat, .lstat_fn = streams_depot_lstat, .unlinkat_fn = streams_depot_unlinkat,