s3/vfs: merge offline functionality into DOS attributes handling
[samba.git] / source3 / modules / vfs_default.c
1 /*
2    Unix SMB/CIFS implementation.
3    Wrap disk only vfs functions to sidestep dodgy compilers.
4    Copyright (C) Tim Potter 1998
5    Copyright (C) Jeremy Allison 2007
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 #include "includes.h"
22 #include "system/time.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "ntioctl.h"
27 #include "smbprofile.h"
28 #include "../libcli/security/security.h"
29 #include "passdb/lookup_sid.h"
30 #include "source3/include/msdfs.h"
31 #include "librpc/gen_ndr/ndr_dfsblobs.h"
32 #include "lib/util/tevent_unix.h"
33 #include "lib/util/tevent_ntstatus.h"
34 #include "lib/util/sys_rw.h"
35 #include "lib/pthreadpool/pthreadpool_tevent.h"
36
37 #undef DBGC_CLASS
38 #define DBGC_CLASS DBGC_VFS
39
40 /* Check for NULL pointer parameters in vfswrap_* functions */
41
42 /* We don't want to have NULL function pointers lying around.  Someone
43    is sure to try and execute them.  These stubs are used to prevent
44    this possibility. */
45
46 static int vfswrap_connect(vfs_handle_struct *handle, const char *service, const char *user)
47 {
48     return 0;    /* Return >= 0 for success */
49 }
50
51 static void vfswrap_disconnect(vfs_handle_struct *handle)
52 {
53 }
54
55 /* Disk operations */
56
57 static uint64_t vfswrap_disk_free(vfs_handle_struct *handle, const char *path,
58                                   uint64_t *bsize, uint64_t *dfree,
59                                   uint64_t *dsize)
60 {
61         if (sys_fsusage(path, dfree, dsize) != 0) {
62                 return (uint64_t)-1;
63         }
64
65         *bsize = 512;
66         return *dfree / 2;
67 }
68
69 static int vfswrap_get_quota(struct vfs_handle_struct *handle, const char *path,
70                              enum SMB_QUOTA_TYPE qtype, unid_t id,
71                              SMB_DISK_QUOTA *qt)
72 {
73 #ifdef HAVE_SYS_QUOTAS
74         int result;
75
76         START_PROFILE(syscall_get_quota);
77         result = sys_get_quota(path, qtype, id, qt);
78         END_PROFILE(syscall_get_quota);
79         return result;
80 #else
81         errno = ENOSYS;
82         return -1;
83 #endif
84 }
85
86 static int vfswrap_set_quota(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
87 {
88 #ifdef HAVE_SYS_QUOTAS
89         int result;
90
91         START_PROFILE(syscall_set_quota);
92         result = sys_set_quota(handle->conn->connectpath, qtype, id, qt);
93         END_PROFILE(syscall_set_quota);
94         return result;
95 #else
96         errno = ENOSYS;
97         return -1;
98 #endif
99 }
100
101 static int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle,
102                                         struct files_struct *fsp,
103                                         struct shadow_copy_data *shadow_copy_data,
104                                         bool labels)
105 {
106         errno = ENOSYS;
107         return -1;  /* Not implemented. */
108 }
109
110 static int vfswrap_statvfs(struct vfs_handle_struct *handle, const char *path, vfs_statvfs_struct *statbuf)
111 {
112         return sys_statvfs(path, statbuf);
113 }
114
115 static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle,
116                 enum timestamp_set_resolution *p_ts_res)
117 {
118         connection_struct *conn = handle->conn;
119         uint32_t caps = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
120         struct smb_filename *smb_fname_cpath = NULL;
121         struct vfs_statvfs_struct statbuf;
122         int ret;
123
124         ZERO_STRUCT(statbuf);
125         ret = sys_statvfs(conn->connectpath, &statbuf);
126         if (ret == 0) {
127                 caps = statbuf.FsCapabilities;
128         }
129
130         *p_ts_res = TIMESTAMP_SET_SECONDS;
131
132         /* Work out what timestamp resolution we can
133          * use when setting a timestamp. */
134
135         smb_fname_cpath = synthetic_smb_fname(talloc_tos(), conn->connectpath,
136                                               NULL, NULL, 0);
137         if (smb_fname_cpath == NULL) {
138                 return caps;
139         }
140
141         ret = SMB_VFS_STAT(conn, smb_fname_cpath);
142         if (ret == -1) {
143                 TALLOC_FREE(smb_fname_cpath);
144                 return caps;
145         }
146
147         if (smb_fname_cpath->st.st_ex_mtime.tv_nsec ||
148                         smb_fname_cpath->st.st_ex_atime.tv_nsec ||
149                         smb_fname_cpath->st.st_ex_ctime.tv_nsec) {
150                 /* If any of the normal UNIX directory timestamps
151                  * have a non-zero tv_nsec component assume
152                  * we might be able to set sub-second timestamps.
153                  * See what filetime set primitives we have.
154                  */
155 #if defined(HAVE_UTIMENSAT)
156                 *p_ts_res = TIMESTAMP_SET_NT_OR_BETTER;
157 #elif defined(HAVE_UTIMES)
158                 /* utimes allows msec timestamps to be set. */
159                 *p_ts_res = TIMESTAMP_SET_MSEC;
160 #elif defined(HAVE_UTIME)
161                 /* utime only allows sec timestamps to be set. */
162                 *p_ts_res = TIMESTAMP_SET_SECONDS;
163 #endif
164
165                 DEBUG(10,("vfswrap_fs_capabilities: timestamp "
166                         "resolution of %s "
167                         "available on share %s, directory %s\n",
168                         *p_ts_res == TIMESTAMP_SET_MSEC ? "msec" : "sec",
169                         lp_servicename(talloc_tos(), conn->params->service),
170                         conn->connectpath ));
171         }
172         TALLOC_FREE(smb_fname_cpath);
173         return caps;
174 }
175
176 static NTSTATUS vfswrap_get_dfs_referrals(struct vfs_handle_struct *handle,
177                                           struct dfs_GetDFSReferral *r)
178 {
179         struct junction_map *junction = NULL;
180         int consumedcnt = 0;
181         bool self_referral = false;
182         char *pathnamep = NULL;
183         char *local_dfs_path = NULL;
184         NTSTATUS status;
185         int i;
186         uint16_t max_referral_level = r->in.req.max_referral_level;
187
188         if (DEBUGLVL(10)) {
189                 NDR_PRINT_IN_DEBUG(dfs_GetDFSReferral, r);
190         }
191
192         /* get the junction entry */
193         if (r->in.req.servername == NULL) {
194                 return NT_STATUS_NOT_FOUND;
195         }
196
197         /*
198          * Trim pathname sent by client so it begins with only one backslash.
199          * Two backslashes confuse some dfs clients
200          */
201
202         local_dfs_path = talloc_strdup(r, r->in.req.servername);
203         if (local_dfs_path == NULL) {
204                 return NT_STATUS_NO_MEMORY;
205         }
206         pathnamep = local_dfs_path;
207         while (IS_DIRECTORY_SEP(pathnamep[0]) &&
208                IS_DIRECTORY_SEP(pathnamep[1])) {
209                 pathnamep++;
210         }
211
212         junction = talloc_zero(r, struct junction_map);
213         if (junction == NULL) {
214                 return NT_STATUS_NO_MEMORY;
215         }
216
217         /* The following call can change cwd. */
218         status = get_referred_path(r, pathnamep,
219                                    !handle->conn->sconn->using_smb2,
220                                    junction, &consumedcnt, &self_referral);
221         if (!NT_STATUS_IS_OK(status)) {
222                 vfs_ChDir(handle->conn, handle->conn->connectpath);
223                 return status;
224         }
225         vfs_ChDir(handle->conn, handle->conn->connectpath);
226
227         if (!self_referral) {
228                 pathnamep[consumedcnt] = '\0';
229
230                 if (DEBUGLVL(3)) {
231                         dbgtext("Path %s to alternate path(s):",
232                                 pathnamep);
233                         for (i=0; i < junction->referral_count; i++) {
234                                 dbgtext(" %s",
235                                 junction->referral_list[i].alternate_path);
236                         }
237                         dbgtext(".\n");
238                 }
239         }
240
241         if (r->in.req.max_referral_level <= 2) {
242                 max_referral_level = 2;
243         }
244         if (r->in.req.max_referral_level >= 3) {
245                 max_referral_level = 3;
246         }
247
248         r->out.resp = talloc_zero(r, struct dfs_referral_resp);
249         if (r->out.resp == NULL) {
250                 return NT_STATUS_NO_MEMORY;
251         }
252
253         r->out.resp->path_consumed = strlen_m(pathnamep) * 2;
254         r->out.resp->nb_referrals = junction->referral_count;
255
256         r->out.resp->header_flags = DFS_HEADER_FLAG_STORAGE_SVR;
257         if (self_referral) {
258                 r->out.resp->header_flags |= DFS_HEADER_FLAG_REFERAL_SVR;
259         }
260
261         r->out.resp->referral_entries = talloc_zero_array(r,
262                                 struct dfs_referral_type,
263                                 r->out.resp->nb_referrals);
264         if (r->out.resp->referral_entries == NULL) {
265                 return NT_STATUS_NO_MEMORY;
266         }
267
268         switch (max_referral_level) {
269         case 2:
270                 for(i=0; i < junction->referral_count; i++) {
271                         struct referral *ref = &junction->referral_list[i];
272                         TALLOC_CTX *mem_ctx = r->out.resp->referral_entries;
273                         struct dfs_referral_type *t =
274                                 &r->out.resp->referral_entries[i];
275                         struct dfs_referral_v2 *v2 = &t->referral.v2;
276
277                         t->version = 2;
278                         v2->size = VERSION2_REFERRAL_SIZE;
279                         if (self_referral) {
280                                 v2->server_type = DFS_SERVER_ROOT;
281                         } else {
282                                 v2->server_type = DFS_SERVER_NON_ROOT;
283                         }
284                         v2->entry_flags = 0;
285                         v2->proximity = ref->proximity;
286                         v2->ttl = ref->ttl;
287                         v2->DFS_path = talloc_strdup(mem_ctx, pathnamep);
288                         if (v2->DFS_path == NULL) {
289                                 return NT_STATUS_NO_MEMORY;
290                         }
291                         v2->DFS_alt_path = talloc_strdup(mem_ctx, pathnamep);
292                         if (v2->DFS_alt_path == NULL) {
293                                 return NT_STATUS_NO_MEMORY;
294                         }
295                         v2->netw_address = talloc_strdup(mem_ctx,
296                                                          ref->alternate_path);
297                         if (v2->netw_address == NULL) {
298                                 return NT_STATUS_NO_MEMORY;
299                         }
300                 }
301
302                 break;
303         case 3:
304                 for(i=0; i < junction->referral_count; i++) {
305                         struct referral *ref = &junction->referral_list[i];
306                         TALLOC_CTX *mem_ctx = r->out.resp->referral_entries;
307                         struct dfs_referral_type *t =
308                                 &r->out.resp->referral_entries[i];
309                         struct dfs_referral_v3 *v3 = &t->referral.v3;
310                         struct dfs_normal_referral *r1 = &v3->referrals.r1;
311
312                         t->version = 3;
313                         v3->size = VERSION3_REFERRAL_SIZE;
314                         if (self_referral) {
315                                 v3->server_type = DFS_SERVER_ROOT;
316                         } else {
317                                 v3->server_type = DFS_SERVER_NON_ROOT;
318                         }
319                         v3->entry_flags = 0;
320                         v3->ttl = ref->ttl;
321                         r1->DFS_path = talloc_strdup(mem_ctx, pathnamep);
322                         if (r1->DFS_path == NULL) {
323                                 return NT_STATUS_NO_MEMORY;
324                         }
325                         r1->DFS_alt_path = talloc_strdup(mem_ctx, pathnamep);
326                         if (r1->DFS_alt_path == NULL) {
327                                 return NT_STATUS_NO_MEMORY;
328                         }
329                         r1->netw_address = talloc_strdup(mem_ctx,
330                                                          ref->alternate_path);
331                         if (r1->netw_address == NULL) {
332                                 return NT_STATUS_NO_MEMORY;
333                         }
334                 }
335                 break;
336         default:
337                 DEBUG(0,("Invalid dfs referral version: %d\n",
338                         max_referral_level));
339                 return NT_STATUS_INVALID_LEVEL;
340         }
341
342         if (DEBUGLVL(10)) {
343                 NDR_PRINT_OUT_DEBUG(dfs_GetDFSReferral, r);
344         }
345
346         return NT_STATUS_OK;
347 }
348
349 static NTSTATUS vfswrap_snap_check_path(struct vfs_handle_struct *handle,
350                                         TALLOC_CTX *mem_ctx,
351                                         const char *service_path,
352                                         char **base_volume)
353 {
354         return NT_STATUS_NOT_SUPPORTED;
355 }
356
357 static NTSTATUS vfswrap_snap_create(struct vfs_handle_struct *handle,
358                                     TALLOC_CTX *mem_ctx,
359                                     const char *base_volume,
360                                     time_t *tstamp,
361                                     bool rw,
362                                     char **base_path,
363                                     char **snap_path)
364 {
365         return NT_STATUS_NOT_SUPPORTED;
366 }
367
368 static NTSTATUS vfswrap_snap_delete(struct vfs_handle_struct *handle,
369                                     TALLOC_CTX *mem_ctx,
370                                     char *base_path,
371                                     char *snap_path)
372 {
373         return NT_STATUS_NOT_SUPPORTED;
374 }
375
376 /* Directory operations */
377
378 static DIR *vfswrap_opendir(vfs_handle_struct *handle,
379                                 const struct smb_filename *smb_fname,
380                                 const char *mask,
381                                 uint32_t attr)
382 {
383         DIR *result;
384
385         START_PROFILE(syscall_opendir);
386         result = opendir(smb_fname->base_name);
387         END_PROFILE(syscall_opendir);
388         return result;
389 }
390
391 static DIR *vfswrap_fdopendir(vfs_handle_struct *handle,
392                         files_struct *fsp,
393                         const char *mask,
394                         uint32_t attr)
395 {
396         DIR *result;
397
398         START_PROFILE(syscall_fdopendir);
399         result = sys_fdopendir(fsp->fh->fd);
400         END_PROFILE(syscall_fdopendir);
401         return result;
402 }
403
404
405 static struct dirent *vfswrap_readdir(vfs_handle_struct *handle,
406                                           DIR *dirp,
407                                           SMB_STRUCT_STAT *sbuf)
408 {
409         struct dirent *result;
410
411         START_PROFILE(syscall_readdir);
412         result = readdir(dirp);
413         END_PROFILE(syscall_readdir);
414         if (sbuf) {
415                 /* Default Posix readdir() does not give us stat info.
416                  * Set to invalid to indicate we didn't return this info. */
417                 SET_STAT_INVALID(*sbuf);
418 #if defined(HAVE_DIRFD) && defined(HAVE_FSTATAT)
419                 if (result != NULL) {
420                         /* See if we can efficiently return this. */
421                         struct stat st;
422                         int flags = AT_SYMLINK_NOFOLLOW;
423                         int ret = fstatat(dirfd(dirp),
424                                         result->d_name,
425                                         &st,
426                                         flags);
427                         /*
428                          * As this is an optimization,
429                          * ignore it if we stat'ed a
430                          * symlink. Make the caller
431                          * do it again as we don't
432                          * know if they wanted the link
433                          * info, or its target info.
434                          */
435                         if ((ret == 0) && (!S_ISLNK(st.st_mode))) {
436                                 init_stat_ex_from_stat(sbuf,
437                                         &st,
438                                         lp_fake_directory_create_times(
439                                                 SNUM(handle->conn)));
440                         }
441                 }
442 #endif
443         }
444         return result;
445 }
446
447 static NTSTATUS vfswrap_readdir_attr(struct vfs_handle_struct *handle,
448                                      const struct smb_filename *fname,
449                                      TALLOC_CTX *mem_ctx,
450                                      struct readdir_attr_data **attr_data)
451 {
452         return NT_STATUS_NOT_SUPPORTED;
453 }
454
455 static void vfswrap_seekdir(vfs_handle_struct *handle, DIR *dirp, long offset)
456 {
457         START_PROFILE(syscall_seekdir);
458         seekdir(dirp, offset);
459         END_PROFILE(syscall_seekdir);
460 }
461
462 static long vfswrap_telldir(vfs_handle_struct *handle, DIR *dirp)
463 {
464         long result;
465         START_PROFILE(syscall_telldir);
466         result = telldir(dirp);
467         END_PROFILE(syscall_telldir);
468         return result;
469 }
470
471 static void vfswrap_rewinddir(vfs_handle_struct *handle, DIR *dirp)
472 {
473         START_PROFILE(syscall_rewinddir);
474         rewinddir(dirp);
475         END_PROFILE(syscall_rewinddir);
476 }
477
478 static int vfswrap_mkdir(vfs_handle_struct *handle,
479                         const struct smb_filename *smb_fname,
480                         mode_t mode)
481 {
482         int result;
483         bool has_dacl = False;
484         const char *path = smb_fname->base_name;
485         char *parent = NULL;
486
487         START_PROFILE(syscall_mkdir);
488
489         if (lp_inherit_acls(SNUM(handle->conn))
490             && parent_dirname(talloc_tos(), path, &parent, NULL)
491             && (has_dacl = directory_has_default_acl(handle->conn, parent))) {
492                 mode = (0777 & lp_directory_mask(SNUM(handle->conn)));
493         }
494
495         TALLOC_FREE(parent);
496
497         result = mkdir(path, mode);
498
499         if (result == 0 && !has_dacl) {
500                 /*
501                  * We need to do this as the default behavior of POSIX ACLs
502                  * is to set the mask to be the requested group permission
503                  * bits, not the group permission bits to be the requested
504                  * group permission bits. This is not what we want, as it will
505                  * mess up any inherited ACL bits that were set. JRA.
506                  */
507                 int saved_errno = errno; /* We may get ENOSYS */
508                 if ((SMB_VFS_CHMOD_ACL(handle->conn, smb_fname, mode) == -1) &&
509                                 (errno == ENOSYS)) {
510                         errno = saved_errno;
511                 }
512         }
513
514         END_PROFILE(syscall_mkdir);
515         return result;
516 }
517
518 static int vfswrap_rmdir(vfs_handle_struct *handle,
519                         const struct smb_filename *smb_fname)
520 {
521         int result;
522
523         START_PROFILE(syscall_rmdir);
524         result = rmdir(smb_fname->base_name);
525         END_PROFILE(syscall_rmdir);
526         return result;
527 }
528
529 static int vfswrap_closedir(vfs_handle_struct *handle, DIR *dirp)
530 {
531         int result;
532
533         START_PROFILE(syscall_closedir);
534         result = closedir(dirp);
535         END_PROFILE(syscall_closedir);
536         return result;
537 }
538
539 static void vfswrap_init_search_op(vfs_handle_struct *handle,
540                                    DIR *dirp)
541 {
542         /* Default behavior is a NOOP */
543 }
544
545 /* File operations */
546
547 static int vfswrap_open(vfs_handle_struct *handle,
548                         struct smb_filename *smb_fname,
549                         files_struct *fsp, int flags, mode_t mode)
550 {
551         int result = -1;
552
553         START_PROFILE(syscall_open);
554
555         if (smb_fname->stream_name) {
556                 errno = ENOENT;
557                 goto out;
558         }
559
560         result = open(smb_fname->base_name, flags, mode);
561  out:
562         END_PROFILE(syscall_open);
563         return result;
564 }
565
566 static NTSTATUS vfswrap_create_file(vfs_handle_struct *handle,
567                                     struct smb_request *req,
568                                     uint16_t root_dir_fid,
569                                     struct smb_filename *smb_fname,
570                                     uint32_t access_mask,
571                                     uint32_t share_access,
572                                     uint32_t create_disposition,
573                                     uint32_t create_options,
574                                     uint32_t file_attributes,
575                                     uint32_t oplock_request,
576                                     struct smb2_lease *lease,
577                                     uint64_t allocation_size,
578                                     uint32_t private_flags,
579                                     struct security_descriptor *sd,
580                                     struct ea_list *ea_list,
581                                     files_struct **result,
582                                     int *pinfo,
583                                     const struct smb2_create_blobs *in_context_blobs,
584                                     struct smb2_create_blobs *out_context_blobs)
585 {
586         return create_file_default(handle->conn, req, root_dir_fid, smb_fname,
587                                    access_mask, share_access,
588                                    create_disposition, create_options,
589                                    file_attributes, oplock_request, lease,
590                                    allocation_size, private_flags,
591                                    sd, ea_list, result,
592                                    pinfo, in_context_blobs, out_context_blobs);
593 }
594
595 static int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp)
596 {
597         int result;
598
599         START_PROFILE(syscall_close);
600         result = fd_close_posix(fsp);
601         END_PROFILE(syscall_close);
602         return result;
603 }
604
605 static ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n)
606 {
607         ssize_t result;
608
609         START_PROFILE_BYTES(syscall_read, n);
610         result = sys_read(fsp->fh->fd, data, n);
611         END_PROFILE_BYTES(syscall_read);
612         return result;
613 }
614
615 static ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, void *data,
616                         size_t n, off_t offset)
617 {
618         ssize_t result;
619
620 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
621         START_PROFILE_BYTES(syscall_pread, n);
622         result = sys_pread(fsp->fh->fd, data, n, offset);
623         END_PROFILE_BYTES(syscall_pread);
624
625         if (result == -1 && errno == ESPIPE) {
626                 /* Maintain the fiction that pipes can be seeked (sought?) on. */
627                 result = SMB_VFS_READ(fsp, data, n);
628                 fsp->fh->pos = 0;
629         }
630
631 #else /* HAVE_PREAD */
632         off_t   curr;
633         int lerrno;
634
635         curr = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
636         if (curr == -1 && errno == ESPIPE) {
637                 /* Maintain the fiction that pipes can be seeked (sought?) on. */
638                 result = SMB_VFS_READ(fsp, data, n);
639                 fsp->fh->pos = 0;
640                 return result;
641         }
642
643         if (SMB_VFS_LSEEK(fsp, offset, SEEK_SET) == -1) {
644                 return -1;
645         }
646
647         errno = 0;
648         result = SMB_VFS_READ(fsp, data, n);
649         lerrno = errno;
650
651         SMB_VFS_LSEEK(fsp, curr, SEEK_SET);
652         errno = lerrno;
653
654 #endif /* HAVE_PREAD */
655
656         return result;
657 }
658
659 static ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n)
660 {
661         ssize_t result;
662
663         START_PROFILE_BYTES(syscall_write, n);
664         result = sys_write(fsp->fh->fd, data, n);
665         END_PROFILE_BYTES(syscall_write);
666         return result;
667 }
668
669 static ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, const void *data,
670                         size_t n, off_t offset)
671 {
672         ssize_t result;
673
674 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
675         START_PROFILE_BYTES(syscall_pwrite, n);
676         result = sys_pwrite(fsp->fh->fd, data, n, offset);
677         END_PROFILE_BYTES(syscall_pwrite);
678
679         if (result == -1 && errno == ESPIPE) {
680                 /* Maintain the fiction that pipes can be sought on. */
681                 result = SMB_VFS_WRITE(fsp, data, n);
682         }
683
684 #else /* HAVE_PWRITE */
685         off_t   curr;
686         int         lerrno;
687
688         curr = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
689         if (curr == -1) {
690                 return -1;
691         }
692
693         if (SMB_VFS_LSEEK(fsp, offset, SEEK_SET) == -1) {
694                 return -1;
695         }
696
697         result = SMB_VFS_WRITE(fsp, data, n);
698         lerrno = errno;
699
700         SMB_VFS_LSEEK(fsp, curr, SEEK_SET);
701         errno = lerrno;
702
703 #endif /* HAVE_PWRITE */
704
705         return result;
706 }
707
708 static int vfswrap_init_pool(struct smbd_server_connection *conn)
709 {
710         int ret;
711
712         if (conn->pool != NULL) {
713                 return 0;
714         }
715
716         ret = pthreadpool_tevent_init(conn, lp_aio_max_threads(),
717                                       &conn->pool);
718         return ret;
719 }
720
721 struct vfswrap_pread_state {
722         ssize_t ret;
723         int err;
724         int fd;
725         void *buf;
726         size_t count;
727         off_t offset;
728
729         struct vfs_aio_state vfs_aio_state;
730         SMBPROFILE_BYTES_ASYNC_STATE(profile_bytes);
731 };
732
733 static void vfs_pread_do(void *private_data);
734 static void vfs_pread_done(struct tevent_req *subreq);
735
736 static struct tevent_req *vfswrap_pread_send(struct vfs_handle_struct *handle,
737                                              TALLOC_CTX *mem_ctx,
738                                              struct tevent_context *ev,
739                                              struct files_struct *fsp,
740                                              void *data,
741                                              size_t n, off_t offset)
742 {
743         struct tevent_req *req, *subreq;
744         struct vfswrap_pread_state *state;
745         int ret;
746
747         req = tevent_req_create(mem_ctx, &state, struct vfswrap_pread_state);
748         if (req == NULL) {
749                 return NULL;
750         }
751
752         ret = vfswrap_init_pool(handle->conn->sconn);
753         if (tevent_req_error(req, ret)) {
754                 return tevent_req_post(req, ev);
755         }
756
757         state->ret = -1;
758         state->fd = fsp->fh->fd;
759         state->buf = data;
760         state->count = n;
761         state->offset = offset;
762
763         SMBPROFILE_BYTES_ASYNC_START(syscall_asys_pread, profile_p,
764                                      state->profile_bytes, n);
765         SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
766
767         subreq = pthreadpool_tevent_job_send(
768                 state, ev, handle->conn->sconn->pool,
769                 vfs_pread_do, state);
770         if (tevent_req_nomem(subreq, req)) {
771                 return tevent_req_post(req, ev);
772         }
773         tevent_req_set_callback(subreq, vfs_pread_done, req);
774
775         return req;
776 }
777
778 static void vfs_pread_do(void *private_data)
779 {
780         struct vfswrap_pread_state *state = talloc_get_type_abort(
781                 private_data, struct vfswrap_pread_state);
782         struct timespec start_time;
783         struct timespec end_time;
784
785         SMBPROFILE_BYTES_ASYNC_SET_BUSY(state->profile_bytes);
786
787         PROFILE_TIMESTAMP(&start_time);
788
789         do {
790                 state->ret = pread(state->fd, state->buf, state->count,
791                                    state->offset);
792         } while ((state->ret == -1) && (errno == EINTR));
793
794         state->err = errno;
795
796         PROFILE_TIMESTAMP(&end_time);
797
798         state->vfs_aio_state.duration = nsec_time_diff(&end_time, &start_time);
799
800         SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
801 }
802
803 static void vfs_pread_done(struct tevent_req *subreq)
804 {
805         struct tevent_req *req = tevent_req_callback_data(
806                 subreq, struct tevent_req);
807 #ifdef WITH_PROFILE
808         struct vfswrap_pread_state *state = tevent_req_data(
809                 req, struct vfswrap_pread_state);
810 #endif
811         int ret;
812
813         ret = pthreadpool_tevent_job_recv(subreq);
814         TALLOC_FREE(subreq);
815         SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes);
816         if (tevent_req_error(req, ret)) {
817                 return;
818         }
819
820         tevent_req_done(req);
821 }
822
823 static ssize_t vfswrap_pread_recv(struct tevent_req *req,
824                                   struct vfs_aio_state *vfs_aio_state)
825 {
826         struct vfswrap_pread_state *state = tevent_req_data(
827                 req, struct vfswrap_pread_state);
828
829         if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
830                 return -1;
831         }
832
833         *vfs_aio_state = state->vfs_aio_state;
834         return state->ret;
835 }
836
837 struct vfswrap_pwrite_state {
838         ssize_t ret;
839         int err;
840         int fd;
841         const void *buf;
842         size_t count;
843         off_t offset;
844
845         struct vfs_aio_state vfs_aio_state;
846         SMBPROFILE_BYTES_ASYNC_STATE(profile_bytes);
847 };
848
849 static void vfs_pwrite_do(void *private_data);
850 static void vfs_pwrite_done(struct tevent_req *subreq);
851
852 static struct tevent_req *vfswrap_pwrite_send(struct vfs_handle_struct *handle,
853                                               TALLOC_CTX *mem_ctx,
854                                               struct tevent_context *ev,
855                                               struct files_struct *fsp,
856                                               const void *data,
857                                               size_t n, off_t offset)
858 {
859         struct tevent_req *req, *subreq;
860         struct vfswrap_pwrite_state *state;
861         int ret;
862
863         req = tevent_req_create(mem_ctx, &state, struct vfswrap_pwrite_state);
864         if (req == NULL) {
865                 return NULL;
866         }
867
868         ret = vfswrap_init_pool(handle->conn->sconn);
869         if (tevent_req_error(req, ret)) {
870                 return tevent_req_post(req, ev);
871         }
872
873         state->ret = -1;
874         state->fd = fsp->fh->fd;
875         state->buf = data;
876         state->count = n;
877         state->offset = offset;
878
879         SMBPROFILE_BYTES_ASYNC_START(syscall_asys_pwrite, profile_p,
880                                      state->profile_bytes, n);
881         SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
882
883         subreq = pthreadpool_tevent_job_send(
884                 state, ev, handle->conn->sconn->pool,
885                 vfs_pwrite_do, state);
886         if (tevent_req_nomem(subreq, req)) {
887                 return tevent_req_post(req, ev);
888         }
889         tevent_req_set_callback(subreq, vfs_pwrite_done, req);
890
891         return req;
892 }
893
894 static void vfs_pwrite_do(void *private_data)
895 {
896         struct vfswrap_pwrite_state *state = talloc_get_type_abort(
897                 private_data, struct vfswrap_pwrite_state);
898         struct timespec start_time;
899         struct timespec end_time;
900
901         SMBPROFILE_BYTES_ASYNC_SET_BUSY(state->profile_bytes);
902
903         PROFILE_TIMESTAMP(&start_time);
904
905         do {
906                 state->ret = pwrite(state->fd, state->buf, state->count,
907                                    state->offset);
908         } while ((state->ret == -1) && (errno == EINTR));
909
910         state->err = errno;
911
912         PROFILE_TIMESTAMP(&end_time);
913
914         state->vfs_aio_state.duration = nsec_time_diff(&end_time, &start_time);
915
916         SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
917 }
918
919 static void vfs_pwrite_done(struct tevent_req *subreq)
920 {
921         struct tevent_req *req = tevent_req_callback_data(
922                 subreq, struct tevent_req);
923 #ifdef WITH_PROFILE
924         struct vfswrap_pwrite_state *state = tevent_req_data(
925                 req, struct vfswrap_pwrite_state);
926 #endif
927         int ret;
928
929         ret = pthreadpool_tevent_job_recv(subreq);
930         TALLOC_FREE(subreq);
931         SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes);
932         if (tevent_req_error(req, ret)) {
933                 return;
934         }
935
936         tevent_req_done(req);
937 }
938
939 static ssize_t vfswrap_pwrite_recv(struct tevent_req *req,
940                                    struct vfs_aio_state *vfs_aio_state)
941 {
942         struct vfswrap_pwrite_state *state = tevent_req_data(
943                 req, struct vfswrap_pwrite_state);
944
945         if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
946                 return -1;
947         }
948
949         *vfs_aio_state = state->vfs_aio_state;
950         return state->ret;
951 }
952
953 struct vfswrap_fsync_state {
954         ssize_t ret;
955         int err;
956         int fd;
957
958         struct vfs_aio_state vfs_aio_state;
959         SMBPROFILE_BASIC_ASYNC_STATE(profile_basic);
960 };
961
962 static void vfs_fsync_do(void *private_data);
963 static void vfs_fsync_done(struct tevent_req *subreq);
964
965 static struct tevent_req *vfswrap_fsync_send(struct vfs_handle_struct *handle,
966                                              TALLOC_CTX *mem_ctx,
967                                              struct tevent_context *ev,
968                                              struct files_struct *fsp)
969 {
970         struct tevent_req *req, *subreq;
971         struct vfswrap_fsync_state *state;
972         int ret;
973
974         req = tevent_req_create(mem_ctx, &state, struct vfswrap_fsync_state);
975         if (req == NULL) {
976                 return NULL;
977         }
978
979         ret = vfswrap_init_pool(handle->conn->sconn);
980         if (tevent_req_error(req, ret)) {
981                 return tevent_req_post(req, ev);
982         }
983
984         state->ret = -1;
985         state->fd = fsp->fh->fd;
986
987         SMBPROFILE_BASIC_ASYNC_START(syscall_asys_fsync, profile_p,
988                                      state->profile_basic);
989
990         subreq = pthreadpool_tevent_job_send(
991                 state, ev, handle->conn->sconn->pool, vfs_fsync_do, state);
992         if (tevent_req_nomem(subreq, req)) {
993                 return tevent_req_post(req, ev);
994         }
995         tevent_req_set_callback(subreq, vfs_fsync_done, req);
996
997         return req;
998 }
999
1000 static void vfs_fsync_do(void *private_data)
1001 {
1002         struct vfswrap_fsync_state *state = talloc_get_type_abort(
1003                 private_data, struct vfswrap_fsync_state);
1004         struct timespec start_time;
1005         struct timespec end_time;
1006
1007         PROFILE_TIMESTAMP(&start_time);
1008
1009         do {
1010                 state->ret = fsync(state->fd);
1011         } while ((state->ret == -1) && (errno == EINTR));
1012
1013         state->err = errno;
1014
1015         PROFILE_TIMESTAMP(&end_time);
1016
1017         state->vfs_aio_state.duration = nsec_time_diff(&end_time, &start_time);
1018 }
1019
1020 static void vfs_fsync_done(struct tevent_req *subreq)
1021 {
1022         struct tevent_req *req = tevent_req_callback_data(
1023                 subreq, struct tevent_req);
1024 #ifdef WITH_PROFILE
1025         struct vfswrap_fsync_state *state = tevent_req_data(
1026                 req, struct vfswrap_fsync_state);
1027 #endif
1028         int ret;
1029
1030         ret = pthreadpool_tevent_job_recv(subreq);
1031         TALLOC_FREE(subreq);
1032         SMBPROFILE_BASIC_ASYNC_END(state->profile_basic);
1033         if (tevent_req_error(req, ret)) {
1034                 return;
1035         }
1036
1037         tevent_req_done(req);
1038 }
1039
1040 static int vfswrap_fsync_recv(struct tevent_req *req,
1041                               struct vfs_aio_state *vfs_aio_state)
1042 {
1043         struct vfswrap_fsync_state *state = tevent_req_data(
1044                 req, struct vfswrap_fsync_state);
1045
1046         if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1047                 return -1;
1048         }
1049
1050         *vfs_aio_state = state->vfs_aio_state;
1051         return state->ret;
1052 }
1053
1054 static off_t vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, off_t offset, int whence)
1055 {
1056         off_t result = 0;
1057
1058         START_PROFILE(syscall_lseek);
1059
1060         /* Cope with 'stat' file opens. */
1061         if (fsp->fh->fd != -1)
1062                 result = lseek(fsp->fh->fd, offset, whence);
1063
1064         /*
1065          * We want to maintain the fiction that we can seek
1066          * on a fifo for file system purposes. This allows
1067          * people to set up UNIX fifo's that feed data to Windows
1068          * applications. JRA.
1069          */
1070
1071         if((result == -1) && (errno == ESPIPE)) {
1072                 result = 0;
1073                 errno = 0;
1074         }
1075
1076         END_PROFILE(syscall_lseek);
1077         return result;
1078 }
1079
1080 static ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fromfsp, const DATA_BLOB *hdr,
1081                         off_t offset, size_t n)
1082 {
1083         ssize_t result;
1084
1085         START_PROFILE_BYTES(syscall_sendfile, n);
1086         result = sys_sendfile(tofd, fromfsp->fh->fd, hdr, offset, n);
1087         END_PROFILE_BYTES(syscall_sendfile);
1088         return result;
1089 }
1090
1091 static ssize_t vfswrap_recvfile(vfs_handle_struct *handle,
1092                         int fromfd,
1093                         files_struct *tofsp,
1094                         off_t offset,
1095                         size_t n)
1096 {
1097         ssize_t result;
1098
1099         START_PROFILE_BYTES(syscall_recvfile, n);
1100         result = sys_recvfile(fromfd, tofsp->fh->fd, offset, n);
1101         END_PROFILE_BYTES(syscall_recvfile);
1102         return result;
1103 }
1104
1105 static int vfswrap_rename(vfs_handle_struct *handle,
1106                           const struct smb_filename *smb_fname_src,
1107                           const struct smb_filename *smb_fname_dst)
1108 {
1109         int result = -1;
1110
1111         START_PROFILE(syscall_rename);
1112
1113         if (smb_fname_src->stream_name || smb_fname_dst->stream_name) {
1114                 errno = ENOENT;
1115                 goto out;
1116         }
1117
1118         result = rename(smb_fname_src->base_name, smb_fname_dst->base_name);
1119
1120  out:
1121         END_PROFILE(syscall_rename);
1122         return result;
1123 }
1124
1125 static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp)
1126 {
1127 #ifdef HAVE_FSYNC
1128         int result;
1129
1130         START_PROFILE(syscall_fsync);
1131         result = fsync(fsp->fh->fd);
1132         END_PROFILE(syscall_fsync);
1133         return result;
1134 #else
1135         return 0;
1136 #endif
1137 }
1138
1139 static int vfswrap_stat(vfs_handle_struct *handle,
1140                         struct smb_filename *smb_fname)
1141 {
1142         int result = -1;
1143
1144         START_PROFILE(syscall_stat);
1145
1146         if (smb_fname->stream_name) {
1147                 errno = ENOENT;
1148                 goto out;
1149         }
1150
1151         result = sys_stat(smb_fname->base_name, &smb_fname->st,
1152                           lp_fake_directory_create_times(SNUM(handle->conn)));
1153  out:
1154         END_PROFILE(syscall_stat);
1155         return result;
1156 }
1157
1158 static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1159 {
1160         int result;
1161
1162         START_PROFILE(syscall_fstat);
1163         result = sys_fstat(fsp->fh->fd,
1164                            sbuf, lp_fake_directory_create_times(SNUM(handle->conn)));
1165         END_PROFILE(syscall_fstat);
1166         return result;
1167 }
1168
1169 static int vfswrap_lstat(vfs_handle_struct *handle,
1170                          struct smb_filename *smb_fname)
1171 {
1172         int result = -1;
1173
1174         START_PROFILE(syscall_lstat);
1175
1176         if (smb_fname->stream_name) {
1177                 errno = ENOENT;
1178                 goto out;
1179         }
1180
1181         result = sys_lstat(smb_fname->base_name, &smb_fname->st,
1182                            lp_fake_directory_create_times(SNUM(handle->conn)));
1183  out:
1184         END_PROFILE(syscall_lstat);
1185         return result;
1186 }
1187
1188 static NTSTATUS vfswrap_translate_name(struct vfs_handle_struct *handle,
1189                                        const char *name,
1190                                        enum vfs_translate_direction direction,
1191                                        TALLOC_CTX *mem_ctx,
1192                                        char **mapped_name)
1193 {
1194         return NT_STATUS_NONE_MAPPED;
1195 }
1196
1197 /*
1198  * Implement the default fsctl operation.
1199  */
1200 static bool vfswrap_logged_ioctl_message = false;
1201
1202 static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
1203                               struct files_struct *fsp,
1204                               TALLOC_CTX *ctx,
1205                               uint32_t function,
1206                               uint16_t req_flags, /* Needed for UNICODE ... */
1207                               const uint8_t *_in_data,
1208                               uint32_t in_len,
1209                               uint8_t **_out_data,
1210                               uint32_t max_out_len,
1211                               uint32_t *out_len)
1212 {
1213         const char *in_data = (const char *)_in_data;
1214         char **out_data = (char **)_out_data;
1215         NTSTATUS status;
1216
1217         switch (function) {
1218         case FSCTL_SET_SPARSE:
1219         {
1220                 bool set_sparse = true;
1221
1222                 if (in_len >= 1 && in_data[0] == 0) {
1223                         set_sparse = false;
1224                 }
1225
1226                 status = file_set_sparse(handle->conn, fsp, set_sparse);
1227
1228                 DEBUG(NT_STATUS_IS_OK(status) ? 10 : 9,
1229                       ("FSCTL_SET_SPARSE: fname[%s] set[%u] - %s\n",
1230                        smb_fname_str_dbg(fsp->fsp_name), set_sparse,
1231                        nt_errstr(status)));
1232
1233                 return status;
1234         }
1235
1236         case FSCTL_CREATE_OR_GET_OBJECT_ID:
1237         {
1238                 unsigned char objid[16];
1239                 char *return_data = NULL;
1240
1241                 /* This should return the object-id on this file.
1242                  * I think I'll make this be the inode+dev. JRA.
1243                  */
1244
1245                 DEBUG(10,("FSCTL_CREATE_OR_GET_OBJECT_ID: called on %s\n",
1246                           fsp_fnum_dbg(fsp)));
1247
1248                 *out_len = MIN(max_out_len, 64);
1249
1250                 /* Hmmm, will this cause problems if less data asked for? */
1251                 return_data = talloc_array(ctx, char, 64);
1252                 if (return_data == NULL) {
1253                         return NT_STATUS_NO_MEMORY;
1254                 }
1255
1256                 /* For backwards compatibility only store the dev/inode. */
1257                 push_file_id_16(return_data, &fsp->file_id);
1258                 memcpy(return_data+16,create_volume_objectid(fsp->conn,objid),16);
1259                 push_file_id_16(return_data+32, &fsp->file_id);
1260                 memset(return_data+48, 0, 16);
1261                 *out_data = return_data;
1262                 return NT_STATUS_OK;
1263         }
1264
1265         case FSCTL_GET_REPARSE_POINT:
1266         {
1267                 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
1268                 DEBUG(10, ("FSCTL_GET_REPARSE_POINT: called on %s. "
1269                            "Status: NOT_IMPLEMENTED\n", fsp_fnum_dbg(fsp)));
1270                 return NT_STATUS_NOT_A_REPARSE_POINT;
1271         }
1272
1273         case FSCTL_SET_REPARSE_POINT:
1274         {
1275                 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
1276                 DEBUG(10, ("FSCTL_SET_REPARSE_POINT: called on %s. "
1277                            "Status: NOT_IMPLEMENTED\n", fsp_fnum_dbg(fsp)));
1278                 return NT_STATUS_NOT_A_REPARSE_POINT;
1279         }
1280
1281         case FSCTL_GET_SHADOW_COPY_DATA:
1282         {
1283                 /*
1284                  * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
1285                  * and return their volume names.  If max_data_count is 16, then it is just
1286                  * asking for the number of volumes and length of the combined names.
1287                  *
1288                  * pdata is the data allocated by our caller, but that uses
1289                  * total_data_count (which is 0 in our case) rather than max_data_count.
1290                  * Allocate the correct amount and return the pointer to let
1291                  * it be deallocated when we return.
1292                  */
1293                 struct shadow_copy_data *shadow_data = NULL;
1294                 bool labels = False;
1295                 uint32_t labels_data_count = 0;
1296                 uint32_t i;
1297                 char *cur_pdata = NULL;
1298
1299                 if (max_out_len < 16) {
1300                         DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
1301                                 max_out_len));
1302                         return NT_STATUS_INVALID_PARAMETER;
1303                 }
1304
1305                 if (max_out_len > 16) {
1306                         labels = True;
1307                 }
1308
1309                 shadow_data = talloc_zero(ctx, struct shadow_copy_data);
1310                 if (shadow_data == NULL) {
1311                         DEBUG(0,("TALLOC_ZERO() failed!\n"));
1312                         return NT_STATUS_NO_MEMORY;
1313                 }
1314
1315                 /*
1316                  * Call the VFS routine to actually do the work.
1317                  */
1318                 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
1319                         int log_lev = 0;
1320                         if (errno == 0) {
1321                                 /* broken module didn't set errno on error */
1322                                 status = NT_STATUS_UNSUCCESSFUL;
1323                         } else {
1324                                 status = map_nt_error_from_unix(errno);
1325                                 if (NT_STATUS_EQUAL(status,
1326                                                     NT_STATUS_NOT_SUPPORTED)) {
1327                                         log_lev = 5;
1328                                 }
1329                         }
1330                         DEBUG(log_lev, ("FSCTL_GET_SHADOW_COPY_DATA: "
1331                                         "connectpath %s, failed - %s.\n",
1332                                         fsp->conn->connectpath,
1333                                         nt_errstr(status)));
1334                         TALLOC_FREE(shadow_data);
1335                         return status;
1336                 }
1337
1338                 labels_data_count = (shadow_data->num_volumes * 2 *
1339                                         sizeof(SHADOW_COPY_LABEL)) + 2;
1340
1341                 if (!labels) {
1342                         *out_len = 16;
1343                 } else {
1344                         *out_len = 12 + labels_data_count;
1345                 }
1346
1347                 if (max_out_len < *out_len) {
1348                         DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
1349                                 max_out_len, *out_len));
1350                         TALLOC_FREE(shadow_data);
1351                         return NT_STATUS_BUFFER_TOO_SMALL;
1352                 }
1353
1354                 cur_pdata = talloc_zero_array(ctx, char, *out_len);
1355                 if (cur_pdata == NULL) {
1356                         TALLOC_FREE(shadow_data);
1357                         return NT_STATUS_NO_MEMORY;
1358                 }
1359
1360                 *out_data = cur_pdata;
1361
1362                 /* num_volumes 4 bytes */
1363                 SIVAL(cur_pdata, 0, shadow_data->num_volumes);
1364
1365                 if (labels) {
1366                         /* num_labels 4 bytes */
1367                         SIVAL(cur_pdata, 4, shadow_data->num_volumes);
1368                 }
1369
1370                 /* needed_data_count 4 bytes */
1371                 SIVAL(cur_pdata, 8, labels_data_count);
1372
1373                 cur_pdata += 12;
1374
1375                 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
1376                           shadow_data->num_volumes, fsp_str_dbg(fsp)));
1377                 if (labels && shadow_data->labels) {
1378                         for (i=0; i<shadow_data->num_volumes; i++) {
1379                                 size_t len = 0;
1380                                 status = srvstr_push(cur_pdata, req_flags,
1381                                             cur_pdata, shadow_data->labels[i],
1382                                             2 * sizeof(SHADOW_COPY_LABEL),
1383                                             STR_UNICODE|STR_TERMINATE, &len);
1384                                 if (!NT_STATUS_IS_OK(status)) {
1385                                         TALLOC_FREE(*out_data);
1386                                         TALLOC_FREE(shadow_data);
1387                                         return status;
1388                                 }
1389                                 cur_pdata += 2 * sizeof(SHADOW_COPY_LABEL);
1390                                 DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
1391                         }
1392                 }
1393
1394                 TALLOC_FREE(shadow_data);
1395
1396                 return NT_STATUS_OK;
1397         }
1398
1399         case FSCTL_FIND_FILES_BY_SID:
1400         {
1401                 /* pretend this succeeded -
1402                  *
1403                  * we have to send back a list with all files owned by this SID
1404                  *
1405                  * but I have to check that --metze
1406                  */
1407                 struct dom_sid sid;
1408                 uid_t uid;
1409                 size_t sid_len;
1410
1411                 DEBUG(10, ("FSCTL_FIND_FILES_BY_SID: called on %s\n",
1412                            fsp_fnum_dbg(fsp)));
1413
1414                 if (in_len < 8) {
1415                         /* NT_STATUS_BUFFER_TOO_SMALL maybe? */
1416                         return NT_STATUS_INVALID_PARAMETER;
1417                 }
1418
1419                 sid_len = MIN(in_len - 4,SID_MAX_SIZE);
1420
1421                 /* unknown 4 bytes: this is not the length of the sid :-(  */
1422                 /*unknown = IVAL(pdata,0);*/
1423
1424                 if (!sid_parse(_in_data + 4, sid_len, &sid)) {
1425                         return NT_STATUS_INVALID_PARAMETER;
1426                 }
1427                 DEBUGADD(10, ("for SID: %s\n", sid_string_dbg(&sid)));
1428
1429                 if (!sid_to_uid(&sid, &uid)) {
1430                         DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
1431                                  sid_string_dbg(&sid),
1432                                  (unsigned long)sid_len));
1433                         uid = (-1);
1434                 }
1435
1436                 /* we can take a look at the find source :-)
1437                  *
1438                  * find ./ -uid $uid  -name '*'   is what we need here
1439                  *
1440                  *
1441                  * and send 4bytes len and then NULL terminated unicode strings
1442                  * for each file
1443                  *
1444                  * but I don't know how to deal with the paged results
1445                  * (maybe we can hang the result anywhere in the fsp struct)
1446                  *
1447                  * but I don't know how to deal with the paged results
1448                  * (maybe we can hang the result anywhere in the fsp struct)
1449                  *
1450                  * we don't send all files at once
1451                  * and at the next we should *not* start from the beginning,
1452                  * so we have to cache the result
1453                  *
1454                  * --metze
1455                  */
1456
1457                 /* this works for now... */
1458                 return NT_STATUS_OK;
1459         }
1460
1461         case FSCTL_QUERY_ALLOCATED_RANGES:
1462         {
1463                 /* FIXME: This is just a dummy reply, telling that all of the
1464                  * file is allocated. MKS cp needs that.
1465                  * Adding the real allocated ranges via FIEMAP on Linux
1466                  * and SEEK_DATA/SEEK_HOLE on Solaris is needed to make
1467                  * this FSCTL correct for sparse files.
1468                  */
1469                 uint64_t offset, length;
1470                 char *out_data_tmp = NULL;
1471
1472                 if (in_len != 16) {
1473                         DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: data_count(%u) != 16 is invalid!\n",
1474                                 in_len));
1475                         return NT_STATUS_INVALID_PARAMETER;
1476                 }
1477
1478                 if (max_out_len < 16) {
1479                         DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: max_out_len (%u) < 16 is invalid!\n",
1480                                 max_out_len));
1481                         return NT_STATUS_INVALID_PARAMETER;
1482                 }
1483
1484                 offset = BVAL(in_data,0);
1485                 length = BVAL(in_data,8);
1486
1487                 if (offset + length < offset) {
1488                         /* No 64-bit integer wrap. */
1489                         return NT_STATUS_INVALID_PARAMETER;
1490                 }
1491
1492                 /* Shouldn't this be SMB_VFS_STAT ... ? */
1493                 status = vfs_stat_fsp(fsp);
1494                 if (!NT_STATUS_IS_OK(status)) {
1495                         return status;
1496                 }
1497
1498                 *out_len = 16;
1499                 out_data_tmp = talloc_array(ctx, char, *out_len);
1500                 if (out_data_tmp == NULL) {
1501                         DEBUG(10, ("unable to allocate memory for response\n"));
1502                         return NT_STATUS_NO_MEMORY;
1503                 }
1504
1505                 if (offset > fsp->fsp_name->st.st_ex_size ||
1506                                 fsp->fsp_name->st.st_ex_size == 0 ||
1507                                 length == 0) {
1508                         memset(out_data_tmp, 0, *out_len);
1509                 } else {
1510                         uint64_t end = offset + length;
1511                         end = MIN(end, fsp->fsp_name->st.st_ex_size);
1512                         SBVAL(out_data_tmp, 0, 0);
1513                         SBVAL(out_data_tmp, 8, end);
1514                 }
1515
1516                 *out_data = out_data_tmp;
1517
1518                 return NT_STATUS_OK;
1519         }
1520
1521         case FSCTL_IS_VOLUME_DIRTY:
1522         {
1523                 DEBUG(10,("FSCTL_IS_VOLUME_DIRTY: called on %s "
1524                           "(but remotely not supported)\n", fsp_fnum_dbg(fsp)));
1525                 /*
1526                  * http://msdn.microsoft.com/en-us/library/cc232128%28PROT.10%29.aspx
1527                  * says we have to respond with NT_STATUS_INVALID_PARAMETER
1528                  */
1529                 return NT_STATUS_INVALID_PARAMETER;
1530         }
1531
1532         default:
1533                 /*
1534                  * Only print once ... unfortunately there could be lots of
1535                  * different FSCTLs that are called.
1536                  */
1537                 if (!vfswrap_logged_ioctl_message) {
1538                         vfswrap_logged_ioctl_message = true;
1539                         DEBUG(2, ("%s (0x%x): Currently not implemented.\n",
1540                         __func__, function));
1541                 }
1542         }
1543
1544         return NT_STATUS_NOT_SUPPORTED;
1545 }
1546
1547 static bool vfswrap_is_offline(struct vfs_handle_struct *handle,
1548                                const struct smb_filename *fname,
1549                                SMB_STRUCT_STAT *sbuf);
1550
1551 static NTSTATUS vfswrap_get_dos_attributes(struct vfs_handle_struct *handle,
1552                                            struct smb_filename *smb_fname,
1553                                            uint32_t *dosmode)
1554 {
1555         bool offline;
1556
1557         offline = vfswrap_is_offline(handle, smb_fname, &smb_fname->st);
1558         if (offline) {
1559                 *dosmode |= FILE_ATTRIBUTE_OFFLINE;
1560         }
1561
1562         return get_ea_dos_attribute(handle->conn, smb_fname, dosmode);
1563 }
1564
1565 static NTSTATUS vfswrap_fget_dos_attributes(struct vfs_handle_struct *handle,
1566                                             struct files_struct *fsp,
1567                                             uint32_t *dosmode)
1568 {
1569         bool offline;
1570
1571         offline = vfswrap_is_offline(handle, fsp->fsp_name, &fsp->fsp_name->st);
1572         if (offline) {
1573                 *dosmode |= FILE_ATTRIBUTE_OFFLINE;
1574         }
1575
1576         return get_ea_dos_attribute(handle->conn, fsp->fsp_name, dosmode);
1577 }
1578
1579 static NTSTATUS vfswrap_set_dos_attributes(struct vfs_handle_struct *handle,
1580                                            const struct smb_filename *smb_fname,
1581                                            uint32_t dosmode)
1582 {
1583         return set_ea_dos_attribute(handle->conn, smb_fname, dosmode);
1584 }
1585
1586 static NTSTATUS vfswrap_fset_dos_attributes(struct vfs_handle_struct *handle,
1587                                             struct files_struct *fsp,
1588                                             uint32_t dosmode)
1589 {
1590         return set_ea_dos_attribute(handle->conn, fsp->fsp_name, dosmode);
1591 }
1592
1593 struct vfs_cc_state {
1594         off_t copied;
1595         uint8_t *buf;
1596 };
1597
1598 static struct tevent_req *vfswrap_copy_chunk_send(struct vfs_handle_struct *handle,
1599                                                   TALLOC_CTX *mem_ctx,
1600                                                   struct tevent_context *ev,
1601                                                   struct files_struct *src_fsp,
1602                                                   off_t src_off,
1603                                                   struct files_struct *dest_fsp,
1604                                                   off_t dest_off,
1605                                                   off_t num)
1606 {
1607         struct tevent_req *req;
1608         struct vfs_cc_state *vfs_cc_state;
1609         NTSTATUS status;
1610
1611         DEBUG(10, ("performing server side copy chunk of length %lu\n",
1612                    (unsigned long)num));
1613
1614         req = tevent_req_create(mem_ctx, &vfs_cc_state, struct vfs_cc_state);
1615         if (req == NULL) {
1616                 return NULL;
1617         }
1618
1619         vfs_cc_state->buf = talloc_array(vfs_cc_state, uint8_t,
1620                                          MIN(num, 8*1024*1024));
1621         if (tevent_req_nomem(vfs_cc_state->buf, req)) {
1622                 return tevent_req_post(req, ev);
1623         }
1624
1625         status = vfs_stat_fsp(src_fsp);
1626         if (tevent_req_nterror(req, status)) {
1627                 return tevent_req_post(req, ev);
1628         }
1629
1630         if (src_fsp->fsp_name->st.st_ex_size < src_off + num) {
1631                 /*
1632                  * [MS-SMB2] 3.3.5.15.6 Handling a Server-Side Data Copy Request
1633                  *   If the SourceOffset or SourceOffset + Length extends beyond
1634                  *   the end of file, the server SHOULD<240> treat this as a
1635                  *   STATUS_END_OF_FILE error.
1636                  * ...
1637                  *   <240> Section 3.3.5.15.6: Windows servers will return
1638                  *   STATUS_INVALID_VIEW_SIZE instead of STATUS_END_OF_FILE.
1639                  */
1640                 tevent_req_nterror(req, NT_STATUS_INVALID_VIEW_SIZE);
1641                 return tevent_req_post(req, ev);
1642         }
1643
1644         /* could use 2.6.33+ sendfile here to do this in kernel */
1645         while (vfs_cc_state->copied < num) {
1646                 ssize_t ret;
1647                 struct lock_struct lck;
1648                 int saved_errno;
1649
1650                 off_t this_num = MIN(talloc_array_length(vfs_cc_state->buf),
1651                                      num - vfs_cc_state->copied);
1652
1653                 if (src_fsp->op == NULL) {
1654                         tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1655                         return tevent_req_post(req, ev);
1656                 }
1657                 init_strict_lock_struct(src_fsp,
1658                                         src_fsp->op->global->open_persistent_id,
1659                                         src_off,
1660                                         this_num,
1661                                         READ_LOCK,
1662                                         &lck);
1663
1664                 if (!SMB_VFS_STRICT_LOCK(src_fsp->conn, src_fsp, &lck)) {
1665                         tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
1666                         return tevent_req_post(req, ev);
1667                 }
1668
1669                 ret = SMB_VFS_PREAD(src_fsp, vfs_cc_state->buf,
1670                                     this_num, src_off);
1671                 if (ret == -1) {
1672                         saved_errno = errno;
1673                 }
1674
1675                 SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &lck);
1676
1677                 if (ret == -1) {
1678                         errno = saved_errno;
1679                         tevent_req_nterror(req, map_nt_error_from_unix(errno));
1680                         return tevent_req_post(req, ev);
1681                 }
1682                 if (ret != this_num) {
1683                         /* zero tolerance for short reads */
1684                         tevent_req_nterror(req, NT_STATUS_IO_DEVICE_ERROR);
1685                         return tevent_req_post(req, ev);
1686                 }
1687
1688                 src_off += ret;
1689
1690                 if (dest_fsp->op == NULL) {
1691                         tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1692                         return tevent_req_post(req, ev);
1693                 }
1694
1695                 init_strict_lock_struct(dest_fsp,
1696                                         dest_fsp->op->global->open_persistent_id,
1697                                         dest_off,
1698                                         this_num,
1699                                         WRITE_LOCK,
1700                                         &lck);
1701
1702                 if (!SMB_VFS_STRICT_LOCK(dest_fsp->conn, dest_fsp, &lck)) {
1703                         tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
1704                         return tevent_req_post(req, ev);
1705                 }
1706
1707                 ret = SMB_VFS_PWRITE(dest_fsp, vfs_cc_state->buf,
1708                                      this_num, dest_off);
1709                 if (ret == -1) {
1710                         saved_errno = errno;
1711                 }
1712
1713                 SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &lck);
1714
1715                 if (ret == -1) {
1716                         errno = saved_errno;
1717                         tevent_req_nterror(req, map_nt_error_from_unix(errno));
1718                         return tevent_req_post(req, ev);
1719                 }
1720                 if (ret != this_num) {
1721                         /* zero tolerance for short writes */
1722                         tevent_req_nterror(req, NT_STATUS_IO_DEVICE_ERROR);
1723                         return tevent_req_post(req, ev);
1724                 }
1725                 dest_off += ret;
1726
1727                 vfs_cc_state->copied += this_num;
1728         }
1729
1730         tevent_req_done(req);
1731         return tevent_req_post(req, ev);
1732 }
1733
1734 static NTSTATUS vfswrap_copy_chunk_recv(struct vfs_handle_struct *handle,
1735                                         struct tevent_req *req,
1736                                         off_t *copied)
1737 {
1738         struct vfs_cc_state *vfs_cc_state = tevent_req_data(req,
1739                                                         struct vfs_cc_state);
1740         NTSTATUS status;
1741
1742         if (tevent_req_is_nterror(req, &status)) {
1743                 DEBUG(2, ("server side copy chunk failed: %s\n",
1744                           nt_errstr(status)));
1745                 *copied = 0;
1746                 tevent_req_received(req);
1747                 return status;
1748         }
1749
1750         *copied = vfs_cc_state->copied;
1751         DEBUG(10, ("server side copy chunk copied %lu\n",
1752                    (unsigned long)*copied));
1753         tevent_req_received(req);
1754
1755         return NT_STATUS_OK;
1756 }
1757
1758 static NTSTATUS vfswrap_get_compression(struct vfs_handle_struct *handle,
1759                                         TALLOC_CTX *mem_ctx,
1760                                         struct files_struct *fsp,
1761                                         struct smb_filename *smb_fname,
1762                                         uint16_t *_compression_fmt)
1763 {
1764         return NT_STATUS_INVALID_DEVICE_REQUEST;
1765 }
1766
1767 static NTSTATUS vfswrap_set_compression(struct vfs_handle_struct *handle,
1768                                         TALLOC_CTX *mem_ctx,
1769                                         struct files_struct *fsp,
1770                                         uint16_t compression_fmt)
1771 {
1772         return NT_STATUS_INVALID_DEVICE_REQUEST;
1773 }
1774
1775 /********************************************************************
1776  Given a stat buffer return the allocated size on disk, taking into
1777  account sparse files.
1778 ********************************************************************/
1779 static uint64_t vfswrap_get_alloc_size(vfs_handle_struct *handle,
1780                                        struct files_struct *fsp,
1781                                        const SMB_STRUCT_STAT *sbuf)
1782 {
1783         uint64_t result;
1784
1785         START_PROFILE(syscall_get_alloc_size);
1786
1787         if(S_ISDIR(sbuf->st_ex_mode)) {
1788                 result = 0;
1789                 goto out;
1790         }
1791
1792 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
1793         /* The type of st_blocksize is blkcnt_t which *MUST* be
1794            signed (according to POSIX) and can be less than 64-bits.
1795            Ensure when we're converting to 64 bits wide we don't
1796            sign extend. */
1797 #if defined(SIZEOF_BLKCNT_T_8)
1798         result = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_ex_blocks;
1799 #elif defined(SIZEOF_BLKCNT_T_4)
1800         {
1801                 uint64_t bs = ((uint64_t)sbuf->st_ex_blocks) & 0xFFFFFFFFLL;
1802                 result = (uint64_t)STAT_ST_BLOCKSIZE * bs;
1803         }
1804 #else
1805 #error SIZEOF_BLKCNT_T_NOT_A_SUPPORTED_VALUE
1806 #endif
1807         if (result == 0) {
1808                 /*
1809                  * Some file systems do not allocate a block for very
1810                  * small files. But for non-empty file should report a
1811                  * positive size.
1812                  */
1813
1814                 uint64_t filesize = get_file_size_stat(sbuf);
1815                 if (filesize > 0) {
1816                         result = MIN((uint64_t)STAT_ST_BLOCKSIZE, filesize);
1817                 }
1818         }
1819 #else
1820         result = get_file_size_stat(sbuf);
1821 #endif
1822
1823         if (fsp && fsp->initial_allocation_size)
1824                 result = MAX(result,fsp->initial_allocation_size);
1825
1826         result = smb_roundup(handle->conn, result);
1827
1828  out:
1829         END_PROFILE(syscall_get_alloc_size);
1830         return result;
1831 }
1832
1833 static int vfswrap_unlink(vfs_handle_struct *handle,
1834                           const struct smb_filename *smb_fname)
1835 {
1836         int result = -1;
1837
1838         START_PROFILE(syscall_unlink);
1839
1840         if (smb_fname->stream_name) {
1841                 errno = ENOENT;
1842                 goto out;
1843         }
1844         result = unlink(smb_fname->base_name);
1845
1846  out:
1847         END_PROFILE(syscall_unlink);
1848         return result;
1849 }
1850
1851 static int vfswrap_chmod(vfs_handle_struct *handle,
1852                         const struct smb_filename *smb_fname,
1853                         mode_t mode)
1854 {
1855         int result;
1856
1857         START_PROFILE(syscall_chmod);
1858
1859         /*
1860          * We need to do this due to the fact that the default POSIX ACL
1861          * chmod modifies the ACL *mask* for the group owner, not the
1862          * group owner bits directly. JRA.
1863          */
1864
1865
1866         {
1867                 int saved_errno = errno; /* We might get ENOSYS */
1868                 result = SMB_VFS_CHMOD_ACL(handle->conn,
1869                                 smb_fname,
1870                                 mode);
1871                 if (result == 0) {
1872                         END_PROFILE(syscall_chmod);
1873                         return result;
1874                 }
1875                 /* Error - return the old errno. */
1876                 errno = saved_errno;
1877         }
1878
1879         result = chmod(smb_fname->base_name, mode);
1880         END_PROFILE(syscall_chmod);
1881         return result;
1882 }
1883
1884 static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
1885 {
1886         int result;
1887
1888         START_PROFILE(syscall_fchmod);
1889
1890         /*
1891          * We need to do this due to the fact that the default POSIX ACL
1892          * chmod modifies the ACL *mask* for the group owner, not the
1893          * group owner bits directly. JRA.
1894          */
1895
1896         {
1897                 int saved_errno = errno; /* We might get ENOSYS */
1898                 if ((result = SMB_VFS_FCHMOD_ACL(fsp, mode)) == 0) {
1899                         END_PROFILE(syscall_fchmod);
1900                         return result;
1901                 }
1902                 /* Error - return the old errno. */
1903                 errno = saved_errno;
1904         }
1905
1906 #if defined(HAVE_FCHMOD)
1907         result = fchmod(fsp->fh->fd, mode);
1908 #else
1909         result = -1;
1910         errno = ENOSYS;
1911 #endif
1912
1913         END_PROFILE(syscall_fchmod);
1914         return result;
1915 }
1916
1917 static int vfswrap_chown(vfs_handle_struct *handle,
1918                         const struct smb_filename *smb_fname,
1919                         uid_t uid,
1920                         gid_t gid)
1921 {
1922         int result;
1923
1924         START_PROFILE(syscall_chown);
1925         result = chown(smb_fname->base_name, uid, gid);
1926         END_PROFILE(syscall_chown);
1927         return result;
1928 }
1929
1930 static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid)
1931 {
1932 #ifdef HAVE_FCHOWN
1933         int result;
1934
1935         START_PROFILE(syscall_fchown);
1936         result = fchown(fsp->fh->fd, uid, gid);
1937         END_PROFILE(syscall_fchown);
1938         return result;
1939 #else
1940         errno = ENOSYS;
1941         return -1;
1942 #endif
1943 }
1944
1945 static int vfswrap_lchown(vfs_handle_struct *handle,
1946                         const struct smb_filename *smb_fname,
1947                         uid_t uid,
1948                         gid_t gid)
1949 {
1950         int result;
1951
1952         START_PROFILE(syscall_lchown);
1953         result = lchown(smb_fname->base_name, uid, gid);
1954         END_PROFILE(syscall_lchown);
1955         return result;
1956 }
1957
1958 static int vfswrap_chdir(vfs_handle_struct *handle, const char *path)
1959 {
1960         int result;
1961
1962         START_PROFILE(syscall_chdir);
1963         result = chdir(path);
1964         END_PROFILE(syscall_chdir);
1965         return result;
1966 }
1967
1968 static char *vfswrap_getwd(vfs_handle_struct *handle)
1969 {
1970         char *result;
1971
1972         START_PROFILE(syscall_getwd);
1973         result = sys_getwd();
1974         END_PROFILE(syscall_getwd);
1975         return result;
1976 }
1977
1978 /*********************************************************************
1979  nsec timestamp resolution call. Convert down to whatever the underlying
1980  system will support.
1981 **********************************************************************/
1982
1983 static int vfswrap_ntimes(vfs_handle_struct *handle,
1984                           const struct smb_filename *smb_fname,
1985                           struct smb_file_time *ft)
1986 {
1987         int result = -1;
1988
1989         START_PROFILE(syscall_ntimes);
1990
1991         if (smb_fname->stream_name) {
1992                 errno = ENOENT;
1993                 goto out;
1994         }
1995
1996         if (ft != NULL) {
1997                 if (null_timespec(ft->atime)) {
1998                         ft->atime= smb_fname->st.st_ex_atime;
1999                 }
2000
2001                 if (null_timespec(ft->mtime)) {
2002                         ft->mtime = smb_fname->st.st_ex_mtime;
2003                 }
2004
2005                 if (!null_timespec(ft->create_time)) {
2006                         set_create_timespec_ea(handle->conn,
2007                                                smb_fname,
2008                                                ft->create_time);
2009                 }
2010
2011                 if ((timespec_compare(&ft->atime,
2012                                       &smb_fname->st.st_ex_atime) == 0) &&
2013                     (timespec_compare(&ft->mtime,
2014                                       &smb_fname->st.st_ex_mtime) == 0)) {
2015                         return 0;
2016                 }
2017         }
2018
2019 #if defined(HAVE_UTIMENSAT)
2020         if (ft != NULL) {
2021                 struct timespec ts[2];
2022                 ts[0] = ft->atime;
2023                 ts[1] = ft->mtime;
2024                 result = utimensat(AT_FDCWD, smb_fname->base_name, ts, 0);
2025         } else {
2026                 result = utimensat(AT_FDCWD, smb_fname->base_name, NULL, 0);
2027         }
2028         if (!((result == -1) && (errno == ENOSYS))) {
2029                 goto out;
2030         }
2031 #endif
2032 #if defined(HAVE_UTIMES)
2033         if (ft != NULL) {
2034                 struct timeval tv[2];
2035                 tv[0] = convert_timespec_to_timeval(ft->atime);
2036                 tv[1] = convert_timespec_to_timeval(ft->mtime);
2037                 result = utimes(smb_fname->base_name, tv);
2038         } else {
2039                 result = utimes(smb_fname->base_name, NULL);
2040         }
2041         if (!((result == -1) && (errno == ENOSYS))) {
2042                 goto out;
2043         }
2044 #endif
2045 #if defined(HAVE_UTIME)
2046         if (ft != NULL) {
2047                 struct utimbuf times;
2048                 times.actime = convert_timespec_to_time_t(ft->atime);
2049                 times.modtime = convert_timespec_to_time_t(ft->mtime);
2050                 result = utime(smb_fname->base_name, &times);
2051         } else {
2052                 result = utime(smb_fname->base_name, NULL);
2053         }
2054         if (!((result == -1) && (errno == ENOSYS))) {
2055                 goto out;
2056         }
2057 #endif
2058         errno = ENOSYS;
2059         result = -1;
2060
2061  out:
2062         END_PROFILE(syscall_ntimes);
2063         return result;
2064 }
2065
2066 /*********************************************************************
2067  A version of ftruncate that will write the space on disk if strict
2068  allocate is set.
2069 **********************************************************************/
2070
2071 static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, off_t len)
2072 {
2073         off_t space_to_write;
2074         uint64_t space_avail;
2075         uint64_t bsize,dfree,dsize;
2076         int ret;
2077         NTSTATUS status;
2078         SMB_STRUCT_STAT *pst;
2079
2080         status = vfs_stat_fsp(fsp);
2081         if (!NT_STATUS_IS_OK(status)) {
2082                 return -1;
2083         }
2084         pst = &fsp->fsp_name->st;
2085
2086 #ifdef S_ISFIFO
2087         if (S_ISFIFO(pst->st_ex_mode))
2088                 return 0;
2089 #endif
2090
2091         if (pst->st_ex_size == len)
2092                 return 0;
2093
2094         /* Shrink - just ftruncate. */
2095         if (pst->st_ex_size > len)
2096                 return ftruncate(fsp->fh->fd, len);
2097
2098         space_to_write = len - pst->st_ex_size;
2099
2100         /* for allocation try fallocate first. This can fail on some
2101            platforms e.g. when the filesystem doesn't support it and no
2102            emulation is being done by the libc (like on AIX with JFS1). In that
2103            case we do our own emulation. fallocate implementations can
2104            return ENOTSUP or EINVAL in cases like that. */
2105         ret = SMB_VFS_FALLOCATE(fsp, 0, pst->st_ex_size, space_to_write);
2106         if (ret == -1 && errno == ENOSPC) {
2107                 return -1;
2108         }
2109         if (ret == 0) {
2110                 return 0;
2111         }
2112         DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
2113                 "error %d. Falling back to slow manual allocation\n", errno));
2114
2115         /* available disk space is enough or not? */
2116         space_avail =
2117             get_dfree_info(fsp->conn, fsp->fsp_name, &bsize, &dfree, &dsize);
2118         /* space_avail is 1k blocks */
2119         if (space_avail == (uint64_t)-1 ||
2120                         ((uint64_t)space_to_write/1024 > space_avail) ) {
2121                 errno = ENOSPC;
2122                 return -1;
2123         }
2124
2125         /* Write out the real space on disk. */
2126         ret = vfs_slow_fallocate(fsp, pst->st_ex_size, space_to_write);
2127         if (ret != 0) {
2128                 return -1;
2129         }
2130
2131         return 0;
2132 }
2133
2134 static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, off_t len)
2135 {
2136         int result = -1;
2137         SMB_STRUCT_STAT *pst;
2138         NTSTATUS status;
2139         char c = 0;
2140
2141         START_PROFILE(syscall_ftruncate);
2142
2143         if (lp_strict_allocate(SNUM(fsp->conn)) && !fsp->is_sparse) {
2144                 result = strict_allocate_ftruncate(handle, fsp, len);
2145                 END_PROFILE(syscall_ftruncate);
2146                 return result;
2147         }
2148
2149         /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
2150            ftruncate if the system supports it. Then I discovered that
2151            you can have some filesystems that support ftruncate
2152            expansion and some that don't! On Linux fat can't do
2153            ftruncate extend but ext2 can. */
2154
2155         result = ftruncate(fsp->fh->fd, len);
2156
2157         /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2158            extend a file with ftruncate. Provide alternate implementation
2159            for this */
2160
2161         /* Do an fstat to see if the file is longer than the requested
2162            size in which case the ftruncate above should have
2163            succeeded or shorter, in which case seek to len - 1 and
2164            write 1 byte of zero */
2165         status = vfs_stat_fsp(fsp);
2166         if (!NT_STATUS_IS_OK(status)) {
2167                 goto done;
2168         }
2169
2170         /* We need to update the files_struct after successful ftruncate */
2171         if (result == 0) {
2172                 goto done;
2173         }
2174
2175         pst = &fsp->fsp_name->st;
2176
2177 #ifdef S_ISFIFO
2178         if (S_ISFIFO(pst->st_ex_mode)) {
2179                 result = 0;
2180                 goto done;
2181         }
2182 #endif
2183
2184         if (pst->st_ex_size == len) {
2185                 result = 0;
2186                 goto done;
2187         }
2188
2189         if (pst->st_ex_size > len) {
2190                 /* the ftruncate should have worked */
2191                 goto done;
2192         }
2193
2194         if (SMB_VFS_PWRITE(fsp, &c, 1, len-1)!=1) {
2195                 goto done;
2196         }
2197
2198         result = 0;
2199
2200   done:
2201
2202         END_PROFILE(syscall_ftruncate);
2203         return result;
2204 }
2205
2206 static int vfswrap_fallocate(vfs_handle_struct *handle,
2207                         files_struct *fsp,
2208                         uint32_t mode,
2209                         off_t offset,
2210                         off_t len)
2211 {
2212         int result;
2213
2214         START_PROFILE(syscall_fallocate);
2215         if (mode == 0) {
2216                 result = sys_posix_fallocate(fsp->fh->fd, offset, len);
2217                 /*
2218                  * posix_fallocate returns 0 on success, errno on error
2219                  * and doesn't set errno. Make it behave like fallocate()
2220                  * which returns -1, and sets errno on failure.
2221                  */
2222                 if (result != 0) {
2223                         errno = result;
2224                         result = -1;
2225                 }
2226         } else {
2227                 /* sys_fallocate handles filtering of unsupported mode flags */
2228                 result = sys_fallocate(fsp->fh->fd, mode, offset, len);
2229         }
2230         END_PROFILE(syscall_fallocate);
2231         return result;
2232 }
2233
2234 static bool vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int op, off_t offset, off_t count, int type)
2235 {
2236         bool result;
2237
2238         START_PROFILE(syscall_fcntl_lock);
2239
2240         if (fsp->use_ofd_locks || !lp_parm_bool(SNUM(fsp->conn),
2241                                                 "smbd",
2242                                                 "force process locks",
2243                                                 false)) {
2244                 op = map_process_lock_to_ofd_lock(op, &fsp->use_ofd_locks);
2245         }
2246
2247         result =  fcntl_lock(fsp->fh->fd, op, offset, count, type);
2248         END_PROFILE(syscall_fcntl_lock);
2249         return result;
2250 }
2251
2252 static int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
2253                                 uint32_t share_mode, uint32_t access_mask)
2254 {
2255         START_PROFILE(syscall_kernel_flock);
2256         kernel_flock(fsp->fh->fd, share_mode, access_mask);
2257         END_PROFILE(syscall_kernel_flock);
2258         return 0;
2259 }
2260
2261 static bool vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid)
2262 {
2263         bool result;
2264         int op = F_GETLK;
2265
2266         START_PROFILE(syscall_fcntl_getlock);
2267
2268         if (fsp->use_ofd_locks || !lp_parm_bool(SNUM(fsp->conn),
2269                                                 "smbd",
2270                                                 "force process locks",
2271                                                 false)) {
2272                 op = map_process_lock_to_ofd_lock(op, &fsp->use_ofd_locks);
2273         }
2274
2275         result = fcntl_getlock(fsp->fh->fd, op, poffset, pcount, ptype, ppid);
2276         END_PROFILE(syscall_fcntl_getlock);
2277         return result;
2278 }
2279
2280 static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp,
2281                                 int leasetype)
2282 {
2283         int result = -1;
2284
2285         START_PROFILE(syscall_linux_setlease);
2286
2287 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
2288         result = linux_setlease(fsp->fh->fd, leasetype);
2289 #else
2290         errno = ENOSYS;
2291 #endif
2292         END_PROFILE(syscall_linux_setlease);
2293         return result;
2294 }
2295
2296 static int vfswrap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
2297 {
2298         int result;
2299
2300         START_PROFILE(syscall_symlink);
2301         result = symlink(oldpath, newpath);
2302         END_PROFILE(syscall_symlink);
2303         return result;
2304 }
2305
2306 static int vfswrap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
2307 {
2308         int result;
2309
2310         START_PROFILE(syscall_readlink);
2311         result = readlink(path, buf, bufsiz);
2312         END_PROFILE(syscall_readlink);
2313         return result;
2314 }
2315
2316 static int vfswrap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
2317 {
2318         int result;
2319
2320         START_PROFILE(syscall_link);
2321         result = link(oldpath, newpath);
2322         END_PROFILE(syscall_link);
2323         return result;
2324 }
2325
2326 static int vfswrap_mknod(vfs_handle_struct *handle, const char *pathname, mode_t mode, SMB_DEV_T dev)
2327 {
2328         int result;
2329
2330         START_PROFILE(syscall_mknod);
2331         result = sys_mknod(pathname, mode, dev);
2332         END_PROFILE(syscall_mknod);
2333         return result;
2334 }
2335
2336 static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path)
2337 {
2338         char *result;
2339
2340         START_PROFILE(syscall_realpath);
2341         result = sys_realpath(path);
2342         END_PROFILE(syscall_realpath);
2343         return result;
2344 }
2345
2346 static int vfswrap_chflags(vfs_handle_struct *handle, const char *path,
2347                            unsigned int flags)
2348 {
2349 #ifdef HAVE_CHFLAGS
2350         return chflags(path, flags);
2351 #else
2352         errno = ENOSYS;
2353         return -1;
2354 #endif
2355 }
2356
2357 static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
2358                                              const SMB_STRUCT_STAT *sbuf)
2359 {
2360         struct file_id key;
2361
2362         /* the ZERO_STRUCT ensures padding doesn't break using the key as a
2363          * blob */
2364         ZERO_STRUCT(key);
2365
2366         key.devid = sbuf->st_ex_dev;
2367         key.inode = sbuf->st_ex_ino;
2368         /* key.extid is unused by default. */
2369
2370         return key;
2371 }
2372
2373 static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
2374                                    struct files_struct *fsp,
2375                                    const struct smb_filename *smb_fname,
2376                                    TALLOC_CTX *mem_ctx,
2377                                    unsigned int *pnum_streams,
2378                                    struct stream_struct **pstreams)
2379 {
2380         SMB_STRUCT_STAT sbuf;
2381         struct stream_struct *tmp_streams = NULL;
2382         int ret;
2383
2384         if ((fsp != NULL) && (fsp->is_directory)) {
2385                 /*
2386                  * No default streams on directories
2387                  */
2388                 goto done;
2389         }
2390
2391         if ((fsp != NULL) && (fsp->fh->fd != -1)) {
2392                 ret = SMB_VFS_FSTAT(fsp, &sbuf);
2393         }
2394         else {
2395                 struct smb_filename smb_fname_cp;
2396
2397                 ZERO_STRUCT(smb_fname_cp);
2398                 smb_fname_cp.base_name = discard_const_p(char,
2399                                         smb_fname->base_name);
2400                 smb_fname_cp.flags = smb_fname->flags;
2401
2402                 if (smb_fname_cp.flags & SMB_FILENAME_POSIX_PATH) {
2403                         ret = SMB_VFS_LSTAT(handle->conn, &smb_fname_cp);
2404                 } else {
2405                         ret = SMB_VFS_STAT(handle->conn, &smb_fname_cp);
2406                 }
2407                 sbuf = smb_fname_cp.st;
2408         }
2409
2410         if (ret == -1) {
2411                 return map_nt_error_from_unix(errno);
2412         }
2413
2414         if (S_ISDIR(sbuf.st_ex_mode)) {
2415                 goto done;
2416         }
2417
2418         tmp_streams = talloc_realloc(mem_ctx, *pstreams, struct stream_struct,
2419                                         (*pnum_streams) + 1);
2420         if (tmp_streams == NULL) {
2421                 return NT_STATUS_NO_MEMORY;
2422         }
2423         tmp_streams[*pnum_streams].name = talloc_strdup(tmp_streams, "::$DATA");
2424         if (tmp_streams[*pnum_streams].name == NULL) {
2425                 return NT_STATUS_NO_MEMORY;
2426         }
2427         tmp_streams[*pnum_streams].size = sbuf.st_ex_size;
2428         tmp_streams[*pnum_streams].alloc_size = SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, &sbuf);
2429
2430         *pnum_streams += 1;
2431         *pstreams = tmp_streams;
2432  done:
2433         return NT_STATUS_OK;
2434 }
2435
2436 static int vfswrap_get_real_filename(struct vfs_handle_struct *handle,
2437                                      const char *path,
2438                                      const char *name,
2439                                      TALLOC_CTX *mem_ctx,
2440                                      char **found_name)
2441 {
2442         /*
2443          * Don't fall back to get_real_filename so callers can differentiate
2444          * between a full directory scan and an actual case-insensitive stat.
2445          */
2446         errno = EOPNOTSUPP;
2447         return -1;
2448 }
2449
2450 static const char *vfswrap_connectpath(struct vfs_handle_struct *handle,
2451                                        const char *fname)
2452 {
2453         return handle->conn->connectpath;
2454 }
2455
2456 static NTSTATUS vfswrap_brl_lock_windows(struct vfs_handle_struct *handle,
2457                                          struct byte_range_lock *br_lck,
2458                                          struct lock_struct *plock,
2459                                          bool blocking_lock)
2460 {
2461         SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
2462
2463         /* Note: blr is not used in the default implementation. */
2464         return brl_lock_windows_default(br_lck, plock, blocking_lock);
2465 }
2466
2467 static bool vfswrap_brl_unlock_windows(struct vfs_handle_struct *handle,
2468                                        struct messaging_context *msg_ctx,
2469                                        struct byte_range_lock *br_lck,
2470                                        const struct lock_struct *plock)
2471 {
2472         SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
2473
2474         return brl_unlock_windows_default(msg_ctx, br_lck, plock);
2475 }
2476
2477 static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct *handle,
2478                                        struct byte_range_lock *br_lck,
2479                                        struct lock_struct *plock)
2480 {
2481         SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
2482
2483         /* Note: blr is not used in the default implementation. */
2484         return brl_lock_cancel_default(br_lck, plock);
2485 }
2486
2487 static bool vfswrap_strict_lock(struct vfs_handle_struct *handle,
2488                                 files_struct *fsp,
2489                                 struct lock_struct *plock)
2490 {
2491         SMB_ASSERT(plock->lock_type == READ_LOCK ||
2492             plock->lock_type == WRITE_LOCK);
2493
2494         return strict_lock_default(fsp, plock);
2495 }
2496
2497 static void vfswrap_strict_unlock(struct vfs_handle_struct *handle,
2498                                 files_struct *fsp,
2499                                 struct lock_struct *plock)
2500 {
2501         SMB_ASSERT(plock->lock_type == READ_LOCK ||
2502             plock->lock_type == WRITE_LOCK);
2503
2504         strict_unlock_default(fsp, plock);
2505 }
2506
2507 /* NT ACL operations. */
2508
2509 static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
2510                                     files_struct *fsp,
2511                                     uint32_t security_info,
2512                                     TALLOC_CTX *mem_ctx,
2513                                     struct security_descriptor **ppdesc)
2514 {
2515         NTSTATUS result;
2516
2517         START_PROFILE(fget_nt_acl);
2518         result = posix_fget_nt_acl(fsp, security_info,
2519                                    mem_ctx, ppdesc);
2520         END_PROFILE(fget_nt_acl);
2521         return result;
2522 }
2523
2524 static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle,
2525                                    const struct smb_filename *smb_fname,
2526                                    uint32_t security_info,
2527                                    TALLOC_CTX *mem_ctx,
2528                                    struct security_descriptor **ppdesc)
2529 {
2530         NTSTATUS result;
2531
2532         START_PROFILE(get_nt_acl);
2533         result = posix_get_nt_acl(handle->conn,
2534                                 smb_fname,
2535                                 security_info,
2536                                 mem_ctx,
2537                                 ppdesc);
2538         END_PROFILE(get_nt_acl);
2539         return result;
2540 }
2541
2542 static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32_t security_info_sent, const struct security_descriptor *psd)
2543 {
2544         NTSTATUS result;
2545
2546         START_PROFILE(fset_nt_acl);
2547         result = set_nt_acl(fsp, security_info_sent, psd);
2548         END_PROFILE(fset_nt_acl);
2549         return result;
2550 }
2551
2552 static NTSTATUS vfswrap_audit_file(struct vfs_handle_struct *handle,
2553                                    struct smb_filename *file,
2554                                    struct security_acl *sacl,
2555                                    uint32_t access_requested,
2556                                    uint32_t access_denied)
2557 {
2558         return NT_STATUS_OK; /* Nothing to do here ... */
2559 }
2560
2561 static int vfswrap_chmod_acl(vfs_handle_struct *handle,
2562                                 const struct smb_filename *smb_fname,
2563                                 mode_t mode)
2564 {
2565 #ifdef HAVE_NO_ACL
2566         errno = ENOSYS;
2567         return -1;
2568 #else
2569         int result;
2570
2571         START_PROFILE(chmod_acl);
2572         result = chmod_acl(handle->conn, smb_fname->base_name, mode);
2573         END_PROFILE(chmod_acl);
2574         return result;
2575 #endif
2576 }
2577
2578 static int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
2579 {
2580 #ifdef HAVE_NO_ACL
2581         errno = ENOSYS;
2582         return -1;
2583 #else
2584         int result;
2585
2586         START_PROFILE(fchmod_acl);
2587         result = fchmod_acl(fsp, mode);
2588         END_PROFILE(fchmod_acl);
2589         return result;
2590 #endif
2591 }
2592
2593 static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle,
2594                                           const char *path_p,
2595                                           SMB_ACL_TYPE_T type,
2596                                           TALLOC_CTX *mem_ctx)
2597 {
2598         return sys_acl_get_file(handle, path_p, type, mem_ctx);
2599 }
2600
2601 static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle,
2602                                         files_struct *fsp,
2603                                         TALLOC_CTX *mem_ctx)
2604 {
2605         return sys_acl_get_fd(handle, fsp, mem_ctx);
2606 }
2607
2608 static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
2609 {
2610         return sys_acl_set_file(handle, name, acltype, theacl);
2611 }
2612
2613 static int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl)
2614 {
2615         return sys_acl_set_fd(handle, fsp, theacl);
2616 }
2617
2618 static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path)
2619 {
2620         return sys_acl_delete_def_file(handle, path);
2621 }
2622
2623 /****************************************************************
2624  Extended attribute operations.
2625 *****************************************************************/
2626
2627 static ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
2628 {
2629         return getxattr(path, name, value, size);
2630 }
2631
2632 static ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size)
2633 {
2634         return fgetxattr(fsp->fh->fd, name, value, size);
2635 }
2636
2637 static ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
2638 {
2639         return listxattr(path, list, size);
2640 }
2641
2642 static ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)
2643 {
2644         return flistxattr(fsp->fh->fd, list, size);
2645 }
2646
2647 static int vfswrap_removexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
2648 {
2649         return removexattr(path, name);
2650 }
2651
2652 static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name)
2653 {
2654         return fremovexattr(fsp->fh->fd, name);
2655 }
2656
2657 static int vfswrap_setxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
2658 {
2659         return setxattr(path, name, value, size, flags);
2660 }
2661
2662 static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags)
2663 {
2664         return fsetxattr(fsp->fh->fd, name, value, size, flags);
2665 }
2666
2667 static bool vfswrap_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp)
2668 {
2669         return false;
2670 }
2671
2672 static bool vfswrap_is_offline(struct vfs_handle_struct *handle,
2673                                const struct smb_filename *fname,
2674                                SMB_STRUCT_STAT *sbuf)
2675 {
2676         NTSTATUS status;
2677         char *path;
2678         bool offline = false;
2679
2680         if (ISDOT(fname->base_name) || ISDOTDOT(fname->base_name)) {
2681                 return false;
2682         }
2683
2684         if (!lp_dmapi_support(SNUM(handle->conn)) || !dmapi_have_session()) {
2685 #if defined(ENOTSUP)
2686                 errno = ENOTSUP;
2687 #endif
2688                 return false;
2689         }
2690
2691         status = get_full_smb_filename(talloc_tos(), fname, &path);
2692         if (!NT_STATUS_IS_OK(status)) {
2693                 errno = map_errno_from_nt_status(status);
2694                 return false;
2695         }
2696
2697         offline = (dmapi_file_flags(path) & FILE_ATTRIBUTE_OFFLINE) != 0;
2698
2699         TALLOC_FREE(path);
2700
2701         return offline;
2702 }
2703
2704 static NTSTATUS vfswrap_durable_cookie(struct vfs_handle_struct *handle,
2705                                        struct files_struct *fsp,
2706                                        TALLOC_CTX *mem_ctx,
2707                                        DATA_BLOB *cookie)
2708 {
2709         return vfs_default_durable_cookie(fsp, mem_ctx, cookie);
2710 }
2711
2712 static NTSTATUS vfswrap_durable_disconnect(struct vfs_handle_struct *handle,
2713                                            struct files_struct *fsp,
2714                                            const DATA_BLOB old_cookie,
2715                                            TALLOC_CTX *mem_ctx,
2716                                            DATA_BLOB *new_cookie)
2717 {
2718         return vfs_default_durable_disconnect(fsp, old_cookie, mem_ctx,
2719                                               new_cookie);
2720 }
2721
2722 static NTSTATUS vfswrap_durable_reconnect(struct vfs_handle_struct *handle,
2723                                           struct smb_request *smb1req,
2724                                           struct smbXsrv_open *op,
2725                                           const DATA_BLOB old_cookie,
2726                                           TALLOC_CTX *mem_ctx,
2727                                           struct files_struct **fsp,
2728                                           DATA_BLOB *new_cookie)
2729 {
2730         return vfs_default_durable_reconnect(handle->conn, smb1req, op,
2731                                              old_cookie, mem_ctx,
2732                                              fsp, new_cookie);
2733 }
2734
2735 static struct vfs_fn_pointers vfs_default_fns = {
2736         /* Disk operations */
2737
2738         .connect_fn = vfswrap_connect,
2739         .disconnect_fn = vfswrap_disconnect,
2740         .disk_free_fn = vfswrap_disk_free,
2741         .get_quota_fn = vfswrap_get_quota,
2742         .set_quota_fn = vfswrap_set_quota,
2743         .get_shadow_copy_data_fn = vfswrap_get_shadow_copy_data,
2744         .statvfs_fn = vfswrap_statvfs,
2745         .fs_capabilities_fn = vfswrap_fs_capabilities,
2746         .get_dfs_referrals_fn = vfswrap_get_dfs_referrals,
2747         .snap_check_path_fn = vfswrap_snap_check_path,
2748         .snap_create_fn = vfswrap_snap_create,
2749         .snap_delete_fn = vfswrap_snap_delete,
2750
2751         /* Directory operations */
2752
2753         .opendir_fn = vfswrap_opendir,
2754         .fdopendir_fn = vfswrap_fdopendir,
2755         .readdir_fn = vfswrap_readdir,
2756         .readdir_attr_fn = vfswrap_readdir_attr,
2757         .seekdir_fn = vfswrap_seekdir,
2758         .telldir_fn = vfswrap_telldir,
2759         .rewind_dir_fn = vfswrap_rewinddir,
2760         .mkdir_fn = vfswrap_mkdir,
2761         .rmdir_fn = vfswrap_rmdir,
2762         .closedir_fn = vfswrap_closedir,
2763         .init_search_op_fn = vfswrap_init_search_op,
2764
2765         /* File operations */
2766
2767         .open_fn = vfswrap_open,
2768         .create_file_fn = vfswrap_create_file,
2769         .close_fn = vfswrap_close,
2770         .read_fn = vfswrap_read,
2771         .pread_fn = vfswrap_pread,
2772         .pread_send_fn = vfswrap_pread_send,
2773         .pread_recv_fn = vfswrap_pread_recv,
2774         .write_fn = vfswrap_write,
2775         .pwrite_fn = vfswrap_pwrite,
2776         .pwrite_send_fn = vfswrap_pwrite_send,
2777         .pwrite_recv_fn = vfswrap_pwrite_recv,
2778         .lseek_fn = vfswrap_lseek,
2779         .sendfile_fn = vfswrap_sendfile,
2780         .recvfile_fn = vfswrap_recvfile,
2781         .rename_fn = vfswrap_rename,
2782         .fsync_fn = vfswrap_fsync,
2783         .fsync_send_fn = vfswrap_fsync_send,
2784         .fsync_recv_fn = vfswrap_fsync_recv,
2785         .stat_fn = vfswrap_stat,
2786         .fstat_fn = vfswrap_fstat,
2787         .lstat_fn = vfswrap_lstat,
2788         .get_alloc_size_fn = vfswrap_get_alloc_size,
2789         .unlink_fn = vfswrap_unlink,
2790         .chmod_fn = vfswrap_chmod,
2791         .fchmod_fn = vfswrap_fchmod,
2792         .chown_fn = vfswrap_chown,
2793         .fchown_fn = vfswrap_fchown,
2794         .lchown_fn = vfswrap_lchown,
2795         .chdir_fn = vfswrap_chdir,
2796         .getwd_fn = vfswrap_getwd,
2797         .ntimes_fn = vfswrap_ntimes,
2798         .ftruncate_fn = vfswrap_ftruncate,
2799         .fallocate_fn = vfswrap_fallocate,
2800         .lock_fn = vfswrap_lock,
2801         .kernel_flock_fn = vfswrap_kernel_flock,
2802         .linux_setlease_fn = vfswrap_linux_setlease,
2803         .getlock_fn = vfswrap_getlock,
2804         .symlink_fn = vfswrap_symlink,
2805         .readlink_fn = vfswrap_readlink,
2806         .link_fn = vfswrap_link,
2807         .mknod_fn = vfswrap_mknod,
2808         .realpath_fn = vfswrap_realpath,
2809         .chflags_fn = vfswrap_chflags,
2810         .file_id_create_fn = vfswrap_file_id_create,
2811         .streaminfo_fn = vfswrap_streaminfo,
2812         .get_real_filename_fn = vfswrap_get_real_filename,
2813         .connectpath_fn = vfswrap_connectpath,
2814         .brl_lock_windows_fn = vfswrap_brl_lock_windows,
2815         .brl_unlock_windows_fn = vfswrap_brl_unlock_windows,
2816         .brl_cancel_windows_fn = vfswrap_brl_cancel_windows,
2817         .strict_lock_fn = vfswrap_strict_lock,
2818         .strict_unlock_fn = vfswrap_strict_unlock,
2819         .translate_name_fn = vfswrap_translate_name,
2820         .fsctl_fn = vfswrap_fsctl,
2821         .set_dos_attributes_fn = vfswrap_set_dos_attributes,
2822         .fset_dos_attributes_fn = vfswrap_fset_dos_attributes,
2823         .get_dos_attributes_fn = vfswrap_get_dos_attributes,
2824         .fget_dos_attributes_fn = vfswrap_fget_dos_attributes,
2825         .copy_chunk_send_fn = vfswrap_copy_chunk_send,
2826         .copy_chunk_recv_fn = vfswrap_copy_chunk_recv,
2827         .get_compression_fn = vfswrap_get_compression,
2828         .set_compression_fn = vfswrap_set_compression,
2829
2830         /* NT ACL operations. */
2831
2832         .fget_nt_acl_fn = vfswrap_fget_nt_acl,
2833         .get_nt_acl_fn = vfswrap_get_nt_acl,
2834         .fset_nt_acl_fn = vfswrap_fset_nt_acl,
2835         .audit_file_fn = vfswrap_audit_file,
2836
2837         /* POSIX ACL operations. */
2838
2839         .chmod_acl_fn = vfswrap_chmod_acl,
2840         .fchmod_acl_fn = vfswrap_fchmod_acl,
2841
2842         .sys_acl_get_file_fn = vfswrap_sys_acl_get_file,
2843         .sys_acl_get_fd_fn = vfswrap_sys_acl_get_fd,
2844         .sys_acl_blob_get_file_fn = posix_sys_acl_blob_get_file,
2845         .sys_acl_blob_get_fd_fn = posix_sys_acl_blob_get_fd,
2846         .sys_acl_set_file_fn = vfswrap_sys_acl_set_file,
2847         .sys_acl_set_fd_fn = vfswrap_sys_acl_set_fd,
2848         .sys_acl_delete_def_file_fn = vfswrap_sys_acl_delete_def_file,
2849
2850         /* EA operations. */
2851         .getxattr_fn = vfswrap_getxattr,
2852         .fgetxattr_fn = vfswrap_fgetxattr,
2853         .listxattr_fn = vfswrap_listxattr,
2854         .flistxattr_fn = vfswrap_flistxattr,
2855         .removexattr_fn = vfswrap_removexattr,
2856         .fremovexattr_fn = vfswrap_fremovexattr,
2857         .setxattr_fn = vfswrap_setxattr,
2858         .fsetxattr_fn = vfswrap_fsetxattr,
2859
2860         /* aio operations */
2861         .aio_force_fn = vfswrap_aio_force,
2862
2863         /* durable handle operations */
2864         .durable_cookie_fn = vfswrap_durable_cookie,
2865         .durable_disconnect_fn = vfswrap_durable_disconnect,
2866         .durable_reconnect_fn = vfswrap_durable_reconnect,
2867 };
2868
2869 NTSTATUS vfs_default_init(void);
2870 NTSTATUS vfs_default_init(void)
2871 {
2872         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
2873                                 DEFAULT_VFS_MODULE_NAME, &vfs_default_fns);
2874 }
2875
2876