vfs: add snapshot create/delete hooks
authorDavid Disseldorp <ddiss@samba.org>
Tue, 10 Apr 2012 01:16:57 +0000 (03:16 +0200)
committerDavid Disseldorp <ddiss@samba.org>
Mon, 15 Apr 2013 16:15:18 +0000 (18:15 +0200)
docs-xml/manpages/vfs_full_audit.8.xml
examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/include/vfs.h
source3/include/vfs_macros.h
source3/modules/vfs_default.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_time_audit.c
source3/smbd/vfs.c

index 312bc25078d00e38c0189db12493a66cb9d67b96..fdae703af3cbb8f7ffbd1b742920442ddf8820f2 100644 (file)
         <member>set_nt_acl</member>
         <member>set_quota</member>
         <member>setxattr</member>
+        <member>snap_check_path</member>
+        <member>snap_create_send</member>
+        <member>snap_create_recv</member>
+        <member>snap_delete_send</member>
+        <member>snap_delete_recv</member>
         <member>stat</member>
         <member>statvfs</member>
         <member>symlink</member>
index f0aff08b50f3255a4ded6e26b9bfba78ed0de97e..2397d08024a81678a1dd6ad7188a43fd9344d4a0 100644 (file)
@@ -94,6 +94,46 @@ static DIR *skel_opendir(vfs_handle_struct *handle,  const char *fname, const ch
        return NULL;
 }
 
