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