s3: vfs: add SMB_VFS_GETXATTRAT_SEND/RECV
authorRalph Boehme <slow@samba.org>
Tue, 13 Mar 2018 07:14:53 +0000 (08:14 +0100)
committerRalph Boehme <slow@samba.org>
Fri, 27 Jul 2018 11:07:14 +0000 (13:07 +0200)
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
21 files changed:
examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/include/smbprofile.h
source3/include/vfs.h
source3/include/vfs_macros.h
source3/modules/vfs_cap.c
source3/modules/vfs_catia.c
source3/modules/vfs_ceph.c
source3/modules/vfs_default.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_glusterfs.c
source3/modules/vfs_media_harmony.c
source3/modules/vfs_not_implemented.c
source3/modules/vfs_posix_eadb.c
source3/modules/vfs_shadow_copy2.c
source3/modules/vfs_snapper.c
source3/modules/vfs_time_audit.c
source3/modules/vfs_unityed_media.c
source3/modules/vfs_vxfs.c
source3/modules/vfs_xattr_tdb.c
source3/smbd/vfs.c

index 6fc4d58022e13c335ea1f96aaf0ad1723ada9623..971303436b01e9cc8ceaaeddd697b00a59549bef 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include "../source3/include/includes.h"
+#include "lib/util/tevent_unix.h"
 #include "lib/util/tevent_ntstatus.h"
 
 /* PLEASE,PLEASE READ THE VFS MODULES CHAPTER OF THE 
@@ -818,6 +819,59 @@ static ssize_t skel_getxattr(vfs_handle_struct *handle,
        return -1;
 }
 
+struct skel_getxattrat_state {
+       struct vfs_aio_state aio_state;
+       ssize_t xattr_size;
+       uint8_t *xattr_value;
+};
+
+static struct tevent_req *skel_getxattrat_send(
+                       TALLOC_CTX *mem_ctx,
+                       const struct smb_vfs_ev_glue *evg,
+                       struct vfs_handle_struct *handle,
+                       files_struct *dir_fsp,
+                       const struct smb_filename *smb_fname,
+                       const char *xattr_name,
+                       size_t alloc_hint)
+{
+       struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
+       struct tevent_req *req = NULL;
+       struct skel_getxattrat_state *state = NULL;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct skel_getxattrat_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       tevent_req_error(req, ENOSYS);
+       return tevent_req_post(req, ev);
+}
+
+static ssize_t skel_getxattrat_recv(struct tevent_req *req,
+                                   struct vfs_aio_state *aio_state,
+                                   TALLOC_CTX *mem_ctx,
+                                   uint8_t **xattr_value)
+{
+       struct skel_getxattrat_state *state = tevent_req_data(
+               req, struct skel_getxattrat_state);
+       ssize_t xattr_size;
+
+       if (tevent_req_is_unix_error(req, &aio_state->error)) {
+               tevent_req_received(req);
+               return -1;
+       }
+
+       *aio_state = state->aio_state;
+       xattr_size = state->xattr_size;
+       if (xattr_value != NULL) {
+               *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
+       }
+
+       tevent_req_received(req);
+       return xattr_size;
+}
+
 static ssize_t skel_fgetxattr(vfs_handle_struct *handle,
                              struct files_struct *fsp, const char *name,
                              void *value, size_t size)
@@ -1037,6 +1091,8 @@ static struct vfs_fn_pointers skel_opaque_fns = {
 
        /* EA operations. */
        .getxattr_fn = skel_getxattr,
+       .getxattrat_send_fn = skel_getxattrat_send,
+       .getxattrat_recv_fn = skel_getxattrat_recv,
        .fgetxattr_fn = skel_fgetxattr,
        .listxattr_fn = skel_listxattr,
        .flistxattr_fn = skel_flistxattr,
index d84e6deee479feae075f1c9b13f8bb769804c561..503c14edcc0ab25a42176a357dd7f6e4be3cdce1 100644 (file)
@@ -1004,6 +1004,93 @@ static ssize_t skel_getxattr(vfs_handle_struct *handle,
        return SMB_VFS_NEXT_GETXATTR(handle, smb_fname, name, value, size);
 }
 
