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