+static NTSTATUS skel_snap_check_path(struct vfs_handle_struct *handle,
+                                    TALLOC_CTX *mem_ctx,
+                                    const char *service_path,
+                                    char **base_volume)
+{
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
+static struct tevent_req *skel_snap_create_send(struct vfs_handle_struct *handle,
+                                               TALLOC_CTX *mem_ctx,
+                                               struct tevent_context *ev,
+                                               const char *base_volume,
+                                               time_t *tstamp,
+                                               bool rw)
+{
+       return NULL;
+}
+
+static NTSTATUS skel_snap_create_recv(struct vfs_handle_struct *handle,
+                                     struct tevent_req *req,
+                                     TALLOC_CTX *mem_ctx,
+                                     char **base_path, char **snap_path)
+{
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
+static struct tevent_req *skel_snap_delete_send(struct vfs_handle_struct *handle,
+                                               TALLOC_CTX *mem_ctx,
+                                               struct tevent_context *ev,
+                                               char *snap_path)
+{
+       return NULL;
+}
+
+static NTSTATUS skel_snap_delete_recv(struct vfs_handle_struct *handle,
+                                     struct tevent_req *req)
+{
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
 static DIR *skel_fdopendir(vfs_handle_struct *handle, files_struct *fsp, const char *mask, uint32 attr)
 {
        return NULL;
@@ -746,6 +786,11 @@ struct vfs_fn_pointers skel_opaque_fns = {
        .statvfs_fn = skel_statvfs,
        .fs_capabilities_fn = skel_fs_capabilities,
        .get_dfs_referrals_fn = skel_get_dfs_referrals,
+       .snap_check_path_fn = skel_snap_check_path,
+       .snap_create_send_fn = skel_snap_create_send,
+       .snap_create_recv_fn = skel_snap_create_recv,
+       .snap_delete_send_fn = skel_snap_delete_send,
+       .snap_delete_recv_fn = skel_snap_delete_recv,
 
        /* Directory operations */
 
index 4085768f1cd40f1d3fd213c25f23a7e64e67af37..b93d2bc2c71a0013f46b878d47d1f8591994f0f6 100644 (file)
@@ -92,6 +92,49 @@ static DIR *skel_opendir(vfs_handle_struct *handle,  const char *fname, const ch
        return SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr);
 }
 
+static NTSTATUS skel_snap_check_path(struct vfs_handle_struct *handle,
+                                    TALLOC_CTX *mem_ctx,
+                                    const char *service_path,
+                                    char **base_volume)
+{
+       return SMB_VFS_NEXT_SNAP_CHECK_PATH(handle, mem_ctx, service_path,
+                                           base_volume);
+}
+
+static struct tevent_req *skel_snap_create_send(struct vfs_handle_struct *handle,
+                                               TALLOC_CTX *mem_ctx,
+                                               struct tevent_context *ev,
+                                               const char *base_volume,
+                                               time_t *tstamp,
+                                               bool rw)
+{
+       return SMB_VFS_NEXT_SNAP_CREATE_SEND(handle, mem_ctx, ev, base_volume,
+                                            tstamp, rw);
+}
+
+static NTSTATUS skel_snap_create_recv(struct vfs_handle_struct *handle,
+                                     struct tevent_req *req,
+                                     TALLOC_CTX *mem_ctx,
+                                     char **base_path, char **snap_path)
+{
+       return SMB_VFS_NEXT_SNAP_CREATE_RECV(handle, req, mem_ctx, base_path,
+                                            snap_path);
+}
+
+static struct tevent_req *skel_snap_delete_send(struct vfs_handle_struct *handle,
+                                               TALLOC_CTX *mem_ctx,
+                                               struct tevent_context *ev,
+                                               char *snap_path)
+{
+       return SMB_VFS_NEXT_SNAP_DELETE_SEND(handle, mem_ctx, ev, snap_path);
+}
+
+static NTSTATUS skel_snap_delete_recv(struct vfs_handle_struct *handle,
+                                     struct tevent_req *req)
+{
+       return SMB_VFS_NEXT_SNAP_DELETE_RECV(handle, req);
+}
+
 static DIR *skel_fdopendir(vfs_handle_struct *handle, files_struct *fsp, const char *mask, uint32 attr)
 {
        return SMB_VFS_NEXT_FDOPENDIR(handle, fsp, mask, attr);
@@ -881,6 +924,11 @@ struct vfs_fn_pointers skel_transparent_fns = {
        .statvfs_fn = skel_statvfs,
        .fs_capabilities_fn = skel_fs_capabilities,
        .get_dfs_referrals_fn = skel_get_dfs_referrals,
+       .snap_check_path_fn = skel_snap_check_path,
+       .snap_create_send_fn = skel_snap_create_send,
+       .snap_create_recv_fn = skel_snap_create_recv,
+       .snap_delete_send_fn = skel_snap_delete_send,
+       .snap_delete_recv_fn = skel_snap_delete_recv,
 
        /* Directory operations */
 
index 2805c1e7a10d3c83986cbef4c9fb2fd9a8241b09..d5d9cd5b07f5463a73fa5b014f99141411291194 100644 (file)
 /* Leave at 30 - not yet released. Added conn->cwd to save vfs_GetWd() calls. */
 /* Leave at 30 - not yet released. Changed sys_acl_blob_get_file interface to remove type */
 /* Leave at 30 - not yet released. add SMB_VFS_COPY_CHUNK() */
+/* Leave at 30 - not yet released. add snapshot create/delete calls */
 #define SMB_VFS_INTERFACE_VERSION 30
 
 /*
@@ -621,6 +622,26 @@ struct vfs_fn_pointers {
        NTSTATUS (*copy_chunk_recv_fn)(struct vfs_handle_struct *handle,
                                       struct tevent_req *req,
                                       off_t *copied);
+       NTSTATUS (*snap_check_path_fn)(struct vfs_handle_struct *handle,
+                                      TALLOC_CTX *mem_ctx,
+                                      const char *service_path,
+                                      char **base_volume);
+       struct tevent_req *(*snap_create_send_fn)(struct vfs_handle_struct *handle,
+                                                 TALLOC_CTX *mem_ctx,
+                                                 struct tevent_context *ev,
+                                                 const char *base_volume,
+                                                 time_t *tstamp,
+                                                 bool rw);
+       NTSTATUS (*snap_create_recv_fn)(struct vfs_handle_struct *handle,
+                                       struct tevent_req *req,
+                                       TALLOC_CTX *mem_ctx,
+                                       char **base_path, char **snap_path);
+       struct tevent_req *(*snap_delete_send_fn)(struct vfs_handle_struct *handle,
+                                                 TALLOC_CTX *mem_ctx,
+                                                 struct tevent_context *ev,
+                                                 char *snap_path);
+       NTSTATUS (*snap_delete_recv_fn)(struct vfs_handle_struct *handle,
+                                       struct tevent_req *req);
 
        NTSTATUS (*streaminfo_fn)(struct vfs_handle_struct *handle,
                                  struct files_struct *fsp,
@@ -1104,6 +1125,26 @@ struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle
 NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
                                      struct tevent_req *req,
                                      off_t *copied);
+NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
+                                     TALLOC_CTX *mem_ctx,
+                                     const char *service_path,
+                                     char **base_volume);
+struct tevent_req *smb_vfs_call_snap_create_send(struct vfs_handle_struct *handle,
+                                                TALLOC_CTX *mem_ctx,
+                                                struct tevent_context *ev,
+                                                const char *base_volume,
+                                                time_t *tstamp,
+                                                bool rw);
+NTSTATUS smb_vfs_call_snap_create_recv(struct vfs_handle_struct *handle,
+                                      struct tevent_req *req,
+                                      TALLOC_CTX *mem_ctx,
+                                      char **base_path, char **snap_path);
+struct tevent_req *smb_vfs_call_snap_delete_send(struct vfs_handle_struct *handle,
+                                                TALLOC_CTX *mem_ctx,
+                                                struct tevent_context *ev,
+                                                char *snap_path);
+NTSTATUS smb_vfs_call_snap_delete_recv(struct vfs_handle_struct *handle,
+                                      struct tevent_req *req);
 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
                                  struct files_struct *fsp,
                                  uint32 security_info,
index 364a4ca6e1a8190bb0b981be535a385d9f316176..254fd55672e96381df37e066c9a998bf6af669b5 100644 (file)
 #define SMB_VFS_NEXT_COPY_CHUNK_RECV(handle, req, copied) \
        smb_vfs_call_copy_chunk_recv((handle)->next, (req), (copied))
 
+#define SMB_VFS_SNAP_CHECK_PATH(conn, mem_ctx, service_path, base_volume) \
+       smb_vfs_call_snap_check_path((conn)->vfs_handles, (mem_ctx), (service_path), (base_volume))
+#define SMB_VFS_NEXT_SNAP_CHECK_PATH(handle, mem_ctx, service_path, base_volume) \
+       smb_vfs_call_snap_check_path((handle)->next, (mem_ctx), (service_path), (base_volume))
+
+#define SMB_VFS_SNAP_CREATE_SEND(conn, mem_ctx, ev, base_volume, tstamp, rw) \
+       smb_vfs_call_snap_create_send((conn)->vfs_handles, (mem_ctx), (ev), (base_volume), (tstamp), (rw))
+#define SMB_VFS_NEXT_SNAP_CREATE_SEND(handle, mem_ctx, ev, base_volume, tstamp, rw) \
+       smb_vfs_call_snap_create_send((handle)->next, (mem_ctx), (ev), (base_volume), (tstamp), (rw))
+
+#define SMB_VFS_SNAP_CREATE_RECV(conn, req, mem_ctx, base_path, snap_path) \
+       smb_vfs_call_snap_create_recv((conn)->vfs_handles, (req), (mem_ctx), (base_path), (snap_path))
+#define SMB_VFS_NEXT_SNAP_CREATE_RECV(handle, req, mem_ctx, base_path, snap_path) \
+       smb_vfs_call_snap_create_recv((handle)->next, (req), (mem_ctx), (base_path), (snap_path))
+
+#define SMB_VFS_SNAP_DELETE_SEND(conn, mem_ctx, ev, snap_path) \
+       smb_vfs_call_snap_delete_send((conn)->vfs_handles, (mem_ctx), (ev), (snap_path))
+#define SMB_VFS_NEXT_SNAP_DELETE_SEND(handle, mem_ctx, ev, snap_path) \
+       smb_vfs_call_snap_delete_send((handle)->next, (mem_ctx), (ev), (snap_path))
+
+#define SMB_VFS_SNAP_DELETE_RECV(conn, req) \
+       smb_vfs_call_snap_delete_recv((conn)->vfs_handles, (req))
+#define SMB_VFS_NEXT_SNAP_DELETE_RECV(handle, req) \
+       smb_vfs_call_snap_delete_recv((handle)->next, (req))
+
 #define SMB_VFS_FGET_NT_ACL(fsp, security_info, mem_ctx, ppdesc)               \
                smb_vfs_call_fget_nt_acl((fsp)->conn->vfs_handles, (fsp), (security_info), (mem_ctx), (ppdesc))
 #define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, mem_ctx, ppdesc) \
index bc7e6ec3c8ae305c8f994400ce3568c8235bd501..a07c7da6e10557efb740ff3a31be6e07d3a4392c 100644 (file)
@@ -346,6 +346,62 @@ static NTSTATUS vfswrap_get_dfs_referrals(struct vfs_handle_struct *handle,
        return NT_STATUS_OK;
 }
 
+static NTSTATUS vfswrap_snap_check_path(struct vfs_handle_struct *handle,
+                                       TALLOC_CTX *mem_ctx,
+                                       const char *service_path,
+                                       char **base_volume)
+{
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
+static struct tevent_req *vfswrap_snap_create_send(struct vfs_handle_struct *handle,
+                                                  TALLOC_CTX *mem_ctx,
+                                                  struct tevent_context *ev,
+                                                  const char *base_volume,
+                                                  time_t *tstamp,
+                                                  bool rw)
+{
+       struct tevent_req *req;
+       uint32_t *unused;
+
+       req = tevent_req_create(mem_ctx, &unused, uint32_t);
+       if (req == NULL) {
+               return NULL;
+       }
+       tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
+       return tevent_req_post(req, ev);
+}
+
+static NTSTATUS vfswrap_snap_create_recv(struct vfs_handle_struct *handle,
+                                        struct tevent_req *req,
+                                        TALLOC_CTX *mem_ctx,
+                                        char **base_path, char **snap_path)
+{
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
+static struct tevent_req *vfswrap_snap_delete_send(struct vfs_handle_struct *handle,
+                                                  TALLOC_CTX *mem_ctx,
+                                                  struct tevent_context *ev,
+                                                  char *snap_path)
+{
+       struct tevent_req *req;
+       uint32_t *unused;
+
+       req = tevent_req_create(mem_ctx, &unused, uint32_t);
+       if (req == NULL) {
+               return NULL;
+       }
+       tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
+       return tevent_req_post(req, ev);
+}
+
+static NTSTATUS vfswrap_snap_delete_recv(struct vfs_handle_struct *handle,
+                                     struct tevent_req *req)
+{
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
 /* Directory operations */
 
 static DIR *vfswrap_opendir(vfs_handle_struct *handle,  const char *fname, const char *mask, uint32 attr)
@@ -2467,6 +2523,11 @@ static struct vfs_fn_pointers vfs_default_fns = {
        .statvfs_fn = vfswrap_statvfs,
        .fs_capabilities_fn = vfswrap_fs_capabilities,
        .get_dfs_referrals_fn = vfswrap_get_dfs_referrals,
+       .snap_check_path_fn = vfswrap_snap_check_path,
+       .snap_create_send_fn = vfswrap_snap_create_send,
+       .snap_create_recv_fn = vfswrap_snap_create_recv,
+       .snap_delete_send_fn = vfswrap_snap_delete_send,
+       .snap_delete_recv_fn = vfswrap_snap_delete_recv,
 
        /* Directory operations */
 
index 549f55e189565ae88b17b9361ded488fa779338a..265c9c39466074a6b0894f14ae7c3d19353df58b 100644 (file)
@@ -91,6 +91,11 @@ typedef enum _vfs_op_type {
        SMB_VFS_OP_GET_SHADOW_COPY_DATA,
        SMB_VFS_OP_STATVFS,
        SMB_VFS_OP_FS_CAPABILITIES,
+       SMB_VFS_OP_SNAP_CHECK_PATH,
+       SMB_VFS_OP_SNAP_CREATE_SEND,
+       SMB_VFS_OP_SNAP_CREATE_RECV,
+       SMB_VFS_OP_SNAP_DELETE_SEND,
+       SMB_VFS_OP_SNAP_DELETE_RECV,
 
        /* Directory operations */
 
@@ -219,6 +224,11 @@ static struct {
        { SMB_VFS_OP_GET_SHADOW_COPY_DATA,      "get_shadow_copy_data" },
        { SMB_VFS_OP_STATVFS,   "statvfs" },
        { SMB_VFS_OP_FS_CAPABILITIES,   "fs_capabilities" },
+       { SMB_VFS_OP_SNAP_CHECK_PATH, "snap_check_path" },
+       { SMB_VFS_OP_SNAP_CREATE_SEND, "snap_create_send" },
+       { SMB_VFS_OP_SNAP_CREATE_RECV, "snap_create_recv" },
+       { SMB_VFS_OP_SNAP_DELETE_SEND, "snap_delete_send" },
+       { SMB_VFS_OP_SNAP_DELETE_RECV, "snap_delete_recv" },
        { SMB_VFS_OP_OPENDIR,   "opendir" },
        { SMB_VFS_OP_FDOPENDIR, "fdopendir" },
        { SMB_VFS_OP_READDIR,   "readdir" },
@@ -645,7 +655,6 @@ static int smb_full_audit_get_quota(struct vfs_handle_struct *handle,
        return result;
 }
 
-       
 static int smb_full_audit_set_quota(struct vfs_handle_struct *handle,
                           enum SMB_QUOTA_TYPE qtype, unid_t id,
                           SMB_DISK_QUOTA *qt)
@@ -697,6 +706,77 @@ static uint32_t smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle,
        return result;
 }
 
+static NTSTATUS smb_full_audit_snap_check_path(struct vfs_handle_struct *handle,
+                                              TALLOC_CTX *mem_ctx,
+                                              const char *service_path,
+                                              char **base_volume)
+{
+       NTSTATUS status;
+
+       status = SMB_VFS_NEXT_SNAP_CHECK_PATH(handle, mem_ctx, service_path,
+                                             base_volume);
+       do_log(SMB_VFS_OP_SNAP_CHECK_PATH, NT_STATUS_IS_OK(status),
+              handle, "");
+
+       return status;
+}
+
+static struct tevent_req *smb_full_audit_snap_create_send(struct vfs_handle_struct *handle,
+                                                         TALLOC_CTX *mem_ctx,
+                                                         struct tevent_context *ev,
+                                                         const char *base_volume,
+                                                         time_t *tstamp,
+                                                         bool rw)
+{
+       struct tevent_req *req;
+
+       req = SMB_VFS_NEXT_SNAP_CREATE_SEND(handle, mem_ctx, ev, base_volume,
+                                           tstamp, rw);
+       do_log(SMB_VFS_OP_SNAP_CREATE_SEND, req, handle, "");
+
+       return req;
+}
+
+static NTSTATUS smb_full_audit_snap_create_recv(struct vfs_handle_struct *handle,
+                                               struct tevent_req *req,
+                                               TALLOC_CTX *mem_ctx,
+                                               char **base_path, char **snap_path)
+{
+       NTSTATUS status;
+
+       status = SMB_VFS_NEXT_SNAP_CREATE_RECV(handle, req, mem_ctx, base_path,
+                                              snap_path);
+       do_log(SMB_VFS_OP_SNAP_CREATE_RECV, NT_STATUS_IS_OK(status),
+              handle, "");
+
+       return status;
+}
+
+static struct tevent_req *smb_full_audit_snap_delete_send(struct vfs_handle_struct *handle,
+                                                         TALLOC_CTX *mem_ctx,
+                                                         struct tevent_context *ev,
+                                                         char *snap_path)
+{
+       struct tevent_req *req;
+
+       req = SMB_VFS_NEXT_SNAP_DELETE_SEND(handle, mem_ctx, ev, snap_path);
+       do_log(SMB_VFS_OP_SNAP_DELETE_SEND, req, handle, "");
+
+       return req;
+}
+
+static NTSTATUS smb_full_audit_snap_delete_recv(struct vfs_handle_struct *handle,
+                                               struct tevent_req *req)
+{
+       NTSTATUS status;
+
+       status = SMB_VFS_NEXT_SNAP_DELETE_RECV(handle, req);
+       do_log(SMB_VFS_OP_SNAP_DELETE_RECV, NT_STATUS_IS_OK(status),
+              handle, "");
+
+       return status;
+}
+
 static DIR *smb_full_audit_opendir(vfs_handle_struct *handle,
                          const char *fname, const char *mask, uint32 attr)
 {
@@ -2103,6 +2183,11 @@ static struct vfs_fn_pointers vfs_full_audit_fns = {
        .get_shadow_copy_data_fn = smb_full_audit_get_shadow_copy_data,
        .statvfs_fn = smb_full_audit_statvfs,
        .fs_capabilities_fn = smb_full_audit_fs_capabilities,
+       .snap_check_path_fn =  smb_full_audit_snap_check_path,
+       .snap_create_send_fn = smb_full_audit_snap_create_send,
+       .snap_create_recv_fn = smb_full_audit_snap_create_recv,
+       .snap_delete_send_fn = smb_full_audit_snap_delete_send,
+       .snap_delete_recv_fn = smb_full_audit_snap_delete_recv,
        .opendir_fn = smb_full_audit_opendir,
        .fdopendir_fn = smb_full_audit_fdopendir,
        .readdir_fn = smb_full_audit_readdir,
index 1b14d650afd3f07b1f5325acd15db93a634b187b..f9ad1a98376cc8653cc6a0beb23a6f7127d95cef 100644 (file)
@@ -279,9 +279,178 @@ static uint32_t smb_time_audit_fs_capabilities(struct vfs_handle_struct *handle,
        return result;
 }
 
+static NTSTATUS smb_time_audit_snap_check_path(struct vfs_handle_struct *handle,
+                                              TALLOC_CTX *mem_ctx,
+                                              const char *service_path,
+                                              char **base_volume)
+{
+       NTSTATUS status;
+       struct timespec ts1,ts2;
+       double timediff;
+
+       clock_gettime_mono(&ts1);
+       status = SMB_VFS_NEXT_SNAP_CHECK_PATH(handle, mem_ctx, service_path,
+                                             base_volume);
+       clock_gettime_mono(&ts2);
+       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+
+       if (timediff > audit_timeout) {
+               smb_time_audit_log("snap_check_path", timediff);
+       }
+
+       return status;
+}
+
+struct time_audit_sc_state {
+       struct timespec ts_send;
+       struct vfs_handle_struct *handle;
+       char *base_path;
+       char *snap_path;
+       NTSTATUS status;
+       struct tevent_req *subreq;
+};
+static void smb_time_audit_snap_create_done(struct tevent_req *subreq);
+
+static struct tevent_req *smb_time_audit_snap_create_send(struct vfs_handle_struct *handle,
+                                                         TALLOC_CTX *mem_ctx,
+                                                         struct tevent_context *ev,
+                                                         const char *base_volume,
+                                                         time_t *tstamp,
+                                                         bool rw)
+{
+       struct tevent_req *req;
+       struct time_audit_sc_state *sc_state;
+
+       req = tevent_req_create(mem_ctx, &sc_state, struct time_audit_sc_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       sc_state->handle = handle;
+       sc_state->status = NT_STATUS_OK;
+       clock_gettime_mono(&sc_state->ts_send);
+       sc_state->subreq = SMB_VFS_NEXT_SNAP_CREATE_SEND(handle, sc_state, ev,
+                                                        base_volume, tstamp,
+                                                        rw);
+       if (tevent_req_nomem(sc_state->subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+
+       tevent_req_set_callback(sc_state->subreq,
+                               smb_time_audit_snap_create_done,
+                               req);
+       return req;
+}
+
+static void smb_time_audit_snap_create_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct time_audit_sc_state *sc_state
+                       = tevent_req_data(req, struct time_audit_sc_state);
+
+       sc_state->status = SMB_VFS_NEXT_SNAP_CREATE_RECV(sc_state->handle,
+                                                        sc_state->subreq,
+                                                        sc_state,
+                                                        &sc_state->base_path,
+                                                        &sc_state->snap_path);
+       if (tevent_req_nterror(req, sc_state->status)) {
+               return;
+       }
+       tevent_req_done(req);
+}
+
+static NTSTATUS smb_time_audit_snap_create_recv(struct vfs_handle_struct *handle,
+                                               struct tevent_req *req,
+                                               TALLOC_CTX *mem_ctx,
+                                               char **base_path, char **snap_path)
+{
+       struct time_audit_sc_state *sc_state
+                       = tevent_req_data(req, struct time_audit_sc_state);
+       struct timespec ts_recv;
+       double timediff;
+
+       clock_gettime_mono(&ts_recv);
+       timediff = nsec_time_diff(&ts_recv, &sc_state->ts_send)*1.0e-9;
+       if (timediff > audit_timeout) {
+               smb_time_audit_log("snap_create", timediff);
+       }
+
+       *base_path = talloc_strdup(mem_ctx, sc_state->base_path);
+       *snap_path = talloc_strdup(mem_ctx, sc_state->snap_path);
+       return sc_state->status;
+}
+
+struct time_audit_sd_state {
+       struct timespec ts_send;
+       struct vfs_handle_struct *handle;
+       NTSTATUS status;
+       struct tevent_req *subreq;
+};
+static void smb_time_audit_snap_delete_done(struct tevent_req *subreq);
+
+static struct tevent_req *smb_time_audit_snap_delete_send(struct vfs_handle_struct *handle,
+                                                         TALLOC_CTX *mem_ctx,
+                                                         struct tevent_context *ev,
+                                                         char *snap_path)
+{
+       struct tevent_req *req;
+       struct time_audit_sd_state *sd_state;
+
+       req = tevent_req_create(mem_ctx, &sd_state, struct time_audit_sd_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       sd_state->handle = handle;
+       sd_state->status = NT_STATUS_OK;
+       clock_gettime_mono(&sd_state->ts_send);
+       sd_state->subreq = SMB_VFS_NEXT_SNAP_DELETE_SEND(handle, sd_state, ev, snap_path);
+       if (tevent_req_nomem(sd_state->subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+
+       tevent_req_set_callback(sd_state->subreq,
+                               smb_time_audit_snap_delete_done,
+                               req);
+       return req;
+}
+
+static void smb_time_audit_snap_delete_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct time_audit_sd_state *sd_state
+                       = tevent_req_data(req, struct time_audit_sd_state);
+
+       sd_state->status = SMB_VFS_NEXT_SNAP_DELETE_RECV(sd_state->handle,
+                                                        sd_state->subreq);
+       if (tevent_req_nterror(req, sd_state->status)) {
+               return;
+       }
+       tevent_req_done(req);
+}
+
+static NTSTATUS smb_time_audit_snap_delete_recv(struct vfs_handle_struct *handle,
+                                               struct tevent_req *req)
+{
+       struct time_audit_sd_state *sd_state
+                       = tevent_req_data(req, struct time_audit_sd_state);
+       struct timespec ts_recv;
+       double timediff;
+
+       clock_gettime_mono(&ts_recv);
+       timediff = nsec_time_diff(&ts_recv, &sd_state->ts_send)*1.0e-9;
+       if (timediff > audit_timeout) {
+               smb_time_audit_log("snap_delete", timediff);
+       }
+
+       return sd_state->status;
+}
+
 static DIR *smb_time_audit_opendir(vfs_handle_struct *handle,
-                                             const char *fname,
-                                             const char *mask, uint32 attr)
+                                  const char *fname,
+                                  const char *mask, uint32 attr)
 {
        DIR *result;
        struct timespec ts1,ts2;
@@ -2198,6 +2367,11 @@ static struct vfs_fn_pointers vfs_time_audit_fns = {
        .get_shadow_copy_data_fn = smb_time_audit_get_shadow_copy_data,
        .statvfs_fn = smb_time_audit_statvfs,
        .fs_capabilities_fn = smb_time_audit_fs_capabilities,
+       .snap_check_path_fn = smb_time_audit_snap_check_path,
+       .snap_create_send_fn = smb_time_audit_snap_create_send,
+       .snap_create_recv_fn = smb_time_audit_snap_create_recv,
+       .snap_delete_send_fn = smb_time_audit_snap_delete_send,
+       .snap_delete_recv_fn = smb_time_audit_snap_delete_recv,
        .opendir_fn = smb_time_audit_opendir,
        .fdopendir_fn = smb_time_audit_fdopendir,
        .readdir_fn = smb_time_audit_readdir,
index b81e8ded3f9c679e093d57723dc64df0e048ac20..c29f393d91e0851abaafa21a3be3d5d168cb7d0d 100644 (file)
@@ -2184,6 +2184,54 @@ NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
        return handle->fns->copy_chunk_recv_fn(handle, req, copied);
 }
 
+NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
+                                     TALLOC_CTX *mem_ctx,
+                                     const char *service_path,
+                                     char **base_volume)
+{
+       VFS_FIND(snap_check_path);
+       return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
+                                              base_volume);
+}
+
+struct tevent_req *smb_vfs_call_snap_create_send(struct vfs_handle_struct *handle,
+                                                TALLOC_CTX *mem_ctx,
+                                                struct tevent_context *ev,
+                                                const char *base_volume,
+                                                time_t *tstamp,
+                                                bool rw)
+{
+       VFS_FIND(snap_create_send);
+       return handle->fns->snap_create_send_fn(handle, mem_ctx, ev,
+                                               base_volume, tstamp, rw);
+}
+
+NTSTATUS smb_vfs_call_snap_create_recv(struct vfs_handle_struct *handle,
+                                      struct tevent_req *req,
+                                      TALLOC_CTX *mem_ctx,
+                                      char **base_path, char **snap_path)
+{
+       VFS_FIND(snap_create_recv);
+       return handle->fns->snap_create_recv_fn(handle, req, mem_ctx,
+                                               base_path, snap_path);
+}
+
+struct tevent_req *smb_vfs_call_snap_delete_send(struct vfs_handle_struct *handle,
+                                                TALLOC_CTX *mem_ctx,
+                                                struct tevent_context *ev,
+                                                char *snap_path)
+{
+       VFS_FIND(snap_delete_send);
+       return handle->fns->snap_delete_send_fn(handle, mem_ctx, ev, snap_path);
+}
+
+NTSTATUS smb_vfs_call_snap_delete_recv(struct vfs_handle_struct *handle,
+                                      struct tevent_req *req)
+{
+       VFS_FIND(snap_delete_recv);
+       return handle->fns->snap_delete_recv_fn(handle, req);
+}
+
 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
                                  struct files_struct *fsp,
                                  uint32 security_info,