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