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