+struct skel_getxattrat_state {
+       struct vfs_aio_state aio_state;
+       ssize_t xattr_size;
+       uint8_t *xattr_value;
+};
+
+static void skel_getxattrat_done(struct tevent_req *subreq);
+
+static struct tevent_req *skel_getxattrat_send(
+                       TALLOC_CTX *mem_ctx,
+                       const struct smb_vfs_ev_glue *evg,
+                       struct vfs_handle_struct *handle,
+                       files_struct *dir_fsp,
+                       const struct smb_filename *smb_fname,
+                       const char *xattr_name,
+                       size_t alloc_hint)
+{
+       struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
+       struct tevent_req *req = NULL;
+       struct skel_getxattrat_state *state = NULL;
+       struct tevent_req *subreq = NULL;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct skel_getxattrat_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       subreq = SMB_VFS_NEXT_GETXATTRAT_SEND(state,
+                                             evg,
+                                             handle,
+                                             dir_fsp,
+                                             smb_fname,
+                                             xattr_name,
+                                             alloc_hint);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, skel_getxattrat_done, req);
+
+       return req;
+}
+
+static void skel_getxattrat_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct skel_getxattrat_state *state = tevent_req_data(
+               req, struct skel_getxattrat_state);
+
+       state->xattr_size = SMB_VFS_NEXT_GETXATTRAT_RECV(subreq,
+                                                        &state->aio_state,
+                                                        state,
+                                                        &state->xattr_value);
+       TALLOC_FREE(subreq);
+       if (state->xattr_size == -1) {
+               tevent_req_error(req, state->aio_state.error);
+               return;
+       }
+
+       tevent_req_done(req);
+}
+
+static ssize_t skel_getxattrat_recv(struct tevent_req *req,
+                                   struct vfs_aio_state *aio_state,
+                                   TALLOC_CTX *mem_ctx,
+                                   uint8_t **xattr_value)
+{
+       struct skel_getxattrat_state *state = tevent_req_data(
+               req, struct skel_getxattrat_state);
+       ssize_t xattr_size;
+
+       if (tevent_req_is_unix_error(req, &aio_state->error)) {
+               tevent_req_received(req);
+               return -1;
+       }
+
+       *aio_state = state->aio_state;
+       xattr_size = state->xattr_size;
+       if (xattr_value != NULL) {
+               *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
+       }
+
+       tevent_req_received(req);
+       return xattr_size;
+}
+
 static ssize_t skel_fgetxattr(vfs_handle_struct *handle,
                              struct files_struct *fsp, const char *name,
                              void *value, size_t size)
@@ -1233,6 +1320,8 @@ static struct vfs_fn_pointers skel_transparent_fns = {
 
        /* EA operations. */
        .getxattr_fn = skel_getxattr,
+       .getxattrat_send_fn = skel_getxattrat_send,
+       .getxattrat_recv_fn = skel_getxattrat_recv,
        .fgetxattr_fn = skel_fgetxattr,
        .listxattr_fn = skel_listxattr,
        .flistxattr_fn = skel_flistxattr,
index e33f77e70e353359d0a958aebff0706d77df2773..8888ae3eaa85a115f05d12fc2b5a8f70a856a8a9 100644 (file)
@@ -95,6 +95,7 @@ struct tevent_context;
        SMBPROFILE_STATS_BASIC(syscall_brl_lock) \
        SMBPROFILE_STATS_BASIC(syscall_brl_unlock) \
        SMBPROFILE_STATS_BASIC(syscall_brl_cancel) \
+       SMBPROFILE_STATS_BYTES(syscall_asys_getxattrat) \
        SMBPROFILE_STATS_SECTION_END \
        \
        SMBPROFILE_STATS_SECTION_START(acl, "ACL Calls") \
index 3d3718d7c075d0b751045757cf6003280d00e6cd..def802c9772b78c59d276ed152225c1de09ec3a5 100644 (file)
 /* Bump to version 40, Samba 4.10 will ship with that */
 /* Version 40 - Introduce smb_vfs_ev_glue infrastructure. */
 /* Version 40 - Add vfs_not_implemented_* helper functions. */
+/* Version 40 - Add SMB_VFS_GETXATTRAT_SEND/RECV */
 
 #define SMB_VFS_INTERFACE_VERSION 40
 
@@ -953,6 +954,18 @@ struct vfs_fn_pointers {
                                        const char *name,
                                        void *value,
                                        size_t size);
+       struct tevent_req *(*getxattrat_send_fn)(
+                               TALLOC_CTX *mem_ctx,
+                               const struct smb_vfs_ev_glue *evg,
+                               struct vfs_handle_struct *handle,
+                               files_struct *dir_fsp,
+                               const struct smb_filename *smb_fname,
+                               const char *xattr_name,
+                               size_t alloc_hint);
+       ssize_t (*getxattrat_recv_fn)(struct tevent_req *req,
+                                     struct vfs_aio_state *aio_state,
+                                     TALLOC_CTX *mem_ctx,
+                                     uint8_t **xattr_value);
        ssize_t (*fgetxattr_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size);
        ssize_t (*listxattr_fn)(struct vfs_handle_struct *handle,
                                        const struct smb_filename *smb_fname,
@@ -1443,6 +1456,18 @@ ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
                                const char *name,
                                void *value,
                                size_t size);
+struct tevent_req *smb_vfs_call_getxattrat_send(
+                       TALLOC_CTX *mem_ctx,
+                       const struct smb_vfs_ev_glue *evg,
+                       struct vfs_handle_struct *handle,
+                       files_struct *dir_fsp,
+                       const struct smb_filename *smb_fname,
+                       const char *xattr_name,
+                       size_t alloc_hint);
+ssize_t smb_vfs_call_getxattrat_recv(struct tevent_req *req,
+                                    struct vfs_aio_state *aio_state,
+                                    TALLOC_CTX *mem_ctx,
+                                    uint8_t **xattr_value);
 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
                               struct files_struct *fsp, const char *name,
                               void *value, size_t size);
