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