vfs: change openat propotype to match linux openat2
[samba.git] / source3 / modules / vfs_time_audit.c
1 /*
2  * Time auditing VFS module for samba.  Log time taken for VFS call to syslog
3  * facility.
4  *
5  * Copyright (C) Abhidnya Chirmule <achirmul@in.ibm.com> 2009
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 /*
22  * This module implements logging for time taken for all Samba VFS operations.
23  *
24  * vfs objects = time_audit
25  */
26
27
28 #include "includes.h"
29 #include "smbd/smbd.h"
30 #include "ntioctl.h"
31 #include "lib/util/tevent_unix.h"
32 #include "lib/util/tevent_ntstatus.h"
33
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_VFS
36
37 static double audit_timeout;
38
39 static void smb_time_audit_log_msg(const char *syscallname, double elapsed,
40                                     const char *msg)
41 {
42         DEBUG(0, ("WARNING: VFS call \"%s\" took unexpectedly long "
43                   "(%.2f seconds) %s%s-- Validate that file and storage "
44                   "subsystems are operating normally\n", syscallname,
45                   elapsed, (msg != NULL) ? msg : "",
46                   (msg != NULL) ? " " : ""));
47 }
48
49 static void smb_time_audit_log(const char *syscallname, double elapsed)
50 {
51         smb_time_audit_log_msg(syscallname, elapsed, NULL);
52 }
53
54 static void smb_time_audit_log_fsp(const char *syscallname, double elapsed,
55                                    const struct files_struct *fsp)
56 {
57         char *base_name = NULL;
58         char *connectpath = NULL;
59         char *msg = NULL;
60
61         if (fsp == NULL) {
62                 smb_time_audit_log(syscallname, elapsed);
63                 return;
64         }
65         if (fsp->conn)
66                 connectpath = fsp->conn->connectpath;
67         if (fsp->fsp_name)
68                 base_name = fsp->fsp_name->base_name;
69
70         if (connectpath != NULL && base_name != NULL) {
71                 msg = talloc_asprintf(talloc_tos(), "filename = \"%s/%s\"",
72                                       connectpath, base_name);
73         } else if (connectpath != NULL && base_name == NULL) {
74                 msg = talloc_asprintf(talloc_tos(), "connectpath = \"%s\", "
75                                       "base_name = <NULL>",
76                                       connectpath);
77         } else if (connectpath == NULL && base_name != NULL) {
78                 msg = talloc_asprintf(talloc_tos(), "connectpath = <NULL>, "
79                                       "base_name = \"%s\"",
80                                       base_name);
81         } else { /* connectpath == NULL && base_name == NULL */
82                 msg = talloc_asprintf(talloc_tos(), "connectpath = <NULL>, "
83                                       "base_name = <NULL>");
84         }
85         smb_time_audit_log_msg(syscallname, elapsed, msg);
86         TALLOC_FREE(msg);
87 }
88
89 static void smb_time_audit_log_at(const char *syscallname,
90                                   double elapsed,
91                                   const struct files_struct *dir_fsp,
92                                   const struct smb_filename *smb_fname)
93 {
94         char *msg = NULL;
95
96         msg = talloc_asprintf(talloc_tos(),
97                               "filename = \"%s/%s/%s\"",
98                               dir_fsp->conn->connectpath,
99                               dir_fsp->fsp_name->base_name,
100                               smb_fname->base_name);
101
102         smb_time_audit_log_msg(syscallname, elapsed, msg);
103         TALLOC_FREE(msg);
104 }
105
106 static void smb_time_audit_log_fname(const char *syscallname, double elapsed,
107                                     const char *fname)
108 {
109         char cwd[PATH_MAX];
110         char *msg = NULL;
111
112         if (getcwd(cwd, sizeof(cwd)) == NULL) {
113                 snprintf(cwd, sizeof(cwd), "<getcwd() error %d>", errno);
114         }
115         if (fname != NULL) {
116                 msg = talloc_asprintf(talloc_tos(),
117                                       "cwd = \"%s\", filename = \"%s\"",
118                                       cwd, fname);
119         } else {
120                 msg = talloc_asprintf(talloc_tos(),
121                                       "cwd = \"%s\", filename = <NULL>",
122                                       cwd);
123         }
124         smb_time_audit_log_msg(syscallname, elapsed, msg);
125         TALLOC_FREE(msg);
126 }
127
128 static void smb_time_audit_log_smb_fname(const char *syscallname, double elapsed,
129                                        const struct smb_filename *smb_fname)
130 {
131         if (smb_fname != NULL) {
132                 smb_time_audit_log_fname(syscallname, elapsed,
133                                          smb_fname->base_name);
134         } else {
135                 smb_time_audit_log_fname(syscallname, elapsed,
136                                          "smb_fname = <NULL>");
137         }
138 }
139
140 static int smb_time_audit_connect(vfs_handle_struct *handle,
141                                   const char *svc, const char *user)
142 {
143         int result;
144         struct timespec ts1,ts2;
145         double timediff;
146
147         if (!handle) {
148                 return -1;
149         }
150
151         clock_gettime_mono(&ts1);
152         result = SMB_VFS_NEXT_CONNECT(handle, svc, user);
153         clock_gettime_mono(&ts2);
154         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
155         if (timediff > audit_timeout) {
156                 smb_time_audit_log_msg("connect", timediff, user);
157         }
158         return result;
159 }
160
161 static void smb_time_audit_disconnect(vfs_handle_struct *handle)
162 {
163         struct timespec ts1,ts2;
164         double timediff;
165
166         clock_gettime_mono(&ts1);
167         SMB_VFS_NEXT_DISCONNECT(handle);
168         clock_gettime_mono(&ts2);
169         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
170
171         if (timediff > audit_timeout) {
172                 smb_time_audit_log("disconnect", timediff);
173         }
174 }
175
176 static uint64_t smb_time_audit_disk_free(vfs_handle_struct *handle,
177                                         const struct smb_filename *smb_fname,
178                                         uint64_t *bsize,
179                                         uint64_t *dfree,
180                                         uint64_t *dsize)
181 {
182         uint64_t result;
183         struct timespec ts1,ts2;
184         double timediff;
185
186         clock_gettime_mono(&ts1);
187         result = SMB_VFS_NEXT_DISK_FREE(handle, smb_fname, bsize, dfree, dsize);
188         clock_gettime_mono(&ts2);
189         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
190
191         /* Don't have a reasonable notion of failure here */
192         if (timediff > audit_timeout) {
193                 smb_time_audit_log_fname("disk_free",
194                                 timediff,
195                                 smb_fname->base_name);
196         }
197
198         return result;
199 }
200
201 static int smb_time_audit_get_quota(struct vfs_handle_struct *handle,
202                                         const struct smb_filename *smb_fname,
203                                         enum SMB_QUOTA_TYPE qtype,
204                                         unid_t id,
205                                         SMB_DISK_QUOTA *qt)
206 {
207         int result;
208         struct timespec ts1,ts2;
209         double timediff;
210
211         clock_gettime_mono(&ts1);
212         result = SMB_VFS_NEXT_GET_QUOTA(handle, smb_fname, qtype, id, qt);
213         clock_gettime_mono(&ts2);
214         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
215
216         if (timediff > audit_timeout) {
217                 smb_time_audit_log_fname("get_quota",
218                                 timediff,
219                                 smb_fname->base_name);
220         }
221         return result;
222 }
223
224 static int smb_time_audit_set_quota(struct vfs_handle_struct *handle,
225                                     enum SMB_QUOTA_TYPE qtype, unid_t id,
226                                     SMB_DISK_QUOTA *qt)
227 {
228         int result;
229         struct timespec ts1,ts2;
230         double timediff;
231
232         clock_gettime_mono(&ts1);
233         result = SMB_VFS_NEXT_SET_QUOTA(handle, qtype, id, qt);
234         clock_gettime_mono(&ts2);
235         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
236
237         if (timediff > audit_timeout) {
238                 smb_time_audit_log("set_quota", timediff);
239         }
240
241         return result;
242 }
243
244 static int smb_time_audit_get_shadow_copy_data(struct vfs_handle_struct *handle,
245                                                struct files_struct *fsp,
246                                                struct shadow_copy_data *shadow_copy_data,
247                                                bool labels)
248 {
249         int result;
250         struct timespec ts1,ts2;
251         double timediff;
252
253         clock_gettime_mono(&ts1);
254         result = SMB_VFS_NEXT_GET_SHADOW_COPY_DATA(handle, fsp,
255                                                    shadow_copy_data, labels);
256         clock_gettime_mono(&ts2);
257         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
258
259         if (timediff > audit_timeout) {
260                 smb_time_audit_log_fsp("get_shadow_copy_data", timediff, fsp);
261         }
262
263         return result;
264 }
265
266 static int smb_time_audit_statvfs(struct vfs_handle_struct *handle,
267                                   const struct smb_filename *smb_fname,
268                                   struct vfs_statvfs_struct *statbuf)
269 {
270         int result;
271         struct timespec ts1,ts2;
272         double timediff;
273
274         clock_gettime_mono(&ts1);
275         result = SMB_VFS_NEXT_STATVFS(handle, smb_fname, statbuf);
276         clock_gettime_mono(&ts2);
277         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
278
279         if (timediff > audit_timeout) {
280                 smb_time_audit_log_fname("statvfs", timediff,
281                         smb_fname->base_name);
282         }
283
284         return result;
285 }
286
287 static uint32_t smb_time_audit_fs_capabilities(struct vfs_handle_struct *handle,
288                                                enum timestamp_set_resolution *p_ts_res)
289 {
290         uint32_t result;
291         struct timespec ts1,ts2;
292         double timediff;
293
294         clock_gettime_mono(&ts1);
295         result = SMB_VFS_NEXT_FS_CAPABILITIES(handle, p_ts_res);
296         clock_gettime_mono(&ts2);
297         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
298
299         if (timediff > audit_timeout) {
300                 smb_time_audit_log("fs_capabilities", timediff);
301         }
302
303         return result;
304 }
305
306 static NTSTATUS smb_time_audit_get_dfs_referrals(
307                         struct vfs_handle_struct *handle,
308                         struct dfs_GetDFSReferral *r)
309 {
310         NTSTATUS result;
311         struct timespec ts1,ts2;
312         double timediff;
313
314         clock_gettime_mono(&ts1);
315         result = SMB_VFS_NEXT_GET_DFS_REFERRALS(handle, r);
316         clock_gettime_mono(&ts2);
317         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
318
319         if (timediff > audit_timeout) {
320                 smb_time_audit_log("get_dfs_referrals", timediff);
321         }
322
323         return result;
324 }
325
326 static NTSTATUS smb_time_audit_create_dfs_pathat(struct vfs_handle_struct *handle,
327                         struct files_struct *dirfsp,
328                         const struct smb_filename *smb_fname,
329                         const struct referral *reflist,
330                         size_t referral_count)
331 {
332         NTSTATUS result;
333         struct timespec ts1,ts2;
334         double timediff;
335         struct smb_filename *full_fname = NULL;
336
337         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
338                                                   dirfsp,
339                                                   smb_fname);
340         if (full_fname == NULL) {
341                 return NT_STATUS_NO_MEMORY;
342         }
343
344         clock_gettime_mono(&ts1);
345         result = SMB_VFS_NEXT_CREATE_DFS_PATHAT(handle,
346                         dirfsp,
347                         smb_fname,
348                         reflist,
349                         referral_count);
350         clock_gettime_mono(&ts2);
351         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
352
353         if (timediff > audit_timeout) {
354                 smb_time_audit_log_smb_fname("create_dfs_pathat",
355                         timediff,
356                         full_fname);
357         }
358         TALLOC_FREE(full_fname);
359         return result;
360 }
361
362 static NTSTATUS smb_time_audit_read_dfs_pathat(struct vfs_handle_struct *handle,
363                         TALLOC_CTX *mem_ctx,
364                         struct files_struct *dirfsp,
365                         struct smb_filename *smb_fname,
366                         struct referral **ppreflist,
367                         size_t *preferral_count)
368 {
369         NTSTATUS result;
370         struct timespec ts1,ts2;
371         double timediff;
372         struct smb_filename *full_fname = NULL;
373
374         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
375                                                   dirfsp,
376                                                   smb_fname);
377         if (full_fname == NULL) {
378                 return NT_STATUS_NO_MEMORY;
379         }
380
381         clock_gettime_mono(&ts1);
382         result = SMB_VFS_NEXT_READ_DFS_PATHAT(handle,
383                         mem_ctx,
384                         dirfsp,
385                         smb_fname,
386                         ppreflist,
387                         preferral_count);
388         clock_gettime_mono(&ts2);
389         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
390
391         if (timediff > audit_timeout) {
392                 smb_time_audit_log_smb_fname("read_dfs_pathat",
393                         timediff,
394                         full_fname);
395         }
396
397         TALLOC_FREE(full_fname);
398         return result;
399 }
400
401 static NTSTATUS smb_time_audit_snap_check_path(struct vfs_handle_struct *handle,
402                                                TALLOC_CTX *mem_ctx,
403                                                const char *service_path,
404                                                char **base_volume)
405 {
406         NTSTATUS status;
407         struct timespec ts1,ts2;
408         double timediff;
409
410         clock_gettime_mono(&ts1);
411         status = SMB_VFS_NEXT_SNAP_CHECK_PATH(handle, mem_ctx, service_path,
412                                               base_volume);
413         clock_gettime_mono(&ts2);
414         timediff = nsec_time_diff(&ts2, &ts1) * 1.0e-9;
415
416         if (timediff > audit_timeout) {
417                 smb_time_audit_log("snap_check_path", timediff);
418         }
419
420         return status;
421 }
422
423 static NTSTATUS smb_time_audit_snap_create(struct vfs_handle_struct *handle,
424                                            TALLOC_CTX *mem_ctx,
425                                            const char *base_volume,
426                                            time_t *tstamp,
427                                            bool rw,
428                                            char **base_path,
429                                            char **snap_path)
430 {
431         NTSTATUS status;
432         struct timespec ts1,ts2;
433         double timediff;
434
435         clock_gettime_mono(&ts1);
436         status = SMB_VFS_NEXT_SNAP_CREATE(handle, mem_ctx, base_volume, tstamp,
437                                           rw, base_path, snap_path);
438         clock_gettime_mono(&ts2);
439         timediff = nsec_time_diff(&ts2 ,&ts1) * 1.0e-9;
440
441         if (timediff > audit_timeout) {
442                 smb_time_audit_log("snap_create", timediff);
443         }
444
445         return status;
446 }
447
448 static NTSTATUS smb_time_audit_snap_delete(struct vfs_handle_struct *handle,
449                                            TALLOC_CTX *mem_ctx,
450                                            char *base_path,
451                                            char *snap_path)
452 {
453         NTSTATUS status;
454         struct timespec ts1,ts2;
455         double timediff;
456
457         clock_gettime_mono(&ts1);
458         status = SMB_VFS_NEXT_SNAP_DELETE(handle, mem_ctx, base_path,
459                                           snap_path);
460         clock_gettime_mono(&ts2);
461         timediff = nsec_time_diff(&ts2, &ts1) * 1.0e-9;
462
463         if (timediff > audit_timeout) {
464                 smb_time_audit_log("snap_delete", timediff);
465         }
466
467         return status;
468 }
469
470 static DIR *smb_time_audit_fdopendir(vfs_handle_struct *handle,
471                                               files_struct *fsp,
472                                               const char *mask, uint32_t attr)
473 {
474         DIR *result;
475         struct timespec ts1,ts2;
476         double timediff;
477
478         clock_gettime_mono(&ts1);
479         result = SMB_VFS_NEXT_FDOPENDIR(handle, fsp, mask, attr);
480         clock_gettime_mono(&ts2);
481         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
482
483         if (timediff > audit_timeout) {
484                 smb_time_audit_log_fsp("fdopendir", timediff, fsp);
485         }
486
487         return result;
488 }
489
490 static struct dirent *smb_time_audit_readdir(vfs_handle_struct *handle,
491                                              struct files_struct *dirfsp,
492                                              DIR *dirp,
493                                              SMB_STRUCT_STAT *sbuf)
494 {
495         struct dirent *result;
496         struct timespec ts1,ts2;
497         double timediff;
498
499         clock_gettime_mono(&ts1);
500         result = SMB_VFS_NEXT_READDIR(handle, dirfsp, dirp, sbuf);
501         clock_gettime_mono(&ts2);
502         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
503
504         if (timediff > audit_timeout) {
505                 smb_time_audit_log("readdir", timediff);
506         }
507
508         return result;
509 }
510
511 static void smb_time_audit_seekdir(vfs_handle_struct *handle,
512                                    DIR *dirp, long offset)
513 {
514         struct timespec ts1,ts2;
515         double timediff;
516
517         clock_gettime_mono(&ts1);
518         SMB_VFS_NEXT_SEEKDIR(handle, dirp, offset);
519         clock_gettime_mono(&ts2);
520         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
521
522         if (timediff > audit_timeout) {
523                 smb_time_audit_log("seekdir", timediff);
524         }
525
526 }
527
528 static long smb_time_audit_telldir(vfs_handle_struct *handle,
529                                    DIR *dirp)
530 {
531         long result;
532         struct timespec ts1,ts2;
533         double timediff;
534
535         clock_gettime_mono(&ts1);
536         result = SMB_VFS_NEXT_TELLDIR(handle, dirp);
537         clock_gettime_mono(&ts2);
538         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
539
540         if (timediff > audit_timeout) {
541                 smb_time_audit_log("telldir", timediff);
542         }
543
544         return result;
545 }
546
547 static void smb_time_audit_rewinddir(vfs_handle_struct *handle,
548                                      DIR *dirp)
549 {
550         struct timespec ts1,ts2;
551         double timediff;
552
553         clock_gettime_mono(&ts1);
554         SMB_VFS_NEXT_REWINDDIR(handle, dirp);
555         clock_gettime_mono(&ts2);
556         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
557
558         if (timediff > audit_timeout) {
559                 smb_time_audit_log("rewinddir", timediff);
560         }
561
562 }
563
564 static int smb_time_audit_mkdirat(vfs_handle_struct *handle,
565                                 struct files_struct *dirfsp,
566                                 const struct smb_filename *smb_fname,
567                                 mode_t mode)
568 {
569         struct smb_filename *full_fname = NULL;
570         int result;
571         struct timespec ts1,ts2;
572         double timediff;
573
574         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
575                                                   dirfsp,
576                                                   smb_fname);
577         if (full_fname == NULL) {
578                 errno = ENOMEM;
579                 return -1;
580         }
581
582         clock_gettime_mono(&ts1);
583         result = SMB_VFS_NEXT_MKDIRAT(handle,
584                                 dirfsp,
585                                 smb_fname,
586                                 mode);
587         clock_gettime_mono(&ts2);
588         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
589
590         if (timediff > audit_timeout) {
591                 smb_time_audit_log_smb_fname("mkdirat",
592                         timediff,
593                         full_fname);
594         }
595
596         TALLOC_FREE(full_fname);
597
598         return result;
599 }
600
601 static int smb_time_audit_closedir(vfs_handle_struct *handle,
602                                    DIR *dirp)
603 {
604         int result;
605         struct timespec ts1,ts2;
606         double timediff;
607
608         clock_gettime_mono(&ts1);
609         result = SMB_VFS_NEXT_CLOSEDIR(handle, dirp);
610         clock_gettime_mono(&ts2);
611         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
612
613         if (timediff > audit_timeout) {
614                 smb_time_audit_log("closedir", timediff);
615         }
616
617         return result;
618 }
619
620 static int smb_time_audit_openat(vfs_handle_struct *handle,
621                                  const struct files_struct *dirfsp,
622                                  const struct smb_filename *smb_fname,
623                                  struct files_struct *fsp,
624                                  const struct vfs_open_how *how)
625 {
626         int result;
627         struct timespec ts1,ts2;
628         double timediff;
629
630         clock_gettime_mono(&ts1);
631         result = SMB_VFS_NEXT_OPENAT(handle,
632                                      dirfsp,
633                                      smb_fname,
634                                      fsp,
635                                      how);
636         clock_gettime_mono(&ts2);
637         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
638
639         if (timediff > audit_timeout) {
640                 smb_time_audit_log_fsp("openat", timediff, fsp);
641         }
642
643         return result;
644 }
645
646 static NTSTATUS smb_time_audit_create_file(vfs_handle_struct *handle,
647                                            struct smb_request *req,
648                                            struct files_struct *dirfsp,
649                                            struct smb_filename *fname,
650                                            uint32_t access_mask,
651                                            uint32_t share_access,
652                                            uint32_t create_disposition,
653                                            uint32_t create_options,
654                                            uint32_t file_attributes,
655                                            uint32_t oplock_request,
656                                            const struct smb2_lease *lease,
657                                            uint64_t allocation_size,
658                                            uint32_t private_flags,
659                                            struct security_descriptor *sd,
660                                            struct ea_list *ea_list,
661                                            files_struct **result_fsp,
662                                            int *pinfo,
663                                            const struct smb2_create_blobs *in_context_blobs,
664                                            struct smb2_create_blobs *out_context_blobs)
665 {
666         NTSTATUS result;
667         struct timespec ts1,ts2;
668         double timediff;
669
670         clock_gettime_mono(&ts1);
671         result = SMB_VFS_NEXT_CREATE_FILE(
672                 handle,                                 /* handle */
673                 req,                                    /* req */
674                 dirfsp,                                 /* dirfsp */
675                 fname,                                  /* fname */
676                 access_mask,                            /* access_mask */
677                 share_access,                           /* share_access */
678                 create_disposition,                     /* create_disposition*/
679                 create_options,                         /* create_options */
680                 file_attributes,                        /* file_attributes */
681                 oplock_request,                         /* oplock_request */
682                 lease,                                  /* lease */
683                 allocation_size,                        /* allocation_size */
684                 private_flags,
685                 sd,                                     /* sd */
686                 ea_list,                                /* ea_list */
687                 result_fsp,                             /* result */
688                 pinfo,
689                 in_context_blobs, out_context_blobs);   /* create context */
690         clock_gettime_mono(&ts2);
691         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
692
693         if (timediff > audit_timeout) {
694                 /*
695                  * can't use result_fsp this time, may have
696                  * invalid content causing smbd crash
697                  */
698                 smb_time_audit_log_smb_fname("create_file", timediff,
699                                            fname);
700         }
701
702         return result;
703 }
704
705 static int smb_time_audit_close(vfs_handle_struct *handle, files_struct *fsp)
706 {
707         int result;
708         struct timespec ts1,ts2;
709         double timediff;
710
711         clock_gettime_mono(&ts1);
712         result = SMB_VFS_NEXT_CLOSE(handle, fsp);
713         clock_gettime_mono(&ts2);
714         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
715
716         if (timediff > audit_timeout) {
717                 smb_time_audit_log_fsp("close", timediff, fsp);
718         }
719
720         return result;
721 }
722
723 static ssize_t smb_time_audit_pread(vfs_handle_struct *handle,
724                                     files_struct *fsp,
725                                     void *data, size_t n, off_t offset)
726 {
727         ssize_t result;
728         struct timespec ts1,ts2;
729         double timediff;
730
731         clock_gettime_mono(&ts1);
732         result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
733         clock_gettime_mono(&ts2);
734         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
735
736         if (timediff > audit_timeout) {
737                 smb_time_audit_log_fsp("pread", timediff, fsp);
738         }
739
740         return result;
741 }
742
743 struct smb_time_audit_pread_state {
744         struct files_struct *fsp;
745         ssize_t ret;
746         struct vfs_aio_state vfs_aio_state;
747 };
748
749 static void smb_time_audit_pread_done(struct tevent_req *subreq);
750
751 static struct tevent_req *smb_time_audit_pread_send(
752         struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx,
753         struct tevent_context *ev, struct files_struct *fsp,
754         void *data, size_t n, off_t offset)
755 {
756         struct tevent_req *req, *subreq;
757         struct smb_time_audit_pread_state *state;
758
759         req = tevent_req_create(mem_ctx, &state,
760                                 struct smb_time_audit_pread_state);
761         if (req == NULL) {
762                 return NULL;
763         }
764         state->fsp = fsp;
765
766         subreq = SMB_VFS_NEXT_PREAD_SEND(state, ev, handle, fsp, data,
767                                          n, offset);
768         if (tevent_req_nomem(subreq, req)) {
769                 return tevent_req_post(req, ev);
770         }
771         tevent_req_set_callback(subreq, smb_time_audit_pread_done, req);
772         return req;
773 }
774
775 static void smb_time_audit_pread_done(struct tevent_req *subreq)
776 {
777         struct tevent_req *req = tevent_req_callback_data(
778                 subreq, struct tevent_req);
779         struct smb_time_audit_pread_state *state = tevent_req_data(
780                 req, struct smb_time_audit_pread_state);
781
782         state->ret = SMB_VFS_PREAD_RECV(subreq, &state->vfs_aio_state);
783         TALLOC_FREE(subreq);
784         tevent_req_done(req);
785 }
786
787 static ssize_t smb_time_audit_pread_recv(struct tevent_req *req,
788                                          struct vfs_aio_state *vfs_aio_state)
789 {
790         struct smb_time_audit_pread_state *state = tevent_req_data(
791                 req, struct smb_time_audit_pread_state);
792         double timediff;
793
794         timediff = state->vfs_aio_state.duration * 1.0e-9;
795
796         if (timediff > audit_timeout) {
797                 smb_time_audit_log_fsp("async pread", timediff, state->fsp);
798         }
799
800         if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
801                 return -1;
802         }
803         *vfs_aio_state = state->vfs_aio_state;
804         return state->ret;
805 }
806
807 static ssize_t smb_time_audit_pwrite(vfs_handle_struct *handle,
808                                      files_struct *fsp,
809                                      const void *data, size_t n,
810                                      off_t offset)
811 {
812         ssize_t result;
813         struct timespec ts1,ts2;
814         double timediff;
815
816         clock_gettime_mono(&ts1);
817         result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
818         clock_gettime_mono(&ts2);
819         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
820
821         if (timediff > audit_timeout) {
822                 smb_time_audit_log_fsp("pwrite", timediff, fsp);
823         }
824
825         return result;
826 }
827
828 struct smb_time_audit_pwrite_state {
829         struct files_struct *fsp;
830         ssize_t ret;
831         struct vfs_aio_state vfs_aio_state;
832 };
833
834 static void smb_time_audit_pwrite_done(struct tevent_req *subreq);
835
836 static struct tevent_req *smb_time_audit_pwrite_send(
837         struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx,
838         struct tevent_context *ev, struct files_struct *fsp,
839         const void *data, size_t n, off_t offset)
840 {
841         struct tevent_req *req, *subreq;
842         struct smb_time_audit_pwrite_state *state;
843
844         req = tevent_req_create(mem_ctx, &state,
845                                 struct smb_time_audit_pwrite_state);
846         if (req == NULL) {
847                 return NULL;
848         }
849         state->fsp = fsp;
850
851         subreq = SMB_VFS_NEXT_PWRITE_SEND(state, ev, handle, fsp, data,
852                                          n, offset);
853         if (tevent_req_nomem(subreq, req)) {
854                 return tevent_req_post(req, ev);
855         }
856         tevent_req_set_callback(subreq, smb_time_audit_pwrite_done, req);
857         return req;
858 }
859
860 static void smb_time_audit_pwrite_done(struct tevent_req *subreq)
861 {
862         struct tevent_req *req = tevent_req_callback_data(
863                 subreq, struct tevent_req);
864         struct smb_time_audit_pwrite_state *state = tevent_req_data(
865                 req, struct smb_time_audit_pwrite_state);
866
867         state->ret = SMB_VFS_PWRITE_RECV(subreq, &state->vfs_aio_state);
868         TALLOC_FREE(subreq);
869         tevent_req_done(req);
870 }
871
872 static ssize_t smb_time_audit_pwrite_recv(struct tevent_req *req,
873                                           struct vfs_aio_state *vfs_aio_state)
874 {
875         struct smb_time_audit_pwrite_state *state = tevent_req_data(
876                 req, struct smb_time_audit_pwrite_state);
877         double timediff;
878
879         timediff = state->vfs_aio_state.duration * 1.0e-9;
880
881         if (timediff > audit_timeout) {
882                 smb_time_audit_log_fsp("async pwrite", timediff, state->fsp);
883         }
884
885         if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
886                 return -1;
887         }
888         *vfs_aio_state = state->vfs_aio_state;
889         return state->ret;
890 }
891
892 static off_t smb_time_audit_lseek(vfs_handle_struct *handle,
893                                       files_struct *fsp,
894                                       off_t offset, int whence)
895 {
896         off_t result;
897         struct timespec ts1,ts2;
898         double timediff;
899
900         clock_gettime_mono(&ts1);
901         result = SMB_VFS_NEXT_LSEEK(handle, fsp, offset, whence);
902         clock_gettime_mono(&ts2);
903         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
904
905         if (timediff > audit_timeout) {
906                 smb_time_audit_log_fsp("lseek", timediff, fsp);
907         }
908
909         return result;
910 }
911
912 static ssize_t smb_time_audit_sendfile(vfs_handle_struct *handle, int tofd,
913                                        files_struct *fromfsp,
914                                        const DATA_BLOB *hdr, off_t offset,
915                                        size_t n)
916 {
917         ssize_t result;
918         struct timespec ts1,ts2;
919         double timediff;
920
921         clock_gettime_mono(&ts1);
922         result = SMB_VFS_NEXT_SENDFILE(handle, tofd, fromfsp, hdr, offset, n);
923         clock_gettime_mono(&ts2);
924         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
925
926         if (timediff > audit_timeout) {
927                 smb_time_audit_log_fsp("sendfile", timediff, fromfsp);
928         }
929
930         return result;
931 }
932
933 static ssize_t smb_time_audit_recvfile(vfs_handle_struct *handle, int fromfd,
934                                        files_struct *tofsp,
935                                        off_t offset,
936                                        size_t n)
937 {
938         ssize_t result;
939         struct timespec ts1,ts2;
940         double timediff;
941
942         clock_gettime_mono(&ts1);
943         result = SMB_VFS_NEXT_RECVFILE(handle, fromfd, tofsp, offset, n);
944         clock_gettime_mono(&ts2);
945         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
946
947         if (timediff > audit_timeout) {
948                 smb_time_audit_log_fsp("recvfile", timediff, tofsp);
949         }
950
951         return result;
952 }
953
954 static int smb_time_audit_renameat(vfs_handle_struct *handle,
955                                 files_struct *srcfsp,
956                                 const struct smb_filename *oldname,
957                                 files_struct *dstfsp,
958                                 const struct smb_filename *newname)
959 {
960         int result;
961         struct timespec ts1,ts2;
962         double timediff;
963         struct smb_filename *new_full_fname = NULL;
964
965         new_full_fname = full_path_from_dirfsp_atname(talloc_tos(),
966                                                   dstfsp,
967                                                   newname);
968         if (new_full_fname == NULL) {
969                 errno = ENOMEM;
970                 return -1;
971         }
972         clock_gettime_mono(&ts1);
973         result = SMB_VFS_NEXT_RENAMEAT(handle,
974                         srcfsp,
975                         oldname,
976                         dstfsp,
977                         newname);
978         clock_gettime_mono(&ts2);
979         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
980
981         if (timediff > audit_timeout) {
982                 smb_time_audit_log_smb_fname("renameat",
983                                         timediff,
984                                         new_full_fname);
985         }
986
987         TALLOC_FREE(new_full_fname);
988         return result;
989 }
990
991 struct smb_time_audit_fsync_state {
992         struct files_struct *fsp;
993         int ret;
994         struct vfs_aio_state vfs_aio_state;
995 };
996
997 static void smb_time_audit_fsync_done(struct tevent_req *subreq);
998
999 static struct tevent_req *smb_time_audit_fsync_send(
1000         struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx,
1001         struct tevent_context *ev, struct files_struct *fsp)
1002 {
1003         struct tevent_req *req, *subreq;
1004         struct smb_time_audit_fsync_state *state;
1005
1006         req = tevent_req_create(mem_ctx, &state,
1007                                 struct smb_time_audit_fsync_state);
1008         if (req == NULL) {
1009                 return NULL;
1010         }
1011         state->fsp = fsp;
1012
1013         subreq = SMB_VFS_NEXT_FSYNC_SEND(state, ev, handle, fsp);
1014         if (tevent_req_nomem(subreq, req)) {
1015                 return tevent_req_post(req, ev);
1016         }
1017         tevent_req_set_callback(subreq, smb_time_audit_fsync_done, req);
1018         return req;
1019 }
1020
1021 static void smb_time_audit_fsync_done(struct tevent_req *subreq)
1022 {
1023         struct tevent_req *req = tevent_req_callback_data(
1024                 subreq, struct tevent_req);
1025         struct smb_time_audit_fsync_state *state = tevent_req_data(
1026                 req, struct smb_time_audit_fsync_state);
1027
1028         state->ret = SMB_VFS_FSYNC_RECV(subreq, &state->vfs_aio_state);
1029         TALLOC_FREE(subreq);
1030         tevent_req_done(req);
1031 }
1032
1033 static int smb_time_audit_fsync_recv(struct tevent_req *req,
1034                                      struct vfs_aio_state *vfs_aio_state)
1035 {
1036         struct smb_time_audit_fsync_state *state = tevent_req_data(
1037                 req, struct smb_time_audit_fsync_state);
1038         double timediff;
1039
1040         timediff = state->vfs_aio_state.duration * 1.0e-9;
1041
1042         if (timediff > audit_timeout) {
1043                 smb_time_audit_log_fsp("async fsync", timediff, state->fsp);
1044         }
1045
1046         if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1047                 return -1;
1048         }
1049         *vfs_aio_state = state->vfs_aio_state;
1050         return state->ret;
1051 }
1052
1053 static int smb_time_audit_stat(vfs_handle_struct *handle,
1054                                struct smb_filename *fname)
1055 {
1056         int result;
1057         struct timespec ts1,ts2;
1058         double timediff;
1059
1060         clock_gettime_mono(&ts1);
1061         result = SMB_VFS_NEXT_STAT(handle, fname);
1062         clock_gettime_mono(&ts2);
1063         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1064
1065         if (timediff > audit_timeout) {
1066                 smb_time_audit_log_smb_fname("stat", timediff, fname);
1067         }
1068
1069         return result;
1070 }
1071
1072 static int smb_time_audit_fstat(vfs_handle_struct *handle, files_struct *fsp,
1073                                 SMB_STRUCT_STAT *sbuf)
1074 {
1075         int result;
1076         struct timespec ts1,ts2;
1077         double timediff;
1078
1079         clock_gettime_mono(&ts1);
1080         result = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
1081         clock_gettime_mono(&ts2);
1082         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1083
1084         if (timediff > audit_timeout) {
1085                 smb_time_audit_log_fsp("fstat", timediff, fsp);
1086         }
1087
1088         return result;
1089 }
1090
1091 static int smb_time_audit_lstat(vfs_handle_struct *handle,
1092                                 struct smb_filename *path)
1093 {
1094         int result;
1095         struct timespec ts1,ts2;
1096         double timediff;
1097
1098         clock_gettime_mono(&ts1);
1099         result = SMB_VFS_NEXT_LSTAT(handle, path);
1100         clock_gettime_mono(&ts2);
1101         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1102
1103         if (timediff > audit_timeout) {
1104                 smb_time_audit_log_smb_fname("lstat", timediff, path);
1105         }
1106
1107         return result;
1108 }
1109
1110 static int smb_time_audit_fstatat(
1111         struct vfs_handle_struct *handle,
1112         const struct files_struct *dirfsp,
1113         const struct smb_filename *smb_fname,
1114         SMB_STRUCT_STAT *sbuf,
1115         int flags)
1116 {
1117         int result;
1118         struct timespec ts1,ts2;
1119         double timediff;
1120
1121         clock_gettime_mono(&ts1);
1122         result = SMB_VFS_NEXT_FSTATAT(handle, dirfsp, smb_fname, sbuf, flags);
1123         clock_gettime_mono(&ts2);
1124         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1125
1126         if (timediff > audit_timeout) {
1127                 smb_time_audit_log_smb_fname("fstatat", timediff, smb_fname);
1128         }
1129
1130         return result;
1131 }
1132
1133 static uint64_t smb_time_audit_get_alloc_size(vfs_handle_struct *handle,
1134                                               files_struct *fsp,
1135                                               const SMB_STRUCT_STAT *sbuf)
1136 {
1137         uint64_t result;
1138         struct timespec ts1,ts2;
1139         double timediff;
1140
1141         clock_gettime_mono(&ts1);
1142         result = SMB_VFS_NEXT_GET_ALLOC_SIZE(handle, fsp, sbuf);
1143         clock_gettime_mono(&ts2);
1144         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1145
1146         if (timediff > audit_timeout) {
1147                 smb_time_audit_log_fsp("get_alloc_size", timediff, fsp);
1148         }
1149
1150         return result;
1151 }
1152
1153 static int smb_time_audit_unlinkat(vfs_handle_struct *handle,
1154                         struct files_struct *dirfsp,
1155                         const struct smb_filename *path,
1156                         int flags)
1157 {
1158         struct smb_filename *full_fname = NULL;
1159         int result;
1160         struct timespec ts1,ts2;
1161         double timediff;
1162
1163         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
1164                                                   dirfsp,
1165                                                   path);
1166         if (full_fname == NULL) {
1167                 return -1;
1168         }
1169
1170         clock_gettime_mono(&ts1);
1171         result = SMB_VFS_NEXT_UNLINKAT(handle,
1172                                 dirfsp,
1173                                 path,
1174                                 flags);
1175         clock_gettime_mono(&ts2);
1176         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1177
1178         if (timediff > audit_timeout) {
1179                 smb_time_audit_log_smb_fname("unlinkat", timediff, full_fname);
1180         }
1181
1182         TALLOC_FREE(full_fname);
1183         return result;
1184 }
1185
1186 static int smb_time_audit_fchmod(vfs_handle_struct *handle, files_struct *fsp,
1187                                  mode_t mode)
1188 {
1189         int result;
1190         struct timespec ts1,ts2;
1191         double timediff;
1192
1193         clock_gettime_mono(&ts1);
1194         result = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
1195         clock_gettime_mono(&ts2);
1196         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1197
1198         if (timediff > audit_timeout) {
1199                 smb_time_audit_log_fsp("fchmod", timediff, fsp);
1200         }
1201
1202         return result;
1203 }
1204
1205 static int smb_time_audit_fchown(vfs_handle_struct *handle, files_struct *fsp,
1206                                  uid_t uid, gid_t gid)
1207 {
1208         int result;
1209         struct timespec ts1,ts2;
1210         double timediff;
1211
1212         clock_gettime_mono(&ts1);
1213         result = SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid);
1214         clock_gettime_mono(&ts2);
1215         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1216
1217         if (timediff > audit_timeout) {
1218                 smb_time_audit_log_fsp("fchown", timediff, fsp);
1219         }
1220
1221         return result;
1222 }
1223
1224 static int smb_time_audit_lchown(vfs_handle_struct *handle,
1225                         const struct smb_filename *smb_fname,
1226                         uid_t uid,
1227                         gid_t gid)
1228 {
1229         int result;
1230         struct timespec ts1,ts2;
1231         double timediff;
1232
1233         clock_gettime_mono(&ts1);
1234         result = SMB_VFS_NEXT_LCHOWN(handle, smb_fname, uid, gid);
1235         clock_gettime_mono(&ts2);
1236         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1237
1238         if (timediff > audit_timeout) {
1239                 smb_time_audit_log_fname("lchown",
1240                         timediff,
1241                         smb_fname->base_name);
1242         }
1243
1244         return result;
1245 }
1246
1247 static int smb_time_audit_chdir(vfs_handle_struct *handle,
1248                         const struct smb_filename *smb_fname)
1249 {
1250         int result;
1251         struct timespec ts1,ts2;
1252         double timediff;
1253
1254         clock_gettime_mono(&ts1);
1255         result = SMB_VFS_NEXT_CHDIR(handle, smb_fname);
1256         clock_gettime_mono(&ts2);
1257         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1258
1259         if (timediff > audit_timeout) {
1260                 smb_time_audit_log_fname("chdir",
1261                         timediff,
1262                         smb_fname->base_name);
1263         }
1264
1265         return result;
1266 }
1267
1268 static struct smb_filename *smb_time_audit_getwd(vfs_handle_struct *handle,
1269                                         TALLOC_CTX *mem_ctx)
1270 {
1271         struct smb_filename *result;
1272         struct timespec ts1,ts2;
1273         double timediff;
1274
1275         clock_gettime_mono(&ts1);
1276         result = SMB_VFS_NEXT_GETWD(handle, mem_ctx);
1277         clock_gettime_mono(&ts2);
1278         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1279
1280         if (timediff > audit_timeout) {
1281                 smb_time_audit_log("getwd", timediff);
1282         }
1283
1284         return result;
1285 }
1286
1287 static int smb_time_audit_fntimes(vfs_handle_struct *handle,
1288                                   files_struct *fsp,
1289                                   struct smb_file_time *ft)
1290 {
1291         int result;
1292         struct timespec ts1,ts2;
1293         double timediff;
1294
1295         clock_gettime_mono(&ts1);
1296         result = SMB_VFS_NEXT_FNTIMES(handle, fsp, ft);
1297         clock_gettime_mono(&ts2);
1298         timediff = nsec_time_diff(&ts2, &ts1) * 1.0e-9;
1299
1300         if (timediff > audit_timeout) {
1301                 smb_time_audit_log_fsp("fntimes", timediff, fsp);
1302         }
1303
1304         return result;
1305 }
1306
1307 static int smb_time_audit_ftruncate(vfs_handle_struct *handle,
1308                                     files_struct *fsp,
1309                                     off_t len)
1310 {
1311         int result;
1312         struct timespec ts1,ts2;
1313         double timediff;
1314
1315         clock_gettime_mono(&ts1);
1316         result = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, len);
1317         clock_gettime_mono(&ts2);
1318         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1319
1320         if (timediff > audit_timeout) {
1321                 smb_time_audit_log_fsp("ftruncate", timediff, fsp);
1322         }
1323
1324         return result;
1325 }
1326
1327 static int smb_time_audit_fallocate(vfs_handle_struct *handle,
1328                                     files_struct *fsp,
1329                                     uint32_t mode,
1330                                     off_t offset,
1331                                     off_t len)
1332 {
1333         int result;
1334         int saved_errno = 0;
1335         struct timespec ts1,ts2;
1336         double timediff;
1337
1338         clock_gettime_mono(&ts1);
1339         result = SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len);
1340         if (result == -1) {
1341                 saved_errno = errno;
1342         }
1343         clock_gettime_mono(&ts2);
1344         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1345
1346         if (timediff > audit_timeout) {
1347                 smb_time_audit_log_fsp("fallocate", timediff, fsp);
1348         }
1349         if (result == -1) {
1350                 errno = saved_errno;
1351         }
1352         return result;
1353 }
1354
1355 static bool smb_time_audit_lock(vfs_handle_struct *handle, files_struct *fsp,
1356                                 int op, off_t offset, off_t count,
1357                                 int type)
1358 {
1359         bool result;
1360         struct timespec ts1,ts2;
1361         double timediff;
1362
1363         clock_gettime_mono(&ts1);
1364         result = SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type);
1365         clock_gettime_mono(&ts2);
1366         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1367
1368         if (timediff > audit_timeout) {
1369                 smb_time_audit_log_fsp("lock", timediff, fsp);
1370         }
1371
1372         return result;
1373 }
1374
1375 static int smb_time_audit_filesystem_sharemode(struct vfs_handle_struct *handle,
1376                                                struct files_struct *fsp,
1377                                                uint32_t share_access,
1378                                                uint32_t access_mask)
1379 {
1380         int result;
1381         struct timespec ts1,ts2;
1382         double timediff;
1383
1384         clock_gettime_mono(&ts1);
1385         result = SMB_VFS_NEXT_FILESYSTEM_SHAREMODE(handle,
1386                                                    fsp,
1387                                                    share_access,
1388                                                    access_mask);
1389         clock_gettime_mono(&ts2);
1390         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1391
1392         if (timediff > audit_timeout) {
1393                 smb_time_audit_log_fsp("filesystem_sharemode", timediff, fsp);
1394         }
1395
1396         return result;
1397 }
1398
1399 static int smb_time_audit_fcntl(struct vfs_handle_struct *handle,
1400                                 struct files_struct *fsp,
1401                                 int cmd, va_list cmd_arg)
1402 {
1403         void *arg;
1404         va_list dup_cmd_arg;
1405         int result;
1406         struct timespec ts1,ts2;
1407         double timediff;
1408
1409         va_copy(dup_cmd_arg, cmd_arg);
1410         arg = va_arg(dup_cmd_arg, void *);
1411         clock_gettime_mono(&ts1);
1412         result = SMB_VFS_NEXT_FCNTL(handle, fsp, cmd, arg);
1413         clock_gettime_mono(&ts2);
1414         va_end(dup_cmd_arg);
1415
1416         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1417         if (timediff > audit_timeout) {
1418                 smb_time_audit_log_fsp("fcntl", timediff, fsp);
1419         }
1420
1421         return result;
1422 }
1423
1424 static int smb_time_audit_linux_setlease(vfs_handle_struct *handle,
1425                                          files_struct *fsp,
1426                                          int leasetype)
1427 {
1428         int result;
1429         struct timespec ts1,ts2;
1430         double timediff;
1431
1432         clock_gettime_mono(&ts1);
1433         result = SMB_VFS_NEXT_LINUX_SETLEASE(handle, fsp, leasetype);
1434         clock_gettime_mono(&ts2);
1435         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1436
1437         if (timediff > audit_timeout) {
1438                 smb_time_audit_log_fsp("linux_setlease", timediff, fsp);
1439         }
1440
1441         return result;
1442 }
1443
1444 static bool smb_time_audit_getlock(vfs_handle_struct *handle,
1445                                    files_struct *fsp,
1446                                    off_t *poffset, off_t *pcount,
1447                                    int *ptype, pid_t *ppid)
1448 {
1449         bool result;
1450         struct timespec ts1,ts2;
1451         double timediff;
1452
1453         clock_gettime_mono(&ts1);
1454         result = SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, pcount, ptype,
1455                                       ppid);
1456         clock_gettime_mono(&ts2);
1457         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1458
1459         if (timediff > audit_timeout) {
1460                 smb_time_audit_log_fsp("getlock", timediff, fsp);
1461         }
1462
1463         return result;
1464 }
1465
1466 static int smb_time_audit_symlinkat(vfs_handle_struct *handle,
1467                                 const struct smb_filename *link_contents,
1468                                 struct files_struct *dirfsp,
1469                                 const struct smb_filename *new_smb_fname)
1470 {
1471         struct smb_filename *full_fname = NULL;
1472         int result;
1473         struct timespec ts1,ts2;
1474         double timediff;
1475
1476         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
1477                                                 dirfsp,
1478                                                 new_smb_fname);
1479         if (full_fname == NULL) {
1480                 errno = ENOMEM;
1481                 return -1;
1482         }
1483
1484         clock_gettime_mono(&ts1);
1485         result = SMB_VFS_NEXT_SYMLINKAT(handle,
1486                                 link_contents,
1487                                 dirfsp,
1488                                 new_smb_fname);
1489         clock_gettime_mono(&ts2);
1490         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1491
1492         if (timediff > audit_timeout) {
1493                 smb_time_audit_log_fname("symlinkat", timediff,
1494                         full_fname->base_name);
1495         }
1496
1497         TALLOC_FREE(full_fname);
1498         return result;
1499 }
1500
1501 static int smb_time_audit_readlinkat(vfs_handle_struct *handle,
1502                                 const struct files_struct *dirfsp,
1503                                 const struct smb_filename *smb_fname,
1504                                 char *buf,
1505                                 size_t bufsiz)
1506 {
1507         struct smb_filename *full_fname = NULL;
1508         int result;
1509         struct timespec ts1,ts2;
1510         double timediff;
1511
1512         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
1513                                                 dirfsp,
1514                                                 smb_fname);
1515         if (full_fname == NULL) {
1516                 errno = ENOMEM;
1517                 return -1;
1518         }
1519
1520         clock_gettime_mono(&ts1);
1521         result = SMB_VFS_NEXT_READLINKAT(handle,
1522                                 dirfsp,
1523                                 smb_fname,
1524                                 buf,
1525                                 bufsiz);
1526         clock_gettime_mono(&ts2);
1527         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1528
1529         if (timediff > audit_timeout) {
1530                 smb_time_audit_log_fname("readlinkat", timediff,
1531                                 full_fname->base_name);
1532         }
1533
1534         TALLOC_FREE(full_fname);
1535         return result;
1536 }
1537
1538 static int smb_time_audit_linkat(vfs_handle_struct *handle,
1539                                 files_struct *srcfsp,
1540                                 const struct smb_filename *old_smb_fname,
1541                                 files_struct *dstfsp,
1542                                 const struct smb_filename *new_smb_fname,
1543                                 int flags)
1544 {
1545         struct smb_filename *new_full_fname = NULL;
1546         int result;
1547         struct timespec ts1,ts2;
1548         double timediff;
1549
1550         new_full_fname = full_path_from_dirfsp_atname(talloc_tos(),
1551                                                   dstfsp,
1552                                                   new_smb_fname);
1553         if (new_full_fname == NULL) {
1554                 errno = ENOMEM;
1555                 return -1;
1556         }
1557
1558         clock_gettime_mono(&ts1);
1559         result = SMB_VFS_NEXT_LINKAT(handle,
1560                         srcfsp,
1561                         old_smb_fname,
1562                         dstfsp,
1563                         new_smb_fname,
1564                         flags);
1565         clock_gettime_mono(&ts2);
1566         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1567
1568         if (timediff > audit_timeout) {
1569                 smb_time_audit_log_fname("linkat", timediff,
1570                         new_full_fname->base_name);
1571         }
1572
1573         TALLOC_FREE(new_full_fname);
1574         return result;
1575 }
1576
1577 static int smb_time_audit_mknodat(vfs_handle_struct *handle,
1578                                 files_struct *dirfsp,
1579                                 const struct smb_filename *smb_fname,
1580                                 mode_t mode,
1581                                 SMB_DEV_T dev)
1582 {
1583         struct smb_filename *full_fname = NULL;
1584         int result;
1585         struct timespec ts1,ts2;
1586         double timediff;
1587
1588         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
1589                                                   dirfsp,
1590                                                   smb_fname);
1591         if (full_fname == NULL) {
1592                 errno = ENOMEM;
1593                 return -1;
1594         }
1595
1596         clock_gettime_mono(&ts1);
1597         result = SMB_VFS_NEXT_MKNODAT(handle,
1598                                 dirfsp,
1599                                 smb_fname,
1600                                 mode,
1601                                 dev);
1602         clock_gettime_mono(&ts2);
1603         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1604
1605         if (timediff > audit_timeout) {
1606                 smb_time_audit_log_smb_fname("mknodat", timediff, full_fname);
1607         }
1608
1609         TALLOC_FREE(full_fname);
1610         return result;
1611 }
1612
1613 static struct smb_filename *smb_time_audit_realpath(vfs_handle_struct *handle,
1614                                 TALLOC_CTX *ctx,
1615                                 const struct smb_filename *smb_fname)
1616 {
1617         struct smb_filename *result_fname;
1618         struct timespec ts1,ts2;
1619         double timediff;
1620
1621         clock_gettime_mono(&ts1);
1622         result_fname = SMB_VFS_NEXT_REALPATH(handle, ctx, smb_fname);
1623         clock_gettime_mono(&ts2);
1624         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1625
1626         if (timediff > audit_timeout) {
1627                 smb_time_audit_log_fname("realpath", timediff,
1628                                 smb_fname->base_name);
1629         }
1630
1631         return result_fname;
1632 }
1633
1634 static int smb_time_audit_fchflags(vfs_handle_struct *handle,
1635                                 struct files_struct *fsp,
1636                                 unsigned int flags)
1637 {
1638         int result;
1639         struct timespec ts1,ts2;
1640         double timediff;
1641
1642         clock_gettime_mono(&ts1);
1643         result = SMB_VFS_NEXT_FCHFLAGS(handle, fsp, flags);
1644         clock_gettime_mono(&ts2);
1645         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1646
1647         if (timediff > audit_timeout) {
1648                 smb_time_audit_log_smb_fname("chflags",
1649                                              timediff,
1650                                              fsp->fsp_name);
1651         }
1652
1653         return result;
1654 }
1655
1656 static struct file_id smb_time_audit_file_id_create(struct vfs_handle_struct *handle,
1657                                                     const SMB_STRUCT_STAT *sbuf)
1658 {
1659         struct file_id id_zero;
1660         struct file_id result;
1661         struct timespec ts1,ts2;
1662         double timediff;
1663
1664         ZERO_STRUCT(id_zero);
1665
1666         clock_gettime_mono(&ts1);
1667         result = SMB_VFS_NEXT_FILE_ID_CREATE(handle, sbuf);
1668         clock_gettime_mono(&ts2);
1669         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1670
1671         if (timediff > audit_timeout) {
1672                 smb_time_audit_log("file_id_create", timediff);
1673         }
1674
1675         return result;
1676 }
1677
1678 static uint64_t smb_time_audit_fs_file_id(struct vfs_handle_struct *handle,
1679                                           const SMB_STRUCT_STAT *sbuf)
1680 {
1681         uint64_t result;
1682         struct timespec ts1,ts2;
1683         double timediff;
1684
1685         clock_gettime_mono(&ts1);
1686         result = SMB_VFS_NEXT_FS_FILE_ID(handle, sbuf);
1687         clock_gettime_mono(&ts2);
1688         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1689
1690         if (timediff > audit_timeout) {
1691                 smb_time_audit_log("fs_file_id", timediff);
1692         }
1693
1694         return result;
1695 }
1696
1697 static NTSTATUS smb_time_audit_fstreaminfo(vfs_handle_struct *handle,
1698                                           struct files_struct *fsp,
1699                                           TALLOC_CTX *mem_ctx,
1700                                           unsigned int *pnum_streams,
1701                                           struct stream_struct **pstreams)
1702 {
1703         NTSTATUS result;
1704         struct timespec ts1,ts2;
1705         double timediff;
1706
1707         clock_gettime_mono(&ts1);
1708         result = SMB_VFS_NEXT_FSTREAMINFO(handle, fsp, mem_ctx,
1709                                          pnum_streams, pstreams);
1710         clock_gettime_mono(&ts2);
1711         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1712
1713         if (timediff > audit_timeout) {
1714                 smb_time_audit_log_fsp("fstreaminfo", timediff, fsp);
1715         }
1716
1717         return result;
1718 }
1719
1720 static NTSTATUS smb_time_audit_get_real_filename_at(
1721         struct vfs_handle_struct *handle,
1722         struct files_struct *dirfsp,
1723         const char *name,
1724         TALLOC_CTX *mem_ctx,
1725         char **found_name)
1726 {
1727         NTSTATUS result;
1728         struct timespec ts1,ts2;
1729         double timediff;
1730
1731         clock_gettime_mono(&ts1);
1732         result = SMB_VFS_NEXT_GET_REAL_FILENAME_AT(
1733                 handle, dirfsp, name, mem_ctx, found_name);
1734         clock_gettime_mono(&ts2);
1735         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1736
1737         if (timediff > audit_timeout) {
1738                 smb_time_audit_log_fname("get_real_filename_at",
1739                                          timediff,
1740                                          fsp_str_dbg(dirfsp));
1741         }
1742
1743         return result;
1744 }
1745
1746 static const char *smb_time_audit_connectpath(vfs_handle_struct *handle,
1747                                         const struct smb_filename *smb_fname)
1748 {
1749         const char *result;
1750         struct timespec ts1,ts2;
1751         double timediff;
1752
1753         clock_gettime_mono(&ts1);
1754         result = SMB_VFS_NEXT_CONNECTPATH(handle, smb_fname);
1755         clock_gettime_mono(&ts2);
1756         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1757
1758         if (timediff > audit_timeout) {
1759                 smb_time_audit_log_fname("connectpath", timediff,
1760                         smb_fname->base_name);
1761         }
1762
1763         return result;
1764 }
1765
1766 static NTSTATUS smb_time_audit_brl_lock_windows(struct vfs_handle_struct *handle,
1767                                                 struct byte_range_lock *br_lck,
1768                                                 struct lock_struct *plock)
1769 {
1770         NTSTATUS result;
1771         struct timespec ts1,ts2;
1772         double timediff;
1773
1774         clock_gettime_mono(&ts1);
1775         result = SMB_VFS_NEXT_BRL_LOCK_WINDOWS(handle, br_lck, plock);
1776         clock_gettime_mono(&ts2);
1777         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1778
1779         if (timediff > audit_timeout) {
1780                 smb_time_audit_log_fsp("brl_lock_windows", timediff,
1781                                        brl_fsp(br_lck));
1782         }
1783
1784         return result;
1785 }
1786
1787 static bool smb_time_audit_brl_unlock_windows(struct vfs_handle_struct *handle,
1788                                               struct byte_range_lock *br_lck,
1789                                               const struct lock_struct *plock)
1790 {
1791         bool result;
1792         struct timespec ts1,ts2;
1793         double timediff;
1794
1795         clock_gettime_mono(&ts1);
1796         result = SMB_VFS_NEXT_BRL_UNLOCK_WINDOWS(handle, br_lck, plock);
1797         clock_gettime_mono(&ts2);
1798         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1799
1800         if (timediff > audit_timeout) {
1801                 smb_time_audit_log_fsp("brl_unlock_windows", timediff,
1802                                        brl_fsp(br_lck));
1803         }
1804
1805         return result;
1806 }
1807
1808 static bool smb_time_audit_strict_lock_check(struct vfs_handle_struct *handle,
1809                                              struct files_struct *fsp,
1810                                              struct lock_struct *plock)
1811 {
1812         bool result;
1813         struct timespec ts1,ts2;
1814         double timediff;
1815
1816         clock_gettime_mono(&ts1);
1817         result = SMB_VFS_NEXT_STRICT_LOCK_CHECK(handle, fsp, plock);
1818         clock_gettime_mono(&ts2);
1819         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1820
1821         if (timediff > audit_timeout) {
1822                 smb_time_audit_log_fsp("strict_lock_check", timediff, fsp);
1823         }
1824
1825         return result;
1826 }
1827
1828 static NTSTATUS smb_time_audit_translate_name(struct vfs_handle_struct *handle,
1829                                               const char *name,
1830                                               enum vfs_translate_direction direction,
1831                                               TALLOC_CTX *mem_ctx,
1832                                               char **mapped_name)
1833 {
1834         NTSTATUS result;
1835         struct timespec ts1,ts2;
1836         double timediff;
1837
1838         clock_gettime_mono(&ts1);
1839         result = SMB_VFS_NEXT_TRANSLATE_NAME(handle, name, direction, mem_ctx,
1840                                              mapped_name);
1841         clock_gettime_mono(&ts2);
1842         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1843
1844         if (timediff > audit_timeout) {
1845                 smb_time_audit_log_fname("translate_name", timediff, name);
1846         }
1847
1848         return result;
1849 }
1850
1851 static NTSTATUS smb_time_audit_parent_pathname(struct vfs_handle_struct *handle,
1852                                                TALLOC_CTX *mem_ctx,
1853                                                const struct smb_filename *smb_fname_in,
1854                                                struct smb_filename **parent_dir_out,
1855                                                struct smb_filename **atname_out)
1856 {
1857         NTSTATUS result;
1858         struct timespec ts1,ts2;
1859         double timediff;
1860
1861         clock_gettime_mono(&ts1);
1862         result = SMB_VFS_NEXT_PARENT_PATHNAME(handle,
1863                                               mem_ctx,
1864                                               smb_fname_in,
1865                                               parent_dir_out,
1866                                               atname_out);
1867         clock_gettime_mono(&ts2);
1868         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1869
1870         if (timediff > audit_timeout) {
1871                 smb_time_audit_log_fname("parent_pathname",
1872                                          timediff,
1873                                          smb_fname_in->base_name);
1874         }
1875
1876         return result;
1877 }
1878
1879 static NTSTATUS smb_time_audit_fsctl(struct vfs_handle_struct *handle,
1880                                 struct files_struct *fsp,
1881                                 TALLOC_CTX *ctx,
1882                                 uint32_t function,
1883                                 uint16_t req_flags,
1884                                 const uint8_t *_in_data,
1885                                 uint32_t in_len,
1886                                 uint8_t **_out_data,
1887                                 uint32_t max_out_len,
1888                                 uint32_t *out_len)
1889 {
1890         NTSTATUS result;
1891         struct timespec ts1,ts2;
1892         double timediff;
1893
1894         clock_gettime_mono(&ts1);
1895         result = SMB_VFS_NEXT_FSCTL(handle,
1896                                 fsp,
1897                                 ctx,
1898                                 function,
1899                                 req_flags,
1900                                 _in_data,
1901                                 in_len,
1902                                 _out_data,
1903                                 max_out_len,
1904                                 out_len);
1905         clock_gettime_mono(&ts2);
1906         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1907
1908         if (timediff > audit_timeout) {
1909                 smb_time_audit_log_fsp("fsctl", timediff, fsp);
1910         }
1911
1912         return result;
1913 }
1914
1915 struct smb_time_audit_get_dos_attributes_state {
1916         struct vfs_aio_state aio_state;
1917         files_struct *dir_fsp;
1918         const struct smb_filename *smb_fname;
1919         uint32_t dosmode;
1920 };
1921
1922 static void smb_time_audit_get_dos_attributes_done(struct tevent_req *subreq);
1923
1924 static struct tevent_req *smb_time_audit_get_dos_attributes_send(
1925                         TALLOC_CTX *mem_ctx,
1926                         struct tevent_context *ev,
1927                         struct vfs_handle_struct *handle,
1928                         files_struct *dir_fsp,
1929                         struct smb_filename *smb_fname)
1930 {
1931         struct tevent_req *req = NULL;
1932         struct smb_time_audit_get_dos_attributes_state *state = NULL;
1933         struct tevent_req *subreq = NULL;
1934
1935         req = tevent_req_create(mem_ctx, &state,
1936                                 struct smb_time_audit_get_dos_attributes_state);
1937         if (req == NULL) {
1938                 return NULL;
1939         }
1940         *state = (struct smb_time_audit_get_dos_attributes_state) {
1941                 .dir_fsp = dir_fsp,
1942                 .smb_fname = smb_fname,
1943         };
1944
1945         subreq = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES_SEND(mem_ctx,
1946                                                       ev,
1947                                                       handle,
1948                                                       dir_fsp,
1949                                                       smb_fname);
1950         if (tevent_req_nomem(subreq, req)) {
1951                 return tevent_req_post(req, ev);
1952         }
1953         tevent_req_set_callback(subreq,
1954                                 smb_time_audit_get_dos_attributes_done,
1955                                 req);
1956
1957         return req;
1958 }
1959
1960 static void smb_time_audit_get_dos_attributes_done(struct tevent_req *subreq)
1961 {
1962         struct tevent_req *req =
1963                 tevent_req_callback_data(subreq,
1964                 struct tevent_req);
1965         struct smb_time_audit_get_dos_attributes_state *state =
1966                 tevent_req_data(req,
1967                 struct smb_time_audit_get_dos_attributes_state);
1968         NTSTATUS status;
1969
1970         status = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES_RECV(subreq,
1971                                                       &state->aio_state,
1972                                                       &state->dosmode);
1973         TALLOC_FREE(subreq);
1974         if (tevent_req_nterror(req, status)) {
1975                 return;
1976         }
1977
1978         tevent_req_done(req);
1979         return;
1980 }
1981
1982 static NTSTATUS smb_time_audit_get_dos_attributes_recv(struct tevent_req *req,
1983                                                 struct vfs_aio_state *aio_state,
1984                                                 uint32_t *dosmode)
1985 {
1986         struct smb_time_audit_get_dos_attributes_state *state =
1987                 tevent_req_data(req,
1988                 struct smb_time_audit_get_dos_attributes_state);
1989         NTSTATUS status;
1990         double timediff;
1991
1992         timediff = state->aio_state.duration * 1.0e-9;
1993
1994         if (timediff > audit_timeout) {
1995                 smb_time_audit_log_at("async get_dos_attributes",
1996                                       timediff,
1997                                       state->dir_fsp,
1998                                       state->smb_fname);
1999         }
2000
2001         if (tevent_req_is_nterror(req, &status)) {
2002                 tevent_req_received(req);
2003                 return status;
2004         }
2005
2006         *aio_state = state->aio_state;
2007         *dosmode = state->dosmode;
2008         tevent_req_received(req);
2009         return NT_STATUS_OK;
2010 }
2011
2012 static NTSTATUS smb_time_fget_dos_attributes(struct vfs_handle_struct *handle,
2013                                         struct files_struct *fsp,
2014                                         uint32_t *dosmode)
2015 {
2016         NTSTATUS result;
2017         struct timespec ts1,ts2;
2018         double timediff;
2019
2020         clock_gettime_mono(&ts1);
2021         result = SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle,
2022                                 fsp,
2023                                 dosmode);
2024         clock_gettime_mono(&ts2);
2025         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2026
2027         if (timediff > audit_timeout) {
2028                 smb_time_audit_log_fsp("fget_dos_attributes", timediff, fsp);
2029         }
2030
2031         return result;
2032 }
2033
2034 static NTSTATUS smb_time_fset_dos_attributes(struct vfs_handle_struct *handle,
2035                                         struct files_struct *fsp,
2036                                         uint32_t dosmode)
2037 {
2038         NTSTATUS result;
2039         struct timespec ts1,ts2;
2040         double timediff;
2041
2042         clock_gettime_mono(&ts1);
2043         result = SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle,
2044                                 fsp,
2045                                 dosmode);
2046         clock_gettime_mono(&ts2);
2047         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2048
2049         if (timediff > audit_timeout) {
2050                 smb_time_audit_log_fsp("fset_dos_attributes", timediff, fsp);
2051         }
2052
2053         return result;
2054 }
2055
2056 struct time_audit_offload_read_state {
2057         struct vfs_handle_struct *handle;
2058         struct timespec ts_send;
2059         uint32_t flags;
2060         uint64_t xferlen;
2061         DATA_BLOB token_blob;
2062 };
2063
2064 static void smb_time_audit_offload_read_done(struct tevent_req *subreq);
2065
2066 static struct tevent_req *smb_time_audit_offload_read_send(
2067         TALLOC_CTX *mem_ctx,
2068         struct tevent_context *ev,
2069         struct vfs_handle_struct *handle,
2070         struct files_struct *fsp,
2071         uint32_t fsctl,
2072         uint32_t ttl,
2073         off_t offset,
2074         size_t to_copy)
2075 {
2076         struct tevent_req *req = NULL;
2077         struct tevent_req *subreq = NULL;
2078         struct time_audit_offload_read_state *state = NULL;
2079
2080         req = tevent_req_create(mem_ctx, &state,
2081                                 struct time_audit_offload_read_state);
2082         if (req == NULL) {
2083                 return NULL;
2084         }
2085         state->handle = handle;
2086         clock_gettime_mono(&state->ts_send);
2087
2088         subreq = SMB_VFS_NEXT_OFFLOAD_READ_SEND(mem_ctx, ev,
2089                                                 handle, fsp,
2090                                                 fsctl, ttl,
2091                                                 offset, to_copy);
2092         if (tevent_req_nomem(subreq, req)) {
2093                 return tevent_req_post(req, ev);
2094         }
2095
2096         tevent_req_set_callback(subreq, smb_time_audit_offload_read_done, req);
2097         return req;
2098 }
2099
2100 static void smb_time_audit_offload_read_done(struct tevent_req *subreq)
2101 {
2102         struct tevent_req *req = tevent_req_callback_data(
2103                 subreq, struct tevent_req);
2104         struct time_audit_offload_read_state *state = tevent_req_data(
2105                 req, struct time_audit_offload_read_state);
2106         NTSTATUS status;
2107
2108         status = SMB_VFS_NEXT_OFFLOAD_READ_RECV(subreq,
2109                                                 state->handle,
2110                                                 state,
2111                                                 &state->flags,
2112                                                 &state->xferlen,
2113                                                 &state->token_blob);
2114         TALLOC_FREE(subreq);
2115         if (tevent_req_nterror(req, status)) {
2116                 return;
2117         }
2118         tevent_req_done(req);
2119 }
2120
2121 static NTSTATUS smb_time_audit_offload_read_recv(
2122         struct tevent_req *req,
2123         struct vfs_handle_struct *handle,
2124         TALLOC_CTX *mem_ctx,
2125         uint32_t *flags,
2126         uint64_t *xferlen,
2127         DATA_BLOB *token_blob)
2128 {
2129         struct time_audit_offload_read_state *state = tevent_req_data(
2130                 req, struct time_audit_offload_read_state);
2131         struct timespec ts_recv;
2132         double timediff;
2133         NTSTATUS status;
2134
2135         clock_gettime_mono(&ts_recv);
2136         timediff = nsec_time_diff(&ts_recv, &state->ts_send) * 1.0e-9;
2137         if (timediff > audit_timeout) {
2138                 smb_time_audit_log("offload_read", timediff);
2139         }
2140
2141         if (tevent_req_is_nterror(req, &status)) {
2142                 tevent_req_received(req);
2143                 return status;
2144         }
2145
2146         *flags = state->flags;
2147         *xferlen = state->xferlen;
2148         token_blob->length = state->token_blob.length;
2149         token_blob->data = talloc_move(mem_ctx, &state->token_blob.data);
2150
2151         tevent_req_received(req);
2152         return NT_STATUS_OK;
2153 }
2154
2155 struct time_audit_offload_write_state {
2156         struct timespec ts_send;
2157         struct vfs_handle_struct *handle;
2158         off_t copied;
2159 };
2160 static void smb_time_audit_offload_write_done(struct tevent_req *subreq);
2161
2162 static struct tevent_req *smb_time_audit_offload_write_send(struct vfs_handle_struct *handle,
2163                                                          TALLOC_CTX *mem_ctx,
2164                                                          struct tevent_context *ev,
2165                                                          uint32_t fsctl,
2166                                                          DATA_BLOB *token,
2167                                                          off_t transfer_offset,
2168                                                          struct files_struct *dest_fsp,
2169                                                          off_t dest_off,
2170                                                          off_t num)
2171 {
2172         struct tevent_req *req;
2173         struct tevent_req *subreq;
2174         struct time_audit_offload_write_state *state;
2175
2176         req = tevent_req_create(mem_ctx, &state,
2177                                 struct time_audit_offload_write_state);
2178         if (req == NULL) {
2179                 return NULL;
2180         }
2181
2182         state->handle = handle;
2183         clock_gettime_mono(&state->ts_send);
2184         subreq = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle, state, ev,
2185                                               fsctl, token, transfer_offset,
2186                                               dest_fsp, dest_off, num);
2187         if (tevent_req_nomem(subreq, req)) {
2188                 return tevent_req_post(req, ev);
2189         }
2190
2191         tevent_req_set_callback(subreq, smb_time_audit_offload_write_done, req);
2192         return req;
2193 }
2194
2195 static void smb_time_audit_offload_write_done(struct tevent_req *subreq)
2196 {
2197         struct tevent_req *req = tevent_req_callback_data(
2198                 subreq, struct tevent_req);
2199         struct time_audit_offload_write_state *state = tevent_req_data(
2200                 req, struct time_audit_offload_write_state);
2201         NTSTATUS status;
2202
2203         status = SMB_VFS_NEXT_OFFLOAD_WRITE_RECV(state->handle,
2204                                               subreq,
2205                                               &state->copied);
2206         TALLOC_FREE(subreq);
2207         if (tevent_req_nterror(req, status)) {
2208                 return;
2209         }
2210         tevent_req_done(req);
2211 }
2212
2213 static NTSTATUS smb_time_audit_offload_write_recv(struct vfs_handle_struct *handle,
2214                                                struct tevent_req *req,
2215                                                off_t *copied)
2216 {
2217         struct time_audit_offload_write_state *state = tevent_req_data(
2218                 req, struct time_audit_offload_write_state);
2219         struct timespec ts_recv;
2220         double timediff;
2221         NTSTATUS status;
2222
2223         clock_gettime_mono(&ts_recv);
2224         timediff = nsec_time_diff(&ts_recv, &state->ts_send)*1.0e-9;
2225         if (timediff > audit_timeout) {
2226                 smb_time_audit_log("offload_write", timediff);
2227         }
2228
2229         *copied = state->copied;
2230         if (tevent_req_is_nterror(req, &status)) {
2231                 tevent_req_received(req);
2232                 return status;
2233         }
2234
2235         tevent_req_received(req);
2236         return NT_STATUS_OK;
2237 }
2238
2239 static NTSTATUS smb_time_audit_fget_compression(vfs_handle_struct *handle,
2240                                                TALLOC_CTX *mem_ctx,
2241                                                struct files_struct *fsp,
2242                                                uint16_t *_compression_fmt)
2243 {
2244         NTSTATUS result;
2245         struct timespec ts1,ts2;
2246         double timediff;
2247
2248         clock_gettime_mono(&ts1);
2249         result = SMB_VFS_NEXT_FGET_COMPRESSION(handle, mem_ctx, fsp,
2250                                               _compression_fmt);
2251         clock_gettime_mono(&ts2);
2252         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2253
2254         if (timediff > audit_timeout) {
2255                 smb_time_audit_log_fsp("get_compression",
2256                                        timediff, fsp);
2257         }
2258
2259         return result;
2260 }
2261
2262 static NTSTATUS smb_time_audit_set_compression(vfs_handle_struct *handle,
2263                                                TALLOC_CTX *mem_ctx,
2264                                                struct files_struct *fsp,
2265                                                uint16_t compression_fmt)
2266 {
2267         NTSTATUS result;
2268         struct timespec ts1,ts2;
2269         double timediff;
2270
2271         clock_gettime_mono(&ts1);
2272         result = SMB_VFS_NEXT_SET_COMPRESSION(handle, mem_ctx, fsp,
2273                                               compression_fmt);
2274         clock_gettime_mono(&ts2);
2275         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2276
2277         if (timediff > audit_timeout) {
2278                 smb_time_audit_log_fsp("set_compression", timediff, fsp);
2279         }
2280
2281         return result;
2282 }
2283
2284 static NTSTATUS smb_time_audit_freaddir_attr(struct vfs_handle_struct *handle,
2285                                         struct files_struct *fsp,
2286                                         TALLOC_CTX *mem_ctx,
2287                                         struct readdir_attr_data **pattr_data)
2288 {
2289         NTSTATUS status;
2290         struct timespec ts1, ts2;
2291         double timediff;
2292
2293         clock_gettime_mono(&ts1);
2294         status = SMB_VFS_NEXT_FREADDIR_ATTR(handle, fsp, mem_ctx, pattr_data);
2295         clock_gettime_mono(&ts2);
2296         timediff = nsec_time_diff(&ts2, &ts1) * 1.0e-9;
2297
2298         if (timediff > audit_timeout) {
2299                 smb_time_audit_log_fsp("freaddir_attr", timediff, fsp);
2300         }
2301
2302         return status;
2303 }
2304
2305 static NTSTATUS smb_time_audit_fget_nt_acl(vfs_handle_struct *handle,
2306                                            files_struct *fsp,
2307                                            uint32_t security_info,
2308                                            TALLOC_CTX *mem_ctx,
2309                                            struct security_descriptor **ppdesc)
2310 {
2311         NTSTATUS result;
2312         struct timespec ts1,ts2;
2313         double timediff;
2314
2315         clock_gettime_mono(&ts1);
2316         result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info,
2317                                           mem_ctx, ppdesc);
2318         clock_gettime_mono(&ts2);
2319         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2320
2321         if (timediff > audit_timeout) {
2322                 smb_time_audit_log_fsp("fget_nt_acl", timediff, fsp);
2323         }
2324
2325         return result;
2326 }
2327
2328 static NTSTATUS smb_time_audit_fset_nt_acl(vfs_handle_struct *handle,
2329                                            files_struct *fsp,
2330                                            uint32_t security_info_sent,
2331                                            const struct security_descriptor *psd)
2332 {
2333         NTSTATUS result;
2334         struct timespec ts1,ts2;
2335         double timediff;
2336
2337         clock_gettime_mono(&ts1);
2338         result = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent,
2339                                           psd);
2340         clock_gettime_mono(&ts2);
2341         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2342
2343         if (timediff > audit_timeout) {
2344                 smb_time_audit_log_fsp("fset_nt_acl", timediff, fsp);
2345         }
2346
2347         return result;
2348 }
2349
2350 static NTSTATUS smb_time_audit_audit_file(struct vfs_handle_struct *handle,
2351                                 struct smb_filename *smb_fname,
2352                                 struct security_acl *sacl,
2353                                 uint32_t access_requested,
2354                                 uint32_t access_denied)
2355 {
2356         NTSTATUS result;
2357         struct timespec ts1,ts2;
2358         double timediff;
2359
2360         clock_gettime_mono(&ts1);
2361         result = SMB_VFS_NEXT_AUDIT_FILE(handle,
2362                                         smb_fname,
2363                                         sacl,
2364                                         access_requested,
2365                                         access_denied);
2366         clock_gettime_mono(&ts2);
2367         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2368
2369         if (timediff > audit_timeout) {
2370                 smb_time_audit_log_fname("audit_file",
2371                         timediff,
2372                         smb_fname->base_name);
2373         }
2374
2375         return result;
2376 }
2377
2378 static SMB_ACL_T smb_time_audit_sys_acl_get_fd(vfs_handle_struct *handle,
2379                                                files_struct *fsp,
2380                                                SMB_ACL_TYPE_T type,
2381                                                TALLOC_CTX *mem_ctx)
2382 {
2383         SMB_ACL_T result;
2384         struct timespec ts1,ts2;
2385         double timediff;
2386
2387         clock_gettime_mono(&ts1);
2388         result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, type, mem_ctx);
2389         clock_gettime_mono(&ts2);
2390         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2391
2392         if (timediff > audit_timeout) {
2393                 smb_time_audit_log_fsp("sys_acl_get_fd", timediff, fsp);
2394         }
2395
2396         return result;
2397 }
2398
2399 static int smb_time_audit_sys_acl_blob_get_fd(vfs_handle_struct *handle,
2400                                               files_struct *fsp,
2401                                               TALLOC_CTX *mem_ctx, 
2402                                               char **blob_description,
2403                                               DATA_BLOB *blob)
2404 {
2405         int result;
2406         struct timespec ts1,ts2;
2407         double timediff;
2408
2409         clock_gettime_mono(&ts1);
2410         result = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle, fsp, mem_ctx, blob_description, blob);
2411         clock_gettime_mono(&ts2);
2412         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2413
2414         if (timediff > audit_timeout) {
2415                 smb_time_audit_log("sys_acl_blob_get_fd", timediff);
2416         }
2417
2418         return result;
2419 }
2420
2421 static int smb_time_audit_sys_acl_set_fd(vfs_handle_struct *handle,
2422                                          files_struct *fsp,
2423                                          SMB_ACL_TYPE_T type,
2424                                          SMB_ACL_T theacl)
2425 {
2426         int result;
2427         struct timespec ts1,ts2;
2428         double timediff;
2429
2430         clock_gettime_mono(&ts1);
2431         result = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, type, theacl);
2432         clock_gettime_mono(&ts2);
2433         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2434
2435         if (timediff > audit_timeout) {
2436                 smb_time_audit_log_fsp("sys_acl_set_fd", timediff, fsp);
2437         }
2438
2439         return result;
2440 }
2441
2442 static int smb_time_audit_sys_acl_delete_def_fd(vfs_handle_struct *handle,
2443                                 files_struct *fsp)
2444 {
2445         int result;
2446         struct timespec ts1,ts2;
2447         double timediff;
2448
2449         clock_gettime_mono(&ts1);
2450         result = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FD(handle, fsp);
2451         clock_gettime_mono(&ts2);
2452         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2453
2454         if (timediff > audit_timeout) {
2455                 smb_time_audit_log_fsp("sys_acl_delete_def_fd", timediff, fsp);
2456         }
2457
2458         return result;
2459 }
2460
2461 struct smb_time_audit_getxattrat_state {
2462         struct vfs_aio_state aio_state;
2463         files_struct *dir_fsp;
2464         const struct smb_filename *smb_fname;
2465         const char *xattr_name;
2466         ssize_t xattr_size;
2467         uint8_t *xattr_value;
2468 };
2469
2470 static void smb_time_audit_getxattrat_done(struct tevent_req *subreq);
2471
2472 static struct tevent_req *smb_time_audit_getxattrat_send(
2473                         TALLOC_CTX *mem_ctx,
2474                         struct tevent_context *ev,
2475                         struct vfs_handle_struct *handle,
2476                         files_struct *dir_fsp,
2477                         const struct smb_filename *smb_fname,
2478                         const char *xattr_name,
2479                         size_t alloc_hint)
2480 {
2481         struct tevent_req *req = NULL;
2482         struct tevent_req *subreq = NULL;
2483         struct smb_time_audit_getxattrat_state *state = NULL;
2484
2485         req = tevent_req_create(mem_ctx, &state,
2486                                 struct smb_time_audit_getxattrat_state);
2487         if (req == NULL) {
2488                 return NULL;
2489         }
2490         *state = (struct smb_time_audit_getxattrat_state) {
2491                 .dir_fsp = dir_fsp,
2492                 .smb_fname = smb_fname,
2493                 .xattr_name = xattr_name,
2494         };
2495
2496         subreq = SMB_VFS_NEXT_GETXATTRAT_SEND(state,
2497                                               ev,
2498                                               handle,
2499                                               dir_fsp,
2500                                               smb_fname,
2501                                               xattr_name,
2502                                               alloc_hint);
2503         if (tevent_req_nomem(subreq, req)) {
2504                 return tevent_req_post(req, ev);
2505         }
2506         tevent_req_set_callback(subreq, smb_time_audit_getxattrat_done, req);
2507
2508         return req;
2509 }
2510
2511 static void smb_time_audit_getxattrat_done(struct tevent_req *subreq)
2512 {
2513         struct tevent_req *req = tevent_req_callback_data(
2514                 subreq, struct tevent_req);
2515         struct smb_time_audit_getxattrat_state *state = tevent_req_data(
2516                 req, struct smb_time_audit_getxattrat_state);
2517
2518         state->xattr_size = SMB_VFS_NEXT_GETXATTRAT_RECV(subreq,
2519                                                          &state->aio_state,
2520                                                          state,
2521                                                          &state->xattr_value);
2522         TALLOC_FREE(subreq);
2523         if (state->xattr_size == -1) {
2524                 tevent_req_error(req, state->aio_state.error);
2525                 return;
2526         }
2527
2528         tevent_req_done(req);
2529 }
2530
2531 static ssize_t smb_time_audit_getxattrat_recv(struct tevent_req *req,
2532                                               struct vfs_aio_state *aio_state,
2533                                               TALLOC_CTX *mem_ctx,
2534                                               uint8_t **xattr_value)
2535 {
2536         struct smb_time_audit_getxattrat_state *state = tevent_req_data(
2537                 req, struct smb_time_audit_getxattrat_state);
2538         ssize_t xattr_size;
2539         double timediff;
2540
2541         timediff = state->aio_state.duration * 1.0e-9;
2542
2543         if (timediff > audit_timeout) {
2544                 smb_time_audit_log_at("async getxattrat",
2545                                       timediff,
2546                                       state->dir_fsp,
2547                                       state->smb_fname);
2548         }
2549
2550         if (tevent_req_is_unix_error(req, &aio_state->error)) {
2551                 tevent_req_received(req);
2552                 return -1;
2553         }
2554
2555         *aio_state = state->aio_state;
2556         xattr_size = state->xattr_size;
2557         if (xattr_value != NULL) {
2558                 *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
2559         }
2560
2561         tevent_req_received(req);
2562         return xattr_size;
2563 }
2564
2565 static ssize_t smb_time_audit_fgetxattr(struct vfs_handle_struct *handle,
2566                                         struct files_struct *fsp,
2567                                         const char *name, void *value,
2568                                         size_t size)
2569 {
2570         ssize_t result;
2571         struct timespec ts1,ts2;
2572         double timediff;
2573
2574         clock_gettime_mono(&ts1);
2575         result = SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, value, size);
2576         clock_gettime_mono(&ts2);
2577         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2578
2579         if (timediff > audit_timeout) {
2580                 smb_time_audit_log_fsp("fgetxattr", timediff, fsp);
2581         }
2582
2583         return result;
2584 }
2585
2586 static ssize_t smb_time_audit_flistxattr(struct vfs_handle_struct *handle,
2587                                          struct files_struct *fsp, char *list,
2588                                          size_t size)
2589 {
2590         ssize_t result;
2591         struct timespec ts1,ts2;
2592         double timediff;
2593
2594         clock_gettime_mono(&ts1);
2595         result = SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size);
2596         clock_gettime_mono(&ts2);
2597         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2598
2599         if (timediff > audit_timeout) {
2600                 smb_time_audit_log_fsp("flistxattr", timediff, fsp);
2601         }
2602
2603         return result;
2604 }
2605
2606 static int smb_time_audit_fremovexattr(struct vfs_handle_struct *handle,
2607                                        struct files_struct *fsp,
2608                                        const char *name)
2609 {
2610         int result;
2611         struct timespec ts1,ts2;
2612         double timediff;
2613
2614         clock_gettime_mono(&ts1);
2615         result = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, name);
2616         clock_gettime_mono(&ts2);
2617         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2618
2619         if (timediff > audit_timeout) {
2620                 smb_time_audit_log_fsp("fremovexattr", timediff, fsp);
2621         }
2622
2623         return result;
2624 }
2625
2626 static int smb_time_audit_fsetxattr(struct vfs_handle_struct *handle,
2627                                     struct files_struct *fsp, const char *name,
2628                                     const void *value, size_t size, int flags)
2629 {
2630         int result;
2631         struct timespec ts1,ts2;
2632         double timediff;
2633
2634         clock_gettime_mono(&ts1);
2635         result = SMB_VFS_NEXT_FSETXATTR(handle, fsp, name, value, size, flags);
2636         clock_gettime_mono(&ts2);
2637         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2638
2639         if (timediff > audit_timeout) {
2640                 smb_time_audit_log_fsp("fsetxattr", timediff, fsp);
2641         }
2642
2643         return result;
2644 }
2645
2646 static bool smb_time_audit_aio_force(struct vfs_handle_struct *handle,
2647                                      struct files_struct *fsp)
2648 {
2649         bool result;
2650         struct timespec ts1,ts2;
2651         double timediff;
2652
2653         clock_gettime_mono(&ts1);
2654         result = SMB_VFS_NEXT_AIO_FORCE(handle, fsp);
2655         clock_gettime_mono(&ts2);
2656         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2657
2658         if (timediff > audit_timeout) {
2659                 smb_time_audit_log_fsp("aio_force", timediff, fsp);
2660         }
2661
2662         return result;
2663 }
2664
2665 static NTSTATUS smb_time_audit_durable_cookie(struct vfs_handle_struct *handle,
2666                                               struct files_struct *fsp,
2667                                               TALLOC_CTX *mem_ctx,
2668                                               DATA_BLOB *cookie)
2669 {
2670         NTSTATUS result;
2671         struct timespec ts1,ts2;
2672         double timediff;
2673
2674         clock_gettime_mono(&ts1);
2675         result = SMB_VFS_NEXT_DURABLE_COOKIE(handle, fsp, mem_ctx, cookie);
2676         clock_gettime_mono(&ts2);
2677         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2678
2679         if (timediff > audit_timeout) {
2680                 smb_time_audit_log_fsp("durable_cookie", timediff, fsp);
2681         }
2682
2683         return result;
2684 }
2685
2686 static NTSTATUS smb_time_audit_durable_disconnect(struct vfs_handle_struct *handle,
2687                                                   struct files_struct *fsp,
2688                                                   const DATA_BLOB old_cookie,
2689                                                   TALLOC_CTX *mem_ctx,
2690                                                   DATA_BLOB *new_cookie)
2691 {
2692         NTSTATUS result;
2693         struct timespec ts1,ts2;
2694         double timediff;
2695
2696         clock_gettime_mono(&ts1);
2697         result = SMB_VFS_NEXT_DURABLE_DISCONNECT(handle, fsp, old_cookie,
2698                                                  mem_ctx, new_cookie);
2699         clock_gettime_mono(&ts2);
2700         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2701
2702         if (timediff > audit_timeout) {
2703                 smb_time_audit_log_fsp("durable_disconnect", timediff, fsp);
2704         }
2705
2706         return result;
2707 }
2708
2709 static NTSTATUS smb_time_audit_durable_reconnect(struct vfs_handle_struct *handle,
2710                                                  struct smb_request *smb1req,
2711                                                  struct smbXsrv_open *op,
2712                                                  const DATA_BLOB old_cookie,
2713                                                  TALLOC_CTX *mem_ctx,
2714                                                  struct files_struct **fsp,
2715                                                  DATA_BLOB *new_cookie)
2716 {
2717         NTSTATUS result;
2718         struct timespec ts1,ts2;
2719         double timediff;
2720
2721         clock_gettime_mono(&ts1);
2722         result = SMB_VFS_NEXT_DURABLE_RECONNECT(handle, smb1req, op, old_cookie,
2723                                                 mem_ctx, fsp, new_cookie);
2724         clock_gettime_mono(&ts2);
2725         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2726
2727         if (timediff > audit_timeout) {
2728                 smb_time_audit_log("durable_reconnect", timediff);
2729         }
2730
2731         return result;
2732 }
2733
2734 /* VFS operations */
2735
2736 static struct vfs_fn_pointers vfs_time_audit_fns = {
2737         .connect_fn = smb_time_audit_connect,
2738         .disconnect_fn = smb_time_audit_disconnect,
2739         .disk_free_fn = smb_time_audit_disk_free,
2740         .get_quota_fn = smb_time_audit_get_quota,
2741         .set_quota_fn = smb_time_audit_set_quota,
2742         .get_shadow_copy_data_fn = smb_time_audit_get_shadow_copy_data,
2743         .statvfs_fn = smb_time_audit_statvfs,
2744         .fs_capabilities_fn = smb_time_audit_fs_capabilities,
2745         .get_dfs_referrals_fn = smb_time_audit_get_dfs_referrals,
2746         .create_dfs_pathat_fn = smb_time_audit_create_dfs_pathat,
2747         .read_dfs_pathat_fn = smb_time_audit_read_dfs_pathat,
2748         .fdopendir_fn = smb_time_audit_fdopendir,
2749         .readdir_fn = smb_time_audit_readdir,
2750         .seekdir_fn = smb_time_audit_seekdir,
2751         .telldir_fn = smb_time_audit_telldir,
2752         .rewind_dir_fn = smb_time_audit_rewinddir,
2753         .mkdirat_fn = smb_time_audit_mkdirat,
2754         .closedir_fn = smb_time_audit_closedir,
2755         .openat_fn = smb_time_audit_openat,
2756         .create_file_fn = smb_time_audit_create_file,
2757         .close_fn = smb_time_audit_close,
2758         .pread_fn = smb_time_audit_pread,
2759         .pread_send_fn = smb_time_audit_pread_send,
2760         .pread_recv_fn = smb_time_audit_pread_recv,
2761         .pwrite_fn = smb_time_audit_pwrite,
2762         .pwrite_send_fn = smb_time_audit_pwrite_send,
2763         .pwrite_recv_fn = smb_time_audit_pwrite_recv,
2764         .lseek_fn = smb_time_audit_lseek,
2765         .sendfile_fn = smb_time_audit_sendfile,
2766         .recvfile_fn = smb_time_audit_recvfile,
2767         .renameat_fn = smb_time_audit_renameat,
2768         .fsync_send_fn = smb_time_audit_fsync_send,
2769         .fsync_recv_fn = smb_time_audit_fsync_recv,
2770         .stat_fn = smb_time_audit_stat,
2771         .fstat_fn = smb_time_audit_fstat,
2772         .lstat_fn = smb_time_audit_lstat,
2773         .fstatat_fn = smb_time_audit_fstatat,
2774         .get_alloc_size_fn = smb_time_audit_get_alloc_size,
2775         .unlinkat_fn = smb_time_audit_unlinkat,
2776         .fchmod_fn = smb_time_audit_fchmod,
2777         .fchown_fn = smb_time_audit_fchown,
2778         .lchown_fn = smb_time_audit_lchown,
2779         .chdir_fn = smb_time_audit_chdir,
2780         .getwd_fn = smb_time_audit_getwd,
2781         .fntimes_fn = smb_time_audit_fntimes,
2782         .ftruncate_fn = smb_time_audit_ftruncate,
2783         .fallocate_fn = smb_time_audit_fallocate,
2784         .lock_fn = smb_time_audit_lock,
2785         .filesystem_sharemode_fn = smb_time_audit_filesystem_sharemode,
2786         .fcntl_fn = smb_time_audit_fcntl,
2787         .linux_setlease_fn = smb_time_audit_linux_setlease,
2788         .getlock_fn = smb_time_audit_getlock,
2789         .symlinkat_fn = smb_time_audit_symlinkat,
2790         .readlinkat_fn = smb_time_audit_readlinkat,
2791         .linkat_fn = smb_time_audit_linkat,
2792         .mknodat_fn = smb_time_audit_mknodat,
2793         .realpath_fn = smb_time_audit_realpath,
2794         .fchflags_fn = smb_time_audit_fchflags,
2795         .file_id_create_fn = smb_time_audit_file_id_create,
2796         .fs_file_id_fn = smb_time_audit_fs_file_id,
2797         .offload_read_send_fn = smb_time_audit_offload_read_send,
2798         .offload_read_recv_fn = smb_time_audit_offload_read_recv,
2799         .offload_write_send_fn = smb_time_audit_offload_write_send,
2800         .offload_write_recv_fn = smb_time_audit_offload_write_recv,
2801         .fget_compression_fn = smb_time_audit_fget_compression,
2802         .set_compression_fn = smb_time_audit_set_compression,
2803         .snap_check_path_fn = smb_time_audit_snap_check_path,
2804         .snap_create_fn = smb_time_audit_snap_create,
2805         .snap_delete_fn = smb_time_audit_snap_delete,
2806         .fstreaminfo_fn = smb_time_audit_fstreaminfo,
2807         .get_real_filename_at_fn = smb_time_audit_get_real_filename_at,
2808         .connectpath_fn = smb_time_audit_connectpath,
2809         .brl_lock_windows_fn = smb_time_audit_brl_lock_windows,
2810         .brl_unlock_windows_fn = smb_time_audit_brl_unlock_windows,
2811         .strict_lock_check_fn = smb_time_audit_strict_lock_check,
2812         .translate_name_fn = smb_time_audit_translate_name,
2813         .parent_pathname_fn = smb_time_audit_parent_pathname,
2814         .fsctl_fn = smb_time_audit_fsctl,
2815         .get_dos_attributes_send_fn = smb_time_audit_get_dos_attributes_send,
2816         .get_dos_attributes_recv_fn = smb_time_audit_get_dos_attributes_recv,
2817         .fget_dos_attributes_fn = smb_time_fget_dos_attributes,
2818         .fset_dos_attributes_fn = smb_time_fset_dos_attributes,
2819         .fget_nt_acl_fn = smb_time_audit_fget_nt_acl,
2820         .fset_nt_acl_fn = smb_time_audit_fset_nt_acl,
2821         .audit_file_fn = smb_time_audit_audit_file,
2822         .sys_acl_get_fd_fn = smb_time_audit_sys_acl_get_fd,
2823         .sys_acl_blob_get_fd_fn = smb_time_audit_sys_acl_blob_get_fd,
2824         .sys_acl_set_fd_fn = smb_time_audit_sys_acl_set_fd,
2825         .sys_acl_delete_def_fd_fn = smb_time_audit_sys_acl_delete_def_fd,
2826         .getxattrat_send_fn = smb_time_audit_getxattrat_send,
2827         .getxattrat_recv_fn = smb_time_audit_getxattrat_recv,
2828         .fgetxattr_fn = smb_time_audit_fgetxattr,
2829         .flistxattr_fn = smb_time_audit_flistxattr,
2830         .fremovexattr_fn = smb_time_audit_fremovexattr,
2831         .fsetxattr_fn = smb_time_audit_fsetxattr,
2832         .aio_force_fn = smb_time_audit_aio_force,
2833         .durable_cookie_fn = smb_time_audit_durable_cookie,
2834         .durable_disconnect_fn = smb_time_audit_durable_disconnect,
2835         .durable_reconnect_fn = smb_time_audit_durable_reconnect,
2836         .freaddir_attr_fn = smb_time_audit_freaddir_attr,
2837 };
2838
2839
2840 static_decl_vfs;
2841 NTSTATUS vfs_time_audit_init(TALLOC_CTX *ctx)
2842 {
2843         smb_vfs_assert_all_fns(&vfs_time_audit_fns, "time_audit");
2844
2845         audit_timeout = (double)lp_parm_int(-1, "time_audit", "timeout",
2846                                             10000) / 1000.0;
2847         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "time_audit",
2848                                 &vfs_time_audit_fns);
2849 }