@@ -1850,6 +1875,18 @@ ssize_t vfs_not_implemented_getxattr(vfs_handle_struct *handle,
                                const char *name,
                                void *value,
                                size_t size);
+struct tevent_req *vfs_not_implemented_getxattrat_send(
+                       TALLOC_CTX *mem_ctx,
+                       const struct smb_vfs_ev_glue *evg,
+                       struct vfs_handle_struct *handle,
+                       files_struct *dir_fsp,
+                       const struct smb_filename *smb_fname,
+                       const char *xattr_name,
+                       size_t alloc_hint);
+ssize_t vfs_not_implemented_getxattrat_recv(struct tevent_req *req,
+                                   struct vfs_aio_state *aio_state,
+                                   TALLOC_CTX *mem_ctx,
+                                   uint8_t **xattr_value);
 ssize_t vfs_not_implemented_fgetxattr(vfs_handle_struct *handle,
                              struct files_struct *fsp, const char *name,
                              void *value, size_t size);
index 46d6728629c33daaab7ad523e88cb43ea96e8980..d4863536cc22a3a8625e2b036c7f066a2851377a 100644 (file)
 #define SMB_VFS_NEXT_GETXATTR(handle,smb_fname,name,value,size) \
        smb_vfs_call_getxattr((handle)->next,(smb_fname),(name),(value),(size))
 
+#define SMB_VFS_GETXATTRAT_SEND(mem_ctx,evg,dir_fsp,smb_fname, \
+                               xattr_name, alloc_hint) \
+       smb_vfs_call_getxattrat_send((mem_ctx),(evg), \
+                                    (dir_fsp)->conn->vfs_handles, \
+                                    (dir_fsp),(smb_fname),(xattr_name), \
+                                    (alloc_hint))
+#define SMB_VFS_GETXATTRAT_RECV(req, aio_state, mem_ctx, xattr_value) \
+       smb_vfs_call_getxattrat_recv((req),(aio_state),(mem_ctx),(xattr_value))
+
+#define SMB_VFS_NEXT_GETXATTRAT_SEND(mem_ctx,evg,handle,dir_fsp,smb_fname, \
+                                    xattr_name,alloc_hint) \
+       smb_vfs_call_getxattrat_send((mem_ctx),(evg), \
+                                    (handle)->next, \
+                                    (dir_fsp), (smb_fname),(xattr_name), \
+                                    (alloc_hint))
+#define SMB_VFS_NEXT_GETXATTRAT_RECV(req, aio_state, mem_ctx, xattr_value) \
+       smb_vfs_call_getxattrat_recv((req),(aio_state),(mem_ctx),(xattr_value))
+
 #define SMB_VFS_FGETXATTR(fsp,name,value,size) \
        smb_vfs_call_fgetxattr((fsp)->conn->vfs_handles, (fsp), (name),(value),(size))
 #define SMB_VFS_NEXT_FGETXATTR(handle,fsp,name,value,size) \
