s3:smbd: make struct vfs_fsp_data private to vfs.c
[ddiss/samba.git] / source3 / smbd / vfs.c
1 /*
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    VFS initialisation and support functions
5    Copyright (C) Tim Potter 1999
6    Copyright (C) Alexander Bokovoy 2002
7    Copyright (C) James Peach 2006
8    Copyright (C) Volker Lendecke 2009
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
23    This work was sponsored by Optifacio Software Services, Inc.
24 */
25
26 #include "includes.h"
27 #include "system/filesys.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "memcache.h"
31 #include "transfer_file.h"
32 #include "ntioctl.h"
33
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_VFS
36
37 static_decl_vfs;
38
39 struct vfs_fsp_data {
40     struct vfs_fsp_data *next;
41     struct vfs_handle_struct *owner;
42     void (*destroy)(void *p_data);
43     void *_dummy_;
44     /* NOTE: This structure contains four pointers so that we can guarantee
45      * that the end of the structure is always both 4-byte and 8-byte aligned.
46      */
47 };
48
49 struct vfs_init_function_entry {
50         char *name;
51         struct vfs_init_function_entry *prev, *next;
52         const struct vfs_fn_pointers *fns;
53 };
54
55 /****************************************************************************
56     maintain the list of available backends
57 ****************************************************************************/
58
59 static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
60 {
61         struct vfs_init_function_entry *entry = backends;
62
63         DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
64
65         while(entry) {
66                 if (strcmp(entry->name, name)==0) return entry;
67                 entry = entry->next;
68         }
69
70         return NULL;
71 }
72
73 NTSTATUS smb_register_vfs(int version, const char *name,
74                           const struct vfs_fn_pointers *fns)
75 {
76         struct vfs_init_function_entry *entry = backends;
77
78         if ((version != SMB_VFS_INTERFACE_VERSION)) {
79                 DEBUG(0, ("Failed to register vfs module.\n"
80                           "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
81                           "current SMB_VFS_INTERFACE_VERSION is %d.\n"
82                           "Please recompile against the current Samba Version!\n",  
83                           version, SMB_VFS_INTERFACE_VERSION));
84                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
85         }
86
87         if (!name || !name[0]) {
88                 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
89                 return NT_STATUS_INVALID_PARAMETER;
90         }
91
92         if (vfs_find_backend_entry(name)) {
93                 DEBUG(0,("VFS module %s already loaded!\n", name));
94                 return NT_STATUS_OBJECT_NAME_COLLISION;
95         }
96
97         entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
98         entry->name = smb_xstrdup(name);
99         entry->fns = fns;
100
101         DLIST_ADD(backends, entry);
102         DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
103         return NT_STATUS_OK;
104 }
105
106 /****************************************************************************
107   initialise default vfs hooks
108 ****************************************************************************/
109
110 static void vfs_init_default(connection_struct *conn)
111 {
112         DEBUG(3, ("Initialising default vfs hooks\n"));
113         vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
114 }
115
116 /****************************************************************************
117   initialise custom vfs hooks
118  ****************************************************************************/
119
120 bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
121 {
122         char *module_path = NULL;
123         char *module_name = NULL;
124         char *module_param = NULL, *p;
125         vfs_handle_struct *handle;
126         const struct vfs_init_function_entry *entry;
127
128         if (!conn||!vfs_object||!vfs_object[0]) {
129                 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
130                           "empty vfs_object!\n"));
131                 return False;
132         }
133
134         if(!backends) {
135                 static_init_vfs;
136         }
137
138         DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
139
140         module_path = smb_xstrdup(vfs_object);
141
142         p = strchr_m(module_path, ':');
143
144         if (p) {
145                 *p = 0;
146                 module_param = p+1;
147                 trim_char(module_param, ' ', ' ');
148         }
149
150         trim_char(module_path, ' ', ' ');
151
152         module_name = smb_xstrdup(module_path);
153
154         if ((module_name[0] == '/') &&
155             (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
156
157                 /*
158                  * Extract the module name from the path. Just use the base
159                  * name of the last path component.
160                  */
161
162                 SAFE_FREE(module_name);
163                 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
164
165                 p = strchr_m(module_name, '.');
166
167                 if (p != NULL) {
168                         *p = '\0';
169                 }
170         }
171
172         /* First, try to load the module with the new module system */
173         entry = vfs_find_backend_entry(module_name);
174         if (!entry) {
175                 NTSTATUS status;
176
177                 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
178                           vfs_object));
179
180                 status = smb_load_module("vfs", module_path);
181                 if (!NT_STATUS_IS_OK(status)) {
182                         DEBUG(0, ("error probing vfs module '%s': %s\n",
183                                   module_path, nt_errstr(status)));
184                         goto fail;
185                 }
186
187                 entry = vfs_find_backend_entry(module_name);
188                 if (!entry) {
189                         DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
190                         goto fail;
191                 }
192         }
193
194         DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
195
196         handle = talloc_zero(conn, vfs_handle_struct);
197         if (!handle) {
198                 DEBUG(0,("TALLOC_ZERO() failed!\n"));
199                 goto fail;
200         }
201         handle->conn = conn;
202         handle->fns = entry->fns;
203         if (module_param) {
204                 handle->param = talloc_strdup(conn, module_param);
205         }
206         DLIST_ADD(conn->vfs_handles, handle);
207
208         SAFE_FREE(module_path);
209         SAFE_FREE(module_name);
210         return True;
211
212  fail:
213         SAFE_FREE(module_path);
214         SAFE_FREE(module_name);
215         return False;
216 }
217
218 /*****************************************************************
219  Allow VFS modules to extend files_struct with VFS-specific state.
220  This will be ok for small numbers of extensions, but might need to
221  be refactored if it becomes more widely used.
222 ******************************************************************/
223
224 #define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
225
226 void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
227                                    files_struct *fsp, size_t ext_size,
228                                    void (*destroy_fn)(void *p_data))
229 {
230         struct vfs_fsp_data *ext;
231         void * ext_data;
232
233         /* Prevent VFS modules adding multiple extensions. */
234         if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
235                 return ext_data;
236         }
237
238         ext = (struct vfs_fsp_data *)TALLOC_ZERO(
239                 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
240         if (ext == NULL) {
241                 return NULL;
242         }
243
244         ext->owner = handle;
245         ext->next = fsp->vfs_extension;
246         ext->destroy = destroy_fn;
247         fsp->vfs_extension = ext;
248         return EXT_DATA_AREA(ext);
249 }
250
251 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
252 {
253         struct vfs_fsp_data *curr;
254         struct vfs_fsp_data *prev;
255
256         for (curr = fsp->vfs_extension, prev = NULL;
257              curr;
258              prev = curr, curr = curr->next) {
259                 if (curr->owner == handle) {
260                     if (prev) {
261                             prev->next = curr->next;
262                     } else {
263                             fsp->vfs_extension = curr->next;
264                     }
265                     if (curr->destroy) {
266                             curr->destroy(EXT_DATA_AREA(curr));
267                     }
268                     TALLOC_FREE(curr);
269                     return;
270                 }
271         }
272 }
273
274 void vfs_remove_all_fsp_extensions(files_struct *fsp)
275 {
276         struct vfs_fsp_data *curr;
277         struct vfs_fsp_data *prev;
278
279         for (curr = fsp->vfs_extension, prev = NULL;
280              curr;
281              prev = curr, curr = curr->next)
282         {
283                 if (prev) {
284                         prev->next = curr->next;
285                 } else {
286                         fsp->vfs_extension = curr->next;
287                 }
288                 if (curr->destroy) {
289                         curr->destroy(EXT_DATA_AREA(curr));
290                 }
291                 TALLOC_FREE(curr);
292         }
293 }
294
295 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
296 {
297         struct vfs_fsp_data *head;
298
299         for (head = fsp->vfs_extension; head; head = head->next) {
300                 if (head->owner == handle) {
301                         return head;
302                 }
303         }
304
305         return NULL;
306 }
307
308 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
309 {
310         struct vfs_fsp_data *head;
311
312         head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
313         if (head != NULL) {
314                 return EXT_DATA_AREA(head);
315         }
316
317         return NULL;
318 }
319
320 #undef EXT_DATA_AREA
321
322 /*****************************************************************
323  Generic VFS init.
324 ******************************************************************/
325
326 bool smbd_vfs_init(connection_struct *conn)
327 {
328         const char **vfs_objects;
329         unsigned int i = 0;
330         int j = 0;
331
332         /* Normal share - initialise with disk access functions */
333         vfs_init_default(conn);
334         vfs_objects = lp_vfs_objects(SNUM(conn));
335
336         /* Override VFS functions if 'vfs object' was not specified*/
337         if (!vfs_objects || !vfs_objects[0])
338                 return True;
339
340         for (i=0; vfs_objects[i] ;) {
341                 i++;
342         }
343
344         for (j=i-1; j >= 0; j--) {
345                 if (!vfs_init_custom(conn, vfs_objects[j])) {
346                         DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
347                         return False;
348                 }
349         }
350         return True;
351 }
352
353 /*******************************************************************
354  Check if a file exists in the vfs.
355 ********************************************************************/
356
357 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
358 {
359         /* Only return OK if stat was successful and S_ISREG */
360         if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
361             S_ISREG(smb_fname->st.st_ex_mode)) {
362                 return NT_STATUS_OK;
363         }
364
365         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
366 }
367
368 /****************************************************************************
369  Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
370 ****************************************************************************/
371
372 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
373 {
374         size_t total=0;
375
376         while (total < byte_count)
377         {
378                 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
379                                            byte_count - total);
380
381                 if (ret == 0) return total;
382                 if (ret == -1) {
383                         if (errno == EINTR)
384                                 continue;
385                         else
386                                 return -1;
387                 }
388                 total += ret;
389         }
390         return (ssize_t)total;
391 }
392
393 ssize_t vfs_pread_data(files_struct *fsp, char *buf,
394                 size_t byte_count, off_t offset)
395 {
396         size_t total=0;
397
398         while (total < byte_count)
399         {
400                 ssize_t ret = SMB_VFS_PREAD(fsp, buf + total,
401                                         byte_count - total, offset + total);
402
403                 if (ret == 0) return total;
404                 if (ret == -1) {
405                         if (errno == EINTR)
406                                 continue;
407                         else
408                                 return -1;
409                 }
410                 total += ret;
411         }
412         return (ssize_t)total;
413 }
414
415 /****************************************************************************
416  Write data to a fd on the vfs.
417 ****************************************************************************/
418
419 ssize_t vfs_write_data(struct smb_request *req,
420                         files_struct *fsp,
421                         const char *buffer,
422                         size_t N)
423 {
424         size_t total=0;
425         ssize_t ret;
426
427         if (req && req->unread_bytes) {
428                 SMB_ASSERT(req->unread_bytes == N);
429                 /* VFS_RECVFILE must drain the socket
430                  * before returning. */
431                 req->unread_bytes = 0;
432                 return SMB_VFS_RECVFILE(req->sconn->sock,
433                                         fsp,
434                                         (off_t)-1,
435                                         N);
436         }
437
438         while (total < N) {
439                 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
440
441                 if (ret == -1)
442                         return -1;
443                 if (ret == 0)
444                         return total;
445
446                 total += ret;
447         }
448         return (ssize_t)total;
449 }
450
451 ssize_t vfs_pwrite_data(struct smb_request *req,
452                         files_struct *fsp,
453                         const char *buffer,
454                         size_t N,
455                         off_t offset)
456 {
457         size_t total=0;
458         ssize_t ret;
459
460         if (req && req->unread_bytes) {
461                 SMB_ASSERT(req->unread_bytes == N);
462                 /* VFS_RECVFILE must drain the socket
463                  * before returning. */
464                 req->unread_bytes = 0;
465                 return SMB_VFS_RECVFILE(req->sconn->sock,
466                                         fsp,
467                                         offset,
468                                         N);
469         }
470
471         while (total < N) {
472                 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
473                                      offset + total);
474
475                 if (ret == -1)
476                         return -1;
477                 if (ret == 0)
478                         return total;
479
480                 total += ret;
481         }
482         return (ssize_t)total;
483 }
484 /****************************************************************************
485  An allocate file space call using the vfs interface.
486  Allocates space for a file from a filedescriptor.
487  Returns 0 on success, -1 on failure.
488 ****************************************************************************/
489
490 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
491 {
492         int ret;
493         connection_struct *conn = fsp->conn;
494         uint64_t space_avail;
495         uint64_t bsize,dfree,dsize;
496         NTSTATUS status;
497
498         /*
499          * Actually try and commit the space on disk....
500          */
501
502         DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
503                   fsp_str_dbg(fsp), (double)len));
504
505         if (((off_t)len) < 0) {
506                 DEBUG(0,("vfs_allocate_file_space: %s negative len "
507                          "requested.\n", fsp_str_dbg(fsp)));
508                 errno = EINVAL;
509                 return -1;
510         }
511
512         status = vfs_stat_fsp(fsp);
513         if (!NT_STATUS_IS_OK(status)) {
514                 return -1;
515         }
516
517         if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
518                 return 0;
519
520         if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
521                 /* Shrink - use ftruncate. */
522
523                 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
524                           "size %.0f\n", fsp_str_dbg(fsp),
525                           (double)fsp->fsp_name->st.st_ex_size));
526
527                 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
528
529                 flush_write_cache(fsp, SIZECHANGE_FLUSH);
530                 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
531                         set_filelen_write_cache(fsp, len);
532                 }
533
534                 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
535
536                 return ret;
537         }
538
539         if (!lp_strict_allocate(SNUM(fsp->conn)))
540                 return 0;
541
542         /* Grow - we need to test if we have enough space. */
543
544         contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
545
546         /* See if we have a syscall that will allocate beyond end-of-file
547            without changing EOF. */
548         ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
549
550         contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
551
552         if (ret == 0) {
553                 /* We changed the allocation size on disk, but not
554                    EOF - exactly as required. We're done ! */
555                 return 0;
556         }
557
558         len -= fsp->fsp_name->st.st_ex_size;
559         len /= 1024; /* Len is now number of 1k blocks needed. */
560         space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
561                                      &bsize, &dfree, &dsize);
562         if (space_avail == (uint64_t)-1) {
563                 return -1;
564         }
565
566         DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
567                   "needed blocks = %.0f, space avail = %.0f\n",
568                   fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
569                   (double)space_avail));
570
571         if (len > space_avail) {
572                 errno = ENOSPC;
573                 return -1;
574         }
575
576         return 0;
577 }
578
579 /****************************************************************************
580  A vfs set_filelen call.
581  set the length of a file from a filedescriptor.
582  Returns 0 on success, -1 on failure.
583 ****************************************************************************/
584
585 int vfs_set_filelen(files_struct *fsp, off_t len)
586 {
587         int ret;
588
589         contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
590
591         DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
592                   fsp_str_dbg(fsp), (double)len));
593         flush_write_cache(fsp, SIZECHANGE_FLUSH);
594         if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
595                 set_filelen_write_cache(fsp, len);
596                 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
597                              FILE_NOTIFY_CHANGE_SIZE
598                              | FILE_NOTIFY_CHANGE_ATTRIBUTES,
599                              fsp->fsp_name->base_name);
600         }
601
602         contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
603
604         return ret;
605 }
606
607 /****************************************************************************
608  A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
609  fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
610  as this is also called from the default SMB_VFS_FTRUNCATE code.
611  Always extends the file size.
612  Returns 0 on success, errno on failure.
613 ****************************************************************************/
614
615 #define SPARSE_BUF_WRITE_SIZE (32*1024)
616
617 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
618 {
619         ssize_t pwrite_ret;
620         size_t total = 0;
621
622         if (!sparse_buf) {
623                 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
624                 if (!sparse_buf) {
625                         errno = ENOMEM;
626                         return ENOMEM;
627                 }
628         }
629
630         while (total < len) {
631                 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
632
633                 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
634                 if (pwrite_ret == -1) {
635                         DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
636                                   "%s failed with error %s\n",
637                                   fsp_str_dbg(fsp), strerror(errno)));
638                         return errno;
639                 }
640                 total += pwrite_ret;
641         }
642
643         return 0;
644 }
645
646 /****************************************************************************
647  A vfs fill sparse call.
648  Writes zeros from the end of file to len, if len is greater than EOF.
649  Used only by strict_sync.
650  Returns 0 on success, -1 on failure.
651 ****************************************************************************/
652
653 int vfs_fill_sparse(files_struct *fsp, off_t len)
654 {
655         int ret;
656         NTSTATUS status;
657         off_t offset;
658         size_t num_to_write;
659
660         status = vfs_stat_fsp(fsp);
661         if (!NT_STATUS_IS_OK(status)) {
662                 return -1;
663         }
664
665         if (len <= fsp->fsp_name->st.st_ex_size) {
666                 return 0;
667         }
668
669 #ifdef S_ISFIFO
670         if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
671                 return 0;
672         }
673 #endif
674
675         DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
676                   "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
677                   (double)fsp->fsp_name->st.st_ex_size, (double)len,
678                   (double)(len - fsp->fsp_name->st.st_ex_size)));
679
680         contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
681
682         flush_write_cache(fsp, SIZECHANGE_FLUSH);
683
684         offset = fsp->fsp_name->st.st_ex_size;
685         num_to_write = len - fsp->fsp_name->st.st_ex_size;
686
687         /* Only do this on non-stream file handles. */
688         if (fsp->base_fsp == NULL) {
689                 /* for allocation try fallocate first. This can fail on some
690                  * platforms e.g. when the filesystem doesn't support it and no
691                  * emulation is being done by the libc (like on AIX with JFS1). In that
692                  * case we do our own emulation. fallocate implementations can
693                  * return ENOTSUP or EINVAL in cases like that. */
694                 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
695                                 offset, num_to_write);
696                 if (ret == ENOSPC) {
697                         errno = ENOSPC;
698                         ret = -1;
699                         goto out;
700                 }
701                 if (ret == 0) {
702                         goto out;
703                 }
704                 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
705                         "error %d. Falling back to slow manual allocation\n", ret));
706         }
707
708         ret = vfs_slow_fallocate(fsp, offset, num_to_write);
709         if (ret != 0) {
710                 errno = ret;
711                 ret = -1;
712         }
713
714  out:
715
716         if (ret == 0) {
717                 set_filelen_write_cache(fsp, len);
718         }
719
720         contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
721         return ret;
722 }
723
724 /****************************************************************************
725  Transfer some data (n bytes) between two file_struct's.
726 ****************************************************************************/
727
728 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
729 {
730         struct files_struct *fsp = (struct files_struct *)file;
731
732         return SMB_VFS_READ(fsp, buf, len);
733 }
734
735 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
736 {
737         struct files_struct *fsp = (struct files_struct *)file;
738
739         return SMB_VFS_WRITE(fsp, buf, len);
740 }
741
742 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
743 {
744         return transfer_file_internal((void *)in, (void *)out, n,
745                                       vfs_read_fn, vfs_write_fn);
746 }
747
748 /*******************************************************************
749  A vfs_readdir wrapper which just returns the file name.
750 ********************************************************************/
751
752 const char *vfs_readdirname(connection_struct *conn, void *p,
753                             SMB_STRUCT_STAT *sbuf, char **talloced)
754 {
755         struct dirent *ptr= NULL;
756         const char *dname;
757         char *translated;
758         NTSTATUS status;
759
760         if (!p)
761                 return(NULL);
762
763         ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
764         if (!ptr)
765                 return(NULL);
766
767         dname = ptr->d_name;
768
769
770 #ifdef NEXT2
771         if (telldir(p) < 0)
772                 return(NULL);
773 #endif
774
775 #ifdef HAVE_BROKEN_READDIR_NAME
776         /* using /usr/ucb/cc is BAD */
777         dname = dname - 2;
778 #endif
779
780         status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
781                                         talloc_tos(), &translated);
782         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
783                 *talloced = NULL;
784                 return dname;
785         }
786         *talloced = translated;
787         if (!NT_STATUS_IS_OK(status)) {
788                 return NULL;
789         }
790         return translated;
791 }
792
793 /*******************************************************************
794  A wrapper for vfs_chdir().
795 ********************************************************************/
796
797 int vfs_ChDir(connection_struct *conn, const char *path)
798 {
799         int res;
800
801         if (!LastDir) {
802                 LastDir = SMB_STRDUP("");
803         }
804
805         if (strcsequal(path,"."))
806                 return(0);
807
808         if (*path == '/' && strcsequal(LastDir,path))
809                 return(0);
810
811         DEBUG(4,("vfs_ChDir to %s\n",path));
812
813         res = SMB_VFS_CHDIR(conn,path);
814         if (!res) {
815                 SAFE_FREE(LastDir);
816                 LastDir = SMB_STRDUP(path);
817         }
818         return(res);
819 }
820
821 /*******************************************************************
822  Return the absolute current directory path - given a UNIX pathname.
823  Note that this path is returned in DOS format, not UNIX
824  format. Note this can be called with conn == NULL.
825 ********************************************************************/
826
827 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
828 {
829         char *current_dir = NULL;
830         char *result = NULL;
831         DATA_BLOB cache_value;
832         struct file_id key;
833         struct smb_filename *smb_fname_dot = NULL;
834         struct smb_filename *smb_fname_full = NULL;
835         NTSTATUS status;
836
837         if (!lp_getwd_cache()) {
838                 goto nocache;
839         }
840
841         status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
842                                             &smb_fname_dot);
843         if (!NT_STATUS_IS_OK(status)) {
844                 errno = map_errno_from_nt_status(status);
845                 goto out;
846         }
847
848         if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
849                 /*
850                  * Known to fail for root: the directory may be NFS-mounted
851                  * and exported with root_squash (so has no root access).
852                  */
853                 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
854                          "(NFS problem ?)\n", strerror(errno) ));
855                 goto nocache;
856         }
857
858         key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
859
860         if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
861                              data_blob_const(&key, sizeof(key)),
862                              &cache_value)) {
863                 goto nocache;
864         }
865
866         SMB_ASSERT((cache_value.length > 0)
867                    && (cache_value.data[cache_value.length-1] == '\0'));
868
869         status = create_synthetic_smb_fname(ctx, (char *)cache_value.data,
870                                             NULL, NULL, &smb_fname_full);
871         if (!NT_STATUS_IS_OK(status)) {
872                 errno = map_errno_from_nt_status(status);
873                 goto out;
874         }
875
876         if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
877             (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
878             (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
879             (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
880                 /*
881                  * Ok, we're done
882                  */
883                 result = talloc_strdup(ctx, smb_fname_full->base_name);
884                 if (result == NULL) {
885                         errno = ENOMEM;
886                 }
887                 goto out;
888         }
889
890  nocache:
891
892         /*
893          * We don't have the information to hand so rely on traditional
894          * methods. The very slow getcwd, which spawns a process on some
895          * systems, or the not quite so bad getwd.
896          */
897
898         current_dir = SMB_VFS_GETWD(conn);
899         if (current_dir == NULL) {
900                 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
901                           strerror(errno)));
902                 goto out;
903         }
904
905         if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
906                 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
907
908                 memcache_add(smbd_memcache(), GETWD_CACHE,
909                              data_blob_const(&key, sizeof(key)),
910                              data_blob_const(current_dir,
911                                                 strlen(current_dir)+1));
912         }
913
914         result = talloc_strdup(ctx, current_dir);
915         if (result == NULL) {
916                 errno = ENOMEM;
917         }
918
919  out:
920         TALLOC_FREE(smb_fname_dot);
921         TALLOC_FREE(smb_fname_full);
922         SAFE_FREE(current_dir);
923         return result;
924 }
925
926 /*******************************************************************
927  Reduce a file name, removing .. elements and checking that
928  it is below dir in the heirachy. This uses realpath.
929  This function must run as root, and will return names
930  and valid stat structs that can be checked on open.
931 ********************************************************************/
932
933 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
934                         const char *fname,
935                         struct smb_request *smbreq)
936 {
937         NTSTATUS status;
938         TALLOC_CTX *ctx = talloc_tos();
939         const char *conn_rootdir;
940         size_t rootdir_len;
941         char *dir_name = NULL;
942         const char *last_component = NULL;
943         char *resolved_name = NULL;
944         char *saved_dir = NULL;
945         struct smb_filename *smb_fname_cwd = NULL;
946         struct privilege_paths *priv_paths = NULL;
947         int ret;
948
949         DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
950                         fname,
951                         conn->connectpath));
952
953
954         priv_paths = talloc_zero(smbreq, struct privilege_paths);
955         if (!priv_paths) {
956                 status = NT_STATUS_NO_MEMORY;
957                 goto err;
958         }
959
960         if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
961                 status = NT_STATUS_NO_MEMORY;
962                 goto err;
963         }
964
965         priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
966         priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
967
968         if (priv_paths->parent_name.base_name == NULL ||
969                         priv_paths->file_name.base_name == NULL) {
970                 status = NT_STATUS_NO_MEMORY;
971                 goto err;
972         }
973
974         if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
975                 status = map_nt_error_from_unix(errno);
976                 goto err;
977         }
978         /* Remember where we were. */
979         saved_dir = vfs_GetWd(ctx, conn);
980         if (!saved_dir) {
981                 status = map_nt_error_from_unix(errno);
982                 goto err;
983         }
984
985         /* Go to the parent directory to lock in memory. */
986         if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
987                 status = map_nt_error_from_unix(errno);
988                 goto err;
989         }
990
991         /* Get the absolute path of the parent directory. */
992         resolved_name = SMB_VFS_REALPATH(conn,".");
993         if (!resolved_name) {
994                 status = map_nt_error_from_unix(errno);
995                 goto err;
996         }
997
998         if (*resolved_name != '/') {
999                 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1000                         "doesn't return absolute paths !\n"));
1001                 status = NT_STATUS_OBJECT_NAME_INVALID;
1002                 goto err;
1003         }
1004
1005         DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1006                 priv_paths->parent_name.base_name,
1007                 resolved_name));
1008
1009         /* Now check the stat value is the same. */
1010         status = create_synthetic_smb_fname(talloc_tos(), ".",
1011                                         NULL, NULL,
1012                                         &smb_fname_cwd);
1013         if (!NT_STATUS_IS_OK(status)) {
1014                 goto err;
1015         }
1016
1017         if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1018                 status = map_nt_error_from_unix(errno);
1019                 goto err;
1020         }
1021
1022         /* Ensure we're pointing at the same place. */
1023         if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1024                 DEBUG(0,("check_reduced_name_with_privilege: "
1025                         "device/inode/uid/gid on directory %s changed. "
1026                         "Denying access !\n",
1027                         priv_paths->parent_name.base_name));
1028                 status = NT_STATUS_ACCESS_DENIED;
1029                 goto err;
1030         }
1031
1032         /* Ensure we're below the connect path. */
1033
1034         conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1035         if (conn_rootdir == NULL) {
1036                 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1037                         "conn_rootdir\n"));
1038                 status = NT_STATUS_ACCESS_DENIED;
1039                 goto err;
1040         }
1041
1042         rootdir_len = strlen(conn_rootdir);
1043         if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1044                 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1045                         "attempt: %s is a symlink outside the "
1046                         "share path\n",
1047                         dir_name));
1048                 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1049                 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1050                 status = NT_STATUS_ACCESS_DENIED;
1051                 goto err;
1052         }
1053
1054         /* Now ensure that the last component either doesn't
1055            exist, or is *NOT* a symlink. */
1056
1057         ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1058         if (ret == -1) {
1059                 /* Errno must be ENOENT for this be ok. */
1060                 if (errno != ENOENT) {
1061                         status = map_nt_error_from_unix(errno);
1062                         DEBUG(2, ("check_reduced_name_with_privilege: "
1063                                 "LSTAT on %s failed with %s\n",
1064                                 priv_paths->file_name.base_name,
1065                                 nt_errstr(status)));
1066                         goto err;
1067                 }
1068         }
1069
1070         if (VALID_STAT(priv_paths->file_name.st) &&
1071                         S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1072                 DEBUG(2, ("check_reduced_name_with_privilege: "
1073                         "Last component %s is a symlink. Denying"
1074                         "access.\n",
1075                         priv_paths->file_name.base_name));
1076                 status = NT_STATUS_ACCESS_DENIED;
1077                 goto err;
1078         }
1079
1080         smbreq->priv_paths = priv_paths;
1081         status = NT_STATUS_OK;
1082
1083   err:
1084
1085         if (saved_dir) {
1086                 vfs_ChDir(conn, saved_dir);
1087         }
1088         SAFE_FREE(resolved_name);
1089         if (!NT_STATUS_IS_OK(status)) {
1090                 TALLOC_FREE(priv_paths);
1091         }
1092         return status;
1093 }
1094
1095 /*******************************************************************
1096  Reduce a file name, removing .. elements and checking that
1097  it is below dir in the heirachy. This uses realpath.
1098 ********************************************************************/
1099
1100 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1101 {
1102         char *resolved_name = NULL;
1103         bool allow_symlinks = true;
1104         bool allow_widelinks = false;
1105
1106         DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1107
1108         resolved_name = SMB_VFS_REALPATH(conn,fname);
1109
1110         if (!resolved_name) {
1111                 switch (errno) {
1112                         case ENOTDIR:
1113                                 DEBUG(3,("check_reduced_name: Component not a "
1114                                          "directory in getting realpath for "
1115                                          "%s\n", fname));
1116                                 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1117                         case ENOENT:
1118                         {
1119                                 TALLOC_CTX *ctx = talloc_tos();
1120                                 char *dir_name = NULL;
1121                                 const char *last_component = NULL;
1122                                 char *new_name = NULL;
1123                                 int ret;
1124
1125                                 /* Last component didn't exist.
1126                                    Remove it and try and canonicalise
1127                                    the directory name. */
1128                                 if (!parent_dirname(ctx, fname,
1129                                                 &dir_name,
1130                                                 &last_component)) {
1131                                         return NT_STATUS_NO_MEMORY;
1132                                 }
1133
1134                                 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1135                                 if (!resolved_name) {
1136                                         NTSTATUS status = map_nt_error_from_unix(errno);
1137
1138                                         if (errno == ENOENT || errno == ENOTDIR) {
1139                                                 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1140                                         }
1141
1142                                         DEBUG(3,("check_reduce_name: "
1143                                                  "couldn't get realpath for "
1144                                                  "%s (%s)\n",
1145                                                 fname,
1146                                                 nt_errstr(status)));
1147                                         return status;
1148                                 }
1149                                 ret = asprintf(&new_name, "%s/%s",
1150                                                resolved_name, last_component);
1151                                 SAFE_FREE(resolved_name);
1152                                 if (ret == -1) {
1153                                         return NT_STATUS_NO_MEMORY;
1154                                 }
1155                                 resolved_name = new_name;
1156                                 break;
1157                         }
1158                         default:
1159                                 DEBUG(3,("check_reduced_name: couldn't get "
1160                                          "realpath for %s\n", fname));
1161                                 return map_nt_error_from_unix(errno);
1162                 }
1163         }
1164
1165         DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1166                   resolved_name));
1167
1168         if (*resolved_name != '/') {
1169                 DEBUG(0,("check_reduced_name: realpath doesn't return "
1170                          "absolute paths !\n"));
1171                 SAFE_FREE(resolved_name);
1172                 return NT_STATUS_OBJECT_NAME_INVALID;
1173         }
1174
1175         allow_widelinks = lp_widelinks(SNUM(conn));
1176         allow_symlinks = lp_symlinks(SNUM(conn));
1177
1178         /* Common widelinks and symlinks checks. */
1179         if (!allow_widelinks || !allow_symlinks) {
1180                 const char *conn_rootdir;
1181                 size_t rootdir_len;
1182
1183                 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1184                 if (conn_rootdir == NULL) {
1185                         DEBUG(2, ("check_reduced_name: Could not get "
1186                                 "conn_rootdir\n"));
1187                         SAFE_FREE(resolved_name);
1188                         return NT_STATUS_ACCESS_DENIED;
1189                 }
1190
1191                 rootdir_len = strlen(conn_rootdir);
1192                 if (strncmp(conn_rootdir, resolved_name,
1193                                 rootdir_len) != 0) {
1194                         DEBUG(2, ("check_reduced_name: Bad access "
1195                                 "attempt: %s is a symlink outside the "
1196                                 "share path\n", fname));
1197                         DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1198                         DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1199                         SAFE_FREE(resolved_name);
1200                         return NT_STATUS_ACCESS_DENIED;
1201                 }
1202
1203                 /* Extra checks if all symlinks are disallowed. */
1204                 if (!allow_symlinks) {
1205                         /* fname can't have changed in resolved_path. */
1206                         const char *p = &resolved_name[rootdir_len];
1207
1208                         /* *p can be '\0' if fname was "." */
1209                         if (*p == '\0' && ISDOT(fname)) {
1210                                 goto out;
1211                         }
1212
1213                         if (*p != '/') {
1214                                 DEBUG(2, ("check_reduced_name: logic error (%c) "
1215                                         "in resolved_name: %s\n",
1216                                         *p,
1217                                         fname));
1218                                 SAFE_FREE(resolved_name);
1219                                 return NT_STATUS_ACCESS_DENIED;
1220                         }
1221
1222                         p++;
1223                         if (strcmp(fname, p)!=0) {
1224                                 DEBUG(2, ("check_reduced_name: Bad access "
1225                                         "attempt: %s is a symlink\n",
1226                                         fname));
1227                                 SAFE_FREE(resolved_name);
1228                                 return NT_STATUS_ACCESS_DENIED;
1229                         }
1230                 }
1231         }
1232
1233   out:
1234
1235         DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1236                  resolved_name));
1237         SAFE_FREE(resolved_name);
1238         return NT_STATUS_OK;
1239 }
1240
1241 /**
1242  * XXX: This is temporary and there should be no callers of this once
1243  * smb_filename is plumbed through all path based operations.
1244  */
1245 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1246                        SMB_STRUCT_STAT *psbuf)
1247 {
1248         struct smb_filename *smb_fname = NULL;
1249         NTSTATUS status;
1250         int ret;
1251
1252         status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1253                                                   &smb_fname);
1254         if (!NT_STATUS_IS_OK(status)) {
1255                 errno = map_errno_from_nt_status(status);
1256                 return -1;
1257         }
1258
1259         if (lp_posix_pathnames()) {
1260                 ret = SMB_VFS_LSTAT(conn, smb_fname);
1261         } else {
1262                 ret = SMB_VFS_STAT(conn, smb_fname);
1263         }
1264
1265         if (ret != -1) {
1266                 *psbuf = smb_fname->st;
1267         }
1268
1269         TALLOC_FREE(smb_fname);
1270         return ret;
1271 }
1272
1273 /**
1274  * XXX: This is temporary and there should be no callers of this once
1275  * smb_filename is plumbed through all path based operations.
1276  */
1277 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1278                         SMB_STRUCT_STAT *psbuf)
1279 {
1280         struct smb_filename *smb_fname = NULL;
1281         NTSTATUS status;
1282         int ret;
1283
1284         status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1285                                                   &smb_fname);
1286         if (!NT_STATUS_IS_OK(status)) {
1287                 errno = map_errno_from_nt_status(status);
1288                 return -1;
1289         }
1290
1291         ret = SMB_VFS_LSTAT(conn, smb_fname);
1292         if (ret != -1) {
1293                 *psbuf = smb_fname->st;
1294         }
1295
1296         TALLOC_FREE(smb_fname);
1297         return ret;
1298 }
1299
1300 /**
1301  * Ensure LSTAT is called for POSIX paths.
1302  */
1303
1304 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1305 {
1306         int ret;
1307
1308         if(fsp->fh->fd == -1) {
1309                 if (fsp->posix_open) {
1310                         ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1311                 } else {
1312                         ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1313                 }
1314                 if (ret == -1) {
1315                         return map_nt_error_from_unix(errno);
1316                 }
1317         } else {
1318                 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1319                         return map_nt_error_from_unix(errno);
1320                 }
1321         }
1322         return NT_STATUS_OK;
1323 }
1324
1325 /**
1326  * Initialize num_streams and streams, then call VFS op streaminfo
1327  */
1328 NTSTATUS vfs_streaminfo(connection_struct *conn,
1329                         struct files_struct *fsp,
1330                         const char *fname,
1331                         TALLOC_CTX *mem_ctx,
1332                         unsigned int *num_streams,
1333                         struct stream_struct **streams)
1334 {
1335         *num_streams = 0;
1336         *streams = NULL;
1337         return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1338 }
1339
1340 /*
1341   generate a file_id from a stat structure
1342  */
1343 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1344 {
1345         return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1346 }
1347
1348 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1349                          const char *service, const char *user)
1350 {
1351         VFS_FIND(connect);
1352         return handle->fns->connect_fn(handle, service, user);
1353 }
1354
1355 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1356 {
1357         VFS_FIND(disconnect);
1358         handle->fns->disconnect_fn(handle);
1359 }
1360
1361 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1362                                 const char *path, bool small_query,
1363                                 uint64_t *bsize, uint64_t *dfree,
1364                                 uint64_t *dsize)
1365 {
1366         VFS_FIND(disk_free);
1367         return handle->fns->disk_free_fn(handle, path, small_query, bsize, 
1368                                          dfree, dsize);
1369 }
1370
1371 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1372                            enum SMB_QUOTA_TYPE qtype, unid_t id,
1373                            SMB_DISK_QUOTA *qt)
1374 {
1375         VFS_FIND(get_quota);
1376         return handle->fns->get_quota_fn(handle, qtype, id, qt);
1377 }
1378
1379 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1380                            enum SMB_QUOTA_TYPE qtype, unid_t id,
1381                            SMB_DISK_QUOTA *qt)
1382 {
1383         VFS_FIND(set_quota);
1384         return handle->fns->set_quota_fn(handle, qtype, id, qt);
1385 }
1386
1387 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1388                                       struct files_struct *fsp,
1389                                       struct shadow_copy_data *shadow_copy_data,
1390                                       bool labels)
1391 {
1392         VFS_FIND(get_shadow_copy_data);
1393         return handle->fns->get_shadow_copy_data_fn(handle, fsp, 
1394                                                     shadow_copy_data,
1395                                                     labels);
1396 }
1397 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1398                          struct vfs_statvfs_struct *statbuf)
1399 {
1400         VFS_FIND(statvfs);
1401         return handle->fns->statvfs_fn(handle, path, statbuf);
1402 }
1403
1404 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1405                         enum timestamp_set_resolution *p_ts_res)
1406 {
1407         VFS_FIND(fs_capabilities);
1408         return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1409 }
1410
1411 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1412                                         struct dfs_GetDFSReferral *r)
1413 {
1414         VFS_FIND(get_dfs_referrals);
1415         return handle->fns->get_dfs_referrals_fn(handle, r);
1416 }
1417
1418 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1419                                      const char *fname, const char *mask,
1420                                      uint32 attributes)
1421 {
1422         VFS_FIND(opendir);
1423         return handle->fns->opendir_fn(handle, fname, mask, attributes);
1424 }
1425
1426 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1427                                         struct files_struct *fsp,
1428                                         const char *mask,
1429                                         uint32 attributes)
1430 {
1431         VFS_FIND(fdopendir);
1432         return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1433 }
1434
1435 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1436                                               DIR *dirp,
1437                                               SMB_STRUCT_STAT *sbuf)
1438 {
1439         VFS_FIND(readdir);
1440         return handle->fns->readdir_fn(handle, dirp, sbuf);
1441 }
1442
1443 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1444                           DIR *dirp, long offset)
1445 {
1446         VFS_FIND(seekdir);
1447         handle->fns->seekdir_fn(handle, dirp, offset);
1448 }
1449
1450 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1451                           DIR *dirp)
1452 {
1453         VFS_FIND(telldir);
1454         return handle->fns->telldir_fn(handle, dirp);
1455 }
1456
1457 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1458                              DIR *dirp)
1459 {
1460         VFS_FIND(rewind_dir);
1461         handle->fns->rewind_dir_fn(handle, dirp);
1462 }
1463
1464 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1465                        mode_t mode)
1466 {
1467         VFS_FIND(mkdir);
1468         return handle->fns->mkdir_fn(handle, path, mode);
1469 }
1470
1471 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1472 {
1473         VFS_FIND(rmdir);
1474         return handle->fns->rmdir_fn(handle, path);
1475 }
1476
1477 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1478                           DIR *dir)
1479 {
1480         VFS_FIND(closedir);
1481         return handle->fns->closedir_fn(handle, dir);
1482 }
1483
1484 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1485                                  DIR *dirp)
1486 {
1487         VFS_FIND(init_search_op);
1488         handle->fns->init_search_op_fn(handle, dirp);
1489 }
1490
1491 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1492                       struct smb_filename *smb_fname, struct files_struct *fsp,
1493                       int flags, mode_t mode)
1494 {
1495         VFS_FIND(open);
1496         return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1497 }
1498
1499 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1500                                   struct smb_request *req,
1501                                   uint16_t root_dir_fid,
1502                                   struct smb_filename *smb_fname,
1503                                   uint32_t access_mask,
1504                                   uint32_t share_access,
1505                                   uint32_t create_disposition,
1506                                   uint32_t create_options,
1507                                   uint32_t file_attributes,
1508                                   uint32_t oplock_request,
1509                                   uint64_t allocation_size,
1510                                   uint32_t private_flags,
1511                                   struct security_descriptor *sd,
1512                                   struct ea_list *ea_list,
1513                                   files_struct **result,
1514                                   int *pinfo)
1515 {
1516         VFS_FIND(create_file);
1517         return handle->fns->create_file_fn(
1518                 handle, req, root_dir_fid, smb_fname, access_mask,
1519                 share_access, create_disposition, create_options,
1520                 file_attributes, oplock_request, allocation_size,
1521                 private_flags, sd, ea_list,
1522                 result, pinfo);
1523 }
1524
1525 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1526                        struct files_struct *fsp)
1527 {
1528         VFS_FIND(close);
1529         return handle->fns->close_fn(handle, fsp);
1530 }
1531
1532 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1533                           struct files_struct *fsp, void *data, size_t n)
1534 {
1535         VFS_FIND(read);
1536         return handle->fns->read_fn(handle, fsp, data, n);
1537 }
1538
1539 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1540                            struct files_struct *fsp, void *data, size_t n,
1541                            off_t offset)
1542 {
1543         VFS_FIND(pread);
1544         return handle->fns->pread_fn(handle, fsp, data, n, offset);
1545 }
1546
1547 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1548                            struct files_struct *fsp, const void *data,
1549                            size_t n)
1550 {
1551         VFS_FIND(write);
1552         return handle->fns->write_fn(handle, fsp, data, n);
1553 }
1554
1555 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1556                             struct files_struct *fsp, const void *data,
1557                             size_t n, off_t offset)
1558 {
1559         VFS_FIND(pwrite);
1560         return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1561 }
1562
1563 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1564                              struct files_struct *fsp, off_t offset,
1565                              int whence)
1566 {
1567         VFS_FIND(lseek);
1568         return handle->fns->lseek_fn(handle, fsp, offset, whence);
1569 }
1570
1571 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1572                               files_struct *fromfsp, const DATA_BLOB *header,
1573                               off_t offset, size_t count)
1574 {
1575         VFS_FIND(sendfile);
1576         return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1577                                         count);
1578 }
1579
1580 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1581                               files_struct *tofsp, off_t offset,
1582                               size_t count)
1583 {
1584         VFS_FIND(recvfile);
1585         return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1586 }
1587
1588 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1589                         const struct smb_filename *smb_fname_src,
1590                         const struct smb_filename *smb_fname_dst)
1591 {
1592         VFS_FIND(rename);
1593         return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1594 }
1595
1596 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1597                        struct files_struct *fsp)
1598 {
1599         VFS_FIND(fsync);
1600         return handle->fns->fsync_fn(handle, fsp);
1601 }
1602
1603 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1604                       struct smb_filename *smb_fname)
1605 {
1606         VFS_FIND(stat);
1607         return handle->fns->stat_fn(handle, smb_fname);
1608 }
1609
1610 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1611                        struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1612 {
1613         VFS_FIND(fstat);
1614         return handle->fns->fstat_fn(handle, fsp, sbuf);
1615 }
1616
1617 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1618                        struct smb_filename *smb_filename)
1619 {
1620         VFS_FIND(lstat);
1621         return handle->fns->lstat_fn(handle, smb_filename);
1622 }
1623
1624 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1625                                      struct files_struct *fsp,
1626                                      const SMB_STRUCT_STAT *sbuf)
1627 {
1628         VFS_FIND(get_alloc_size);
1629         return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1630 }
1631
1632 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1633                         const struct smb_filename *smb_fname)
1634 {
1635         VFS_FIND(unlink);
1636         return handle->fns->unlink_fn(handle, smb_fname);
1637 }
1638
1639 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1640                        mode_t mode)
1641 {
1642         VFS_FIND(chmod);
1643         return handle->fns->chmod_fn(handle, path, mode);
1644 }
1645
1646 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1647                         struct files_struct *fsp, mode_t mode)
1648 {
1649         VFS_FIND(fchmod);
1650         return handle->fns->fchmod_fn(handle, fsp, mode);
1651 }
1652
1653 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1654                        uid_t uid, gid_t gid)
1655 {
1656         VFS_FIND(chown);
1657         return handle->fns->chown_fn(handle, path, uid, gid);
1658 }
1659
1660 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1661                         struct files_struct *fsp, uid_t uid, gid_t gid)
1662 {
1663         VFS_FIND(fchown);
1664         return handle->fns->fchown_fn(handle, fsp, uid, gid);
1665 }
1666
1667 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1668                         uid_t uid, gid_t gid)
1669 {
1670         VFS_FIND(lchown);
1671         return handle->fns->lchown_fn(handle, path, uid, gid);
1672 }
1673
1674 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1675 {
1676         int ret;
1677         bool as_root = false;
1678         const char *path;
1679         char *saved_dir = NULL;
1680         char *parent_dir = NULL;
1681         NTSTATUS status;
1682
1683         if (fsp->fh->fd != -1) {
1684                 /* Try fchown. */
1685                 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1686                 if (ret == 0) {
1687                         return NT_STATUS_OK;
1688                 }
1689                 if (ret == -1 && errno != ENOSYS) {
1690                         return map_nt_error_from_unix(errno);
1691                 }
1692         }
1693
1694         as_root = (geteuid() == 0);
1695
1696         if (as_root) {
1697                 /*
1698                  * We are being asked to chown as root. Make
1699                  * sure we chdir() into the path to pin it,
1700                  * and always act using lchown to ensure we
1701                  * don't deref any symbolic links.
1702                  */
1703                 const char *final_component = NULL;
1704                 struct smb_filename local_fname;
1705
1706                 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1707                 if (!saved_dir) {
1708                         status = map_nt_error_from_unix(errno);
1709                         DEBUG(0,("vfs_chown_fsp: failed to get "
1710                                 "current working directory. Error was %s\n",
1711                                 strerror(errno)));
1712                         return status;
1713                 }
1714
1715                 if (!parent_dirname(talloc_tos(),
1716                                 fsp->fsp_name->base_name,
1717                                 &parent_dir,
1718                                 &final_component)) {
1719                         return NT_STATUS_NO_MEMORY;
1720                 }
1721
1722                 /* cd into the parent dir to pin it. */
1723                 ret = vfs_ChDir(fsp->conn, parent_dir);
1724                 if (ret == -1) {
1725                         return map_nt_error_from_unix(errno);
1726                 }
1727
1728                 ZERO_STRUCT(local_fname);
1729                 local_fname.base_name = discard_const_p(char, final_component);
1730
1731                 /* Must use lstat here. */
1732                 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1733                 if (ret == -1) {
1734                         status = map_nt_error_from_unix(errno);
1735                         goto out;
1736                 }
1737
1738                 /* Ensure it matches the fsp stat. */
1739                 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1740                         status = NT_STATUS_ACCESS_DENIED;
1741                         goto out;
1742                 }
1743                 path = final_component;
1744         } else {
1745                 path = fsp->fsp_name->base_name;
1746         }
1747
1748         if (fsp->posix_open || as_root) {
1749                 ret = SMB_VFS_LCHOWN(fsp->conn,
1750                         path,
1751                         uid, gid);
1752         } else {
1753                 ret = SMB_VFS_CHOWN(fsp->conn,
1754                         path,
1755                         uid, gid);
1756         }
1757
1758         if (ret == 0) {
1759                 status = NT_STATUS_OK;
1760         } else {
1761                 status = map_nt_error_from_unix(errno);
1762         }
1763
1764   out:
1765
1766         if (as_root) {
1767                 vfs_ChDir(fsp->conn,saved_dir);
1768                 TALLOC_FREE(saved_dir);
1769                 TALLOC_FREE(parent_dir);
1770         }
1771         return status;
1772 }
1773
1774 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1775 {
1776         VFS_FIND(chdir);
1777         return handle->fns->chdir_fn(handle, path);
1778 }
1779
1780 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1781 {
1782         VFS_FIND(getwd);
1783         return handle->fns->getwd_fn(handle);
1784 }
1785
1786 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1787                         const struct smb_filename *smb_fname,
1788                         struct smb_file_time *ft)
1789 {
1790         VFS_FIND(ntimes);
1791         return handle->fns->ntimes_fn(handle, smb_fname, ft);
1792 }
1793
1794 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1795                            struct files_struct *fsp, off_t offset)
1796 {
1797         VFS_FIND(ftruncate);
1798         return handle->fns->ftruncate_fn(handle, fsp, offset);
1799 }
1800
1801 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1802                                 struct files_struct *fsp,
1803                                 enum vfs_fallocate_mode mode,
1804                                 off_t offset,
1805                                 off_t len)
1806 {
1807         VFS_FIND(fallocate);
1808         return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
1809 }
1810
1811 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
1812                               struct files_struct *fsp, uint32 share_mode,
1813                               uint32_t access_mask)
1814 {
1815         VFS_FIND(kernel_flock);
1816         return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
1817                                          access_mask);
1818 }
1819
1820 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
1821                                 struct files_struct *fsp, int leasetype)
1822 {
1823         VFS_FIND(linux_setlease);
1824         return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
1825 }
1826
1827 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
1828                          const char *newpath)
1829 {
1830         VFS_FIND(symlink);
1831         return handle->fns->symlink_fn(handle, oldpath, newpath);
1832 }
1833
1834 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
1835                               const char *path, char *buf, size_t bufsiz)
1836 {
1837         VFS_FIND(readlink);
1838         return handle->fns->readlink_fn(handle, path, buf, bufsiz);
1839 }
1840
1841 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
1842                       const char *newpath)
1843 {
1844         VFS_FIND(link);
1845         return handle->fns->link_fn(handle, oldpath, newpath);
1846 }
1847
1848 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
1849                        mode_t mode, SMB_DEV_T dev)
1850 {
1851         VFS_FIND(mknod);
1852         return handle->fns->mknod_fn(handle, path, mode, dev);
1853 }
1854
1855 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
1856 {
1857         VFS_FIND(realpath);
1858         return handle->fns->realpath_fn(handle, path);
1859 }
1860
1861 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
1862                                    struct sys_notify_context *ctx,
1863                                    const char *path,
1864                                    uint32_t *filter,
1865                                    uint32_t *subdir_filter,
1866                                    void (*callback)(struct sys_notify_context *ctx,
1867                                                     void *private_data,
1868                                                     struct notify_event *ev),
1869                                    void *private_data, void *handle_p)
1870 {
1871         VFS_FIND(notify_watch);
1872         return handle->fns->notify_watch_fn(handle, ctx, path,
1873                                             filter, subdir_filter, callback,
1874                                             private_data, handle_p);
1875 }
1876
1877 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
1878                          unsigned int flags)
1879 {
1880         VFS_FIND(chflags);
1881         return handle->fns->chflags_fn(handle, path, flags);
1882 }
1883
1884 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
1885                                            const SMB_STRUCT_STAT *sbuf)
1886 {
1887         VFS_FIND(file_id_create);
1888         return handle->fns->file_id_create_fn(handle, sbuf);
1889 }
1890
1891 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
1892                                  struct files_struct *fsp,
1893                                  const char *fname,
1894                                  TALLOC_CTX *mem_ctx,
1895                                  unsigned int *num_streams,
1896                                  struct stream_struct **streams)
1897 {
1898         VFS_FIND(streaminfo);
1899         return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
1900                                           num_streams, streams);
1901 }
1902
1903 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
1904                                    const char *path, const char *name,
1905                                    TALLOC_CTX *mem_ctx, char **found_name)
1906 {
1907         VFS_FIND(get_real_filename);
1908         return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
1909                                                  found_name);
1910 }
1911
1912 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
1913                                      const char *filename)
1914 {
1915         VFS_FIND(connectpath);
1916         return handle->fns->connectpath_fn(handle, filename);
1917 }
1918
1919 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
1920                               struct files_struct *fsp,
1921                               struct lock_struct *plock)
1922 {
1923         VFS_FIND(strict_lock);
1924         return handle->fns->strict_lock_fn(handle, fsp, plock);
1925 }
1926
1927 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
1928                                 struct files_struct *fsp,
1929                                 struct lock_struct *plock)
1930 {
1931         VFS_FIND(strict_unlock);
1932         handle->fns->strict_unlock_fn(handle, fsp, plock);
1933 }
1934
1935 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
1936                                      const char *name,
1937                                      enum vfs_translate_direction direction,
1938                                      TALLOC_CTX *mem_ctx,
1939                                      char **mapped_name)
1940 {
1941         VFS_FIND(translate_name);
1942         return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
1943                                               mapped_name);
1944 }
1945
1946 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
1947                             struct files_struct *fsp,
1948                             TALLOC_CTX *ctx,
1949                             uint32_t function,
1950                             uint16_t req_flags,
1951                             const uint8_t *in_data,
1952                             uint32_t in_len,
1953                             uint8_t **out_data,
1954                             uint32_t max_out_len,
1955                             uint32_t *out_len)
1956 {
1957         VFS_FIND(fsctl);
1958         return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags, 
1959                                      in_data, in_len, out_data, max_out_len, 
1960                                      out_len);
1961 }
1962
1963 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
1964                                   struct files_struct *fsp,
1965                                   uint32 security_info,
1966                                   struct security_descriptor **ppdesc)
1967 {
1968         VFS_FIND(fget_nt_acl);
1969         return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
1970                                            ppdesc);
1971 }
1972
1973 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
1974                                  const char *name,
1975                                  uint32 security_info,
1976                                  struct security_descriptor **ppdesc)
1977 {
1978         VFS_FIND(get_nt_acl);
1979         return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc);
1980 }
1981
1982 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
1983                                   struct files_struct *fsp,
1984                                   uint32 security_info_sent,
1985                                   const struct security_descriptor *psd)
1986 {
1987         VFS_FIND(fset_nt_acl);
1988         return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent, 
1989                                            psd);
1990 }
1991
1992 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
1993                                  struct smb_filename *file,
1994                                  struct security_acl *sacl,
1995                                  uint32_t access_requested,
1996                                  uint32_t access_denied)
1997 {
1998         VFS_FIND(audit_file);
1999         return handle->fns->audit_file_fn(handle, 
2000                                           file, 
2001                                           sacl, 
2002                                           access_requested, 
2003                                           access_denied);
2004 }
2005
2006 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2007                            mode_t mode)
2008 {
2009         VFS_FIND(chmod_acl);
2010         return handle->fns->chmod_acl_fn(handle, name, mode);
2011 }
2012
2013 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2014                             struct files_struct *fsp, mode_t mode)
2015 {
2016         VFS_FIND(fchmod_acl);
2017         return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2018 }
2019
2020 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct *handle,
2021                                    SMB_ACL_T theacl, int entry_id,
2022                                    SMB_ACL_ENTRY_T *entry_p)
2023 {
2024         VFS_FIND(sys_acl_get_entry);
2025         return handle->fns->sys_acl_get_entry_fn(handle, theacl, entry_id,
2026                                                  entry_p);
2027 }
2028
2029 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct *handle,
2030                                       SMB_ACL_ENTRY_T entry_d,
2031                                       SMB_ACL_TAG_T *tag_type_p)
2032 {
2033         VFS_FIND(sys_acl_get_tag_type);
2034         return handle->fns->sys_acl_get_tag_type_fn(handle, entry_d, 
2035                                                     tag_type_p);
2036 }
2037
2038 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct *handle,
2039                                      SMB_ACL_ENTRY_T entry_d,
2040                                      SMB_ACL_PERMSET_T *permset_p)
2041 {
2042         VFS_FIND(sys_acl_get_permset);
2043         return handle->fns->sys_acl_get_permset_fn(handle, entry_d, permset_p);
2044 }
2045
2046 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct *handle,
2047                                           SMB_ACL_ENTRY_T entry_d)
2048 {
2049         VFS_FIND(sys_acl_get_qualifier);
2050         return handle->fns->sys_acl_get_qualifier_fn(handle, entry_d);
2051 }
2052
2053 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2054                                         const char *path_p,
2055                                         SMB_ACL_TYPE_T type)
2056 {
2057         VFS_FIND(sys_acl_get_file);
2058         return handle->fns->sys_acl_get_file_fn(handle, path_p, type);
2059 }
2060
2061 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2062                                       struct files_struct *fsp)
2063 {
2064         VFS_FIND(sys_acl_get_fd);
2065         return handle->fns->sys_acl_get_fd_fn(handle, fsp);
2066 }
2067
2068 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct *handle,
2069                                      SMB_ACL_PERMSET_T permset)
2070 {
2071         VFS_FIND(sys_acl_clear_perms);
2072         return handle->fns->sys_acl_clear_perms_fn(handle, permset);
2073 }
2074
2075 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct *handle,
2076                                   SMB_ACL_PERMSET_T permset,
2077                                   SMB_ACL_PERM_T perm)
2078 {
2079         VFS_FIND(sys_acl_add_perm);
2080         return handle->fns->sys_acl_add_perm_fn(handle, permset, perm);
2081 }
2082
2083 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct *handle,
2084                                     SMB_ACL_T theacl, ssize_t *plen)
2085 {
2086         VFS_FIND(sys_acl_to_text);
2087         return handle->fns->sys_acl_to_text_fn(handle, theacl, plen);
2088 }
2089
2090 SMB_ACL_T smb_vfs_call_sys_acl_init(struct vfs_handle_struct *handle,
2091                                     int count)
2092 {
2093         VFS_FIND(sys_acl_init);
2094         return handle->fns->sys_acl_init_fn(handle, count);
2095 }
2096
2097 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct *handle,
2098                                       SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2099 {
2100         VFS_FIND(sys_acl_create_entry);
2101         return handle->fns->sys_acl_create_entry_fn(handle, pacl, pentry);
2102 }
2103
2104 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct *handle,
2105                                       SMB_ACL_ENTRY_T entry,
2106                                       SMB_ACL_TAG_T tagtype)
2107 {
2108         VFS_FIND(sys_acl_set_tag_type);
2109         return handle->fns->sys_acl_set_tag_type_fn(handle, entry, tagtype);
2110 }
2111
2112 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct *handle,
2113                                        SMB_ACL_ENTRY_T entry, void *qual)
2114 {
2115         VFS_FIND(sys_acl_set_qualifier);
2116         return handle->fns->sys_acl_set_qualifier_fn(handle, entry, qual);
2117 }
2118
2119 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct *handle,
2120                                      SMB_ACL_ENTRY_T entry,
2121                                      SMB_ACL_PERMSET_T permset)
2122 {
2123         VFS_FIND(sys_acl_set_permset);
2124         return handle->fns->sys_acl_set_permset_fn(handle, entry, permset);
2125 }
2126
2127 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct *handle,
2128                                SMB_ACL_T theacl)
2129 {
2130         VFS_FIND(sys_acl_valid);
2131         return handle->fns->sys_acl_valid_fn(handle, theacl);
2132 }
2133
2134 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2135                                   const char *name, SMB_ACL_TYPE_T acltype,
2136                                   SMB_ACL_T theacl)
2137 {
2138         VFS_FIND(sys_acl_set_file);
2139         return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2140 }
2141
2142 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2143                                 struct files_struct *fsp, SMB_ACL_T theacl)
2144 {
2145         VFS_FIND(sys_acl_set_fd);
2146         return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2147 }
2148
2149 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2150                                          const char *path)
2151 {
2152         VFS_FIND(sys_acl_delete_def_file);
2153         return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2154 }
2155
2156 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct *handle,
2157                                   SMB_ACL_PERMSET_T permset,
2158                                   SMB_ACL_PERM_T perm)
2159 {
2160         VFS_FIND(sys_acl_get_perm);
2161         return handle->fns->sys_acl_get_perm_fn(handle, permset, perm);
2162 }
2163
2164 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct *handle,
2165                                    char *text)
2166 {
2167         VFS_FIND(sys_acl_free_text);
2168         return handle->fns->sys_acl_free_text_fn(handle, text);
2169 }
2170
2171 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct *handle,
2172                                   SMB_ACL_T posix_acl)
2173 {
2174         VFS_FIND(sys_acl_free_acl);
2175         return handle->fns->sys_acl_free_acl_fn(handle, posix_acl);
2176 }
2177
2178 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct *handle,
2179                                         void *qualifier, SMB_ACL_TAG_T tagtype)
2180 {
2181         VFS_FIND(sys_acl_free_qualifier);
2182         return handle->fns->sys_acl_free_qualifier_fn(handle, qualifier, 
2183                                                       tagtype);
2184 }
2185
2186 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2187                               const char *path, const char *name, void *value,
2188                               size_t size)
2189 {
2190         VFS_FIND(getxattr);
2191         return handle->fns->getxattr_fn(handle, path, name, value, size);
2192 }
2193
2194 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2195                                struct files_struct *fsp, const char *name,
2196                                void *value, size_t size)
2197 {
2198         VFS_FIND(fgetxattr);
2199         return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2200 }
2201
2202 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2203                                const char *path, char *list, size_t size)
2204 {
2205         VFS_FIND(listxattr);
2206         return handle->fns->listxattr_fn(handle, path, list, size);
2207 }
2208
2209 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2210                                 struct files_struct *fsp, char *list,
2211                                 size_t size)
2212 {
2213         VFS_FIND(flistxattr);
2214         return handle->fns->flistxattr_fn(handle, fsp, list, size);
2215 }
2216
2217 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2218                              const char *path, const char *name)
2219 {
2220         VFS_FIND(removexattr);
2221         return handle->fns->removexattr_fn(handle, path, name);
2222 }
2223
2224 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2225                               struct files_struct *fsp, const char *name)
2226 {
2227         VFS_FIND(fremovexattr);
2228         return handle->fns->fremovexattr_fn(handle, fsp, name);
2229 }
2230
2231 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2232                           const char *name, const void *value, size_t size,
2233                           int flags)
2234 {
2235         VFS_FIND(setxattr);
2236         return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2237 }
2238
2239 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2240                            struct files_struct *fsp, const char *name,
2241                            const void *value, size_t size, int flags)
2242 {
2243         VFS_FIND(fsetxattr);
2244         return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2245 }
2246
2247 int smb_vfs_call_aio_read(struct vfs_handle_struct *handle,
2248                           struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2249 {
2250         VFS_FIND(aio_read);
2251         return handle->fns->aio_read_fn(handle, fsp, aiocb);
2252 }
2253
2254 int smb_vfs_call_aio_write(struct vfs_handle_struct *handle,
2255                            struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2256 {
2257         VFS_FIND(aio_write);
2258         return handle->fns->aio_write_fn(handle, fsp, aiocb);
2259 }
2260
2261 ssize_t smb_vfs_call_aio_return(struct vfs_handle_struct *handle,
2262                                 struct files_struct *fsp,
2263                                 SMB_STRUCT_AIOCB *aiocb)
2264 {
2265         VFS_FIND(aio_return);
2266         return handle->fns->aio_return_fn(handle, fsp, aiocb);
2267 }
2268
2269 int smb_vfs_call_aio_cancel(struct vfs_handle_struct *handle,
2270                             struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2271 {
2272         VFS_FIND(aio_cancel);
2273         return handle->fns->aio_cancel_fn(handle, fsp, aiocb);
2274 }
2275
2276 int smb_vfs_call_aio_error(struct vfs_handle_struct *handle,
2277                            struct files_struct *fsp,
2278                            SMB_STRUCT_AIOCB *aiocb)
2279 {
2280         VFS_FIND(aio_error);
2281         return handle->fns->aio_error_fn(handle, fsp, aiocb);
2282 }
2283
2284 int smb_vfs_call_aio_fsync(struct vfs_handle_struct *handle,
2285                            struct files_struct *fsp, int op,
2286                            SMB_STRUCT_AIOCB *aiocb)
2287 {
2288         VFS_FIND(aio_fsync);
2289         return handle->fns->aio_fsync_fn(handle, fsp, op, aiocb);
2290 }
2291
2292 int smb_vfs_call_aio_suspend(struct vfs_handle_struct *handle,
2293                              struct files_struct *fsp,
2294                              const SMB_STRUCT_AIOCB * const aiocb[], int n,
2295                              const struct timespec *timeout)
2296 {
2297         VFS_FIND(aio_suspend);
2298         return handle->fns->aio_suspend_fn(handle, fsp, aiocb, n, timeout);
2299 }
2300
2301 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2302                             struct files_struct *fsp)
2303 {
2304         VFS_FIND(aio_force);
2305         return handle->fns->aio_force_fn(handle, fsp);
2306 }
2307
2308 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2309                              const struct smb_filename *fname,
2310                              SMB_STRUCT_STAT *sbuf)
2311 {
2312         VFS_FIND(is_offline);
2313         return handle->fns->is_offline_fn(handle, fname, sbuf);
2314 }
2315
2316 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2317                              const struct smb_filename *fname)
2318 {
2319         VFS_FIND(set_offline);
2320         return handle->fns->set_offline_fn(handle, fname);
2321 }