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