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