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