From 47d77432e4e0c61ba93390a5e33641a401154b54 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 15 Mar 2018 13:08:55 +0100 Subject: [PATCH] s3: vfs: add SMB_VFS_GET_DOS_ATTRIBUTES_SEND/RECV Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- examples/VFS/skel_opaque.c | 48 ++++++++++ examples/VFS/skel_transparent.c | 82 ++++++++++++++++ source3/include/vfs.h | 33 +++++++ source3/include/vfs_macros.h | 15 +++ source3/modules/vfs_catia.c | 2 + source3/modules/vfs_default.c | 2 + source3/modules/vfs_full_audit.c | 129 ++++++++++++++++++++++++++ source3/modules/vfs_gpfs.c | 2 + source3/modules/vfs_not_implemented.c | 49 ++++++++++ source3/modules/vfs_offline.c | 2 + source3/modules/vfs_time_audit.c | 100 ++++++++++++++++++++ source3/modules/vfs_tsmsm.c | 2 + source3/smbd/vfs.c | 97 +++++++++++++++++++ 13 files changed, 563 insertions(+) diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index 971303436b0..054de50197e 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -707,6 +707,52 @@ static NTSTATUS skel_get_dos_attributes(struct vfs_handle_struct *handle, return NT_STATUS_NOT_IMPLEMENTED; } +struct skel_get_dos_attributes_state { + struct vfs_aio_state aio_state; + uint32_t dosmode; +}; + +static struct tevent_req *skel_get_dos_attributes_send( + TALLOC_CTX *mem_ctx, + const struct smb_vfs_ev_glue *evg, + struct vfs_handle_struct *handle, + files_struct *dir_fsp, + struct smb_filename *smb_fname) +{ + struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg); + struct tevent_req *req = NULL; + struct skel_get_dos_attributes_state *state = NULL; + + req = tevent_req_create(mem_ctx, &state, + struct skel_get_dos_attributes_state); + if (req == NULL) { + return NULL; + } + + tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED); + return tevent_req_post(req, ev); +} + +static NTSTATUS skel_get_dos_attributes_recv(struct tevent_req *req, + struct vfs_aio_state *aio_state, + uint32_t *dosmode) +{ + struct skel_get_dos_attributes_state *state = + tevent_req_data(req, + struct skel_get_dos_attributes_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; + } + + *aio_state = state->aio_state; + *dosmode = state->dosmode; + tevent_req_received(req); + return NT_STATUS_OK; +} + static NTSTATUS skel_fget_dos_attributes(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32_t *dosmode) @@ -1069,6 +1115,8 @@ static struct vfs_fn_pointers skel_opaque_fns = { /* DOS attributes. */ .get_dos_attributes_fn = skel_get_dos_attributes, + .get_dos_attributes_send_fn = skel_get_dos_attributes_send, + .get_dos_attributes_recv_fn = skel_get_dos_attributes_recv, .fget_dos_attributes_fn = skel_fget_dos_attributes, .set_dos_attributes_fn = skel_set_dos_attributes, .fset_dos_attributes_fn = skel_fset_dos_attributes, diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index 503c14edcc0..cff52fa185e 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -886,6 +886,86 @@ static NTSTATUS skel_get_dos_attributes(struct vfs_handle_struct *handle, dosmode); } +struct skel_get_dos_attributes_state { + struct vfs_aio_state aio_state; + uint32_t dosmode; +}; + +static void skel_get_dos_attributes_done(struct tevent_req *subreq); + +static struct tevent_req *skel_get_dos_attributes_send( + TALLOC_CTX *mem_ctx, + const struct smb_vfs_ev_glue *evg, + struct vfs_handle_struct *handle, + files_struct *dir_fsp, + struct smb_filename *smb_fname) +{ + struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg); + struct tevent_req *req = NULL; + struct skel_get_dos_attributes_state *state = NULL; + struct tevent_req *subreq = NULL; + + req = tevent_req_create(mem_ctx, &state, + struct skel_get_dos_attributes_state); + if (req == NULL) { + return NULL; + } + + subreq = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES_SEND(mem_ctx, + evg, + handle, + dir_fsp, + smb_fname); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, skel_get_dos_attributes_done, req); + + return req; +} + +static void skel_get_dos_attributes_done(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + struct skel_get_dos_attributes_state *state = + tevent_req_data(req, + struct skel_get_dos_attributes_state); + NTSTATUS status; + + status = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES_RECV(subreq, + &state->aio_state, + &state->dosmode); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + + tevent_req_done(req); + return; +} + +static NTSTATUS skel_get_dos_attributes_recv(struct tevent_req *req, + struct vfs_aio_state *aio_state, + uint32_t *dosmode) +{ + struct skel_get_dos_attributes_state *state = + tevent_req_data(req, + struct skel_get_dos_attributes_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; + } + + *aio_state = state->aio_state; + *dosmode = state->dosmode; + tevent_req_received(req); + return NT_STATUS_OK; +} + static NTSTATUS skel_fget_dos_attributes(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32_t *dosmode) @@ -1298,6 +1378,8 @@ static struct vfs_fn_pointers skel_transparent_fns = { /* DOS attributes. */ .get_dos_attributes_fn = skel_get_dos_attributes, + .get_dos_attributes_send_fn = skel_get_dos_attributes_send, + .get_dos_attributes_recv_fn = skel_get_dos_attributes_recv, .fget_dos_attributes_fn = skel_fget_dos_attributes, .set_dos_attributes_fn = skel_set_dos_attributes, .fset_dos_attributes_fn = skel_fset_dos_attributes, diff --git a/source3/include/vfs.h b/source3/include/vfs.h index def802c9772..4f3db694896 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -260,6 +260,7 @@ /* Version 40 - Introduce smb_vfs_ev_glue infrastructure. */ /* Version 40 - Add vfs_not_implemented_* helper functions. */ /* Version 40 - Add SMB_VFS_GETXATTRAT_SEND/RECV */ +/* Version 40 - Add SMB_VFS_GET_DOS_ATTRIBUTES_SEND/RECV */ #define SMB_VFS_INTERFACE_VERSION 40 @@ -900,6 +901,18 @@ struct vfs_fn_pointers { struct files_struct *fsp, uint32_t dosmode); + struct tevent_req *(*get_dos_attributes_send_fn)( + TALLOC_CTX *mem_ctx, + const struct smb_vfs_ev_glue *evg, + struct vfs_handle_struct *handle, + files_struct *dir_fsp, + struct smb_filename *smb_fname); + + NTSTATUS (*get_dos_attributes_recv_fn)( + struct tevent_req *req, + struct vfs_aio_state *aio_state, + uint32_t *dosmode); + /* NT ACL operations. */ NTSTATUS (*fget_nt_acl_fn)(struct vfs_handle_struct *handle, @@ -1355,6 +1368,16 @@ NTSTATUS smb_vfs_call_set_dos_attributes(struct vfs_handle_struct *handle, NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32_t dosmode); +struct tevent_req *smb_vfs_call_get_dos_attributes_send( + TALLOC_CTX *mem_ctx, + const struct smb_vfs_ev_glue *evg, + struct vfs_handle_struct *handle, + files_struct *dir_fsp, + struct smb_filename *smb_fname); +NTSTATUS smb_vfs_call_get_dos_attributes_recv( + struct tevent_req *req, + struct vfs_aio_state *aio_state, + uint32_t *dosmode); struct tevent_req *smb_vfs_call_offload_read_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -1827,6 +1850,16 @@ NTSTATUS vfs_not_implemented_readdir_attr(struct vfs_handle_struct *handle, NTSTATUS vfs_not_implemented_get_dos_attributes(struct vfs_handle_struct *handle, struct smb_filename *smb_fname, uint32_t *dosmode); +struct tevent_req *vfs_not_implemented_get_dos_attributes_send( + TALLOC_CTX *mem_ctx, + const struct smb_vfs_ev_glue *evg, + struct vfs_handle_struct *handle, + files_struct *dir_fsp, + struct smb_filename *smb_fname); +NTSTATUS vfs_not_implemented_get_dos_attributes_recv( + struct tevent_req *req, + struct vfs_aio_state *aio_state, + uint32_t *dosmode); NTSTATUS vfs_not_implemented_fget_dos_attributes(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32_t *dosmode); diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index d4863536cc2..a13680c239e 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -386,6 +386,21 @@ #define SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, attributes) \ smb_vfs_call_fget_dos_attributes((handle)->next, (fsp), (attributes)) +#define SMB_VFS_GET_DOS_ATTRIBUTES_SEND(mem_ctx, evg, dir_fsp, smb_fname) \ + smb_vfs_call_get_dos_attributes_send((mem_ctx), (evg), \ + (dir_fsp)->conn->vfs_handles, \ + (dir_fsp), (smb_fname)) +#define SMB_VFS_GET_DOS_ATTRIBUTES_RECV(req, aio_state, dosmode) \ + smb_vfs_call_get_dos_attributes_recv((req), (aio_state), (dosmode)) + +#define SMB_VFS_NEXT_GET_DOS_ATTRIBUTES_SEND(mem_ctx, evg, handle, dir_fsp, \ + smb_fname) \ + smb_vfs_call_get_dos_attributes_send((mem_ctx), (evg), \ + (handle)->next, \ + (dir_fsp), (smb_fname)) +#define SMB_VFS_NEXT_GET_DOS_ATTRIBUTES_RECV(req, aio_state, dosmode) \ + smb_vfs_call_get_dos_attributes_recv((req), (aio_state), (dosmode)) + #define SMB_VFS_SET_DOS_ATTRIBUTES(conn, smb_fname, attributes) \ smb_vfs_call_set_dos_attributes((conn)->vfs_handles, (smb_fname), (attributes)) #define SMB_VFS_NEXT_SET_DOS_ATTRIBUTES(handle, smb_fname, attributes) \ diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index d2dddaf6921..12995dda9bf 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -2447,6 +2447,8 @@ static struct vfs_fn_pointers vfs_catia_fns = { .translate_name_fn = catia_translate_name, .fsctl_fn = catia_fsctl, .get_dos_attributes_fn = catia_get_dos_attributes, + .get_dos_attributes_send_fn = vfs_not_implemented_get_dos_attributes_send, + .get_dos_attributes_recv_fn = vfs_not_implemented_get_dos_attributes_recv, .set_dos_attributes_fn = catia_set_dos_attributes, .fset_dos_attributes_fn = catia_fset_dos_attributes, .fget_dos_attributes_fn = catia_fget_dos_attributes, diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 0523644ac98..81c707d15ec 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -3164,6 +3164,8 @@ static struct vfs_fn_pointers vfs_default_fns = { .set_dos_attributes_fn = vfswrap_set_dos_attributes, .fset_dos_attributes_fn = vfswrap_fset_dos_attributes, .get_dos_attributes_fn = vfswrap_get_dos_attributes, + .get_dos_attributes_send_fn = vfs_not_implemented_get_dos_attributes_send, + .get_dos_attributes_recv_fn = vfs_not_implemented_get_dos_attributes_recv, .fget_dos_attributes_fn = vfswrap_fget_dos_attributes, .offload_read_send_fn = vfswrap_offload_read_send, .offload_read_recv_fn = vfswrap_offload_read_recv, diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index f28413b83c2..0fbf9ecafe3 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -69,6 +69,7 @@ #include "lib/util/tevent_unix.h" #include "libcli/security/sddl.h" #include "passdb/machine_sid.h" +#include "lib/util/tevent_ntstatus.h" static int vfs_full_audit_debug_level = DBGC_VFS; @@ -178,6 +179,8 @@ typedef enum _vfs_op_type { /* DOS attribute operations. */ SMB_VFS_OP_GET_DOS_ATTRIBUTES, + SMB_VFS_OP_GET_DOS_ATTRIBUTES_SEND, + SMB_VFS_OP_GET_DOS_ATTRIBUTES_RECV, SMB_VFS_OP_FGET_DOS_ATTRIBUTES, SMB_VFS_OP_SET_DOS_ATTRIBUTES, SMB_VFS_OP_FSET_DOS_ATTRIBUTES, @@ -317,6 +320,8 @@ static struct { { SMB_VFS_OP_SNAP_CREATE, "snap_create" }, { SMB_VFS_OP_SNAP_DELETE, "snap_delete" }, { SMB_VFS_OP_GET_DOS_ATTRIBUTES, "get_dos_attributes" }, + { SMB_VFS_OP_GET_DOS_ATTRIBUTES_SEND, "get_dos_attributes_send" }, + { SMB_VFS_OP_GET_DOS_ATTRIBUTES_RECV, "get_dos_attributes_recv" }, { SMB_VFS_OP_FGET_DOS_ATTRIBUTES, "fget_dos_attributes" }, { SMB_VFS_OP_SET_DOS_ATTRIBUTES, "set_dos_attributes" }, { SMB_VFS_OP_FSET_DOS_ATTRIBUTES, "fset_dos_attributes" }, @@ -2064,6 +2069,128 @@ static NTSTATUS smb_full_audit_get_dos_attributes( return status; } +struct smb_full_audit_get_dos_attributes_state { + struct vfs_aio_state aio_state; + vfs_handle_struct *handle; + files_struct *dir_fsp; + const struct smb_filename *smb_fname; + uint32_t dosmode; +}; + +static void smb_full_audit_get_dos_attributes_done(struct tevent_req *subreq); + +static struct tevent_req *smb_full_audit_get_dos_attributes_send( + TALLOC_CTX *mem_ctx, + const struct smb_vfs_ev_glue *evg, + struct vfs_handle_struct *handle, + files_struct *dir_fsp, + struct smb_filename *smb_fname) +{ + struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg); + struct tevent_req *req = NULL; + struct smb_full_audit_get_dos_attributes_state *state = NULL; + struct tevent_req *subreq = NULL; + + req = tevent_req_create(mem_ctx, &state, + struct smb_full_audit_get_dos_attributes_state); + if (req == NULL) { + do_log(SMB_VFS_OP_GET_DOS_ATTRIBUTES_SEND, + false, + handle, + "%s/%s", + fsp_str_do_log(dir_fsp), + smb_fname->base_name); + return NULL; + } + *state = (struct smb_full_audit_get_dos_attributes_state) { + .handle = handle, + .dir_fsp = dir_fsp, + .smb_fname = smb_fname, + }; + + subreq = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES_SEND(mem_ctx, + evg, + handle, + dir_fsp, + smb_fname); + if (tevent_req_nomem(subreq, req)) { + do_log(SMB_VFS_OP_GET_DOS_ATTRIBUTES_SEND, + false, + handle, + "%s/%s", + fsp_str_do_log(dir_fsp), + smb_fname->base_name); + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, + smb_full_audit_get_dos_attributes_done, + req); + + do_log(SMB_VFS_OP_GET_DOS_ATTRIBUTES_SEND, + true, + handle, + "%s/%s", + fsp_str_do_log(dir_fsp), + smb_fname->base_name); + + return req; +} + +static void smb_full_audit_get_dos_attributes_done(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + struct smb_full_audit_get_dos_attributes_state *state = + tevent_req_data(req, + struct smb_full_audit_get_dos_attributes_state); + NTSTATUS status; + + status = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES_RECV(subreq, + &state->aio_state, + &state->dosmode); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + + tevent_req_done(req); + return; +} + +static NTSTATUS smb_full_audit_get_dos_attributes_recv(struct tevent_req *req, + struct vfs_aio_state *aio_state, + uint32_t *dosmode) +{ + struct smb_full_audit_get_dos_attributes_state *state = + tevent_req_data(req, + struct smb_full_audit_get_dos_attributes_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + do_log(SMB_VFS_OP_GET_DOS_ATTRIBUTES_RECV, + false, + state->handle, + "%s/%s", + fsp_str_do_log(state->dir_fsp), + state->smb_fname->base_name); + tevent_req_received(req); + return status; + } + + do_log(SMB_VFS_OP_GET_DOS_ATTRIBUTES_RECV, + true, + state->handle, + "%s/%s", + fsp_str_do_log(state->dir_fsp), + state->smb_fname->base_name); + + *aio_state = state->aio_state; + *dosmode = state->dosmode; + tevent_req_received(req); + return NT_STATUS_OK; +} + static NTSTATUS smb_full_audit_fget_dos_attributes( struct vfs_handle_struct *handle, struct files_struct *fsp, @@ -2716,6 +2843,8 @@ static struct vfs_fn_pointers vfs_full_audit_fns = { .translate_name_fn = smb_full_audit_translate_name, .fsctl_fn = smb_full_audit_fsctl, .get_dos_attributes_fn = smb_full_audit_get_dos_attributes, + .get_dos_attributes_send_fn = smb_full_audit_get_dos_attributes_send, + .get_dos_attributes_recv_fn = smb_full_audit_get_dos_attributes_recv, .fget_dos_attributes_fn = smb_full_audit_fget_dos_attributes, .set_dos_attributes_fn = smb_full_audit_set_dos_attributes, .fset_dos_attributes_fn = smb_full_audit_fset_dos_attributes, diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index d733df0aa5c..5f21bc0826d 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -2561,6 +2561,8 @@ static struct vfs_fn_pointers vfs_gpfs_fns = { .linux_setlease_fn = vfs_gpfs_setlease, .get_real_filename_fn = vfs_gpfs_get_real_filename, .get_dos_attributes_fn = vfs_gpfs_get_dos_attributes, + .get_dos_attributes_send_fn = vfs_not_implemented_get_dos_attributes_send, + .get_dos_attributes_recv_fn = vfs_not_implemented_get_dos_attributes_recv, .fget_dos_attributes_fn = vfs_gpfs_fget_dos_attributes, .set_dos_attributes_fn = vfs_gpfs_set_dos_attributes, .fset_dos_attributes_fn = vfs_gpfs_fset_dos_attributes, diff --git a/source3/modules/vfs_not_implemented.c b/source3/modules/vfs_not_implemented.c index bb4854d8bf8..e20b7eb76ed 100644 --- a/source3/modules/vfs_not_implemented.c +++ b/source3/modules/vfs_not_implemented.c @@ -710,6 +710,53 @@ NTSTATUS vfs_not_implemented_get_dos_attributes(struct vfs_handle_struct *handle return NT_STATUS_NOT_IMPLEMENTED; } +struct vfs_not_implemented_get_dos_attributes_state { + struct vfs_aio_state aio_state; + uint32_t dosmode; +}; + +struct tevent_req *vfs_not_implemented_get_dos_attributes_send( + TALLOC_CTX *mem_ctx, + const struct smb_vfs_ev_glue *evg, + struct vfs_handle_struct *handle, + files_struct *dir_fsp, + struct smb_filename *smb_fname) +{ + struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg); + struct tevent_req *req = NULL; + struct vfs_not_implemented_get_dos_attributes_state *state = NULL; + + req = tevent_req_create(mem_ctx, &state, + struct vfs_not_implemented_get_dos_attributes_state); + if (req == NULL) { + return NULL; + } + + tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED); + return tevent_req_post(req, ev); +} + +NTSTATUS vfs_not_implemented_get_dos_attributes_recv( + struct tevent_req *req, + struct vfs_aio_state *aio_state, + uint32_t *dosmode) +{ + struct vfs_not_implemented_get_dos_attributes_state *state = + tevent_req_data(req, + struct vfs_not_implemented_get_dos_attributes_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; + } + + *aio_state = state->aio_state; + *dosmode = state->dosmode; + tevent_req_received(req); + return NT_STATUS_OK; +} + NTSTATUS vfs_not_implemented_fget_dos_attributes(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32_t *dosmode) @@ -1072,6 +1119,8 @@ static struct vfs_fn_pointers vfs_not_implemented_fns = { /* DOS attributes. */ .get_dos_attributes_fn = vfs_not_implemented_get_dos_attributes, + .get_dos_attributes_send_fn = vfs_not_implemented_get_dos_attributes_send, + .get_dos_attributes_recv_fn = vfs_not_implemented_get_dos_attributes_recv, .fget_dos_attributes_fn = vfs_not_implemented_fget_dos_attributes, .set_dos_attributes_fn = vfs_not_implemented_set_dos_attributes, .fset_dos_attributes_fn = vfs_not_implemented_fset_dos_attributes, diff --git a/source3/modules/vfs_offline.c b/source3/modules/vfs_offline.c index d70fad4c042..0a7e8af469c 100644 --- a/source3/modules/vfs_offline.c +++ b/source3/modules/vfs_offline.c @@ -46,6 +46,8 @@ static NTSTATUS offline_fget_dos_attributes(struct vfs_handle_struct *handle, static struct vfs_fn_pointers offline_fns = { .fs_capabilities_fn = offline_fs_capabilities, .get_dos_attributes_fn = offline_get_dos_attributes, + .get_dos_attributes_send_fn = vfs_not_implemented_get_dos_attributes_send, + .get_dos_attributes_recv_fn = vfs_not_implemented_get_dos_attributes_recv, .fget_dos_attributes_fn = offline_fget_dos_attributes, }; diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index 07c14415312..64e1f5d4d13 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -1757,6 +1757,104 @@ static NTSTATUS smb_time_get_dos_attributes(struct vfs_handle_struct *handle, return result; } +struct smb_time_audit_get_dos_attributes_state { + struct vfs_aio_state aio_state; + files_struct *dir_fsp; + const struct smb_filename *smb_fname; + uint32_t dosmode; +}; + +static void smb_time_audit_get_dos_attributes_done(struct tevent_req *subreq); + +static struct tevent_req *smb_time_audit_get_dos_attributes_send( + TALLOC_CTX *mem_ctx, + const struct smb_vfs_ev_glue *evg, + struct vfs_handle_struct *handle, + files_struct *dir_fsp, + struct smb_filename *smb_fname) +{ + struct tevent_context *ev = smb_vfs_ev_glue_ev_ctx(evg); + struct tevent_req *req = NULL; + struct smb_time_audit_get_dos_attributes_state *state = NULL; + struct tevent_req *subreq = NULL; + + req = tevent_req_create(mem_ctx, &state, + struct smb_time_audit_get_dos_attributes_state); + if (req == NULL) { + return NULL; + } + *state = (struct smb_time_audit_get_dos_attributes_state) { + .dir_fsp = dir_fsp, + .smb_fname = smb_fname, + }; + + subreq = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES_SEND(mem_ctx, + evg, + handle, + dir_fsp, + smb_fname); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, + smb_time_audit_get_dos_attributes_done, + req); + + return req; +} + +static void smb_time_audit_get_dos_attributes_done(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + struct smb_time_audit_get_dos_attributes_state *state = + tevent_req_data(req, + struct smb_time_audit_get_dos_attributes_state); + NTSTATUS status; + + status = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES_RECV(subreq, + &state->aio_state, + &state->dosmode); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + + tevent_req_done(req); + return; +} + +static NTSTATUS smb_time_audit_get_dos_attributes_recv(struct tevent_req *req, + struct vfs_aio_state *aio_state, + uint32_t *dosmode) +{ + struct smb_time_audit_get_dos_attributes_state *state = + tevent_req_data(req, + struct smb_time_audit_get_dos_attributes_state); + NTSTATUS status; + double timediff; + + timediff = state->aio_state.duration * 1.0e-9; + + if (timediff > audit_timeout) { + smb_time_audit_log_at("async get_dos_attributes", + timediff, + state->dir_fsp, + state->smb_fname); + } + + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; + } + + *aio_state = state->aio_state; + *dosmode = state->dosmode; + tevent_req_received(req); + return NT_STATUS_OK; +} + static NTSTATUS smb_time_fget_dos_attributes(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32_t *dosmode) @@ -2774,6 +2872,8 @@ static struct vfs_fn_pointers vfs_time_audit_fns = { .translate_name_fn = smb_time_audit_translate_name, .fsctl_fn = smb_time_audit_fsctl, .get_dos_attributes_fn = smb_time_get_dos_attributes, + .get_dos_attributes_send_fn = smb_time_audit_get_dos_attributes_send, + .get_dos_attributes_recv_fn = smb_time_audit_get_dos_attributes_recv, .fget_dos_attributes_fn = smb_time_fget_dos_attributes, .set_dos_attributes_fn = smb_time_set_dos_attributes, .fset_dos_attributes_fn = smb_time_fset_dos_attributes, diff --git a/source3/modules/vfs_tsmsm.c b/source3/modules/vfs_tsmsm.c index 99d11a53f9d..85a9bfdfa9c 100644 --- a/source3/modules/vfs_tsmsm.c +++ b/source3/modules/vfs_tsmsm.c @@ -605,6 +605,8 @@ static struct vfs_fn_pointers tsmsm_fns = { .set_dos_attributes_fn = tsmsm_set_dos_attributes, .fset_dos_attributes_fn = tsmsm_fset_dos_attributes, .get_dos_attributes_fn = tsmsm_get_dos_attributes, + .get_dos_attributes_send_fn = vfs_not_implemented_get_dos_attributes_send, + .get_dos_attributes_recv_fn = vfs_not_implemented_get_dos_attributes_recv, .fget_dos_attributes_fn = tsmsm_fget_dos_attributes, }; diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 501eafe1c02..2687e3540b8 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -31,6 +31,7 @@ #include "transfer_file.h" #include "ntioctl.h" #include "lib/util/tevent_unix.h" +#include "lib/util/tevent_ntstatus.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_VFS @@ -3250,6 +3251,102 @@ NTSTATUS smb_vfs_call_offload_write_recv(struct vfs_handle_struct *handle, return handle->fns->offload_write_recv_fn(handle, req, copied); } +struct smb_vfs_call_get_dos_attributes_state { + NTSTATUS (*recv_fn)(struct tevent_req *req, + struct vfs_aio_state *aio_state, + uint32_t *dosmode); + struct vfs_aio_state aio_state; + uint32_t dos_attributes; +}; + +static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq); + +struct tevent_req *smb_vfs_call_get_dos_attributes_send( + TALLOC_CTX *mem_ctx, + const struct smb_vfs_ev_glue *evg, + struct vfs_handle_struct *handle, + files_struct *dir_fsp, + struct smb_filename *smb_fname) +{ + struct tevent_req *req = NULL; + struct smb_vfs_call_get_dos_attributes_state *state = NULL; + struct tevent_req *subreq = NULL; + bool ok; + + req = tevent_req_create(mem_ctx, &state, + struct smb_vfs_call_get_dos_attributes_state); + if (req == NULL) { + return NULL; + } + + VFS_FIND(get_dos_attributes_send); + state->recv_fn = handle->fns->get_dos_attributes_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->get_dos_attributes_send_fn(mem_ctx, + evg->next_glue, + handle, + dir_fsp, + smb_fname); + 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_get_dos_attributes_done, + req); + + return req; +} + +static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + struct smb_vfs_call_get_dos_attributes_state *state = + tevent_req_data(req, + struct smb_vfs_call_get_dos_attributes_state); + NTSTATUS status; + + status = state->recv_fn(subreq, + &state->aio_state, + &state->dos_attributes); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + + tevent_req_done(req); +} + +NTSTATUS smb_vfs_call_get_dos_attributes_recv( + struct tevent_req *req, + struct vfs_aio_state *aio_state, + uint32_t *dos_attributes) +{ + struct smb_vfs_call_get_dos_attributes_state *state = + tevent_req_data(req, + struct smb_vfs_call_get_dos_attributes_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; + } + + *aio_state = state->aio_state; + *dos_attributes = state->dos_attributes; + tevent_req_received(req); + return NT_STATUS_OK; +} + NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, struct files_struct *fsp,