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