index ffc35d60407372656366116bed75a27ab02c51c2..56b7efe1b42ac9c0b71ee635f93c835b94c06fff 100644 (file)
@@ -1027,6 +1027,8 @@ static struct vfs_fn_pointers vfs_cap_fns = {
        .sys_acl_set_file_fn = cap_sys_acl_set_file,
        .sys_acl_delete_def_file_fn = cap_sys_acl_delete_def_file,
        .getxattr_fn = cap_getxattr,
+       .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
+       .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
        .fgetxattr_fn = cap_fgetxattr,
        .listxattr_fn = cap_listxattr,
        .removexattr_fn = cap_removexattr,
index fce2dcf8ca59d3d943189a39eb48d2f2c0820224..d2dddaf692136a7c6500251e89610088ca3499ee 100644 (file)
@@ -2468,6 +2468,8 @@ static struct vfs_fn_pointers vfs_catia_fns = {
 
        /* EA operations. */
        .getxattr_fn = catia_getxattr,
+       .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
+       .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
        .listxattr_fn = catia_listxattr,
        .removexattr_fn = catia_removexattr,
        .setxattr_fn = catia_setxattr,
index 47371bc9e08201d12ccdb9f3ba28996a50d15431..8b709eddc908473a19ef951e89cfa0d7daf886b9 100644 (file)
@@ -1528,6 +1528,8 @@ static struct vfs_fn_pointers ceph_fns = {
 
        /* EA operations. */
        .getxattr_fn = cephwrap_getxattr,
+       .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
+       .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
        .fgetxattr_fn = cephwrap_fgetxattr,
        .listxattr_fn = cephwrap_listxattr,
        .flistxattr_fn = cephwrap_flistxattr,
index 72dbd75673590e8ab7179ca0c900bd4dc59f6f9a..d985cba9cb7f9c3ea67e4c124f3fbed14f122de7 100644 (file)
@@ -2986,6 +2986,8 @@ static struct vfs_fn_pointers vfs_default_fns = {
 
        /* EA operations. */
        .getxattr_fn = vfswrap_getxattr,
+       .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
+       .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
        .fgetxattr_fn = vfswrap_fgetxattr,
        .listxattr_fn = vfswrap_listxattr,
        .flistxattr_fn = vfswrap_flistxattr,
index bd904e8ef875cd3020d2cb39fc3f8bfec893466f..f28413b83c28d6fe5d5c3dfe7ce0bebb927a0ce5 100644 (file)
@@ -201,6 +201,8 @@ typedef enum _vfs_op_type {
 
        /* EA operations. */
        SMB_VFS_OP_GETXATTR,
+       SMB_VFS_OP_GETXATTRAT_SEND,
+       SMB_VFS_OP_GETXATTRAT_RECV,
        SMB_VFS_OP_FGETXATTR,
        SMB_VFS_OP_LISTXATTR,
        SMB_VFS_OP_FLISTXATTR,
@@ -330,6 +332,8 @@ static struct {
        { SMB_VFS_OP_SYS_ACL_SET_FD,    "sys_acl_set_fd" },
        { SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,   "sys_acl_delete_def_file" },
        { SMB_VFS_OP_GETXATTR,  "getxattr" },
+       { SMB_VFS_OP_GETXATTRAT_SEND, "getxattrat_send" },
+       { SMB_VFS_OP_GETXATTRAT_RECV, "getxattrat_recv" },
        { SMB_VFS_OP_FGETXATTR, "fgetxattr" },
        { SMB_VFS_OP_LISTXATTR, "listxattr" },
        { SMB_VFS_OP_FLISTXATTR,        "flistxattr" },
@@ -2317,6 +2321,140 @@ static ssize_t smb_full_audit_getxattr(struct vfs_handle_struct *handle,
        return result;
 }
 
+struct smb_full_audit_getxattrat_state {
+       struct vfs_aio_state aio_state;
+       vfs_handle_struct *handle;
+       files_struct *dir_fsp;
+       const struct smb_filename *smb_fname;
+       const char *xattr_name;
+       ssize_t xattr_size;
+       uint8_t *xattr_value;
+};
+
+static void smb_full_audit_getxattrat_done(struct tevent_req *subreq);
+
+static struct tevent_req *smb_full_audit_getxattrat_send(
+                       TALLOC_CTX *mem_ctx,
+                       const struct smb_vfs_ev_glue *evg,
+                       struct vfs_handle_struct *handle,
+                       files_struct *dir_fsp,
+                       const struct smb_filename *smb_fname,
+                       const char *xattr_name,
+                       size_t alloc_hint)
+{
+       struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
+       struct tevent_req *req = NULL;
+       struct tevent_req *subreq = NULL;
+       struct smb_full_audit_getxattrat_state *state = NULL;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct smb_full_audit_getxattrat_state);
+       if (req == NULL) {
+               do_log(SMB_VFS_OP_GETXATTRAT_SEND,
+                      false,
+                      handle,
+                      "%s/%s|%s",
+                      fsp_str_do_log(dir_fsp),
+                      smb_fname->base_name,
+                      xattr_name);
+               return NULL;
+       }
+       *state = (struct smb_full_audit_getxattrat_state) {
+               .handle = handle,
+               .dir_fsp = dir_fsp,
+               .smb_fname = smb_fname,
+               .xattr_name = xattr_name,
+       };
+
+       subreq = SMB_VFS_NEXT_GETXATTRAT_SEND(state,
+                                             evg,
+                                             handle,
+                                             dir_fsp,
+                                             smb_fname,
+                                             xattr_name,
+                                             alloc_hint);
+       if (tevent_req_nomem(subreq, req)) {
+               do_log(SMB_VFS_OP_GETXATTRAT_SEND,
+                      false,
+                      handle,
+                      "%s/%s|%s",
+                      fsp_str_do_log(dir_fsp),
+                      smb_fname->base_name,
+                      xattr_name);
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, smb_full_audit_getxattrat_done, req);
+
+       do_log(SMB_VFS_OP_GETXATTRAT_SEND,
+              true,
+              handle,
+              "%s/%s|%s",
+              fsp_str_do_log(dir_fsp),
+              smb_fname->base_name,
+              xattr_name);
+
+       return req;
+}
+
+static void smb_full_audit_getxattrat_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct smb_full_audit_getxattrat_state *state = tevent_req_data(
+               req, struct smb_full_audit_getxattrat_state);
+
+       state->xattr_size = SMB_VFS_NEXT_GETXATTRAT_RECV(subreq,
+                                                        &state->aio_state,
+                                                        state,
+                                                        &state->xattr_value);
+       TALLOC_FREE(subreq);
+       if (state->xattr_size == -1) {
+               tevent_req_error(req, state->aio_state.error);
+               return;
+       }
+
+       tevent_req_done(req);
+}
+
+static ssize_t smb_full_audit_getxattrat_recv(struct tevent_req *req,
+                                             struct vfs_aio_state *aio_state,
+                                             TALLOC_CTX *mem_ctx,
+                                             uint8_t **xattr_value)
+{
+       struct smb_full_audit_getxattrat_state *state = tevent_req_data(
+               req, struct smb_full_audit_getxattrat_state);
+       ssize_t xattr_size;
+
+       if (tevent_req_is_unix_error(req, &aio_state->error)) {
+               do_log(SMB_VFS_OP_GETXATTRAT_RECV,
+                      false,
+                      state->handle,
+                      "%s/%s|%s",
+                      fsp_str_do_log(state->dir_fsp),
+                      state->smb_fname->base_name,
+                      state->xattr_name);
+               tevent_req_received(req);
+               return -1;
+       }
+
+       do_log(SMB_VFS_OP_GETXATTRAT_RECV,
+              true,
+              state->handle,
+              "%s/%s|%s",
+              fsp_str_do_log(state->dir_fsp),
+              state->smb_fname->base_name,
+              state->xattr_name);
+
+       *aio_state = state->aio_state;
+       xattr_size = state->xattr_size;
+       if (xattr_value != NULL) {
+               *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
+       }
+
+       tevent_req_received(req);
+       return xattr_size;
+}
+
 static ssize_t smb_full_audit_fgetxattr(struct vfs_handle_struct *handle,
                               struct files_struct *fsp,
                               const char *name, void *value, size_t size)
@@ -2593,6 +2731,8 @@ static struct vfs_fn_pointers vfs_full_audit_fns = {
        .sys_acl_set_fd_fn = smb_full_audit_sys_acl_set_fd,
        .sys_acl_delete_def_file_fn = smb_full_audit_sys_acl_delete_def_file,
        .getxattr_fn = smb_full_audit_getxattr,
+       .getxattrat_send_fn = smb_full_audit_getxattrat_send,
+       .getxattrat_recv_fn = smb_full_audit_getxattrat_recv,
        .fgetxattr_fn = smb_full_audit_fgetxattr,
        .listxattr_fn = smb_full_audit_listxattr,
        .flistxattr_fn = smb_full_audit_flistxattr,
index 02289a64e5051aa57321441bdcd011c430e98ff3..98be3c6d4e2a7bf6123987269380f9098f4fb627 100644 (file)
@@ -1542,6 +1542,8 @@ static struct vfs_fn_pointers glusterfs_fns = {
 
        /* EA Operations */
        .getxattr_fn = vfs_gluster_getxattr,
+       .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
+       .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
        .fgetxattr_fn = vfs_gluster_fgetxattr,
        .listxattr_fn = vfs_gluster_listxattr,
        .flistxattr_fn = vfs_gluster_flistxattr,
index 32ba45a7fe8922f717cf7f82c12c441dbec3ab45..ea49eff6d8ff1bb09fb43407c0978883a579c386 100644 (file)
@@ -2311,6 +2311,8 @@ static struct vfs_fn_pointers vfs_mh_fns = {
 
        /* EA operations. */
        .getxattr_fn = mh_getxattr,
+       .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
+       .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
        .listxattr_fn = mh_listxattr,
        .removexattr_fn = mh_removexattr,
        .setxattr_fn = mh_setxattr,
index 45c3a01c9f57707d3c16a3363b7eac537413c18f..bb4854d8bf8cf5ca27ff4c5a0dde418b67d18bf2 100644 (file)
@@ -822,6 +822,59 @@ ssize_t vfs_not_implemented_getxattr(vfs_handle_struct *handle,
        return -1;
 }
 
+struct vfs_not_implemented_getxattrat_state {
+       struct vfs_aio_state aio_state;
+       ssize_t xattr_size;
+       uint8_t *xattr_value;
+};
+
+struct tevent_req *vfs_not_implemented_getxattrat_send(
+                       TALLOC_CTX *mem_ctx,
+                       const struct smb_vfs_ev_glue *evg,
+                       struct vfs_handle_struct *handle,
+                       files_struct *dir_fsp,
+                       const struct smb_filename *smb_fname,
+                       const char *xattr_name,
+                       size_t alloc_hint)
+{
+       struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
+       struct tevent_req *req = NULL;
+       struct vfs_not_implemented_getxattrat_state *state = NULL;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct vfs_not_implemented_getxattrat_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       tevent_req_error(req, ENOSYS);
+       return tevent_req_post(req, ev);
+}
+
+ssize_t vfs_not_implemented_getxattrat_recv(struct tevent_req *req,
+                                   struct vfs_aio_state *aio_state,
+                                   TALLOC_CTX *mem_ctx,
+                                   uint8_t **xattr_value)
+{
+       struct vfs_not_implemented_getxattrat_state *state = tevent_req_data(
+               req, struct vfs_not_implemented_getxattrat_state);
+       ssize_t xattr_size;
+
+       if (tevent_req_is_unix_error(req, &aio_state->error)) {
+               tevent_req_received(req);
+               return -1;
+       }
+
+       *aio_state = state->aio_state;
+       xattr_size = state->xattr_size;
+       if (xattr_value != NULL) {
+               *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
+       }
+
+       tevent_req_received(req);
+       return xattr_size;
+}
+
 ssize_t vfs_not_implemented_fgetxattr(vfs_handle_struct *handle,
                              struct files_struct *fsp, const char *name,
                              void *value, size_t size)
@@ -1041,6 +1094,8 @@ static struct vfs_fn_pointers vfs_not_implemented_fns = {
 
        /* EA operations. */
        .getxattr_fn = vfs_not_implemented_getxattr,
+       .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
+       .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
        .fgetxattr_fn = vfs_not_implemented_fgetxattr,
        .listxattr_fn = vfs_not_implemented_listxattr,
        .flistxattr_fn = vfs_not_implemented_flistxattr,
index 889655e52ce053235eed1111afe2215cba235554..44bef9f9d82e6b2a647e736079a31c345b3684a4 100644 (file)
@@ -431,6 +431,8 @@ static int posix_eadb_connect(vfs_handle_struct *handle, const char *service,
 
 static struct vfs_fn_pointers vfs_posix_eadb_fns = {
        .getxattr_fn = posix_eadb_getxattr,
+       .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
+       .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
        .fgetxattr_fn = posix_eadb_fgetxattr,
        .setxattr_fn = posix_eadb_setxattr,
        .fsetxattr_fn = posix_eadb_fsetxattr,
index aa7cd9c61d0fd6d9e51ed73fe46aa75fa94fc779..79c1ee5cf3378e4d018f4a4e79fbe7fa1ece8b2c 100644 (file)
@@ -3212,6 +3212,8 @@ static struct vfs_fn_pointers vfs_shadow_copy2_fns = {
        .mkdir_fn = shadow_copy2_mkdir,
        .rmdir_fn = shadow_copy2_rmdir,
        .getxattr_fn = shadow_copy2_getxattr,
+       .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
+       .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
        .listxattr_fn = shadow_copy2_listxattr,
        .removexattr_fn = shadow_copy2_removexattr,
        .setxattr_fn = shadow_copy2_setxattr,
index 6b935c3df41e392e4d69abc932f7a49d37bc4064..443a940b17a8a2e787b6ff4c2d6b68511df17db7 100644 (file)
@@ -3125,6 +3125,8 @@ static struct vfs_fn_pointers snapper_fns = {
        .mkdir_fn = snapper_gmt_mkdir,
        .rmdir_fn = snapper_gmt_rmdir,
        .getxattr_fn = snapper_gmt_getxattr,
+       .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
+       .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
        .listxattr_fn = snapper_gmt_listxattr,
        .removexattr_fn = snapper_gmt_removexattr,
        .setxattr_fn = snapper_gmt_setxattr,
index e85ded5e4c360aa5d579a21ead117b939c731d31..07c14415312fb6a13d89b36dcad0448046b82047 100644 (file)
@@ -86,6 +86,23 @@ static void smb_time_audit_log_fsp(const char *syscallname, double elapsed,
        TALLOC_FREE(msg);
 }
 
+static void smb_time_audit_log_at(const char *syscallname,
+                                 double elapsed,
+                                 const struct files_struct *dir_fsp,
+                                 const struct smb_filename *smb_fname)
+{
+       char *msg = NULL;
+
+       msg = talloc_asprintf(talloc_tos(),
+                             "filename = \"%s/%s/%s\"",
+                             dir_fsp->conn->connectpath,
+                             dir_fsp->fsp_name->base_name,
+                             smb_fname->base_name);
+
+       smb_time_audit_log_msg(syscallname, elapsed, msg);
+       TALLOC_FREE(msg);
+}
+
 static void smb_time_audit_log_fname(const char *syscallname, double elapsed,
                                    const char *fname)
 {
@@ -2334,6 +2351,111 @@ static ssize_t smb_time_audit_getxattr(struct vfs_handle_struct *handle,
        return result;
 }
 
+struct smb_time_audit_getxattrat_state {
+       struct vfs_aio_state aio_state;
+       files_struct *dir_fsp;
+       const struct smb_filename *smb_fname;
+       const char *xattr_name;
+       ssize_t xattr_size;
+       uint8_t *xattr_value;
+};
+
+static void smb_time_audit_getxattrat_done(struct tevent_req *subreq);
+
+static struct tevent_req *smb_time_audit_getxattrat_send(
+                       TALLOC_CTX *mem_ctx,
+                       const struct smb_vfs_ev_glue *evg,
+                       struct vfs_handle_struct *handle,
+                       files_struct *dir_fsp,
+                       const struct smb_filename *smb_fname,
+                       const char *xattr_name,
+                       size_t alloc_hint)
+{
+       struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg);
+       struct tevent_req *req = NULL;
+       struct tevent_req *subreq = NULL;
+       struct smb_time_audit_getxattrat_state *state = NULL;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct smb_time_audit_getxattrat_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       *state = (struct smb_time_audit_getxattrat_state) {
+               .dir_fsp = dir_fsp,
+               .smb_fname = smb_fname,
+               .xattr_name = xattr_name,
+       };
+
+       subreq = SMB_VFS_NEXT_GETXATTRAT_SEND(state,
+                                             evg,
+                                             handle,
+                                             dir_fsp,
+                                             smb_fname,
+                                             xattr_name,
+                                             alloc_hint);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, smb_time_audit_getxattrat_done, req);
+
+       return req;
+}
+
+static void smb_time_audit_getxattrat_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct smb_time_audit_getxattrat_state *state = tevent_req_data(
+               req, struct smb_time_audit_getxattrat_state);
+
+       state->xattr_size = SMB_VFS_NEXT_GETXATTRAT_RECV(subreq,
+                                                        &state->aio_state,
+                                                        state,
+                                                        &state->xattr_value);
+       TALLOC_FREE(subreq);
+       if (state->xattr_size == -1) {
+               tevent_req_error(req, state->aio_state.error);
+               return;
+       }
+
+       tevent_req_done(req);
+}
+
+static ssize_t smb_time_audit_getxattrat_recv(struct tevent_req *req,
+                                             struct vfs_aio_state *aio_state,
+                                             TALLOC_CTX *mem_ctx,
+                                             uint8_t **xattr_value)
+{
+       struct smb_time_audit_getxattrat_state *state = tevent_req_data(
+               req, struct smb_time_audit_getxattrat_state);
+       ssize_t xattr_size;
+       double timediff;
+
+       timediff = state->aio_state.duration * 1.0e-9;
+
+       if (timediff > audit_timeout) {
+               smb_time_audit_log_at("async getxattrat",
+                                     timediff,
+                                     state->dir_fsp,
+                                     state->smb_fname);
+       }
+
+       if (tevent_req_is_unix_error(req, &aio_state->error)) {
+               tevent_req_received(req);
+               return -1;
+       }
+
+       *aio_state = state->aio_state;
+       xattr_size = state->xattr_size;
+       if (xattr_value != NULL) {
+               *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
+       }
+
+       tevent_req_received(req);
+       return xattr_size;
+}
+
 static ssize_t smb_time_audit_fgetxattr(struct vfs_handle_struct *handle,
                                        struct files_struct *fsp,
                                        const char *name, void *value,
@@ -2667,6 +2789,8 @@ static struct vfs_fn_pointers vfs_time_audit_fns = {
        .sys_acl_set_fd_fn = smb_time_audit_sys_acl_set_fd,
        .sys_acl_delete_def_file_fn = smb_time_audit_sys_acl_delete_def_file,
        .getxattr_fn = smb_time_audit_getxattr,
+       .getxattrat_send_fn = smb_time_audit_getxattrat_send,
+       .getxattrat_recv_fn = smb_time_audit_getxattrat_recv,
        .fgetxattr_fn = smb_time_audit_fgetxattr,
        .listxattr_fn = smb_time_audit_listxattr,
        .flistxattr_fn = smb_time_audit_flistxattr,
index 328a93d7043666c8efb36fd2661fdb25c7f9413e..235adf523a3d058d2729f7e35fda6ac28e9f5bfe 100644 (file)
@@ -1904,6 +1904,8 @@ static struct vfs_fn_pointers vfs_um_fns = {
 
        /* EA operations. */
        .getxattr_fn = um_getxattr,
+       .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
+       .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
        .listxattr_fn = um_listxattr,
        .removexattr_fn = um_removexattr,
        .setxattr_fn = um_setxattr,
index 1295c7541e79ffdd162643ad80583827b1f3ae3f..5baa38568676f2b1ae71594bb03ab9176e5f3f73 100644 (file)
@@ -944,6 +944,8 @@ static struct vfs_fn_pointers vfs_vxfs_fns = {
        .set_dos_attributes_fn = vxfs_set_ea_dos_attributes,
        .fset_dos_attributes_fn = vxfs_fset_ea_dos_attributes,
        .getxattr_fn = vxfs_get_xattr,
+       .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
+       .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
        .fgetxattr_fn = vxfs_fget_xattr,
        .listxattr_fn = vxfs_listxattr,
        .flistxattr_fn = vxfs_flistxattr,
index a8b3ee2174a00deea837ac0aeec2b4afbc560002..ceed3a9cbf8b27ce6c02268e9c934d8eb3260e5a 100644 (file)
@@ -602,6 +602,8 @@ static int xattr_tdb_connect(vfs_handle_struct *handle, const char *service,
 
 static struct vfs_fn_pointers vfs_xattr_tdb_fns = {
        .getxattr_fn = xattr_tdb_getxattr,
+       .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
+       .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
        .fgetxattr_fn = xattr_tdb_fgetxattr,
        .setxattr_fn = xattr_tdb_setxattr,
        .fsetxattr_fn = xattr_tdb_fsetxattr,
index a0fc005dad3dc901f131e5de4e1a44118b216710..501eafe1c02853506c97e89a216dc7b62a7255ae 100644 (file)
@@ -2287,7 +2287,6 @@ struct smb_vfs_ev_glue *smb_vfs_ev_glue_create_switch(
        return evg_u;
 }
 
-_UNUSED_
 static bool smb_vfs_ev_glue_push_use(const struct smb_vfs_ev_glue *evg,
                                     struct tevent_req *req)
 {
@@ -2312,7 +2311,6 @@ static bool smb_vfs_ev_glue_push_use(const struct smb_vfs_ev_glue *evg,
        return tevent_context_push_use(evg->run_ev);
 }
 
-_UNUSED_
 static void smb_vfs_ev_glue_pop_use(const struct smb_vfs_ev_glue *evg)
 {
        if (evg->run_ev == evg->return_ev) {
@@ -3427,6 +3425,108 @@ ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
        return handle->fns->getxattr_fn(handle, smb_fname, name, value, size);
 }
 
+
+struct smb_vfs_call_getxattrat_state {
+       ssize_t (*recv_fn)(struct tevent_req *req,
+                          struct vfs_aio_state *aio_state,
+                          TALLOC_CTX *mem_ctx,
+                          uint8_t **xattr_value);
+       ssize_t retval;
+       uint8_t *xattr_value;
+       struct vfs_aio_state aio_state;
+};
+
+static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq);
+
+struct tevent_req *smb_vfs_call_getxattrat_send(
+                       TALLOC_CTX *mem_ctx,
+                       const struct smb_vfs_ev_glue *evg,
+                       struct vfs_handle_struct *handle,
+                       files_struct *dir_fsp,
+                       const struct smb_filename *smb_fname,
+                       const char *xattr_name,
+                       size_t alloc_hint)
+{
+       struct tevent_req *req = NULL;
+       struct smb_vfs_call_getxattrat_state *state = NULL;
+       struct tevent_req *subreq = NULL;
+       bool ok;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct smb_vfs_call_getxattrat_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       VFS_FIND(getxattrat_send);
+       state->recv_fn = handle->fns->getxattrat_recv_fn;
+
+       ok = smb_vfs_ev_glue_push_use(evg, req);
+       if (!ok) {
+               tevent_req_error(req, EIO);
+               return tevent_req_post(req, evg->return_ev);
+       }
+
+       subreq = handle->fns->getxattrat_send_fn(mem_ctx,
+                                                evg->next_glue,
+                                                handle,
+                                                dir_fsp,
+                                                smb_fname,
+                                                xattr_name,
+                                                alloc_hint);
+       smb_vfs_ev_glue_pop_use(evg);
+
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, evg->return_ev);
+       }
+       tevent_req_set_callback(subreq, smb_vfs_call_getxattrat_done, req);
+       return req;
+}
+
+static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
+               req, struct smb_vfs_call_getxattrat_state);
+
+       state->retval = state->recv_fn(subreq,
+                                      &state->aio_state,
+                                      state,
+                                      &state->xattr_value);
+       TALLOC_FREE(subreq);
+       if (state->retval == -1) {
+               tevent_req_error(req, state->aio_state.error);
+               return;
+       }
+
+       tevent_req_done(req);
+}
+
+ssize_t smb_vfs_call_getxattrat_recv(struct tevent_req *req,
+                                    struct vfs_aio_state *aio_state,
+                                    TALLOC_CTX *mem_ctx,
+                                    uint8_t **xattr_value)
+{
+       struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
+               req, struct smb_vfs_call_getxattrat_state);
+       size_t xattr_size;
+
+       if (tevent_req_is_unix_error(req, &aio_state->error)) {
+               tevent_req_received(req);
+               return -1;
+       }
+
+       *aio_state = state->aio_state;
+       xattr_size = state->retval;
+       if (xattr_value != NULL) {
+               *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
+       }
+
+       tevent_req_received(req);
+       return xattr_size;
+}
+
 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
                               struct files_struct *fsp, const char *name,
                               void *value, size_t size)