From: Ralph Boehme Date: Thu, 11 May 2017 16:05:18 +0000 (+0200) Subject: vfs_streams_xattr: implement all missing handle based VFS functions X-Git-Tag: tdb-1.3.15~134 X-Git-Url: http://git.samba.org/?a=commitdiff_plain;h=9647af6bec62c9f61d541aad4a9b8f25fd5bc627;p=samba.git vfs_streams_xattr: implement all missing handle based VFS functions Implement all missing handle based VFS function. If the call is on a named stream, implement the appropriate action for the VFS function, in most cases a no-op. Bug: https://bugzilla.samba.org/show_bug.cgi?id=12791 Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke --- diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index 5eb2b9b230a..988d2f1d837 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -26,6 +26,7 @@ #include "system/filesys.h" #include "../lib/crypto/md5.h" #include "lib/util/tevent_unix.h" +#include "librpc/gen_ndr/ioctl.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_VFS @@ -1322,6 +1323,396 @@ static int streams_xattr_fallocate(struct vfs_handle_struct *handle, return -1; } +static int streams_xattr_fchown(vfs_handle_struct *handle, files_struct *fsp, + uid_t uid, gid_t gid) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid); + } + + return 0; +} + +static int streams_xattr_fchmod(vfs_handle_struct *handle, + files_struct *fsp, + mode_t mode) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode); + } + + return 0; +} + +static int streams_xattr_fsync(vfs_handle_struct *handle, files_struct *fsp) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_FSYNC(handle, fsp); + } + + return 0; +} + +static ssize_t streams_xattr_fgetxattr(struct vfs_handle_struct *handle, + struct files_struct *fsp, + const char *name, + void *value, + size_t size) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, value, size); + } + + errno = ENOTSUP; + return -1; +} + +static ssize_t streams_xattr_flistxattr(struct vfs_handle_struct *handle, + struct files_struct *fsp, + char *list, + size_t size) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size); + } + + errno = ENOTSUP; + return -1; +} + +static int streams_xattr_fremovexattr(struct vfs_handle_struct *handle, + struct files_struct *fsp, + const char *name) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, name); + } + + errno = ENOTSUP; + return -1; +} + +static int streams_xattr_fsetxattr(struct vfs_handle_struct *handle, + struct files_struct *fsp, + const char *name, + const void *value, + size_t size, + int flags) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_FSETXATTR(handle, fsp, name, value, + size, flags); + } + + errno = ENOTSUP; + return -1; +} + +static int streams_xattr_fchmod_acl(vfs_handle_struct *handle, + files_struct *fsp, + mode_t mode) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode); + } + + return 0; +} + +static SMB_ACL_T streams_xattr_sys_acl_get_fd(vfs_handle_struct *handle, + files_struct *fsp, + TALLOC_CTX *mem_ctx) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, mem_ctx); + } + + return SMB_VFS_NEXT_SYS_ACL_GET_FILE( + handle, fsp->base_fsp->fsp_name, + SMB_ACL_TYPE_ACCESS, mem_ctx); +} + +static int streams_xattr_sys_acl_set_fd(vfs_handle_struct *handle, + files_struct *fsp, + SMB_ACL_T theacl) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl); + } + + return 0; +} + +static int streams_xattr_sys_acl_blob_get_fd(vfs_handle_struct *handle, + files_struct *fsp, + TALLOC_CTX *mem_ctx, + char **blob_description, + DATA_BLOB *blob) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle, fsp, mem_ctx, + blob_description, blob); + } + + return SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE( + handle, fsp->base_fsp->fsp_name, mem_ctx, + blob_description, blob); +} + +static NTSTATUS streams_xattr_fget_nt_acl(vfs_handle_struct *handle, + files_struct *fsp, + uint32_t security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, + mem_ctx, ppdesc); + } + + return SMB_VFS_NEXT_GET_NT_ACL(handle, fsp->base_fsp->fsp_name, + security_info, mem_ctx, ppdesc); +} + +static NTSTATUS streams_xattr_fset_nt_acl(vfs_handle_struct *handle, + files_struct *fsp, + uint32_t security_info_sent, + const struct security_descriptor *psd) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, + security_info_sent, psd); + } + + return NT_STATUS_OK; +} + +struct streams_xattr_fsync_state { + int ret; + struct vfs_aio_state vfs_aio_state; +}; + +static void streams_xattr_fsync_done(struct tevent_req *subreq); + +static struct tevent_req *streams_xattr_fsync_send( + struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct files_struct *fsp) +{ + struct tevent_req *req = NULL; + struct tevent_req *subreq = NULL; + struct streams_xattr_fsync_state *state = NULL; + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + req = tevent_req_create(mem_ctx, &state, + struct streams_xattr_fsync_state); + if (req == NULL) { + return NULL; + } + + if (sio == NULL) { + subreq = SMB_VFS_NEXT_FSYNC_SEND(state, ev, handle, fsp); + if (tevent_req_nomem(req, subreq)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, streams_xattr_fsync_done, req); + return req; + } + + /* + * There's no pathname based sync variant and we don't have access to + * the basefile handle, so we can't do anything here. + */ + + tevent_req_done(req); + return tevent_req_post(req, ev); +} + +static void streams_xattr_fsync_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct streams_xattr_fsync_state *state = tevent_req_data( + req, struct streams_xattr_fsync_state); + + state->ret = SMB_VFS_FSYNC_RECV(subreq, &state->vfs_aio_state); + TALLOC_FREE(subreq); + if (state->ret != 0) { + tevent_req_error(req, errno); + return; + } + + tevent_req_done(req); +} + +static int streams_xattr_fsync_recv(struct tevent_req *req, + struct vfs_aio_state *vfs_aio_state) +{ + struct streams_xattr_fsync_state *state = tevent_req_data( + req, struct streams_xattr_fsync_state); + + if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) { + return -1; + } + + *vfs_aio_state = state->vfs_aio_state; + return state->ret; +} + +static bool streams_xattr_lock(vfs_handle_struct *handle, + files_struct *fsp, + int op, + off_t offset, + off_t count, + int type) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type); + } + + return true; +} + +static bool streams_xattr_getlock(vfs_handle_struct *handle, + files_struct *fsp, + off_t *poffset, + off_t *pcount, + int *ptype, + pid_t *ppid) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, + pcount, ptype, ppid); + } + + errno = ENOTSUP; + return false; +} + +static int streams_xattr_kernel_flock(vfs_handle_struct *handle, + files_struct *fsp, + uint32_t share_mode, + uint32_t access_mask) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, + share_mode, access_mask); + } + + return 0; +} + +static int streams_xattr_linux_setlease(vfs_handle_struct *handle, + files_struct *fsp, + int leasetype) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_LINUX_SETLEASE(handle, fsp, leasetype); + } + + return 0; +} + +static bool streams_xattr_strict_lock_check(struct vfs_handle_struct *handle, + files_struct *fsp, + struct lock_struct *plock) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_STRICT_LOCK_CHECK(handle, fsp, plock); + } + + return true; +} + +static NTSTATUS streams_xattr_get_compression(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + struct smb_filename *smb_fname, + uint16_t *_compression_fmt) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_GET_COMPRESSION(handle, mem_ctx, fsp, + smb_fname, _compression_fmt); + } + + *_compression_fmt = COMPRESSION_FORMAT_NONE; + return NT_STATUS_OK; +} + +static NTSTATUS streams_xattr_set_compression(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + uint16_t compression_fmt) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (sio == NULL) { + return SMB_VFS_NEXT_SET_COMPRESSION(handle, mem_ctx, fsp, + compression_fmt); + } + + return NT_STATUS_NOT_SUPPORTED; +} static struct vfs_fn_pointers vfs_streams_xattr_fns = { .fs_capabilities_fn = streams_xattr_fs_capabilities, @@ -1341,6 +1732,36 @@ static struct vfs_fn_pointers vfs_streams_xattr_fns = { .ftruncate_fn = streams_xattr_ftruncate, .fallocate_fn = streams_xattr_fallocate, .streaminfo_fn = streams_xattr_streaminfo, + + .fsync_send_fn = streams_xattr_fsync_send, + .fsync_recv_fn = streams_xattr_fsync_recv, + + .lock_fn = streams_xattr_lock, + .getlock_fn = streams_xattr_getlock, + .kernel_flock_fn = streams_xattr_kernel_flock, + .linux_setlease_fn = streams_xattr_linux_setlease, + .strict_lock_check_fn = streams_xattr_strict_lock_check, + + .get_compression_fn = streams_xattr_get_compression, + .set_compression_fn = streams_xattr_set_compression, + + .fchown_fn = streams_xattr_fchown, + .fchmod_fn = streams_xattr_fchmod, + .fsync_fn = streams_xattr_fsync, + + .fgetxattr_fn = streams_xattr_fgetxattr, + .flistxattr_fn = streams_xattr_flistxattr, + .fremovexattr_fn = streams_xattr_fremovexattr, + .fsetxattr_fn = streams_xattr_fsetxattr, + + .fchmod_acl_fn = streams_xattr_fchmod_acl, + + .sys_acl_get_fd_fn = streams_xattr_sys_acl_get_fd, + .sys_acl_blob_get_fd_fn = streams_xattr_sys_acl_blob_get_fd, + .sys_acl_set_fd_fn = streams_xattr_sys_acl_set_fd, + + .fget_nt_acl_fn = streams_xattr_fget_nt_acl, + .fset_nt_acl_fn = streams_xattr_fset_nt_acl, }; NTSTATUS vfs_streams_xattr_init(TALLOC_CTX *);