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