s3-includes: only include system/filesys.h when needed.
[kai/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/filesys.h"
23
24 #undef DBGC_CLASS
25 #define DBGC_CLASS DBGC_VFS
26
27 /* Check for NULL pointer parameters in vfswrap_* functions */
28
29 /* We don't want to have NULL function pointers lying around.  Someone
30    is sure to try and execute them.  These stubs are used to prevent
31    this possibility. */
32
33 static int vfswrap_connect(vfs_handle_struct *handle,  const char *service, const char *user)
34 {
35     return 0;    /* Return >= 0 for success */
36 }
37
38 static void vfswrap_disconnect(vfs_handle_struct *handle)
39 {
40 }
41
42 /* Disk operations */
43
44 static uint64_t vfswrap_disk_free(vfs_handle_struct *handle,  const char *path, bool small_query, uint64_t *bsize,
45                                uint64_t *dfree, uint64_t *dsize)
46 {
47         uint64_t result;
48
49         result = sys_disk_free(handle->conn, path, small_query, bsize, dfree, dsize);
50         return result;
51 }
52
53 static int vfswrap_get_quota(struct vfs_handle_struct *handle,  enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
54 {
55 #ifdef HAVE_SYS_QUOTAS
56         int result;
57
58         START_PROFILE(syscall_get_quota);
59         result = sys_get_quota(handle->conn->connectpath, qtype, id, qt);
60         END_PROFILE(syscall_get_quota);
61         return result;
62 #else
63         errno = ENOSYS;
64         return -1;
65 #endif
66 }
67
68 static int vfswrap_set_quota(struct vfs_handle_struct *handle,  enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
69 {
70 #ifdef HAVE_SYS_QUOTAS
71         int result;
72
73         START_PROFILE(syscall_set_quota);
74         result = sys_set_quota(handle->conn->connectpath, qtype, id, qt);
75         END_PROFILE(syscall_set_quota);
76         return result;
77 #else
78         errno = ENOSYS;
79         return -1;
80 #endif
81 }
82
83 static int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, bool labels)
84 {
85         errno = ENOSYS;
86         return -1;  /* Not implemented. */
87 }
88
89 static int vfswrap_statvfs(struct vfs_handle_struct *handle,  const char *path, vfs_statvfs_struct *statbuf)
90 {
91         return sys_statvfs(path, statbuf);
92 }
93
94 static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle,
95                 enum timestamp_set_resolution *p_ts_res)
96 {
97         connection_struct *conn = handle->conn;
98         uint32_t caps = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
99         struct smb_filename *smb_fname_cpath = NULL;
100         NTSTATUS status;
101         int ret = -1;
102
103 #if defined(DARWINOS)
104         struct vfs_statvfs_struct statbuf;
105         ZERO_STRUCT(statbuf);
106         sys_statvfs(conn->connectpath, &statbuf);
107         caps = statbuf.FsCapabilities;
108 #endif
109
110         *p_ts_res = TIMESTAMP_SET_SECONDS;
111
112         /* Work out what timestamp resolution we can
113          * use when setting a timestamp. */
114
115         status = create_synthetic_smb_fname(talloc_tos(),
116                                 conn->connectpath,
117                                 NULL,
118                                 NULL,
119                                 &smb_fname_cpath);
120         if (!NT_STATUS_IS_OK(status)) {
121                 return caps;
122         }
123
124         ret = SMB_VFS_STAT(conn, smb_fname_cpath);
125         if (ret == -1) {
126                 TALLOC_FREE(smb_fname_cpath);
127                 return caps;
128         }
129
130         if (smb_fname_cpath->st.st_ex_mtime.tv_nsec ||
131                         smb_fname_cpath->st.st_ex_atime.tv_nsec ||
132                         smb_fname_cpath->st.st_ex_ctime.tv_nsec) {
133                 /* If any of the normal UNIX directory timestamps
134                  * have a non-zero tv_nsec component assume
135                  * we might be able to set sub-second timestamps.
136                  * See what filetime set primitives we have.
137                  */
138 #if defined(HAVE_UTIMENSAT)
139                 *p_ts_res = TIMESTAMP_SET_NT_OR_BETTER;
140 #elif defined(HAVE_UTIMES)
141                 /* utimes allows msec timestamps to be set. */
142                 *p_ts_res = TIMESTAMP_SET_MSEC;
143 #elif defined(HAVE_UTIME)
144                 /* utime only allows sec timestamps to be set. */
145                 *p_ts_res = TIMESTAMP_SET_SECONDS;
146 #endif
147
148                 DEBUG(10,("vfswrap_fs_capabilities: timestamp "
149                         "resolution of %s "
150                         "available on share %s, directory %s\n",
151                         *p_ts_res == TIMESTAMP_SET_MSEC ? "msec" : "sec",
152                         lp_servicename(conn->params->service),
153                         conn->connectpath ));
154         }
155         TALLOC_FREE(smb_fname_cpath);
156         return caps;
157 }
158
159 /* Directory operations */
160
161 static SMB_STRUCT_DIR *vfswrap_opendir(vfs_handle_struct *handle,  const char *fname, const char *mask, uint32 attr)
162 {
163         SMB_STRUCT_DIR *result;
164
165         START_PROFILE(syscall_opendir);
166         result = sys_opendir(fname);
167         END_PROFILE(syscall_opendir);
168         return result;
169 }
170
171 static SMB_STRUCT_DIR *vfswrap_fdopendir(vfs_handle_struct *handle,
172                         files_struct *fsp,
173                         const char *mask,
174                         uint32 attr)
175 {
176         SMB_STRUCT_DIR *result;
177
178         START_PROFILE(syscall_fdopendir);
179         result = sys_fdopendir(fsp->fh->fd);
180         END_PROFILE(syscall_fdopendir);
181         return result;
182 }
183
184
185 static SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle,
186                                           SMB_STRUCT_DIR *dirp,
187                                           SMB_STRUCT_STAT *sbuf)
188 {
189         SMB_STRUCT_DIRENT *result;
190
191         START_PROFILE(syscall_readdir);
192         result = sys_readdir(dirp);
193         /* Default Posix readdir() does not give us stat info.
194          * Set to invalid to indicate we didn't return this info. */
195         if (sbuf)
196                 SET_STAT_INVALID(*sbuf);
197         END_PROFILE(syscall_readdir);
198         return result;
199 }
200
201 static void vfswrap_seekdir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp, long offset)
202 {
203         START_PROFILE(syscall_seekdir);
204         sys_seekdir(dirp, offset);
205         END_PROFILE(syscall_seekdir);
206 }
207
208 static long vfswrap_telldir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp)
209 {
210         long result;
211         START_PROFILE(syscall_telldir);
212         result = sys_telldir(dirp);
213         END_PROFILE(syscall_telldir);
214         return result;
215 }
216
217 static void vfswrap_rewinddir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp)
218 {
219         START_PROFILE(syscall_rewinddir);
220         sys_rewinddir(dirp);
221         END_PROFILE(syscall_rewinddir);
222 }
223
224 static int vfswrap_mkdir(vfs_handle_struct *handle,  const char *path, mode_t mode)
225 {
226         int result;
227         bool has_dacl = False;
228         char *parent = NULL;
229
230         START_PROFILE(syscall_mkdir);
231
232         if (lp_inherit_acls(SNUM(handle->conn))
233             && parent_dirname(talloc_tos(), path, &parent, NULL)
234             && (has_dacl = directory_has_default_acl(handle->conn, parent)))
235                 mode = (0777 & lp_dir_mask(SNUM(handle->conn)));
236
237         TALLOC_FREE(parent);
238
239         result = mkdir(path, mode);
240
241         if (result == 0 && !has_dacl) {
242                 /*
243                  * We need to do this as the default behavior of POSIX ACLs
244                  * is to set the mask to be the requested group permission
245                  * bits, not the group permission bits to be the requested
246                  * group permission bits. This is not what we want, as it will
247                  * mess up any inherited ACL bits that were set. JRA.
248                  */
249                 int saved_errno = errno; /* We may get ENOSYS */
250                 if ((SMB_VFS_CHMOD_ACL(handle->conn, path, mode) == -1) && (errno == ENOSYS))
251                         errno = saved_errno;
252         }
253
254         END_PROFILE(syscall_mkdir);
255         return result;
256 }
257
258 static int vfswrap_rmdir(vfs_handle_struct *handle,  const char *path)
259 {
260         int result;
261
262         START_PROFILE(syscall_rmdir);
263         result = rmdir(path);
264         END_PROFILE(syscall_rmdir);
265         return result;
266 }
267
268 static int vfswrap_closedir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp)
269 {
270         int result;
271
272         START_PROFILE(syscall_closedir);
273         result = sys_closedir(dirp);
274         END_PROFILE(syscall_closedir);
275         return result;
276 }
277
278 static void vfswrap_init_search_op(vfs_handle_struct *handle,
279                                    SMB_STRUCT_DIR *dirp)
280 {
281         /* Default behavior is a NOOP */
282 }
283
284 /* File operations */
285
286 static int vfswrap_open(vfs_handle_struct *handle,
287                         struct smb_filename *smb_fname,
288                         files_struct *fsp, int flags, mode_t mode)
289 {
290         int result = -1;
291
292         START_PROFILE(syscall_open);
293
294         if (smb_fname->stream_name) {
295                 errno = ENOENT;
296                 goto out;
297         }
298
299         result = sys_open(smb_fname->base_name, flags, mode);
300  out:
301         END_PROFILE(syscall_open);
302         return result;
303 }
304
305 static NTSTATUS vfswrap_create_file(vfs_handle_struct *handle,
306                                     struct smb_request *req,
307                                     uint16_t root_dir_fid,
308                                     struct smb_filename *smb_fname,
309                                     uint32_t access_mask,
310                                     uint32_t share_access,
311                                     uint32_t create_disposition,
312                                     uint32_t create_options,
313                                     uint32_t file_attributes,
314                                     uint32_t oplock_request,
315                                     uint64_t allocation_size,
316                                     uint32_t private_flags,
317                                     struct security_descriptor *sd,
318                                     struct ea_list *ea_list,
319                                     files_struct **result,
320                                     int *pinfo)
321 {
322         return create_file_default(handle->conn, req, root_dir_fid, smb_fname,
323                                    access_mask, share_access,
324                                    create_disposition, create_options,
325                                    file_attributes, oplock_request,
326                                    allocation_size, private_flags,
327                                    sd, ea_list, result,
328                                    pinfo);
329 }
330
331 static int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp)
332 {
333         int result;
334
335         START_PROFILE(syscall_close);
336         result = fd_close_posix(fsp);
337         END_PROFILE(syscall_close);
338         return result;
339 }
340
341 static ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n)
342 {
343         ssize_t result;
344
345         START_PROFILE_BYTES(syscall_read, n);
346         result = sys_read(fsp->fh->fd, data, n);
347         END_PROFILE(syscall_read);
348         return result;
349 }
350
351 static ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, void *data,
352                         size_t n, SMB_OFF_T offset)
353 {
354         ssize_t result;
355
356 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
357         START_PROFILE_BYTES(syscall_pread, n);
358         result = sys_pread(fsp->fh->fd, data, n, offset);
359         END_PROFILE(syscall_pread);
360
361         if (result == -1 && errno == ESPIPE) {
362                 /* Maintain the fiction that pipes can be seeked (sought?) on. */
363                 result = SMB_VFS_READ(fsp, data, n);
364                 fsp->fh->pos = 0;
365         }
366
367 #else /* HAVE_PREAD */
368         SMB_OFF_T   curr;
369         int lerrno;
370
371         curr = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
372         if (curr == -1 && errno == ESPIPE) {
373                 /* Maintain the fiction that pipes can be seeked (sought?) on. */
374                 result = SMB_VFS_READ(fsp, data, n);
375                 fsp->fh->pos = 0;
376                 return result;
377         }
378
379         if (SMB_VFS_LSEEK(fsp, offset, SEEK_SET) == -1) {
380                 return -1;
381         }
382
383         errno = 0;
384         result = SMB_VFS_READ(fsp, data, n);
385         lerrno = errno;
386
387         SMB_VFS_LSEEK(fsp, curr, SEEK_SET);
388         errno = lerrno;
389
390 #endif /* HAVE_PREAD */
391
392         return result;
393 }
394
395 static ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n)
396 {
397         ssize_t result;
398
399         START_PROFILE_BYTES(syscall_write, n);
400         result = sys_write(fsp->fh->fd, data, n);
401         END_PROFILE(syscall_write);
402         return result;
403 }
404
405 static ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, const void *data,
406                         size_t n, SMB_OFF_T offset)
407 {
408         ssize_t result;
409
410 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
411         START_PROFILE_BYTES(syscall_pwrite, n);
412         result = sys_pwrite(fsp->fh->fd, data, n, offset);
413         END_PROFILE(syscall_pwrite);
414
415         if (result == -1 && errno == ESPIPE) {
416                 /* Maintain the fiction that pipes can be sought on. */
417                 result = SMB_VFS_WRITE(fsp, data, n);
418         }
419
420 #else /* HAVE_PWRITE */
421         SMB_OFF_T   curr;
422         int         lerrno;
423
424         curr = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
425         if (curr == -1) {
426                 return -1;
427         }
428
429         if (SMB_VFS_LSEEK(fsp, offset, SEEK_SET) == -1) {
430                 return -1;
431         }
432
433         result = SMB_VFS_WRITE(fsp, data, n);
434         lerrno = errno;
435
436         SMB_VFS_LSEEK(fsp, curr, SEEK_SET);
437         errno = lerrno;
438
439 #endif /* HAVE_PWRITE */
440
441         return result;
442 }
443
444 static SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T offset, int whence)
445 {
446         SMB_OFF_T result = 0;
447
448         START_PROFILE(syscall_lseek);
449
450         /* Cope with 'stat' file opens. */
451         if (fsp->fh->fd != -1)
452                 result = sys_lseek(fsp->fh->fd, offset, whence);
453
454         /*
455          * We want to maintain the fiction that we can seek
456          * on a fifo for file system purposes. This allows
457          * people to set up UNIX fifo's that feed data to Windows
458          * applications. JRA.
459          */
460
461         if((result == -1) && (errno == ESPIPE)) {
462                 result = 0;
463                 errno = 0;
464         }
465
466         END_PROFILE(syscall_lseek);
467         return result;
468 }
469
470 static ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fromfsp, const DATA_BLOB *hdr,
471                         SMB_OFF_T offset, size_t n)
472 {
473         ssize_t result;
474
475         START_PROFILE_BYTES(syscall_sendfile, n);
476         result = sys_sendfile(tofd, fromfsp->fh->fd, hdr, offset, n);
477         END_PROFILE(syscall_sendfile);
478         return result;
479 }
480
481 static ssize_t vfswrap_recvfile(vfs_handle_struct *handle,
482                         int fromfd,
483                         files_struct *tofsp,
484                         SMB_OFF_T offset,
485                         size_t n)
486 {
487         ssize_t result;
488
489         START_PROFILE_BYTES(syscall_recvfile, n);
490         result = sys_recvfile(fromfd, tofsp->fh->fd, offset, n);
491         END_PROFILE(syscall_recvfile);
492         return result;
493 }
494
495 static int vfswrap_rename(vfs_handle_struct *handle,
496                           const struct smb_filename *smb_fname_src,
497                           const struct smb_filename *smb_fname_dst)
498 {
499         int result = -1;
500
501         START_PROFILE(syscall_rename);
502
503         if (smb_fname_src->stream_name || smb_fname_dst->stream_name) {
504                 errno = ENOENT;
505                 goto out;
506         }
507
508         result = rename(smb_fname_src->base_name, smb_fname_dst->base_name);
509
510  out:
511         END_PROFILE(syscall_rename);
512         return result;
513 }
514
515 static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp)
516 {
517 #ifdef HAVE_FSYNC
518         int result;
519
520         START_PROFILE(syscall_fsync);
521         result = fsync(fsp->fh->fd);
522         END_PROFILE(syscall_fsync);
523         return result;
524 #else
525         return 0;
526 #endif
527 }
528
529 static int vfswrap_stat(vfs_handle_struct *handle,
530                         struct smb_filename *smb_fname)
531 {
532         int result = -1;
533
534         START_PROFILE(syscall_stat);
535
536         if (smb_fname->stream_name) {
537                 errno = ENOENT;
538                 goto out;
539         }
540
541         result = sys_stat(smb_fname->base_name, &smb_fname->st,
542                           lp_fake_dir_create_times(SNUM(handle->conn)));
543  out:
544         END_PROFILE(syscall_stat);
545         return result;
546 }
547
548 static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
549 {
550         int result;
551
552         START_PROFILE(syscall_fstat);
553         result = sys_fstat(fsp->fh->fd,
554                            sbuf, lp_fake_dir_create_times(SNUM(handle->conn)));
555         END_PROFILE(syscall_fstat);
556         return result;
557 }
558
559 static int vfswrap_lstat(vfs_handle_struct *handle,
560                          struct smb_filename *smb_fname)
561 {
562         int result = -1;
563
564         START_PROFILE(syscall_lstat);
565
566         if (smb_fname->stream_name) {
567                 errno = ENOENT;
568                 goto out;
569         }
570
571         result = sys_lstat(smb_fname->base_name, &smb_fname->st,
572                            lp_fake_dir_create_times(SNUM(handle->conn)));
573  out:
574         END_PROFILE(syscall_lstat);
575         return result;
576 }
577
578 static NTSTATUS vfswrap_translate_name(struct vfs_handle_struct *handle,
579                                        const char *name,
580                                        enum vfs_translate_direction direction,
581                                        TALLOC_CTX *mem_ctx,
582                                        char **mapped_name)
583 {
584         return NT_STATUS_NONE_MAPPED;
585 }
586
587 /********************************************************************
588  Given a stat buffer return the allocated size on disk, taking into
589  account sparse files.
590 ********************************************************************/
591 static uint64_t vfswrap_get_alloc_size(vfs_handle_struct *handle,
592                                        struct files_struct *fsp,
593                                        const SMB_STRUCT_STAT *sbuf)
594 {
595         uint64_t result;
596
597         START_PROFILE(syscall_get_alloc_size);
598
599         if(S_ISDIR(sbuf->st_ex_mode)) {
600                 result = 0;
601                 goto out;
602         }
603
604 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
605         result = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_ex_blocks;
606 #else
607         result = get_file_size_stat(sbuf);
608 #endif
609
610         if (fsp && fsp->initial_allocation_size)
611                 result = MAX(result,fsp->initial_allocation_size);
612
613         result = smb_roundup(handle->conn, result);
614
615  out:
616         END_PROFILE(syscall_get_alloc_size);
617         return result;
618 }
619
620 static int vfswrap_unlink(vfs_handle_struct *handle,
621                           const struct smb_filename *smb_fname)
622 {
623         int result = -1;
624
625         START_PROFILE(syscall_unlink);
626
627         if (smb_fname->stream_name) {
628                 errno = ENOENT;
629                 goto out;
630         }
631         result = unlink(smb_fname->base_name);
632
633  out:
634         END_PROFILE(syscall_unlink);
635         return result;
636 }
637
638 static int vfswrap_chmod(vfs_handle_struct *handle,  const char *path, mode_t mode)
639 {
640         int result;
641
642         START_PROFILE(syscall_chmod);
643
644         /*
645          * We need to do this due to the fact that the default POSIX ACL
646          * chmod modifies the ACL *mask* for the group owner, not the
647          * group owner bits directly. JRA.
648          */
649
650
651         {
652                 int saved_errno = errno; /* We might get ENOSYS */
653                 if ((result = SMB_VFS_CHMOD_ACL(handle->conn, path, mode)) == 0) {
654                         END_PROFILE(syscall_chmod);
655                         return result;
656                 }
657                 /* Error - return the old errno. */
658                 errno = saved_errno;
659         }
660
661         result = chmod(path, mode);
662         END_PROFILE(syscall_chmod);
663         return result;
664 }
665
666 static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
667 {
668         int result;
669
670         START_PROFILE(syscall_fchmod);
671
672         /*
673          * We need to do this due to the fact that the default POSIX ACL
674          * chmod modifies the ACL *mask* for the group owner, not the
675          * group owner bits directly. JRA.
676          */
677
678         {
679                 int saved_errno = errno; /* We might get ENOSYS */
680                 if ((result = SMB_VFS_FCHMOD_ACL(fsp, mode)) == 0) {
681                         END_PROFILE(syscall_fchmod);
682                         return result;
683                 }
684                 /* Error - return the old errno. */
685                 errno = saved_errno;
686         }
687
688 #if defined(HAVE_FCHMOD)
689         result = fchmod(fsp->fh->fd, mode);
690 #else
691         result = -1;
692         errno = ENOSYS;
693 #endif
694
695         END_PROFILE(syscall_fchmod);
696         return result;
697 }
698
699 static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
700 {
701         int result;
702
703         START_PROFILE(syscall_chown);
704         result = chown(path, uid, gid);
705         END_PROFILE(syscall_chown);
706         return result;
707 }
708
709 static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid)
710 {
711 #ifdef HAVE_FCHOWN
712         int result;
713
714         START_PROFILE(syscall_fchown);
715         result = fchown(fsp->fh->fd, uid, gid);
716         END_PROFILE(syscall_fchown);
717         return result;
718 #else
719         errno = ENOSYS;
720         return -1;
721 #endif
722 }
723
724 static int vfswrap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
725 {
726         int result;
727
728         START_PROFILE(syscall_lchown);
729         result = lchown(path, uid, gid);
730         END_PROFILE(syscall_lchown);
731         return result;
732 }
733
734 static int vfswrap_chdir(vfs_handle_struct *handle,  const char *path)
735 {
736         int result;
737
738         START_PROFILE(syscall_chdir);
739         result = chdir(path);
740         END_PROFILE(syscall_chdir);
741         return result;
742 }
743
744 static char *vfswrap_getwd(vfs_handle_struct *handle,  char *path)
745 {
746         char *result;
747
748         START_PROFILE(syscall_getwd);
749         result = sys_getwd(path);
750         END_PROFILE(syscall_getwd);
751         return result;
752 }
753
754 /*********************************************************************
755  nsec timestamp resolution call. Convert down to whatever the underlying
756  system will support.
757 **********************************************************************/
758
759 static int vfswrap_ntimes(vfs_handle_struct *handle,
760                           const struct smb_filename *smb_fname,
761                           struct smb_file_time *ft)
762 {
763         int result = -1;
764
765         START_PROFILE(syscall_ntimes);
766
767         if (smb_fname->stream_name) {
768                 errno = ENOENT;
769                 goto out;
770         }
771
772         if (ft != NULL) {
773                 if (null_timespec(ft->atime)) {
774                         ft->atime= smb_fname->st.st_ex_atime;
775                 }
776
777                 if (null_timespec(ft->mtime)) {
778                         ft->mtime = smb_fname->st.st_ex_mtime;
779                 }
780
781                 if (!null_timespec(ft->create_time)) {
782                         set_create_timespec_ea(handle->conn,
783                                                smb_fname,
784                                                ft->create_time);
785                 }
786
787                 if ((timespec_compare(&ft->atime,
788                                       &smb_fname->st.st_ex_atime) == 0) &&
789                     (timespec_compare(&ft->mtime,
790                                       &smb_fname->st.st_ex_mtime) == 0)) {
791                         return 0;
792                 }
793         }
794
795 #if defined(HAVE_UTIMENSAT)
796         if (ft != NULL) {
797                 struct timespec ts[2];
798                 ts[0] = ft->atime;
799                 ts[1] = ft->mtime;
800                 result = utimensat(AT_FDCWD, smb_fname->base_name, ts, 0);
801         } else {
802                 result = utimensat(AT_FDCWD, smb_fname->base_name, NULL, 0);
803         }
804         if (!((result == -1) && (errno == ENOSYS))) {
805                 goto out;
806         }
807 #endif
808 #if defined(HAVE_UTIMES)
809         if (ft != NULL) {
810                 struct timeval tv[2];
811                 tv[0] = convert_timespec_to_timeval(ft->atime);
812                 tv[1] = convert_timespec_to_timeval(ft->mtime);
813                 result = utimes(smb_fname->base_name, tv);
814         } else {
815                 result = utimes(smb_fname->base_name, NULL);
816         }
817         if (!((result == -1) && (errno == ENOSYS))) {
818                 goto out;
819         }
820 #endif
821 #if defined(HAVE_UTIME)
822         if (ft != NULL) {
823                 struct utimbuf times;
824                 times.actime = convert_timespec_to_time_t(ft->atime);
825                 times.modtime = convert_timespec_to_time_t(ft->mtime);
826                 result = utime(smb_fname->base_name, &times);
827         } else {
828                 result = utime(smb_fname->base_name, NULL);
829         }
830         if (!((result == -1) && (errno == ENOSYS))) {
831                 goto out;
832         }
833 #endif
834         errno = ENOSYS;
835         result = -1;
836
837  out:
838         END_PROFILE(syscall_ntimes);
839         return result;
840 }
841
842 /*********************************************************************
843  A version of ftruncate that will write the space on disk if strict
844  allocate is set.
845 **********************************************************************/
846
847 static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T len)
848 {
849         SMB_OFF_T space_to_write;
850         uint64_t space_avail;
851         uint64_t bsize,dfree,dsize;
852         int ret;
853         NTSTATUS status;
854         SMB_STRUCT_STAT *pst;
855
856         status = vfs_stat_fsp(fsp);
857         if (!NT_STATUS_IS_OK(status)) {
858                 return -1;
859         }
860         pst = &fsp->fsp_name->st;
861
862 #ifdef S_ISFIFO
863         if (S_ISFIFO(pst->st_ex_mode))
864                 return 0;
865 #endif
866
867         if (pst->st_ex_size == len)
868                 return 0;
869
870         /* Shrink - just ftruncate. */
871         if (pst->st_ex_size > len)
872                 return sys_ftruncate(fsp->fh->fd, len);
873
874         space_to_write = len - pst->st_ex_size;
875
876         /* for allocation try fallocate first. This can fail on some
877            platforms e.g. when the filesystem doesn't support it and no
878            emulation is being done by the libc (like on AIX with JFS1). In that
879            case we do our own emulation. fallocate implementations can
880            return ENOTSUP or EINVAL in cases like that. */
881         ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
882                                 pst->st_ex_size, space_to_write);
883         if (ret == ENOSPC) {
884                 errno = ENOSPC;
885                 return -1;
886         }
887         if (ret == 0) {
888                 return 0;
889         }
890         DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
891                 "error %d. Falling back to slow manual allocation\n", ret));
892
893         /* available disk space is enough or not? */
894         space_avail = get_dfree_info(fsp->conn,
895                                      fsp->fsp_name->base_name, false,
896                                      &bsize,&dfree,&dsize);
897         /* space_avail is 1k blocks */
898         if (space_avail == (uint64_t)-1 ||
899                         ((uint64_t)space_to_write/1024 > space_avail) ) {
900                 errno = ENOSPC;
901                 return -1;
902         }
903
904         /* Write out the real space on disk. */
905         ret = vfs_slow_fallocate(fsp, pst->st_ex_size, space_to_write);
906         if (ret != 0) {
907                 errno = ret;
908                 ret = -1;
909         }
910
911         return 0;
912 }
913
914 static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T len)
915 {
916         int result = -1;
917         SMB_STRUCT_STAT *pst;
918         NTSTATUS status;
919         char c = 0;
920
921         START_PROFILE(syscall_ftruncate);
922
923         if (lp_strict_allocate(SNUM(fsp->conn)) && !fsp->is_sparse) {
924                 result = strict_allocate_ftruncate(handle, fsp, len);
925                 END_PROFILE(syscall_ftruncate);
926                 return result;
927         }
928
929         /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
930            sys_ftruncate if the system supports it. Then I discovered that
931            you can have some filesystems that support ftruncate
932            expansion and some that don't! On Linux fat can't do
933            ftruncate extend but ext2 can. */
934
935         result = sys_ftruncate(fsp->fh->fd, len);
936         if (result == 0)
937                 goto done;
938
939         /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
940            extend a file with ftruncate. Provide alternate implementation
941            for this */
942
943         /* Do an fstat to see if the file is longer than the requested
944            size in which case the ftruncate above should have
945            succeeded or shorter, in which case seek to len - 1 and
946            write 1 byte of zero */
947         status = vfs_stat_fsp(fsp);
948         if (!NT_STATUS_IS_OK(status)) {
949                 goto done;
950         }
951         pst = &fsp->fsp_name->st;
952
953 #ifdef S_ISFIFO
954         if (S_ISFIFO(pst->st_ex_mode)) {
955                 result = 0;
956                 goto done;
957         }
958 #endif
959
960         if (pst->st_ex_size == len) {
961                 result = 0;
962                 goto done;
963         }
964
965         if (pst->st_ex_size > len) {
966                 /* the sys_ftruncate should have worked */
967                 goto done;
968         }
969
970         if (SMB_VFS_PWRITE(fsp, &c, 1, len-1)!=1) {
971                 goto done;
972         }
973
974         result = 0;
975
976   done:
977
978         END_PROFILE(syscall_ftruncate);
979         return result;
980 }
981
982 static int vfswrap_fallocate(vfs_handle_struct *handle,
983                         files_struct *fsp,
984                         enum vfs_fallocate_mode mode,
985                         SMB_OFF_T offset,
986                         SMB_OFF_T len)
987 {
988         int result;
989
990         START_PROFILE(syscall_fallocate);
991         if (mode == VFS_FALLOCATE_EXTEND_SIZE) {
992                 result = sys_posix_fallocate(fsp->fh->fd, offset, len);
993         } else if (mode == VFS_FALLOCATE_KEEP_SIZE) {
994                 result = sys_fallocate(fsp->fh->fd, mode, offset, len);
995         } else {
996                 errno = EINVAL;
997                 result = -1;
998         }
999         END_PROFILE(syscall_fallocate);
1000         return result;
1001 }
1002
1003 static bool vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
1004 {
1005         bool result;
1006
1007         START_PROFILE(syscall_fcntl_lock);
1008         result =  fcntl_lock(fsp->fh->fd, op, offset, count, type);
1009         END_PROFILE(syscall_fcntl_lock);
1010         return result;
1011 }
1012
1013 static int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
1014                                 uint32 share_mode, uint32 access_mask)
1015 {
1016         START_PROFILE(syscall_kernel_flock);
1017         kernel_flock(fsp->fh->fd, share_mode, access_mask);
1018         END_PROFILE(syscall_kernel_flock);
1019         return 0;
1020 }
1021
1022 static bool vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1023 {
1024         bool result;
1025
1026         START_PROFILE(syscall_fcntl_getlock);
1027         result =  fcntl_getlock(fsp->fh->fd, poffset, pcount, ptype, ppid);
1028         END_PROFILE(syscall_fcntl_getlock);
1029         return result;
1030 }
1031
1032 static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp,
1033                                 int leasetype)
1034 {
1035         int result = -1;
1036
1037         START_PROFILE(syscall_linux_setlease);
1038
1039 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
1040         /* first set the signal handler */
1041         if(linux_set_lease_sighandler(fsp->fh->fd) == -1) {
1042                 return -1;
1043         }
1044
1045         result = linux_setlease(fsp->fh->fd, leasetype);
1046 #else
1047         errno = ENOSYS;
1048 #endif
1049         END_PROFILE(syscall_linux_setlease);
1050         return result;
1051 }
1052
1053 static int vfswrap_symlink(vfs_handle_struct *handle,  const char *oldpath, const char *newpath)
1054 {
1055         int result;
1056
1057         START_PROFILE(syscall_symlink);
1058         result = symlink(oldpath, newpath);
1059         END_PROFILE(syscall_symlink);
1060         return result;
1061 }
1062
1063 static int vfswrap_readlink(vfs_handle_struct *handle,  const char *path, char *buf, size_t bufsiz)
1064 {
1065         int result;
1066
1067         START_PROFILE(syscall_readlink);
1068         result = readlink(path, buf, bufsiz);
1069         END_PROFILE(syscall_readlink);
1070         return result;
1071 }
1072
1073 static int vfswrap_link(vfs_handle_struct *handle,  const char *oldpath, const char *newpath)
1074 {
1075         int result;
1076
1077         START_PROFILE(syscall_link);
1078         result = link(oldpath, newpath);
1079         END_PROFILE(syscall_link);
1080         return result;
1081 }
1082
1083 static int vfswrap_mknod(vfs_handle_struct *handle,  const char *pathname, mode_t mode, SMB_DEV_T dev)
1084 {
1085         int result;
1086
1087         START_PROFILE(syscall_mknod);
1088         result = sys_mknod(pathname, mode, dev);
1089         END_PROFILE(syscall_mknod);
1090         return result;
1091 }
1092
1093 static char *vfswrap_realpath(vfs_handle_struct *handle,  const char *path)
1094 {
1095         char *result;
1096
1097         START_PROFILE(syscall_realpath);
1098 #ifdef REALPATH_TAKES_NULL
1099         result = realpath(path, NULL);
1100 #else
1101         result = SMB_MALLOC_ARRAY(char, PATH_MAX+1);
1102         if (result) {
1103                 char *resolved_path = realpath(path, result);
1104                 if (!resolved_path) {
1105                         SAFE_FREE(result);
1106                 } else {
1107                         /* SMB_ASSERT(result == resolved_path) ? */
1108                         result = resolved_path;
1109                 }
1110         }
1111 #endif
1112         END_PROFILE(syscall_realpath);
1113         return result;
1114 }
1115
1116 static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
1117                                      struct sys_notify_context *ctx,
1118                                      struct notify_entry *e,
1119                                      void (*callback)(struct sys_notify_context *ctx, 
1120                                                       void *private_data,
1121                                                       struct notify_event *ev),
1122                                      void *private_data, void *handle)
1123 {
1124         /*
1125          * So far inotify is the only supported default notify mechanism. If
1126          * another platform like the the BSD's or a proprietary Unix comes
1127          * along and wants another default, we can play the same trick we
1128          * played with Posix ACLs.
1129          *
1130          * Until that is the case, hard-code inotify here.
1131          */
1132 #ifdef HAVE_INOTIFY
1133         if (lp_kernel_change_notify(ctx->conn->params)) {
1134                 return inotify_watch(ctx, e, callback, private_data, handle);
1135         }
1136 #endif
1137         /*
1138          * Do nothing, leave everything to notify_internal.c
1139          */
1140         return NT_STATUS_OK;
1141 }
1142
1143 static int vfswrap_chflags(vfs_handle_struct *handle, const char *path,
1144                            unsigned int flags)
1145 {
1146 #ifdef HAVE_CHFLAGS
1147         return chflags(path, flags);
1148 #else
1149         errno = ENOSYS;
1150         return -1;
1151 #endif
1152 }
1153
1154 static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
1155                                              const SMB_STRUCT_STAT *sbuf)
1156 {
1157         struct file_id key;
1158
1159         /* the ZERO_STRUCT ensures padding doesn't break using the key as a
1160          * blob */
1161         ZERO_STRUCT(key);
1162
1163         key.devid = sbuf->st_ex_dev;
1164         key.inode = sbuf->st_ex_ino;
1165         /* key.extid is unused by default. */
1166
1167         return key;
1168 }
1169
1170 static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
1171                                    struct files_struct *fsp,
1172                                    const char *fname,
1173                                    TALLOC_CTX *mem_ctx,
1174                                    unsigned int *pnum_streams,
1175                                    struct stream_struct **pstreams)
1176 {
1177         SMB_STRUCT_STAT sbuf;
1178         unsigned int num_streams = 0;
1179         struct stream_struct *streams = NULL;
1180         int ret;
1181
1182         if ((fsp != NULL) && (fsp->is_directory)) {
1183                 /*
1184                  * No default streams on directories
1185                  */
1186                 goto done;
1187         }
1188
1189         if ((fsp != NULL) && (fsp->fh->fd != -1)) {
1190                 ret = SMB_VFS_FSTAT(fsp, &sbuf);
1191         }
1192         else {
1193                 struct smb_filename smb_fname;
1194
1195                 ZERO_STRUCT(smb_fname);
1196                 smb_fname.base_name = discard_const_p(char, fname);
1197
1198                 if (lp_posix_pathnames()) {
1199                         ret = SMB_VFS_LSTAT(handle->conn, &smb_fname);
1200                 } else {
1201                         ret = SMB_VFS_STAT(handle->conn, &smb_fname);
1202                 }
1203                 sbuf = smb_fname.st;
1204         }
1205
1206         if (ret == -1) {
1207                 return map_nt_error_from_unix(errno);
1208         }
1209
1210         if (S_ISDIR(sbuf.st_ex_mode)) {
1211                 goto done;
1212         }
1213
1214         streams = talloc(mem_ctx, struct stream_struct);
1215
1216         if (streams == NULL) {
1217                 return NT_STATUS_NO_MEMORY;
1218         }
1219
1220         streams->size = sbuf.st_ex_size;
1221         streams->alloc_size = SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, &sbuf);
1222
1223         streams->name = talloc_strdup(streams, "::$DATA");
1224         if (streams->name == NULL) {
1225                 TALLOC_FREE(streams);
1226                 return NT_STATUS_NO_MEMORY;
1227         }
1228
1229         num_streams = 1;
1230  done:
1231         *pnum_streams = num_streams;
1232         *pstreams = streams;
1233         return NT_STATUS_OK;
1234 }
1235
1236 static int vfswrap_get_real_filename(struct vfs_handle_struct *handle,
1237                                      const char *path,
1238                                      const char *name,
1239                                      TALLOC_CTX *mem_ctx,
1240                                      char **found_name)
1241 {
1242         /*
1243          * Don't fall back to get_real_filename so callers can differentiate
1244          * between a full directory scan and an actual case-insensitive stat.
1245          */
1246         errno = EOPNOTSUPP;
1247         return -1;
1248 }
1249
1250 static const char *vfswrap_connectpath(struct vfs_handle_struct *handle,
1251                                        const char *fname)
1252 {
1253         return handle->conn->connectpath;
1254 }
1255
1256 static NTSTATUS vfswrap_brl_lock_windows(struct vfs_handle_struct *handle,
1257                                          struct byte_range_lock *br_lck,
1258                                          struct lock_struct *plock,
1259                                          bool blocking_lock,
1260                                          struct blocking_lock_record *blr)
1261 {
1262         SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1263
1264         /* Note: blr is not used in the default implementation. */
1265         return brl_lock_windows_default(br_lck, plock, blocking_lock);
1266 }
1267
1268 static bool vfswrap_brl_unlock_windows(struct vfs_handle_struct *handle,
1269                                        struct messaging_context *msg_ctx,
1270                                        struct byte_range_lock *br_lck,
1271                                        const struct lock_struct *plock)
1272 {
1273         SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1274
1275         return brl_unlock_windows_default(msg_ctx, br_lck, plock);
1276 }
1277
1278 static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct *handle,
1279                                        struct byte_range_lock *br_lck,
1280                                        struct lock_struct *plock,
1281                                        struct blocking_lock_record *blr)
1282 {
1283         SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1284
1285         /* Note: blr is not used in the default implementation. */
1286         return brl_lock_cancel_default(br_lck, plock);
1287 }
1288
1289 static bool vfswrap_strict_lock(struct vfs_handle_struct *handle,
1290                                 files_struct *fsp,
1291                                 struct lock_struct *plock)
1292 {
1293         SMB_ASSERT(plock->lock_type == READ_LOCK ||
1294             plock->lock_type == WRITE_LOCK);
1295
1296         return strict_lock_default(fsp, plock);
1297 }
1298
1299 static void vfswrap_strict_unlock(struct vfs_handle_struct *handle,
1300                                 files_struct *fsp,
1301                                 struct lock_struct *plock)
1302 {
1303         SMB_ASSERT(plock->lock_type == READ_LOCK ||
1304             plock->lock_type == WRITE_LOCK);
1305
1306         strict_unlock_default(fsp, plock);
1307 }
1308
1309 /* NT ACL operations. */
1310
1311 static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
1312                                     files_struct *fsp,
1313                                     uint32 security_info,
1314                                     struct security_descriptor **ppdesc)
1315 {
1316         NTSTATUS result;
1317
1318         START_PROFILE(fget_nt_acl);
1319         result = posix_fget_nt_acl(fsp, security_info, ppdesc);
1320         END_PROFILE(fget_nt_acl);
1321         return result;
1322 }
1323
1324 static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle,
1325                                    const char *name,
1326                                    uint32 security_info,
1327                                    struct security_descriptor **ppdesc)
1328 {
1329         NTSTATUS result;
1330
1331         START_PROFILE(get_nt_acl);
1332         result = posix_get_nt_acl(handle->conn, name, security_info, ppdesc);
1333         END_PROFILE(get_nt_acl);
1334         return result;
1335 }
1336
1337 static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, const struct security_descriptor *psd)
1338 {
1339         NTSTATUS result;
1340
1341         START_PROFILE(fset_nt_acl);
1342         result = set_nt_acl(fsp, security_info_sent, psd);
1343         END_PROFILE(fset_nt_acl);
1344         return result;
1345 }
1346
1347 static int vfswrap_chmod_acl(vfs_handle_struct *handle,  const char *name, mode_t mode)
1348 {
1349 #ifdef HAVE_NO_ACL
1350         errno = ENOSYS;
1351         return -1;
1352 #else
1353         int result;
1354
1355         START_PROFILE(chmod_acl);
1356         result = chmod_acl(handle->conn, name, mode);
1357         END_PROFILE(chmod_acl);
1358         return result;
1359 #endif
1360 }
1361
1362 static int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
1363 {
1364 #ifdef HAVE_NO_ACL
1365         errno = ENOSYS;
1366         return -1;
1367 #else
1368         int result;
1369
1370         START_PROFILE(fchmod_acl);
1371         result = fchmod_acl(fsp, mode);
1372         END_PROFILE(fchmod_acl);
1373         return result;
1374 #endif
1375 }
1376
1377 static int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle,  SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1378 {
1379         return sys_acl_get_entry(theacl, entry_id, entry_p);
1380 }
1381
1382 static int vfswrap_sys_acl_get_tag_type(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
1383 {
1384         return sys_acl_get_tag_type(entry_d, tag_type_p);
1385 }
1386
1387 static int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1388 {
1389         return sys_acl_get_permset(entry_d, permset_p);
1390 }
1391
1392 static void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry_d)
1393 {
1394         return sys_acl_get_qualifier(entry_d);
1395 }
1396
1397 static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle,  const char *path_p, SMB_ACL_TYPE_T type)
1398 {
1399         return sys_acl_get_file(handle, path_p, type);
1400 }
1401
1402 static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp)
1403 {
1404         return sys_acl_get_fd(handle, fsp);
1405 }
1406
1407 static int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle,  SMB_ACL_PERMSET_T permset)
1408 {
1409         return sys_acl_clear_perms(permset);
1410 }
1411
1412 static int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle,  SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1413 {
1414         return sys_acl_add_perm(permset, perm);
1415 }
1416
1417 static char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle,  SMB_ACL_T theacl, ssize_t *plen)
1418 {
1419         return sys_acl_to_text(theacl, plen);
1420 }
1421
1422 static SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle,  int count)
1423 {
1424         return sys_acl_init(count);
1425 }
1426
1427 static int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle,  SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
1428 {
1429         return sys_acl_create_entry(pacl, pentry);
1430 }
1431
1432 static int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
1433 {
1434         return sys_acl_set_tag_type(entry, tagtype);
1435 }
1436
1437 static int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry, void *qual)
1438 {
1439         return sys_acl_set_qualifier(entry, qual);
1440 }
1441
1442 static int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
1443 {
1444         return sys_acl_set_permset(entry, permset);
1445 }
1446
1447 static int vfswrap_sys_acl_valid(vfs_handle_struct *handle,  SMB_ACL_T theacl )
1448 {
1449         return sys_acl_valid(theacl );
1450 }
1451
1452 static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle,  const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
1453 {
1454         return sys_acl_set_file(handle, name, acltype, theacl);
1455 }
1456
1457 static int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl)
1458 {
1459         return sys_acl_set_fd(handle, fsp, theacl);
1460 }
1461
1462 static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle,  const char *path)
1463 {
1464         return sys_acl_delete_def_file(handle, path);
1465 }
1466
1467 static int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle,  SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1468 {
1469         return sys_acl_get_perm(permset, perm);
1470 }
1471
1472 static int vfswrap_sys_acl_free_text(vfs_handle_struct *handle,  char *text)
1473 {
1474         return sys_acl_free_text(text);
1475 }
1476
1477 static int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle,  SMB_ACL_T posix_acl)
1478 {
1479         return sys_acl_free_acl(posix_acl);
1480 }
1481
1482 static int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle,  void *qualifier, SMB_ACL_TAG_T tagtype)
1483 {
1484         return sys_acl_free_qualifier(qualifier, tagtype);
1485 }
1486
1487 /****************************************************************
1488  Extended attribute operations.
1489 *****************************************************************/
1490
1491 static ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
1492 {
1493         return sys_getxattr(path, name, value, size);
1494 }
1495
1496 static ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
1497 {
1498         return sys_lgetxattr(path, name, value, size);
1499 }
1500
1501 static ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size)
1502 {
1503         return sys_fgetxattr(fsp->fh->fd, name, value, size);
1504 }
1505
1506 static ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
1507 {
1508         return sys_listxattr(path, list, size);
1509 }
1510
1511 ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
1512 {
1513         return sys_llistxattr(path, list, size);
1514 }
1515
1516 ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)
1517 {
1518         return sys_flistxattr(fsp->fh->fd, list, size);
1519 }
1520
1521 static int vfswrap_removexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
1522 {
1523         return sys_removexattr(path, name);
1524 }
1525
1526 static int vfswrap_lremovexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
1527 {
1528         return sys_lremovexattr(path, name);
1529 }
1530
1531 static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name)
1532 {
1533         return sys_fremovexattr(fsp->fh->fd, name);
1534 }
1535
1536 static int vfswrap_setxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
1537 {
1538         return sys_setxattr(path, name, value, size, flags);
1539 }
1540
1541 static int vfswrap_lsetxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
1542 {
1543         return sys_lsetxattr(path, name, value, size, flags);
1544 }
1545
1546 static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags)
1547 {
1548         return sys_fsetxattr(fsp->fh->fd, name, value, size, flags);
1549 }
1550
1551 static int vfswrap_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1552 {
1553         int ret;
1554         /*
1555          * aio_read must be done as root, because in the glibc aio
1556          * implementation the helper thread needs to be able to send a signal
1557          * to the main thread, even when it has done a seteuid() to a
1558          * different user.
1559          */
1560         become_root();
1561         ret = sys_aio_read(aiocb);
1562         unbecome_root();
1563         return ret;
1564 }
1565
1566 static int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1567 {
1568         int ret;
1569         /*
1570          * aio_write must be done as root, because in the glibc aio
1571          * implementation the helper thread needs to be able to send a signal
1572          * to the main thread, even when it has done a seteuid() to a
1573          * different user.
1574          */
1575         become_root();
1576         ret = sys_aio_write(aiocb);
1577         unbecome_root();
1578         return ret;
1579 }
1580
1581 static ssize_t vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1582 {
1583         return sys_aio_return(aiocb);
1584 }
1585
1586 static int vfswrap_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1587 {
1588         return sys_aio_cancel(fsp->fh->fd, aiocb);
1589 }
1590
1591 static int vfswrap_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1592 {
1593         return sys_aio_error(aiocb);
1594 }
1595
1596 static int vfswrap_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb)
1597 {
1598         return sys_aio_fsync(op, aiocb);
1599 }
1600
1601 static int vfswrap_aio_suspend(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *timeout)
1602 {
1603         return sys_aio_suspend(aiocb, n, timeout);
1604 }
1605
1606 static bool vfswrap_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp)
1607 {
1608         return false;
1609 }
1610
1611 static bool vfswrap_is_offline(struct vfs_handle_struct *handle,
1612                                const struct smb_filename *fname,
1613                                SMB_STRUCT_STAT *sbuf)
1614 {
1615         NTSTATUS status;
1616         char *path;
1617
1618         if (ISDOT(fname->base_name) || ISDOTDOT(fname->base_name)) {
1619                 return false;
1620         }
1621
1622         if (!lp_dmapi_support(SNUM(handle->conn)) || !dmapi_have_session()) {
1623 #if defined(ENOTSUP)
1624                 errno = ENOTSUP;
1625 #endif
1626                 return false;
1627         }
1628
1629         status = get_full_smb_filename(talloc_tos(), fname, &path);
1630         if (!NT_STATUS_IS_OK(status)) {
1631                 errno = map_errno_from_nt_status(status);
1632                 return false;
1633         }
1634
1635         return (dmapi_file_flags(path) & FILE_ATTRIBUTE_OFFLINE) != 0;
1636 }
1637
1638 static int vfswrap_set_offline(struct vfs_handle_struct *handle,
1639                                const struct smb_filename *fname)
1640 {
1641         /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
1642 #if defined(ENOTSUP)
1643         errno = ENOTSUP;
1644 #endif
1645         return -1;
1646 }
1647
1648 static struct vfs_fn_pointers vfs_default_fns = {
1649         /* Disk operations */
1650
1651         .connect_fn = vfswrap_connect,
1652         .disconnect = vfswrap_disconnect,
1653         .disk_free = vfswrap_disk_free,
1654         .get_quota = vfswrap_get_quota,
1655         .set_quota = vfswrap_set_quota,
1656         .get_shadow_copy_data = vfswrap_get_shadow_copy_data,
1657         .statvfs = vfswrap_statvfs,
1658         .fs_capabilities = vfswrap_fs_capabilities,
1659
1660         /* Directory operations */
1661
1662         .opendir = vfswrap_opendir,
1663         .fdopendir = vfswrap_fdopendir,
1664         .readdir = vfswrap_readdir,
1665         .seekdir = vfswrap_seekdir,
1666         .telldir = vfswrap_telldir,
1667         .rewind_dir = vfswrap_rewinddir,
1668         .mkdir = vfswrap_mkdir,
1669         .rmdir = vfswrap_rmdir,
1670         .closedir = vfswrap_closedir,
1671         .init_search_op = vfswrap_init_search_op,
1672
1673         /* File operations */
1674
1675         .open = vfswrap_open,
1676         .create_file = vfswrap_create_file,
1677         .close_fn = vfswrap_close,
1678         .vfs_read = vfswrap_read,
1679         .pread = vfswrap_pread,
1680         .write = vfswrap_write,
1681         .pwrite = vfswrap_pwrite,
1682         .lseek = vfswrap_lseek,
1683         .sendfile = vfswrap_sendfile,
1684         .recvfile = vfswrap_recvfile,
1685         .rename = vfswrap_rename,
1686         .fsync = vfswrap_fsync,
1687         .stat = vfswrap_stat,
1688         .fstat = vfswrap_fstat,
1689         .lstat = vfswrap_lstat,
1690         .get_alloc_size = vfswrap_get_alloc_size,
1691         .unlink = vfswrap_unlink,
1692         .chmod = vfswrap_chmod,
1693         .fchmod = vfswrap_fchmod,
1694         .chown = vfswrap_chown,
1695         .fchown = vfswrap_fchown,
1696         .lchown = vfswrap_lchown,
1697         .chdir = vfswrap_chdir,
1698         .getwd = vfswrap_getwd,
1699         .ntimes = vfswrap_ntimes,
1700         .ftruncate = vfswrap_ftruncate,
1701         .fallocate = vfswrap_fallocate,
1702         .lock = vfswrap_lock,
1703         .kernel_flock = vfswrap_kernel_flock,
1704         .linux_setlease = vfswrap_linux_setlease,
1705         .getlock = vfswrap_getlock,
1706         .symlink = vfswrap_symlink,
1707         .vfs_readlink = vfswrap_readlink,
1708         .link = vfswrap_link,
1709         .mknod = vfswrap_mknod,
1710         .realpath = vfswrap_realpath,
1711         .notify_watch = vfswrap_notify_watch,
1712         .chflags = vfswrap_chflags,
1713         .file_id_create = vfswrap_file_id_create,
1714         .streaminfo = vfswrap_streaminfo,
1715         .get_real_filename = vfswrap_get_real_filename,
1716         .connectpath = vfswrap_connectpath,
1717         .brl_lock_windows = vfswrap_brl_lock_windows,
1718         .brl_unlock_windows = vfswrap_brl_unlock_windows,
1719         .brl_cancel_windows = vfswrap_brl_cancel_windows,
1720         .strict_lock = vfswrap_strict_lock,
1721         .strict_unlock = vfswrap_strict_unlock,
1722         .translate_name = vfswrap_translate_name,
1723
1724         /* NT ACL operations. */
1725
1726         .fget_nt_acl = vfswrap_fget_nt_acl,
1727         .get_nt_acl = vfswrap_get_nt_acl,
1728         .fset_nt_acl = vfswrap_fset_nt_acl,
1729
1730         /* POSIX ACL operations. */
1731
1732         .chmod_acl = vfswrap_chmod_acl,
1733         .fchmod_acl = vfswrap_fchmod_acl,
1734
1735         .sys_acl_get_entry = vfswrap_sys_acl_get_entry,
1736         .sys_acl_get_tag_type = vfswrap_sys_acl_get_tag_type,
1737         .sys_acl_get_permset = vfswrap_sys_acl_get_permset,
1738         .sys_acl_get_qualifier = vfswrap_sys_acl_get_qualifier,
1739         .sys_acl_get_file = vfswrap_sys_acl_get_file,
1740         .sys_acl_get_fd = vfswrap_sys_acl_get_fd,
1741         .sys_acl_clear_perms = vfswrap_sys_acl_clear_perms,
1742         .sys_acl_add_perm = vfswrap_sys_acl_add_perm,
1743         .sys_acl_to_text = vfswrap_sys_acl_to_text,
1744         .sys_acl_init = vfswrap_sys_acl_init,
1745         .sys_acl_create_entry = vfswrap_sys_acl_create_entry,
1746         .sys_acl_set_tag_type = vfswrap_sys_acl_set_tag_type,
1747         .sys_acl_set_qualifier = vfswrap_sys_acl_set_qualifier,
1748         .sys_acl_set_permset = vfswrap_sys_acl_set_permset,
1749         .sys_acl_valid = vfswrap_sys_acl_valid,
1750         .sys_acl_set_file = vfswrap_sys_acl_set_file,
1751         .sys_acl_set_fd = vfswrap_sys_acl_set_fd,
1752         .sys_acl_delete_def_file = vfswrap_sys_acl_delete_def_file,
1753         .sys_acl_get_perm = vfswrap_sys_acl_get_perm,
1754         .sys_acl_free_text = vfswrap_sys_acl_free_text,
1755         .sys_acl_free_acl = vfswrap_sys_acl_free_acl,
1756         .sys_acl_free_qualifier = vfswrap_sys_acl_free_qualifier,
1757
1758         /* EA operations. */
1759         .getxattr = vfswrap_getxattr,
1760         .lgetxattr = vfswrap_lgetxattr,
1761         .fgetxattr = vfswrap_fgetxattr,
1762         .listxattr = vfswrap_listxattr,
1763         .llistxattr = vfswrap_llistxattr,
1764         .flistxattr = vfswrap_flistxattr,
1765         .removexattr = vfswrap_removexattr,
1766         .lremovexattr = vfswrap_lremovexattr,
1767         .fremovexattr = vfswrap_fremovexattr,
1768         .setxattr = vfswrap_setxattr,
1769         .lsetxattr = vfswrap_lsetxattr,
1770         .fsetxattr = vfswrap_fsetxattr,
1771
1772         /* aio operations */
1773         .aio_read = vfswrap_aio_read,
1774         .aio_write = vfswrap_aio_write,
1775         .aio_return_fn = vfswrap_aio_return,
1776         .aio_cancel = vfswrap_aio_cancel,
1777         .aio_error_fn = vfswrap_aio_error,
1778         .aio_fsync = vfswrap_aio_fsync,
1779         .aio_suspend = vfswrap_aio_suspend,
1780         .aio_force = vfswrap_aio_force,
1781
1782         /* offline operations */
1783         .is_offline = vfswrap_is_offline,
1784         .set_offline = vfswrap_set_offline
1785 };
1786
1787 NTSTATUS vfs_default_init(void);
1788 NTSTATUS vfs_default_init(void)
1789 {
1790         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
1791                                 DEFAULT_VFS_MODULE_NAME, &vfs_default_fns);
1792 }
1793
1794