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