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