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