95b4148232b369878c62a599d44d5b70358bddff
[sfrench/samba-autobuild/.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
33 #undef DBGC_CLASS
34 #define DBGC_CLASS DBGC_VFS
35
36 static double audit_timeout;
37
38 static void smb_time_audit_log_msg(const char *syscallname, double elapsed,
39                                     const char *msg)
40 {
41         DEBUG(0, ("WARNING: VFS call \"%s\" took unexpectedly long "
42                   "(%.2f seconds) %s%s-- Validate that file and storage "
43                   "subsystems are operating normally\n", syscallname,
44                   elapsed, (msg != NULL) ? msg : "",
45                   (msg != NULL) ? " " : ""));
46 }
47
48 static void smb_time_audit_log(const char *syscallname, double elapsed)
49 {
50         smb_time_audit_log_msg(syscallname, elapsed, NULL);
51 }
52
53 static void smb_time_audit_log_fsp(const char *syscallname, double elapsed,
54                                    const struct files_struct *fsp)
55 {
56         char *base_name = NULL;
57         char *connectpath = NULL;
58         char *msg = NULL;
59
60         if (fsp == NULL) {
61                 smb_time_audit_log(syscallname, elapsed);
62                 return;
63         }
64         if (fsp->conn)
65                 connectpath = fsp->conn->connectpath;
66         if (fsp->fsp_name)
67                 base_name = fsp->fsp_name->base_name;
68
69         if (connectpath != NULL && base_name != NULL) {
70                 msg = talloc_asprintf(talloc_tos(), "filename = \"%s/%s\"",
71                                       connectpath, base_name);
72         } else if (connectpath != NULL && base_name == NULL) {
73                 msg = talloc_asprintf(talloc_tos(), "connectpath = \"%s\", "
74                                       "base_name = <NULL>",
75                                       connectpath);
76         } else if (connectpath == NULL && base_name != NULL) {
77                 msg = talloc_asprintf(talloc_tos(), "connectpath = <NULL>, "
78                                       "base_name = \"%s\"",
79                                       base_name);
80         } else { /* connectpath == NULL && base_name == NULL */
81                 msg = talloc_asprintf(talloc_tos(), "connectpath = <NULL>, "
82                                       "base_name = <NULL>");
83         }
84         smb_time_audit_log_msg(syscallname, elapsed, msg);
85         TALLOC_FREE(msg);
86 }
87
88 static void smb_time_audit_log_fname(const char *syscallname, double elapsed,
89                                     const char *fname)
90 {
91         char cwd[PATH_MAX];
92         char *msg = NULL;
93
94         if (getcwd(cwd, sizeof(cwd)) == NULL) {
95                 snprintf(cwd, sizeof(cwd), "<getcwd() error %d>", errno);
96         }
97         if (fname != NULL) {
98                 msg = talloc_asprintf(talloc_tos(),
99                                       "cwd = \"%s\", filename = \"%s\"",
100                                       cwd, fname);
101         } else {
102                 msg = talloc_asprintf(talloc_tos(),
103                                       "cwd = \"%s\", filename = <NULL>",
104                                       cwd);
105         }
106         smb_time_audit_log_msg(syscallname, elapsed, msg);
107         TALLOC_FREE(msg);
108 }
109
110 static void smb_time_audit_log_smb_fname(const char *syscallname, double elapsed,
111                                        const struct smb_filename *smb_fname)
112 {
113         if (smb_fname != NULL) {
114                 smb_time_audit_log_fname(syscallname, elapsed,
115                                          smb_fname->base_name);
116         } else {
117                 smb_time_audit_log_fname(syscallname, elapsed,
118                                          "smb_fname = <NULL>");
119         }
120 }
121
122 static int smb_time_audit_connect(vfs_handle_struct *handle,
123                                   const char *svc, const char *user)
124 {
125         int result;
126         struct timespec ts1,ts2;
127         double timediff;
128
129         if (!handle) {
130                 return -1;
131         }
132
133         clock_gettime_mono(&ts1);
134         result = SMB_VFS_NEXT_CONNECT(handle, svc, user);
135         clock_gettime_mono(&ts2);
136         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
137         if (timediff > audit_timeout) {
138                 smb_time_audit_log_msg("connect", timediff, user);
139         }
140         return result;
141 }
142
143 static void smb_time_audit_disconnect(vfs_handle_struct *handle)
144 {
145         struct timespec ts1,ts2;
146         double timediff;
147
148         clock_gettime_mono(&ts1);
149         SMB_VFS_NEXT_DISCONNECT(handle);
150         clock_gettime_mono(&ts2);
151         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
152
153         if (timediff > audit_timeout) {
154                 smb_time_audit_log("disconnect", timediff);
155         }
156 }
157
158 static uint64_t smb_time_audit_disk_free(vfs_handle_struct *handle,
159                                          const char *path,
160                                          bool small_query, uint64_t *bsize,
161                                          uint64_t *dfree, uint64_t *dsize)
162 {
163         uint64_t result;
164         struct timespec ts1,ts2;
165         double timediff;
166
167         clock_gettime_mono(&ts1);
168         result = SMB_VFS_NEXT_DISK_FREE(handle, path, small_query, bsize,
169                                         dfree, dsize);
170         clock_gettime_mono(&ts2);
171         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
172
173         /* Don't have a reasonable notion of failure here */
174         if (timediff > audit_timeout) {
175                 smb_time_audit_log_fname("disk_free", timediff, path);
176         }
177
178         return result;
179 }
180
181 static int smb_time_audit_get_quota(struct vfs_handle_struct *handle,
182                                     enum SMB_QUOTA_TYPE qtype, unid_t id,
183                                     SMB_DISK_QUOTA *qt)
184 {
185         int result;
186         struct timespec ts1,ts2;
187         double timediff;
188
189         clock_gettime_mono(&ts1);
190         result = SMB_VFS_NEXT_GET_QUOTA(handle, qtype, id, qt);
191         clock_gettime_mono(&ts2);
192         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
193
194         if (timediff > audit_timeout) {
195                 smb_time_audit_log("get_quota", timediff);
196         }
197         return result;
198 }
199
200 static int smb_time_audit_set_quota(struct vfs_handle_struct *handle,
201                                     enum SMB_QUOTA_TYPE qtype, unid_t id,
202                                     SMB_DISK_QUOTA *qt)
203 {
204         int result;
205         struct timespec ts1,ts2;
206         double timediff;
207
208         clock_gettime_mono(&ts1);
209         result = SMB_VFS_NEXT_SET_QUOTA(handle, qtype, id, qt);
210         clock_gettime_mono(&ts2);
211         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
212
213         if (timediff > audit_timeout) {
214                 smb_time_audit_log("set_quota", timediff);
215         }
216
217         return result;
218 }
219
220 static int smb_time_audit_get_shadow_copy_data(struct vfs_handle_struct *handle,
221                                                struct files_struct *fsp,
222                                                struct shadow_copy_data *shadow_copy_data,
223                                                bool labels)
224 {
225         int result;
226         struct timespec ts1,ts2;
227         double timediff;
228
229         clock_gettime_mono(&ts1);
230         result = SMB_VFS_NEXT_GET_SHADOW_COPY_DATA(handle, fsp,
231                                                    shadow_copy_data, labels);
232         clock_gettime_mono(&ts2);
233         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
234
235         if (timediff > audit_timeout) {
236                 smb_time_audit_log_fsp("get_shadow_copy_data", timediff, fsp);
237         }
238
239         return result;
240 }
241
242 static int smb_time_audit_statvfs(struct vfs_handle_struct *handle,
243                                   const char *path,
244                                   struct vfs_statvfs_struct *statbuf)
245 {
246         int result;
247         struct timespec ts1,ts2;
248         double timediff;
249
250         clock_gettime_mono(&ts1);
251         result = SMB_VFS_NEXT_STATVFS(handle, path, statbuf);
252         clock_gettime_mono(&ts2);
253         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
254
255         if (timediff > audit_timeout) {
256                 smb_time_audit_log_fname("statvfs", timediff, path);
257         }
258
259         return result;
260 }
261
262 static uint32_t smb_time_audit_fs_capabilities(struct vfs_handle_struct *handle,
263                                                enum timestamp_set_resolution *p_ts_res)
264 {
265         uint32_t result;
266         struct timespec ts1,ts2;
267         double timediff;
268
269         clock_gettime_mono(&ts1);
270         result = SMB_VFS_NEXT_FS_CAPABILITIES(handle, p_ts_res);
271         clock_gettime_mono(&ts2);
272         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
273
274         if (timediff > audit_timeout) {
275                 smb_time_audit_log("fs_capabilities", timediff);
276         }
277
278         return result;
279 }
280
281 static DIR *smb_time_audit_opendir(vfs_handle_struct *handle,
282                                               const char *fname,
283                                               const char *mask, uint32 attr)
284 {
285         DIR *result;
286         struct timespec ts1,ts2;
287         double timediff;
288
289         clock_gettime_mono(&ts1);
290         result = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr);
291         clock_gettime_mono(&ts2);
292         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
293
294         if (timediff > audit_timeout) {
295                 smb_time_audit_log_fname("opendir", timediff, fname);
296         }
297
298         return result;
299 }
300
301 static DIR *smb_time_audit_fdopendir(vfs_handle_struct *handle,
302                                               files_struct *fsp,
303                                               const char *mask, uint32 attr)
304 {
305         DIR *result;
306         struct timespec ts1,ts2;
307         double timediff;
308
309         clock_gettime_mono(&ts1);
310         result = SMB_VFS_NEXT_FDOPENDIR(handle, fsp, mask, attr);
311         clock_gettime_mono(&ts2);
312         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
313
314         if (timediff > audit_timeout) {
315                 smb_time_audit_log_fsp("fdopendir", timediff, fsp);
316         }
317
318         return result;
319 }
320
321 static struct dirent *smb_time_audit_readdir(vfs_handle_struct *handle,
322                                                  DIR *dirp,
323                                                  SMB_STRUCT_STAT *sbuf)
324 {
325         struct dirent *result;
326         struct timespec ts1,ts2;
327         double timediff;
328
329         clock_gettime_mono(&ts1);
330         result = SMB_VFS_NEXT_READDIR(handle, dirp, sbuf);
331         clock_gettime_mono(&ts2);
332         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
333
334         if (timediff > audit_timeout) {
335                 smb_time_audit_log("readdir", timediff);
336         }
337
338         return result;
339 }
340
341 static void smb_time_audit_seekdir(vfs_handle_struct *handle,
342                                    DIR *dirp, long offset)
343 {
344         struct timespec ts1,ts2;
345         double timediff;
346
347         clock_gettime_mono(&ts1);
348         SMB_VFS_NEXT_SEEKDIR(handle, dirp, offset);
349         clock_gettime_mono(&ts2);
350         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
351
352         if (timediff > audit_timeout) {
353                 smb_time_audit_log("seekdir", timediff);
354         }
355
356 }
357
358 static long smb_time_audit_telldir(vfs_handle_struct *handle,
359                                    DIR *dirp)
360 {
361         long result;
362         struct timespec ts1,ts2;
363         double timediff;
364
365         clock_gettime_mono(&ts1);
366         result = SMB_VFS_NEXT_TELLDIR(handle, dirp);
367         clock_gettime_mono(&ts2);
368         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
369
370         if (timediff > audit_timeout) {
371                 smb_time_audit_log("telldir", timediff);
372         }
373
374         return result;
375 }
376
377 static void smb_time_audit_rewinddir(vfs_handle_struct *handle,
378                                      DIR *dirp)
379 {
380         struct timespec ts1,ts2;
381         double timediff;
382
383         clock_gettime_mono(&ts1);
384         SMB_VFS_NEXT_REWINDDIR(handle, dirp);
385         clock_gettime_mono(&ts2);
386         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
387
388         if (timediff > audit_timeout) {
389                 smb_time_audit_log("rewinddir", timediff);
390         }
391
392 }
393
394 static int smb_time_audit_mkdir(vfs_handle_struct *handle,
395                                 const char *path, mode_t mode)
396 {
397         int result;
398         struct timespec ts1,ts2;
399         double timediff;
400
401         clock_gettime_mono(&ts1);
402         result = SMB_VFS_NEXT_MKDIR(handle, path, mode);
403         clock_gettime_mono(&ts2);
404         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
405
406         if (timediff > audit_timeout) {
407                 smb_time_audit_log_fname("mkdir", timediff, path);
408         }
409
410         return result;
411 }
412
413 static int smb_time_audit_rmdir(vfs_handle_struct *handle,
414                                 const char *path)
415 {
416         int result;
417         struct timespec ts1,ts2;
418         double timediff;
419
420         clock_gettime_mono(&ts1);
421         result = SMB_VFS_NEXT_RMDIR(handle, path);
422         clock_gettime_mono(&ts2);
423         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
424
425         if (timediff > audit_timeout) {
426                 smb_time_audit_log_fname("rmdir", timediff, path);
427         }
428
429         return result;
430 }
431
432 static int smb_time_audit_closedir(vfs_handle_struct *handle,
433                                    DIR *dirp)
434 {
435         int result;
436         struct timespec ts1,ts2;
437         double timediff;
438
439         clock_gettime_mono(&ts1);
440         result = SMB_VFS_NEXT_CLOSEDIR(handle, dirp);
441         clock_gettime_mono(&ts2);
442         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
443
444         if (timediff > audit_timeout) {
445                 smb_time_audit_log("closedir", timediff);
446         }
447
448         return result;
449 }
450
451 static void smb_time_audit_init_search_op(vfs_handle_struct *handle,
452                                           DIR *dirp)
453 {
454         struct timespec ts1,ts2;
455         double timediff;
456
457         clock_gettime_mono(&ts1);
458         SMB_VFS_NEXT_INIT_SEARCH_OP(handle, dirp);
459         clock_gettime_mono(&ts2);
460         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
461
462         if (timediff > audit_timeout) {
463                 smb_time_audit_log("init_search_op", timediff);
464         }
465 }
466
467 static int smb_time_audit_open(vfs_handle_struct *handle,
468                                struct smb_filename *fname,
469                                files_struct *fsp,
470                                int flags, mode_t mode)
471 {
472         int result;
473         struct timespec ts1,ts2;
474         double timediff;
475
476         clock_gettime_mono(&ts1);
477         result = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
478         clock_gettime_mono(&ts2);
479         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
480
481         if (timediff > audit_timeout) {
482                 smb_time_audit_log_fsp("open", timediff, fsp);
483         }
484
485         return result;
486 }
487
488 static NTSTATUS smb_time_audit_create_file(vfs_handle_struct *handle,
489                                            struct smb_request *req,
490                                            uint16_t root_dir_fid,
491                                            struct smb_filename *fname,
492                                            uint32_t access_mask,
493                                            uint32_t share_access,
494                                            uint32_t create_disposition,
495                                            uint32_t create_options,
496                                            uint32_t file_attributes,
497                                            uint32_t oplock_request,
498                                            uint64_t allocation_size,
499                                            uint32_t private_flags,
500                                            struct security_descriptor *sd,
501                                            struct ea_list *ea_list,
502                                            files_struct **result_fsp,
503                                            int *pinfo)
504 {
505         NTSTATUS result;
506         struct timespec ts1,ts2;
507         double timediff;
508
509         clock_gettime_mono(&ts1);
510         result = SMB_VFS_NEXT_CREATE_FILE(
511                 handle,                                 /* handle */
512                 req,                                    /* req */
513                 root_dir_fid,                           /* root_dir_fid */
514                 fname,                                  /* fname */
515                 access_mask,                            /* access_mask */
516                 share_access,                           /* share_access */
517                 create_disposition,                     /* create_disposition*/
518                 create_options,                         /* create_options */
519                 file_attributes,                        /* file_attributes */
520                 oplock_request,                         /* oplock_request */
521                 allocation_size,                        /* allocation_size */
522                 private_flags,
523                 sd,                                     /* sd */
524                 ea_list,                                /* ea_list */
525                 result_fsp,                             /* result */
526                 pinfo);
527         clock_gettime_mono(&ts2);
528         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
529
530         if (timediff > audit_timeout) {
531                 /*
532                  * can't use result_fsp this time, may have
533                  * invalid content causing smbd crash
534                  */
535                 smb_time_audit_log_smb_fname("create_file", timediff,
536                                            fname);
537         }
538
539         return result;
540 }
541
542 static int smb_time_audit_close(vfs_handle_struct *handle, files_struct *fsp)
543 {
544         int result;
545         struct timespec ts1,ts2;
546         double timediff;
547
548         clock_gettime_mono(&ts1);
549         result = SMB_VFS_NEXT_CLOSE(handle, fsp);
550         clock_gettime_mono(&ts2);
551         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
552
553         if (timediff > audit_timeout) {
554                 smb_time_audit_log_fsp("close", timediff, fsp);
555         }
556
557         return result;
558 }
559
560 static ssize_t smb_time_audit_read(vfs_handle_struct *handle,
561                                    files_struct *fsp, void *data, size_t n)
562 {
563         ssize_t result;
564         struct timespec ts1,ts2;
565         double timediff;
566
567         clock_gettime_mono(&ts1);
568         result = SMB_VFS_NEXT_READ(handle, fsp, data, n);
569         clock_gettime_mono(&ts2);
570         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
571
572         if (timediff > audit_timeout) {
573                 smb_time_audit_log_fsp("read", timediff, fsp);
574         }
575
576         return result;
577 }
578
579 static ssize_t smb_time_audit_pread(vfs_handle_struct *handle,
580                                     files_struct *fsp,
581                                     void *data, size_t n, off_t offset)
582 {
583         ssize_t result;
584         struct timespec ts1,ts2;
585         double timediff;
586
587         clock_gettime_mono(&ts1);
588         result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
589         clock_gettime_mono(&ts2);
590         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
591
592         if (timediff > audit_timeout) {
593                 smb_time_audit_log_fsp("pread", timediff, fsp);
594         }
595
596         return result;
597 }
598
599 struct smb_time_audit_pread_state {
600         struct files_struct *fsp;
601         struct timespec ts1;
602         ssize_t ret;
603         int err;
604 };
605
606 static void smb_time_audit_pread_done(struct tevent_req *subreq);
607
608 static struct tevent_req *smb_time_audit_pread_send(
609         struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx,
610         struct tevent_context *ev, struct files_struct *fsp,
611         void *data, size_t n, off_t offset)
612 {
613         struct tevent_req *req, *subreq;
614         struct smb_time_audit_pread_state *state;
615
616         req = tevent_req_create(mem_ctx, &state,
617                                 struct smb_time_audit_pread_state);
618         if (req == NULL) {
619                 return NULL;
620         }
621         clock_gettime_mono(&state->ts1);
622         state->fsp = fsp;
623
624         subreq = SMB_VFS_NEXT_PREAD_SEND(state, ev, handle, fsp, data,
625                                          n, offset);
626         if (tevent_req_nomem(subreq, req)) {
627                 return tevent_req_post(req, ev);
628         }
629         tevent_req_set_callback(subreq, smb_time_audit_pread_done, req);
630         return req;
631 }
632
633 static void smb_time_audit_pread_done(struct tevent_req *subreq)
634 {
635         struct tevent_req *req = tevent_req_callback_data(
636                 subreq, struct tevent_req);
637         struct smb_time_audit_pread_state *state = tevent_req_data(
638                 req, struct smb_time_audit_pread_state);
639
640         state->ret = SMB_VFS_PREAD_RECV(subreq, &state->err);
641         TALLOC_FREE(subreq);
642         tevent_req_done(req);
643 }
644
645 static ssize_t smb_time_audit_pread_recv(struct tevent_req *req, int *err)
646 {
647         struct smb_time_audit_pread_state *state = tevent_req_data(
648                 req, struct smb_time_audit_pread_state);
649         struct timespec ts2;
650         double timediff;
651
652         clock_gettime_mono(&ts2);
653         timediff = nsec_time_diff(&ts2,&state->ts1)*1.0e-9;
654
655         if (timediff > audit_timeout) {
656                 smb_time_audit_log_fsp("pread", timediff, state->fsp);
657         }
658
659         if (tevent_req_is_unix_error(req, err)) {
660                 return -1;
661         }
662         *err = state->err;
663         return state->ret;
664 }
665
666 static ssize_t smb_time_audit_write(vfs_handle_struct *handle,
667                                     files_struct *fsp,
668                                     const void *data, size_t n)
669 {
670         ssize_t result;
671         struct timespec ts1,ts2;
672         double timediff;
673
674         clock_gettime_mono(&ts1);
675         result = SMB_VFS_NEXT_WRITE(handle, fsp, data, n);
676         clock_gettime_mono(&ts2);
677         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
678
679         if (timediff > audit_timeout) {
680                 smb_time_audit_log_fsp("write", timediff, fsp);
681         }
682
683         return result;
684 }
685
686 static ssize_t smb_time_audit_pwrite(vfs_handle_struct *handle,
687                                      files_struct *fsp,
688                                      const void *data, size_t n,
689                                      off_t offset)
690 {
691         ssize_t result;
692         struct timespec ts1,ts2;
693         double timediff;
694
695         clock_gettime_mono(&ts1);
696         result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
697         clock_gettime_mono(&ts2);
698         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
699
700         if (timediff > audit_timeout) {
701                 smb_time_audit_log_fsp("pwrite", timediff, fsp);
702         }
703
704         return result;
705 }
706
707 struct smb_time_audit_pwrite_state {
708         struct files_struct *fsp;
709         struct timespec ts1;
710         ssize_t ret;
711         int err;
712 };
713
714 static void smb_time_audit_pwrite_done(struct tevent_req *subreq);
715
716 static struct tevent_req *smb_time_audit_pwrite_send(
717         struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx,
718         struct tevent_context *ev, struct files_struct *fsp,
719         const void *data, size_t n, off_t offset)
720 {
721         struct tevent_req *req, *subreq;
722         struct smb_time_audit_pwrite_state *state;
723
724         req = tevent_req_create(mem_ctx, &state,
725                                 struct smb_time_audit_pwrite_state);
726         if (req == NULL) {
727                 return NULL;
728         }
729         clock_gettime_mono(&state->ts1);
730         state->fsp = fsp;
731
732         subreq = SMB_VFS_NEXT_PWRITE_SEND(state, ev, handle, fsp, data,
733                                          n, offset);
734         if (tevent_req_nomem(subreq, req)) {
735                 return tevent_req_post(req, ev);
736         }
737         tevent_req_set_callback(subreq, smb_time_audit_pwrite_done, req);
738         return req;
739 }
740
741 static void smb_time_audit_pwrite_done(struct tevent_req *subreq)
742 {
743         struct tevent_req *req = tevent_req_callback_data(
744                 subreq, struct tevent_req);
745         struct smb_time_audit_pwrite_state *state = tevent_req_data(
746                 req, struct smb_time_audit_pwrite_state);
747
748         state->ret = SMB_VFS_PWRITE_RECV(subreq, &state->err);
749         TALLOC_FREE(subreq);
750         tevent_req_done(req);
751 }
752
753 static ssize_t smb_time_audit_pwrite_recv(struct tevent_req *req, int *err)
754 {
755         struct smb_time_audit_pwrite_state *state = tevent_req_data(
756                 req, struct smb_time_audit_pwrite_state);
757         struct timespec ts2;
758         double timediff;
759
760         clock_gettime_mono(&ts2);
761         timediff = nsec_time_diff(&ts2,&state->ts1)*1.0e-9;
762
763         if (timediff > audit_timeout) {
764                 smb_time_audit_log_fsp("pwrite", timediff, state->fsp);
765         }
766
767         if (tevent_req_is_unix_error(req, err)) {
768                 return -1;
769         }
770         *err = state->err;
771         return state->ret;
772 }
773
774 static off_t smb_time_audit_lseek(vfs_handle_struct *handle,
775                                       files_struct *fsp,
776                                       off_t offset, int whence)
777 {
778         off_t result;
779         struct timespec ts1,ts2;
780         double timediff;
781
782         clock_gettime_mono(&ts1);
783         result = SMB_VFS_NEXT_LSEEK(handle, fsp, offset, whence);
784         clock_gettime_mono(&ts2);
785         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
786
787         if (timediff > audit_timeout) {
788                 smb_time_audit_log_fsp("lseek", timediff, fsp);
789         }
790
791         return result;
792 }
793
794 static ssize_t smb_time_audit_sendfile(vfs_handle_struct *handle, int tofd,
795                                        files_struct *fromfsp,
796                                        const DATA_BLOB *hdr, off_t offset,
797                                        size_t n)
798 {
799         ssize_t result;
800         struct timespec ts1,ts2;
801         double timediff;
802
803         clock_gettime_mono(&ts1);
804         result = SMB_VFS_NEXT_SENDFILE(handle, tofd, fromfsp, hdr, offset, n);
805         clock_gettime_mono(&ts2);
806         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
807
808         if (timediff > audit_timeout) {
809                 smb_time_audit_log_fsp("sendfile", timediff, fromfsp);
810         }
811
812         return result;
813 }
814
815 static ssize_t smb_time_audit_recvfile(vfs_handle_struct *handle, int fromfd,
816                                        files_struct *tofsp,
817                                        off_t offset,
818                                        size_t n)
819 {
820         ssize_t result;
821         struct timespec ts1,ts2;
822         double timediff;
823
824         clock_gettime_mono(&ts1);
825         result = SMB_VFS_NEXT_RECVFILE(handle, fromfd, tofsp, offset, n);
826         clock_gettime_mono(&ts2);
827         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
828
829         if (timediff > audit_timeout) {
830                 smb_time_audit_log_fsp("recvfile", timediff, tofsp);
831         }
832
833         return result;
834 }
835
836 static int smb_time_audit_rename(vfs_handle_struct *handle,
837                                  const struct smb_filename *oldname,
838                                  const struct smb_filename *newname)
839 {
840         int result;
841         struct timespec ts1,ts2;
842         double timediff;
843
844         clock_gettime_mono(&ts1);
845         result = SMB_VFS_NEXT_RENAME(handle, oldname, newname);
846         clock_gettime_mono(&ts2);
847         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
848
849         if (timediff > audit_timeout) {
850                 smb_time_audit_log_smb_fname("rename", timediff, newname);
851         }
852
853         return result;
854 }
855
856 static int smb_time_audit_fsync(vfs_handle_struct *handle, files_struct *fsp)
857 {
858         int result;
859         struct timespec ts1,ts2;
860         double timediff;
861
862         clock_gettime_mono(&ts1);
863         result = SMB_VFS_NEXT_FSYNC(handle, fsp);
864         clock_gettime_mono(&ts2);
865         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
866
867         if (timediff > audit_timeout) {
868                 smb_time_audit_log_fsp("fsync", timediff, fsp);
869         }
870
871         return result;
872 }
873
874 struct smb_time_audit_fsync_state {
875         struct files_struct *fsp;
876         struct timespec ts1;
877         int ret;
878         int err;
879 };
880
881 static void smb_time_audit_fsync_done(struct tevent_req *subreq);
882
883 static struct tevent_req *smb_time_audit_fsync_send(
884         struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx,
885         struct tevent_context *ev, struct files_struct *fsp)
886 {
887         struct tevent_req *req, *subreq;
888         struct smb_time_audit_fsync_state *state;
889
890         req = tevent_req_create(mem_ctx, &state,
891                                 struct smb_time_audit_fsync_state);
892         if (req == NULL) {
893                 return NULL;
894         }
895         clock_gettime_mono(&state->ts1);
896         state->fsp = fsp;
897
898         subreq = SMB_VFS_NEXT_FSYNC_SEND(state, ev, handle, fsp);
899         if (tevent_req_nomem(subreq, req)) {
900                 return tevent_req_post(req, ev);
901         }
902         tevent_req_set_callback(subreq, smb_time_audit_fsync_done, req);
903         return req;
904 }
905
906 static void smb_time_audit_fsync_done(struct tevent_req *subreq)
907 {
908         struct tevent_req *req = tevent_req_callback_data(
909                 subreq, struct tevent_req);
910         struct smb_time_audit_fsync_state *state = tevent_req_data(
911                 req, struct smb_time_audit_fsync_state);
912
913         state->ret = SMB_VFS_FSYNC_RECV(subreq, &state->err);
914         TALLOC_FREE(subreq);
915         tevent_req_done(req);
916 }
917
918 static int smb_time_audit_fsync_recv(struct tevent_req *req, int *err)
919 {
920         struct smb_time_audit_fsync_state *state = tevent_req_data(
921                 req, struct smb_time_audit_fsync_state);
922         struct timespec ts2;
923         double timediff;
924
925         clock_gettime_mono(&ts2);
926         timediff = nsec_time_diff(&ts2,&state->ts1)*1.0e-9;
927
928         if (timediff > audit_timeout) {
929                 smb_time_audit_log_fsp("fsync", timediff, state->fsp);
930         }
931
932         if (tevent_req_is_unix_error(req, err)) {
933                 return -1;
934         }
935         *err = state->err;
936         return state->ret;
937 }
938
939 static int smb_time_audit_stat(vfs_handle_struct *handle,
940                                struct smb_filename *fname)
941 {
942         int result;
943         struct timespec ts1,ts2;
944         double timediff;
945
946         clock_gettime_mono(&ts1);
947         result = SMB_VFS_NEXT_STAT(handle, fname);
948         clock_gettime_mono(&ts2);
949         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
950
951         if (timediff > audit_timeout) {
952                 smb_time_audit_log_smb_fname("stat", timediff, fname);
953         }
954
955         return result;
956 }
957
958 static int smb_time_audit_fstat(vfs_handle_struct *handle, files_struct *fsp,
959                                 SMB_STRUCT_STAT *sbuf)
960 {
961         int result;
962         struct timespec ts1,ts2;
963         double timediff;
964
965         clock_gettime_mono(&ts1);
966         result = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
967         clock_gettime_mono(&ts2);
968         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
969
970         if (timediff > audit_timeout) {
971                 smb_time_audit_log_fsp("fstat", timediff, fsp);
972         }
973
974         return result;
975 }
976
977 static int smb_time_audit_lstat(vfs_handle_struct *handle,
978                                 struct smb_filename *path)
979 {
980         int result;
981         struct timespec ts1,ts2;
982         double timediff;
983
984         clock_gettime_mono(&ts1);
985         result = SMB_VFS_NEXT_LSTAT(handle, path);
986         clock_gettime_mono(&ts2);
987         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
988
989         if (timediff > audit_timeout) {
990                 smb_time_audit_log_smb_fname("lstat", timediff, path);
991         }
992
993         return result;
994 }
995
996 static uint64_t smb_time_audit_get_alloc_size(vfs_handle_struct *handle,
997                                               files_struct *fsp,
998                                               const SMB_STRUCT_STAT *sbuf)
999 {
1000         uint64_t result;
1001         struct timespec ts1,ts2;
1002         double timediff;
1003
1004         clock_gettime_mono(&ts1);
1005         result = SMB_VFS_NEXT_GET_ALLOC_SIZE(handle, fsp, sbuf);
1006         clock_gettime_mono(&ts2);
1007         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1008
1009         if (timediff > audit_timeout) {
1010                 smb_time_audit_log_fsp("get_alloc_size", timediff, fsp);
1011         }
1012
1013         return result;
1014 }
1015
1016 static int smb_time_audit_unlink(vfs_handle_struct *handle,
1017                                  const struct smb_filename *path)
1018 {
1019         int result;
1020         struct timespec ts1,ts2;
1021         double timediff;
1022
1023         clock_gettime_mono(&ts1);
1024         result = SMB_VFS_NEXT_UNLINK(handle, path);
1025         clock_gettime_mono(&ts2);
1026         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1027
1028         if (timediff > audit_timeout) {
1029                 smb_time_audit_log_smb_fname("unlink", timediff, path);
1030         }
1031
1032         return result;
1033 }
1034
1035 static int smb_time_audit_chmod(vfs_handle_struct *handle,
1036                                 const char *path, mode_t mode)
1037 {
1038         int result;
1039         struct timespec ts1,ts2;
1040         double timediff;
1041
1042         clock_gettime_mono(&ts1);
1043         result = SMB_VFS_NEXT_CHMOD(handle, path, mode);
1044         clock_gettime_mono(&ts2);
1045         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1046
1047         if (timediff > audit_timeout) {
1048                 smb_time_audit_log_fname("chmod", timediff, path);
1049         }
1050
1051         return result;
1052 }
1053
1054 static int smb_time_audit_fchmod(vfs_handle_struct *handle, files_struct *fsp,
1055                                  mode_t mode)
1056 {
1057         int result;
1058         struct timespec ts1,ts2;
1059         double timediff;
1060
1061         clock_gettime_mono(&ts1);
1062         result = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
1063         clock_gettime_mono(&ts2);
1064         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1065
1066         if (timediff > audit_timeout) {
1067                 smb_time_audit_log_fsp("fchmod", timediff, fsp);
1068         }
1069
1070         return result;
1071 }
1072
1073 static int smb_time_audit_chown(vfs_handle_struct *handle,
1074                                 const char *path, uid_t uid, gid_t gid)
1075 {
1076         int result;
1077         struct timespec ts1,ts2;
1078         double timediff;
1079
1080         clock_gettime_mono(&ts1);
1081         result = SMB_VFS_NEXT_CHOWN(handle, path, uid, gid);
1082         clock_gettime_mono(&ts2);
1083         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1084
1085         if (timediff > audit_timeout) {
1086                 smb_time_audit_log_fname("chown", timediff, path);
1087         }
1088
1089         return result;
1090 }
1091
1092 static int smb_time_audit_fchown(vfs_handle_struct *handle, files_struct *fsp,
1093                                  uid_t uid, gid_t gid)
1094 {
1095         int result;
1096         struct timespec ts1,ts2;
1097         double timediff;
1098
1099         clock_gettime_mono(&ts1);
1100         result = SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid);
1101         clock_gettime_mono(&ts2);
1102         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1103
1104         if (timediff > audit_timeout) {
1105                 smb_time_audit_log_fsp("fchown", timediff, fsp);
1106         }
1107
1108         return result;
1109 }
1110
1111 static int smb_time_audit_lchown(vfs_handle_struct *handle,
1112                                  const char *path, uid_t uid, gid_t gid)
1113 {
1114         int result;
1115         struct timespec ts1,ts2;
1116         double timediff;
1117
1118         clock_gettime_mono(&ts1);
1119         result = SMB_VFS_NEXT_LCHOWN(handle, path, uid, gid);
1120         clock_gettime_mono(&ts2);
1121         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1122
1123         if (timediff > audit_timeout) {
1124                 smb_time_audit_log_fname("lchown", timediff, path);
1125         }
1126
1127         return result;
1128 }
1129
1130 static int smb_time_audit_chdir(vfs_handle_struct *handle, const char *path)
1131 {
1132         int result;
1133         struct timespec ts1,ts2;
1134         double timediff;
1135
1136         clock_gettime_mono(&ts1);
1137         result = SMB_VFS_NEXT_CHDIR(handle, path);
1138         clock_gettime_mono(&ts2);
1139         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1140
1141         if (timediff > audit_timeout) {
1142                 smb_time_audit_log_fname("chdir", timediff, path);
1143         }
1144
1145         return result;
1146 }
1147
1148 static char *smb_time_audit_getwd(vfs_handle_struct *handle)
1149 {
1150         char *result;
1151         struct timespec ts1,ts2;
1152         double timediff;
1153
1154         clock_gettime_mono(&ts1);
1155         result = SMB_VFS_NEXT_GETWD(handle);
1156         clock_gettime_mono(&ts2);
1157         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1158
1159         if (timediff > audit_timeout) {
1160                 smb_time_audit_log("getwd", timediff);
1161         }
1162
1163         return result;
1164 }
1165
1166 static int smb_time_audit_ntimes(vfs_handle_struct *handle,
1167                                  const struct smb_filename *path,
1168                                  struct smb_file_time *ft)
1169 {
1170         int result;
1171         struct timespec ts1,ts2;
1172         double timediff;
1173
1174         clock_gettime_mono(&ts1);
1175         result = SMB_VFS_NEXT_NTIMES(handle, path, ft);
1176         clock_gettime_mono(&ts2);
1177         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1178
1179         if (timediff > audit_timeout) {
1180                 smb_time_audit_log_smb_fname("ntimes", timediff, path);
1181         }
1182
1183         return result;
1184 }
1185
1186 static int smb_time_audit_ftruncate(vfs_handle_struct *handle,
1187                                     files_struct *fsp,
1188                                     off_t len)
1189 {
1190         int result;
1191         struct timespec ts1,ts2;
1192         double timediff;
1193
1194         clock_gettime_mono(&ts1);
1195         result = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, len);
1196         clock_gettime_mono(&ts2);
1197         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1198
1199         if (timediff > audit_timeout) {
1200                 smb_time_audit_log_fsp("ftruncate", timediff, fsp);
1201         }
1202
1203         return result;
1204 }
1205
1206 static int smb_time_audit_fallocate(vfs_handle_struct *handle,
1207                                     files_struct *fsp,
1208                                     enum vfs_fallocate_mode mode,
1209                                     off_t offset,
1210                                     off_t len)
1211 {
1212         int result;
1213         struct timespec ts1,ts2;
1214         double timediff;
1215
1216         clock_gettime_mono(&ts1);
1217         result = SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len);
1218         clock_gettime_mono(&ts2);
1219         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1220
1221         if (timediff > audit_timeout) {
1222                 smb_time_audit_log_fsp("fallocate", timediff, fsp);
1223         }
1224
1225         return result;
1226 }
1227
1228 static bool smb_time_audit_lock(vfs_handle_struct *handle, files_struct *fsp,
1229                                 int op, off_t offset, off_t count,
1230                                 int type)
1231 {
1232         bool result;
1233         struct timespec ts1,ts2;
1234         double timediff;
1235
1236         clock_gettime_mono(&ts1);
1237         result = SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type);
1238         clock_gettime_mono(&ts2);
1239         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1240
1241         if (timediff > audit_timeout) {
1242                 smb_time_audit_log_fsp("lock", timediff, fsp);
1243         }
1244
1245         return result;
1246 }
1247
1248 static int smb_time_audit_kernel_flock(struct vfs_handle_struct *handle,
1249                                        struct files_struct *fsp,
1250                                        uint32 share_mode, uint32 access_mask)
1251 {
1252         int result;
1253         struct timespec ts1,ts2;
1254         double timediff;
1255
1256         clock_gettime_mono(&ts1);
1257         result = SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, share_mode,
1258                                            access_mask);
1259         clock_gettime_mono(&ts2);
1260         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1261
1262         if (timediff > audit_timeout) {
1263                 smb_time_audit_log_fsp("kernel_flock", timediff, fsp);
1264         }
1265
1266         return result;
1267 }
1268
1269 static int smb_time_audit_linux_setlease(vfs_handle_struct *handle,
1270                                          files_struct *fsp,
1271                                          int leasetype)
1272 {
1273         int result;
1274         struct timespec ts1,ts2;
1275         double timediff;
1276
1277         clock_gettime_mono(&ts1);
1278         result = SMB_VFS_NEXT_LINUX_SETLEASE(handle, fsp, leasetype);
1279         clock_gettime_mono(&ts2);
1280         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1281
1282         if (timediff > audit_timeout) {
1283                 smb_time_audit_log_fsp("linux_setlease", timediff, fsp);
1284         }
1285
1286         return result;
1287 }
1288
1289 static bool smb_time_audit_getlock(vfs_handle_struct *handle,
1290                                    files_struct *fsp,
1291                                    off_t *poffset, off_t *pcount,
1292                                    int *ptype, pid_t *ppid)
1293 {
1294         bool result;
1295         struct timespec ts1,ts2;
1296         double timediff;
1297
1298         clock_gettime_mono(&ts1);
1299         result = SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, pcount, ptype,
1300                                       ppid);
1301         clock_gettime_mono(&ts2);
1302         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1303
1304         if (timediff > audit_timeout) {
1305                 smb_time_audit_log_fsp("getlock", timediff, fsp);
1306         }
1307
1308         return result;
1309 }
1310
1311 static int smb_time_audit_symlink(vfs_handle_struct *handle,
1312                                   const char *oldpath, const char *newpath)
1313 {
1314         int result;
1315         struct timespec ts1,ts2;
1316         double timediff;
1317
1318         clock_gettime_mono(&ts1);
1319         result = SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
1320         clock_gettime_mono(&ts2);
1321         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1322
1323         if (timediff > audit_timeout) {
1324                 smb_time_audit_log_fname("symlink", timediff, newpath);
1325         }
1326
1327         return result;
1328 }
1329
1330 static int smb_time_audit_readlink(vfs_handle_struct *handle,
1331                           const char *path, char *buf, size_t bufsiz)
1332 {
1333         int result;
1334         struct timespec ts1,ts2;
1335         double timediff;
1336
1337         clock_gettime_mono(&ts1);
1338         result = SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz);
1339         clock_gettime_mono(&ts2);
1340         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1341
1342         if (timediff > audit_timeout) {
1343                 smb_time_audit_log_fname("readlink", timediff, path);
1344         }
1345
1346         return result;
1347 }
1348
1349 static int smb_time_audit_link(vfs_handle_struct *handle,
1350                                const char *oldpath, const char *newpath)
1351 {
1352         int result;
1353         struct timespec ts1,ts2;
1354         double timediff;
1355
1356         clock_gettime_mono(&ts1);
1357         result = SMB_VFS_NEXT_LINK(handle, oldpath, newpath);
1358         clock_gettime_mono(&ts2);
1359         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1360
1361         if (timediff > audit_timeout) {
1362                 smb_time_audit_log_fname("link", timediff, newpath);
1363         }
1364
1365         return result;
1366 }
1367
1368 static int smb_time_audit_mknod(vfs_handle_struct *handle,
1369                                 const char *pathname, mode_t mode,
1370                                 SMB_DEV_T dev)
1371 {
1372         int result;
1373         struct timespec ts1,ts2;
1374         double timediff;
1375
1376         clock_gettime_mono(&ts1);
1377         result = SMB_VFS_NEXT_MKNOD(handle, pathname, mode, dev);
1378         clock_gettime_mono(&ts2);
1379         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1380
1381         if (timediff > audit_timeout) {
1382                 smb_time_audit_log_fname("mknod", timediff, pathname);
1383         }
1384
1385         return result;
1386 }
1387
1388 static char *smb_time_audit_realpath(vfs_handle_struct *handle,
1389                                      const char *path)
1390 {
1391         char *result;
1392         struct timespec ts1,ts2;
1393         double timediff;
1394
1395         clock_gettime_mono(&ts1);
1396         result = SMB_VFS_NEXT_REALPATH(handle, path);
1397         clock_gettime_mono(&ts2);
1398         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1399
1400         if (timediff > audit_timeout) {
1401                 smb_time_audit_log_fname("realpath", timediff, path);
1402         }
1403
1404         return result;
1405 }
1406
1407 static NTSTATUS smb_time_audit_notify_watch(struct vfs_handle_struct *handle,
1408                         struct sys_notify_context *ctx,
1409                         const char *path,
1410                         uint32_t *filter,
1411                         uint32_t *subdir_filter,
1412                         void (*callback)(struct sys_notify_context *ctx,
1413                                         void *private_data,
1414                                         struct notify_event *ev),
1415                         void *private_data, void *handle_p)
1416 {
1417         NTSTATUS result;
1418         struct timespec ts1,ts2;
1419         double timediff;
1420
1421         clock_gettime_mono(&ts1);
1422         result = SMB_VFS_NEXT_NOTIFY_WATCH(handle, ctx, path,
1423                                            filter, subdir_filter, callback,
1424                                            private_data, handle_p);
1425         clock_gettime_mono(&ts2);
1426         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1427
1428         if (timediff > audit_timeout) {
1429                 smb_time_audit_log_fname("notify_watch", timediff, path);
1430         }
1431
1432         return result;
1433 }
1434
1435 static int smb_time_audit_chflags(vfs_handle_struct *handle,
1436                                   const char *path, unsigned int flags)
1437 {
1438         int result;
1439         struct timespec ts1,ts2;
1440         double timediff;
1441
1442         clock_gettime_mono(&ts1);
1443         result = SMB_VFS_NEXT_CHFLAGS(handle, path, flags);
1444         clock_gettime_mono(&ts2);
1445         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1446
1447         if (timediff > audit_timeout) {
1448                 smb_time_audit_log_fname("chflags", timediff, path);
1449         }
1450
1451         return result;
1452 }
1453
1454 static struct file_id smb_time_audit_file_id_create(struct vfs_handle_struct *handle,
1455                                                     const SMB_STRUCT_STAT *sbuf)
1456 {
1457         struct file_id id_zero;
1458         struct file_id result;
1459         struct timespec ts1,ts2;
1460         double timediff;
1461
1462         ZERO_STRUCT(id_zero);
1463
1464         clock_gettime_mono(&ts1);
1465         result = SMB_VFS_NEXT_FILE_ID_CREATE(handle, sbuf);
1466         clock_gettime_mono(&ts2);
1467         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1468
1469         if (timediff > audit_timeout) {
1470                 smb_time_audit_log("file_id_create", timediff);
1471         }
1472
1473         return result;
1474 }
1475
1476 static NTSTATUS smb_time_audit_streaminfo(vfs_handle_struct *handle,
1477                                           struct files_struct *fsp,
1478                                           const char *fname,
1479                                           TALLOC_CTX *mem_ctx,
1480                                           unsigned int *pnum_streams,
1481                                           struct stream_struct **pstreams)
1482 {
1483         NTSTATUS result;
1484         struct timespec ts1,ts2;
1485         double timediff;
1486
1487         clock_gettime_mono(&ts1);
1488         result = SMB_VFS_NEXT_STREAMINFO(handle, fsp, fname, mem_ctx,
1489                                          pnum_streams, pstreams);
1490         clock_gettime_mono(&ts2);
1491         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1492
1493         if (timediff > audit_timeout) {
1494                 smb_time_audit_log_fsp("streaminfo", timediff, fsp);
1495         }
1496
1497         return result;
1498 }
1499
1500 static int smb_time_audit_get_real_filename(struct vfs_handle_struct *handle,
1501                                             const char *path,
1502                                             const char *name,
1503                                             TALLOC_CTX *mem_ctx,
1504                                             char **found_name)
1505 {
1506         int result;
1507         struct timespec ts1,ts2;
1508         double timediff;
1509
1510         clock_gettime_mono(&ts1);
1511         result = SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name, mem_ctx,
1512                                                 found_name);
1513         clock_gettime_mono(&ts2);
1514         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1515
1516         if (timediff > audit_timeout) {
1517                 smb_time_audit_log_fname("get_real_filename", timediff, path);
1518         }
1519
1520         return result;
1521 }
1522
1523 static const char *smb_time_audit_connectpath(vfs_handle_struct *handle,
1524                                               const char *fname)
1525 {
1526         const char *result;
1527         struct timespec ts1,ts2;
1528         double timediff;
1529
1530         clock_gettime_mono(&ts1);
1531         result = SMB_VFS_NEXT_CONNECTPATH(handle, fname);
1532         clock_gettime_mono(&ts2);
1533         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1534
1535         if (timediff > audit_timeout) {
1536                 smb_time_audit_log_fname("connectpath", timediff, fname);
1537         }
1538
1539         return result;
1540 }
1541
1542 static NTSTATUS smb_time_audit_brl_lock_windows(struct vfs_handle_struct *handle,
1543                                                 struct byte_range_lock *br_lck,
1544                                                 struct lock_struct *plock,
1545                                                 bool blocking_lock,
1546                                                 struct blocking_lock_record *blr)
1547 {
1548         NTSTATUS result;
1549         struct timespec ts1,ts2;
1550         double timediff;
1551
1552         clock_gettime_mono(&ts1);
1553         result = SMB_VFS_NEXT_BRL_LOCK_WINDOWS(handle, br_lck, plock,
1554                                                blocking_lock, blr);
1555         clock_gettime_mono(&ts2);
1556         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1557
1558         if (timediff > audit_timeout) {
1559                 smb_time_audit_log_fsp("brl_lock_windows", timediff,
1560                                        br_lck->fsp);
1561         }
1562
1563         return result;
1564 }
1565
1566 static bool smb_time_audit_brl_unlock_windows(struct vfs_handle_struct *handle,
1567                                               struct messaging_context *msg_ctx,
1568                                               struct byte_range_lock *br_lck,
1569                                               const struct lock_struct *plock)
1570 {
1571         bool result;
1572         struct timespec ts1,ts2;
1573         double timediff;
1574
1575         clock_gettime_mono(&ts1);
1576         result = SMB_VFS_NEXT_BRL_UNLOCK_WINDOWS(handle, msg_ctx, br_lck,
1577                                                  plock);
1578         clock_gettime_mono(&ts2);
1579         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1580
1581         if (timediff > audit_timeout) {
1582                 smb_time_audit_log_fsp("brl_unlock_windows", timediff,
1583                                        br_lck->fsp);
1584         }
1585
1586         return result;
1587 }
1588
1589 static bool smb_time_audit_brl_cancel_windows(struct vfs_handle_struct *handle,
1590                                               struct byte_range_lock *br_lck,
1591                                               struct lock_struct *plock,
1592                                               struct blocking_lock_record *blr)
1593 {
1594         bool result;
1595         struct timespec ts1,ts2;
1596         double timediff;
1597
1598         clock_gettime_mono(&ts1);
1599         result = SMB_VFS_NEXT_BRL_CANCEL_WINDOWS(handle, br_lck, plock, blr);
1600         clock_gettime_mono(&ts2);
1601         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1602
1603         if (timediff > audit_timeout) {
1604                 smb_time_audit_log_fsp("brl_cancel_windows", timediff,
1605                                        br_lck->fsp);
1606         }
1607
1608         return result;
1609 }
1610
1611 static bool smb_time_audit_strict_lock(struct vfs_handle_struct *handle,
1612                                        struct files_struct *fsp,
1613                                        struct lock_struct *plock)
1614 {
1615         bool result;
1616         struct timespec ts1,ts2;
1617         double timediff;
1618
1619         clock_gettime_mono(&ts1);
1620         result = SMB_VFS_NEXT_STRICT_LOCK(handle, fsp, plock);
1621         clock_gettime_mono(&ts2);
1622         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1623
1624         if (timediff > audit_timeout) {
1625                 smb_time_audit_log_fsp("strict_lock", timediff, fsp);
1626         }
1627
1628         return result;
1629 }
1630
1631 static void smb_time_audit_strict_unlock(struct vfs_handle_struct *handle,
1632                                          struct files_struct *fsp,
1633                                          struct lock_struct *plock)
1634 {
1635         struct timespec ts1,ts2;
1636         double timediff;
1637
1638         clock_gettime_mono(&ts1);
1639         SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock);
1640         clock_gettime_mono(&ts2);
1641         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1642
1643         if (timediff > audit_timeout) {
1644                 smb_time_audit_log_fsp("strict_unlock", timediff, fsp);
1645         }
1646 }
1647
1648 static NTSTATUS smb_time_audit_translate_name(struct vfs_handle_struct *handle,
1649                                               const char *name,
1650                                               enum vfs_translate_direction direction,
1651                                               TALLOC_CTX *mem_ctx,
1652                                               char **mapped_name)
1653 {
1654         NTSTATUS result;
1655         struct timespec ts1,ts2;
1656         double timediff;
1657
1658         clock_gettime_mono(&ts1);
1659         result = SMB_VFS_NEXT_TRANSLATE_NAME(handle, name, direction, mem_ctx,
1660                                              mapped_name);
1661         clock_gettime_mono(&ts2);
1662         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1663
1664         if (timediff > audit_timeout) {
1665                 smb_time_audit_log_fname("translate_name", timediff, name);
1666         }
1667
1668         return result;
1669 }
1670
1671 static NTSTATUS smb_time_audit_fget_nt_acl(vfs_handle_struct *handle,
1672                                            files_struct *fsp,
1673                                            uint32 security_info,
1674                                            TALLOC_CTX *mem_ctx,
1675                                            struct security_descriptor **ppdesc)
1676 {
1677         NTSTATUS result;
1678         struct timespec ts1,ts2;
1679         double timediff;
1680
1681         clock_gettime_mono(&ts1);
1682         result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info,
1683                                           mem_ctx, ppdesc);
1684         clock_gettime_mono(&ts2);
1685         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1686
1687         if (timediff > audit_timeout) {
1688                 smb_time_audit_log_fsp("fget_nt_acl", timediff, fsp);
1689         }
1690
1691         return result;
1692 }
1693
1694 static NTSTATUS smb_time_audit_get_nt_acl(vfs_handle_struct *handle,
1695                                           const char *name,
1696                                           uint32 security_info,
1697                                           TALLOC_CTX *mem_ctx,
1698                                           struct security_descriptor **ppdesc)
1699 {
1700         NTSTATUS result;
1701         struct timespec ts1,ts2;
1702         double timediff;
1703
1704         clock_gettime_mono(&ts1);
1705         result = SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info,
1706                                          mem_ctx, ppdesc);
1707         clock_gettime_mono(&ts2);
1708         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1709
1710         if (timediff > audit_timeout) {
1711                 smb_time_audit_log_fname("get_nt_acl", timediff, name);
1712         }
1713
1714         return result;
1715 }
1716
1717 static NTSTATUS smb_time_audit_fset_nt_acl(vfs_handle_struct *handle,
1718                                            files_struct *fsp,
1719                                            uint32 security_info_sent,
1720                                            const struct security_descriptor *psd)
1721 {
1722         NTSTATUS result;
1723         struct timespec ts1,ts2;
1724         double timediff;
1725
1726         clock_gettime_mono(&ts1);
1727         result = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent,
1728                                           psd);
1729         clock_gettime_mono(&ts2);
1730         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1731
1732         if (timediff > audit_timeout) {
1733                 smb_time_audit_log_fsp("fset_nt_acl", timediff, fsp);
1734         }
1735
1736         return result;
1737 }
1738
1739 static int smb_time_audit_chmod_acl(vfs_handle_struct *handle,
1740                                     const char *path, mode_t mode)
1741 {
1742         int result;
1743         struct timespec ts1,ts2;
1744         double timediff;
1745
1746         clock_gettime_mono(&ts1);
1747         result = SMB_VFS_NEXT_CHMOD_ACL(handle, path, mode);
1748         clock_gettime_mono(&ts2);
1749         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1750
1751         if (timediff > audit_timeout) {
1752                 smb_time_audit_log_fname("chmod_acl", timediff, path);
1753         }
1754
1755         return result;
1756 }
1757
1758 static int smb_time_audit_fchmod_acl(vfs_handle_struct *handle,
1759                                      files_struct *fsp, mode_t mode)
1760 {
1761         int result;
1762         struct timespec ts1,ts2;
1763         double timediff;
1764
1765         clock_gettime_mono(&ts1);
1766         result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode);
1767         clock_gettime_mono(&ts2);
1768         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1769
1770         if (timediff > audit_timeout) {
1771                 smb_time_audit_log_fsp("fchmod_acl", timediff, fsp);
1772         }
1773
1774         return result;
1775 }
1776
1777 static SMB_ACL_T smb_time_audit_sys_acl_get_file(vfs_handle_struct *handle,
1778                                                  const char *path_p,
1779                                                  SMB_ACL_TYPE_T type,
1780                                                  TALLOC_CTX *mem_ctx)
1781 {
1782         SMB_ACL_T result;
1783         struct timespec ts1,ts2;
1784         double timediff;
1785
1786         clock_gettime_mono(&ts1);
1787         result = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type, mem_ctx);
1788         clock_gettime_mono(&ts2);
1789         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1790
1791         if (timediff > audit_timeout) {
1792                 smb_time_audit_log_fname("sys_acl_get_file", timediff, path_p);
1793         }
1794
1795         return result;
1796 }
1797
1798 static SMB_ACL_T smb_time_audit_sys_acl_get_fd(vfs_handle_struct *handle,
1799                                                files_struct *fsp,
1800                                                TALLOC_CTX *mem_ctx)
1801 {
1802         SMB_ACL_T result;
1803         struct timespec ts1,ts2;
1804         double timediff;
1805
1806         clock_gettime_mono(&ts1);
1807         result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, mem_ctx);
1808         clock_gettime_mono(&ts2);
1809         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1810
1811         if (timediff > audit_timeout) {
1812                 smb_time_audit_log_fsp("sys_acl_get_fd", timediff, fsp);
1813         }
1814
1815         return result;
1816 }
1817
1818
1819 static int smb_time_audit_sys_acl_blob_get_file(vfs_handle_struct *handle,
1820                                                 const char *path_p,
1821                                                 TALLOC_CTX *mem_ctx, 
1822                                                 char **blob_description,
1823                                                 DATA_BLOB *blob)
1824 {
1825         int result;
1826         struct timespec ts1,ts2;
1827         double timediff;
1828
1829         clock_gettime_mono(&ts1);
1830         result = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, path_p, mem_ctx, blob_description, blob);
1831         clock_gettime_mono(&ts2);
1832         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1833
1834         if (timediff > audit_timeout) {
1835                 smb_time_audit_log("sys_acl_blob_get_file", timediff);
1836         }
1837
1838         return result;
1839 }
1840
1841 static int smb_time_audit_sys_acl_blob_get_fd(vfs_handle_struct *handle,
1842                                               files_struct *fsp,
1843                                               TALLOC_CTX *mem_ctx, 
1844                                               char **blob_description,
1845                                               DATA_BLOB *blob)
1846 {
1847         int result;
1848         struct timespec ts1,ts2;
1849         double timediff;
1850
1851         clock_gettime_mono(&ts1);
1852         result = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle, fsp, mem_ctx, blob_description, blob);
1853         clock_gettime_mono(&ts2);
1854         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1855
1856         if (timediff > audit_timeout) {
1857                 smb_time_audit_log("sys_acl_blob_get_fd", timediff);
1858         }
1859
1860         return result;
1861 }
1862
1863 static int smb_time_audit_sys_acl_set_file(vfs_handle_struct *handle,
1864                                            const char *name,
1865                                            SMB_ACL_TYPE_T acltype,
1866                                            SMB_ACL_T theacl)
1867 {
1868         int result;
1869         struct timespec ts1,ts2;
1870         double timediff;
1871
1872         clock_gettime_mono(&ts1);
1873         result = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name, acltype,
1874                                                theacl);
1875         clock_gettime_mono(&ts2);
1876         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1877
1878         if (timediff > audit_timeout) {
1879                 smb_time_audit_log_fname("sys_acl_set_file", timediff, name);
1880         }
1881
1882         return result;
1883 }
1884
1885 static int smb_time_audit_sys_acl_set_fd(vfs_handle_struct *handle,
1886                                          files_struct *fsp,
1887                                          SMB_ACL_T theacl)
1888 {
1889         int result;
1890         struct timespec ts1,ts2;
1891         double timediff;
1892
1893         clock_gettime_mono(&ts1);
1894         result = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl);
1895         clock_gettime_mono(&ts2);
1896         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1897
1898         if (timediff > audit_timeout) {
1899                 smb_time_audit_log_fsp("sys_acl_set_fd", timediff, fsp);
1900         }
1901
1902         return result;
1903 }
1904
1905 static int smb_time_audit_sys_acl_delete_def_file(vfs_handle_struct *handle,
1906                                                   const char *path)
1907 {
1908         int result;
1909         struct timespec ts1,ts2;
1910         double timediff;
1911
1912         clock_gettime_mono(&ts1);
1913         result = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, path);
1914         clock_gettime_mono(&ts2);
1915         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1916
1917         if (timediff > audit_timeout) {
1918                 smb_time_audit_log_fname("sys_acl_delete_def_file", timediff, path);
1919         }
1920
1921         return result;
1922 }
1923
1924 static ssize_t smb_time_audit_getxattr(struct vfs_handle_struct *handle,
1925                                        const char *path, const char *name,
1926                                        void *value, size_t size)
1927 {
1928         ssize_t result;
1929         struct timespec ts1,ts2;
1930         double timediff;
1931
1932         clock_gettime_mono(&ts1);
1933         result = SMB_VFS_NEXT_GETXATTR(handle, path, name, value, size);
1934         clock_gettime_mono(&ts2);
1935         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1936
1937         if (timediff > audit_timeout) {
1938                 smb_time_audit_log_fname("getxattr", timediff, path);
1939         }
1940
1941         return result;
1942 }
1943
1944 static ssize_t smb_time_audit_fgetxattr(struct vfs_handle_struct *handle,
1945                                         struct files_struct *fsp,
1946                                         const char *name, void *value,
1947                                         size_t size)
1948 {
1949         ssize_t result;
1950         struct timespec ts1,ts2;
1951         double timediff;
1952
1953         clock_gettime_mono(&ts1);
1954         result = SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, value, size);
1955         clock_gettime_mono(&ts2);
1956         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1957
1958         if (timediff > audit_timeout) {
1959                 smb_time_audit_log_fsp("fgetxattr", timediff, fsp);
1960         }
1961
1962         return result;
1963 }
1964
1965 static ssize_t smb_time_audit_listxattr(struct vfs_handle_struct *handle,
1966                                         const char *path, char *list,
1967                                         size_t size)
1968 {
1969         ssize_t result;
1970         struct timespec ts1,ts2;
1971         double timediff;
1972
1973         clock_gettime_mono(&ts1);
1974         result = SMB_VFS_NEXT_LISTXATTR(handle, path, list, size);
1975         clock_gettime_mono(&ts2);
1976         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1977
1978         if (timediff > audit_timeout) {
1979                 smb_time_audit_log_fname("listxattr", timediff, path);
1980         }
1981
1982         return result;
1983 }
1984
1985 static ssize_t smb_time_audit_flistxattr(struct vfs_handle_struct *handle,
1986                                          struct files_struct *fsp, char *list,
1987                                          size_t size)
1988 {
1989         ssize_t result;
1990         struct timespec ts1,ts2;
1991         double timediff;
1992
1993         clock_gettime_mono(&ts1);
1994         result = SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size);
1995         clock_gettime_mono(&ts2);
1996         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1997
1998         if (timediff > audit_timeout) {
1999                 smb_time_audit_log_fsp("flistxattr", timediff, fsp);
2000         }
2001
2002         return result;
2003 }
2004
2005 static int smb_time_audit_removexattr(struct vfs_handle_struct *handle,
2006                                       const char *path, const char *name)
2007 {
2008         int result;
2009         struct timespec ts1,ts2;
2010         double timediff;
2011
2012         clock_gettime_mono(&ts1);
2013         result = SMB_VFS_NEXT_REMOVEXATTR(handle, path, name);
2014         clock_gettime_mono(&ts2);
2015         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2016
2017         if (timediff > audit_timeout) {
2018                 smb_time_audit_log_fname("removexattr", timediff, path);
2019         }
2020
2021         return result;
2022 }
2023
2024 static int smb_time_audit_fremovexattr(struct vfs_handle_struct *handle,
2025                                        struct files_struct *fsp,
2026                                        const char *name)
2027 {
2028         int result;
2029         struct timespec ts1,ts2;
2030         double timediff;
2031
2032         clock_gettime_mono(&ts1);
2033         result = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, name);
2034         clock_gettime_mono(&ts2);
2035         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2036
2037         if (timediff > audit_timeout) {
2038                 smb_time_audit_log_fsp("fremovexattr", timediff, fsp);
2039         }
2040
2041         return result;
2042 }
2043
2044 static int smb_time_audit_setxattr(struct vfs_handle_struct *handle,
2045                                    const char *path, const char *name,
2046                                    const void *value, size_t size,
2047                                    int flags)
2048 {
2049         int result;
2050         struct timespec ts1,ts2;
2051         double timediff;
2052
2053         clock_gettime_mono(&ts1);
2054         result = SMB_VFS_NEXT_SETXATTR(handle, path, name, value, size,
2055                                        flags);
2056         clock_gettime_mono(&ts2);
2057         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2058
2059         if (timediff > audit_timeout) {
2060                 smb_time_audit_log_fname("setxattr", timediff, path);
2061         }
2062
2063         return result;
2064 }
2065
2066 static int smb_time_audit_fsetxattr(struct vfs_handle_struct *handle,
2067                                     struct files_struct *fsp, const char *name,
2068                                     const void *value, size_t size, int flags)
2069 {
2070         int result;
2071         struct timespec ts1,ts2;
2072         double timediff;
2073
2074         clock_gettime_mono(&ts1);
2075         result = SMB_VFS_NEXT_FSETXATTR(handle, fsp, name, value, size, flags);
2076         clock_gettime_mono(&ts2);
2077         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2078
2079         if (timediff > audit_timeout) {
2080                 smb_time_audit_log_fsp("fsetxattr", timediff, fsp);
2081         }
2082
2083         return result;
2084 }
2085
2086 static bool smb_time_audit_aio_force(struct vfs_handle_struct *handle,
2087                                      struct files_struct *fsp)
2088 {
2089         bool result;
2090         struct timespec ts1,ts2;
2091         double timediff;
2092
2093         clock_gettime_mono(&ts1);
2094         result = SMB_VFS_NEXT_AIO_FORCE(handle, fsp);
2095         clock_gettime_mono(&ts2);
2096         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2097
2098         if (timediff > audit_timeout) {
2099                 smb_time_audit_log_fsp("aio_force", timediff, fsp);
2100         }
2101
2102         return result;
2103 }
2104
2105
2106
2107 /* VFS operations */
2108
2109 static struct vfs_fn_pointers vfs_time_audit_fns = {
2110         .connect_fn = smb_time_audit_connect,
2111         .disconnect_fn = smb_time_audit_disconnect,
2112         .disk_free_fn = smb_time_audit_disk_free,
2113         .get_quota_fn = smb_time_audit_get_quota,
2114         .set_quota_fn = smb_time_audit_set_quota,
2115         .get_shadow_copy_data_fn = smb_time_audit_get_shadow_copy_data,
2116         .statvfs_fn = smb_time_audit_statvfs,
2117         .fs_capabilities_fn = smb_time_audit_fs_capabilities,
2118         .opendir_fn = smb_time_audit_opendir,
2119         .fdopendir_fn = smb_time_audit_fdopendir,
2120         .readdir_fn = smb_time_audit_readdir,
2121         .seekdir_fn = smb_time_audit_seekdir,
2122         .telldir_fn = smb_time_audit_telldir,
2123         .rewind_dir_fn = smb_time_audit_rewinddir,
2124         .mkdir_fn = smb_time_audit_mkdir,
2125         .rmdir_fn = smb_time_audit_rmdir,
2126         .closedir_fn = smb_time_audit_closedir,
2127         .init_search_op_fn = smb_time_audit_init_search_op,
2128         .open_fn = smb_time_audit_open,
2129         .create_file_fn = smb_time_audit_create_file,
2130         .close_fn = smb_time_audit_close,
2131         .read_fn = smb_time_audit_read,
2132         .pread_fn = smb_time_audit_pread,
2133         .pread_send_fn = smb_time_audit_pread_send,
2134         .pread_recv_fn = smb_time_audit_pread_recv,
2135         .write_fn = smb_time_audit_write,
2136         .pwrite_fn = smb_time_audit_pwrite,
2137         .pwrite_send_fn = smb_time_audit_pwrite_send,
2138         .pwrite_recv_fn = smb_time_audit_pwrite_recv,
2139         .lseek_fn = smb_time_audit_lseek,
2140         .sendfile_fn = smb_time_audit_sendfile,
2141         .recvfile_fn = smb_time_audit_recvfile,
2142         .rename_fn = smb_time_audit_rename,
2143         .fsync_fn = smb_time_audit_fsync,
2144         .fsync_send_fn = smb_time_audit_fsync_send,
2145         .fsync_recv_fn = smb_time_audit_fsync_recv,
2146         .stat_fn = smb_time_audit_stat,
2147         .fstat_fn = smb_time_audit_fstat,
2148         .lstat_fn = smb_time_audit_lstat,
2149         .get_alloc_size_fn = smb_time_audit_get_alloc_size,
2150         .unlink_fn = smb_time_audit_unlink,
2151         .chmod_fn = smb_time_audit_chmod,
2152         .fchmod_fn = smb_time_audit_fchmod,
2153         .chown_fn = smb_time_audit_chown,
2154         .fchown_fn = smb_time_audit_fchown,
2155         .lchown_fn = smb_time_audit_lchown,
2156         .chdir_fn = smb_time_audit_chdir,
2157         .getwd_fn = smb_time_audit_getwd,
2158         .ntimes_fn = smb_time_audit_ntimes,
2159         .ftruncate_fn = smb_time_audit_ftruncate,
2160         .fallocate_fn = smb_time_audit_fallocate,
2161         .lock_fn = smb_time_audit_lock,
2162         .kernel_flock_fn = smb_time_audit_kernel_flock,
2163         .linux_setlease_fn = smb_time_audit_linux_setlease,
2164         .getlock_fn = smb_time_audit_getlock,
2165         .symlink_fn = smb_time_audit_symlink,
2166         .readlink_fn = smb_time_audit_readlink,
2167         .link_fn = smb_time_audit_link,
2168         .mknod_fn = smb_time_audit_mknod,
2169         .realpath_fn = smb_time_audit_realpath,
2170         .notify_watch_fn = smb_time_audit_notify_watch,
2171         .chflags_fn = smb_time_audit_chflags,
2172         .file_id_create_fn = smb_time_audit_file_id_create,
2173         .streaminfo_fn = smb_time_audit_streaminfo,
2174         .get_real_filename_fn = smb_time_audit_get_real_filename,
2175         .connectpath_fn = smb_time_audit_connectpath,
2176         .brl_lock_windows_fn = smb_time_audit_brl_lock_windows,
2177         .brl_unlock_windows_fn = smb_time_audit_brl_unlock_windows,
2178         .brl_cancel_windows_fn = smb_time_audit_brl_cancel_windows,
2179         .strict_lock_fn = smb_time_audit_strict_lock,
2180         .strict_unlock_fn = smb_time_audit_strict_unlock,
2181         .translate_name_fn = smb_time_audit_translate_name,
2182         .fget_nt_acl_fn = smb_time_audit_fget_nt_acl,
2183         .get_nt_acl_fn = smb_time_audit_get_nt_acl,
2184         .fset_nt_acl_fn = smb_time_audit_fset_nt_acl,
2185         .chmod_acl_fn = smb_time_audit_chmod_acl,
2186         .fchmod_acl_fn = smb_time_audit_fchmod_acl,
2187         .sys_acl_get_file_fn = smb_time_audit_sys_acl_get_file,
2188         .sys_acl_get_fd_fn = smb_time_audit_sys_acl_get_fd,
2189         .sys_acl_blob_get_file_fn = smb_time_audit_sys_acl_blob_get_file,
2190         .sys_acl_blob_get_fd_fn = smb_time_audit_sys_acl_blob_get_fd,
2191         .sys_acl_set_file_fn = smb_time_audit_sys_acl_set_file,
2192         .sys_acl_set_fd_fn = smb_time_audit_sys_acl_set_fd,
2193         .sys_acl_delete_def_file_fn = smb_time_audit_sys_acl_delete_def_file,
2194         .getxattr_fn = smb_time_audit_getxattr,
2195         .fgetxattr_fn = smb_time_audit_fgetxattr,
2196         .listxattr_fn = smb_time_audit_listxattr,
2197         .flistxattr_fn = smb_time_audit_flistxattr,
2198         .removexattr_fn = smb_time_audit_removexattr,
2199         .fremovexattr_fn = smb_time_audit_fremovexattr,
2200         .setxattr_fn = smb_time_audit_setxattr,
2201         .fsetxattr_fn = smb_time_audit_fsetxattr,
2202         .aio_force_fn = smb_time_audit_aio_force,
2203 };
2204
2205
2206 NTSTATUS vfs_time_audit_init(void);
2207 NTSTATUS vfs_time_audit_init(void)
2208 {
2209         audit_timeout = (double)lp_parm_int(-1, "time_audit", "timeout",
2210                                             10000) / 1000.0;
2211         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "time_audit",
2212                                 &vfs_time_audit_fns);
2213 }