5393dfc75563b64ba6bfca5015ca5123db59e8a1
[samba.git] / source3 / smbd / vfs-wrap.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Wrap disk only vfs functions to sidestep dodgy compilers.
4    Copyright (C) Tim Potter 1998
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 #undef DBGC_CLASS
24 #define DBGC_CLASS DBGC_VFS
25
26
27 /* Check for NULL pointer parameters in vfswrap_* functions */
28
29 /* We don't want to have NULL function pointers lying around.  Someone
30    is sure to try and execute them.  These stubs are used to prevent
31    this possibility. */
32
33 int vfswrap_dummy_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user)
34 {
35     return 0;    /* Return >= 0 for success */
36 }
37
38 void vfswrap_dummy_disconnect(vfs_handle_struct *handle, connection_struct *conn)
39 {
40 }
41
42 /* Disk operations */
43
44 SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle, connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize, 
45                                SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
46 {
47         SMB_BIG_UINT result;
48
49         result = sys_disk_free(path, small_query, bsize, dfree, dsize);
50         return result;
51 }
52
53 int vfswrap_get_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
54 {
55 #ifdef HAVE_SYS_QUOTAS
56         int result;
57
58         START_PROFILE(syscall_get_quota);
59         result = sys_get_quota(conn->connectpath, qtype, id, qt);
60         END_PROFILE(syscall_get_quota);
61         return result;
62 #else
63         errno = ENOSYS;
64         return -1;
65 #endif  
66 }
67
68 int vfswrap_set_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
69 {
70 #ifdef HAVE_SYS_QUOTAS
71         int result;
72
73         START_PROFILE(syscall_set_quota);
74         result = sys_set_quota(conn->connectpath, qtype, id, qt);
75         END_PROFILE(syscall_set_quota);
76         return result;
77 #else
78         errno = ENOSYS;
79         return -1;
80 #endif  
81 }
82
83 int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels)
84 {
85         errno = ENOSYS;
86         return -1;  /* Not implemented. */
87 }
88     
89 /* Directory operations */
90
91 DIR *vfswrap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname)
92 {
93         DIR *result;
94
95         START_PROFILE(syscall_opendir);
96         result = opendir(fname);
97         END_PROFILE(syscall_opendir);
98         return result;
99 }
100
101 struct dirent *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
102 {
103         struct dirent *result;
104
105         START_PROFILE(syscall_readdir);
106         result = readdir(dirp);
107         END_PROFILE(syscall_readdir);
108         return result;
109 }
110
111 int vfswrap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
112 {
113         int result;
114         BOOL has_dacl = False;
115
116         START_PROFILE(syscall_mkdir);
117
118         if (lp_inherit_acls(SNUM(conn)) && (has_dacl = directory_has_default_acl(conn, parent_dirname(path))))
119                 mode = 0777;
120
121         result = mkdir(path, mode);
122
123         if (result == 0 && !has_dacl) {
124                 /*
125                  * We need to do this as the default behavior of POSIX ACLs     
126                  * is to set the mask to be the requested group permission
127                  * bits, not the group permission bits to be the requested
128                  * group permission bits. This is not what we want, as it will
129                  * mess up any inherited ACL bits that were set. JRA.
130                  */
131                 int saved_errno = errno; /* We may get ENOSYS */
132                 if ((SMB_VFS_CHMOD_ACL(conn, path, mode) == -1) && (errno == ENOSYS))
133                         errno = saved_errno;
134         }
135
136         END_PROFILE(syscall_mkdir);
137         return result;
138 }
139
140 int vfswrap_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
141 {
142         int result;
143
144         START_PROFILE(syscall_rmdir);
145         result = rmdir(path);
146         END_PROFILE(syscall_rmdir);
147         return result;
148 }
149
150 int vfswrap_closedir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
151 {
152         int result;
153
154         START_PROFILE(syscall_closedir);
155         result = closedir(dirp);
156         END_PROFILE(syscall_closedir);
157         return result;
158 }
159
160 /* File operations */
161     
162 int vfswrap_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
163 {
164         int result;
165
166         START_PROFILE(syscall_open);
167         result = sys_open(fname, flags, mode);
168         END_PROFILE(syscall_open);
169         return result;
170 }
171
172 int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
173 {
174         int result;
175
176         START_PROFILE(syscall_close);
177
178         result = close(fd);
179         END_PROFILE(syscall_close);
180         return result;
181 }
182
183 ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n)
184 {
185         ssize_t result;
186
187         START_PROFILE_BYTES(syscall_read, n);
188         result = sys_read(fd, data, n);
189         END_PROFILE(syscall_read);
190         return result;
191 }
192
193 ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data,
194                         size_t n, SMB_OFF_T offset)
195 {
196         ssize_t result;
197
198 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
199         START_PROFILE_BYTES(syscall_pread, n);
200         result = sys_pread(fd, data, n, offset);
201         END_PROFILE(syscall_pread);
202  
203         if (result == -1 && errno == ESPIPE) {
204                 /* Maintain the fiction that pipes can be seeked (sought?) on. */
205                 result = SMB_VFS_READ(fsp, fd, data, n);
206                 fsp->pos = 0;
207         }
208
209 #else /* HAVE_PREAD */
210         SMB_OFF_T   curr;
211         int lerrno;
212    
213         curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
214         if (curr == -1 && errno == ESPIPE) {
215                 /* Maintain the fiction that pipes can be seeked (sought?) on. */
216                 result = SMB_VFS_READ(fsp, fd, data, n);
217                 fsp->pos = 0;
218                 return result;
219         }
220
221         if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) {
222                 return -1;
223         }
224
225         errno = 0;
226         result = SMB_VFS_READ(fsp, fd, data, n);
227         lerrno = errno;
228
229         SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET);
230         errno = lerrno;
231
232 #endif /* HAVE_PREAD */
233
234         return result;
235 }
236
237 ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n)
238 {
239         ssize_t result;
240
241         START_PROFILE_BYTES(syscall_write, n);
242         result = sys_write(fd, data, n);
243         END_PROFILE(syscall_write);
244         return result;
245 }
246
247 ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data,
248                         size_t n, SMB_OFF_T offset)
249 {
250         ssize_t result;
251
252 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
253         START_PROFILE_BYTES(syscall_pwrite, n);
254         result = sys_pwrite(fd, data, n, offset);
255         END_PROFILE(syscall_pwrite);
256
257         if (result == -1 && errno == ESPIPE) {
258                 /* Maintain the fiction that pipes can be sought on. */
259                 result = SMB_VFS_WRITE(fsp, fd, data, n);
260         }
261
262 #else /* HAVE_PWRITE */
263         SMB_OFF_T   curr;
264         int         lerrno;
265
266         curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
267         if (curr == -1) {
268                 return -1;
269         }
270
271         if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) {
272                 return -1;
273         }
274
275         result = SMB_VFS_WRITE(fsp, fd, data, n);
276         lerrno = errno;
277
278         SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET);
279         errno = lerrno;
280
281 #endif /* HAVE_PWRITE */
282
283         return result;
284 }
285
286 SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
287 {
288         SMB_OFF_T result = 0;
289
290         START_PROFILE(syscall_lseek);
291
292         /* Cope with 'stat' file opens. */
293         if (filedes != -1)
294                 result = sys_lseek(filedes, offset, whence);
295
296         /*
297          * We want to maintain the fiction that we can seek
298          * on a fifo for file system purposes. This allows
299          * people to set up UNIX fifo's that feed data to Windows
300          * applications. JRA.
301          */
302
303         if((result == -1) && (errno == ESPIPE)) {
304                 result = 0;
305                 errno = 0;
306         }
307
308         END_PROFILE(syscall_lseek);
309         return result;
310 }
311
312 ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *hdr,
313                         SMB_OFF_T offset, size_t n)
314 {
315         ssize_t result;
316
317         START_PROFILE_BYTES(syscall_sendfile, n);
318         result = sys_sendfile(tofd, fromfd, hdr, offset, n);
319         END_PROFILE(syscall_sendfile);
320         return result;
321 }
322
323 /*********************************************************
324  For rename across filesystems Patch from Warren Birnbaum
325  <warrenb@hpcvscdp.cv.hp.com>
326 **********************************************************/
327
328 static int copy_reg(const char *source, const char *dest)
329 {
330         SMB_STRUCT_STAT source_stats;
331         int saved_errno;
332         int ifd = -1;
333         int ofd = -1;
334
335         if (sys_lstat (source, &source_stats) == -1)
336                 return -1;
337
338         if (!S_ISREG (source_stats.st_mode))
339                 return -1;
340
341         if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
342                 return -1;
343
344         if (unlink (dest) && errno != ENOENT)
345                 return -1;
346
347 #ifdef O_NOFOLLOW
348         if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 )
349 #else
350         if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 )
351 #endif
352                 goto err;
353
354         if (transfer_file(ifd, ofd, (size_t)-1) == -1)
355                 goto err;
356
357         /*
358          * Try to preserve ownership.  For non-root it might fail, but that's ok.
359          * But root probably wants to know, e.g. if NFS disallows it.
360          */
361
362 #ifdef HAVE_FCHOWN
363         if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM))
364 #else
365         if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM))
366 #endif
367                 goto err;
368
369         /*
370          * fchown turns off set[ug]id bits for non-root,
371          * so do the chmod last.
372          */
373
374 #if defined(HAVE_FCHMOD)
375         if (fchmod (ofd, source_stats.st_mode & 07777))
376 #else
377         if (chmod (dest, source_stats.st_mode & 07777))
378 #endif
379                 goto err;
380
381         if (close (ifd) == -1)
382                 goto err;
383
384         if (close (ofd) == -1)
385                 return -1;
386
387         /* Try to copy the old file's modtime and access time.  */
388         {
389                 struct utimbuf tv;
390
391                 tv.actime = source_stats.st_atime;
392                 tv.modtime = source_stats.st_mtime;
393                 utime(dest, &tv);
394         }
395
396         if (unlink (source) == -1)
397                 return -1;
398
399         return 0;
400
401   err:
402
403         saved_errno = errno;
404         if (ifd != -1)
405                 close(ifd);
406         if (ofd != -1)
407                 close(ofd);
408         errno = saved_errno;
409         return -1;
410 }
411
412 int vfswrap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new)
413 {
414         int result;
415
416         START_PROFILE(syscall_rename);
417         result = rename(old, new);
418         if (errno == EXDEV) {
419                 /* Rename across filesystems needed. */
420                 result = copy_reg(old, new);
421         }
422
423         END_PROFILE(syscall_rename);
424         return result;
425 }
426
427 int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd)
428 {
429 #ifdef HAVE_FSYNC
430         int result;
431
432         START_PROFILE(syscall_fsync);
433         result = fsync(fd);
434         END_PROFILE(syscall_fsync);
435         return result;
436 #else
437         return 0;
438 #endif
439 }
440
441 int vfswrap_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
442 {
443         int result;
444
445         START_PROFILE(syscall_stat);
446         result = sys_stat(fname, sbuf);
447         END_PROFILE(syscall_stat);
448         return result;
449 }
450
451 int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
452 {
453         int result;
454
455         START_PROFILE(syscall_fstat);
456         result = sys_fstat(fd, sbuf);
457         END_PROFILE(syscall_fstat);
458         return result;
459 }
460
461 int vfswrap_lstat(vfs_handle_struct *handle, connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf)
462 {
463         int result;
464
465         START_PROFILE(syscall_lstat);
466         result = sys_lstat(path, sbuf);
467         END_PROFILE(syscall_lstat);
468         return result;
469 }
470
471 int vfswrap_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
472 {
473         int result;
474
475         START_PROFILE(syscall_unlink);
476         result = unlink(path);
477         END_PROFILE(syscall_unlink);
478         return result;
479 }
480
481 int vfswrap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
482 {
483         int result;
484
485         START_PROFILE(syscall_chmod);
486
487         /*
488          * We need to do this due to the fact that the default POSIX ACL
489          * chmod modifies the ACL *mask* for the group owner, not the
490          * group owner bits directly. JRA.
491          */
492
493         
494         {
495                 int saved_errno = errno; /* We might get ENOSYS */
496                 if ((result = SMB_VFS_CHMOD_ACL(conn, path, mode)) == 0) {
497                         END_PROFILE(syscall_chmod);
498                         return result;
499                 }
500                 /* Error - return the old errno. */
501                 errno = saved_errno;
502         }
503
504         result = chmod(path, mode);
505         END_PROFILE(syscall_chmod);
506         return result;
507 }
508
509 int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
510 {
511         int result;
512         
513         START_PROFILE(syscall_fchmod);
514
515         /*
516          * We need to do this due to the fact that the default POSIX ACL
517          * chmod modifies the ACL *mask* for the group owner, not the
518          * group owner bits directly. JRA.
519          */
520         
521         {
522                 int saved_errno = errno; /* We might get ENOSYS */
523                 if ((result = SMB_VFS_FCHMOD_ACL(fsp, fd, mode)) == 0) {
524                         END_PROFILE(syscall_chmod);
525                         return result;
526                 }
527                 /* Error - return the old errno. */
528                 errno = saved_errno;
529         }
530
531 #if defined(HAVE_FCHMOD)
532         result = fchmod(fd, mode);
533 #else
534         result = -1;
535         errno = ENOSYS;
536 #endif
537
538         END_PROFILE(syscall_fchmod);
539         return result;
540 }
541
542 int vfswrap_chown(vfs_handle_struct *handle, connection_struct *conn, const char *path, uid_t uid, gid_t gid)
543 {
544         int result;
545
546         START_PROFILE(syscall_chown);
547         result = sys_chown(path, uid, gid);
548         END_PROFILE(syscall_chown);
549         return result;
550 }
551
552 int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid)
553 {
554 #ifdef HAVE_FCHOWN
555         int result;
556
557         START_PROFILE(syscall_fchown);
558         result = fchown(fd, uid, gid);
559         END_PROFILE(syscall_fchown);
560         return result;
561 #else
562         errno = ENOSYS;
563         return -1;
564 #endif
565 }
566
567 int vfswrap_chdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
568 {
569         int result;
570
571         START_PROFILE(syscall_chdir);
572         result = chdir(path);
573         END_PROFILE(syscall_chdir);
574         return result;
575 }
576
577 char *vfswrap_getwd(vfs_handle_struct *handle, connection_struct *conn, char *path)
578 {
579         char *result;
580
581         START_PROFILE(syscall_getwd);
582         result = sys_getwd(path);
583         END_PROFILE(syscall_getwd);
584         return result;
585 }
586
587 int vfswrap_utime(vfs_handle_struct *handle, connection_struct *conn, const char *path, struct utimbuf *times)
588 {
589         int result;
590
591         START_PROFILE(syscall_utime);
592         result = utime(path, times);
593         END_PROFILE(syscall_utime);
594         return result;
595 }
596
597 /*********************************************************************
598  A version of ftruncate that will write the space on disk if strict
599  allocate is set.
600 **********************************************************************/
601
602 static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len)
603 {
604         SMB_STRUCT_STAT st;
605         SMB_OFF_T currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
606         unsigned char zero_space[4096];
607         SMB_OFF_T space_to_write;
608
609         if (currpos == -1)
610                 return -1;
611
612         if (SMB_VFS_FSTAT(fsp, fd, &st) == -1)
613                 return -1;
614
615         space_to_write = len - st.st_size;
616
617 #ifdef S_ISFIFO
618         if (S_ISFIFO(st.st_mode))
619                 return 0;
620 #endif
621
622         if (st.st_size == len)
623                 return 0;
624
625         /* Shrink - just ftruncate. */
626         if (st.st_size > len)
627                 return sys_ftruncate(fd, len);
628
629         /* Write out the real space on disk. */
630         if (SMB_VFS_LSEEK(fsp, fd, st.st_size, SEEK_SET) != st.st_size)
631                 return -1;
632
633         space_to_write = len - st.st_size;
634
635         memset(zero_space, '\0', sizeof(zero_space));
636         while ( space_to_write > 0) {
637                 SMB_OFF_T retlen;
638                 SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write);
639
640                 retlen = SMB_VFS_WRITE(fsp,fsp->fd,(char *)zero_space,current_len_to_write);
641                 if (retlen <= 0)
642                         return -1;
643
644                 space_to_write -= retlen;
645         }
646
647         /* Seek to where we were */
648         if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos)
649                 return -1;
650
651         return 0;
652 }
653
654 int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len)
655 {
656         int result = -1;
657         SMB_STRUCT_STAT st;
658         char c = 0;
659         SMB_OFF_T currpos;
660
661         START_PROFILE(syscall_ftruncate);
662
663         if (lp_strict_allocate(SNUM(fsp->conn))) {
664                 result = strict_allocate_ftruncate(handle, fsp, fd, len);
665                 END_PROFILE(syscall_ftruncate);
666                 return result;
667         }
668
669         /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
670            sys_ftruncate if the system supports it. Then I discovered that
671            you can have some filesystems that support ftruncate
672            expansion and some that don't! On Linux fat can't do
673            ftruncate extend but ext2 can. */
674
675         result = sys_ftruncate(fd, len);
676         if (result == 0)
677                 goto done;
678
679         /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
680            extend a file with ftruncate. Provide alternate implementation
681            for this */
682         currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
683         if (currpos == -1) {
684                 goto done;
685         }
686
687         /* Do an fstat to see if the file is longer than the requested
688            size in which case the ftruncate above should have
689            succeeded or shorter, in which case seek to len - 1 and
690            write 1 byte of zero */
691         if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) {
692                 goto done;
693         }
694
695 #ifdef S_ISFIFO
696         if (S_ISFIFO(st.st_mode)) {
697                 result = 0;
698                 goto done;
699         }
700 #endif
701
702         if (st.st_size == len) {
703                 result = 0;
704                 goto done;
705         }
706
707         if (st.st_size > len) {
708                 /* the sys_ftruncate should have worked */
709                 goto done;
710         }
711
712         if (SMB_VFS_LSEEK(fsp, fd, len-1, SEEK_SET) != len -1)
713                 goto done;
714
715         if (SMB_VFS_WRITE(fsp, fd, &c, 1)!=1)
716                 goto done;
717
718         /* Seek to where we were */
719         if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos)
720                 goto done;
721         result = 0;
722
723   done:
724
725         END_PROFILE(syscall_ftruncate);
726         return result;
727 }
728
729 BOOL vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
730 {
731         BOOL result;
732
733         START_PROFILE(syscall_fcntl_lock);
734         result =  fcntl_lock(fd, op, offset, count,type);
735         END_PROFILE(syscall_fcntl_lock);
736         return result;
737 }
738
739 int vfswrap_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
740 {
741         int result;
742
743         START_PROFILE(syscall_symlink);
744         result = sys_symlink(oldpath, newpath);
745         END_PROFILE(syscall_symlink);
746         return result;
747 }
748
749 int vfswrap_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz)
750 {
751         int result;
752
753         START_PROFILE(syscall_readlink);
754         result = sys_readlink(path, buf, bufsiz);
755         END_PROFILE(syscall_readlink);
756         return result;
757 }
758
759 int vfswrap_link(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
760 {
761         int result;
762
763         START_PROFILE(syscall_link);
764         result = sys_link(oldpath, newpath);
765         END_PROFILE(syscall_link);
766         return result;
767 }
768
769 int vfswrap_mknod(vfs_handle_struct *handle, connection_struct *conn, const char *pathname, mode_t mode, SMB_DEV_T dev)
770 {
771         int result;
772
773         START_PROFILE(syscall_mknod);
774         result = sys_mknod(pathname, mode, dev);
775         END_PROFILE(syscall_mknod);
776         return result;
777 }
778
779 char *vfswrap_realpath(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *resolved_path)
780 {
781         char *result;
782
783         START_PROFILE(syscall_realpath);
784         result = sys_realpath(path, resolved_path);
785         END_PROFILE(syscall_realpath);
786         return result;
787 }
788
789 size_t vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, SEC_DESC **ppdesc)
790 {
791         size_t result;
792
793         START_PROFILE(fget_nt_acl);
794         result = get_nt_acl(fsp, security_info, ppdesc);
795         END_PROFILE(fget_nt_acl);
796         return result;
797 }
798
799 size_t vfswrap_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, SEC_DESC **ppdesc)
800 {
801         size_t result;
802
803         START_PROFILE(get_nt_acl);
804         result = get_nt_acl(fsp, security_info, ppdesc);
805         END_PROFILE(get_nt_acl);
806         return result;
807 }
808
809 BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
810 {
811         BOOL result;
812
813         START_PROFILE(fset_nt_acl);
814         result = set_nt_acl(fsp, security_info_sent, psd);
815         END_PROFILE(fset_nt_acl);
816         return result;
817 }
818
819 BOOL vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd)
820 {
821         BOOL result;
822
823         START_PROFILE(set_nt_acl);
824         result = set_nt_acl(fsp, security_info_sent, psd);
825         END_PROFILE(set_nt_acl);
826         return result;
827 }
828
829 int vfswrap_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode)
830 {
831 #ifdef HAVE_NO_ACL
832         errno = ENOSYS;
833         return -1;
834 #else
835         int result;
836
837         START_PROFILE(chmod_acl);
838         result = chmod_acl(conn, name, mode);
839         END_PROFILE(chmod_acl);
840         return result;
841 #endif
842 }
843
844 int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
845 {
846 #ifdef HAVE_NO_ACL
847         errno = ENOSYS;
848         return -1;
849 #else
850         int result;
851
852         START_PROFILE(fchmod_acl);
853         result = fchmod_acl(fsp, fd, mode);
854         END_PROFILE(fchmod_acl);
855         return result;
856 #endif
857 }
858
859 int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
860 {
861         return sys_acl_get_entry(theacl, entry_id, entry_p);
862 }
863
864 int vfswrap_sys_acl_get_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
865 {
866         return sys_acl_get_tag_type(entry_d, tag_type_p);
867 }
868
869 int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
870 {
871         return sys_acl_get_permset(entry_d, permset_p);
872 }
873
874 void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d)
875 {
876         return sys_acl_get_qualifier(entry_d);
877 }
878
879 SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle, connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type)
880 {
881         return sys_acl_get_file(path_p, type);
882 }
883
884 SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
885 {
886         return sys_acl_get_fd(fd);
887 }
888
889 int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset)
890 {
891         return sys_acl_clear_perms(permset);
892 }
893
894 int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
895 {
896         return sys_acl_add_perm(permset, perm);
897 }
898
899 char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen)
900 {
901         return sys_acl_to_text(theacl, plen);
902 }
903
904 SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle, connection_struct *conn, int count)
905 {
906         return sys_acl_init(count);
907 }
908
909 int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
910 {
911         return sys_acl_create_entry(pacl, pentry);
912 }
913
914 int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
915 {
916         return sys_acl_set_tag_type(entry, tagtype);
917 }
918
919 int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual)
920 {
921         return sys_acl_set_qualifier(entry, qual);
922 }
923
924 int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
925 {
926         return sys_acl_set_permset(entry, permset);
927 }
928
929 int vfswrap_sys_acl_valid(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl )
930 {
931         return sys_acl_valid(theacl );
932 }
933
934 int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
935 {
936         return sys_acl_set_file(name, acltype, theacl);
937 }
938
939 int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_ACL_T theacl)
940 {
941         return sys_acl_set_fd(fd, theacl);
942 }
943
944 int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, connection_struct *conn, const char *path)
945 {
946         return sys_acl_delete_def_file(path);
947 }
948
949 int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
950 {
951         return sys_acl_get_perm(permset, perm);
952 }
953
954 int vfswrap_sys_acl_free_text(vfs_handle_struct *handle, connection_struct *conn, char *text)
955 {
956         return sys_acl_free_text(text);
957 }
958
959 int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T posix_acl)
960 {
961         return sys_acl_free_acl(posix_acl);
962 }
963
964 int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle, connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype)
965 {
966         return sys_acl_free_qualifier(qualifier, tagtype);
967 }
968
969 /****************************************************************
970  Extended attribute operations.
971 *****************************************************************/
972
973 ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size)
974 {
975         return sys_getxattr(path, name, value, size);
976 }
977
978 ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size)
979 {
980         return sys_lgetxattr(path, name, value, size);
981 }
982
983 ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size)
984 {
985         return sys_fgetxattr(fd, name, value, size);
986 }
987
988 ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size)
989 {
990         return sys_listxattr(path, list, size);
991 }
992
993 ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size)
994 {
995         return sys_llistxattr(path, list, size);
996 }
997
998 ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size)
999 {
1000         return sys_flistxattr(fd, list, size);
1001 }
1002
1003 int vfswrap_removexattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
1004 {
1005         return sys_removexattr(path, name);
1006 }
1007
1008 int vfswrap_lremovexattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
1009 {
1010         return sys_lremovexattr(path, name);
1011 }
1012
1013 int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name)
1014 {
1015         return sys_fremovexattr(fd, name);
1016 }
1017
1018 int vfswrap_setxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
1019 {
1020         return sys_setxattr(path, name, value, size, flags);
1021 }
1022
1023 int vfswrap_lsetxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
1024 {
1025         return sys_lsetxattr(path, name, value, size, flags);
1026 }
1027
1028 int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags)
1029 {
1030         return sys_fsetxattr(fd, name, value, size, flags);
1031 }