smbd: Add extra VFS hooks to get the posix ACL as a blob
[mat/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
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                                            struct security_descriptor **ppdesc)
1675 {
1676         NTSTATUS result;
1677         struct timespec ts1,ts2;
1678         double timediff;
1679
1680         clock_gettime_mono(&ts1);
1681         result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc);
1682         clock_gettime_mono(&ts2);
1683         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1684
1685         if (timediff > audit_timeout) {
1686                 smb_time_audit_log_fsp("fget_nt_acl", timediff, fsp);
1687         }
1688
1689         return result;
1690 }
1691
1692 static NTSTATUS smb_time_audit_get_nt_acl(vfs_handle_struct *handle,
1693                                           const char *name,
1694                                           uint32 security_info,
1695                                           struct security_descriptor **ppdesc)
1696 {
1697         NTSTATUS result;
1698         struct timespec ts1,ts2;
1699         double timediff;
1700
1701         clock_gettime_mono(&ts1);
1702         result = SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, ppdesc);
1703         clock_gettime_mono(&ts2);
1704         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1705
1706         if (timediff > audit_timeout) {
1707                 smb_time_audit_log_fname("get_nt_acl", timediff, name);
1708         }
1709
1710         return result;
1711 }
1712
1713 static NTSTATUS smb_time_audit_fset_nt_acl(vfs_handle_struct *handle,
1714                                            files_struct *fsp,
1715                                            uint32 security_info_sent,
1716                                            const struct security_descriptor *psd)
1717 {
1718         NTSTATUS result;
1719         struct timespec ts1,ts2;
1720         double timediff;
1721
1722         clock_gettime_mono(&ts1);
1723         result = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent,
1724                                           psd);
1725         clock_gettime_mono(&ts2);
1726         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1727
1728         if (timediff > audit_timeout) {
1729                 smb_time_audit_log_fsp("fset_nt_acl", timediff, fsp);
1730         }
1731
1732         return result;
1733 }
1734
1735 static int smb_time_audit_chmod_acl(vfs_handle_struct *handle,
1736                                     const char *path, mode_t mode)
1737 {
1738         int result;
1739         struct timespec ts1,ts2;
1740         double timediff;
1741
1742         clock_gettime_mono(&ts1);
1743         result = SMB_VFS_NEXT_CHMOD_ACL(handle, path, mode);
1744         clock_gettime_mono(&ts2);
1745         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1746
1747         if (timediff > audit_timeout) {
1748                 smb_time_audit_log_fname("chmod_acl", timediff, path);
1749         }
1750
1751         return result;
1752 }
1753
1754 static int smb_time_audit_fchmod_acl(vfs_handle_struct *handle,
1755                                      files_struct *fsp, mode_t mode)
1756 {
1757         int result;
1758         struct timespec ts1,ts2;
1759         double timediff;
1760
1761         clock_gettime_mono(&ts1);
1762         result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode);
1763         clock_gettime_mono(&ts2);
1764         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1765
1766         if (timediff > audit_timeout) {
1767                 smb_time_audit_log_fsp("fchmod_acl", timediff, fsp);
1768         }
1769
1770         return result;
1771 }
1772
1773 static SMB_ACL_T smb_time_audit_sys_acl_get_file(vfs_handle_struct *handle,
1774                                                  const char *path_p,
1775                                                  SMB_ACL_TYPE_T type)
1776 {
1777         SMB_ACL_T result;
1778         struct timespec ts1,ts2;
1779         double timediff;
1780
1781         clock_gettime_mono(&ts1);
1782         result = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type);
1783         clock_gettime_mono(&ts2);
1784         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1785
1786         if (timediff > audit_timeout) {
1787                 smb_time_audit_log_fname("sys_acl_get_file", timediff, path_p);
1788         }
1789
1790         return result;
1791 }
1792
1793 static SMB_ACL_T smb_time_audit_sys_acl_get_fd(vfs_handle_struct *handle,
1794                                                files_struct *fsp)
1795 {
1796         SMB_ACL_T result;
1797         struct timespec ts1,ts2;
1798         double timediff;
1799
1800         clock_gettime_mono(&ts1);
1801         result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp);
1802         clock_gettime_mono(&ts2);
1803         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1804
1805         if (timediff > audit_timeout) {
1806                 smb_time_audit_log_fsp("sys_acl_get_fd", timediff, fsp);
1807         }
1808
1809         return result;
1810 }
1811
1812
1813 static int smb_time_audit_sys_acl_blob_get_file(vfs_handle_struct *handle,
1814                                                 const char *path_p,
1815                                                 SMB_ACL_TYPE_T type,    
1816                                                 TALLOC_CTX *mem_ctx, 
1817                                                 char **blob_description,
1818                                                 DATA_BLOB *blob)
1819 {
1820         int result;
1821         struct timespec ts1,ts2;
1822         double timediff;
1823
1824         clock_gettime_mono(&ts1);
1825         result = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, path_p, type, mem_ctx, blob_description, blob);
1826         clock_gettime_mono(&ts2);
1827         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1828
1829         if (timediff > audit_timeout) {
1830                 smb_time_audit_log("sys_acl_blob_get_file", timediff);
1831         }
1832
1833         return result;
1834 }
1835
1836 static int smb_time_audit_sys_acl_blob_get_fd(vfs_handle_struct *handle,
1837                                               files_struct *fsp,
1838                                               TALLOC_CTX *mem_ctx, 
1839                                               char **blob_description,
1840                                               DATA_BLOB *blob)
1841 {
1842         int result;
1843         struct timespec ts1,ts2;
1844         double timediff;
1845
1846         clock_gettime_mono(&ts1);
1847         result = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle, fsp, mem_ctx, blob_description, blob);
1848         clock_gettime_mono(&ts2);
1849         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1850
1851         if (timediff > audit_timeout) {
1852                 smb_time_audit_log("sys_acl_blob_get_fd", timediff);
1853         }
1854
1855         return result;
1856 }
1857
1858 static int smb_time_audit_sys_acl_set_file(vfs_handle_struct *handle,
1859                                            const char *name,
1860                                            SMB_ACL_TYPE_T acltype,
1861                                            SMB_ACL_T theacl)
1862 {
1863         int result;
1864         struct timespec ts1,ts2;
1865         double timediff;
1866
1867         clock_gettime_mono(&ts1);
1868         result = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name, acltype,
1869                                                theacl);
1870         clock_gettime_mono(&ts2);
1871         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1872
1873         if (timediff > audit_timeout) {
1874                 smb_time_audit_log_fname("sys_acl_set_file", timediff, name);
1875         }
1876
1877         return result;
1878 }
1879
1880 static int smb_time_audit_sys_acl_set_fd(vfs_handle_struct *handle,
1881                                          files_struct *fsp,
1882                                          SMB_ACL_T theacl)
1883 {
1884         int result;
1885         struct timespec ts1,ts2;
1886         double timediff;
1887
1888         clock_gettime_mono(&ts1);
1889         result = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl);
1890         clock_gettime_mono(&ts2);
1891         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1892
1893         if (timediff > audit_timeout) {
1894                 smb_time_audit_log_fsp("sys_acl_set_fd", timediff, fsp);
1895         }
1896
1897         return result;
1898 }
1899
1900 static int smb_time_audit_sys_acl_delete_def_file(vfs_handle_struct *handle,
1901                                                   const char *path)
1902 {
1903         int result;
1904         struct timespec ts1,ts2;
1905         double timediff;
1906
1907         clock_gettime_mono(&ts1);
1908         result = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, path);
1909         clock_gettime_mono(&ts2);
1910         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1911
1912         if (timediff > audit_timeout) {
1913                 smb_time_audit_log_fname("sys_acl_delete_def_file", timediff, path);
1914         }
1915
1916         return result;
1917 }
1918
1919 static ssize_t smb_time_audit_getxattr(struct vfs_handle_struct *handle,
1920                                        const char *path, const char *name,
1921                                        void *value, size_t size)
1922 {
1923         ssize_t result;
1924         struct timespec ts1,ts2;
1925         double timediff;
1926
1927         clock_gettime_mono(&ts1);
1928         result = SMB_VFS_NEXT_GETXATTR(handle, path, name, value, size);
1929         clock_gettime_mono(&ts2);
1930         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1931
1932         if (timediff > audit_timeout) {
1933                 smb_time_audit_log_fname("getxattr", timediff, path);
1934         }
1935
1936         return result;
1937 }
1938
1939 static ssize_t smb_time_audit_fgetxattr(struct vfs_handle_struct *handle,
1940                                         struct files_struct *fsp,
1941                                         const char *name, void *value,
1942                                         size_t size)
1943 {
1944         ssize_t result;
1945         struct timespec ts1,ts2;
1946         double timediff;
1947
1948         clock_gettime_mono(&ts1);
1949         result = SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, value, size);
1950         clock_gettime_mono(&ts2);
1951         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1952
1953         if (timediff > audit_timeout) {
1954                 smb_time_audit_log_fsp("fgetxattr", timediff, fsp);
1955         }
1956
1957         return result;
1958 }
1959
1960 static ssize_t smb_time_audit_listxattr(struct vfs_handle_struct *handle,
1961                                         const char *path, char *list,
1962                                         size_t size)
1963 {
1964         ssize_t result;
1965         struct timespec ts1,ts2;
1966         double timediff;
1967
1968         clock_gettime_mono(&ts1);
1969         result = SMB_VFS_NEXT_LISTXATTR(handle, path, list, size);
1970         clock_gettime_mono(&ts2);
1971         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1972
1973         if (timediff > audit_timeout) {
1974                 smb_time_audit_log_fname("listxattr", timediff, path);
1975         }
1976
1977         return result;
1978 }
1979
1980 static ssize_t smb_time_audit_flistxattr(struct vfs_handle_struct *handle,
1981                                          struct files_struct *fsp, char *list,
1982                                          size_t size)
1983 {
1984         ssize_t result;
1985         struct timespec ts1,ts2;
1986         double timediff;
1987
1988         clock_gettime_mono(&ts1);
1989         result = SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size);
1990         clock_gettime_mono(&ts2);
1991         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
1992
1993         if (timediff > audit_timeout) {
1994                 smb_time_audit_log_fsp("flistxattr", timediff, fsp);
1995         }
1996
1997         return result;
1998 }
1999
2000 static int smb_time_audit_removexattr(struct vfs_handle_struct *handle,
2001                                       const char *path, const char *name)
2002 {
2003         int result;
2004         struct timespec ts1,ts2;
2005         double timediff;
2006
2007         clock_gettime_mono(&ts1);
2008         result = SMB_VFS_NEXT_REMOVEXATTR(handle, path, name);
2009         clock_gettime_mono(&ts2);
2010         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2011
2012         if (timediff > audit_timeout) {
2013                 smb_time_audit_log_fname("removexattr", timediff, path);
2014         }
2015
2016         return result;
2017 }
2018
2019 static int smb_time_audit_fremovexattr(struct vfs_handle_struct *handle,
2020                                        struct files_struct *fsp,
2021                                        const char *name)
2022 {
2023         int result;
2024         struct timespec ts1,ts2;
2025         double timediff;
2026
2027         clock_gettime_mono(&ts1);
2028         result = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, name);
2029         clock_gettime_mono(&ts2);
2030         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2031
2032         if (timediff > audit_timeout) {
2033                 smb_time_audit_log_fsp("fremovexattr", timediff, fsp);
2034         }
2035
2036         return result;
2037 }
2038
2039 static int smb_time_audit_setxattr(struct vfs_handle_struct *handle,
2040                                    const char *path, const char *name,
2041                                    const void *value, size_t size,
2042                                    int flags)
2043 {
2044         int result;
2045         struct timespec ts1,ts2;
2046         double timediff;
2047
2048         clock_gettime_mono(&ts1);
2049         result = SMB_VFS_NEXT_SETXATTR(handle, path, name, value, size,
2050                                        flags);
2051         clock_gettime_mono(&ts2);
2052         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2053
2054         if (timediff > audit_timeout) {
2055                 smb_time_audit_log_fname("setxattr", timediff, path);
2056         }
2057
2058         return result;
2059 }
2060
2061 static int smb_time_audit_fsetxattr(struct vfs_handle_struct *handle,
2062                                     struct files_struct *fsp, const char *name,
2063                                     const void *value, size_t size, int flags)
2064 {
2065         int result;
2066         struct timespec ts1,ts2;
2067         double timediff;
2068
2069         clock_gettime_mono(&ts1);
2070         result = SMB_VFS_NEXT_FSETXATTR(handle, fsp, name, value, size, flags);
2071         clock_gettime_mono(&ts2);
2072         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2073
2074         if (timediff > audit_timeout) {
2075                 smb_time_audit_log_fsp("fsetxattr", timediff, fsp);
2076         }
2077
2078         return result;
2079 }
2080
2081 static bool smb_time_audit_aio_force(struct vfs_handle_struct *handle,
2082                                      struct files_struct *fsp)
2083 {
2084         bool result;
2085         struct timespec ts1,ts2;
2086         double timediff;
2087
2088         clock_gettime_mono(&ts1);
2089         result = SMB_VFS_NEXT_AIO_FORCE(handle, fsp);
2090         clock_gettime_mono(&ts2);
2091         timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
2092
2093         if (timediff > audit_timeout) {
2094                 smb_time_audit_log_fsp("aio_force", timediff, fsp);
2095         }
2096
2097         return result;
2098 }
2099
2100
2101
2102 /* VFS operations */
2103
2104 static struct vfs_fn_pointers vfs_time_audit_fns = {
2105         .connect_fn = smb_time_audit_connect,
2106         .disconnect_fn = smb_time_audit_disconnect,
2107         .disk_free_fn = smb_time_audit_disk_free,
2108         .get_quota_fn = smb_time_audit_get_quota,
2109         .set_quota_fn = smb_time_audit_set_quota,
2110         .get_shadow_copy_data_fn = smb_time_audit_get_shadow_copy_data,
2111         .statvfs_fn = smb_time_audit_statvfs,
2112         .fs_capabilities_fn = smb_time_audit_fs_capabilities,
2113         .opendir_fn = smb_time_audit_opendir,
2114         .fdopendir_fn = smb_time_audit_fdopendir,
2115         .readdir_fn = smb_time_audit_readdir,
2116         .seekdir_fn = smb_time_audit_seekdir,
2117         .telldir_fn = smb_time_audit_telldir,
2118         .rewind_dir_fn = smb_time_audit_rewinddir,
2119         .mkdir_fn = smb_time_audit_mkdir,
2120         .rmdir_fn = smb_time_audit_rmdir,
2121         .closedir_fn = smb_time_audit_closedir,
2122         .init_search_op_fn = smb_time_audit_init_search_op,
2123         .open_fn = smb_time_audit_open,
2124         .create_file_fn = smb_time_audit_create_file,
2125         .close_fn = smb_time_audit_close,
2126         .read_fn = smb_time_audit_read,
2127         .pread_fn = smb_time_audit_pread,
2128         .pread_send_fn = smb_time_audit_pread_send,
2129         .pread_recv_fn = smb_time_audit_pread_recv,
2130         .write_fn = smb_time_audit_write,
2131         .pwrite_fn = smb_time_audit_pwrite,
2132         .pwrite_send_fn = smb_time_audit_pwrite_send,
2133         .pwrite_recv_fn = smb_time_audit_pwrite_recv,
2134         .lseek_fn = smb_time_audit_lseek,
2135         .sendfile_fn = smb_time_audit_sendfile,
2136         .recvfile_fn = smb_time_audit_recvfile,
2137         .rename_fn = smb_time_audit_rename,
2138         .fsync_fn = smb_time_audit_fsync,
2139         .fsync_send_fn = smb_time_audit_fsync_send,
2140         .fsync_recv_fn = smb_time_audit_fsync_recv,
2141         .stat_fn = smb_time_audit_stat,
2142         .fstat_fn = smb_time_audit_fstat,
2143         .lstat_fn = smb_time_audit_lstat,
2144         .get_alloc_size_fn = smb_time_audit_get_alloc_size,
2145         .unlink_fn = smb_time_audit_unlink,
2146         .chmod_fn = smb_time_audit_chmod,
2147         .fchmod_fn = smb_time_audit_fchmod,
2148         .chown_fn = smb_time_audit_chown,
2149         .fchown_fn = smb_time_audit_fchown,
2150         .lchown_fn = smb_time_audit_lchown,
2151         .chdir_fn = smb_time_audit_chdir,
2152         .getwd_fn = smb_time_audit_getwd,
2153         .ntimes_fn = smb_time_audit_ntimes,
2154         .ftruncate_fn = smb_time_audit_ftruncate,
2155         .fallocate_fn = smb_time_audit_fallocate,
2156         .lock_fn = smb_time_audit_lock,
2157         .kernel_flock_fn = smb_time_audit_kernel_flock,
2158         .linux_setlease_fn = smb_time_audit_linux_setlease,
2159         .getlock_fn = smb_time_audit_getlock,
2160         .symlink_fn = smb_time_audit_symlink,
2161         .readlink_fn = smb_time_audit_readlink,
2162         .link_fn = smb_time_audit_link,
2163         .mknod_fn = smb_time_audit_mknod,
2164         .realpath_fn = smb_time_audit_realpath,
2165         .notify_watch_fn = smb_time_audit_notify_watch,
2166         .chflags_fn = smb_time_audit_chflags,
2167         .file_id_create_fn = smb_time_audit_file_id_create,
2168         .streaminfo_fn = smb_time_audit_streaminfo,
2169         .get_real_filename_fn = smb_time_audit_get_real_filename,
2170         .connectpath_fn = smb_time_audit_connectpath,
2171         .brl_lock_windows_fn = smb_time_audit_brl_lock_windows,
2172         .brl_unlock_windows_fn = smb_time_audit_brl_unlock_windows,
2173         .brl_cancel_windows_fn = smb_time_audit_brl_cancel_windows,
2174         .strict_lock_fn = smb_time_audit_strict_lock,
2175         .strict_unlock_fn = smb_time_audit_strict_unlock,
2176         .translate_name_fn = smb_time_audit_translate_name,
2177         .fget_nt_acl_fn = smb_time_audit_fget_nt_acl,
2178         .get_nt_acl_fn = smb_time_audit_get_nt_acl,
2179         .fset_nt_acl_fn = smb_time_audit_fset_nt_acl,
2180         .chmod_acl_fn = smb_time_audit_chmod_acl,
2181         .fchmod_acl_fn = smb_time_audit_fchmod_acl,
2182         .sys_acl_get_file_fn = smb_time_audit_sys_acl_get_file,
2183         .sys_acl_get_fd_fn = smb_time_audit_sys_acl_get_fd,
2184         .sys_acl_blob_get_file_fn = smb_time_audit_sys_acl_blob_get_file,
2185         .sys_acl_blob_get_fd_fn = smb_time_audit_sys_acl_blob_get_fd,
2186         .sys_acl_set_file_fn = smb_time_audit_sys_acl_set_file,
2187         .sys_acl_set_fd_fn = smb_time_audit_sys_acl_set_fd,
2188         .sys_acl_delete_def_file_fn = smb_time_audit_sys_acl_delete_def_file,
2189         .getxattr_fn = smb_time_audit_getxattr,
2190         .fgetxattr_fn = smb_time_audit_fgetxattr,
2191         .listxattr_fn = smb_time_audit_listxattr,
2192         .flistxattr_fn = smb_time_audit_flistxattr,
2193         .removexattr_fn = smb_time_audit_removexattr,
2194         .fremovexattr_fn = smb_time_audit_fremovexattr,
2195         .setxattr_fn = smb_time_audit_setxattr,
2196         .fsetxattr_fn = smb_time_audit_fsetxattr,
2197         .aio_force_fn = smb_time_audit_aio_force,
2198 };
2199
2200
2201 NTSTATUS vfs_time_audit_init(void);
2202 NTSTATUS vfs_time_audit_init(void)
2203 {
2204         audit_timeout = (double)lp_parm_int(-1, "time_audit", "timeout",
2205                                             10000) / 1000.0;
2206         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "time_audit",
2207                                 &vfs_time_audit_fns);
2208 }