s3: Fix Coverity ID 710827 Resource leak
[kai/samba-autobuild/.git] / source3 / smbd / vfs.c
1 /*
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    VFS initialisation and support functions
5    Copyright (C) Tim Potter 1999
6    Copyright (C) Alexander Bokovoy 2002
7    Copyright (C) James Peach 2006
8    Copyright (C) Volker Lendecke 2009
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
23    This work was sponsored by Optifacio Software Services, Inc.
24 */
25
26 #include "includes.h"
27 #include "system/filesys.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "memcache.h"
31 #include "transfer_file.h"
32 #include "ntioctl.h"
33 #include "lib/util/tevent_unix.h"
34
35 #undef DBGC_CLASS
36 #define DBGC_CLASS DBGC_VFS
37
38 static_decl_vfs;
39
40 struct vfs_fsp_data {
41     struct vfs_fsp_data *next;
42     struct vfs_handle_struct *owner;
43     void (*destroy)(void *p_data);
44     void *_dummy_;
45     /* NOTE: This structure contains four pointers so that we can guarantee
46      * that the end of the structure is always both 4-byte and 8-byte aligned.
47      */
48 };
49
50 struct vfs_init_function_entry {
51         char *name;
52         struct vfs_init_function_entry *prev, *next;
53         const struct vfs_fn_pointers *fns;
54 };
55
56 /****************************************************************************
57     maintain the list of available backends
58 ****************************************************************************/
59
60 static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
61 {
62         struct vfs_init_function_entry *entry = backends;
63
64         DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
65
66         while(entry) {
67                 if (strcmp(entry->name, name)==0) return entry;
68                 entry = entry->next;
69         }
70
71         return NULL;
72 }
73
74 NTSTATUS smb_register_vfs(int version, const char *name,
75                           const struct vfs_fn_pointers *fns)
76 {
77         struct vfs_init_function_entry *entry = backends;
78
79         if ((version != SMB_VFS_INTERFACE_VERSION)) {
80                 DEBUG(0, ("Failed to register vfs module.\n"
81                           "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
82                           "current SMB_VFS_INTERFACE_VERSION is %d.\n"
83                           "Please recompile against the current Samba Version!\n",  
84                           version, SMB_VFS_INTERFACE_VERSION));
85                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
86         }
87
88         if (!name || !name[0]) {
89                 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
90                 return NT_STATUS_INVALID_PARAMETER;
91         }
92
93         if (vfs_find_backend_entry(name)) {
94                 DEBUG(0,("VFS module %s already loaded!\n", name));
95                 return NT_STATUS_OBJECT_NAME_COLLISION;
96         }
97
98         entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
99         entry->name = smb_xstrdup(name);
100         entry->fns = fns;
101
102         DLIST_ADD(backends, entry);
103         DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
104         return NT_STATUS_OK;
105 }
106
107 /****************************************************************************
108   initialise default vfs hooks
109 ****************************************************************************/
110
111 static void vfs_init_default(connection_struct *conn)
112 {
113         DEBUG(3, ("Initialising default vfs hooks\n"));
114         vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
115 }
116
117 /****************************************************************************
118   initialise custom vfs hooks
119  ****************************************************************************/
120
121 bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
122 {
123         char *module_path = NULL;
124         char *module_name = NULL;
125         char *module_param = NULL, *p;
126         vfs_handle_struct *handle;
127         const struct vfs_init_function_entry *entry;
128
129         if (!conn||!vfs_object||!vfs_object[0]) {
130                 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
131                           "empty vfs_object!\n"));
132                 return False;
133         }
134
135         if(!backends) {
136                 static_init_vfs;
137         }
138
139         DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
140
141         module_path = smb_xstrdup(vfs_object);
142
143         p = strchr_m(module_path, ':');
144
145         if (p) {
146                 *p = 0;
147                 module_param = p+1;
148                 trim_char(module_param, ' ', ' ');
149         }
150
151         trim_char(module_path, ' ', ' ');
152
153         module_name = smb_xstrdup(module_path);
154
155         if ((module_name[0] == '/') &&
156             (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
157
158                 /*
159                  * Extract the module name from the path. Just use the base
160                  * name of the last path component.
161                  */
162
163                 SAFE_FREE(module_name);
164                 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
165
166                 p = strchr_m(module_name, '.');
167
168                 if (p != NULL) {
169                         *p = '\0';
170                 }
171         }
172
173         /* First, try to load the module with the new module system */
174         entry = vfs_find_backend_entry(module_name);
175         if (!entry) {
176                 NTSTATUS status;
177
178                 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
179                           vfs_object));
180
181                 status = smb_load_module("vfs", module_path);
182                 if (!NT_STATUS_IS_OK(status)) {
183                         DEBUG(0, ("error probing vfs module '%s': %s\n",
184                                   module_path, nt_errstr(status)));
185                         goto fail;
186                 }
187
188                 entry = vfs_find_backend_entry(module_name);
189                 if (!entry) {
190                         DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
191                         goto fail;
192                 }
193         }
194
195         DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
196
197         handle = talloc_zero(conn, vfs_handle_struct);
198         if (!handle) {
199                 DEBUG(0,("TALLOC_ZERO() failed!\n"));
200                 goto fail;
201         }
202         handle->conn = conn;
203         handle->fns = entry->fns;
204         if (module_param) {
205                 handle->param = talloc_strdup(conn, module_param);
206         }
207         DLIST_ADD(conn->vfs_handles, handle);
208
209         SAFE_FREE(module_path);
210         SAFE_FREE(module_name);
211         return True;
212
213  fail:
214         SAFE_FREE(module_path);
215         SAFE_FREE(module_name);
216         return False;
217 }
218
219 /*****************************************************************
220  Allow VFS modules to extend files_struct with VFS-specific state.
221  This will be ok for small numbers of extensions, but might need to
222  be refactored if it becomes more widely used.
223 ******************************************************************/
224
225 #define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
226
227 void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
228                                    files_struct *fsp, size_t ext_size,
229                                    void (*destroy_fn)(void *p_data))
230 {
231         struct vfs_fsp_data *ext;
232         void * ext_data;
233
234         /* Prevent VFS modules adding multiple extensions. */
235         if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
236                 return ext_data;
237         }
238
239         ext = (struct vfs_fsp_data *)TALLOC_ZERO(
240                 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
241         if (ext == NULL) {
242                 return NULL;
243         }
244
245         ext->owner = handle;
246         ext->next = fsp->vfs_extension;
247         ext->destroy = destroy_fn;
248         fsp->vfs_extension = ext;
249         return EXT_DATA_AREA(ext);
250 }
251
252 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
253 {
254         struct vfs_fsp_data *curr;
255         struct vfs_fsp_data *prev;
256
257         for (curr = fsp->vfs_extension, prev = NULL;
258              curr;
259              prev = curr, curr = curr->next) {
260                 if (curr->owner == handle) {
261                     if (prev) {
262                             prev->next = curr->next;
263                     } else {
264                             fsp->vfs_extension = curr->next;
265                     }
266                     if (curr->destroy) {
267                             curr->destroy(EXT_DATA_AREA(curr));
268                     }
269                     TALLOC_FREE(curr);
270                     return;
271                 }
272         }
273 }
274
275 void vfs_remove_all_fsp_extensions(files_struct *fsp)
276 {
277         struct vfs_fsp_data *curr;
278         struct vfs_fsp_data *next;
279
280         for (curr = fsp->vfs_extension; curr; curr = next) {
281
282                 next = curr->next;
283                 fsp->vfs_extension = next;
284
285                 if (curr->destroy) {
286                         curr->destroy(EXT_DATA_AREA(curr));
287                 }
288                 TALLOC_FREE(curr);
289         }
290 }
291
292 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
293 {
294         struct vfs_fsp_data *head;
295
296         for (head = fsp->vfs_extension; head; head = head->next) {
297                 if (head->owner == handle) {
298                         return head;
299                 }
300         }
301
302         return NULL;
303 }
304
305 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
306 {
307         struct vfs_fsp_data *head;
308
309         head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
310         if (head != NULL) {
311                 return EXT_DATA_AREA(head);
312         }
313
314         return NULL;
315 }
316
317 #undef EXT_DATA_AREA
318
319 /*****************************************************************
320  Generic VFS init.
321 ******************************************************************/
322
323 bool smbd_vfs_init(connection_struct *conn)
324 {
325         const char **vfs_objects;
326         unsigned int i = 0;
327         int j = 0;
328
329         /* Normal share - initialise with disk access functions */
330         vfs_init_default(conn);
331         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         TALLOC_FREE(dir_name);
1090         return status;
1091 }
1092
1093 /*******************************************************************
1094  Reduce a file name, removing .. elements and checking that
1095  it is below dir in the heirachy. This uses realpath.
1096 ********************************************************************/
1097
1098 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1099 {
1100         char *resolved_name = NULL;
1101         bool allow_symlinks = true;
1102         bool allow_widelinks = false;
1103
1104         DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1105
1106         resolved_name = SMB_VFS_REALPATH(conn,fname);
1107
1108         if (!resolved_name) {
1109                 switch (errno) {
1110                         case ENOTDIR:
1111                                 DEBUG(3,("check_reduced_name: Component not a "
1112                                          "directory in getting realpath for "
1113                                          "%s\n", fname));
1114                                 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1115                         case ENOENT:
1116                         {
1117                                 TALLOC_CTX *ctx = talloc_tos();
1118                                 char *dir_name = NULL;
1119                                 const char *last_component = NULL;
1120                                 char *new_name = NULL;
1121                                 int ret;
1122
1123                                 /* Last component didn't exist.
1124                                    Remove it and try and canonicalise
1125                                    the directory name. */
1126                                 if (!parent_dirname(ctx, fname,
1127                                                 &dir_name,
1128                                                 &last_component)) {
1129                                         return NT_STATUS_NO_MEMORY;
1130                                 }
1131
1132                                 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1133                                 if (!resolved_name) {
1134                                         NTSTATUS status = map_nt_error_from_unix(errno);
1135
1136                                         if (errno == ENOENT || errno == ENOTDIR) {
1137                                                 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1138                                         }
1139
1140                                         DEBUG(3,("check_reduce_name: "
1141                                                  "couldn't get realpath for "
1142                                                  "%s (%s)\n",
1143                                                 fname,
1144                                                 nt_errstr(status)));
1145                                         return status;
1146                                 }
1147                                 ret = asprintf(&new_name, "%s/%s",
1148                                                resolved_name, last_component);
1149                                 SAFE_FREE(resolved_name);
1150                                 if (ret == -1) {
1151                                         return NT_STATUS_NO_MEMORY;
1152                                 }
1153                                 resolved_name = new_name;
1154                                 break;
1155                         }
1156                         default:
1157                                 DEBUG(3,("check_reduced_name: couldn't get "
1158                                          "realpath for %s\n", fname));
1159                                 return map_nt_error_from_unix(errno);
1160                 }
1161         }
1162
1163         DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1164                   resolved_name));
1165
1166         if (*resolved_name != '/') {
1167                 DEBUG(0,("check_reduced_name: realpath doesn't return "
1168                          "absolute paths !\n"));
1169                 SAFE_FREE(resolved_name);
1170                 return NT_STATUS_OBJECT_NAME_INVALID;
1171         }
1172
1173         allow_widelinks = lp_widelinks(SNUM(conn));
1174         allow_symlinks = lp_symlinks(SNUM(conn));
1175
1176         /* Common widelinks and symlinks checks. */
1177         if (!allow_widelinks || !allow_symlinks) {
1178                 const char *conn_rootdir;
1179                 size_t rootdir_len;
1180
1181                 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1182                 if (conn_rootdir == NULL) {
1183                         DEBUG(2, ("check_reduced_name: Could not get "
1184                                 "conn_rootdir\n"));
1185                         SAFE_FREE(resolved_name);
1186                         return NT_STATUS_ACCESS_DENIED;
1187                 }
1188
1189                 rootdir_len = strlen(conn_rootdir);
1190                 if (strncmp(conn_rootdir, resolved_name,
1191                                 rootdir_len) != 0) {
1192                         DEBUG(2, ("check_reduced_name: Bad access "
1193                                 "attempt: %s is a symlink outside the "
1194                                 "share path\n", fname));
1195                         DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1196                         DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1197                         SAFE_FREE(resolved_name);
1198                         return NT_STATUS_ACCESS_DENIED;
1199                 }
1200
1201                 /* Extra checks if all symlinks are disallowed. */
1202                 if (!allow_symlinks) {
1203                         /* fname can't have changed in resolved_path. */
1204                         const char *p = &resolved_name[rootdir_len];
1205
1206                         /* *p can be '\0' if fname was "." */
1207                         if (*p == '\0' && ISDOT(fname)) {
1208                                 goto out;
1209                         }
1210
1211                         if (*p != '/') {
1212                                 DEBUG(2, ("check_reduced_name: logic error (%c) "
1213                                         "in resolved_name: %s\n",
1214                                         *p,
1215                                         fname));
1216                                 SAFE_FREE(resolved_name);
1217                                 return NT_STATUS_ACCESS_DENIED;
1218                         }
1219
1220                         p++;
1221                         if (strcmp(fname, p)!=0) {
1222                                 DEBUG(2, ("check_reduced_name: Bad access "
1223                                         "attempt: %s is a symlink\n",
1224                                         fname));
1225                                 SAFE_FREE(resolved_name);
1226                                 return NT_STATUS_ACCESS_DENIED;
1227                         }
1228                 }
1229         }
1230
1231   out:
1232
1233         DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1234                  resolved_name));
1235         SAFE_FREE(resolved_name);
1236         return NT_STATUS_OK;
1237 }
1238
1239 /**
1240  * XXX: This is temporary and there should be no callers of this once
1241  * smb_filename is plumbed through all path based operations.
1242  */
1243 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1244                        SMB_STRUCT_STAT *psbuf)
1245 {
1246         struct smb_filename *smb_fname = NULL;
1247         NTSTATUS status;
1248         int ret;
1249
1250         status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1251                                                   &smb_fname);
1252         if (!NT_STATUS_IS_OK(status)) {
1253                 errno = map_errno_from_nt_status(status);
1254                 return -1;
1255         }
1256
1257         if (lp_posix_pathnames()) {
1258                 ret = SMB_VFS_LSTAT(conn, smb_fname);
1259         } else {
1260                 ret = SMB_VFS_STAT(conn, smb_fname);
1261         }
1262
1263         if (ret != -1) {
1264                 *psbuf = smb_fname->st;
1265         }
1266
1267         TALLOC_FREE(smb_fname);
1268         return ret;
1269 }
1270
1271 /**
1272  * XXX: This is temporary and there should be no callers of this once
1273  * smb_filename is plumbed through all path based operations.
1274  */
1275 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1276                         SMB_STRUCT_STAT *psbuf)
1277 {
1278         struct smb_filename *smb_fname = NULL;
1279         NTSTATUS status;
1280         int ret;
1281
1282         status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1283                                                   &smb_fname);
1284         if (!NT_STATUS_IS_OK(status)) {
1285                 errno = map_errno_from_nt_status(status);
1286                 return -1;
1287         }
1288
1289         ret = SMB_VFS_LSTAT(conn, smb_fname);
1290         if (ret != -1) {
1291                 *psbuf = smb_fname->st;
1292         }
1293
1294         TALLOC_FREE(smb_fname);
1295         return ret;
1296 }
1297
1298 /**
1299  * Ensure LSTAT is called for POSIX paths.
1300  */
1301
1302 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1303 {
1304         int ret;
1305
1306         if(fsp->fh->fd == -1) {
1307                 if (fsp->posix_open) {
1308                         ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1309                 } else {
1310                         ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1311                 }
1312                 if (ret == -1) {
1313                         return map_nt_error_from_unix(errno);
1314                 }
1315         } else {
1316                 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1317                         return map_nt_error_from_unix(errno);
1318                 }
1319         }
1320         return NT_STATUS_OK;
1321 }
1322
1323 /**
1324  * Initialize num_streams and streams, then call VFS op streaminfo
1325  */
1326 NTSTATUS vfs_streaminfo(connection_struct *conn,
1327                         struct files_struct *fsp,
1328                         const char *fname,
1329                         TALLOC_CTX *mem_ctx,
1330                         unsigned int *num_streams,
1331                         struct stream_struct **streams)
1332 {
1333         *num_streams = 0;
1334         *streams = NULL;
1335         return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1336 }
1337
1338 /*
1339   generate a file_id from a stat structure
1340  */
1341 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1342 {
1343         return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1344 }
1345
1346 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1347                          const char *service, const char *user)
1348 {
1349         VFS_FIND(connect);
1350         return handle->fns->connect_fn(handle, service, user);
1351 }
1352
1353 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1354 {
1355         VFS_FIND(disconnect);
1356         handle->fns->disconnect_fn(handle);
1357 }
1358
1359 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1360                                 const char *path, bool small_query,
1361                                 uint64_t *bsize, uint64_t *dfree,
1362                                 uint64_t *dsize)
1363 {
1364         VFS_FIND(disk_free);
1365         return handle->fns->disk_free_fn(handle, path, small_query, bsize, 
1366                                          dfree, dsize);
1367 }
1368
1369 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1370                            enum SMB_QUOTA_TYPE qtype, unid_t id,
1371                            SMB_DISK_QUOTA *qt)
1372 {
1373         VFS_FIND(get_quota);
1374         return handle->fns->get_quota_fn(handle, qtype, id, qt);
1375 }
1376
1377 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1378                            enum SMB_QUOTA_TYPE qtype, unid_t id,
1379                            SMB_DISK_QUOTA *qt)
1380 {
1381         VFS_FIND(set_quota);
1382         return handle->fns->set_quota_fn(handle, qtype, id, qt);
1383 }
1384
1385 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1386                                       struct files_struct *fsp,
1387                                       struct shadow_copy_data *shadow_copy_data,
1388                                       bool labels)
1389 {
1390         VFS_FIND(get_shadow_copy_data);
1391         return handle->fns->get_shadow_copy_data_fn(handle, fsp, 
1392                                                     shadow_copy_data,
1393                                                     labels);
1394 }
1395 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1396                          struct vfs_statvfs_struct *statbuf)
1397 {
1398         VFS_FIND(statvfs);
1399         return handle->fns->statvfs_fn(handle, path, statbuf);
1400 }
1401
1402 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1403                         enum timestamp_set_resolution *p_ts_res)
1404 {
1405         VFS_FIND(fs_capabilities);
1406         return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1407 }
1408
1409 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1410                                         struct dfs_GetDFSReferral *r)
1411 {
1412         VFS_FIND(get_dfs_referrals);
1413         return handle->fns->get_dfs_referrals_fn(handle, r);
1414 }
1415
1416 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1417                                      const char *fname, const char *mask,
1418                                      uint32 attributes)
1419 {
1420         VFS_FIND(opendir);
1421         return handle->fns->opendir_fn(handle, fname, mask, attributes);
1422 }
1423
1424 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1425                                         struct files_struct *fsp,
1426                                         const char *mask,
1427                                         uint32 attributes)
1428 {
1429         VFS_FIND(fdopendir);
1430         return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1431 }
1432
1433 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1434                                               DIR *dirp,
1435                                               SMB_STRUCT_STAT *sbuf)
1436 {
1437         VFS_FIND(readdir);
1438         return handle->fns->readdir_fn(handle, dirp, sbuf);
1439 }
1440
1441 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1442                           DIR *dirp, long offset)
1443 {
1444         VFS_FIND(seekdir);
1445         handle->fns->seekdir_fn(handle, dirp, offset);
1446 }
1447
1448 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1449                           DIR *dirp)
1450 {
1451         VFS_FIND(telldir);
1452         return handle->fns->telldir_fn(handle, dirp);
1453 }
1454
1455 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1456                              DIR *dirp)
1457 {
1458         VFS_FIND(rewind_dir);
1459         handle->fns->rewind_dir_fn(handle, dirp);
1460 }
1461
1462 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1463                        mode_t mode)
1464 {
1465         VFS_FIND(mkdir);
1466         return handle->fns->mkdir_fn(handle, path, mode);
1467 }
1468
1469 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1470 {
1471         VFS_FIND(rmdir);
1472         return handle->fns->rmdir_fn(handle, path);
1473 }
1474
1475 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1476                           DIR *dir)
1477 {
1478         VFS_FIND(closedir);
1479         return handle->fns->closedir_fn(handle, dir);
1480 }
1481
1482 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1483                                  DIR *dirp)
1484 {
1485         VFS_FIND(init_search_op);
1486         handle->fns->init_search_op_fn(handle, dirp);
1487 }
1488
1489 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1490                       struct smb_filename *smb_fname, struct files_struct *fsp,
1491                       int flags, mode_t mode)
1492 {
1493         VFS_FIND(open);
1494         return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1495 }
1496
1497 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1498                                   struct smb_request *req,
1499                                   uint16_t root_dir_fid,
1500                                   struct smb_filename *smb_fname,
1501                                   uint32_t access_mask,
1502                                   uint32_t share_access,
1503                                   uint32_t create_disposition,
1504                                   uint32_t create_options,
1505                                   uint32_t file_attributes,
1506                                   uint32_t oplock_request,
1507                                   uint64_t allocation_size,
1508                                   uint32_t private_flags,
1509                                   struct security_descriptor *sd,
1510                                   struct ea_list *ea_list,
1511                                   files_struct **result,
1512                                   int *pinfo)
1513 {
1514         VFS_FIND(create_file);
1515         return handle->fns->create_file_fn(
1516                 handle, req, root_dir_fid, smb_fname, access_mask,
1517                 share_access, create_disposition, create_options,
1518                 file_attributes, oplock_request, allocation_size,
1519                 private_flags, sd, ea_list,
1520                 result, pinfo);
1521 }
1522
1523 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1524                        struct files_struct *fsp)
1525 {
1526         VFS_FIND(close);
1527         return handle->fns->close_fn(handle, fsp);
1528 }
1529
1530 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1531                           struct files_struct *fsp, void *data, size_t n)
1532 {
1533         VFS_FIND(read);
1534         return handle->fns->read_fn(handle, fsp, data, n);
1535 }
1536
1537 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1538                            struct files_struct *fsp, void *data, size_t n,
1539                            off_t offset)
1540 {
1541         VFS_FIND(pread);
1542         return handle->fns->pread_fn(handle, fsp, data, n, offset);
1543 }
1544
1545 struct smb_vfs_call_pread_state {
1546         ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1547         ssize_t retval;
1548 };
1549
1550 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1551
1552 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1553                                            TALLOC_CTX *mem_ctx,
1554                                            struct tevent_context *ev,
1555                                            struct files_struct *fsp,
1556                                            void *data,
1557                                            size_t n, off_t offset)
1558 {
1559         struct tevent_req *req, *subreq;
1560         struct smb_vfs_call_pread_state *state;
1561
1562         req = tevent_req_create(mem_ctx, &state,
1563                                 struct smb_vfs_call_pread_state);
1564         if (req == NULL) {
1565                 return NULL;
1566         }
1567         VFS_FIND(pread_send);
1568         state->recv_fn = handle->fns->pread_recv_fn;
1569
1570         subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1571                                             offset);
1572         if (tevent_req_nomem(subreq, req)) {
1573                 return tevent_req_post(req, ev);
1574         }
1575         tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1576         return req;
1577 }
1578
1579 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1580 {
1581         struct tevent_req *req = tevent_req_callback_data(
1582                 subreq, struct tevent_req);
1583         struct smb_vfs_call_pread_state *state = tevent_req_data(
1584                 req, struct smb_vfs_call_pread_state);
1585         int err;
1586
1587         state->retval = state->recv_fn(subreq, &err);
1588         TALLOC_FREE(subreq);
1589         if (state->retval == -1) {
1590                 tevent_req_error(req, err);
1591                 return;
1592         }
1593         tevent_req_done(req);
1594 }
1595
1596 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1597 {
1598         struct smb_vfs_call_pread_state *state = tevent_req_data(
1599                 req, struct smb_vfs_call_pread_state);
1600         int err;
1601
1602         if (tevent_req_is_unix_error(req, &err)) {
1603                 *perrno = err;
1604                 return -1;
1605         }
1606         return state->retval;
1607 }
1608
1609 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1610                            struct files_struct *fsp, const void *data,
1611                            size_t n)
1612 {
1613         VFS_FIND(write);
1614         return handle->fns->write_fn(handle, fsp, data, n);
1615 }
1616
1617 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1618                             struct files_struct *fsp, const void *data,
1619                             size_t n, off_t offset)
1620 {
1621         VFS_FIND(pwrite);
1622         return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1623 }
1624
1625 struct smb_vfs_call_pwrite_state {
1626         ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1627         ssize_t retval;
1628 };
1629
1630 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1631
1632 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1633                                             TALLOC_CTX *mem_ctx,
1634                                             struct tevent_context *ev,
1635                                             struct files_struct *fsp,
1636                                             const void *data,
1637                                             size_t n, off_t offset)
1638 {
1639         struct tevent_req *req, *subreq;
1640         struct smb_vfs_call_pwrite_state *state;
1641
1642         req = tevent_req_create(mem_ctx, &state,
1643                                 struct smb_vfs_call_pwrite_state);
1644         if (req == NULL) {
1645                 return NULL;
1646         }
1647         VFS_FIND(pwrite_send);
1648         state->recv_fn = handle->fns->pwrite_recv_fn;
1649
1650         subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1651                                              offset);
1652         if (tevent_req_nomem(subreq, req)) {
1653                 return tevent_req_post(req, ev);
1654         }
1655         tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1656         return req;
1657 }
1658
1659 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1660 {
1661         struct tevent_req *req = tevent_req_callback_data(
1662                 subreq, struct tevent_req);
1663         struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1664                 req, struct smb_vfs_call_pwrite_state);
1665         int err;
1666
1667         state->retval = state->recv_fn(subreq, &err);
1668         TALLOC_FREE(subreq);
1669         if (state->retval == -1) {
1670                 tevent_req_error(req, err);
1671                 return;
1672         }
1673         tevent_req_done(req);
1674 }
1675
1676 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1677 {
1678         struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1679                 req, struct smb_vfs_call_pwrite_state);
1680         int err;
1681
1682         if (tevent_req_is_unix_error(req, &err)) {
1683                 *perrno = err;
1684                 return -1;
1685         }
1686         return state->retval;
1687 }
1688
1689 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1690                              struct files_struct *fsp, off_t offset,
1691                              int whence)
1692 {
1693         VFS_FIND(lseek);
1694         return handle->fns->lseek_fn(handle, fsp, offset, whence);
1695 }
1696
1697 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1698                               files_struct *fromfsp, const DATA_BLOB *header,
1699                               off_t offset, size_t count)
1700 {
1701         VFS_FIND(sendfile);
1702         return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1703                                         count);
1704 }
1705
1706 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1707                               files_struct *tofsp, off_t offset,
1708                               size_t count)
1709 {
1710         VFS_FIND(recvfile);
1711         return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1712 }
1713
1714 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1715                         const struct smb_filename *smb_fname_src,
1716                         const struct smb_filename *smb_fname_dst)
1717 {
1718         VFS_FIND(rename);
1719         return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1720 }
1721
1722 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1723                        struct files_struct *fsp)
1724 {
1725         VFS_FIND(fsync);
1726         return handle->fns->fsync_fn(handle, fsp);
1727 }
1728
1729 struct smb_vfs_call_fsync_state {
1730         int (*recv_fn)(struct tevent_req *req, int *err);
1731         int retval;
1732 };
1733
1734 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1735
1736 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1737                                            TALLOC_CTX *mem_ctx,
1738                                            struct tevent_context *ev,
1739                                            struct files_struct *fsp)
1740 {
1741         struct tevent_req *req, *subreq;
1742         struct smb_vfs_call_fsync_state *state;
1743
1744         req = tevent_req_create(mem_ctx, &state,
1745                                 struct smb_vfs_call_fsync_state);
1746         if (req == NULL) {
1747                 return NULL;
1748         }
1749         VFS_FIND(fsync_send);
1750         state->recv_fn = handle->fns->fsync_recv_fn;
1751
1752         subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1753         if (tevent_req_nomem(subreq, req)) {
1754                 return tevent_req_post(req, ev);
1755         }
1756         tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1757         return req;
1758 }
1759
1760 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1761 {
1762         struct tevent_req *req = tevent_req_callback_data(
1763                 subreq, struct tevent_req);
1764         struct smb_vfs_call_fsync_state *state = tevent_req_data(
1765                 req, struct smb_vfs_call_fsync_state);
1766         int err;
1767
1768         state->retval = state->recv_fn(subreq, &err);
1769         TALLOC_FREE(subreq);
1770         if (state->retval == -1) {
1771                 tevent_req_error(req, err);
1772                 return;
1773         }
1774         tevent_req_done(req);
1775 }
1776
1777 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1778 {
1779         struct smb_vfs_call_fsync_state *state = tevent_req_data(
1780                 req, struct smb_vfs_call_fsync_state);
1781         int err;
1782
1783         if (tevent_req_is_unix_error(req, &err)) {
1784                 *perrno = err;
1785                 return -1;
1786         }
1787         return state->retval;
1788 }
1789
1790
1791 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1792                       struct smb_filename *smb_fname)
1793 {
1794         VFS_FIND(stat);
1795         return handle->fns->stat_fn(handle, smb_fname);
1796 }
1797
1798 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1799                        struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1800 {
1801         VFS_FIND(fstat);
1802         return handle->fns->fstat_fn(handle, fsp, sbuf);
1803 }
1804
1805 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1806                        struct smb_filename *smb_filename)
1807 {
1808         VFS_FIND(lstat);
1809         return handle->fns->lstat_fn(handle, smb_filename);
1810 }
1811
1812 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1813                                      struct files_struct *fsp,
1814                                      const SMB_STRUCT_STAT *sbuf)
1815 {
1816         VFS_FIND(get_alloc_size);
1817         return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1818 }
1819
1820 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1821                         const struct smb_filename *smb_fname)
1822 {
1823         VFS_FIND(unlink);
1824         return handle->fns->unlink_fn(handle, smb_fname);
1825 }
1826
1827 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1828                        mode_t mode)
1829 {
1830         VFS_FIND(chmod);
1831         return handle->fns->chmod_fn(handle, path, mode);
1832 }
1833
1834 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1835                         struct files_struct *fsp, mode_t mode)
1836 {
1837         VFS_FIND(fchmod);
1838         return handle->fns->fchmod_fn(handle, fsp, mode);
1839 }
1840
1841 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1842                        uid_t uid, gid_t gid)
1843 {
1844         VFS_FIND(chown);
1845         return handle->fns->chown_fn(handle, path, uid, gid);
1846 }
1847
1848 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1849                         struct files_struct *fsp, uid_t uid, gid_t gid)
1850 {
1851         VFS_FIND(fchown);
1852         return handle->fns->fchown_fn(handle, fsp, uid, gid);
1853 }
1854
1855 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1856                         uid_t uid, gid_t gid)
1857 {
1858         VFS_FIND(lchown);
1859         return handle->fns->lchown_fn(handle, path, uid, gid);
1860 }
1861
1862 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1863 {
1864         int ret;
1865         bool as_root = false;
1866         const char *path;
1867         char *saved_dir = NULL;
1868         char *parent_dir = NULL;
1869         NTSTATUS status;
1870
1871         if (fsp->fh->fd != -1) {
1872                 /* Try fchown. */
1873                 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1874                 if (ret == 0) {
1875                         return NT_STATUS_OK;
1876                 }
1877                 if (ret == -1 && errno != ENOSYS) {
1878                         return map_nt_error_from_unix(errno);
1879                 }
1880         }
1881
1882         as_root = (geteuid() == 0);
1883
1884         if (as_root) {
1885                 /*
1886                  * We are being asked to chown as root. Make
1887                  * sure we chdir() into the path to pin it,
1888                  * and always act using lchown to ensure we
1889                  * don't deref any symbolic links.
1890                  */
1891                 const char *final_component = NULL;
1892                 struct smb_filename local_fname;
1893
1894                 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1895                 if (!saved_dir) {
1896                         status = map_nt_error_from_unix(errno);
1897                         DEBUG(0,("vfs_chown_fsp: failed to get "
1898                                 "current working directory. Error was %s\n",
1899                                 strerror(errno)));
1900                         return status;
1901                 }
1902
1903                 if (!parent_dirname(talloc_tos(),
1904                                 fsp->fsp_name->base_name,
1905                                 &parent_dir,
1906                                 &final_component)) {
1907                         return NT_STATUS_NO_MEMORY;
1908                 }
1909
1910                 /* cd into the parent dir to pin it. */
1911                 ret = vfs_ChDir(fsp->conn, parent_dir);
1912                 if (ret == -1) {
1913                         return map_nt_error_from_unix(errno);
1914                 }
1915
1916                 ZERO_STRUCT(local_fname);
1917                 local_fname.base_name = discard_const_p(char, final_component);
1918
1919                 /* Must use lstat here. */
1920                 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1921                 if (ret == -1) {
1922                         status = map_nt_error_from_unix(errno);
1923                         goto out;
1924                 }
1925
1926                 /* Ensure it matches the fsp stat. */
1927                 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1928                         status = NT_STATUS_ACCESS_DENIED;
1929                         goto out;
1930                 }
1931                 path = final_component;
1932         } else {
1933                 path = fsp->fsp_name->base_name;
1934         }
1935
1936         if (fsp->posix_open || as_root) {
1937                 ret = SMB_VFS_LCHOWN(fsp->conn,
1938                         path,
1939                         uid, gid);
1940         } else {
1941                 ret = SMB_VFS_CHOWN(fsp->conn,
1942                         path,
1943                         uid, gid);
1944         }
1945
1946         if (ret == 0) {
1947                 status = NT_STATUS_OK;
1948         } else {
1949                 status = map_nt_error_from_unix(errno);
1950         }
1951
1952   out:
1953
1954         if (as_root) {
1955                 vfs_ChDir(fsp->conn,saved_dir);
1956                 TALLOC_FREE(saved_dir);
1957                 TALLOC_FREE(parent_dir);
1958         }
1959         return status;
1960 }
1961
1962 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1963 {
1964         VFS_FIND(chdir);
1965         return handle->fns->chdir_fn(handle, path);
1966 }
1967
1968 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1969 {
1970         VFS_FIND(getwd);
1971         return handle->fns->getwd_fn(handle);
1972 }
1973
1974 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1975                         const struct smb_filename *smb_fname,
1976                         struct smb_file_time *ft)
1977 {
1978         VFS_FIND(ntimes);
1979         return handle->fns->ntimes_fn(handle, smb_fname, ft);
1980 }
1981
1982 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1983                            struct files_struct *fsp, off_t offset)
1984 {
1985         VFS_FIND(ftruncate);
1986         return handle->fns->ftruncate_fn(handle, fsp, offset);
1987 }
1988
1989 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1990                                 struct files_struct *fsp,
1991                                 enum vfs_fallocate_mode mode,
1992                                 off_t offset,
1993                                 off_t len)
1994 {
1995         VFS_FIND(fallocate);
1996         return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
1997 }
1998
1999 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2000                               struct files_struct *fsp, uint32 share_mode,
2001                               uint32_t access_mask)
2002 {
2003         VFS_FIND(kernel_flock);
2004         return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2005                                          access_mask);
2006 }
2007
2008 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2009                                 struct files_struct *fsp, int leasetype)
2010 {
2011         VFS_FIND(linux_setlease);
2012         return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2013 }
2014
2015 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2016                          const char *newpath)
2017 {
2018         VFS_FIND(symlink);
2019         return handle->fns->symlink_fn(handle, oldpath, newpath);
2020 }
2021
2022 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2023                               const char *path, char *buf, size_t bufsiz)
2024 {
2025         VFS_FIND(readlink);
2026         return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2027 }
2028
2029 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2030                       const char *newpath)
2031 {
2032         VFS_FIND(link);
2033         return handle->fns->link_fn(handle, oldpath, newpath);
2034 }
2035
2036 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2037                        mode_t mode, SMB_DEV_T dev)
2038 {
2039         VFS_FIND(mknod);
2040         return handle->fns->mknod_fn(handle, path, mode, dev);
2041 }
2042
2043 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2044 {
2045         VFS_FIND(realpath);
2046         return handle->fns->realpath_fn(handle, path);
2047 }
2048
2049 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
2050                                    struct sys_notify_context *ctx,
2051                                    const char *path,
2052                                    uint32_t *filter,
2053                                    uint32_t *subdir_filter,
2054                                    void (*callback)(struct sys_notify_context *ctx,
2055                                                     void *private_data,
2056                                                     struct notify_event *ev),
2057                                    void *private_data, void *handle_p)
2058 {
2059         VFS_FIND(notify_watch);
2060         return handle->fns->notify_watch_fn(handle, ctx, path,
2061                                             filter, subdir_filter, callback,
2062                                             private_data, handle_p);
2063 }
2064
2065 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2066                          unsigned int flags)
2067 {
2068         VFS_FIND(chflags);
2069         return handle->fns->chflags_fn(handle, path, flags);
2070 }
2071
2072 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2073                                            const SMB_STRUCT_STAT *sbuf)
2074 {
2075         VFS_FIND(file_id_create);
2076         return handle->fns->file_id_create_fn(handle, sbuf);
2077 }
2078
2079 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2080                                  struct files_struct *fsp,
2081                                  const char *fname,
2082                                  TALLOC_CTX *mem_ctx,
2083                                  unsigned int *num_streams,
2084                                  struct stream_struct **streams)
2085 {
2086         VFS_FIND(streaminfo);
2087         return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2088                                           num_streams, streams);
2089 }
2090
2091 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2092                                    const char *path, const char *name,
2093                                    TALLOC_CTX *mem_ctx, char **found_name)
2094 {
2095         VFS_FIND(get_real_filename);
2096         return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2097                                                  found_name);
2098 }
2099
2100 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2101                                      const char *filename)
2102 {
2103         VFS_FIND(connectpath);
2104         return handle->fns->connectpath_fn(handle, filename);
2105 }
2106
2107 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2108                               struct files_struct *fsp,
2109                               struct lock_struct *plock)
2110 {
2111         VFS_FIND(strict_lock);
2112         return handle->fns->strict_lock_fn(handle, fsp, plock);
2113 }
2114
2115 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2116                                 struct files_struct *fsp,
2117                                 struct lock_struct *plock)
2118 {
2119         VFS_FIND(strict_unlock);
2120         handle->fns->strict_unlock_fn(handle, fsp, plock);
2121 }
2122
2123 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2124                                      const char *name,
2125                                      enum vfs_translate_direction direction,
2126                                      TALLOC_CTX *mem_ctx,
2127                                      char **mapped_name)
2128 {
2129         VFS_FIND(translate_name);
2130         return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2131                                               mapped_name);
2132 }
2133
2134 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2135                             struct files_struct *fsp,
2136                             TALLOC_CTX *ctx,
2137                             uint32_t function,
2138                             uint16_t req_flags,
2139                             const uint8_t *in_data,
2140                             uint32_t in_len,
2141                             uint8_t **out_data,
2142                             uint32_t max_out_len,
2143                             uint32_t *out_len)
2144 {
2145         VFS_FIND(fsctl);
2146         return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags, 
2147                                      in_data, in_len, out_data, max_out_len, 
2148                                      out_len);
2149 }
2150
2151 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2152                                   struct files_struct *fsp,
2153                                   uint32 security_info,
2154                                   struct security_descriptor **ppdesc)
2155 {
2156         VFS_FIND(fget_nt_acl);
2157         return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2158                                            ppdesc);
2159 }
2160
2161 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2162                                  const char *name,
2163                                  uint32 security_info,
2164                                  struct security_descriptor **ppdesc)
2165 {
2166         VFS_FIND(get_nt_acl);
2167         return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc);
2168 }
2169
2170 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2171                                   struct files_struct *fsp,
2172                                   uint32 security_info_sent,
2173                                   const struct security_descriptor *psd)
2174 {
2175         VFS_FIND(fset_nt_acl);
2176         return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent, 
2177                                            psd);
2178 }
2179
2180 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2181                                  struct smb_filename *file,
2182                                  struct security_acl *sacl,
2183                                  uint32_t access_requested,
2184                                  uint32_t access_denied)
2185 {
2186         VFS_FIND(audit_file);
2187         return handle->fns->audit_file_fn(handle, 
2188                                           file, 
2189                                           sacl, 
2190                                           access_requested, 
2191                                           access_denied);
2192 }
2193
2194 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2195                            mode_t mode)
2196 {
2197         VFS_FIND(chmod_acl);
2198         return handle->fns->chmod_acl_fn(handle, name, mode);
2199 }
2200
2201 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2202                             struct files_struct *fsp, mode_t mode)
2203 {
2204         VFS_FIND(fchmod_acl);
2205         return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2206 }
2207
2208 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct *handle,
2209                                    SMB_ACL_T theacl, int entry_id,
2210                                    SMB_ACL_ENTRY_T *entry_p)
2211 {
2212         VFS_FIND(sys_acl_get_entry);
2213         return handle->fns->sys_acl_get_entry_fn(handle, theacl, entry_id,
2214                                                  entry_p);
2215 }
2216
2217 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct *handle,
2218                                       SMB_ACL_ENTRY_T entry_d,
2219                                       SMB_ACL_TAG_T *tag_type_p)
2220 {
2221         VFS_FIND(sys_acl_get_tag_type);
2222         return handle->fns->sys_acl_get_tag_type_fn(handle, entry_d, 
2223                                                     tag_type_p);
2224 }
2225
2226 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct *handle,
2227                                      SMB_ACL_ENTRY_T entry_d,
2228                                      SMB_ACL_PERMSET_T *permset_p)
2229 {
2230         VFS_FIND(sys_acl_get_permset);
2231         return handle->fns->sys_acl_get_permset_fn(handle, entry_d, permset_p);
2232 }
2233
2234 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct *handle,
2235                                           SMB_ACL_ENTRY_T entry_d)
2236 {
2237         VFS_FIND(sys_acl_get_qualifier);
2238         return handle->fns->sys_acl_get_qualifier_fn(handle, entry_d);
2239 }
2240
2241 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2242                                         const char *path_p,
2243                                         SMB_ACL_TYPE_T type)
2244 {
2245         VFS_FIND(sys_acl_get_file);
2246         return handle->fns->sys_acl_get_file_fn(handle, path_p, type);
2247 }
2248
2249 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2250                                       struct files_struct *fsp)
2251 {
2252         VFS_FIND(sys_acl_get_fd);
2253         return handle->fns->sys_acl_get_fd_fn(handle, fsp);
2254 }
2255
2256 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct *handle,
2257                                      SMB_ACL_PERMSET_T permset)
2258 {
2259         VFS_FIND(sys_acl_clear_perms);
2260         return handle->fns->sys_acl_clear_perms_fn(handle, permset);
2261 }
2262
2263 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct *handle,
2264                                   SMB_ACL_PERMSET_T permset,
2265                                   SMB_ACL_PERM_T perm)
2266 {
2267         VFS_FIND(sys_acl_add_perm);
2268         return handle->fns->sys_acl_add_perm_fn(handle, permset, perm);
2269 }
2270
2271 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct *handle,
2272                                     SMB_ACL_T theacl, ssize_t *plen)
2273 {
2274         VFS_FIND(sys_acl_to_text);
2275         return handle->fns->sys_acl_to_text_fn(handle, theacl, plen);
2276 }
2277
2278 SMB_ACL_T smb_vfs_call_sys_acl_init(struct vfs_handle_struct *handle,
2279                                     int count)
2280 {
2281         VFS_FIND(sys_acl_init);
2282         return handle->fns->sys_acl_init_fn(handle, count);
2283 }
2284
2285 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct *handle,
2286                                       SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2287 {
2288         VFS_FIND(sys_acl_create_entry);
2289         return handle->fns->sys_acl_create_entry_fn(handle, pacl, pentry);
2290 }
2291
2292 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct *handle,
2293                                       SMB_ACL_ENTRY_T entry,
2294                                       SMB_ACL_TAG_T tagtype)
2295 {
2296         VFS_FIND(sys_acl_set_tag_type);
2297         return handle->fns->sys_acl_set_tag_type_fn(handle, entry, tagtype);
2298 }
2299
2300 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct *handle,
2301                                        SMB_ACL_ENTRY_T entry, void *qual)
2302 {
2303         VFS_FIND(sys_acl_set_qualifier);
2304         return handle->fns->sys_acl_set_qualifier_fn(handle, entry, qual);
2305 }
2306
2307 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct *handle,
2308                                      SMB_ACL_ENTRY_T entry,
2309                                      SMB_ACL_PERMSET_T permset)
2310 {
2311         VFS_FIND(sys_acl_set_permset);
2312         return handle->fns->sys_acl_set_permset_fn(handle, entry, permset);
2313 }
2314
2315 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct *handle,
2316                                SMB_ACL_T theacl)
2317 {
2318         VFS_FIND(sys_acl_valid);
2319         return handle->fns->sys_acl_valid_fn(handle, theacl);
2320 }
2321
2322 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2323                                   const char *name, SMB_ACL_TYPE_T acltype,
2324                                   SMB_ACL_T theacl)
2325 {
2326         VFS_FIND(sys_acl_set_file);
2327         return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2328 }
2329
2330 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2331                                 struct files_struct *fsp, SMB_ACL_T theacl)
2332 {
2333         VFS_FIND(sys_acl_set_fd);
2334         return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2335 }
2336
2337 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2338                                          const char *path)
2339 {
2340         VFS_FIND(sys_acl_delete_def_file);
2341         return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2342 }
2343
2344 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct *handle,
2345                                   SMB_ACL_PERMSET_T permset,
2346                                   SMB_ACL_PERM_T perm)
2347 {
2348         VFS_FIND(sys_acl_get_perm);
2349         return handle->fns->sys_acl_get_perm_fn(handle, permset, perm);
2350 }
2351
2352 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct *handle,
2353                                    char *text)
2354 {
2355         VFS_FIND(sys_acl_free_text);
2356         return handle->fns->sys_acl_free_text_fn(handle, text);
2357 }
2358
2359 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct *handle,
2360                                   SMB_ACL_T posix_acl)
2361 {
2362         VFS_FIND(sys_acl_free_acl);
2363         return handle->fns->sys_acl_free_acl_fn(handle, posix_acl);
2364 }
2365
2366 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct *handle,
2367                                         void *qualifier, SMB_ACL_TAG_T tagtype)
2368 {
2369         VFS_FIND(sys_acl_free_qualifier);
2370         return handle->fns->sys_acl_free_qualifier_fn(handle, qualifier, 
2371                                                       tagtype);
2372 }
2373
2374 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2375                               const char *path, const char *name, void *value,
2376                               size_t size)
2377 {
2378         VFS_FIND(getxattr);
2379         return handle->fns->getxattr_fn(handle, path, name, value, size);
2380 }
2381
2382 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2383                                struct files_struct *fsp, const char *name,
2384                                void *value, size_t size)
2385 {
2386         VFS_FIND(fgetxattr);
2387         return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2388 }
2389
2390 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2391                                const char *path, char *list, size_t size)
2392 {
2393         VFS_FIND(listxattr);
2394         return handle->fns->listxattr_fn(handle, path, list, size);
2395 }
2396
2397 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2398                                 struct files_struct *fsp, char *list,
2399                                 size_t size)
2400 {
2401         VFS_FIND(flistxattr);
2402         return handle->fns->flistxattr_fn(handle, fsp, list, size);
2403 }
2404
2405 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2406                              const char *path, const char *name)
2407 {
2408         VFS_FIND(removexattr);
2409         return handle->fns->removexattr_fn(handle, path, name);
2410 }
2411
2412 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2413                               struct files_struct *fsp, const char *name)
2414 {
2415         VFS_FIND(fremovexattr);
2416         return handle->fns->fremovexattr_fn(handle, fsp, name);
2417 }
2418
2419 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2420                           const char *name, const void *value, size_t size,
2421                           int flags)
2422 {
2423         VFS_FIND(setxattr);
2424         return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2425 }
2426
2427 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2428                            struct files_struct *fsp, const char *name,
2429                            const void *value, size_t size, int flags)
2430 {
2431         VFS_FIND(fsetxattr);
2432         return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2433 }
2434
2435 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2436                             struct files_struct *fsp)
2437 {
2438         VFS_FIND(aio_force);
2439         return handle->fns->aio_force_fn(handle, fsp);
2440 }
2441
2442 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2443                              const struct smb_filename *fname,
2444                              SMB_STRUCT_STAT *sbuf)
2445 {
2446         VFS_FIND(is_offline);
2447         return handle->fns->is_offline_fn(handle, fname, sbuf);
2448 }
2449
2450 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2451                              const struct smb_filename *fname)
2452 {
2453         VFS_FIND(set_offline);
2454         return handle->fns->set_offline_fn(handle, fname);
2455 }